first init

master
xcw 2023-05-11 10:51:56 +08:00
commit 26bb2a1f5e
193 changed files with 31802 additions and 0 deletions

16
.hbuilderx/launch.json Normal file
View File

@ -0,0 +1,16 @@
{ // launch.json configurations app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtypelocalremote, localremote
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}

55
App.vue Normal file
View File

@ -0,0 +1,55 @@
<script>
import toolAll from './jsFile/tools.js';
export default {
globalData:{
projectname:'', //
lat:'', //
lng:'' ,//
hostapi:'https://yisi-scan.scdxtc.cn' //
},
// show
onLaunch() {
let that = this;
uni.login({
provider: 'weixin',
success: (result)=> {
if (result.code) {
that.$requst.post('/api/user/login',{code:result.code}).then(res => {
if(res.code == 0){
uni.setStorageSync('token',res.data.token) //token
uni.setStorageSync('openid',res.data.openid) //openid
that.$isResolve(); //promise
}
},error => {
})
}
},
});
},
onShow: ()=> {
},
onHide: ()=> {
}
};
</script>
<style>
/* 阿里巴巴矢量图标库 start */
@import url("./commons/icon-font.css");
/* 阿里巴巴矢量图标库 end */
/* 项目页面样式 start */
@import url("./commons/style.css");
/* 项目页面样式 end */
/* 加载中样式 start */
@import url("./commons/loading.css");
/* 加载中样式 end */
</style>

12
commons/animate.min.css vendored Normal file

File diff suppressed because one or more lines are too long

155
commons/icon-font.css Normal file
View File

@ -0,0 +1,155 @@
@font-face {
font-family: "iconfont"; /* Project id 3180711 */
src: url('https://at.alicdn.com/t/font_3180711_atv5gkgm4w4.woff2?t=1651830764889') format('woff2'),
url('https://at.alicdn.com/t/font_3180711_atv5gkgm4w4.woff?t=1651830764889') format('woff'),
url('https://at.alicdn.com/t/font_3180711_atv5gkgm4w4.ttf?t=1651830764889') format('truetype');
}
.icon {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-del:before {
content: "\e718";
}
.icon-cut:before {
content: "\e609";
}
.icon-add:before {
content: "\e60a";
}
.icon-add-picture05:before {
content: "\e639";
}
.icon-add-picture04:before {
content: "\e636";
}
.icon-add-picture03:before {
content: "\e642";
}
.icon-add-picture02:before {
content: "\e8bc";
}
.icon-add-picture01:before {
content: "\e62c";
}
.icon-sandian:before {
content: "\e769";
}
.icon-nothing-collection:before {
content: "\e610";
}
.icon-nothing-more:before {
content: "\e624";
}
.icon-nothing-data:before {
content: "\e60c";
}
.icon-address-check:before {
content: "\e6c2";
}
.icon-address-unchecked:before {
content: "\e623";
}
.icon-navigate-now:before {
content: "\e640";
}
.icon-send-goods:before {
content: "\e601";
}
.icon-payment:before {
content: "\e602";
}
.icon-finish:before {
content: "\e63f";
}
.icon-take:before {
content: "\e649";
}
.icon-refund:before {
content: "\e613";
}
.icon-customer-black:before {
content: "\ec2e";
}
.icon-customer:before {
content: "\e628";
}
.icon-check:before {
content: "\e61e";
}
.icon-del-white:before {
content: "\e61f";
}
.icon-screen:before {
content: "\e60b";
}
.icon-search:before {
content: "\e653";
}
.icon-caidan-mo:before {
content: "\e73e";
}
.icon-renwu-mo:before {
content: "\e73f";
}
.icon-shop-cart:before {
content: "\e73d";
}
.icon-caidan-active:before {
content: "\e608";
}
.icon-renwu-acitve:before {
content: "\e67c";
}
.icon-home-mo:before {
content: "\e673";
}
.icon-home-active:before {
content: "\e674";
}
.icon-return:before {
content: "\e600";
}
.icon-next:before {
content: "\e60e";
}

1054
commons/loading.css Normal file

File diff suppressed because it is too large Load Diff

58
commons/style.css Normal file
View File

@ -0,0 +1,58 @@
/* 图片处理 */
image {
/* 照顾低版本浏览器 如果图片外面包含了链接会有边框的问题 */
border: 0;
/* 取消图片底侧有空白缝隙的问题 ① */
vertical-align: middle;
/* 取消图片底侧有空白缝隙的问题 ② */
object-fit: cover;
}
/* 去除滚动条 */
scroll-view ::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
/* 文字行数 */
.clips {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
word-wrap: break-word;
word-break: break-all;
}
/* 页面样式 */
page {
background-color: #f7f7f7;
color: #333333;
}
.main {
padding-bottom: 120rpx;
}
/* 输入默认提示 */
::-webkit-input-placeholder {
/* WebKit browserswebkit内核浏览器 */
color: #8f989f;
}
:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #8f989f;
}
::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #8f989f;
}
:-ms-input-placeholder {
/* Internet Explorer 10+ */
color: #8f989f;
}

View File

@ -0,0 +1,132 @@
<template>
<view class="foot-bar">
<!-- 底部导航 -->
<view class="item" :style="{'width':`calc(100%/${footBarList.length})`}" @tap="chooseEv(index)" v-for="(item,index) in footBarList" :key="index">
<view class="icon"><image :src="current==index?item.activePath:item.normalPath" mode="heightFix"></image></view>
<view class="title" :style="{'color':current==index?'#0567b8':'#a0a5af'}">{{item.title}}</view>
</view>
</view>
</template>
<script>
export default {
name:'foot-bar',
props:{
//
current:{
type:Number,
default:0
},
},
data() {
return {
footBarList:[
{
normalPath:'/static/foot-bar/index.png',
activePath:'/static/foot-bar/index-active.png',
key: "home",
title: "首页"
},
{
normalPath:'/static/foot-bar/my.png',
activePath:'/static/foot-bar/my-active.png',
key: "my",
title: "我的"
}
], //
};
},
mounted() {
if(uni.getStorageSync('footBarList')){
this.footBarList = uni.getStorageSync('footBarList');
}else{
//
// this.getFootBar();
}
//
const query = wx.createSelectorQuery().in(this);
query.select('.foot-bar').boundingClientRect((rect) => {
uni.setStorageSync('footHeight',rect.height)
}).exec()
},
methods:{
//
getFootBar(){
this.$requst.get('/api/index/mini-program-setting').then(res => {
if(res.code == 0){
console.log(res,'底部信息');
let footBar= [];
res.data.footBar.forEach(item=>{
let obj = {
normalPath: `${getApp().globalData.hostapi}`+item.icon[0],
activePath: `${getApp().globalData.hostapi}`+item.icon[1],
title:item.name
}
footBar.push(obj);
})
this.footBarList = footBar;
uni.setStorageSync('footBarList',this.footBarList)
}else{
this.$toolAll.tools.showToast(res.msg)
}
})
},
// tabbar
chooseEv(index){
console.log(index)
switch (index){
case 0:
uni.reLaunch({
url:'/pages/index/index',
})
break;
case 1:
if(this.$toolAll.tools.judgeAuth()) {
uni.reLaunch({
url:'/pages/my/my',
})
}
break;
}
},
}
}
</script>
<style scoped>
.foot-bar{
display: flex;
justify-content: space-around;
align-items: center;
width: 100%;
height: 98rpx;
background-color: #ffffff;
box-shadow: 0 0 16rpx rgba(146, 146, 146, .06);
position: fixed;
left: 0;
bottom: 0;
z-index: 99;
}
.foot-bar .item{
display: flex;
flex-wrap: wrap;
justify-items: center;
text-align: center;
}
.foot-bar .icon{
justify-content: center;
align-items: center;
width: 100%;
height: 39rpx;
}
.foot-bar .icon image{
height: 100%;
}
.foot-bar .title{
width: 100%;
margin-top: 6rpx;
font-size: 22rpx;
line-height: 1.3;
}
</style>

View File

@ -0,0 +1,260 @@
<template>
<view class="goods-list">
<view class="goods-item" :class="showType!==''?showType:''" v-for="(item,index) in goodsList" :key="index" @tap.stop="toDetail(item.id)">
<view class="tag" :style="{backgroundColor:item1}" v-if="item.tag!==''&&item.tag==index1" v-for="(item1,index1) in tag_bg_color" :key="index1">
{{item.tag}}
</view>
<!-- <view class="tag tag-green" v-else-if="">放心购</view> -->
<view class="img">
<image :src="item.src" mode="aspectFit"></image>
</view>
<view class="msg">
<view class="title clips">{{item.title}}</view>
<view class="price-bg">
<view class="price">
<view class="price-item">
<text></text>
<text>{{item.price.substr(0,item.price.indexOf('.'))}}</text>
<text>{{item.price.substr(item.price.indexOf('.'),item.price.length)}}</text>
</view>
<view class="price-item" v-if="item.integral>0">
<text>+</text>
<text>{{item.integral}}</text>
<text>积分</text>
</view>
</view>
<view class="btn">
<view class="icon-spot" v-if="!ifShowCart">
<image src="/static/icon/icon-spot.png" mode="widthFix"></image>
</view>
<view class="icon-cart" v-else @tap.stop="addCart(item.sku_id)">
<image src="/static/icon/icon-add-cart.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name:'goods-list',
props:{
//
ifShowCart:{
type:Boolean,
default:true
},
//
ifRefreshCart:{
type:Boolean,
default:false
},
//
showType:{
type:String,
default:'' //search-column cate-column
},
//
goodsList:{
type:Array,
default:[]
},
},
data() {
return {
tag_bg_color:{}, //tag
};
},
mounted() {
//
this.getBaseConfig();
},
methods:{
//
getBaseConfig(){
this.$requst.get('/api.index/baseConfig').then(res => {
if(res.code == 0){
this.tag_bg_color = res.data.tag_bg_color;
}else{
this.$toolAll.tools.showToast(res.msg);
}
})
},
//
toDetail(id){
uni.navigateTo({
url:`/pagesB/goodsDetail/goodsDetail?id=${id}`
})
},
//
addCart(sku_id){
let params = {
sku_id:sku_id,
num:1
}
this.$requst.post('/api/order/shopping-cart-add',params).then(res => {
if(res.code == 0){
this.$toolAll.tools.showToast('已加入购物车');
if(this.ifRefreshCart){
this.$emit("getCartList");
}
}else{
this.$toolAll.tools.showToast(res.msg);
}
})
}
}
}
</script>
<style scoped>
.goods-list{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.goods-item{
box-sizing: border-box;
width: calc(50% - 9rpx);
padding: 18rpx;
margin-bottom: 18rpx;
border-radius: 10rpx;
background-color: #ffffff;
overflow: hidden;
position: relative;
}
.goods-list .goods-item:nth-last-of-type(1),
.goods-list .goods-item:nth-last-of-type(2){
/* margin-bottom: 0; */
}
.goods-item .tag{
line-height: 34rpx;
padding: 0 8rpx;
background-color: #d4996d;
font-size: 20rpx;
text-align: center;
color: #ffffff;
position: absolute;
top: 0;
left: 0;
}
.goods-item .tag-green{
background-color: #4cc474;
}
.goods-item .img,
.goods-item .img image{
width: 290rpx;
height: 290rpx;
}
.goods-item .msg{
margin-top: 30rpx;
}
.goods-item .msg .title{
font-size: 26rpx;
line-height: 40rpx;
-webkit-line-clamp: 2;
}
.goods-item .msg .price-bg{
display: flex;
justify-content: space-between;
align-items: center;
height: 40rpx;
margin-top: 20rpx;
}
.goods-item .msg .price{
display: flex;
align-items: center;
max-width: calc(100% - 36rpx);
}
.goods-item .msg .price-item{
display: flex;
align-items: flex-end;
}
.goods-item .msg .price-item text{
font-size: 24rpx;
line-height: 30rpx;
color: #f72e2e;
}
.goods-item .msg .price-item text:nth-of-type(2){
font-size: 34rpx;
line-height: 40rpx;
}
.goods-item .icon-spot image{
width: 32rpx;
height: 7rpx;
}
.goods-item .icon-cart image{
width: 36rpx;
height: 35rpx;
}
/* 搜索页面样式 */
.search-column{
display: flex;
justify-content: space-between;
align-items: flex-start;
width: 100%;
padding: 20rpx 20rpx 0;
border-radius: 0;
margin-bottom: 0;
}
.search-column .img{
width: 195rpx;
height: 195rpx;
margin-bottom: 20rpx;
}
.search-column .img image{
width: 195rpx;
height: 195rpx;
}
.search-column .msg{
width: calc(100% - 205rpx);
height: 195rpx;
border-bottom: 1px solid #eaeaea;
padding-bottom: 20rpx;
margin-top: 0;
}
.search-column .msg .title{
margin-top: 10rpx;
}
.search-column .tag{
left: 20rpx;
top: 20rpx;
border-radius: 10rpx 0 0 0;
}
.search-column .msg .price-bg{
margin-top: 46rpx;
}
/* 分类页面样式 */
.cate-column{
display: flex;
justify-content: space-between;
align-items: flex-start;
width: 100%;
padding: 20rpx 0;
border-radius: 0;
margin-bottom: 0;
}
.cate-column .img,
.cate-column .img image{
width: 155rpx;
height: 155rpx;
}
.cate-column .msg{
width: calc(100% - 170rpx);
height: 155rpx;
margin-top: 0;
}
.cate-column .msg .title{
margin-top: 6rpx;
}
.cate-column .tag{
left: 0;
top: 20rpx;
border-radius: 10rpx 0 0 0;
}
</style>

View File

@ -0,0 +1,41 @@
<template>
<view class="nothing">
<view class="nothing-box">
<image v-if="imgSrc!=''" class="nothing-img" :src="imgSrc" mode="aspectFill" lazy-load></image>
<i class="iconImg icon"
:class="['icon-nothing-more','icon-nothing-data','icon-nothing-collection'][currentType]"></i>
<view v-if="currentType!=1" class="nothing-con">{{content}}</view>
</view>
</view>
</template>
<script>
export default {
name:"nothing-page",
props:{
imgSrc:{ //
type:String,
default:''
},
content:{ //
type:String,
default:'暂无内容'
},
currentType:{ // icon
type:Number,
default: 0
}
},
data() {
return {};
}
}
</script>
<style scoped>
.nothing{position: fixed;top: 0;bottom: 0;left: 0;right: 0;display: flex;justify-content: center;align-items: center;}
.nothing-box{display: flex;justify-content: center;flex-direction: column;align-items: center;}
.nothing-box .nothing-img{width: 470rpx;height: 270rpx;}
.iconImg {font-size: 280rpx;color: #999999;}
.nothing-con{font-size: 24rpx;font-family: PingFang SC;font-weight: 500;color: #999999;}
</style>

View File

@ -0,0 +1,54 @@
<template>
<view :style="{
color: textColor,
fontSize: textFontSize,
fontWeight: `${ ifBold ? 'bold' : 0 }`,
textAlign: `${ ifCenter ? 'center' : 'left' }`,
padding: paddingStr
}">{{textStr}}</view>
</template>
<script>
export default {
name:"pitera",
props:{
//
textStr: {
type:String,
default:'-- NO MORE --'
},
//
textColor: {
type:String,
default:'#999999'
},
//
textFontSize: {
type: String,
default: '24rpx'
},
//
ifBold: {
type:Boolean,
default:false
},
//
ifCenter: {
type:Boolean,
default: true
},
//
paddingStr: {
type:String,
default:'20rpx'
}
},
data() {
return {};
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,187 @@
<template>
<view class="status-box" :style="{marginBottom:marginBottom,background:backgroudColor}">
<!-- 网络电量栏 -->
<view :style="{height:statusBarHeight+'px'}"></view>
<!-- 头部状态栏 -->
<view class="status-nav" :style="{height:navBarHeight}">
<!-- 返回键 -->
<view class="left-box" @tap="backEv" v-if="ifReturn" :style="{height:navBarHeight}">
<slot name="leftcontent">
<i class="icon icon-return" style="font-size: 38rpx;" :style="{color:returnColor}"></i>
</slot>
</view>
<!-- 标题 -->
<view class="tab-title" :style="{color:titleColor,fontWeight:ifBold?'bold':'',justifyContent:ifCenter?'center':'',padding:ifCenter?'0px':`${ifReturn ?'0 38':'0 15'}px`}">
<view class="title-box" :class="['','clips1','clips2'][clipNumber*1]" :style="{maxWidth: ifCenter ?'360rpx':'70%'}">
<!-- 有网络 -->
<view v-if="ifTitle && ifNet">{{navBarTitle}}</view>
<!-- 无网络 -->
<view v-if="!ifNet">{{netText}}<text @tap="refreshEv" style="color: #1f6fbb;margin-left: 20rpx;">刷新</text></view>
</view>
</view>
<!-- 右侧图标 -->
<view class="right-box" :style="{height:navBarHeight}">
<slot name="rightcontent"></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'status-nav',
props: {
//
backgroudColor: {
type: String,
default: '#f7f7f7'
},
//
navBarHeight: {
type: String,
default: '50px'
},
//
ifReturn: {
type: Boolean,
default: true
},
//
returnColor: {
type: String,
default: '#333333'
},
//
ifTitle: {
type: Boolean,
default: true
},
//
navBarTitle: {
type: String,
default: ''
},
//
clipNumber: {
type: String,
default: '1'
},
//
titleColor: {
type: String,
default: '#333333'
},
//
ifCenter: {
type: Boolean,
default: true
},
//
ifBold: {
type: Boolean,
default: false
},
//
marginBottom: {
type: String,
default: '0'
},
},
data() {
return {
statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
ifNet: true, //
netText: '当前无网络',
netTimer: null
}
},
mounted() {
//
this.$toolAll.tools.networkStatus();
//
this.$toolAll.tools.obtainPagePath();
setTimeout(() => {
this.ifNet = uni.getStorageSync('isNet');
}, 500)
},
methods: {
//
refreshEv() {
this.netText = '正在刷新...';
let outTime = 0; //
this.netTimer = setInterval(() => {
outTime++;
this.$toolAll.tools.networkStatus();
if (uni.getStorageSync('isNet')) {
clearInterval(this.netTimer);
this.ifNet = true;
}
if (outTime == 10) {
clearInterval(this.netTimer);
this.netText = '刷新失败';
outTime = 0;
}
}, 1000)
},
//
backEv() {
uni.navigateBack({
delta: 1,
fail: () => {
uni.reLaunch({
url: '/pages/index/index'
})
}
})
}
}
}
</script>
<style scoped>
.status-box {
background-repeat: no-repeat;
background-size: 750rpx auto;
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 99;
}
.status-nav {
display: flex;
align-items: center;
width: 100%;
}
.left-box {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
padding: 0 50rpx 0 20rpx;
}
.right-box {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
right: 0;
padding: 0 20rpx 0 50rpx;
}
.tab-title {
display: flex;
width: 100%;
font-size: 32rpx;
line-height: 1.5;
letter-spacing: 2rpx;
text-indent: 2rpx;
}
.tab-title .title-box {
margin-top: -4rpx;
}
</style>

View File

@ -0,0 +1,62 @@
<template>
<view class="lamp-box">
<swiper :current="lampCur" :style="{height: newHeight}" :autoplay="isplay" :circular="true" :interval="1000" :vertical="true" :duration="1000">
<swiper-item v-for="(item,index) in lampList" :key="index">
<view @tap="toDetail(index)">{{item.title}}</view>
</swiper-item>
<swiper-item v-if="lampList.length==1" v-for="(item,index) in lampList" :key="index">
<view @tap="toDetail(index)">{{item.title}}</view>
</swiper-item>
</swiper>
</view>
</template>
<script>
export default {
name: "swiper-lamp",
props: {
isplay: {
type: Boolean,
default: true
},
isClick: {
type: Boolean,
default: false
},
lampList: { //
type: Array,
default: []
},
newHeight: { //swiper
type: String,
default: '42rpx'
},
},
data() {
return {
lampCur: 0, //
autoplay: true, //
};
},
methods: {
//
toDetail(index) {
this.lampCur = index;
if(this.isClick){
//
uni.navigateTo({
url: `/pagesB/news/newsDetail?id=${this.lampList[index].id}`
})
}
},
}
}
</script>
<style scoped>
.lamp-box {
width: 100%;
overflow: hidden;
position: relative;
}
</style>

View File

@ -0,0 +1,167 @@
<template>
<view class="banner-box">
<swiper :current="bcurrent" @change="changeBanner" :style="{height: newHeight}" :autoplay="isplay" :circular="true" :interval="3000" :duration="500">
<swiper-item v-for="(item,index) in bannerList" :key="index">
<view @tap="chooseImg(index,item.url)" class="img-box">
<image :style="{borderRadius:newRadius,height:newHeight}" class="img animated fadeIn" :src="item.imgSrc" mode="widthFix"></image>
</view>
</swiper-item>
</swiper>
<!-- 指示点 -->
<view v-if="isDot" class="dot-box" :style="{bottom:newBottom}">
<view class="item-dot" :style="{backgroundColor: bcurrent==indexd ? activec : defaultc}" v-for="(itemd,indexd) in bannerList.length" :key="indexd" @tap="chooseDot(indexd)"></view>
</view>
<!-- 指示数字 -->
<view v-if="isNum" class="num-box" :style="{bottom:newBottom}">
<text>{{bcurrent+1}}</text>
<text>/</text>
<text>{{bannerList.length}}</text>
</view>
</view>
</template>
<script>
export default {
name: "swiper-pu",
props: {
isplay: {
type: Boolean,
default: false
},
isDot: { //
type: Boolean,
default: true
},
isNum: { //
type: Boolean,
default: false
},
bannerList: { //
type: Array,
default: []
},
newHeight: { //swiper
type: String,
default: '330rpx'
},
newBottom: { //
type: String,
default: '12rpx'
},
newRadius: { //
type: String,
default: '0rpx'
},
browseP: { //
type: Boolean,
default: false
},
activec: {
type: String,
default: 'rgba(255,255,255,1)'
},
defaultc: {
type: String,
default: 'rgba(255,255,255,.6)'
}
},
data() {
return {
bcurrent: 0, //
isShowVideo: false, //
autoplay: false, //
isVedio: uni.getStorageSync('is_vedio') //
};
},
methods: {
//
chooseImg(index, url) {
console.log('当前banner图', index, url);
this.bcurrent = index
if (this.browseP) {
let imgList = []
this.bannerList.forEach(item => {
let obj = {
url: item.imgSrc,
type: 'image'
}
imgList.push(obj)
})
//
uni.previewMedia({
current: this.bcurrent,
sources: imgList
})
}
if (url) {
//
uni.navigateTo({
url: `${url}`
})
console.log(`${url}`, '跳转链接');
}
},
//
changeBanner(e) {
this.bcurrent = e.detail.current //
},
//
chooseDot(index) {
this.bcurrent = index;
},
}
}
</script>
<style scoped>
.banner-box {
width: 100%;
overflow: hidden;
position: relative;
}
.img-box {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.img {
width: 100%;
vertical-align: bottom;
}
.dot-box {
display: flex;
justify-content: center;
width: 100%;
position: absolute;
}
.item-dot {
width: 12rpx;
height: 12rpx;
border-radius: 100%;
margin: 0 4rpx;
}
.num-box{
box-sizing: border-box;
display: flex;
justify-content: flex-end;
width: auto;
line-height: 46rpx;
border-radius: 4rpx;
padding: 0 12rpx;
background-color: rgba(0, 0, 0, .4);
font-size: 26rpx;
color: #ffffff;
position: absolute;
right: 38rpx;
}
.num-box text:nth-of-type(2){
font-size: 24rpx;
margin: 0 4rpx;
}
</style>

View File

@ -0,0 +1,107 @@
<template>
<view @touchmove.stop.prevent>
<view class="tui-popup-class tui-bottom-popup" :class="{ 'tui-popup-show': show, 'tui-popup-radius': radius }" :style="{ backgroundColor: backgroundColor, height: height ? height + 'rpx' : 'auto', zIndex: zIndex,transform:`translate3d(0, ${show?translateY:'100%'}, 0)`}">
<slot></slot>
</view>
<view class="tui-popup-mask" :class="[show ? 'tui-mask-show' : '']" :style="{ zIndex: maskZIndex }" v-if="mask" @tap="handleClose"></view>
</view>
</template>
<script>
export default {
name: 'tuiBottomPopup',
emits: ['close'],
props: {
//mask
mask: {
type: Boolean,
default: true
},
//
show: {
type: Boolean,
default: false
},
//
backgroundColor: {
type: String,
default: '#fff'
},
// rpx
height: {
type: Number,
default: 0
},
//
radius: {
type: Boolean,
default: true
},
zIndex: {
type: [Number, String],
default: 997
},
maskZIndex: {
type: [Number, String],
default: 996
},
//
translateY: {
type: String,
default: '0'
}
},
methods: {
handleClose() {
if (!this.show) {
return;
}
this.$emit('close', {});
}
}
};
</script>
<style scoped>
.tui-bottom-popup {
width: 100%;
position: fixed;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
transform: translate3d(0, 100%, 0);
transform-origin: center;
transition: all 0.3s ease-in-out;
min-height: 20rpx;
}
.tui-popup-radius {
border-top-left-radius: 24rpx;
border-top-right-radius: 24rpx;
padding-bottom: env(safe-area-inset-bottom);
overflow: hidden;
}
.tui-popup-show {
opacity: 1;
/* transform: translate3d(0, 0, 0); */
}
.tui-popup-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
transition: all 0.3s ease-in-out;
opacity: 0;
visibility: hidden;
}
.tui-mask-show {
opacity: 1;
visibility: visible;
}
</style>

View File

@ -0,0 +1,204 @@
<template>
<view :class="{ 'tui-flex-end': flexEnd }">
<view class="tui-popup-list" :class="{ 'tui-popup-show': show,'tui-z_index':show && position!='relative' }" :style="{ width: width, backgroundColor: backgroundColor, borderRadius: radius, color: color, position: position, left: left, right: right, bottom: bottom, top: top,transform:`translate(${translateX},${translateY})` }">
<view class="tui-triangle" :style="{
borderWidth: borderWidth,
borderColor: `transparent transparent ${backgroundColor} transparent`,
left: triangleLeft,
right: triangleRight,
top: triangleTop,
bottom: triangleBottom
}"
v-if="direction == 'top'"></view>
<view class="tui-triangle" :style="{
borderWidth: borderWidth,
borderColor: `${backgroundColor} transparent transparent transparent`,
left: triangleLeft,
right: triangleRight,
top: triangleTop,
bottom: triangleBottom
}"
v-if="direction == 'bottom'"></view>
<view class="tui-triangle" :style="{
borderWidth: borderWidth,
borderColor: `transparent ${backgroundColor} transparent transparent`,
left: triangleLeft,
right: triangleRight,
top: triangleTop,
bottom: triangleBottom
}"
v-if="direction == 'left'"></view>
<view class="tui-triangle" :style="{
borderWidth: borderWidth,
borderColor: `transparent transparent transparent ${backgroundColor}`,
left: triangleLeft,
right: triangleRight,
top: triangleTop,
bottom: triangleBottom
}"
v-if="direction == 'right'"></view>
<slot />
</view>
<view @touchmove.stop.prevent="stop" class="tui-popup-mask" :class="{ 'tui-popup-show': show }" :style="{ backgroundColor: maskBgColor }"
v-if="mask" @tap="handleClose"></view>
</view>
</template>
<script>
export default {
name: 'tuiBubblePopup',
emits: ['close'],
props: {
//
width: {
type: String,
default: '300rpx'
},
//popup
radius: {
type: String,
default: '8rpx'
},
//popup left right top bottom
left: {
type: String,
default: 'auto'
},
right: {
type: String,
default: 'auto'
},
top: {
type: String,
default: 'auto'
},
bottom: {
type: String,
default: 'auto'
},
translateX:{
type: String,
default: '0'
},
translateY:{
type: String,
default: '0'
},
//
backgroundColor: {
type: String,
default: '#4c4c4c'
},
//
color: {
type: String,
default: '#fff'
},
//border-width
borderWidth: {
type: String,
default: '12rpx'
},
// top left right bottom
direction: {
type: String,
default: 'top'
},
// left right top bottom
triangleLeft: {
type: String,
default: 'auto'
},
triangleRight: {
type: String,
default: 'auto'
},
triangleTop: {
type: String,
default: 'auto'
},
triangleBottom: {
type: String,
default: 'auto'
},
// relative absolute fixed
position: {
type: String,
default: 'fixed'
},
//flex-end
flexEnd: {
type: Boolean,
default: false
},
//mask
mask: {
type: Boolean,
default: true
},
maskBgColor: {
type: String,
default: 'rgba(0, 0, 0, 0.4)'
},
//
show: {
type: Boolean,
default: false
}
},
methods: {
handleClose() {
if (!this.show) {
return;
}
this.$emit('close', {});
},
stop() {
return false;
}
}
};
</script>
<style scoped>
.tui-popup-list {
z-index: 1;
transition: all 0.3s ease-in-out;
opacity: 0;
visibility: hidden;
}
.tui-flex-end {
width: 100%;
display: flex;
justify-content: flex-end;
}
.tui-triangle {
position: absolute;
width: 0;
height: 0;
border-style: solid;
z-index: 997;
}
.tui-popup-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 995;
transition: all 0.3s ease-in-out;
opacity: 0;
visibility: hidden;
}
.tui-popup-show {
opacity: 1;
visibility: visible;
}
.tui-z_index {
z-index: 996;
}
</style>

View File

@ -0,0 +1,520 @@
<template>
<button
class="tui-btn"
:class="[
plain ? 'tui-' + type + '-outline' : 'tui-btn-' + (type || 'primary'),
getDisabledClass(disabled, type, plain),
getShapeClass(shape, plain),
getShadowClass(type, shadow, plain),
bold ? 'tui-text-bold' : '',
link ? 'tui-btn__link' : ''
]"
:hover-class="getHoverClass(disabled, type, plain)"
:style="{ width: width, height: height, lineHeight: height, fontSize: size + 'rpx', margin: margin }"
:loading="loading"
:form-type="formType"
:open-type="openType"
@getuserinfo="bindgetuserinfo"
@getphonenumber="bindgetphonenumber"
@contact="bindcontact"
@error="binderror"
:disabled="disabled"
@tap="handleClick"
>
<slot></slot>
</button>
</template>
<script>
export default {
name: 'tuiButton',
emits: ['click','getuserinfo','contact','getphonenumber','error'],
// #ifndef MP-QQ
behaviors: ['wx://form-field-button'],
// #endif
props: {
// primary, white, danger, warning, green,blue, grayblack,brown,gray-primary,gray-danger,gray-warning,gray-green
type: {
type: String,
default: 'primary'
},
//
shadow: {
type: Boolean,
default: false
},
// rpx %
width: {
type: String,
default: '100%'
},
// rpx
height: {
type: String,
default: '96rpx'
},
// rpx
size: {
type: Number,
default: 32
},
bold: {
type: Boolean,
default: false
},
margin: {
type: String,
default: '0'
},
// circle(), square()rightAngle()
shape: {
type: String,
default: 'square'
},
plain: {
type: Boolean,
default: false
},
//linkplain使
link: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
// button
disabledGray: {
type: Boolean,
default: false
},
loading: {
type: Boolean,
default: false
},
formType: {
type: String,
default: ''
},
openType: {
type: String,
default: ''
},
index: {
type: [Number, String],
default: 0
},
//200ms
preventClick: {
type: Boolean,
default: false
}
},
data() {
return {
time: 0
};
},
methods: {
handleClick() {
if (this.disabled) return;
if (this.preventClick) {
if(new Date().getTime() - this.time <= 200) return;
this.time = new Date().getTime();
setTimeout(() => {
this.time = 0;
}, 200);
}
this.$emit('click', {
index: Number(this.index)
});
},
bindgetuserinfo({ detail = {} } = {}) {
this.$emit('getuserinfo', detail);
},
bindcontact({ detail = {} } = {}) {
this.$emit('contact', detail);
},
bindgetphonenumber({ detail = {} } = {}) {
this.$emit('getphonenumber', detail);
},
binderror({ detail = {} } = {}) {
this.$emit('error', detail);
},
getShadowClass: function(type, shadow, plain) {
let className = '';
if (shadow && type != 'white' && !plain) {
className = 'tui-shadow-' + type;
}
return className;
},
getDisabledClass: function(disabled, type, plain) {
let className = '';
if (disabled && type != 'white' && type.indexOf('-') == -1) {
let classVal = this.disabledGray ? 'tui-gray-disabled' : 'tui-dark-disabled';
className = plain ? 'tui-dark-disabled-outline' : classVal;
}
return className;
},
getShapeClass: function(shape, plain) {
let className = '';
if (shape == 'circle') {
className = plain ? 'tui-outline-fillet' : 'tui-fillet';
} else if (shape == 'rightAngle') {
className = plain ? 'tui-outline-rightAngle' : 'tui-rightAngle';
}
return className;
},
getHoverClass: function(disabled, type, plain) {
let className = '';
if (!disabled) {
className = plain ? 'tui-outline-hover' : 'tui-' + (type || 'primary') + '-hover';
}
return className;
}
}
};
</script>
<style scoped>
.tui-btn-primary {
background: #5677fc !important;
color: #fff;
}
.tui-shadow-primary {
box-shadow: 0 10rpx 14rpx 0 rgba(86, 119, 252, 0.2);
}
.tui-btn-danger {
background: #eb0909 !important;
color: #fff;
}
.tui-shadow-danger {
box-shadow: 0 10rpx 14rpx 0 rgba(235, 9, 9, 0.2);
}
.tui-btn-warning {
background: #fc872d !important;
color: #fff;
}
.tui-shadow-warning {
box-shadow: 0 10rpx 14rpx 0 rgba(252, 135, 45, 0.2);
}
.tui-btn-green {
background: #07c160 !important;
color: #fff;
}
.tui-shadow-green {
box-shadow: 0 10rpx 14rpx 0 rgba(7, 193, 96, 0.2);
}
.tui-btn-blue {
background: #007aff !important;
color: #fff;
}
.tui-shadow-blue {
box-shadow: 0 10rpx 14rpx 0 rgba(0, 122, 255, 0.2);
}
.tui-btn-white {
background: #fff !important;
color: #333 !important;
}
.tui-btn-gray {
background: #bfbfbf !important;
color: #fff !important;
}
.tui-btn-black {
background: #333 !important;
color: #fff !important;
}
.tui-btn-brown{
background: #ac9157 !important;
color: #fff !important;
}
.tui-btn-gray-black {
background: #f2f2f2 !important;
color: #333;
}
.tui-btn-gray-primary {
background: #f2f2f2 !important;
color: #5677fc !important;
}
.tui-gray-primary-hover {
background: #d9d9d9 !important;
}
.tui-btn-gray-green {
background: #f2f2f2 !important;
color: #07c160 !important;
}
.tui-gray-green-hover {
background: #d9d9d9 !important;
}
.tui-btn-gray-danger {
background: #f2f2f2 !important;
color: #eb0909 !important;
}
.tui-gray-danger-hover {
background: #d9d9d9 !important;
}
.tui-btn-gray-warning {
background: #f2f2f2 !important;
color: #fc872d !important;
}
.tui-gray-warning-hover {
background: #d9d9d9 !important;
}
.tui-shadow-gray {
box-shadow: 0 10rpx 14rpx 0 rgba(191, 191, 191, 0.2);
}
.tui-hover-gray {
background: #f7f7f9 !important;
}
.tui-black-hover {
background: #555 !important;
color: #e5e5e5 !important;
}
.tui-brown-hover{
background: #A37F49 !important;
color: #e5e5e5 !important;
}
/* button start*/
.tui-btn {
width: 100%;
position: relative;
border: 0 !important;
border-radius: 6rpx;
padding-left: 0;
padding-right: 0;
overflow: visible;
}
.tui-btn::after {
content: '';
position: absolute;
width: 200%;
height: 200%;
transform-origin: 0 0;
transform: scale(0.5, 0.5) translateZ(0);
box-sizing: border-box;
left: 0;
top: 0;
border-radius: 12rpx;
border: 0;
}
.tui-text-bold {
font-weight: bold;
}
.tui-btn-white::after {
border: 1px solid #bfbfbf;
}
.tui-white-hover {
background: #e5e5e5 !important;
color: #2e2e2e !important;
}
.tui-dark-disabled {
opacity: 0.6 !important;
color: #fafbfc !important;
}
.tui-dark-disabled-outline {
opacity: 0.5 !important;
}
.tui-gray-disabled {
background: #f3f3f3 !important;
color: #919191 !important;
box-shadow: none;
}
.tui-outline-hover {
opacity: 0.5;
}
.tui-primary-hover {
background: #4a67d6 !important;
color: #e5e5e5 !important;
}
.tui-primary-outline::after {
border: 1px solid #5677fc !important;
}
.tui-primary-outline {
color: #5677fc !important;
background: transparent;
}
.tui-danger-hover {
background: #c80808 !important;
color: #e5e5e5 !important;
}
.tui-danger-outline {
color: #eb0909 !important;
background: transparent;
}
.tui-danger-outline::after {
border: 1px solid #eb0909 !important;
}
.tui-warning-hover {
background: #d67326 !important;
color: #e5e5e5 !important;
}
.tui-warning-outline {
color: #fc872d !important;
background: transparent;
}
.tui-warning-outline::after {
border: 1px solid #fc872d !important;
}
.tui-green-hover {
background: #06ad56 !important;
color: #e5e5e5 !important;
}
.tui-green-outline {
color: #07c160 !important;
background: transparent;
}
.tui-green-outline::after {
border: 1px solid #07c160 !important;
}
.tui-blue-hover {
background: #0062cc !important;
color: #e5e5e5 !important;
}
.tui-blue-outline {
color: #007aff !important;
background: transparent;
}
.tui-blue-outline::after {
border: 1px solid #007aff !important;
}
/* #ifndef APP-NVUE */
.tui-btn-gradual {
background: linear-gradient(90deg, rgb(255, 89, 38), rgb(240, 14, 44)) !important;
color: #fff !important;
}
.tui-shadow-gradual {
box-shadow: 0 10rpx 14rpx 0 rgba(235, 9, 9, 0.15);
}
/* #endif */
.tui-gray-hover {
background: #a3a3a3 !important;
color: #898989;
}
/* #ifndef APP-NVUE */
.tui-gradual-hover {
background: linear-gradient(90deg, #d74620, #cd1225) !important;
color: #fff !important;
}
/* #endif */
.tui-gray-outline {
color: #999 !important;
background: transparent !important;
}
.tui-white-outline {
color: #fff !important;
background: transparent !important;
}
.tui-black-outline {
background: transparent !important;
color: #333 !important;
}
.tui-gray-outline::after {
border: 1px solid #ccc !important;
}
.tui-white-outline::after {
border: 1px solid #fff !important;
}
.tui-black-outline::after {
border: 1px solid #333 !important;
}
.tui-brown-outline {
color: #ac9157 !important;
background: transparent;
}
.tui-brown-outline::after {
border: 1px solid #ac9157 !important;
}
/*圆角 */
.tui-fillet {
border-radius: 50rpx;
}
.tui-btn-white.tui-fillet::after {
border-radius: 98rpx;
}
.tui-outline-fillet::after {
border-radius: 98rpx;
}
/*平角*/
.tui-rightAngle {
border-radius: 0;
}
.tui-btn-white.tui-rightAngle::after {
border-radius: 0;
}
.tui-outline-rightAngle::after {
border-radius: 0;
}
.tui-btn__link::after {
border: 0 !important;
}
</style>

View File

@ -0,0 +1,562 @@
/**
* @1900-2100区间内的公历农历互转
* @公历转农历solar2lunar(1987,11,01);
* @农历转公历lunar2solar(1987,09,10);
*/
let calendar = {
/**
* 农历1900-2100的润大小信息表
* @Array Of Property
* @return Hex
*/
lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-1909
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-1919
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-1929
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-1939
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-1949
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099
0x0d520
], //2100
/**
* 公历每个月份的天数普通表
* @Array Of Property
* @return Number
*/
solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
/**
* 天干地支之天干速查表
* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
* @return Cn string
*/
Gan: ["\u7532", "\u4e59", "\u4e19", "\u4e01", "\u620a", "\u5df1", "\u5e9a", "\u8f9b", "\u58ec", "\u7678"],
/**
* 天干地支之地支速查表
* @Array Of Property
* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
* @return Cn string
*/
Zhi: ["\u5b50", "\u4e11", "\u5bc5", "\u536f", "\u8fb0", "\u5df3", "\u5348", "\u672a", "\u7533", "\u9149", "\u620c",
"\u4ea5"
],
/**
* 天干地支之地支速查表<=>生肖
* @Array Of Property
* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
* @return Cn string
*/
Animals: ["\u9f20", "\u725b", "\u864e", "\u5154", "\u9f99", "\u86c7", "\u9a6c", "\u7f8a", "\u7334", "\u9e21",
"\u72d7", "\u732a"
],
/**
* 24节气速查表
* @Array Of Property
* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
* @return Cn string
*/
solarTerm: ["\u5c0f\u5bd2", "\u5927\u5bd2", "\u7acb\u6625", "\u96e8\u6c34", "\u60ca\u86f0", "\u6625\u5206",
"\u6e05\u660e", "\u8c37\u96e8", "\u7acb\u590f", "\u5c0f\u6ee1", "\u8292\u79cd", "\u590f\u81f3", "\u5c0f\u6691",
"\u5927\u6691", "\u7acb\u79cb", "\u5904\u6691", "\u767d\u9732", "\u79cb\u5206", "\u5bd2\u9732", "\u971c\u964d",
"\u7acb\u51ac", "\u5c0f\u96ea", "\u5927\u96ea", "\u51ac\u81f3"
],
/**
* 1900-2100各年的24节气日期速查表
* @Array Of Property
* @return 0x string For splice
*/
sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
'97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
'97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
'97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
'97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
'9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
'7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
'977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
'7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
'7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
'665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'
],
/**
* 数字转中文速查表
* @Array Of Property
* @trans ['日','一','二','三','四','五','六','七','八','九','十']
* @return Cn string
*/
nStr1: ["\u65e5", "\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341"],
/**
* 日期转农历称呼速查表
* @Array Of Property
* @trans ['初','十','廿','卅']
* @return Cn string
*/
nStr2: ["\u521d", "\u5341", "\u5eff", "\u5345"],
/**
* 月份转农历称呼速查表
* @Array Of Property
* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
* @return Cn string
*/
nStr3: ["\u6b63", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341", "\u51ac",
"\u814a"
],
/**
* 返回农历y年一整年的总天数
* @param lunar Year
* @return Number
* @eg:let count = calendar.lYearDays(1987) ;//count=387
*/
lYearDays: function(y) {
let i, sum = 348;
for (i = 0x8000; i > 0x8; i >>= 1) {
sum += (calendar.lunarInfo[y - 1900] & i) ? 1 : 0;
}
return (sum + calendar.leapDays(y));
},
/**
* 返回农历y年闰月是哪个月若y年没有闰月 则返回0
* @param lunar Year
* @return Number (0-12)
* @eg:let leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
*/
leapMonth: function(y) { //闰字编码 \u95f0
return (calendar.lunarInfo[y - 1900] & 0xf);
},
/**
* 返回农历y年闰月的天数 若该年没有闰月则返回0
* @param lunar Year
* @return Number (02930)
* @eg:let leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
*/
leapDays: function(y) {
if (calendar.leapMonth(y)) {
return ((calendar.lunarInfo[y - 1900] & 0x10000) ? 30 : 29);
}
return (0);
},
/**
* 返回农历y年m月非闰月的总天数计算m为闰月时的天数请使用leapDays方法
* @param lunar Year
* @return Number (-12930)
* @eg:let MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
*/
monthDays: function(y, m) {
if (m > 12 || m < 1) {
return -1
} //月份参数从1至12参数错误返回-1
return ((calendar.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29);
},
/**
* 返回公历(!)y年m月的天数
* @param solar Year
* @return Number (-128293031)
* @eg:let solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
*/
solarDays: function(y, m) {
if (m > 12 || m < 1) {
return -1
} //若参数错误 返回-1
let ms = m - 1;
if (ms == 1) { //2月份的闰平规律测算后确认返回28或29
return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28);
} else {
return (calendar.solarMonth[ms]);
}
},
/**
* 农历年份转换为干支纪年
* @param lYear 农历年的年份数
* @return Cn string
*/
toGanZhiYear: function(lYear) {
let ganKey = (lYear - 3) % 10;
let zhiKey = (lYear - 3) % 12;
if (ganKey == 0) ganKey = 10; //如果余数为0则为最后一个天干
if (zhiKey == 0) zhiKey = 12; //如果余数为0则为最后一个地支
return calendar.Gan[ganKey - 1] + calendar.Zhi[zhiKey - 1];
},
/**
* 公历月日判断所属星座
* @param cMonth [description]
* @param cDay [description]
* @return Cn string
*/
toAstro: function(cMonth, cDay) {
let s =
"\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf";
let arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22];
return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + "\u5ea7"; //座
},
/**
* 传入offset偏移量返回干支
* @param offset 相对甲子的偏移量
* @return Cn string
*/
toGanZhi: function(offset) {
return calendar.Gan[offset % 10] + calendar.Zhi[offset % 12];
},
/**
* 传入公历(!)y年获得该年第n个节气的公历日期
* @param y公历年(1900-2100)n二十四节气中的第几个节气(1~24)从n=1(小寒)算起
* @return day Number
* @eg:let _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
*/
getTerm: function(y, n) {
if (y < 1900 || y > 2100) {
return -1;
}
if (n < 1 || n > 24) {
return -1;
}
let _table = calendar.sTermInfo[y - 1900];
let _info = [
parseInt('0x' + _table.substr(0, 5)).toString(),
parseInt('0x' + _table.substr(5, 5)).toString(),
parseInt('0x' + _table.substr(10, 5)).toString(),
parseInt('0x' + _table.substr(15, 5)).toString(),
parseInt('0x' + _table.substr(20, 5)).toString(),
parseInt('0x' + _table.substr(25, 5)).toString()
];
let _calday = [
_info[0].substr(0, 1),
_info[0].substr(1, 2),
_info[0].substr(3, 1),
_info[0].substr(4, 2),
_info[1].substr(0, 1),
_info[1].substr(1, 2),
_info[1].substr(3, 1),
_info[1].substr(4, 2),
_info[2].substr(0, 1),
_info[2].substr(1, 2),
_info[2].substr(3, 1),
_info[2].substr(4, 2),
_info[3].substr(0, 1),
_info[3].substr(1, 2),
_info[3].substr(3, 1),
_info[3].substr(4, 2),
_info[4].substr(0, 1),
_info[4].substr(1, 2),
_info[4].substr(3, 1),
_info[4].substr(4, 2),
_info[5].substr(0, 1),
_info[5].substr(1, 2),
_info[5].substr(3, 1),
_info[5].substr(4, 2),
];
return parseInt(_calday[n - 1]);
},
/**
* 传入农历数字月份返回汉语通俗表示法
* @param lunar month
* @return Cn string
* @eg:let cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
*/
toChinaMonth: function(m) { // 月 => \u6708
if (m > 12 || m < 1) {
return -1
} //若参数错误 返回-1
let s = calendar.nStr3[m - 1];
s += "\u6708"; //加上月字
return s;
},
/**
* 传入农历日期数字返回汉字表示法
* @param lunar day
* @return Cn string
* @eg:let cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
*/
toChinaDay: function(d) { //日 => \u65e5
let s;
switch (d) {
case 10:
s = '\u521d\u5341';
break;
case 20:
s = '\u4e8c\u5341';
break;
break;
case 30:
s = '\u4e09\u5341';
break;
break;
default:
s = calendar.nStr2[Math.floor(d / 10)];
s += calendar.nStr1[d % 10];
}
return (s);
},
/**
* 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是立春
* @param y year
* @return Cn string
* @eg:let animal = calendar.getAnimal(1987) ;//animal='兔'
*/
getAnimal: function(y) {
return calendar.Animals[(y - 4) % 12]
},
/**
* 传入阳历年月日获得详细的公历农历object信息 <=>JSON
* @param y solar year
* @param m solar month
* @param d solar day
* @return JSON object
* @eg:console.log(calendar.solar2lunar(1987,11,01));
*/
solar2lunar: function(y, m, d) { //参数区间1900.1.31~2100.12.31
if (y < 1900 || y > 2100) {
return -1;
} //年份限定、上限
if (y == 1900 && m == 1 && d < 31) {
return -1;
} //下限
let objDate;
if (!y) { //未传参 获得当天
objDate = new Date();
} else {
objDate = new Date(y, parseInt(m) - 1, d)
}
let i, leap = 0,
temp = 0;
//修正ymd参数
y = objDate.getFullYear();
m = objDate.getMonth() + 1;
d = objDate.getDate();
let offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) /
86400000;
for (i = 1900; i < 2101 && offset > 0; i++) {
temp = calendar.lYearDays(i);
offset -= temp;
}
if (offset < 0) {
offset += temp;
i--;
}
//是否今天
let isTodayObj = new Date(),
isToday = false;
if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
isToday = true;
}
//星期几
let nWeek = objDate.getDay(),
cWeek = calendar.nStr1[nWeek];
if (nWeek == 0) {
nWeek = 7;
} //数字表示周几顺应天朝周一开始的惯例
//农历年
let year = i;
leap = calendar.leapMonth(i); //闰哪个月
let isLeap = false;
//效验闰月
for (i = 1; i < 13 && offset > 0; i++) {
//闰月
if (leap > 0 && i == (leap + 1) && isLeap == false) {
--i;
isLeap = true;
temp = calendar.leapDays(year); //计算农历闰月天数
} else {
temp = calendar.monthDays(year, i); //计算农历普通月天数
}
//解除闰月
if (isLeap == true && i == (leap + 1)) {
isLeap = false;
}
offset -= temp;
}
if (offset == 0 && leap > 0 && i == leap + 1)
if (isLeap) {
isLeap = false;
} else {
isLeap = true;
--i;
}
if (offset < 0) {
offset += temp;
--i;
}
//农历月
let month = i;
//农历日
let day = offset + 1;
//天干地支处理
let sm = m - 1;
let gzY = calendar.toGanZhiYear(year);
//月柱 1900年1月小寒以前为 丙子月(60进制12)
let firstNode = calendar.getTerm(year, (m * 2 - 1)); //返回当月「节」为几日开始
let secondNode = calendar.getTerm(year, (m * 2)); //返回当月「节」为几日开始
//依据12节气修正干支月
let gzM = calendar.toGanZhi((y - 1900) * 12 + m + 11);
if (d >= firstNode) {
gzM = calendar.toGanZhi((y - 1900) * 12 + m + 12);
}
//传入的日期的节气与否
let isTerm = false;
let Term = null;
if (firstNode == d) {
isTerm = true;
Term = calendar.solarTerm[m * 2 - 2];
}
if (secondNode == d) {
isTerm = true;
Term = calendar.solarTerm[m * 2 - 1];
}
//日柱 当月一日与 1900/1/1 相差天数
let dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10;
let gzD = calendar.toGanZhi(dayCyclical + d - 1);
//该日期所属的星座
let astro = calendar.toAstro(m, d);
return {
'lYear': year,
'lMonth': month,
'lDay': day,
'Animal': calendar.getAnimal(year),
'IMonthCn': (isLeap ? "\u95f0" : '') + calendar.toChinaMonth(month),
'IDayCn': calendar.toChinaDay(day),
'cYear': y,
'cMonth': m,
'cDay': d,
'gzYear': gzY,
'gzMonth': gzM,
'gzDay': gzD,
'isToday': isToday,
'isLeap': isLeap,
'nWeek': nWeek,
'ncWeek': "\u661f\u671f" + cWeek,
'isTerm': isTerm,
'Term': Term,
'astro': astro
};
},
/**
* 传入农历年月日以及传入的月份是否闰月获得详细的公历农历object信息 <=>JSON
* @param y lunar year
* @param m lunar month
* @param d lunar day
* @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
* @return JSON object
* @eg:console.log(calendar.lunar2solar(1987,9,10));
*/
lunar2solar: function(y, m, d, isLeapMonth) { //参数区间1900.1.31~2100.12.1
isLeapMonth = !!isLeapMonth;
let leapOffset = 0;
let leapMonth = calendar.leapMonth(y);
let leapDay = calendar.leapDays(y);
if (isLeapMonth && (leapMonth != m)) {
return -1;
} //传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) {
return -1;
} //超出了最大极限值
let day = calendar.monthDays(y, m);
let _day = day;
//bugFix 2016-9-25
//if month is leap, _day use leapDays method
if (isLeapMonth) {
_day = calendar.leapDays(y, m);
}
if (y < 1900 || y > 2100 || d > _day) {
return -1;
} //参数合法性效验
//计算农历的时间差
let offset = 0;
for (let i = 1900; i < y; i++) {
offset += calendar.lYearDays(i);
}
let leap = 0,
isAdd = false;
for (let i = 1; i < m; i++) {
leap = calendar.leapMonth(y);
if (!isAdd) { //处理闰月
if (leap <= i && leap > 0) {
offset += calendar.leapDays(y);
isAdd = true;
}
}
offset += calendar.monthDays(y, i);
}
//转换闰月农历 需补充该年闰月的前一个月的时差
if (isLeapMonth) {
offset += day;
}
//1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
let stmap = Date.UTC(1900, 1, 30, 0, 0, 0);
let calObj = new Date((offset + d - 31) * 86400000 + stmap);
let cY = calObj.getUTCFullYear();
let cM = calObj.getUTCMonth() + 1;
let cD = calObj.getUTCDate();
return calendar.solar2lunar(cY, cM, cD);
}
};
export default {
solar2lunar: calendar.solar2lunar,
lunar2solar: calendar.lunar2solar
};

View File

@ -0,0 +1,915 @@
<template>
<view @touchmove.stop.prevent="stop" v-if="isFixed">
<view class="tui-bottom-popup" :class="{'tui-popup-show': isShow}">
<view class="tui-calendar-header" :class="{ 'tui-calendar-radius': radius }">
<view>日期选择</view>
<view class="tui-iconfont tui-font-close" hover-class="tui-opacity" :hover-stay-time="150" @tap="hide">
</view>
</view>
<view class="tui-date-box">
<view class="tui-iconfont tui-font-arrowleft" :style="{ color: yearArrowColor }"
hover-class="tui-opacity" :hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(0)"></view>
<view class="tui-iconfont tui-font-arrowleft" :style="{ color: monthArrowColor }"
hover-class="tui-opacity" :hover-stay-time="150" @tap="changeMonth(0)"></view>
<view class="tui-date_time">{{ showTitle }}</view>
<view class="tui-iconfont tui-font-arrowright" :style="{ color: monthArrowColor }"
hover-class="tui-opacity" :hover-stay-time="150" @tap="changeMonth(1)"></view>
<view class="tui-iconfont tui-font-arrowright" :style="{ color: yearArrowColor }"
hover-class="tui-opacity" :hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(1)"></view>
</view>
<view class="tui-date-header">
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
</view>
<view class="tui-date-content" :class="{ 'tui-flex-start': isFixed && fixedHeight }"
:style="{ height: isFixed && fixedHeight ? dateHeight * 6 + 'px' : 'auto' }">
<block v-for="(item, index) in weekdayArr" :key="index">
<view class="tui-date"></view>
</block>
<view class="tui-date" :class="{
'tui-date-pd_0': isFixed && fixedHeight,
'tui-opacity': openDisAbled(year, month, index + 1),
'tui-start-date': (type == 2 && startDate == `${year}-${month}-${index + 1}`) || type == 1,
'tui-end-date': (type == 2 && endDate == `${year}-${month}-${index + 1}`) || type == 1
}" :style="{ backgroundColor: isFixed ? getColor(index, 1) : 'transparent', height: isFixed && fixedHeight ? dateHeight + 'px' : 'auto' }"
v-for="(item, index) in daysArr" :key="index" @tap="dateClick(index)">
<view class="tui-date-text"
:style="{ color: isFixed ? getColor(index, 2) : getStatusData(3, index), backgroundColor: getStatusData(2, index) }">
<view v-if="isFixed || !getStatusData(4, index)">{{ index + 1 }}</view>
<view v-if="!getStatusData(4, index)" class="tui-custom-desc"
:class="{ 'tui-lunar-unshow': !lunar && isFixed }">
{{ getDescText(index, startDate, endDate) }}
</view>
<text class="tui-iconfont tui-font-check" v-if="getStatusData(4, index)"></text>
</view>
<view class="tui-date-desc" :style="{ color: activeColor }"
v-if="!lunar && type == 2 && startDate == `${year}-${month}-${index + 1}` && startDate != endDate">
{{ startText }}
</view>
<view class="tui-date-desc" :style="{ color: activeColor }"
v-if="!lunar && type == 2 && endDate == `${year}-${month}-${index + 1}`">{{ endText }}</view>
</view>
<view class="tui-bg-month">{{ month }}</view>
</view>
<view class="tui-calendar-op">
<view class="tui-calendar-result">
<text>{{ type == 1 ? activeDate : startDate }}</text>
<text v-if="endDate">{{ endDate }}</text>
</view>
<view class="tui-calendar-btn_box">
<tui-button :type="btnType" height="72rpx" shape="circle" :size="28" :disabled="disabled"
@click="btnFix(false)">确定
</tui-button>
</view>
</view>
</view>
<view class="tui-popup-mask" :class="[isShow ? 'tui-mask-show' : '']" @tap="hide"></view>
</view>
<view v-else>
<view class="tui-date-box">
<view class="tui-iconfont tui-font-arrowleft" :style="{ color: yearArrowColor }" hover-class="tui-opacity"
:hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(0)"></view>
<view class="tui-iconfont tui-font-arrowleft" :style="{ color: monthArrowColor }" hover-class="tui-opacity"
:hover-stay-time="150" @tap="changeMonth(0)"></view>
<view class="tui-date_time">{{ showTitle }}</view>
<view class="tui-iconfont tui-font-arrowright" :style="{ color: monthArrowColor }" hover-class="tui-opacity"
:hover-stay-time="150" @tap="changeMonth(1)"></view>
<view class="tui-iconfont tui-font-arrowright" :style="{ color: yearArrowColor }" hover-class="tui-opacity"
:hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(1)"></view>
</view>
<view class="tui-date-header">
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
<view class="tui-date"></view>
</view>
<view class="tui-date-content" :style="{ height: isFixed && fixedHeight ? dateHeight * 6 + 'px' : 'auto' }">
<block v-for="(item, index) in weekdayArr" :key="index">
<view class="tui-date"></view>
</block>
<view class="tui-date" :class="{
'tui-date-pd_0': isFixed && fixedHeight,
'tui-opacity': openDisAbled(year, month, index + 1),
'tui-start-date': (type == 2 && startDate == `${year}-${month}-${index + 1}`) || type == 1,
'tui-end-date': (type == 2 && endDate == `${year}-${month}-${index + 1}`) || type == 1
}" :style="{ backgroundColor: isFixed ? getColor(index, 1) : 'transparent', height: isFixed && fixedHeight ? dateHeight + 'px' : 'auto' }"
v-for="(item, index) in daysArr" :key="index" @tap="dateClick(index)">
<view class="tui-date-text"
:style="{ color: isFixed ? getColor(index, 2) : getStatusData(3, index), backgroundColor: getStatusData(2, index) }">
<view v-if="isFixed || !getStatusData(4, index)">{{ index + 1 }}</view>
<view v-if="!getStatusData(4, index)" class="tui-custom-desc"
:class="{ 'tui-lunar-unshow': !lunar && isFixed }">
{{ getDescText(index, startDate, endDate) }}
</view>
<text class="tui-iconfont tui-font-check" v-if="getStatusData(4, index)"></text>
</view>
<view class="tui-date-desc" :style="{ color: activeColor }"
v-if="!lunar && type == 2 && startDate == `${year}-${month}-${index + 1}` && startDate != endDate">
{{ startText }}
</view>
<view class="tui-date-desc" :style="{ color: activeColor }"
v-if="!lunar && type == 2 && endDate == `${year}-${month}-${index + 1}`">{{ endText }}</view>
</view>
<view class="tui-bg-month">{{ month }}</view>
</view>
</view>
</template>
<script>
//easycom
// import tuiButton from "../tui-button/tui-button"
import calendar from './tui-calendar.js';
export default {
name: 'tuiCalendar',
emits: ['hide', 'change'],
// components:{
// tuiButton
// },
props: {
//1- 2-
arrowType: {
type: [Number, String],
default: 1
},
//1- 2-+
type: {
type: Number,
default: 1
},
//
maxYear: {
type: Number,
default: 2030
},
//
minYear: {
type: Number,
default: 1920
},
//()
minDate: {
type: String,
default: '1920-01-01'
},
/**
* 最大可选日期
* 默认最大值为今天之后的日期不可选
* 2030-12-31
* */
maxDate: {
type: String,
default: ''
},
//
radius: {
type: Boolean,
default: true
},
// index=>day
/**
* [{
* text:"", 描述2字以内
* value:"",状态值
* bgColor:"",背景色
* color:"" 文字颜色,
* check:false //
*
}]
*
* **/
status: {
type: Array,
default () {
return [];
}
},
//
monthArrowColor: {
type: String,
default: '#999'
},
//
yearArrowColor: {
type: String,
default: '#bcbcbc'
},
//
color: {
type: String,
default: '#333'
},
//|
activeBgColor: {
type: String,
default: '#5677fc'
},
//|
activeColor: {
type: String,
default: '#fff'
},
//
rangeBgColor: {
type: String,
default: 'rgba(86,119,252,0.1)'
},
//
rangeColor: {
type: String,
default: '#5677fc'
},
//type=2
startText: {
type: String,
default: '开始'
},
//type=2
endText: {
type: String,
default: '结束'
},
//
btnType: {
type: String,
default: 'primary'
},
//
isFixed: {
type: Boolean,
default: false
},
//isFixed=true
fixedHeight: {
type: Boolean,
default: true
},
//
isActiveCurrent: {
type: Boolean,
default: true
},
// type=1
isChange: {
type: Boolean,
default: false
},
//
lunar: {
type: Boolean,
default: false
},
// 2020-06-06 2020/06/06 type=1 or 2
initStartDate: {
type: String,
default: ''
},
// 2020-06-06 2020/06/06type=2
initEndDate: {
type: String,
default: ''
}
},
data() {
return {
isShow: false,
weekday: 1, // ,1-7
weekdayArr: [],
days: 0, //
daysArr: [],
showTitle: '',
year: 2020,
month: 0,
day: 0,
startYear: 0,
startMonth: 0,
startDay: 0,
endYear: 0,
endMonth: 0,
endDay: 0,
today: '',
activeDate: '',
startDate: '',
endDate: '',
isStart: true,
min: null,
max: null,
dateHeight: 20
};
},
computed: {
dataChange() {
return `${this.type}-${this.minDate}-${this.maxDate}-${this.initStartDate}-${this.initEndDate}`;
},
disabled() {
return this.type == 2 && (!this.startDate || !this.endDate)
}
},
watch: {
dataChange(val) {
this.init();
},
fixedHeight(val) {
if (val) {
this.initDateHeight();
}
}
},
created() {
this.init();
},
methods: {
getColor(index, type) {
let color = type == 1 ? '' : this.color;
let day = index + 1;
let date = `${this.year}-${this.month}-${day}`;
let timestamp = new Date(date.replace(/\-/g, '/')).getTime();
let start = this.startDate.replace(/\-/g, '/');
let end = this.endDate.replace(/\-/g, '/');
if ((this.isActiveCurrent && this.activeDate == date) || this.startDate == date || this.endDate == date) {
color = type == 1 ? this.activeBgColor : this.activeColor;
} else if (this.endDate && timestamp > new Date(start).getTime() && timestamp < new Date(end).getTime()) {
color = type == 1 ? this.rangeBgColor : this.rangeColor;
}
return color;
},
//
getStatusData(type, index) {
//1-text,2-bgColor,3-color 4-check
let val = ['', 'transparent', '#333', ''][type - 1];
if (!this.isFixed && this.status && this.status.length > 0) {
let item = this.status[index];
if (item) {
switch (type) {
case 1:
val = item.text;
break;
case 2:
val = item.bgColor;
break;
case 3:
val = item.color;
break;
case 4:
val = item.check;
break;
default:
break;
}
}
}
return val;
},
getDescText(index, startDate, endDate) {
let text = this.lunar ? this.getLunar(this.year, this.month, index + 1) : '';
if (this.isFixed && this.type == 2) {
//
if (this.lunar) {
let date = `${this.year}-${this.month}-${index + 1}`;
if (startDate == date && startDate != endDate) {
text = this.startText;
} else if (endDate == date) {
text = this.endText;
}
}
} else {
let status = this.getStatusData(1, index);
if (status) text = status;
}
return text;
},
getLunar(year, month, day) {
let obj = calendar.solar2lunar(year, month, day);
return obj.IDayCn;
},
initDateHeight() {
if (this.fixedHeight && this.isFixed) {
this.dateHeight = uni.getSystemInfoSync().windowWidth / 7;
}
},
init() {
this.initDateHeight();
let now = new Date();
this.year = now.getFullYear();
this.month = now.getMonth() + 1;
this.day = now.getDate();
this.today = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
this.activeDate = this.today;
this.min = this.initDate(this.minDate);
this.max = this.initDate(this.maxDate || this.today);
this.startDate = '';
this.startYear = 0;
this.startMonth = 0;
this.startDay = 0;
if (this.initStartDate) {
let start = new Date(this.initStartDate.replace(/\-/g, '/'));
if (this.type == 1) {
this.year = start.getFullYear();
this.month = start.getMonth() + 1;
this.day = start.getDate();
this.activeDate = `${start.getFullYear()}-${start.getMonth() + 1}-${start.getDate()}`;
} else {
this.startDate = `${start.getFullYear()}-${start.getMonth() + 1}-${start.getDate()}`;
this.startYear = start.getFullYear();
this.startMonth = start.getMonth() + 1;
this.startDay = start.getDate();
this.activeDate = '';
}
}
this.endYear = 0;
this.endMonth = 0;
this.endDay = 0;
this.endDate = '';
if (this.initEndDate && this.type == 2) {
let end = new Date(this.initEndDate.replace(/\-/g, '/'));
this.endDate = `${end.getFullYear()}-${end.getMonth() + 1}-${end.getDate()}`;
this.endYear = end.getFullYear();
this.endMonth = end.getMonth() + 1;
this.endDay = end.getDate();
this.activeDate = '';
this.year = end.getFullYear();
this.month = end.getMonth() + 1;
this.day = end.getDate();
}
this.isStart = true;
this.changeData();
},
//
initDate(date) {
let fdate = date.split('-');
return {
year: Number(fdate[0] || 1920),
month: Number(fdate[1] || 1),
day: Number(fdate[2] || 1)
};
},
openDisAbled: function(year, month, day) {
let bool = true;
let date = `${year}/${month}/${day}`;
// let today = this.today.replace(/\-/g, '/');
let min = `${this.min.year}/${this.min.month}/${this.min.day}`;
let max = `${this.max.year}/${this.max.month}/${this.max.day}`;
let timestamp = new Date(date).getTime();
if (timestamp >= new Date(min).getTime() && timestamp <= new Date(max).getTime()) {
bool = false;
}
return bool;
},
generateArray: function(start, end) {
return Array.from(new Array(end + 1).keys()).slice(start);
},
formatNum: function(num) {
return num < 10 ? '0' + num : num + '';
},
stop() {
return false;
},
//
getMonthDay(year, month) {
let days = new Date(year, month, 0).getDate();
return days;
},
getWeekday(year, month) {
let date = new Date(`${year}/${month}/01 00:00:00`);
return date.getDay();
},
checkRange(year) {
let overstep = false;
if (year < this.minYear || year > this.maxYear) {
uni.showToast({
title: '日期超出范围啦~',
icon: 'none'
});
overstep = true;
}
return overstep;
},
changeMonth(isAdd) {
if (isAdd) {
let month = this.month + 1;
let year = month > 12 ? this.year + 1 : this.year;
if (!this.checkRange(year)) {
this.month = month > 12 ? 1 : month;
this.year = year;
this.changeData();
}
} else {
let month = this.month - 1;
let year = month < 1 ? this.year - 1 : this.year;
if (!this.checkRange(year)) {
this.month = month < 1 ? 12 : month;
this.year = year;
this.changeData();
}
}
},
changeYear(isAdd) {
let year = isAdd ? this.year + 1 : this.year - 1;
if (!this.checkRange(year)) {
this.year = year;
this.changeData();
}
},
changeData() {
this.days = this.getMonthDay(this.year, this.month);
this.daysArr = this.generateArray(1, this.days);
this.weekday = this.getWeekday(this.year, this.month);
this.weekdayArr = this.generateArray(1, this.weekday);
this.showTitle = `${this.year}${this.month}`;
if (this.isChange && this.type == 1) {
this.btnFix(true);
}
},
dateClick: function(day) {
day += 1;
if (!this.openDisAbled(this.year, this.month, day)) {
this.day = day;
let date = `${this.year}-${this.month}-${day}`;
if (this.type == 1) {
this.activeDate = date;
} else {
let compare = new Date(date.replace(/\-/g, '/')).getTime() < new Date(this.startDate.replace(
/\-/g, '/')).getTime();
if (this.isStart || compare) {
this.startDate = date;
this.startYear = this.year;
this.startMonth = this.month;
this.startDay = this.day;
this.endYear = 0;
this.endMonth = 0;
this.endDay = 0;
this.endDate = '';
this.activeDate = '';
this.isStart = false;
} else {
this.endDate = date;
this.endYear = this.year;
this.endMonth = this.month;
this.endDay = this.day;
this.isStart = true;
}
}
if (!this.isFixed) {
this.btnFix();
}
}
},
show() {
this.isShow = true;
},
hide() {
this.isShow = false;
this.$emit('hide', {})
},
getWeekText(date) {
date = new Date(`${date.replace(/\-/g, '/')} 00:00:00`);
let week = date.getDay();
return '星期' + ['日', '一', '二', '三', '四', '五', '六'][week];
},
btnFix(show) {
if (!show) {
this.hide();
}
if (this.type == 1) {
let arr = this.activeDate.split('-');
let year = this.isChange ? this.year : Number(arr[0]);
let month = this.isChange ? this.month : Number(arr[1]);
let day = this.isChange ? this.day : Number(arr[2]);
//
let days = this.getMonthDay(year, month);
let result = `${year}-${this.formatNum(month)}-${this.formatNum(day)}`;
let weekText = this.getWeekText(result);
let isToday = false;
if (`${year}-${month}-${day}` == this.today) {
//
isToday = true;
}
let lunar = calendar.solar2lunar(year, month, day);
this.$emit('change', {
year: year,
month: month,
day: day,
days: days,
result: result,
week: weekText,
isToday: isToday,
switch: show, //
lunar: lunar
});
} else {
if (!this.startDate || !this.endDate) return;
let startMonth = this.formatNum(this.startMonth);
let startDay = this.formatNum(this.startDay);
let startDate = `${this.startYear}-${startMonth}-${startDay}`;
let startWeek = this.getWeekText(startDate);
let startLunar = calendar.solar2lunar(this.startYear, startMonth, startDay);
let endMonth = this.formatNum(this.endMonth);
let endDay = this.formatNum(this.endDay);
let endDate = `${this.endYear}-${endMonth}-${endDay}`;
let endWeek = this.getWeekText(endDate);
let endLunar = calendar.solar2lunar(this.endYear, endMonth, endDay);
this.$emit('change', {
startYear: this.startYear,
startMonth: this.startMonth,
startDay: this.startDay,
startDate: startDate,
startWeek: startWeek,
startLunar: startLunar,
endYear: this.endYear,
endMonth: this.endMonth,
endDay: this.endDay,
endDate: endDate,
endWeek: endWeek,
endLunar: endLunar
});
}
}
}
};
</script>
<style scoped>
@font-face {
font-family: 'tuiDateFont';
src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAVgAA0AAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAFRAAAABoAAAAci0/w50dERUYAAAUkAAAAHgAAAB4AKQANT1MvMgAAAaAAAABDAAAAVjxuSNNjbWFwAAAB+AAAAEoAAAFS5iPQt2dhc3AAAAUcAAAACAAAAAj//wADZ2x5ZgAAAlQAAAFHAAABvPf29TBoZWFkAAABMAAAADAAAAA2GMsN3WhoZWEAAAFgAAAAHQAAACQHjAOFaG10eAAAAeQAAAATAAAAFgzQAPJsb2NhAAACRAAAABAAAAAQAOoBSG1heHAAAAGAAAAAHgAAACABEwA3bmFtZQAAA5wAAAFJAAACiCnmEVVwb3N0AAAE6AAAADQAAABLUwjqHHjaY2BkYGAAYp5Gj5/x/DZfGbhZGEDg1tUn7+F00P/LzOuY9YFcDgYmkCgAa0gNlHjaY2BkYGBu+N/AEMPCAALM6xgYGVABCwBT4AMaAAAAeNpjYGRgYGBn0GZgYgABEMkFhAwM/8F8BgANaAFLAAB42mNgZGFgnMDAysDA1Ml0hoGBoR9CM75mMGLkAIoysDIzYAUBaa4pDA7PGJ49ZG7438AQw9zA0AAUZgTJAQDrcAy8AHjaY2GAABYIDgLCBQx1AAcEAc8AeNpjYGBgZoBgGQZGBhDwAfIYwXwWBgMgzQGETAwMzxifcTx7+P8/kMUAYUkxS/6VVIXqAgNGNgY4lxGoB6QPBTAyDHsAADDkDYkAAAAAAAAAAAAAADQAagC2AN542m2QsU7DMBCG/Tt1bNPUiUnkSgiVtqKpxJAgVLVbeAa6MaK+B4JXgJWBjY21UtW5gpkdMTFX7dzApaJLhXU6n8+n//ttxtn458N79XJWZ8eMxS00C4wy9A1EP8PQncAlIQzS4WgsVtPpSmwzV3OFRqLetH5TSQMK939X61ptPZ2p2EAttNMLBRMrtschQblDeS34aY50cIkCzg/B2Y5C+VpyQxhFkRgu515O8jvU5mmPM2O0wJ5Z27vhX+yMsV437WvCdTM+GI40MgwKfuGammC0uURqeqFMfe9cxaJclkt5GMaB1hIR1VobOgpEiKq+sLZcIrJWhO3/Jw7qWlYj1Jf21FaCtmd5bevrlk28O/7A4spXTl4KTh9MTlqQ8PESBRstReic+sRj0Dni9fIqmNS/pXNWCvWOeYBmx5S9Bsn9Ah+5WtAAeNp9kD1OAzEQhZ/zByQSQiCoXVEA2vyUKRMp9Ailo0g23pBo1155nUg5AS0VB6DlGByAGyDRcgpelkmTImvt6PObmeexAZzjGwr/3yXuhBWO8ShcwREy4Sr1F+Ea+V24jhY+hRvUf4SbuFUD4RYu1BsdVO2Eu5vSbcsKZxgIV3CKJ+Eq9ZVwjfwqXMcVPoQb1L+EmxjjV7iFa2WpDOFhMEFgnEFjig3jAjEcLJIyBtahOfRmEsxMTzd6ETubOBso71dilwMeaDnngCntPbdmvkon/mDLgdSYbh4FS7YpjS4idCgbXyyc1d2oc7D9nu22tNi/a4E1x+xRDWzU/D3bM9JIbAyvkJI18jK3pBJTj2hrrPG7ZynW814IiU68y/SIx5o0dTr3bmniwOLn8owcfbS5kj33qBw+Y1kIeb/dTsQgil2GP5PYcRkAAAB42mNgYoAALjDJyIAO2MGiTIxMjMyMLIys7GmJeRmlmWZQ2pQ5OSORLaU0Mz2/FACDfwlbAAAAAf//AAIAAQAAAAwAAAAWAAAAAgABAAMABgABAAQAAAACAAAAAHjaY2BgYGQAgqtL1DlA9K2rT97DaABNlwiuAAA=) format('woff');
font-weight: normal;
font-style: normal;
}
.tui-iconfont {
font-family: 'tuiDateFont' !important;
font-size: 36rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.tui-font-close:before {
content: '\e608';
}
.tui-font-check:before {
content: '\e6e1';
}
.tui-font-arrowright:before {
content: '\e600';
}
.tui-font-arrowleft:before {
content: '\e601';
}
.tui-date-box {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx 0 30rpx;
background-color: #fff;
}
.tui-calendar-radius {
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
overflow: hidden;
}
.tui-date_time {
padding: 0 16rpx;
color: #333;
font-size: 32rpx;
line-height: 32rpx;
font-weight: bold;
}
.tui-font-arrowleft {
margin-right: 32rpx;
}
.tui-font-arrowright {
margin-left: 32rpx;
}
.tui-date-header {
width: 100%;
display: flex;
align-items: center;
background-color: #fff;
font-size: 24rpx;
line-height: 24rpx;
color: #555;
box-shadow: 0 15rpx 20rpx -15rpx #efefef;
position: relative;
z-index: 2;
}
.tui-date-content {
width: 100%;
display: flex;
flex-wrap: wrap;
padding: 12rpx 0;
box-sizing: border-box;
background-color: #fff;
position: relative;
}
.tui-flex-start {
align-content: flex-start;
}
.tui-bg-month {
position: absolute;
font-size: 260rpx;
line-height: 260rpx;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: #f5f5f7;
z-index: 1;
}
.tui-date {
width: 14.2857%;
display: flex;
align-items: center;
justify-content: center;
padding: 12rpx 0;
overflow: hidden;
position: relative;
z-index: 2;
}
.tui-date-pd_0 {
padding: 0 !important;
}
.tui-start-date {
border-top-left-radius: 8rpx;
border-bottom-left-radius: 8rpx;
}
.tui-end-date {
border-top-right-radius: 8rpx;
border-bottom-right-radius: 8rpx;
}
.tui-date-text {
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
font-size: 32rpx;
line-height: 32rpx;
position: relative;
border-radius: 50%;
}
.tui-btn-calendar {
padding: 16rpx;
box-sizing: border-box;
text-align: center;
text-decoration: none;
}
.tui-opacity {
opacity: 0.5;
}
.tui-bottom-popup {
width: 100%;
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
visibility: hidden;
transform: translate3d(0, 100%, 0);
transform-origin: center;
transition: all 0.3s ease-in-out;
min-height: 20rpx;
}
.tui-popup-show {
transform: translate3d(0, 0, 0);
visibility: visible;
}
.tui-popup-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 9996;
transition: all 0.3s ease-in-out;
opacity: 0;
visibility: hidden;
}
.tui-mask-show {
opacity: 1;
visibility: visible;
}
.tui-calendar-header {
width: 100%;
height: 80rpx;
padding: 0 40rpx;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
font-size: 30rpx;
background-color: #fff;
color: #555;
position: relative;
}
.tui-font-close {
position: absolute;
right: 30rpx;
top: 50%;
transform: translateY(-50%);
color: #999;
}
.tui-btn-calendar {
padding: 16rpx;
box-sizing: border-box;
text-align: center;
text-decoration: none;
}
.tui-font-check {
color: #fff;
font-size: 54rpx;
line-height: 54rpx;
}
.tui-custom-desc {
width: 100%;
font-size: 24rpx;
line-height: 24rpx;
transform: scale(0.8);
transform-origin: center center;
text-align: center;
}
.tui-lunar-unshow {
position: absolute;
left: 0;
bottom: 8rpx;
z-index: 2;
}
.tui-date-desc {
width: 100%;
font-size: 24rpx;
line-height: 24rpx;
position: absolute;
left: 0;
transform: scale(0.8);
transform-origin: center center;
text-align: center;
bottom: 8rpx;
z-index: 2;
}
.tui-calendar-op {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: #fff;
padding: 0 42rpx 30rpx;
box-sizing: border-box;
font-size: 24rpx;
color: #666;
}
.tui-calendar-result {
height: 48rpx;
transform: scale(0.9);
transform-origin: center 100%;
}
.tui-calendar-btn_box {
width: 100%;
}
</style>

View File

@ -0,0 +1,212 @@
<template>
<view class="tui-card-class tui-card" :class="[full?'tui-card-full':'',border?'tui-card-border':'']" @tap="handleClick"
@longtap="longTap">
<view class="tui-card-header" :class="{'tui-header-line':header.line}" :style="{background:header.bgcolor || '#fff'}">
<view class="tui-header-left">
<image :src="image.url" class="tui-header-thumb" :class="{'tui-thumb-circle':image.circle}" mode="widthFix" v-if="image.url"
:style="{height:(image.height || 60)+'rpx',width:(image.width || 60)+'rpx'}"></image>
<text class="tui-header-title" :style="{fontSize:(title.size || 30)+'rpx',color:(title.color || '#7A7A7A')}" v-if="title.text">{{title.text}}</text>
</view>
<view class="tui-header-right" :style="{fontSize:(tag.size || 24)+'rpx',color:(tag.color || '#b2b2b2')}" v-if="tag.text">
{{tag.text}}
</view>
</view>
<view class="tui-card-body">
<slot name="body"></slot>
</view>
<view class="tui-card-footer">
<slot name="footer"></slot>
</view>
</view>
</template>
<script>
export default {
name: "tuiCard",
emits: ['click','longclick'],
props: {
//
full: {
type: Boolean,
default: false
},
image: {
type: Object,
default: function() {
return {
url: "", //
height: 60, //
width: 60, //
circle: false
}
}
},
//
title: {
type: Object,
default: function() {
return {
text: "", //
size: 30, //
color: "#7A7A7A" //
}
}
},
//
tag: {
type: Object,
default: function() {
return {
text: "", //
size: 24, //
color: "#b2b2b2" //
}
}
},
header: {
type: Object,
default: function() {
return {
bgcolor: "#fff", //
line: false //线
}
}
},
//
border: {
type: Boolean,
default: false
},
index: {
type: Number,
default: 0
}
},
methods: {
handleClick() {
this.$emit('click', {
index: this.index
});
},
longTap() {
this.$emit('longclick', {
index: this.index
});
}
}
}
</script>
<style scoped>
.tui-card {
margin: 0 30rpx;
font-size: 28rpx;
background-color: #fff;
border-radius: 10rpx;
box-shadow: 0 0 10rpx #eee;
box-sizing: border-box;
overflow: hidden;
}
.tui-card-full {
margin: 0 !important;
border-radius: 0 !important;
}
.tui-card-full::after {
border-radius: 0 !important;
}
.tui-card-border {
position: relative;
box-shadow: none !important
}
.tui-card-border::after {
content: ' ';
position: absolute;
height: 200%;
width: 200%;
border: 1px solid #ddd;
transform-origin: 0 0;
-webkit-transform-origin: 0 0;
-webkit-transform: scale(0.5);
transform: scale(0.5);
left: 0;
top: 0;
border-radius: 20rpx;
box-sizing: border-box;
pointer-events: none;
}
.tui-card-header {
width: 100%;
padding: 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
box-sizing: border-box;
overflow: hidden;
border-top-left-radius: 10rpx;
border-top-right-radius: 10rpx;
}
.tui-card-header::after {
content: '';
position: absolute;
border-bottom: 1rpx solid #eaeef1;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
bottom: 0;
right: 0;
left: 0;
pointer-events: none;
}
.tui-header-line::after {
border-bottom: 0 !important;
}
.tui-header-thumb {
height: 60rpx;
width: 60rpx;
vertical-align: middle;
margin-right: 20rpx;
border-radius: 6rpx;
}
.tui-thumb-circle {
border-radius: 50% !important;
}
.tui-header-title {
display: inline-block;
font-size: 30rpx;
color: #7a7a7a;
vertical-align: middle;
max-width: 460rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.tui-header-right {
font-size: 24rpx;
color: #b2b2b2;
}
.tui-card-body {
font-size: 32rpx;
color: #262b3a;
box-sizing: border-box;
}
.tui-card-footer {
font-size: 28rpx;
color: #596d96;
border-bottom-left-radius: 10rpx;
border-bottom-right-radius: 10rpx;
box-sizing: border-box;
}
</style>

View File

@ -0,0 +1,513 @@
<template>
<view class="tui-cascade-selection">
<scroll-view scroll-x scroll-with-animation :scroll-into-view="scrollViewId"
:style="{ backgroundColor: headerBgColor }" class="tui-bottom-line"
:class="{ 'tui-btm-none': !headerLine }">
<view class="tui-selection-header" :style="{ height: tabsHeight, backgroundColor: backgroundColor }">
<view class="tui-header-item" :class="{ 'tui-font-bold': idx === currentTab && bold }"
:style="{ color: idx === currentTab ? activeColor : color, fontSize: size + 'rpx' }"
:id="`id_${idx}`" @tap.stop="swichNav" :data-current="idx" v-for="(item, idx) in selectedArr"
:key="idx">
{{ item.text }}
<view class="tui-active-line" :style="{ backgroundColor: lineColor }"
v-if="idx === currentTab && showLine"></view>
</view>
</view>
</scroll-view>
<swiper class="tui-selection-list" :current="currentTab" duration="300" @change="switchTab"
:style="{ height: height, backgroundColor: backgroundColor }">
<swiper-item v-for="(item, index) in selectedArr" :key="index">
<scroll-view scroll-y :scroll-into-view="item.scrollViewId" class="tui-selection-item"
:style="{ height: height }">
<view class="tui-first-item" :style="{ height: firstItemTop }"></view>
<view class="tui-selection-cell" :style="{ padding: padding, backgroundColor: backgroundColor }"
:id="`id_${subIndex}`" v-for="(subItem, subIndex) in item.list" :key="subIndex"
@tap="change(index, subIndex, subItem)">
<icon type="success_no_circle" v-if="item.index === subIndex" :color="checkMarkColor"
:size="checkMarkSize" class="tui-icon-success"></icon>
<image :src="subItem.src" v-if="subItem.src" class="tui-cell-img"
:style="{ width: imgWidth, height: imgHeight, borderRadius: radius }"></image>
<view class="tui-cell-title"
:class="{ 'tui-font-bold': item.index === subIndex && textBold, 'tui-flex-shrink': nowrap }"
:style="{ color: item.index === subIndex ? textActiveColor : textColor, fontSize: textSize + 'rpx' }">
{{ subItem.text }}
</view>
<view class="tui-cell-sub_title" :style="{ color: subTextColor, fontSize: subTextSize + 'rpx' }"
v-if="subItem.subText">{{ subItem.subText }}</view>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
</template>
<script>
export default {
name: 'tuiCascadeSelection',
emits: ['change','complete'],
props: {
/**
* 如果下一级是请求返回则为第一级数据否则所有数据
* 数据格式
[{
src: "",
text: "",
subText: "",
value: 0,
children:[{
text: "",
subText: "",
value: 0,
children:[]
}]
}]
* */
itemList: {
type: Array,
default: () => {
return [];
}
},
/*
初始化默认选中数据
[{
text: "",//text
subText: '',//subText
value: '',//value
src: '', //src
index: 0, //layer
list: [{src: "", text: "", subText: "", value: 101}] //layer
}];
*/
defaultItemList: {
type: Array,
value: []
},
//header线
headerLine: {
type: Boolean,
default: true
},
//header
headerBgColor: {
type: String,
default: '#FFFFFF'
},
//
tabsHeight: {
type: String,
default: '88rpx'
},
//
text: {
type: String,
default: '请选择'
},
//tabs
size: {
type: Number,
default: 28
},
//tabs
color: {
type: String,
default: '#555'
},
//
activeColor: {
type: String,
default: '#5677fc'
},
//
bold: {
type: Boolean,
default: true
},
//线
showLine: {
type: Boolean,
default: true
},
//线
lineColor: {
type: String,
default: '#5677fc'
},
//icon
checkMarkSize: {
type: Number,
default: 15
},
//icon
checkMarkColor: {
type: String,
default: '#5677fc'
},
//item
imgWidth: {
type: String,
default: '40rpx'
},
//item
imgHeight: {
type: String,
default: '40rpx'
},
//
radius: {
type: String,
default: '50%'
},
//item text
textColor: {
type: String,
default: '#333'
},
textActiveColor: {
type: String,
default: '#333'
},
//
textBold: {
type: Boolean,
default: true
},
//item text
textSize: {
type: Number,
default: 28
},
//text
nowrap: {
type: Boolean,
default: false
},
//item subText
subTextColor: {
type: String,
default: '#999'
},
//item subText
subTextSize: {
type: Number,
default: 24
},
// item padding
padding: {
type: String,
default: '20rpx 30rpx'
},
//
firstItemTop: {
type: String,
default: '20rpx'
},
//swiper
height: {
type: String,
default: '300px'
},
//item swiper
backgroundColor: {
type: String,
default: '#FFFFFF'
},
//false
request: {
type: Boolean,
default: false
},
//request=true
receiveData: {
type: Array,
default: () => {
return [];
}
},
//
reset: {
type: [Number, String],
default: 0
}
},
watch: {
itemList(val) {
this.initData(val, -1);
},
receiveData(val) {
this.subLevelData(val, this.currentTab);
},
reset() {
this.initData(this.itemList, -1);
},
defaultItemList(val) {
this.setDefaultData(val)
}
},
created() {
this.setDefaultData(this.defaultItemList)
},
data() {
return {
currentTab: 0,
//tabscrollview
scrollViewId: 'id__1',
selectedArr: []
};
},
methods: {
setDefaultData(val) {
let defaultItemList = val || [];
if (defaultItemList.length > 0) {
defaultItemList.map(item => {
item.scrollViewId = `id_${item.index}`;
});
this.selectedArr = defaultItemList;
this.currentTab = defaultItemList.length - 1;
this.$nextTick(() => {
this.checkCor();
});
} else {
this.initData(this.itemList, -1);
}
},
initData(data, layer) {
if (!data || data.length === 0) return;
if (this.request) {
//
this.subLevelData(data, layer);
} else {
let selectedValue = this.selectedValue || {};
if (selectedValue.type) {
this.setDefaultData(selectedValue);
} else {
this.subLevelData(this.getItemList(layer, -1), layer);
}
}
},
removeChildren(data) {
let list = data.map(item => {
delete item['children'];
return item;
});
return list;
},
getItemList(layer, index) {
let list = [];
let arr = JSON.parse(JSON.stringify(this.itemList));
if (layer == -1) {
list = this.removeChildren(arr);
} else {
let value = this.selectedArr[0].index;
value = value == -1 ? index : value;
list = arr[value].children || [];
if (layer > 0) {
for (let i = 1; i < layer + 1; i++) {
let val = layer === i ? index : this.selectedArr[i].index;
list = list[val].children || [];
if (list.length === 0) break;
}
}
list = this.removeChildren(list);
}
return list;
},
//
switchTab: function(e) {
this.currentTab = e.detail.current;
this.checkCor();
},
//
swichNav: function(e) {
let cur = e.currentTarget.dataset.current;
if (this.currentTab != cur) {
this.currentTab = cur;
}
},
checkCor: function() {
let item = this.selectedArr[this.currentTab];
item.scrollViewId = 'id__1';
this.$nextTick(() => {
setTimeout(() => {
let val = item.index < 2 ? 0 : Number(item.index - 2);
item.scrollViewId = `id_${val}`;
}, 2);
});
if (this.currentTab > 1) {
this.scrollViewId = `id_${this.currentTab - 1}`;
} else {
this.scrollViewId = `id_0`;
}
},
change(index, subIndex, subItem) {
let item = this.selectedArr[index];
if (item.index == subIndex) return;
item.index = subIndex;
item.text = subItem.text;
item.value = subItem.value;
item.subText = subItem.subText || '';
item.src = subItem.src || '';
this.$emit('change', {
layer: index,
subIndex: subIndex, //layer=> Array index
...subItem
});
if (!this.request) {
let data = this.getItemList(index, subIndex);
this.subLevelData(data, index);
}
},
//
subLevelData(data, layer) {
if (!data || data.length === 0) {
if (layer == -1) return;
//
let arr = this.selectedArr;
if (layer < arr.length - 1) {
let newArr = arr.slice(0, layer + 1);
this.selectedArr = newArr;
}
let result = JSON.parse(JSON.stringify(this.selectedArr));
let lastItem = result[result.length - 1] || {};
let text = '';
result.map(item => {
text += item.text;
delete item['list'];
//delete item['index'];
delete item['scrollViewId'];
return item;
});
this.$emit('complete', {
result: result,
value: lastItem.value,
text: text,
subText: lastItem.subText,
src: lastItem.src
});
} else {
// >layer
let item = [{
text: this.text,
subText: '',
value: '',
src: '',
index: -1,
scrollViewId: 'id__1',
list: data
}];
if (layer == -1) {
this.selectedArr = item;
} else {
let retainArr = this.selectedArr.slice(0, layer + 1);
this.selectedArr = retainArr.concat(item);
}
this.$nextTick(() => {
this.currentTab = this.selectedArr.length - 1;
});
}
}
}
};
</script>
<style scoped>
.tui-cascade-selection {
width: 100%;
box-sizing: border-box;
}
.tui-selection-header {
width: 100%;
display: flex;
align-items: center;
position: relative;
box-sizing: border-box;
}
.tui-bottom-line {
position: relative;
}
.tui-bottom-line::after {
width: 100%;
content: '';
position: absolute;
border-bottom: 1rpx solid #eaeef1;
-webkit-transform: scaleY(0.5) translateZ(0);
transform: scaleY(0.5) translateZ(0);
transform-origin: 0 100%;
bottom: 0;
right: 0;
left: 0;
}
.tui-btm-none::after {
border-bottom: 0 !important;
}
.tui-header-item {
max-width: 240rpx;
padding: 15rpx 30rpx;
box-sizing: border-box;
flex-shrink: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
position: relative;
}
.tui-font-bold {
font-weight: bold;
}
.tui-active-line {
width: 60rpx;
height: 6rpx;
border-radius: 4rpx;
position: absolute;
bottom: 0;
right: 0;
left: 50%;
transform: translateX(-50%);
}
.tui-selection-cell {
width: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
}
.tui-icon-success {
margin-right: 12rpx;
}
.tui-cell-img {
margin-right: 12rpx;
flex-shrink: 0;
}
.tui-cell-title {
word-break: break-all;
}
.tui-flex-shrink {
flex-shrink: 0;
}
.tui-font-bold {
font-weight: bold;
}
.tui-cell-sub_title {
margin-left: 20rpx;
word-break: break-all;
}
.tui-first-item {
width: 100%;
}
</style>

View File

@ -0,0 +1,265 @@
<template>
<view class="tui-circular-container" :style="{ width: diam + 'px', height: (height || diam) + 'px' }">
<canvas
class="tui-circular-default"
:canvas-id="defaultCanvasId"
:id="defaultCanvasId"
:style="{ width: diam + 'px', height: (height || diam) + 'px' }"
v-if="defaultShow"
></canvas>
<canvas class="tui-circular-progress" :canvas-id="progressCanvasId" :id="progressCanvasId" :style="{ width: diam + 'px', height: (height || diam) + 'px' }"></canvas>
<slot />
</view>
</template>
<script>
export default {
name: 'tuiCircularProgress',
emits: ['change','end'],
props: {
/*
传值需使用rpx进行转换保证各终端兼容
px = rpx / 750 * wx.getSystemInfoSync().windowWidth
圆形进度条(画布)宽度直径 [px]
*/
diam: {
type: Number,
default: 60
},
//()diam[heightheight]
height: {
type: Number,
default: 0
},
//线[px]
lineWidth: {
type: Number,
default: 4
},
/*
线条的端点样式
butt向线条的每个末端添加平直的边缘
round 向线条的每个末端添加圆形线帽
square 向线条的每个末端添加正方形线帽
*/
lineCap: {
type: String,
default: 'round'
},
// [px]
fontSize: {
type: Number,
default: 12
},
//
fontColor: {
type: String,
default: '#5677fc'
},
//
fontShow: {
type: Boolean,
default: true
},
/*
自定义显示文字[默认为空显示百分比fontShow=true时生效]
可以使用 slot自定义显示内容
*/
percentText: {
type: String,
default: ''
},
//()
defaultShow: {
type: Boolean,
default: true
},
//
defaultColor: {
type: String,
default: '#CCC'
},
//
progressColor: {
type: String,
default: '#5677fc'
},
//[progressColor使]
gradualColor: {
type: String,
default: ''
},
//
sAngle: {
type: Number,
default: -Math.PI / 2
},
//false
counterclockwise: {
type: Boolean,
default: false
},
// [10% 10]
percentage: {
type: Number,
default: 0
},
//[使100%2]
multiple: {
type: Number,
default: 1
},
//[50]
duration: {
type: Number,
default: 800
},
//backwards: forwards
activeMode: {
type: String,
default: 'backwards'
}
},
watch: {
percentage(val) {
this.initDraw();
}
},
data() {
return {
// #ifdef MP-WEIXIN
progressCanvasId: 'progressCanvasId',
defaultCanvasId: 'defaultCanvasId',
// #endif
// #ifndef MP-WEIXIN
progressCanvasId: this.getCanvasId(),
defaultCanvasId: this.getCanvasId(),
// #endif
progressContext: null,
linearGradient: null,
//
startPercentage: 0
// dpi
//pixelRatio: uni.getSystemInfoSync().pixelRatio
};
},
mounted() {
this.initDraw(true);
},
methods: {
//
initDraw(init) {
let start = this.activeMode === 'backwards' ? 0 : this.startPercentage;
start = start > this.percentage ? 0 : start;
if (this.defaultShow && init) {
this.drawDefaultCircular();
}
this.drawProgressCircular(start);
},
//()
drawDefaultCircular() {
let ctx = uni.createCanvasContext(this.defaultCanvasId, this);
ctx.setLineWidth(this.lineWidth);
ctx.setStrokeStyle(this.defaultColor);
//
let eAngle = Math.PI * (this.height ? 1 : 2) + this.sAngle;
this.drawArc(ctx, eAngle);
},
//
drawProgressCircular(startPercentage) {
let ctx = this.progressContext;
let gradient = this.linearGradient;
if (!ctx) {
ctx = uni.createCanvasContext(this.progressCanvasId, this);
//线 CanvasGradient
gradient = ctx.createLinearGradient(0, 0, this.diam, 0);
gradient.addColorStop('0', this.progressColor);
if (this.gradualColor) {
gradient.addColorStop('1', this.gradualColor);
}
// #ifdef APP-PLUS || MP
const res = uni.getSystemInfoSync();
if (!this.gradualColor && res.platform.toLocaleLowerCase() == 'android') {
gradient.addColorStop('1', this.progressColor);
}
// #endif
this.progressContext = ctx;
this.linearGradient = gradient;
}
ctx.setLineWidth(this.lineWidth);
ctx.setStrokeStyle(gradient);
let time = this.percentage == 0 || this.duration < 50 ? 0 : this.duration / this.percentage;
if (this.percentage > 0) {
startPercentage = this.duration < 50 ? this.percentage - 1 : startPercentage;
startPercentage++;
}
if (this.fontShow) {
ctx.setFontSize(this.fontSize);
ctx.setFillStyle(this.fontColor);
ctx.setTextAlign('center');
ctx.setTextBaseline('middle');
let percentage = this.percentText;
if (!percentage) {
percentage = this.counterclockwise ? 100 - startPercentage * this.multiple : startPercentage * this.multiple;
percentage = `${percentage}%`;
}
let radius = this.diam / 2;
ctx.fillText(percentage, radius, radius);
}
if (this.percentage == 0 || (this.counterclockwise && startPercentage == 100)) {
ctx.draw();
}else{
let eAngle = ((2 * Math.PI) / 100) * startPercentage + this.sAngle;
this.drawArc(ctx, eAngle);
}
setTimeout(() => {
this.startPercentage = startPercentage;
if (startPercentage == this.percentage) {
this.$emit('end', {
canvasId: this.progressCanvasId,
percentage: startPercentage
});
} else {
this.drawProgressCircular(startPercentage);
}
this.$emit('change', {
percentage: startPercentage
});
}, time);
// #ifdef H5
// requestAnimationFrame(()=>{})
// #endif
},
//线
drawArc(ctx, eAngle) {
ctx.setLineCap(this.lineCap);
ctx.beginPath();
let radius = this.diam / 2; //x=y
ctx.arc(radius, radius, radius - this.lineWidth, this.sAngle, eAngle, this.counterclockwise);
ctx.stroke();
ctx.draw();
},
//canvasId
getCanvasId() {
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16);
});
return uuid;
}
}
};
</script>
<style scoped>
.tui-circular-container,
.tui-circular-default {
position: relative;
}
.tui-circular-progress {
position: absolute;
left: 0;
top: 0;
z-index: 10;
}
</style>

View File

@ -0,0 +1,167 @@
<template>
<view class="tui-collapse" :style="{backgroundColor:bgColor}">
<view class="tui-collapse-head" :style="{backgroundColor:hdBgColor}" @tap.stop="handleClick">
<view class="tui-header" :class="{'tui-opacity':disabled}">
<slot name="title"></slot>
<view class="tui-collapse-icon tui-icon-arrow" :class="{'tui-icon-active':isOpen}" :style="{color:arrowColor}" v-if="arrow"></view>
</view>
</view>
<view class="tui-collapse-body_box" :style="{backgroundColor:bdBgColor,height:isOpen?height:'0rpx'}">
<view class="tui-collapse-body" :class="{'tui-collapse-transform':height=='auto','tui-collapse-body_show':isOpen && height=='auto'}">
<slot name="content"></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: "tuiCollapse",
emits: ['click'],
props: {
//collapse
bgColor: {
type: String,
default: 'transparent'
},
//collapse-head
hdBgColor: {
type: String,
default: '#fff'
},
//collapse-body
bdBgColor: {
type: String,
default: 'transparent'
},
//collapse-body open使
height: {
type: String,
default: 'auto'
},
//
index: {
type: Number,
default: 0
},
//index==current
current: {
type: Number,
default: -1
},
//
disabled: {
type: [Boolean, String],
default: false
},
//
arrow: {
type: [Boolean, String],
default: true
},
//
arrowColor: {
type: String,
default: "#333"
}
},
watch: {
current() {
this.updateCurrentChange()
}
},
created() {
this.updateCurrentChange()
},
data() {
return {
isOpen: false
};
},
methods: {
updateCurrentChange() {
this.isOpen = this.index == this.current
},
handleClick() {
if (this.disabled) return;
this.$emit("click", {
index: Number(this.index)
})
}
}
}
</script>
<style scoped>
@font-face {
font-family: 'tuiCollapse';
src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAQ4AA0AAAAABlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAEHAAAABoAAAAciRx3B0dERUYAAAP8AAAAHgAAAB4AKQAKT1MvMgAAAaAAAABCAAAAVjxuR/JjbWFwAAAB9AAAAD4AAAFCAA/pq2dhc3AAAAP0AAAACAAAAAj//wADZ2x5ZgAAAkAAAABEAAAARCs1U/toZWFkAAABMAAAADAAAAA2FpaT+mhoZWEAAAFgAAAAHQAAACQHngOFaG10eAAAAeQAAAAPAAAAEAwAAEBsb2NhAAACNAAAAAoAAAAKACIAAG1heHAAAAGAAAAAHwAAACABDwAdbmFtZQAAAoQAAAFJAAACiCnmEVVwb3N0AAAD0AAAACMAAAA1DunpUnjaY2BkYGAAYja/oO54fpuvDNwsDCBwc4/6fzjtwNDNfICpBMjlYGACiQIAGVAKZnjaY2BkYGBu+N/AEMPCAALMBxgYGVABCwBVNgMsAAAAeNpjYGRgYGBhEGQA0QwMTEDMBYQMDP/BfAYACnYBLQB42mNgZGFgnMDAysDA1Ml0hoGBoR9CM75mMGLkAIoysDIzYAUBaa4pDA7PGJ4xMDf8b2CIYW5gaAAKM4LkANq9C9sAAHjaY2GAABYIdgAAAMAATQB42mNgYGBmgGAZBkYGELAB8hjBfBYGBSDNAoRA/jOG//8hpBQzVCUDIxsDjMnAyAQkmBhQASPDsAcAMCAGoQAAAAAAAAAAAAAAIgAAAAEAQACLA8ACdAAQAAAlASYiBhQXARYyNwE2NCYiBwIA/oYNIBkMAZcNIA0BlwwZIA3uAXoMGSAN/mkMDAGXDSAZDAB42n2QPU4DMRCFn/MHJBJCIKhdUQDa/JQpEyn0CKWjSDbekGjXXnmdSDkBLRUHoOUYHIAbINFyCl6WSZMia+3o85uZ57EBnOMbCv/fJe6EFY7xKFzBETLhKvUX4Rr5XbiOFj6FG9R/hJu4VQPhFi7UGx1U7YS7m9JtywpnGAhXcIon4Sr1lXCN/CpcxxU+hBvUv4SbGONXuIVrZakM4WEwQWCcQWOKDeMCMRwskjIG1qE59GYSzExPN3oRO5s4GyjvV2KXAx5oOeeAKe09t2a+Sif+YMuB1JhuHgVLtimNLiJ0KBtfLJzV3ahzsP2e7ba02L9rgTXH7FENbNT8Pdsz0khsDK+QkjXyMrekElOPaGus8btnKdbzXgiJTrzL9IjHmjR1OvduaeLA4ufyjBx9tLmSPfeoHD5jWQh5v91OxCCKXYY/k9hxGQAAAHjaY2BigAAuMMnIgA5YwKJMjExciUVF+eW6KfnleQAZ0wQyAAAAAAH//wACAAEAAAAMAAAAFgAAAAIAAQADAAMAAQAEAAAAAgAAAAB42mNgYGBkAIKrS9Q5QPTNPer/YTQAQ+0HIAAA) format('woff');
font-weight: normal;
font-style: normal;
}
.tui-collapse-icon {
font-family: "tuiCollapse" !important;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.tui-icon-arrow:before {
content: "\e600";
}
.tui-icon-arrow {
font-size: 32rpx;
transform: rotate(0);
transform-origin: center center;
transition: all 0.3s;
position: absolute;
top: 50%;
margin-top: -8px;
right: 30rpx;
}
.tui-arrow-padding {
padding-right: 62rpx;
box-sizing: border-box;
}
.tui-icon-active {
transform: rotate(180deg);
transform-origin: center center;
}
.tui-header {
position: relative;
z-index: 2;
}
.tui-collapse-body_box{
transition: all 0.25s;
overflow: hidden;
}
.tui-collapse-body {
transition: all 0.25s;
overflow: hidden;
position: relative;
z-index: 1;
}
.tui-collapse-transform {
opacity: 0;
visibility: hidden;
-webkit-transform: translateY(-40%);
transform: translateY(-40%);
}
.tui-collapse-body_show {
opacity: 1;
visibility: visible;
-webkit-transform: translateY(0);
transform: translateY(0);
}
.tui-opacity {
opacity: 0.6;
}
</style>

View File

@ -0,0 +1,343 @@
<template>
<view class="tui-countdown-box">
<view class="tui-countdown-item" :style="{ background: backgroundColor, borderColor: borderColor, width: getWidth(d, width) + 'rpx', height: height + 'rpx' }" v-if="days">
<view class="tui-countdown-time" :class="[scale ? 'tui-countdown-scale' : '']" :style="{ fontSize: size + 'rpx', color: color, lineHeight: size + 'rpx' }">
{{ d }}
</view>
</view>
<view
class="tui-countdown-colon"
:class="{ 'tui-colon-pad': borderColor == 'transparent' }"
:style="{ lineHeight: colonSize + 'rpx', fontSize: colonSize + 'rpx', color: colonColor }"
v-if="days"
>
{{ isColon ? ':' : '天' }}
</view>
<view class="tui-countdown-item" :style="{ background: backgroundColor, borderColor: borderColor, width: getWidth(h, width) + 'rpx', height: height + 'rpx' }" v-if="hours">
<view class="tui-countdown-time" :class="[scale ? 'tui-countdown-scale' : '']" :style="{ fontSize: size + 'rpx', color: color, lineHeight: size + 'rpx' }">
{{ h }}
</view>
</view>
<view
class="tui-countdown-colon"
:class="{ 'tui-colon-pad': borderColor == 'transparent' }"
:style="{ lineHeight: colonSize + 'rpx', fontSize: colonSize + 'rpx', color: colonColor }"
v-if="hours"
>
{{ isColon ? ':' : '时' }}
</view>
<view
class="tui-countdown-item"
:style="{ background: backgroundColor, borderColor: borderColor, width: getWidth(i, width) + 'rpx', height: height + 'rpx' }"
v-if="minutes"
>
<view class="tui-countdown-time" :class="[scale ? 'tui-countdown-scale' : '']" :style="{ fontSize: size + 'rpx', color: color, lineHeight: size + 'rpx' }">
{{ i }}
</view>
</view>
<view
class="tui-countdown-colon"
:class="{ 'tui-colon-pad': borderColor == 'transparent' }"
:style="{ lineHeight: colonSize + 'rpx', fontSize: colonSize + 'rpx', color: colonColor }"
v-if="minutes"
>
{{ isColon ? ':' : '分' }}
</view>
<view
class="tui-countdown-item"
:style="{ background: backgroundColor, borderColor: borderColor, width: getWidth(s, width) + 'rpx', height: height + 'rpx' }"
v-if="seconds"
>
<view class="tui-countdown-time" :class="[scale ? 'tui-countdown-scale' : '']" :style="{ fontSize: size + 'rpx', color: color, lineHeight: size + 'rpx' }">
{{ s }}
</view>
</view>
<view
class="tui-countdown-colon"
:class="{ 'tui-colon-pad': borderColor == 'transparent' }"
:style="{ lineHeight: colonSize + 'rpx', fontSize: colonSize + 'rpx', color: colonColor }"
v-if="seconds && !isColon"
>
{{ unitEn ? 's' : '秒' }}
</view>
<view class="tui-countdown-colon" :style="{ lineHeight: colonSize + 'rpx', fontSize: colonSize + 'rpx', color: colonColor }" v-if="seconds && isMs && isColon">.</view>
<view
class="tui-countdown__ms"
:style="{
background: backgroundColor,
borderColor: borderColor,
fontSize: msSize + 'rpx',
color: msColor,
height: height + 'rpx',
width: msWidth > 0 ? msWidth + 'rpx' : 'auto'
}"
v-if="seconds && isMs"
>
<view :class="{ 'tui-ms__list': ani }">
<view class="tui-ms__item" :style="{ height: height + 'rpx' }" v-for="(item, index) in ms" :key="index">
<view :class="[scale ? 'tui-countdown-scale' : '']">{{item}}</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'tuiCountdown',
emits: ['end','time'],
props: {
//
width: {
type: Number,
default: 32
},
//
height: {
type: Number,
default: 32
},
//border
borderColor: {
type: String,
default: '#333'
},
//
backgroundColor: {
type: String,
default: '#fff'
},
//
size: {
type: Number,
default: 24
},
//
color: {
type: String,
default: '#333'
},
// 0.9
scale: {
type: Boolean,
default: false
},
//
colonSize: {
type: Number,
default: 28
},
//
colonColor: {
type: String,
default: '#333'
},
// ()
time: {
type: Number,
default: 0
},
//
days: {
type: Boolean,
default: false
},
//
hours: {
type: Boolean,
default: true
},
//
minutes: {
type: Boolean,
default: true
},
//
seconds: {
type: Boolean,
default: true
},
// seconds
unitEn: {
type: Boolean,
default: false
},
//,false
isColon: {
type: Boolean,
default: true
},
//
returnTime: {
type: Boolean,
default: false
},
//
isMs: {
type: Boolean,
default: false
},
msWidth: {
type: Number,
default: 32
},
msSize: {
type: Number,
default: 24
},
msColor: {
type: String,
default: '#333'
}
},
watch: {
time(val) {
this.clearTimer();
this.doLoop();
}
},
data() {
return {
countdown: null,
d: '0',
h: '00',
i: '00',
s: '00',
//91
ms: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
ani: false
};
},
created() {
this.clearTimer();
this.doLoop();
},
// #ifndef VUE3
beforeDestroy() {
this.clearTimer();
},
// #endif
// #ifdef VUE3
beforeUnmount(){
this.clearTimer();
},
// #endif
methods: {
getWidth: function(num, width) {
return num > 99 ? (width / 2) * num.toString().length : width;
},
clearTimer() {
clearInterval(this.countdown);
this.countdown = null;
},
endOfTime() {
this.ani = false;
this.clearTimer();
this.$emit('end', {});
},
doLoop: function() {
let seconds = this.time || 0;
this.ani = true;
this.countDown(seconds);
this.countdown = setInterval(() => {
seconds--;
if (seconds < 0) {
this.endOfTime();
return;
}
this.countDown(seconds);
if (this.returnTime) {
this.$emit('time', { seconds: seconds });
}
}, 1000);
},
countDown(seconds) {
let [day, hour, minute, second] = [0, 0, 0, 0];
if (seconds > 0) {
day = this.days ? Math.floor(seconds / (60 * 60 * 24)) : 0;
hour = this.hours ? Math.floor(seconds / (60 * 60)) - day * 24 : 0;
minute = this.minutes ? Math.floor(seconds / 60) - hour * 60 - day * 24 * 60 : 0;
second = Math.floor(seconds) - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60;
} else {
this.endOfTime();
}
hour = hour < 10 ? '0' + hour : hour;
minute = minute < 10 ? '0' + minute : minute;
second = second < 10 ? '0' + second : second;
this.d = day;
this.h = hour;
this.i = minute;
this.s = second;
}
}
};
</script>
<style scoped>
.tui-countdown-box {
display: flex;
align-items: center;
}
.tui-countdown-box {
display: flex;
align-items: center;
}
.tui-countdown-item {
border: 1rpx solid;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6rpx;
white-space: nowrap;
transform: translateZ(0);
}
.tui-countdown-time {
margin: 0;
padding: 0;
}
.tui-countdown-colon {
display: flex;
justify-content: center;
padding: 0 5rpx;
}
.tui-colon-pad {
padding: 0 !important;
}
.tui-countdown-scale {
transform: scale(0.9);
transform-origin: center center;
}
.tui-countdown__ms {
border: 1rpx solid;
overflow: hidden;
border-radius: 6rpx;
}
/*ms使用css3代替js频繁更新操作性能优化*/
.tui-ms__list {
animation: loop 1s steps(10) infinite;
}
@keyframes loop {
from {
transform: translateY(0);
}
to {
transform: translateY(-100%);
}
}
.tui-ms__item {
display: flex;
align-items: center;
justify-content: center;
}
</style>

View File

@ -0,0 +1,103 @@
<template>
<view class="tui-divider" :style="{ height: height + 'rpx' }">
<view class="tui-divider-line" :style="{ width: width, background: getBgColor(gradual, gradualColor, dividerColor) }"></view>
<view
class="tui-divider-text"
:style="{ color: color, fontSize: size + 'rpx', lineHeight: size + 'rpx', backgroundColor: backgroundColor, fontWeight: bold ? 'bold' : 'normal' }"
>
<slot></slot>
</view>
</view>
</template>
<script>
export default {
name: 'tuiDivider',
props: {
//divider
height: {
type: Number,
default: 100
},
//divider400rpx
width: {
type: String,
default: '100%'
},
//divider线
dividerColor: {
type: String,
default: '#e5e5e5'
},
//
color: {
type: String,
default: '#999'
},
// rpx
size: {
type: Number,
default: 24
},
bold: {
type: Boolean,
default: false
},
//
backgroundColor: {
type: String,
default: '#fafafa'
},
//线truedivideColor
gradual: {
type: Boolean,
default: false
},
//to right
gradualColor: {
type: Array,
default: function() {
return ['#eee', '#ccc'];
}
}
},
methods: {
getBgColor: function(gradual, gradualColor, dividerColor) {
let bgColor = dividerColor;
if (gradual) {
bgColor = 'linear-gradient(to right,' + gradualColor[0] + ',' + gradualColor[1] + ',' + gradualColor[1] + ',' + gradualColor[0] + ')';
}
return bgColor;
}
}
};
</script>
<style scoped>
.tui-divider {
width: 100%;
position: relative;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
overflow: hidden;
}
.tui-divider-line {
position: absolute;
height: 1rpx;
top: 50%;
left: 50%;
-webkit-transform: scaleY(0.5) translateX(-50%) translateZ(0);
transform: scaleY(0.5) translateX(-50%) translateZ(0);
}
.tui-divider-text {
position: relative;
text-align: center;
padding: 0 18rpx;
z-index: 1;
}
</style>

View File

@ -0,0 +1,140 @@
<template>
<!-- @touchmove.stop.prevent -->
<view>
<view v-if="mask" class="tui-drawer-mask" :class="{ 'tui-drawer-mask_show': visible }" :style="{ zIndex: maskZIndex }" @tap="handleMaskClick"></view>
<view
class="tui-drawer-container"
:class="[`tui-drawer-container_${mode}`, visible ? `tui-drawer-${mode}__show` : '']"
:style="{ zIndex: zIndex, backgroundColor: backgroundColor }"
>
<slot></slot>
</view>
</view>
</template>
<script>
/**
* 超过一屏时插槽使用scroll-view
**/
export default {
name: 'tuiDrawer',
emits: ['close'],
props: {
visible: {
type: Boolean,
default: false
},
mask: {
type: Boolean,
default: true
},
maskClosable: {
type: Boolean,
default: true
},
// left right bottom top
mode: {
type: String,
default: 'right'
},
//drawer z-index
zIndex: {
type: [Number, String],
default: 9999
},
//mask z-index
maskZIndex: {
type: [Number, String],
default: 9998
},
backgroundColor: {
type: String,
default: '#17172F'
}
},
methods: {
handleMaskClick() {
if (!this.maskClosable) {
return;
}
this.$emit('close', {});
}
}
};
</script>
<style scoped>
.tui-drawer-mask {
opacity: 0;
visibility: hidden;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
transition: all 0.3s ease-in-out;
}
.tui-drawer-mask_show {
display: block;
visibility: visible;
opacity: 1;
}
.tui-drawer-container {
position: fixed;
left: 80%;
height: 100.2%;
top: 0;
transform: translate3d(-50%, -50%, 0);
transform-origin: center;
transition: all 0.3s ease-in-out;
opacity: 0;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
-ms-touch-action: pan-y cross-slide-y;
-ms-scroll-chaining: none;
-ms-scroll-limit: 0 50 0 50;
}
.tui-drawer-container_left {
left: 0;
top: 50%;
transform: translate3d(-100%, -50%, 0);
}
.tui-drawer-container_right {
right: 0;
top: 50%;
left: auto;
transform: translate3d(100%, -80%, 0);
}
.tui-drawer-container_bottom,
.tui-drawer-container_top {
width: 100%;
height: auto !important;
min-height: 20rpx;
left: 0;
right: 0;
transform-origin: center;
transition: all 0.3s ease-in-out;
}
.tui-drawer-container_bottom {
bottom: 0;
top: auto;
transform: translate3d(0, 100%, 0);
}
.tui-drawer-container_top {
transform: translate3d(0, -100%, 0);
}
.tui-drawer-left__show,
.tui-drawer-right__show {
opacity: 1;
transform: translate3d(0, -50%, 0);
}
.tui-drawer-top__show,
.tui-drawer-bottom__show {
opacity: 1;
transform: translate3d(0, 0, 0);
}
</style>

View File

@ -0,0 +1,190 @@
export default {
"about": "\ue772",
"about-fill": "\ue771",
"add": "\ue770",
"add-fill": "\ue76f",
"addmessage": "\ue76e",
"addressbook": "\ue76d",
"agree": "\ue76c",
"agree-fill": "\ue76b",
"alarm": "\ue76a",
"alarm-fill": "\ue769",
"alipay": "\ue768",
"android": "\ue767",
"applets": "\ue766",
"arrowdown": "\ue765",
"arrowleft": "\ue764",
"arrowright": "\ue763",
"arrowup": "\ue762",
"attestation": "\ue761",
"back": "\ue760",
"bag": "\ue75f",
"bag-fill": "\ue75e",
"balloon": "\ue75d",
"bankcard": "\ue75c",
"bankcard-fill": "\ue75b",
"bottom": "\ue75a",
"calendar": "\ue759",
"camera": "\ue758",
"camera-fill": "\ue757",
"camera-add": "\ue756",
"card": "\ue755",
"card-fill": "\ue754",
"cart": "\ue753",
"cart-fill": "\ue752",
"category": "\ue751",
"category-fill": "\ue750",
"check": "\ue74f",
"circle": "\ue74e",
"circle-fill": "\ue74d",
"circle-selected": "\ue74c",
"clock": "\ue74b",
"clock-fill": "\ue74a",
"close": "\ue749",
"close-fill": "\ue748",
"community": "\ue747",
"community-fill": "\ue746",
"computer": "\ue745",
"computer-fill": "\ue744",
"coupon": "\ue743",
"delete": "\ue742",
"deletekey": "\ue741",
"dingtalk": "\ue740",
"dissatisfied": "\ue73f",
"down": "\ue73e",
"download": "\ue73d",
"edit": "\ue73c",
"ellipsis": "\ue73b",
"enlarge": "\ue73a",
"evaluate": "\ue739",
"exchange": "\ue738",
"explain": "\ue737",
"explain-fill": "\ue736",
"explore": "\ue735",
"explore-fill": "\ue734",
"eye": "\ue733",
"feedback": "\ue732",
"fingerprint": "\ue730",
"friendadd": "\ue72f",
"friendadd-fill": "\ue72e",
"gps": "\ue72d",
"histogram": "\ue72c",
"home": "\ue72b",
"home-fill": "\ue72a",
"house": "\ue729",
"imface": "\ue728",
"imkeyboard": "\ue727",
"immore": "\ue726",
"imvoice": "\ue725",
"ios": "\ue724",
"kefu": "\ue723",
"label": "\ue722",
"label-fill": "\ue721",
"like": "\ue720",
"like-fill": "\ue71f",
"link": "\ue71e",
"listview": "\ue71d",
"loading": "\ue71c",
"location": "\ue71b",
"mail": "\ue71a",
"mail-fill": "\ue719",
"manage": "\ue718",
"manage-fill": "\ue717",
"member": "\ue716",
"member-fill": "\ue715",
"message": "\ue714",
"message-fill": "\ue713",
"mobile": "\ue712",
"moments": "\ue711",
"more": "\ue710",
"more-fill": "\ue70f",
"narrow": "\ue70e",
"news": "\ue70d",
"news-fill": "\ue70c",
"nodata": "\ue70b",
"notice": "\ue699",
"notice-fill": "\ue698",
"offline": "\ue697",
"offline-fill": "\ue696",
"oppose": "\ue695",
"oppose-fill": "\ue694",
"order": "\ue693",
"partake": "\ue692",
"people": "\ue691",
"people-fill": "\ue690",
"pic": "\ue68f",
"pic-fill": "\ue68e",
"picture": "\ue68d",
"pie": "\ue68c",
"plus": "\ue689",
"polygonal": "\ue688",
"position": "\ue686",
"pwd": "\ue685",
"qq": "\ue684",
"qrcode": "\ue682",
"redpacket": "\ue681",
"redpacket-fill": "\ue680",
"reduce": "\ue67f",
"refresh": "\ue67e",
"revoke": "\ue67d",
"satisfied": "\ue67c",
"screen": "\ue67b",
"search": "\ue67a",
"search-2": "\ue679",
"send": "\ue678",
"service": "\ue677",
"service-fill": "\ue676",
"setup": "\ue675",
"setup-fill": "\ue674",
"share": "\ue673",
"share-fill": "\ue672",
"shield": "\ue671",
"shop": "\ue670",
"shop-fill": "\ue66f",
"shut": "\ue66e",
"signin": "\ue66d",
"sina": "\ue66c",
"skin": "\ue66b",
"soso": "\ue669",
"square": "\ue668",
"square-fill": "\ue667",
"square-selected": "\ue666",
"star": "\ue665",
"star-fill": "\ue664",
"strategy": "\ue663",
"sweep": "\ue662",
"time": "\ue661",
"time-fill": "\ue660",
"todown": "\ue65f",
"toleft": "\ue65e",
"tool": "\ue65d",
"top": "\ue65c",
"toright": "\ue65b",
"towardsleft": "\ue65a",
"towardsright": "\ue659",
"towardsright-fill": "\ue658",
"transport": "\ue657",
"transport-fill": "\ue656",
"turningdown": "\ue654",
"turningleft": "\ue653",
"turningright": "\ue652",
"turningup": "\ue651",
"unreceive": "\ue650",
"seen": "\ue7d2",
"unseen": "\ue7d1",
"up": "\ue64e",
"upload": "\ue64c",
"video": "\ue64b",
"voice": "\ue649",
"voice-fill": "\ue648",
"voipphone": "\ue647",
"wallet": "\ue646",
"warning": "\ue645",
"wealth": "\ue644",
"wealth-fill": "\ue643",
"weather": "\ue642",
"wechat": "\ue641",
"wifi": "\ue640",
"play": "\ue7d5",
"suspend": "\ue7d4"
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,78 @@
<template>
<view class="tui-loading-init">
<view class="tui-loading-center"></view>
<view class="tui-loadmore-tips">{{text}}</view>
</view>
</template>
<script>
export default {
name: "tuiLoading",
props: {
text: {
type: String,
default: "正在加载..."
}
}
}
</script>
<style scoped>
.tui-loading-init {
min-width: 200rpx;
min-height: 200rpx;
max-width: 500rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
font-size: 26rpx;
color: #fff;
background-color: rgba(0, 0, 0, 0.7);
border-radius: 10rpx;
}
.tui-loading-center {
width: 50rpx;
height: 50rpx;
border: 3px solid #fff;
border-radius: 50%;
margin: 0 6px;
display: inline-block;
vertical-align: middle;
clip-path: polygon(0% 0%, 100% 0%, 100% 40%, 0% 40%);
animation: rotate 1s linear infinite;
margin-bottom: 36rpx;
}
.tui-loadmore-tips {
text-align: center;
padding: 0 20rpx;
box-sizing: border-box;
}
@-webkit-keyframes rotate {
from {
transform: rotatez(0deg);
}
to {
transform: rotatez(360deg);
}
}
@keyframes rotate {
from {
transform: rotatez(0deg);
}
to {
transform: rotatez(360deg);
}
}
</style>

View File

@ -0,0 +1,161 @@
<template>
<view class="tui-loadmore">
<view :class="['tui-loading-'+index, (index==3 && type)?'tui-loading-'+type:'']"></view>
<view class="tui-loadmore-tips">{{text}}</view>
</view>
</template>
<script>
export default {
name: "tuiLoadmore",
props: {
//
text: {
type: String,
default: "正在加载..."
},
//loading 1,2,3
index: {
type: Number,
default: 1
},
//index=3primaryredorangegreen
type: {
type: String,
default: ""
}
}
}
</script>
<style scoped>
.tui-loadmore {
width: 48%;
margin: 1.5em auto;
line-height: 1.5em;
font-size: 24rpx;
text-align: center;
}
.tui-loading-1 {
margin: 0 5px;
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
-webkit-animation: a 1s steps(12) infinite;
animation: a 1s steps(12) infinite;
background: transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=) no-repeat;
background-size: 100%;
}
@-webkit-keyframes a {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(1turn);
transform: rotate(1turn);
}
}
@keyframes a {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(1turn);
transform: rotate(1turn);
}
}
.tui-loadmore-tips {
display: inline-block;
vertical-align: middle;
}
.tui-loading-2 {
width: 28rpx;
height: 28rpx;
border: 1px solid #8f8d8e;
border-radius: 50%;
margin: 0 6px;
display: inline-block;
vertical-align: middle;
clip-path: polygon(0% 0%,100% 0%,100% 30%,0% 30%);
animation: rotate 1s linear infinite;
}
@-webkit-keyframes rotate {
from {
transform: rotatez(0deg);
}
to {
transform: rotatez(360deg);
}
}
@keyframes rotate {
from {
transform: rotatez(0deg);
}
to {
transform: rotatez(360deg);
}
}
.tui-loading-3 {
display: inline-block;
margin: 0 6px;
vertical-align: middle;
width: 28rpx;
height: 28rpx;
background: 0 0;
border-radius: 50%;
border: 2px solid;
border-color: #e5e5e5 #e5e5e5 #e5e5e5 #8f8d8e;
animation: tui-rotate 0.7s linear infinite;
}
.tui-loading-3.tui-loading-primary {
border-color: #e5e5e5 #e5e5e5 #e5e5e5 #5677fc;
}
.tui-loading-3.tui-loading-green {
border-color: #e5e5e5 #e5e5e5 #e5e5e5 #19be6b;
}
.tui-loading-3.tui-loading-orange {
border-color: #e5e5e5 #e5e5e5 #e5e5e5 #ff7900;
}
.tui-loading-3.tui-loading-red {
border-color: #ededed #ededed #ededed #ed3f14;
}
@-webkit-keyframes tui-rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
@keyframes tui-rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
</style>

View File

@ -0,0 +1,408 @@
<template>
<view class="tui-modal__container" :class="[show ? 'tui-modal-show' : '']" :style="{zIndex:zIndex}" @touchmove.stop.prevent>
<view
class="tui-modal-box"
:style="{ width: width, padding: padding, borderRadius: radius, backgroundColor: backgroundColor,zIndex:zIndex+1 }"
:class="[fadeIn || show ? 'tui-modal-normal' : 'tui-modal-scale', show ? 'tui-modal-show' : '']"
>
<view v-if="!custom">
<view class="tui-modal-title" v-if="title">{{ title }}</view>
<view class="tui-modal-content" :class="[title ? '' : 'tui-mtop']" :style="{ color: color, fontSize: size + 'rpx' }">{{ content }}</view>
<view class="tui-modalBtn-box" :class="[button.length != 2 ? 'tui-flex-column' : '']">
<block v-for="(item, index) in button" :key="index">
<button
class="tui-modal-btn"
:class="[
'tui-' + (item.type || 'primary') + (item.plain ? '-outline' : ''),
button.length != 2 ? 'tui-btn-width' : '',
button.length > 2 ? 'tui-mbtm' : '',
shape == 'circle' ? 'tui-circle-btn' : ''
]"
:hover-class="'tui-' + (item.plain ? 'outline' : item.type || 'primary') + '-hover'"
:data-index="index"
@tap="handleClick"
>
{{ item.text || '确定' }}
</button>
</block>
</view>
</view>
<view v-else><slot></slot></view>
</view>
<view class="tui-modal-mask" :class="[show ? 'tui-mask-show' : '']" :style="{zIndex:maskZIndex}" @tap="handleClickCancel"></view>
</view>
</template>
<script>
export default {
name: 'tuiModal',
emits: ['click','cancel'],
props: {
//
show: {
type: Boolean,
default: false
},
width: {
type: String,
default: '84%'
},
backgroundColor: {
type: String,
default: '#fff'
},
padding: {
type: String,
default: '30rpx 0rpx 0rpx 0rpx'
},
radius: {
type: String,
default: '24rpx'
},
//
title: {
type: String,
default: ''
},
//
content: {
type: String,
default: ''
},
//
color: {
type: String,
default: '#999'
},
// rpx
size: {
type: Number,
default: 28
},
// circle, square
shape: {
type: String,
default: 'square'
},
button: {
type: Array,
default: function() {
return [
{
text: '取消',
type: 'red',
plain: true //
},
{
text: '确定',
type: 'red',
plain: false
}
];
}
},
//
maskClosable: {
type: Boolean,
default: true
},
//inputtrue
fadeIn: {
type: Boolean,
default: false
},
//
custom: {
type: Boolean,
default: false
},
//z-index
zIndex:{
type: Number,
default: 9997
},
//mask z-index
maskZIndex:{
type: Number,
default: 9990
}
},
data() {
return {};
},
methods: {
handleClick(e) {
if (!this.show) return;
const dataset = e.currentTarget.dataset;
this.$emit('click', {
index: Number(dataset.index)
});
},
handleClickCancel() {
if (!this.maskClosable) return;
this.$emit('cancel');
}
}
};
</script>
<style scoped>
.tui-modal__container {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
visibility: hidden;
}
.tui-modal-box {
position: relative;
opacity: 0;
visibility: hidden;
box-sizing: border-box;
transition: all 0.3s ease-in-out;
}
.tui-modal-scale {
transform: scale(0);
}
.tui-modal-normal {
transform: scale(1);
}
.tui-modal-show {
opacity: 1;
visibility: visible;
}
.tui-modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
transition: all 0.3s ease-in-out;
opacity: 0;
visibility: hidden;
}
.tui-mask-show {
visibility: visible;
opacity: 1;
}
.tui-modal-title {
text-align: center;
font-size: 34rpx;
color: #333;
padding-top: 20rpx;
font-weight: bold;
}
.tui-modal-content {
text-align: center;
color: #999;
font-size: 28rpx;
padding-top: 20rpx;
padding-bottom: 60rpx;
}
.tui-mtop {
margin-top: 30rpx;
}
.tui-mbtm {
margin-bottom: 30rpx;
}
.tui-modalBtn-box {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.tui-flex-column {
flex-direction: column;
}
.tui-modal-btn {
width: 46%;
height: 68rpx;
line-height: 68rpx;
position: relative;
border-radius: 10rpx;
font-size: 26rpx;
overflow: visible;
margin-left: 0;
margin-right: 0;
}
.tui-modal-btn::after {
content: ' ';
position: absolute;
width: 200%;
height: 200%;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
transform: scale(0.5, 0.5) translateZ(0);
left: 0;
top: 0;
border-radius: 20rpx;
z-index: 2;
}
.tui-btn-width {
width: 80% !important;
}
.tui-primary {
background: #5677fc;
color: #fff;
}
.tui-primary-hover {
background: #4a67d6;
color: #e5e5e5;
}
.tui-primary-outline {
color: #5677fc;
background: transparent;
}
.tui-primary-outline::after {
border: 1px solid #5677fc;
}
.tui-danger {
background: #ed3f14;
color: #fff;
}
.tui-danger-hover {
background: #d53912;
color: #e5e5e5;
}
.tui-danger-outline {
color: #ed3f14;
background: transparent;
}
.tui-danger-outline::after {
border: 1px solid #ed3f14;
}
.tui-red {
background: #e41f19;
color: #fff;
}
.tui-red-hover {
background: #c51a15;
color: #e5e5e5;
}
.tui-red-outline {
color: #e41f19;
background: transparent;
}
.tui-red-outline::after {
border: 1px solid #e41f19;
}
.tui-warning {
background: #ff7900;
color: #fff;
}
.tui-warning-hover {
background: #e56d00;
color: #e5e5e5;
}
.tui-warning-outline {
color: #ff7900;
background: transparent;
}
.tui-warning-outline::after {
border: 1px solid #ff7900;
}
.tui-green {
background: #19be6b;
color: #fff;
}
.tui-green-hover {
background: #16ab60;
color: #e5e5e5;
}
.tui-green-outline {
color: #19be6b;
background: transparent;
}
.tui-green-outline::after {
border: 1px solid #19be6b;
}
.tui-white {
background: #fff;
color: #333;
}
.tui-white-hover {
background: #f7f7f9;
color: #666;
}
.tui-white-outline {
color: #333;
background: transparent;
}
.tui-white-outline::after {
border: 1px solid #333;
}
.tui-gray {
background: #ededed;
color: #999;
}
.tui-gray-hover {
background: #d5d5d5;
color: #898989;
}
.tui-gray-outline {
color: #999;
background: transparent;
}
.tui-gray-outline::after {
border: 1px solid #999;
}
.tui-outline-hover {
opacity: 0.6;
}
.tui-circle-btn {
border-radius: 40rpx !important;
}
.tui-circle-btn::after {
border-radius: 80rpx !important;
}
</style>

View File

@ -0,0 +1,118 @@
<template>
<view class="tui-nodata-box" :class="[fixed?'tui-nodata-fixed':'']">
<image v-if="imgUrl" :src="imgUrl" class="tui-tips-icon" :style="{width:imgWidth+'rpx',height:imgHeight+'rpx'}"></image>
<view class="tui-tips-content">
<slot></slot>
</view>
<view class="tui-tips-btn" hover-class="tui-btn__hover" :hover-stay-time="150" :style="{width:btnWidth+'rpx',height:btnHeight+'rpx',background:backgroundColor,borderRadius:radius,fontSize:size+'rpx'}" v-if="btnText" @tap="handleClick">{{btnText}}</view>
</view>
</template>
<script>
export default {
name: "tuiNoData",
emits: ['click'],
props: {
//
fixed: {
type: Boolean,
default: true
},
//
imgUrl: {
type: String,
default: ""
},
//
imgWidth: {
type: Number,
default: 200
},
//
imgHeight:{
type: Number,
default: 200
},
//
btnWidth:{
type: Number,
default: 200
},
btnHeight:{
type: Number,
default: 60
},
//
btnText:{
type:String,
default: ""
},
//
backgroundColor:{
type:String,
default: "#EB0909"
},
size:{
type:Number,
default:28
},
radius:{
type:String,
default:'8rpx'
}
},
methods: {
handleClick(e) {
this.$emit('click', {});
}
}
}
</script>
<style scoped>
.tui-nodata-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.tui-nodata-fixed {
width: 90%;
position: fixed;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.tui-tips-icon {
display: block;
flex-shrink: 0;
width: 280rpx;
height: 280rpx;
margin-bottom: 40rpx;
}
.tui-tips-content {
text-align: center;
color: #666666;
font-size: 28rpx;
padding: 0 50rpx 28rpx 50rpx;
box-sizing: border-box;
word-break: break-all;
word-wrap: break-word;
}
.tui-tips-btn {
color: #fff;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
}
.tui-btn__hover{
opacity: 0.5;
}
</style>

View File

@ -0,0 +1,115 @@
<template>
<view class="tui-nomore-class tui-loadmore-none">
<view :class="[isDot?'tui-nomore-dot':'tui-nomore']">
<view :style="{backgroundColor:backgroundColor}" :class="[isDot?'tui-dot-text':'tui-nomore-text']">{{isDot?dotText:text}}</view>
</view>
</view>
</template>
<script>
export default {
name: "tuiNomore",
props: {
//
backgroundColor: {
type: String,
default: "#F6F7FA"
},
// ""
isDot: {
type: Boolean,
default: false
},
//isDotfalse
text: {
type: String,
default: "到底啦~"
}
},
data() {
return {
dotText: "●"
};
}
}
</script>
<style scoped>
.tui-loadmore-none {
width: 50%;
margin: 1.5em auto;
line-height: 1.5em;
font-size: 24rpx;
display: flex;
justify-content: center;
}
.tui-nomore {
width: 100%;
height: 100%;
position: relative;
display: flex;
justify-content: center;
margin-top: 10rpx;
padding-bottom: 6rpx;
}
.tui-nomore::before {
content: ' ';
position: absolute;
border-bottom: 1rpx solid #e5e5e5;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
width: 100%;
top: 18rpx;
left: 0;
}
.tui-nomore-text {
color: #999;
font-size: 24rpx;
text-align: center;
padding: 0 18rpx;
height: 36rpx;
line-height: 36rpx;
position: relative;
z-index: 1;
}
.tui-nomore-dot {
position: relative;
text-align: center;
-webkit-display: flex;
display: flex;
-webkit-justify-content: center;
justify-content: center;
margin-top: 10rpx;
padding-bottom: 6rpx;
}
.tui-nomore-dot::before {
content: '';
position: absolute;
border-bottom: 1rpx solid #e5e5e5;
-webkit-transform: scaleY(0.5) translateX(-50%);
transform: scaleY(0.5) translateX(-50%);
width: 360rpx;
top: 18rpx;
left: 50%;
}
.tui-dot-text {
position: relative;
color: #e5e5e5;
font-size: 10px;
text-align: center;
width: 50rpx;
height: 36rpx;
line-height: 36rpx;
-webkit-transform: scale(0.8);
transform: scale(0.8);
-webkit-transform-origin: center center;
transform-origin: center center;
z-index: 1;
}
</style>

View File

@ -0,0 +1,231 @@
<template>
<view class="tui-numberbox">
<view class="tui-numbox-icon tui-icon-reduce " :class="[disabled || min >= inputValue ? 'tui-disabled' : '']"
@tap="reduce" :style="{ color: iconColor, fontSize: iconSize + 'rpx' }"></view>
<input type="number" v-model="inputValue" :disabled="disabled" @blur="blur" class="tui-num-input"
:style="{ color: color, fontSize: size + 'rpx', backgroundColor: backgroundColor, height: height + 'rpx', minHeight: height + 'rpx', width: width + 'rpx' }" />
<view class="tui-numbox-icon tui-icon-plus" :class="[disabled || inputValue >= max ? 'tui-disabled' : '']"
@tap="plus" :style="{ color: iconColor, fontSize: iconSize + 'rpx' }"></view>
</view>
</template>
<script>
export default {
name: 'tuiNumberbox',
emits: ['change'],
props: {
value: {
type: [Number, String],
default: 1
},
//
min: {
type: Number,
default: 1
},
//
max: {
type: Number,
default: 99
},
// 1 1.1 10...
step: {
type: Number,
default: 1
},
//
disabled: {
type: Boolean,
default: false
},
// rpx
iconSize: {
type: Number,
default: 26
},
iconColor: {
type: String,
default: '#666666'
},
//input
height: {
type: Number,
default: 42
},
//input
width: {
type: Number,
default: 80
},
size: {
type: Number,
default: 28
},
//input
backgroundColor: {
type: String,
default: '#F5F5F5'
},
//input
color: {
type: String,
default: '#333'
},
//使
index: {
type: [Number, String],
default: 0
},
//
custom: {
type: [Number, String],
default: 0
}
},
created() {
this.inputValue = +this.value;
},
data() {
return {
inputValue: 0
};
},
watch: {
value(val) {
this.inputValue = +val;
}
},
methods: {
getLen(val, step) {
let len = 0;
let lenVal = 0;
//
if (!Number.isInteger(step)) {
len = (step + '').split('.')[1].length
}
//
if (!Number.isInteger(val)) {
lenVal = (val + '').split('.')[1].length
}
return Math.max(len, lenVal);
},
getScale(val, step) {
let scale = 1;
let scaleVal = 1;
//
if (!Number.isInteger(step)) {
scale = Math.pow(10, (step + '').split('.')[1].length);
}
//
if (!Number.isInteger(val)) {
scaleVal = Math.pow(10, (val + '').split('.')[1].length);
}
return Math.max(scale, scaleVal);
},
calcNum: function(type) {
if (this.disabled || (this.inputValue == this.min && type === 'reduce') || (this.inputValue == this
.max && type === 'plus')) {
return;
}
const scale = this.getScale(this.inputValue, this.step);
let len = this.getLen(this.inputValue, this.step);
let num = Number(this.inputValue) * scale;
let step = this.step * scale;
if (type === 'reduce') {
num -= step;
} else if (type === 'plus') {
num += step;
}
let value = this.toFixed(num / scale, len);
if (value < this.min) {
value = this.min;
}else if (value > this.max) {
value = this.max;
}
this.handleChange(value, type);
},
plus: function() {
this.calcNum('plus');
},
reduce: function() {
this.calcNum('reduce');
},
blur: function(e) {
let value = e.detail.value;
if (value) {
if (~value.indexOf('.') && Number.isInteger(this.step) && Number.isInteger(Number(value))) {
value = value.split('.')[0];
}
value = Number(value);
if (value > this.max) {
value = this.max;
} else if (value < this.min) {
value = this.min;
}
} else {
value = this.min;
}
if ((value == this.value && value != this.inputValue) || !e.detail.value) {
this.inputValue = value;
}
this.handleChange(value, 'blur');
},
handleChange(value, type) {
if (this.disabled) return;
this.$emit('change', {
value: Number(value),
type: type,
index: this.index,
custom: this.custom
});
},
toFixed(num, s) {
let times = Math.pow(10, s)
let des = num * times + 0.5
des = parseInt(des, 10) / times
return des + ''
}
}
};
</script>
<style scoped>
@font-face {
font-family: 'numberbox';
src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAASQAA0AAAAABtwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAEdAAAABoAAAAciBpnRUdERUYAAARUAAAAHgAAAB4AKQALT1MvMgAAAZwAAABDAAAAVjxzSINjbWFwAAAB9AAAAEYAAAFK5zLpOGdhc3AAAARMAAAACAAAAAj//wADZ2x5ZgAAAkgAAACHAAAAnIfIEjxoZWFkAAABMAAAAC8AAAA2FZWEOWhoZWEAAAFgAAAAHAAAACQH3gOFaG10eAAAAeAAAAARAAAAEgwAAAFsb2NhAAACPAAAAAwAAAAMADAATm1heHAAAAF8AAAAHwAAACABEAAobmFtZQAAAtAAAAFJAAACiCnmEVVwb3N0AAAEHAAAAC0AAABV/+8iFXjaY2BkYGAA4gVmC5Tj+W2+MnCzMIDATWsFOQT9v5GFgbkeyOVgYAKJAgDrogf+AHjaY2BkYGBu+N/AEMPCAAJAkpEBFbAAAEcKAm142mNgZGBgYGWQYQDRDAxMQMwFhAwM/8F8BgALpAE5AHjaY2BkYWCcwMDKwMDUyXSGgYGhH0IzvmYwYuQAijKwMjNgBQFprikMDs9Yn01kbvjfwBDD3MDQABRmBMkBAOXpDHEAeNpjYYAAFghmZGAAAACdAA4AAAB42mNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZiesT6b+P8/AwOElvwnWQxVDwSMbAxwDiMTkGBiQAWMDMMeAABRZwszAAAAAAAAAAAAAAAwAE542iWKQQrCMBBF5xNpd0pQ7EIoTEnahSCTUNqdWz2A9TrieXKeXCc1qcPn/zfzh0BYv2pVH7oQgbvqdG5Yt/DTrNlPYz+wHvuuqhFSME4sFshTgKUsKfhH5lg8BSul3i5bS3mQdd0RIh2IjnvUrkXDd8zuhuFt86tY9fonIsSYgsXpB+cCGosAeNp9kD1OAzEQhZ/zByQSQiCoXVEA2vyUKRMp9Ailo0g23pBo1155nUg5AS0VB6DlGByAGyDRcgpelkmTImvt6PObmeexAZzjGwr/3yXuhBWO8ShcwREy4Sr1F+Ea+V24jhY+hRvUf4SbuFUD4RYu1BsdVO2Eu5vSbcsKZxgIV3CKJ+Eq9ZVwjfwqXMcVPoQb1L+EmxjjV7iFa2WpDOFhMEFgnEFjig3jAjEcLJIyBtahOfRmEsxMTzd6ETubOBso71dilwMeaDnngCntPbdmvkon/mDLgdSYbh4FS7YpjS4idCgbXyyc1d2oc7D9nu22tNi/a4E1x+xRDWzU/D3bM9JIbAyvkJI18jK3pBJTj2hrrPG7ZynW814IiU68y/SIx5o0dTr3bmniwOLn8owcfbS5kj33qBw+Y1kIeb/dTsQgil2GP5PYcRkAAAB42mNgYoAALjDJyIAOWMGiTIxMjMwiWZmJQJRXVQoigTgjMd9QGIsgAFDsEBsAAAAAAAAB//8AAgABAAAADAAAABYAAAACAAEAAwAEAAEABAAAAAIAAAAAeNpjYGBgZACCq0vUOUD0TWsFORgNADPBBE4AAA==) format('woff');
font-weight: normal;
font-style: normal;
}
.tui-numbox-icon {
font-family: 'numberbox' !important;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding: 10rpx;
}
.tui-icon-reduce:before {
content: '\e691';
}
.tui-icon-plus:before {
content: '\e605';
}
.tui-numberbox {
display: -webkit-inline-flex;
display: inline-flex;
align-items: center;
}
.tui-num-input {
text-align: center;
margin: 0 12rpx;
font-weight: 400;
}
.tui-disabled {
color: #ededed !important;
}
</style>

View File

@ -0,0 +1,168 @@
<template>
<view class="tui-rate-class tui-rate-box" @touchmove="touchMove">
<block v-for="(item, index) in quantity" :key="index">
<view class="tui-icon tui-relative"
:class="['tui-icon-collection' + (hollow && (current <= index || (disabled && current <= index + 1)) ? '' : '-fill')]"
:data-index="index" @tap="handleTap"
:style="{ fontSize: size + 'px', color: current > index + 1 || (!disabled && current > index) ? active : normal }">
<view class="tui-icon tui-icon-main tui-icon-collection-fill" v-if="disabled && current == index + 1"
:style="{ fontSize: size + 'px', color: active, width: percent + '%' }"></view>
</view>
</block>
</view>
</template>
<script>
export default {
name: 'tuiRate',
emits: ['change'],
props: {
//
quantity: {
type: Number,
default: 5
},
//
current: {
type: Number,
default: 0
},
//(01)
score: {
type: [Number, String],
default: 1
},
//
disabled: {
type: Boolean,
default: false
},
//
size: {
type: Number,
default: 20
},
//
normal: {
type: String,
default: '#b2b2b2'
},
//
active: {
type: String,
default: '#e41f19'
},
//
hollow: {
type: Boolean,
default: false
},
//
params: {
type: [Number, String],
default: 0
}
},
data() {
return {
pageX: 0,
percent: 0
};
},
created() {
this.percent = Number(this.score || 0) * 100;
},
watch: {
score(newVal, oldVal) {
this.percent = Number(newVal || 0) * 100;
}
},
methods: {
handleTap(e) {
if (this.disabled) {
return;
}
const index = e.currentTarget.dataset.index;
this.$emit('change', {
index: Number(index) + 1,
params: this.params
});
},
touchMove(e) {
if (this.disabled) {
return;
}
if (!e.changedTouches[0]) {
return;
}
const movePageX = e.changedTouches[0].pageX;
const distance = movePageX - this.pageX;
if (distance <= 0) {
return;
}
let index = Math.ceil(distance / this.size);
index = index > this.quantity ? this.quantity : index;
this.$emit('change', {
index: index,
params: this.params
});
}
},
mounted() {
const className = '.tui-rate-box';
let query = uni.createSelectorQuery().in(this);
query
.select(className)
.boundingClientRect(res => {
this.pageX = res.left || 0;
})
.exec();
}
};
</script>
<style scoped>
@font-face {
font-family: 'rateFont';
src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAT4AA0AAAAAB4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAE3AAAABoAAAAciBprQUdERUYAAAS8AAAAHgAAAB4AKQALT1MvMgAAAaAAAABDAAAAVj1YSN1jbWFwAAAB+AAAAEIAAAFCAA/qlmdhc3AAAAS0AAAACAAAAAj//wADZ2x5ZgAAAkgAAADwAAABZLMTdXtoZWFkAAABMAAAADAAAAA2FZKISmhoZWEAAAFgAAAAHQAAACQHYgOFaG10eAAAAeQAAAARAAAAEgx6AHpsb2NhAAACPAAAAAwAAAAMAEYAsm1heHAAAAGAAAAAHgAAACABEQBPbmFtZQAAAzgAAAFJAAACiCnmEVVwb3N0AAAEhAAAAC0AAABHLO3vkXjaY2BkYGAA4t2/VF7G89t8ZeBmYQCBm9ZKMnC6ikGMuYXpP5DLwcAEEgUAHPQJOXjaY2BkYGBu+N/AEMPCAALMLQyMDKiABQBQwgLwAAAAeNpjYGRgYGBlcGZgYgABEMkFhAwM/8F8BgAPigFhAAB42mNgZGFgnMDAysDA1Ml0hoGBoR9CM75mMGLkAIoysDIzYAUBaa4pDA7PXj17zdzwv4EhhrmBoQEozAiSAwD/YA2wAHjaY2GAABYIrmKoAgACggEBAAAAeNpjYGBgZoBgGQZGBhCwAfIYwXwWBgUgzQKEQP6z1///A8lX//9LSkJVMjCyMcCYDIxMQIKJARUwMgx7AAA/9QiLAAAAAAAAAAAAAABGALJ42mNgZKhiEGNuYfrPoMnAwGimps+ox6jPqKbEz8jHCMLyjHJAmk1czMie0cxInlHMDChrZs6cJyaosI+NlzmU34I/lImPdb+CoHgXCyujIosYtzTfKlYBtlWyuqwKjKwsjNvFTdlkGDnZ1srKrmXjZJRhMxVvZxFgA+rgYI9iYoriV1TYzybAwsDABHeLBIMT0DUg29VBTjEHucvcjtGeUVyOUZ6JaFcybefnZ5HuFdEX6ZVm5uMvniemxuXmzqUmNs+FeOfHCeiKzfPi4vKaJ6YrUCDOIiM8YYKwDIu4OMRbrOtkZdex4vMWACzGM5B42n2QPU4DMRCFn/MHJBJCIKhdUQDa/JQpEyn0CKWjSDbekGjXXnmdSDkBLRUHoOUYHIAbINFyCl6WSZMia+3o85uZ57EBnOMbCv/fJe6EFY7xKFzBETLhKvUX4Rr5XbiOFj6FG9R/hJu4VQPhFi7UGx1U7YS7m9JtywpnGAhXcIon4Sr1lXCN/CpcxxU+hBvUv4SbGONXuIVrZakM4WEwQWCcQWOKDeMCMRwskjIG1qE59GYSzExPN3oRO5s4GyjvV2KXAx5oOeeAKe09t2a+Sif+YMuB1JhuHgVLtimNLiJ0KBtfLJzV3ahzsP2e7ba02L9rgTXH7FENbNT8Pdsz0khsDK+QkjXyMrekElOPaGus8btnKdbzXgiJTrzL9IjHmjR1OvduaeLA4ufyjBx9tLmSPfeoHD5jWQh5v91OxCCKXYY/k9hxGQAAAHjaY2BigAAuMMnIgA5YwaJMjEyMzPzJ+Tk5qcklmfl58WmZOTlcCD4Ak9QKlAAAAAAAAAH//wACAAEAAAAMAAAAFgAAAAIAAQADAAQAAQAEAAAAAgAAAAB42mNgYGBkAIKrS9Q5QPRNayUZGA0AM8UETgAA) format('woff');
font-weight: normal;
font-style: normal;
}
.tui-icon {
font-family: 'rateFont' !important;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: block;
}
.tui-relative {
position: relative;
}
.tui-icon-main {
position: absolute;
height: 100%;
left: 0;
top: 0;
overflow: hidden;
}
.tui-icon-collection-fill:before {
content: '\e6ea';
}
.tui-icon-collection:before {
content: '\e6eb';
}
.tui-rate-box {
display: -webkit-inline-flex;
display: inline-flex;
align-items: center;
margin: 0;
padding: 0;
}
</style>

View File

@ -0,0 +1,218 @@
<template>
<view class="tui-slide-vcode" :style="{width:slideBarWidth+'px',height:slideBlockWidth+'px',backgroundColor:backgroundColor}">
<text class="tui-text-flashover" :style="{fontSize:size+'rpx',background:getBgColor}">拖动滑块验证</text>
<view class="tui-slide-glided" :style="{backgroundColor:activeBgColor}">
<text :style="{fontSize:size+'rpx',color:activeColor}" v-if="isPass">{{passText}}</text>
</view>
<view class="tui-slider-block" :style="{width:slideBlockWidth+'px',height:slideBlockWidth+'px',borderColor:isPass?activeBorderColor: borderColor}"
:change:prop="parse.slidereset" :prop="reset" :data-slideBarWidth="slideBarWidth" :data-slideBlockWidth="slideBlockWidth"
:data-errorRange="errorRange" :data-disabled="disabled" @touchstart="parse.touchstart" @touchmove="parse.touchmove"
@touchend="parse.touchend">
<text class="tui-slide-icon tui-icon-double_arrow" :style="{fontSize:iconSize+'rpx',color:arrowColor}" v-if="!isPass"></text>
<text class="tui-slide-icon tui-icon-check_mark" :style="{fontSize:iconSize+'rpx',color:checkColor}" v-if="isPass"></text>
</view>
</view>
</template>
<script src="./tui-slide-verify.wxs" module="parse" lang="wxs"></script>
<script>
export default {
name: "tuiSlideVerify",
emits: ['success'],
props: {
// px
slideBarWidth: {
type: [Number, String],
default: 300
},
// px =
slideBlockWidth: {
type: [Number, String],
default: 40
},
//border
borderColor: {
type: String,
default: '#E9E9E9'
},
//border
activeBorderColor: {
type: String,
default: '#19be6b'
},
// px
errorRange: {
type: [Number, String],
default: 2
},
//
resetSlide: {
type: Number,
default: 0
},
//
size: {
type: Number,
default: 30
},
//
color: {
type: String,
default: "#444"
},
//
activeColor: {
type: String,
default: "#fff"
},
// rpx
iconSize: {
type: Number,
default: 32
},
//
arrowColor: {
type: String,
default: "#cbcbcb"
},
checkColor: {
type: String,
default: "#19be6b"
},
//
backgroundColor: {
type: String,
default: "#E9E9E9"
},
//
activeBgColor: {
type: String,
default: "#19be6b"
},
//
passText: {
type: String,
default: '验证通过'
}
},
computed: {
getBgColor() {
return `-webkit-gradient(linear, left top, right top, color-stop(0, ${this.color}), color-stop(.4, ${this.color}), color-stop(.5, white), color-stop(.6, ${this.color}), color-stop(1, ${this.color}))`
}
},
watch: {
resetSlide(val) {
if (val > 0) {
this.slideReset()
}
}
},
data() {
return {
isPass: false,
disabled: false,
reset: 0
}
},
methods: {
success() {
//
this.isPass = true;
this.disabled = true;
this.$emit('success', {})
},
slideReset() {
this.isPass = false;
this.disabled = false;
this.reset++;
}
}
}
</script>
<style scoped>
@font-face {
font-family: 'tuiSlideVcode';
src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAUYAA0AAAAAB1wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAE/AAAABoAAAAci6lfG0dERUYAAATcAAAAHgAAAB4AKQALT1MvMgAAAaAAAABCAAAAVjxuSCZjbWFwAAAB+AAAAEUAAAFK5n3pi2dhc3AAAATUAAAACAAAAAj//wADZ2x5ZgAAAkwAAAD8AAABJDQ/n7JoZWFkAAABMAAAADAAAAA2GSR8FGhoZWEAAAFgAAAAHQAAACQHygOFaG10eAAAAeQAAAARAAAAEgwUAD5sb2NhAAACQAAAAAwAAAAMAFQAkm1heHAAAAGAAAAAHgAAACABEQA6bmFtZQAAA0gAAAFJAAACiCnmEVVwb3N0AAAElAAAAD0AAABPYJEgVXjaY2BkYGAA4oqPSw3j+W2+MnCzMIDAbaY5nHBa5P905jfMeUAuBwMTSBQAHycKCHjaY2BkYGBu+N/AEMPCAALMbxgYGVABCwBYegNYAAAAeNpjYGRgYGBl0GNgYgABEMkFhAwM/8F8BgANfQFMAAB42mNgZGFgnMDAysDA1Ml0hoGBoR9CM75mMGLkAIoysDIzYAUBaa4pDA7PGJ6ZMDf8b2CIYW5gaAAKM4LkAN6ZDA8AAHjaY2GAABYItmMQAQABaABfAAAAeNpjYGBgZoBgGQZGBhBwAfIYwXwWBg0gzQakGRmYnjE8M/n/n4EBQksxS16AqgcCRjYGOIeRCUgwMaACRoZhDwDR6wnSAAAAAAAAAAAAAAAAVACSeNpFzjFOwzAYxfHv2Yodu4ozxHEq2qoSEilLQYoqh6lIIBaugMTC3hswMcPQhYmBjV4AMSFxAppjQDmDSzJle9L7DX9itNx/8i9+QY7mRPDn8ItTlDOcQLhCwcBVtWLCOl/D10v0L5vHnAGMx+EuLSctvQ8PBpMyxWU30/GxwUvMwXqDW6lkNIikllgnGM1MeAqPyWxkeNktczRGgrXUXOkeETGy+2f+x1c0oGnbKUg6KjzVJWUQh23TwlfTrhW+cpZRE3ZCIG8a5EKE3U34yM/sRttCb5hiuNLDjK+i8PO9Db8igmu2cOE1vNsWDTP9xhiuVXZARP+yvTqbeNp9kD1OAzEQhZ/zByQSQiCoXVEA2vyUKRMp9Ailo0g23pBo1155nUg5AS0VB6DlGByAGyDRcgpelkmTImvt6PObmeexAZzjGwr/3yXuhBWO8ShcwREy4Sr1F+Ea+V24jhY+hRvUf4SbuFUD4RYu1BsdVO2Eu5vSbcsKZxgIV3CKJ+Eq9ZVwjfwqXMcVPoQb1L+EmxjjV7iFa2WpDOFhMEFgnEFjig3jAjEcLJIyBtahOfRmEsxMTzd6ETubOBso71dilwMeaDnngCntPbdmvkon/mDLgdSYbh4FS7YpjS4idCgbXyyc1d2oc7D9nu22tNi/a4E1x+xRDWzU/D3bM9JIbAyvkJI18jK3pBJTj2hrrPG7ZynW814IiU68y/SIx5o0dTr3bmniwOLn8owcfbS5kj33qBw+Y1kIeb/dTsQgil2GP5PYcRkAAAB42mNgYoAALjDJyIAOWMGiTIxMjMyCOalpJbop+aVJOam6iUVF+eUCKaWZ6fmlJZmJeckZ+XnpugDvDw1eAAAAAAAAAf//AAIAAQAAAAwAAAAWAAAAAgABAAMABAABAAQAAAACAAAAAHjaY2BgYGQAgqtL1DlA9G2mOZwwGgA1wQSuAAA=) format('woff');
font-weight: normal;
font-style: normal;
font-display: swap;
}
.tui-slide-icon {
font-family: "tuiSlideVcode" !important;
font-size: 34rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
}
.tui-icon-check_mark:before {
content: "\e634";
}
.tui-icon-double_arrow:before {
content: "\e600";
}
.tui-slide-vcode {
background-color: #EAEEF1;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.tui-slide-glided {
width: 0;
height: 100%;
background-color: #19BE6B;
position: absolute;
left: 0;
top: 0;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
}
.tui-slider-block {
position: absolute;
z-index: 2;
background-color: #FFFFFF;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
border: 1rpx solid;
box-sizing: border-box;
left: 0;
top: 0;
transition: border-color 0.08s;
}
.tui-text-flashover {
-webkit-background-clip: text !important;
-webkit-text-fill-color: transparent !important;
-webkit-animation: animate 1.8s infinite;
}
@-webkit-keyframes animate {
from {
background-position: -90rpx;
}
to {
background-position: 90rpx;
}
}
@keyframes animate {
from {
background-position: -90rpx;
}
to {
background-position: 90rpx;
}
}
</style>

View File

@ -0,0 +1,73 @@
var slideBarWidth = 200;
var slideBlockWidth = 32;
var errorRange = 2
var disabled = false
function bool(str) {
return str === 'true' || str == true ? true : false
}
function touchstart(e, ins) {
var state=e.instance.getState()
var touch = e.touches[0] || e.changedTouches[0]
var dataset = e.instance.getDataset()
state.startX = touch.pageX
slideBarWidth = +dataset.slidebarwidth
slideBlockWidth = +dataset.slideblockwidth
errorRange = +dataset.errorrange
disabled = bool(dataset.disabled)
}
function styleChange(left, ins) {
if (!ins) return;
ins.selectComponent('.tui-slider-block').setStyle({
transform: 'translate3d(' + left + 'px,0,0)'
})
ins.selectComponent('.tui-slide-glided').setStyle({
width: left + 'px'
})
}
function touchmove(e, ins) {
if (disabled) return;
var state=e.instance.getState()
var touch = e.touches[0] || e.changedTouches[0]
var pageX = touch.pageX;
var left = pageX - state.startX + (state.lastLeft || 0);
left = left < 0 ? 0 : left;
var width = slideBarWidth - slideBlockWidth;
left = left >= width ? width : left;
state.startX = pageX
state.lastLeft = left
styleChange(left, ins)
}
function touchend(e, ins) {
if (disabled) return;
var state=e.instance.getState()
let left = slideBarWidth - slideBlockWidth
if (left - state.lastLeft <= errorRange) {
styleChange(left, ins)
ins.callMethod('success')
} else {
state.startX = 0;
state.lastLeft = 0;
styleChange(0, ins)
}
}
function slidereset(reset, oldreset, owner, ins) {
var state=ins.getState()
if (reset > 0) {
state.startX = 0;
state.lastLeft = 0;
styleChange(0, owner)
}
}
module.exports = {
touchstart: touchstart,
touchmove: touchmove,
touchend: touchend,
slidereset: slidereset
}

View File

@ -0,0 +1,253 @@
<template>
<view class="tui-steps-box" :class="{ 'tui-steps-column': direction === 'column' }">
<view class="tui-step-item" :style="{ width: direction === 'column' ? '100%' : spacing }"
:class="[direction === 'row' ? 'tui-step-horizontal' : 'tui-step-vertical']" v-for="(item, index) in items"
:key="index" @tap.stop="handleClick(index)">
<view class="tui-step-item-ico" :class="[direction === 'column' ? 'tui-step-column_ico' : 'tui-step-row_ico']" :style="{ width: direction === 'column' ? '36rpx' : '100%' }">
<view v-if="!item.name && !item.icon" class="tui-step-ico"
:style="{
width: type == 2 || activeSteps === index ? '36rpx' : '16rpx',
height: type == 2 || activeSteps === index ? '36rpx' : '16rpx',
backgroundColor: index <= activeSteps ? activeColor : type == 2 ? '#fff' : deactiveColor,
borderColor: index <= activeSteps ? activeColor : deactiveColor
}">
<text v-if="activeSteps !== index"
:style="{ color: index <= activeSteps ? '#fff' : '' }">{{ type == 1 ? '' : index + 1 }}</text>
<tui-icon name="check" :size="16" color="#fff" v-if="activeSteps === index"></tui-icon>
</view>
<view class="tui-step-custom" :style="{ backgroundColor: backgroundColor }"
v-if="item.name || item.icon">
<tui-icon :name="item.name" :size="20" :color="index <= activeSteps ? activeColor : deactiveColor"
v-if="item.name"></tui-icon>
<image :src="index <= activeSteps ? item.activeIcon : item.icon" class="tui-step-img"
mode="widthFix" v-if="!item.name"></image>
</view>
<view class="tui-step-line"
:class="['tui-step-' + direction + '_line', direction == 'column' && (item.name || item.icon) ? 'tui-custom-left' : '']"
:style="{
borderColor: index <= activeSteps - 1 ? activeColor : deactiveColor,
borderRightStyle: direction == 'column' ? lineStyle : '',
borderTopStyle: direction == 'column' ? '' : lineStyle
}" v-if="index != items.length - 1"></view>
</view>
<view class="tui-step-item-main" :class="['tui-step-' + direction + '_item_main']">
<view class="tui-step-item-title" :style="{
color: index <= activeSteps ? activeColor : deactiveColor,
fontSize: titleSize + 'rpx',
lineHeight: titleSize + 'rpx',
fontWeight: bold ? 'bold' : 'normal'
}">
{{ item.title }}
</view>
<view class="tui-step-item-content"
:style="{ color: index <= activeSteps ? activeColor : deactiveColor, fontSize: descSize + 'rpx' }">
{{ item.desc }}</view>
</view>
</view>
</view>
</template>
<script>
//
export default {
name: 'tuiSteps',
emits: ['click'],
props: {
// 1- 2-
type: {
type: Number,
default: 1
},
spacing: {
type: String,
default: '160rpx'
},
// row column
direction: {
type: String,
default: 'row'
},
//
activeColor: {
type: String,
default: '#5677fc'
},
//
deactiveColor: {
type: String,
default: '#999999'
},
//title
titleSize: {
type: Number,
default: 28
},
//title
bold: {
type: Boolean,
default: false
},
//desc
descSize: {
type: Number,
default: 24
},
//
activeSteps: {
type: Number,
default: -1
},
//线 border线
lineStyle: {
type: String,
default: 'solid'
},
/**
* [{
title: "标题",
desc: "描述",
name:"字体图标 thorui icon内",
icon:"图片图标",
activeIcon:"已完成步骤显示图片图标"
}]
* */
items: {
type: Array,
default () {
return [];
}
},
//item
backgroundColor: {
type: String,
default: '#fff'
}
},
data() {
return {};
},
methods: {
handleClick(index) {
this.$emit('click', {
index: index
});
}
}
};
</script>
<style scoped>
.tui-steps-box {
width: 100%;
display: flex;
justify-content: center;
}
.tui-steps-column {
flex-direction: column;
}
.tui-step-ico {
border-radius: 50%;
position: relative;
z-index: 3;
margin: 0 auto;
border-width: 1rpx;
border-style: solid;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.tui-step-row_ico {
align-items: center;
}
.tui-step-column_ico {
align-items: flex-start;
}
.tui-step-line {
position: absolute;
left: 50%;
top: 20rpx;
width: 100%;
height: 0rpx;
border-top-width: 1rpx;
z-index: 2;
transform: translateY(-50%) translateZ(0);
}
.tui-step-row_item_main {
text-align: center;
}
.tui-step-item {
font-size: 24rpx;
position: relative;
box-sizing: border-box;
}
.tui-step-item-ico {
height: 36rpx;
display: flex;
justify-content: center;
}
.tui-step-custom {
display: flex;
align-items: center;
justify-content: center;
width: 48rpx;
height: 40rpx;
position: relative;
z-index: 4;
margin: 0 auto;
}
.tui-step-img {
width: 40rpx;
height: 40rpx;
}
.tui-step-item-main {
margin-top: 16rpx;
clear: both;
}
.tui-step-item-title {
word-break: break-all;
}
.tui-step-item-content {
margin-top: 8rpx;
word-break: break-all;
}
.tui-step-vertical {
width: 100%;
display: flex;
padding-bottom: 60rpx;
}
.tui-step-column_item_main {
margin-top: 0;
padding-left: 20rpx;
}
.tui-step-column_line {
position: absolute;
height: 100%;
top: 0;
left: 18rpx;
margin: 0;
width: 0rpx;
border-right-width: 1rpx;
transform: none !important;
}
.tui-custom-left {
left: 20rpx !important;
}
</style>

View File

@ -0,0 +1,125 @@
<template>
<view class="tui-sticky-class" :change:prop="parse.stickyChange" :prop="scrollTop" :data-top="top" :data-height="height"
:data-stickytop="stickyTop" :data-container="container" :data-isNativeHeader="isNativeHeader" :data-index="index">
<!--sticky 容器-->
<view class="tui-sticky-seat" :style="{ height: stickyHeight, backgroundColor: backgroundColor }"></view>
<view class="tui-sticky-bar">
<slot name="header"></slot>
</view>
<!--sticky 容器-->
<!--内容-->
<slot name="content"></slot>
</view>
</template>
<script src="./tui-sticky.wxs" module="parse" lang="wxs"></script>
<script>
export default {
name: 'tuiStickyWxs',
emits: ['prop', 'change'],
props: {
scrollTop: {
type: [Number, String],
value: 0
},
//px
stickyTop: {
type: [Number, String],
// #ifndef H5
default: 0,
// #endif
// #ifdef H5
default: 44
// #endif
},
//content
container: {
type: Boolean,
default: false
},
//header
isNativeHeader: {
type: Boolean,
default: true
},
// rpx
stickyHeight: {
type: String,
default: 'auto'
},
//
backgroundColor: {
type: String,
default: 'transparent'
},
//[使,0]
recalc: {
type: Number,
default: 0
},
//
index: {
type: [Number, String],
default: 0
}
},
watch: {
recalc(newValue, oldValue) {
this.updateScrollChange(() => {
//prop scrollTop(+0.1),change
this.$emit("prop",{})
});
}
},
mounted() {
setTimeout(() => {
this.updateScrollChange();
}, 20);
},
data() {
return {
timer: null,
top: 0,
height: 0
};
},
methods: {
updateScrollChange(callback) {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
this.timer = setTimeout(() => {
const className = '.tui-sticky-class';
const query = uni.createSelectorQuery().in(this);
query
.select(className)
.boundingClientRect(res => {
if (res) {
this.top = res.top + (this.scrollTop || 0);
this.height = res.height;
callback && callback();
this.$emit('change', {
index: Number(this.index),
top: this.top
});
}
})
.exec();
}, 0);
}
}
};
</script>
<style scoped>
.tui-sticky-fixed {
width: 100%;
position: fixed;
left: 0;
z-index: 998;
}
.tui-sticky-seat {
display: none;
}
</style>

View File

@ -0,0 +1,44 @@
var stickyChange = function(scrollTop, oldScrollTop, ownerInstance, ins) {
if (!oldScrollTop && scrollTop === 0) return false;
var dataset = ins.getDataset()
var top = +dataset.top;
var height = +dataset.height;
var stickyTop = +dataset.stickytop;
var isNativeHeader = dataset.isnativeheader;
var isFixed = false;
var distance = stickyTop
// #ifdef H5
if (isNativeHeader) {
distance = distance - 44
distance = distance < 0 ? 0 : distance
}
// #endif
if (dataset.container) {
isFixed = (scrollTop + distance >= top && scrollTop + distance < top + height) ? true : false
} else {
isFixed = scrollTop + distance >= top ? true : false
}
if (isFixed) {
ownerInstance.selectComponent('.tui-sticky-bar').setStyle({
"top": stickyTop + 'px'
}).addClass('tui-sticky-fixed')
ownerInstance.selectComponent('.tui-sticky-seat').setStyle({
"display": 'block'
})
} else {
ownerInstance.selectComponent('.tui-sticky-bar').setStyle({
"top": 'auto'
}).removeClass('tui-sticky-fixed')
ownerInstance.selectComponent('.tui-sticky-seat').setStyle({
"display": 'none'
})
}
ownerInstance.triggerEvent("sticky", [{
isFixed: isFixed,
index: parseInt(dataset.index)
}])
}
module.exports = {
stickyChange: stickyChange
}

View File

@ -0,0 +1,155 @@
<template>
<view class="tui-sticky-class">
<!--sticky 容器-->
<view :style="{height: stickyHeight,backgroundColor:backgroundColor}" v-if="isFixed"></view>
<view :class="{'tui-sticky-fixed':isFixed}" :style="{top:isFixed?stickyTop+'px':'auto'}">
<slot name="header"></slot>
</view>
<!--sticky 容器-->
<!--内容-->
<slot name="content"></slot>
</view>
</template>
<script>
export default {
name: "tuiSticky",
emits: ['sticky', 'change'],
props: {
scrollTop: {
type: Number
},
//px
stickyTop: {
type: [Number, String]
// #ifndef H5
,
default: 0
// #endif
// #ifdef H5
,
default: 44
// #endif
},
//content
container: {
type: Boolean,
default: false
},
//header
isNativeHeader: {
type: Boolean,
default: true
},
// rpx
stickyHeight: {
type: String,
default: "auto"
},
//
backgroundColor: {
type: String,
default: "transparent"
},
//[使,0]
recalc: {
type: Number,
default: 0
},
//
index: {
type: [Number, String],
default: 0
}
},
watch: {
scrollTop(newValue, oldValue) {
if (this.initialize != 0) {
this.updateScrollChange(() => {
this.updateStickyChange();
this.initialize = 0
});
} else {
this.updateStickyChange();
}
},
recalc(newValue, oldValue) {
this.updateScrollChange(() => {
this.updateStickyChange();
this.initialize = 0;
});
}
},
created() {
this.initialize = this.recalc
},
mounted() {
setTimeout(() => {
this.updateScrollChange();
}, 20)
},
data() {
return {
timer: null,
top: 0,
height: 0,
isFixed: false,
initialize: 0 //
};
},
methods: {
updateStickyChange() {
const top = this.top;
const height = this.height;
const scrollTop = this.scrollTop
let stickyTop = this.stickyTop
// #ifdef H5
if (this.isNativeHeader) {
stickyTop = stickyTop - 44
stickyTop = stickyTop < 0 ? 0 : stickyTop
}
// #endif
if (this.container) {
this.isFixed = (scrollTop + stickyTop >= top && scrollTop + stickyTop < top + height) ? true : false
} else {
this.isFixed = scrollTop + stickyTop >= top ? true : false
}
//
this.$emit("sticky", {
isFixed: this.isFixed,
index: this.index
})
},
updateScrollChange(callback) {
if (this.timer) {
clearTimeout(this.timer)
this.timer = null
}
this.timer = setTimeout(() => {
const className = '.tui-sticky-class';
const query = uni.createSelectorQuery().in(this);
query.select(className).boundingClientRect((res) => {
if (res) {
this.top = res.top + (this.scrollTop || 0);
this.height = res.height;
callback && callback();
this.$emit("change", {
index: Number(this.index),
top: this.top
})
}
}).exec()
}, 0)
}
}
}
</script>
<style scoped>
.tui-sticky-fixed {
width: 100%;
position: fixed;
left: 0;
z-index: 888;
}
</style>

View File

@ -0,0 +1,360 @@
<template>
<view class="tui-tag" :hover-class="hover ? 'tui-tag-opcity' : ''" :hover-stay-time="150" :class="[originLeft ? 'tui-origin-left' : '', originRight ? 'tui-origin-right' : '', getClassName(shape, plain), getTypeClass(type, plain)]"
:style="{ transform: `scale(${scaleMultiple})`, padding: padding, margin: margin, fontSize: size, lineHeight: size }"
@tap="handleClick">
<slot></slot>
</view>
</template>
<script>
export default {
name: 'tuiTag',
emits: ['click'],
props: {
type: {
type: String,
default: 'primary'
},
//padding
padding: {
type: String,
default: '16rpx 26rpx'
},
margin: {
type: String,
default: '0'
},
// rpx
size: {
type: String,
default: '28rpx'
},
// circle, squarecircleLeftcircleRight
shape: {
type: String,
default: 'square'
},
//
plain: {
type: Boolean,
default: false
},
//
hover: {
type: Boolean,
default: false
},
//
scaleMultiple: {
type: Number,
default: 1
},
originLeft: {
type: Boolean,
default: false
},
originRight: {
type: Boolean,
default: false
},
index: {
type: Number,
default: 0
}
},
methods: {
handleClick() {
this.$emit('click', {
index: this.index
});
},
getTypeClass: function(type, plain) {
return plain ? 'tui-' + type + '-outline' : 'tui-' + type;
},
getClassName: function(shape, plain) {
//circle, squarecircleLeftcircleRight
var className = plain ? 'tui-tag-outline ' : '';
if (shape != 'square') {
if (shape == 'circle') {
className = className + (plain ? 'tui-tag-outline-fillet' : 'tui-tag-fillet');
} else if (shape == 'circleLeft') {
className = className + 'tui-tag-fillet-left';
} else if (shape == 'circleRight') {
className = className + 'tui-tag-fillet-right';
}
}
return className;
}
}
};
</script>
<style scoped>
/* color start*/
.tui-primary {
background: #5677fc !important;
color: #fff;
}
.tui-light-primary {
background: #5c8dff !important;
color: #fff;
}
.tui-dark-primary {
background: #4a67d6 !important;
color: #fff;
}
.tui-dLight-primary {
background: #4e77d9 !important;
color: #fff;
}
.tui-danger {
background: #ed3f14 !important;
color: #fff;
}
.tui-red {
background: #ff201f !important;
color: #fff;
}
.tui-warning {
background: #ff7900 !important;
color: #fff;
}
.tui-green {
background: #19be6b !important;
color: #fff;
}
.tui-high-green {
background: #52dcae !important;
color: #52dcae;
}
.tui-black {
background: #000 !important;
color: #fff;
}
.tui-white {
background: #fff !important;
color: #333 !important;
}
.tui-translucent {
background: rgba(0, 0, 0, 0.7);
}
.tui-light-black {
background: #333 !important;
}
.tui-gray {
background: #ededed !important;
}
.tui-phcolor-gray {
background: #ccc !important;
}
.tui-divider-gray {
background: #eaeef1 !important;
}
.tui-btn-gray {
background: #ededed !important;
color: #999 !important;
}
.tui-hover-gray {
background: #f7f7f9 !important;
}
.tui-bg-gray {
background: #fafafa !important;
}
.tui-light-blue {
background: #ecf6fd;
color: #4dabeb !important;
}
.tui-light-brownish {
background: #fcebef;
color: #8a5966 !important;
}
.tui-light-orange {
background: #fef5eb;
color: #faa851 !important;
}
.tui-light-green {
background: #e8f6e8;
color: #44cf85 !important;
}
.tui-primary-outline::after {
border: 1px solid #5677fc !important;
}
.tui-primary-outline {
color: #5677fc !important;
background: none;
}
.tui-danger-outline {
color: #ed3f14 !important;
background: none;
}
.tui-danger-outline::after {
border: 1px solid #ed3f14 !important;
}
.tui-red-outline {
color: #ff201f !important;
background: none;
}
.tui-red-outline::after {
border: 1px solid #ff201f !important;
}
.tui-warning-outline {
color: #ff7900 !important;
background: none;
}
.tui-warning-outline::after {
border: 1px solid #ff7900 !important;
}
.tui-green-outline {
color: #44cf85 !important;
background: none;
}
.tui-green-outline::after {
border: 1px solid #44cf85 !important;
}
.tui-high-green-outline {
color: #52dcae !important;
background: none;
}
.tui-high-green-outline::after {
border: 1px solid #52dcae !important;
}
.tui-gray-outline {
color: #999 !important;
background: none;
}
.tui-gray-outline::after {
border: 1px solid #ccc !important;
}
.tui-black-outline {
color: #333 !important;
background: none;
}
.tui-black-outline::after {
border: 1px solid #333 !important;
}
.tui-white-outline {
color: #fff !important;
background: none;
}
.tui-white-outline::after {
border: 1px solid #fff !important;
}
/* color end*/
/* tag start*/
.tui-tag {
padding: 16rpx 26rpx;
font-size: 28rpx;
border-radius: 6rpx;
/* display: inline-block;
vertical-align: middle; */
line-height: 28rpx;
}
.tui-tag-small {
padding: 10rpx 16rpx;
font-size: 24rpx;
border-radius: 6rpx;
/* display: inline-block;
vertical-align: middle; */
line-height: 24rpx;
}
.tui-tag-outline {
position: relative;
background: none;
color: #5677fc;
}
.tui-tag-outline::after {
content: "";
position: absolute;
width: 200%;
height: 200%;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: scale(0.5, 0.5);
transform: scale(0.5, 0.5);
-webkit-box-sizing: border-box;
box-sizing: border-box;
left: 0;
top: 0;
border-radius: 80rpx;
border: 1px solid #5677fc;
}
.tui-tag-fillet {
border-radius: 50rpx;
}
.tui-white.tui-tag-fillet::after {
border-radius: 80rpx;
}
.tui-tag-outline-fillet::after {
border-radius: 80rpx;
}
.tui-tag-fillet-left {
border-radius: 50rpx 0 0 50rpx;
}
.tui-tag-fillet-right {
border-radius: 0 50rpx 50rpx 0;
}
.tui-tag-fillet-left.tui-tag-outline::after {
border-radius: 100rpx 0 0 100rpx;
}
.tui-tag-fillet-right.tui-tag-outline::after {
border-radius: 0 100rpx 100rpx 0;
}
/* tag end*/
</style>

View File

@ -0,0 +1,129 @@
<template>
<block v-if="position == 'top'">
<view class="tui-tips-class tui-toptips" :style="{backgroundColor:backgroundColor,color:color,fontSize:size+'rpx'}" :class="[show ? 'tui-top-show' : '']">{{ msg }}</view>
</block>
<block v-else>
<view class="tui-tips-class tui-toast" :class="[position == 'center' ? 'tui-centertips' : 'tui-bottomtips', show ? 'tui-toast-show' : '']">
<view class="tui-tips-content" :style="{backgroundColor:backgroundColor,color:color,fontSize:size+'rpx'}">{{ msg }}</view>
</view>
</block>
</template>
<script>
export default {
name: 'tuiTips',
props: {
//top bottom center
position: {
type: String,
default: 'top'
},
backgroundColor: {
type: String,
default: 'rgba(0, 0, 0, 0.7)'
},
color: {
type: String,
default: '#fff'
},
size: {
type: Number,
default: 30
}
},
data() {
return {
timer: null,
show: false,
msg: '无法连接到服务器~'
};
},
methods: {
showTips: function(options) {
const {duration = 2000 } = options;
clearTimeout(this.timer);
this.show = true;
// this.duration = duration < 2000 ? 2000 : duration;
this.msg = options.msg;
this.timer = setTimeout(() => {
this.show = false;
clearTimeout(this.timer);
this.timer = null;
}, duration);
}
}
};
</script>
<style scoped>
/*顶部消息提醒 start*/
.tui-toptips {
width: 100%;
padding: 18rpx 30rpx;
box-sizing: border-box;
position: fixed;
z-index: 9999;
left: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
word-break: break-all;
opacity: 0;
transform: translateZ(0) translateY(-100%);
transition: all 0.3s ease-in-out;
}
.tui-top-show {
transform: translateZ(0) translateY(0);
opacity: 1;
}
/*顶部消息提醒 end*/
/*toast消息提醒 start*/
/*
1fixed 元素宽度无法自适应所以增加了子元素
2fixed display冲突导致动画效果消失暂时使用visibility替代
*/
.tui-toast {
width: 80%;
box-sizing: border-box;
color: #fff;
font-size: 28rpx;
position: fixed;
visibility: hidden;
opacity: 0;
left: 50%;
transition: all 0.3s ease-in-out;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.tui-toast-show {
visibility: visible;
opacity: 1;
}
.tui-tips-content {
word-wrap: break-word;
word-break: break-all;
border-radius: 8rpx;
padding: 18rpx 30rpx;
}
.tui-bottomtips {
bottom: 120rpx;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
}
.tui-centertips {
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
</style>

View File

@ -0,0 +1,121 @@
<template>
<view class="tui-toast" :class="[visible?'tui-toast-show':'',content?'tui-toast-padding':'',icon?'':'tui-unicon-padding']" :style="{width:getWidth(icon,content),zIndex:zIndex}">
<image :src="imgUrl" class="tui-toast-img" v-if="icon"></image>
<view class="tui-toast-text" :class="[icon?'':'tui-unicon']">{{title}}</view>
<view class="tui-toast-text tui-content-ptop" v-if="content && icon">{{content}}</view>
</view>
</template>
<script>
export default {
name: "tuiToast",
props: {
zIndex:{
type:Number,
default:99999
}
},
data() {
return {
timer: null,
//
visible: false,
//
title: "操作成功",
//
content: "",
//icon
icon:false,
imgUrl:""
};
},
methods: {
show: function(options) {
let {
duration = 2000,
icon=false
} = options;
clearTimeout(this.timer);
this.visible = true;
this.title = options.title || "";
this.content = options.content || "";
this.icon=icon;
if(icon && options.imgUrl){
this.imgUrl=options.imgUrl
}
this.timer = setTimeout(() => {
this.visible = false;
clearTimeout(this.timer);
this.timer = null;
}, duration);
},
getWidth(icon,content){
let width="auto";
if(icon){
width=content?'420rpx':'360rpx'
}
return width
}
}
}
</script>
<style scoped>
.tui-toast {
background-color: rgba(0, 0, 0, 0.75);
border-radius: 10rpx;
position: fixed;
visibility: hidden;
opacity: 0;
left: 50%;
top: 48%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
transition: 0.3s ease-in-out;
transition-property:opacity,visibility;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 60rpx 20rpx 54rpx 20rpx;
box-sizing: border-box;
}
.tui-toast-padding {
padding-top: 50rpx !important;
padding-bottom: 50rpx !important;
}
.tui-unicon-padding {
padding: 24rpx 40rpx !important;
word-break: break-all;
}
.tui-toast-show {
visibility: visible;
opacity: 1;
}
.tui-toast-img {
width: 120rpx;
height: 120rpx;
display: block;
margin-bottom: 28rpx;
}
.tui-toast-text {
font-size: 30rpx;
line-height: 30rpx;
font-weight: 400;
color: #fff;
text-align: center;
}
.tui-unicon{
line-height: 40rpx !important;
font-size: 32rpx !important;
}
.tui-content-ptop {
padding-top: 10rpx;
font-size: 26rpx !important;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,163 @@
<template>
<view class="code-box">
<view class="flex-box">
<input
type="number"
focus="true"
:maxlength="maxlength"
class="hide-input"
@input="getVal"
/>
<block v-for="(item, index) in ranges" :key="index">
<view :class="['item', { active: codeIndex === item, middle: type === 'middle', bottom: type === 'bottom', box: type === 'box' }]">
<view class="line" v-if="type !== 'middle'"></view>
<view v-if="type === 'middle' && codeIndex <= item" class="bottom-line"></view>
<block v-if="isPwd && codeArr.length >= item">
<text class="dot">.</text>
</block>
<block v-else> {{ codeArr[index] ? codeArr[index] : ''}}</block>
</view>
</block>
</view>
</view>
</template>
<script>
export default {
name: 'uiOneInput',
props: {
// 4/6
maxlength: {
type: Number,
default: 6
},
isPwd: {
type: Boolean,
default: false
},
// middle-middle line, bottom-bottom line, box-square box
type: {
type: String,
default: "middle"
}
},
watch: {
maxlength: {
immediate: true,
handler: function(newV) {
if (newV === 6) {
this.ranges = [1, 2, 3, 4, 5, 6]
} else {
this.ranges = [1, 2, 3, 4]
}
}
}
},
data() {
return {
codeIndex: 1,
codeArr: [],
ranges: [1, 2, 3, 4]
}
},
methods: {
getVal(e) {
let { value } = e.detail
let arr = value.split('')
this.codeIndex = arr.length + 1
this.codeArr = arr
if (this.codeIndex > Number(this.maxlength)) {
this.$emit('finish',this.codeArr.join(''))
}
}
}
}
</script>
<style scoped>
@keyframes twinkling {
0% {
opacity: 0.2;
}
50% {
opacity: 0.5;
}
100% {
opacity: 0.2;
}
}
.code-box {
text-align: center;
}
.flex-box {
display: flex;
justify-content: center;
flex-wrap: wrap;
position: relative;
}
.flex-box .hide-input {
position: absolute;
top: 0;
left: -100%;
width: 200%;
height: 100%;
text-align: left;
z-index: 9;
opacity: 1;
}
.flex-box .item {
position: relative;
width: 92upx;
height: 92upx;
margin-right: 20upx;
font-size: 40upx;
color: #333333;
line-height: 92upx;
}
.flex-box .item:last-child {
margin-right: 0;
}
.flex-box .middle {
border: none;
}
.flex-box .box {
box-sizing: border-box;
border: 2upx solid #dae3eb;
border-radius: 20rpx;
}
.flex-box .bottom {
box-sizing: border-box;
border-bottom: 8rpx solid #212121;
}
.flex-box .active {
border-color: #0567b8;
}
.flex-box .active .line {
display: block;
}
.flex-box .line {
display: none;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 2upx;
height: 40upx;
background: #333333;
animation: twinkling 1s infinite ease;
}
.flex-box .dot{
font-size: 80upx;
line-height: 40upx;
}
.flex-box .bottom-line {
height: 4px;
background: #000000;
width: 80%;
position: absolute;
border-radius: 2px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,172 @@
# 使用
下载下来直接引入,然后使用。也可以直接复制下面的源码内容。无任何依赖。
`type`可以控制是 中间划线(middle) 下划线(bottom) 方宽(box) 样式。
# 源码
```vue
<template>
<view class="code-box">
<view class="flex-box">
<input
type="number"
focus="true"
:maxlength="maxlength"
class="hide-input"
@input="getVal"
/>
<block v-for="(item, index) in ranges" :key="index">
<view :class="['item', { active: codeIndex === item, middle: type === 'middle', bottom: type === 'bottom', box: type === 'box' }]">
<view class="line" v-if="type !== 'middle'"></view>
<view v-if="type === 'middle' && codeIndex <= item" class="bottom-line"></view>
<block v-if="isPwd && codeArr.length >= item">
<text class="dot">.</text>
</block>
<block v-else> {{ codeArr[index] ? codeArr[index] : ''}}</block>
</view>
</block>
</view>
</view>
</template>
<script>
export default {
name: 'uiOneInput',
props: {
// 4/6
maxlength: {
type: Number,
default: 4
},
isPwd: {
type: Boolean,
default: false
},
// middle-middle line, bottom-bottom line, box-square box
type: {
type: String,
default: "middle"
}
},
watch: {
maxlength: {
immediate: true,
handler: function(newV) {
if (newV === 6) {
this.ranges = [1, 2, 3, 4, 5, 6]
} else {
this.ranges = [1, 2, 3, 4]
}
}
}
},
data() {
return {
codeIndex: 1,
codeArr: [],
ranges: [1, 2, 3, 4]
}
},
methods: {
getVal(e) {
let { value } = e.detail
let arr = value.split('')
this.codeIndex = arr.length + 1
this.codeArr = arr
if (this.codeIndex > Number(this.maxlength)) {
this.$emit('finish',this.codeArr.join(''))
}
}
}
}
</script>
<style scoped>
@keyframes twinkling {
0% {
opacity: 0.2;
}
50% {
opacity: 0.5;
}
100% {
opacity: 0.2;
}
}
.code-box {
text-align: center;
}
.flex-box {
display: flex;
justify-content: center;
flex-wrap: wrap;
position: relative;
}
.flex-box .hide-input {
position: absolute;
top: 0;
left: -100%;
width: 200%;
height: 100%;
text-align: left;
z-index: 9;
opacity: 1;
}
.flex-box .item {
position: relative;
width: 100upx;
height: 100upx;
margin-right: 18upx;
font-size: 70upx;
font-weight: bold;
color: #333333;
line-height: 100upx;
}
.flex-box .item:last-child {
margin-right: 0;
}
.flex-box .middle {
border: none;
}
.flex-box .box {
box-sizing: border-box;
border: 2upx solid #cccccc;
border-radius: 6rpx;
}
.flex-box .bottom {
box-sizing: border-box;
border-bottom: 8rpx solid #212121;
}
.flex-box .active {
border-color: #00C777;
}
.flex-box .active .line {
display: block;
}
.flex-box .line {
display: none;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 2upx;
height: 40upx;
background: #333333;
animation: twinkling 1s infinite ease;
}
.flex-box .dot{
font-size: 80upx;
line-height: 40upx;
}
.flex-box .bottom-line {
height: 4px;
background: #000000;
width: 80%;
position: absolute;
border-radius: 2px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
```

Binary file not shown.

201
jsFile/base64-src.js Normal file
View File

@ -0,0 +1,201 @@
function getLocalFilePath(path) {
if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf(
'_downloads') === 0) {
return path
}
if (path.indexOf('file://') === 0) {
return path
}
if (path.indexOf('/storage/emulated/0/') === 0) {
return path
}
if (path.indexOf('/') === 0) {
var localFilePath = plus.io.convertAbsoluteFileSystem(path)
if (localFilePath !== path) {
return localFilePath
} else {
path = path.substr(1)
}
}
return '_www/' + path
}
function dataUrlToBase64(str) {
var array = str.split(',')
return array[array.length - 1]
}
var index = 0
function getNewFileId() {
return Date.now() + String(index++)
}
function biggerThan(v1, v2) {
var v1Array = v1.split('.')
var v2Array = v2.split('.')
var update = false
for (var index = 0; index < v2Array.length; index++) {
var diff = v1Array[index] - v2Array[index]
if (diff !== 0) {
update = diff > 0
break
}
}
return update
}
export function pathToBase64(path) {
return new Promise(function(resolve, reject) {
if (typeof window === 'object' && 'document' in window) {
if (typeof FileReader === 'function') {
var xhr = new XMLHttpRequest()
xhr.open('GET', path, true)
xhr.responseType = 'blob'
xhr.onload = function() {
if (this.status === 200) {
let fileReader = new FileReader()
fileReader.onload = function(e) {
resolve(e.target.result)
}
fileReader.onerror = reject
fileReader.readAsDataURL(this.response)
}
}
xhr.onerror = reject
xhr.send()
return
}
var canvas = document.createElement('canvas')
var c2x = canvas.getContext('2d')
var img = new Image
img.onload = function() {
canvas.width = img.width
canvas.height = img.height
c2x.drawImage(img, 0, 0)
resolve(canvas.toDataURL())
canvas.height = canvas.width = 0
}
img.onerror = reject
img.src = path
return
}
if (typeof plus === 'object') {
plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) {
entry.file(function(file) {
var fileReader = new plus.io.FileReader()
fileReader.onload = function(data) {
resolve(data.target.result)
}
fileReader.onerror = function(error) {
reject(error)
}
fileReader.readAsDataURL(file)
}, function(error) {
reject(error)
})
}, function(error) {
reject(error)
})
return
}
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
wx.getFileSystemManager().readFile({
filePath: path,
encoding: 'base64',
success: function(res) {
resolve('data:image/png;base64,' + res.data)
},
fail: function(error) {
reject(error)
}
})
return
}
reject(new Error('not support'))
})
}
export function base64ToPath(base64) {
return new Promise(function(resolve, reject) {
if (typeof window === 'object' && 'document' in window) {
base64 = base64.split(',')
var type = base64[0].match(/:(.*?);/)[1]
var str = atob(base64[1])
var n = str.length
var array = new Uint8Array(n)
while (n--) {
array[n] = str.charCodeAt(n)
}
return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], {
type: type
})))
}
var extName = base64.split(',')[0].match(/data\:\S+\/(\S+);/)
if (extName) {
extName = extName[1]
} else {
reject(new Error('base64 error'))
}
var fileName = getNewFileId() + '.' + extName
if (typeof plus === 'object') {
var basePath = '_doc'
var dirPath = 'uniapp_temp'
var filePath = basePath + '/' + dirPath + '/' + fileName
if (!biggerThan(plus.os.name === 'Android' ? '1.9.9.80627' : '1.9.9.80472', plus.runtime
.innerVersion)) {
plus.io.resolveLocalFileSystemURL(basePath, function(entry) {
entry.getDirectory(dirPath, {
create: true,
exclusive: false,
}, function(entry) {
entry.getFile(fileName, {
create: true,
exclusive: false,
}, function(entry) {
entry.createWriter(function(writer) {
writer.onwrite = function() {
resolve(filePath)
}
writer.onerror = reject
writer.seek(0)
writer.writeAsBinary(dataUrlToBase64(base64))
}, reject)
}, reject)
}, reject)
}, reject)
return
}
var bitmap = new plus.nativeObj.Bitmap(fileName)
bitmap.loadBase64Data(base64, function() {
bitmap.save(filePath, {}, function() {
bitmap.clear()
resolve(filePath)
}, function(error) {
bitmap.clear()
reject(error)
})
}, function(error) {
bitmap.clear()
reject(error)
})
return
}
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
var filePath = wx.env.USER_DATA_PATH + '/' + fileName
wx.getFileSystemManager().writeFile({
filePath: filePath,
data: dataUrlToBase64(base64),
encoding: 'base64',
success: function() {
resolve(filePath)
},
fail: function(error) {
reject(error)
}
})
return
}
reject(new Error('not support'))
})
}

891
jsFile/map/qqmap-wx-jssdk.min.js vendored Normal file
View File

@ -0,0 +1,891 @@
var ERROR_CONF = {
KEY_ERR: 311,
KEY_ERR_MSG: 'key格式错误',
PARAM_ERR: 310,
PARAM_ERR_MSG: '请求参数信息有误',
SYSTEM_ERR: 600,
SYSTEM_ERR_MSG: '系统错误',
WX_ERR_CODE: 1000,
WX_OK_CODE: 200
};
var BASE_URL = 'https://apis.map.qq.com/ws/';
var URL_SEARCH = BASE_URL + 'place/v1/search';
var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion';
var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/';
var URL_CITY_LIST = BASE_URL + 'district/v1/list';
var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren';
var URL_DISTANCE = BASE_URL + 'distance/v1/';
var URL_DIRECTION = BASE_URL + 'direction/v1/';
var MODE = {
driving: 'driving',
transit: 'transit'
};
var EARTH_RADIUS = 6378136.49;
var Utils = {
safeAdd(x, y) {
var lsw = (x & 0xffff) + (y & 0xffff);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xffff)
},
bitRotateLeft(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt))
},
md5cmn(q, a, b, x, s, t) {
return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b)
},
md5ff(a, b, c, d, x, s, t) {
return this.md5cmn((b & c) | (~b & d), a, b, x, s, t)
},
md5gg(a, b, c, d, x, s, t) {
return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t)
},
md5hh(a, b, c, d, x, s, t) {
return this.md5cmn(b ^ c ^ d, a, b, x, s, t)
},
md5ii(a, b, c, d, x, s, t) {
return this.md5cmn(c ^ (b | ~d), a, b, x, s, t)
},
binlMD5(x, len) {
x[len >> 5] |= 0x80 << (len % 32);
x[((len + 64) >>> 9 << 4) + 14] = len;
var i;
var olda;
var oldb;
var oldc;
var oldd;
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
for (i = 0; i < x.length; i += 16) {
olda = a;
oldb = b;
oldc = c;
oldd = d;
a = this.md5ff(a, b, c, d, x[i], 7, -680876936);
d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586);
c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819);
b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897);
d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983);
a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063);
b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101);
c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510);
d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713);
b = this.md5gg(b, c, d, a, x[i], 20, -373897302);
a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691);
d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083);
c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335);
b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848);
a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438);
d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961);
b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784);
c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558);
d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556);
a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632);
b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174);
d = this.md5hh(d, a, b, c, x[i], 11, -358537222);
c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979);
b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189);
a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487);
d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835);
c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520);
b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651);
a = this.md5ii(a, b, c, d, x[i], 6, -198630844);
d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055);
a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523);
b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744);
c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070);
d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259);
b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551);
a = this.safeAdd(a, olda);
b = this.safeAdd(b, oldb);
c = this.safeAdd(c, oldc);
d = this.safeAdd(d, oldd)
}
return [a, b, c, d]
},
binl2rstr(input) {
var i;
var output = '';
var length32 = input.length * 32;
for (i = 0; i < length32; i += 8) {
output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff)
}
return output
},
rstr2binl(input) {
var i;
var output = [];
output[(input.length >> 2) - 1] = undefined;
for (i = 0; i < output.length; i += 1) {
output[i] = 0
}
var length8 = input.length * 8;
for (i = 0; i < length8; i += 8) {
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32)
}
return output
},
rstrMD5(s) {
return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8))
},
rstrHMACMD5(key, data) {
var i;
var bkey = this.rstr2binl(key);
var ipad = [];
var opad = [];
var hash;
ipad[15] = opad[15] = undefined;
if (bkey.length > 16) {
bkey = this.binlMD5(bkey, key.length * 8)
}
for (i = 0; i < 16; i += 1) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5c5c5c5c
}
hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8);
return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128))
},
rstr2hex(input) {
var hexTab = '0123456789abcdef';
var output = '';
var x;
var i;
for (i = 0; i < input.length; i += 1) {
x = input.charCodeAt(i);
output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f)
}
return output
},
str2rstrUTF8(input) {
return unescape(encodeURIComponent(input))
},
rawMD5(s) {
return this.rstrMD5(this.str2rstrUTF8(s))
},
hexMD5(s) {
return this.rstr2hex(this.rawMD5(s))
},
rawHMACMD5(k, d) {
return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d))
},
hexHMACMD5(k, d) {
return this.rstr2hex(this.rawHMACMD5(k, d))
},
md5(string, key, raw) {
if (!key) {
if (!raw) {
return this.hexMD5(string)
}
return this.rawMD5(string)
}
if (!raw) {
return this.hexHMACMD5(key, string)
}
return this.rawHMACMD5(key, string)
},
getSig(requestParam, sk, feature, mode) {
var sig = null;
var requestArr = [];
Object.keys(requestParam).sort().forEach(function(key) {
requestArr.push(key + '=' + requestParam[key])
});
if (feature == 'search') {
sig = '/ws/place/v1/search?' + requestArr.join('&') + sk
}
if (feature == 'suggest') {
sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk
}
if (feature == 'reverseGeocoder') {
sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk
}
if (feature == 'geocoder') {
sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk
}
if (feature == 'getCityList') {
sig = '/ws/district/v1/list?' + requestArr.join('&') + sk
}
if (feature == 'getDistrictByCityId') {
sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk
}
if (feature == 'calculateDistance') {
sig = '/ws/distance/v1/?' + requestArr.join('&') + sk
}
if (feature == 'direction') {
sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk
}
sig = this.md5(sig);
return sig
},
location2query(data) {
if (typeof data == 'string') {
return data
}
var query = '';
for (var i = 0; i < data.length; i++) {
var d = data[i];
if (!!query) {
query += ';'
}
if (d.location) {
query = query + d.location.lat + ',' + d.location.lng
}
if (d.latitude && d.longitude) {
query = query + d.latitude + ',' + d.longitude
}
}
return query
},
rad(d) {
return d * Math.PI / 180.0
},
getEndLocation(location) {
var to = location.split(';');
var endLocation = [];
for (var i = 0; i < to.length; i++) {
endLocation.push({
lat: parseFloat(to[i].split(',')[0]),
lng: parseFloat(to[i].split(',')[1])
})
}
return endLocation
},
getDistance(latFrom, lngFrom, latTo, lngTo) {
var radLatFrom = this.rad(latFrom);
var radLatTo = this.rad(latTo);
var a = radLatFrom - radLatTo;
var b = this.rad(lngFrom) - this.rad(lngTo);
var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(
radLatTo) * Math.pow(Math.sin(b / 2), 2)));
distance = distance * EARTH_RADIUS;
distance = Math.round(distance * 10000) / 10000;
return parseFloat(distance.toFixed(0))
},
getWXLocation(success, fail, complete) {
wx.getLocation({
type: 'gcj02',
success: success,
fail: fail,
complete: complete
})
},
getLocationParam(location) {
if (typeof location == 'string') {
var locationArr = location.split(',');
if (locationArr.length === 2) {
location = {
latitude: location.split(',')[0],
longitude: location.split(',')[1]
}
} else {
location = {}
}
}
return location
},
polyfillParam(param) {
param.success = param.success || function() {};
param.fail = param.fail || function() {};
param.complete = param.complete || function() {}
},
checkParamKeyEmpty(param, key) {
if (!param[key]) {
var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key + '参数格式有误');
param.fail(errconf);
param.complete(errconf);
return true
}
return false
},
checkKeyword(param) {
return !this.checkParamKeyEmpty(param, 'keyword')
},
checkLocation(param) {
var location = this.getLocationParam(param.location);
if (!location || !location.latitude || !location.longitude) {
var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误');
param.fail(errconf);
param.complete(errconf);
return false
}
return true
},
buildErrorConfig(errCode, errMsg) {
return {
status: errCode,
message: errMsg
}
},
handleData(param, data, feature) {
if (feature == 'search') {
var searchResult = data.data;
var searchSimplify = [];
for (var i = 0; i < searchResult.length; i++) {
searchSimplify.push({
id: searchResult[i].id || null,
title: searchResult[i].title || null,
latitude: searchResult[i].location && searchResult[i].location.lat || null,
longitude: searchResult[i].location && searchResult[i].location.lng || null,
address: searchResult[i].address || null,
category: searchResult[i].category || null,
tel: searchResult[i].tel || null,
adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null,
city: searchResult[i].ad_info && searchResult[i].ad_info.city || null,
district: searchResult[i].ad_info && searchResult[i].ad_info.district || null,
province: searchResult[i].ad_info && searchResult[i].ad_info.province || null
})
}
param.success(data, {
searchResult: searchResult,
searchSimplify: searchSimplify
})
} else if (feature == 'suggest') {
var suggestResult = data.data;
var suggestSimplify = [];
for (var i = 0; i < suggestResult.length; i++) {
suggestSimplify.push({
adcode: suggestResult[i].adcode || null,
address: suggestResult[i].address || null,
category: suggestResult[i].category || null,
city: suggestResult[i].city || null,
district: suggestResult[i].district || null,
id: suggestResult[i].id || null,
latitude: suggestResult[i].location && suggestResult[i].location.lat || null,
longitude: suggestResult[i].location && suggestResult[i].location.lng || null,
province: suggestResult[i].province || null,
title: suggestResult[i].title || null,
type: suggestResult[i].type || null
})
}
param.success(data, {
suggestResult: suggestResult,
suggestSimplify: suggestSimplify
})
} else if (feature == 'reverseGeocoder') {
var reverseGeocoderResult = data.result;
var reverseGeocoderSimplify = {
address: reverseGeocoderResult.address || null,
latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null,
longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null,
adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null,
city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city ||
null,
district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component
.district || null,
nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component
.nation || null,
province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component
.province || null,
street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component
.street || null,
street_number: reverseGeocoderResult.address_component && reverseGeocoderResult
.address_component.street_number || null,
recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult
.formatted_addresses.recommend || null,
rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses
.rough || null
};
if (reverseGeocoderResult.pois) {
var pois = reverseGeocoderResult.pois;
var poisSimplify = [];
for (var i = 0; i < pois.length; i++) {
poisSimplify.push({
id: pois[i].id || null,
title: pois[i].title || null,
latitude: pois[i].location && pois[i].location.lat || null,
longitude: pois[i].location && pois[i].location.lng || null,
address: pois[i].address || null,
category: pois[i].category || null,
adcode: pois[i].ad_info && pois[i].ad_info.adcode || null,
city: pois[i].ad_info && pois[i].ad_info.city || null,
district: pois[i].ad_info && pois[i].ad_info.district || null,
province: pois[i].ad_info && pois[i].ad_info.province || null
})
}
param.success(data, {
reverseGeocoderResult: reverseGeocoderResult,
reverseGeocoderSimplify: reverseGeocoderSimplify,
pois: pois,
poisSimplify: poisSimplify
})
} else {
param.success(data, {
reverseGeocoderResult: reverseGeocoderResult,
reverseGeocoderSimplify: reverseGeocoderSimplify
})
}
} else if (feature == 'geocoder') {
var geocoderResult = data.result;
var geocoderSimplify = {
title: geocoderResult.title || null,
latitude: geocoderResult.location && geocoderResult.location.lat || null,
longitude: geocoderResult.location && geocoderResult.location.lng || null,
adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null,
province: geocoderResult.address_components && geocoderResult.address_components.province ||
null,
city: geocoderResult.address_components && geocoderResult.address_components.city || null,
district: geocoderResult.address_components && geocoderResult.address_components.district ||
null,
street: geocoderResult.address_components && geocoderResult.address_components.street || null,
street_number: geocoderResult.address_components && geocoderResult.address_components
.street_number || null,
level: geocoderResult.level || null
};
param.success(data, {
geocoderResult: geocoderResult,
geocoderSimplify: geocoderSimplify
})
} else if (feature == 'getCityList') {
var provinceResult = data.result[0];
var cityResult = data.result[1];
var districtResult = data.result[2];
param.success(data, {
provinceResult: provinceResult,
cityResult: cityResult,
districtResult: districtResult
})
} else if (feature == 'getDistrictByCityId') {
var districtByCity = data.result[0];
param.success(data, districtByCity)
} else if (feature == 'calculateDistance') {
var calculateDistanceResult = data.result.elements;
var distance = [];
for (var i = 0; i < calculateDistanceResult.length; i++) {
distance.push(calculateDistanceResult[i].distance)
}
param.success(data, {
calculateDistanceResult: calculateDistanceResult,
distance: distance
})
} else if (feature == 'direction') {
var direction = data.result.routes;
param.success(data, direction)
} else {
param.success(data)
}
},
buildWxRequestConfig(param, options, feature) {
var that = this;
options.header = {
"content-type": "application/json"
};
options.method = 'GET';
options.success = function(res) {
var data = res.data;
if (data.status === 0) {
that.handleData(param, data, feature)
} else {
param.fail(data)
}
};
options.fail = function(res) {
res.statusCode = ERROR_CONF.WX_ERR_CODE;
param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg))
};
options.complete = function(res) {
var statusCode = +res.statusCode;
switch (statusCode) {
case ERROR_CONF.WX_ERR_CODE: {
param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
break
}
case ERROR_CONF.WX_OK_CODE: {
var data = res.data;
if (data.status === 0) {
param.complete(data)
} else {
param.complete(that.buildErrorConfig(data.status, data.message))
}
break
}
default: {
param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG))
}
}
};
return options
},
locationProcess(param, locationsuccess, locationfail, locationcomplete) {
var that = this;
locationfail = locationfail || function(res) {
res.statusCode = ERROR_CONF.WX_ERR_CODE;
param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg))
};
locationcomplete = locationcomplete || function(res) {
if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg))
}
};
if (!param.location) {
that.getWXLocation(locationsuccess, locationfail, locationcomplete)
} else if (that.checkLocation(param)) {
var location = Utils.getLocationParam(param.location);
locationsuccess(location)
}
}
};
class QQMapWX {
constructor(options) {
if (!options.key) {
throw Error('key值不能为空')
}
this.key = options.key
};
search(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (!Utils.checkKeyword(options)) {
return
}
var requestParam = {
keyword: options.keyword,
orderby: options.orderby || '_distance',
page_size: options.page_size || 10,
page_index: options.page_index || 1,
output: 'json',
key: that.key
};
if (options.address_format) {
requestParam.address_format = options.address_format
}
if (options.filter) {
requestParam.filter = options.filter
}
var distance = options.distance || "1000";
var auto_extend = options.auto_extend || 1;
var region = null;
var rectangle = null;
if (options.region) {
region = options.region
}
if (options.rectangle) {
rectangle = options.rectangle
}
var locationsuccess = function(result) {
if (region && !rectangle) {
requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," +
result.longitude + ")";
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'search')
}
} else if (rectangle && !region) {
requestParam.boundary = "rectangle(" + rectangle + ")";
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'search')
}
} else {
requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance +
"," + auto_extend + ")";
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'search')
}
}
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_SEARCH,
data: requestParam
}, 'search'))
};
Utils.locationProcess(options, locationsuccess)
};
getSuggestion(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (!Utils.checkKeyword(options)) {
return
}
var requestParam = {
keyword: options.keyword,
region: options.region || '全国',
region_fix: options.region_fix || 0,
policy: options.policy || 0,
page_size: options.page_size || 10,
page_index: options.page_index || 1,
get_subpois: options.get_subpois || 0,
output: 'json',
key: that.key
};
if (options.address_format) {
requestParam.address_format = options.address_format
}
if (options.filter) {
requestParam.filter = options.filter
}
if (options.location) {
var locationsuccess = function(result) {
requestParam.location = result.latitude + ',' + result.longitude;
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest')
}
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_SUGGESTION,
data: requestParam
}, "suggest"))
};
Utils.locationProcess(options, locationsuccess)
} else {
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest')
}
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_SUGGESTION,
data: requestParam
}, "suggest"))
}
};
reverseGeocoder(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
var requestParam = {
coord_type: options.coord_type || 5,
get_poi: options.get_poi || 0,
output: 'json',
key: that.key
};
if (options.poi_options) {
requestParam.poi_options = options.poi_options
}
var locationsuccess = function(result) {
requestParam.location = result.latitude + ',' + result.longitude;
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder')
}
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_GET_GEOCODER,
data: requestParam
}, 'reverseGeocoder'))
};
Utils.locationProcess(options, locationsuccess)
};
geocoder(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (Utils.checkParamKeyEmpty(options, 'address')) {
return
}
var requestParam = {
address: options.address,
output: 'json',
key: that.key
};
if (options.region) {
requestParam.region = options.region
}
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder')
}
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_GET_GEOCODER,
data: requestParam
}, 'geocoder'))
};
getCityList(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
var requestParam = {
output: 'json',
key: that.key
};
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList')
}
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_CITY_LIST,
data: requestParam
}, 'getCityList'))
};
getDistrictByCityId(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (Utils.checkParamKeyEmpty(options, 'id')) {
return
}
var requestParam = {
id: options.id || '',
output: 'json',
key: that.key
};
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId')
}
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_AREA_LIST,
data: requestParam
}, 'getDistrictByCityId'))
};
calculateDistance(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (Utils.checkParamKeyEmpty(options, 'to')) {
return
}
var requestParam = {
mode: options.mode || 'walking',
to: Utils.location2query(options.to),
output: 'json',
key: that.key
};
if (options.from) {
options.location = options.from
}
if (requestParam.mode == 'straight') {
var locationsuccess = function(result) {
var locationTo = Utils.getEndLocation(requestParam.to);
var data = {
message: "query ok",
result: {
elements: []
},
status: 0
};
for (var i = 0; i < locationTo.length; i++) {
data.result.elements.push({
distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i]
.lat, locationTo[i].lng),
duration: 0,
from: {
lat: result.latitude,
lng: result.longitude
},
to: {
lat: locationTo[i].lat,
lng: locationTo[i].lng
}
})
}
var calculateResult = data.result.elements;
var distanceResult = [];
for (var i = 0; i < calculateResult.length; i++) {
distanceResult.push(calculateResult[i].distance)
}
return options.success(data, {
calculateResult: calculateResult,
distanceResult: distanceResult
})
};
Utils.locationProcess(options, locationsuccess)
} else {
var locationsuccess = function(result) {
requestParam.from = result.latitude + ',' + result.longitude;
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance')
}
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_DISTANCE,
data: requestParam
}, 'calculateDistance'))
};
Utils.locationProcess(options, locationsuccess)
}
};
direction(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (Utils.checkParamKeyEmpty(options, 'to')) {
return
}
var requestParam = {
output: 'json',
key: that.key
};
if (typeof options.to == 'string') {
requestParam.to = options.to
} else {
requestParam.to = options.to.latitude + ',' + options.to.longitude
}
var SET_URL_DIRECTION = null;
options.mode = options.mode || MODE.driving;
SET_URL_DIRECTION = URL_DIRECTION + options.mode;
if (options.from) {
options.location = options.from
}
if (options.mode == MODE.driving) {
if (options.from_poi) {
requestParam.from_poi = options.from_poi
}
if (options.heading) {
requestParam.heading = options.heading
}
if (options.speed) {
requestParam.speed = options.speed
}
if (options.accuracy) {
requestParam.accuracy = options.accuracy
}
if (options.road_type) {
requestParam.road_type = options.road_type
}
if (options.to_poi) {
requestParam.to_poi = options.to_poi
}
if (options.from_track) {
requestParam.from_track = options.from_track
}
if (options.waypoints) {
requestParam.waypoints = options.waypoints
}
if (options.policy) {
requestParam.policy = options.policy
}
if (options.plate_number) {
requestParam.plate_number = options.plate_number
}
}
if (options.mode == MODE.transit) {
if (options.departure_time) {
requestParam.departure_time = options.departure_time
}
if (options.policy) {
requestParam.policy = options.policy
}
}
var locationsuccess = function(result) {
requestParam.from = result.latitude + ',' + result.longitude;
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction', options.mode)
}
wx.request(Utils.buildWxRequestConfig(options, {
url: SET_URL_DIRECTION,
data: requestParam
}, 'direction'))
};
Utils.locationProcess(options, locationsuccess)
}
};
module.exports = QQMapWX;

19
jsFile/public-api.js Normal file
View File

@ -0,0 +1,19 @@
import requst from './requst.js';
import store from '@/store/index.js'
// 查询轮播位置
export function slidePosition(data) {
return requst.get("/api/common/slide-positions");
}
// 查询购物车信息
export function getCartInfo(){
return requst.post('/api/index/indexGetShoppingCartInformation').then(res=>{
if(res.code==0){
console.log(res,'首页购物车信息')
let cartObj = res.data;
store.commit('setNum', cartObj.count)
store.commit('setPrice', cartObj.price)
}
})
}

152
jsFile/requst.js Normal file
View File

@ -0,0 +1,152 @@
// 清理所有缓存并前往登录授权页
const goLogin = () => {
uni.clearStorageSync();
uni.navigateTo({
url: '/pagesA/login/login'
})
}
// 请求错误处理
const checkError = (e) => {
console.log('500接口错误');
// console.error("----接口错误----", e)
if (e.data) {
if (e.data.code) {
switch (Number(e.data.code)) {
case 500:
// 接口错误
console.log('500接口错误');
case 4003:
// 参数错误
console.log('4003参数错误');
break;
case 4004:
// 记录不存在
console.log('4004记录不存在');
break;
case 5001:
// xxx错误
console.log('5001xxx错误');
break;
case 5050:
// 服务器错误,请稍后重试
console.log('5050服务器错误请稍后重试');
// 调用到登录页
goLogin();
break;
case 5051:
// 未知错误
console.log('5051未知错误');
break;
case 6001:
// token验证失败或已失效
console.log('6001token验证失败或已失效');
// 调用到登录页
goLogin();
break;
}
}
}
}
// 封装request的(GET、POST)请求
const request = (method, url, options) => {
let methods = '';
let headers = {};
switch (method) {
case 'get':
methods = 'GET'
headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer '+uni.getStorageSync('token') || ''
}
break;
case 'post':
methods = 'POST'
headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer '+uni.getStorageSync('token') || ''
}
break;
case 'postForm':
methods = 'POST'
headers = {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Authorization': 'Bearer '+uni.getStorageSync('token') || ''
}
break;
}
return new Promise((resolve, reject) => {
uni.request({
url: `${getApp().globalData.hostapi}${url}`,
method: methods,
data: options,
header: headers,
success: res => {
console.log(`${url}返的结果===>`,res);
if (res.statusCode == 200) {
resolve(res.data);
if(res.data.code !== 0){
// 接口返回错误信息
checkError(res);
}
} else {
// 接口返回错误信息
checkError(res);
}
},
fail: e => {
// 接口请求错误
checkError(e, reject);
},
complete: rest => {
// 是否成功,都会执行
console.log(rest,100);
}
})
})
}
// 上传文件 封装请求
const uploadFile = (url, options) => {
let tempData = options || {}
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${getApp().globalData.hostapi}${url}`,
filePath: tempData.path,
name: 'image',
fileType:'image',
formData: tempData,
header: {
'Content-Type': 'multipart/form-data;charset=UTF-8',
'Authorization': 'Bearer '+uni.getStorageSync('token') || ''
},
success: res => {
if (res.statusCode == 200) {
let temp = JSON.parse(res.data)
if (temp.code == 0) {
resolve(temp)
}
}
}
});
})
}
export default {
get: (url, options) => {
return request('get', url, options)
},
// JOSN格式
post: (url, options) => {
return request('post', url, options)
},
// form-data格式
postForm: (url, options) => {
return request('postForm', url, options)
},
// 上传
upload: (url, options) => {
return uploadFile(url, options)
}
}

622
jsFile/tools.js Normal file
View File

@ -0,0 +1,622 @@
const tools = {
/**
* @description 判断当前环境清空日志输出
*/
currentContext(){
// #ifdef APP-PLUS
if(uni.getSystemInfoSync().platform != "devtools"){//devtools开发版 值域为ios、android、mac3.1.10+、windows3.1.10+、linux3.1.10+
// console.log = () =>{}
}
// #endif
},
/**
* @description 获取字符串中的数字
*/
obtainCount(str) {
return parseInt(str.replace(/[^0-9]/ig,""))
},
/**
* @description 手机号验证
*/
isPhone:function(phone){
// 手机号正则表达式
let reg_tel = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
return !reg_tel.test(phone);
},
/**
* @description 电子邮箱验证
*/
isEmail(email){
let reg_email = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
return !reg_email.test(email);
},
/**
* @description 身份证验证
*/
isIdentity(identity) {
let reg_identity = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
return !reg_identity.test(identity);
},
/**
* @description 手机号中间四位用"****"带替
*/
hideMPhone(phone){
return `${phone.substr(0, 3)}****${phone.substr(7)}`
},
/**
* @description 手机号中间加字符
*/
phoneAddChat(phone,startNum=3,endNum=7,character=' '){
let phoneStr = phone;
phoneStr = phoneStr.replace(/\s*/g, "");
var phoneArr = [];
for(var i = 0; i < phoneStr.length; i++){
if (i==startNum||i==endNum){
phoneArr.push(`${character}` + phoneStr.charAt(i));
} else {
phoneArr.push(phoneStr.charAt(i));
}
}
phone = phoneArr.join("");
return phone;
},
/**
* @description 昵称从第一个字开始后面的都用"*"代替
*/
hideName(name,num){
return `${name.substr(0, 1)}****${name.substr(name.length-1)}`
},
/**
* @description 金额转换各三位数使用英文","隔开
*/
changeNum(num){
if (num) {
// 针对整数部分进行格式化处理,这是此方法的核心,也是稍难理解的一个地方,逆向的来思考或者采用简单的事例来实现就容易多了
/*
也可以这样想象现在有一串数字字符串在你面前如果让你给他家千分位的逗号的话你是怎么来思考和操作的?
字符串长度为0/1/2/3时都不用添加
字符串长度大于3的时候从右往左数有三位字符就加一个逗号然后继续往前数直到不到往前数少于三位字符为止
*/
num = num+''; // 数字转换为字符串,数字是没有.length属性的
for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) {
num = num.substring(0, num.length - (4 * i + 3)) + ',' + num.substring(num.length - (4 * i + 3))
}
// 将数据(符号、整数部分、小数部分)整体组合返回
return num;
}
},
/**
* @description 整数添加.00小数就不添加
*/
addXiaoShu(num){
// console.log(num,'添加小数点后两位小数');
let str = num.toString();
str = str*1;
str = str.toFixed(2);
str = str+'';
return str.includes('.') ? str : str = num + '.00';
},
// type:+加、-减、*乘、/除
// len:小数后保留几位
/**
* @description 数字换算解决失精度问题
*/
operationEv(num1,num2,type,len=0){
// 将数字转化成字符串
num1 = num1.toString();
num2 = num2.toString();
// 获取小数点的位置
var index1 = num1.indexOf(".");
var index2 = num2.indexOf(".");
// 如果小数点存在,那么就再获取各自的小数位数
var ws1 = 0;
var ws2 = 0;
if(index1 != -1){
ws1 = num1.split(".")[1].length;
}
if(index2 != -1){
ws2 = num2.split(".")[1].length;
}
// 看谁的小数位数大,谁的小数位数小
var bigger = (ws1 > ws2) ? ws1 : ws2;
var smaller = (ws1 < ws2) ? ws1 : ws2;
// 计算得到需要补齐的0的个数
var zerosCount = bigger - smaller;
// 好了,现在不管三七二十,全部去除小数点
num1 = num1.replace(".","");
num2 = num2.replace(".","");
// 比较num1和num2谁大比较方法就是看谁是smaller是smaller的一方就补0
if(ws1 == smaller){
for (var i = 0; i < zerosCount; i++) {
num1 += "0";
}
} else {
for (var i = 0; i < zerosCount; i++) {
num2 += "0";
}
}
// 开始计算
var sum = "";
if(type=="+"){
// 加
sum = parseInt(num1) + parseInt(num2);
}
if(type=="-"){
// 减
sum = parseInt(num1) - parseInt(num2);
}
if(type=="*"){
// 乘
sum = parseInt(num1) * parseInt(num2);
}
if(type=="/"){
// 除
sum = parseInt(num1) / parseInt(num2);
}
// 根据较大的小数位数计算倍数
var beishu = 1;
for (var i = 0; i < bigger; i++) {
beishu = beishu*10;
}
sum = sum/beishu;
if(type=="*"){
switch (bigger){
case 1:
sum = sum / 10;
break;
case 2:
sum = sum / 100;
break;
case 3:
sum = sum / 1000;
break;
}
}
if(type=="/"){
switch (bigger){
case 1:
sum = sum * 10;
break;
case 2:
sum = sum * 100;
break;
case 3:
sum = sum * 1000;
break;
}
}
len!=0 ? sum = sum.toFixed(len) : '';
return sum;
},
/**
* @description 金额输入框验证
*/
checkPrice(number,zong){
let reg = /^[0-9]*$/;//数字正则表达式
let newObj = {}
zong = parseInt(zong).toString()//取小数点左边的整数
if(!reg.test(number)){//不是数字时
newObj = {
len:zong.length,//动态设置长度
val:zong//动态设置值正整数的总金额
}
} else {//是数字时
newObj = {
len:zong.length,
val:number//动态设置当前输入的值
}
if(number*1 > zong*1){//输入的金额大于总金额
newObj.val = zong//赋值总金额
}
}
return newObj
},
/**
* @description 文本提示
*/
showToast: function(msg, icon='none',time) {
// 弹框显示时间默认2秒
var newTime = 2000
if (time) {newTime = time;}
return uni.showToast({
title: msg,
icon: icon,
duration:newTime
})
},
/**
* @description 富文本处理
*/
escape2Html(str) {
var arrEntities = { 'lt': '<', 'gt': '>', 'nbsp': ' ', 'amp': '&', 'quot': '"' };
return str.replace(/&(lt|gt|nbsp|amp|quot|src);/ig, function (all, t) {
return arrEntities[t];
})
.replace('<section', '<div')
.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, p1) => {
return `<img mode="widthFix" style="max-width:100%!important;height:auto" src='${p1.indexOf('http') > -1 ? p1 : 'https://guofu.scdxtc.cn' + p1}' />`
})
},
/**
* @description 检查网络状态
*/
networkStatus(){
uni.getNetworkType({
success: (res)=> {
console.log('当前网络状态:',res.networkType);//none当前无网络连接
if(res.networkType=='none'){
uni.setStorageSync('isNet',false)
} else {
uni.setStorageSync('isNet',true);
// 微信小程序原生API性能优化
// #ifdef MP-WEIXIN
// 连网下,检测小程序是否有更新
this.checkUpdate();
// #endif
}
}
});
},
/**
* @description app小程序的检测版本并更新
*/
checkUpdate(){
// 检测app
// #ifdef APP-PLUS
// #endif
//检测小程序
// #ifdef MP-WEIXIN
var self = this;
// 获取小程序更新机制兼容
if (wx.canIUse('getUpdateManager')) {
const updateManager = wx.getUpdateManager();//1. 检查小程序是否有新版本发布
updateManager.onCheckForUpdate(function(res) {// 请求完新版本信息的回调
if (res.hasUpdate) {
//检测到新版本,需要更新,给出提示
wx.showModal({
title: '更新提示',
content: '检测到新版本,是否下载新版本并重启小程序?',
success: function(res) {
if (res.confirm) {
//2. 用户确定下载更新小程序,小程序下载及更新静默进行
self.downLoadAndUpdate(updateManager)
// 清除所有缓存
uni.clearStorage();
uni.clearStorageSync();
} else if (res.cancel) {
//用户点击取消按钮的处理,如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了
wx.showModal({
title: '温馨提示~',
content: '本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~',
showCancel:false,//隐藏取消按钮
confirmText:"确定更新",//只保留确定更新按钮
success: function(res) {
if (res.confirm) {
//下载新版本,并重新应用
self.downLoadAndUpdate(updateManager)
}
}
})
}
}
})
}
})
} else { // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}
// #endif
},
// 下载小程序新版本并重启应用
downLoadAndUpdate(updateManager){
var self = this;
wx.showLoading(); //静默下载更新小程序新版本
updateManager.onUpdateReady(function () {
wx.hideLoading(); //新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
// 清除缓存
uni.clearStorageSync();
uni.clearStorage();
})
updateManager.onUpdateFailed(function () { // 新的版本下载失败
wx.showModal({
title: '已经有新版本了哟~',
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~',
})
})
},
/**
* @description 文本复制
*/
clickCopy(data){
uni.setClipboardData({
data: data,
success: ()=> {
uni.showToast({title: '复制成功',duration: 2000,icon: 'none'});
}
});
},
authTimer:null,
/**
* @description 判断是否授权没授权前往登录页面授权
*/
judgeAuth(){
let auth = false;
clearTimeout(this.authTimer);
if(!uni.getStorageSync('token')) {
this.showToast('请授权登录');
this.authTimer = setTimeout(()=>{
uni.reLaunch({url:'/pagesA/login/login'});
},1000)
} else {
auth = true;
}
return auth;
},
/**
* @description 禁止小程序使用右上角分享
*/
disableShareEv(){
// #ifdef MP-WEIXIN
wx.hideShareMenu({
menus: ['shareAppMessage', 'shareTimeline']
})
// #endif
},
/**
* @description 获取当前页面完整url
*/
obtainPagePath(){
let pages = getCurrentPages();
// 获取纯页面路径
let route = pages[pages.length - 1].route;
// 获取当前页面url带参数
let routeParam = pages[pages.length - 1].$page.fullPath;
// console.log(routeParam.options,'获取当前url参数');
if(routeParam.indexOf('/pagesA/login')==-1 && routeParam.indexOf('/pagesB/register')==-1 && routeParam.indexOf('/pagesB/password')==-1){
uni.setStorageSync('url',route);
uni.setStorageSync('page-path-options',routeParam);
}
},
/**
* @description 拨打电话
* @param {Number} phone
*/
countCustomer(phone){
const res = uni.getSystemInfoSync();
let phoneList = [];
if(phone!==''){
phoneList.push(phone);
}
uni.showActionSheet({
itemList:phoneList,
itemColor:'#1981ff',
success: (res) => {
uni.makePhoneCall({
phoneNumber:phoneList[res.tapIndex]
})
}
})
},
/**
* @description 图片选择
* @param {Number} count
*/
uploadImg(count=1) {
let imgArr = [];
uni.chooseImage({
count:count,
sizeType:['compressed'],
sourceType:['album','camera'],
success: (res) => {
let files = res.tempFilePaths
console.log(files);
files.forEach(item=>{
imgArr.push(item);
})
}
})
return imgArr;
},
/**
* @description 打开小程序获取用户信息权限
*/
wxOpenSet() {
// #ifdef MP-WEIXIN
// 用户信息
uni.authorize({
scope:'scope.userInfo',
success: (res) => {},
fail: (res) => {
uni.showModal({
content:'检测到您没打开获取信息功能权限,是否去设置打开?',
confirmText: "确认",
cancelText:'取消',
success: (res) => {
if(res.confirm){
uni.openSetting({
success: (res) => {
console.log(res);
}
})
}else{
console.log('取消');
}
}
})
}
})
// #endif
},
/**
* @description 传入目的地的经纬度地点名称详细地址打开地图导航到达目的地
*/
goFlag:true,
goThere(latitude=30.656693,longitude=104.136425,address="四川省成都市成华区双店路B口"){
if(this.goFlag){
this.goFlag = false;
// #ifdef MP-WEIXIN
wx.getLocation({//获取当前经纬度
type: 'wgs84', //返回可以用于wx.openLocation的经纬度官方提示bug: iOS 6.3.30 type 参数不生效,只会返回 wgs84 类型的坐标信息
success: (res)=> {
wx.openLocation({//​使用微信内置地图查看位置。
latitude: parseFloat(latitude),//要去的纬度-地址
longitude: parseFloat(longitude),//要去的经度-地址
address: address,
fail:err=>{
tools.showToast('地址信息错误');
}
})
}
})
// #endif
// #ifdef APP-PLUS || H5
uni.openLocation({
latitude: parseFloat(latitude),
longitude: parseFloat(longitude),
address:address,
success:()=> {
console.log('success');
},
fail:err=>{
console.log(err)
}
});
// #endif
setTimeout(()=>{
this.goFlag = true;
},2000)
} else {
tools.showToast('请勿多次点击');
}
},
/**
* @description 保存图片
* @param {String} src
*/
saveImg(src) {
// #ifdef APP-PLUS
uni.saveImageToPhotosAlbum({
filePath: src,
success:(resimg)=> {}
});
// #endif
// #ifdef MP-WEIXIN
let exist = src.slice(0,4);
if(exist=='http') {
uni.downloadFile({
url: src,
success: (res) => {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: ()=> {
uni.showToast({title:'保存成功',icon:'error'})
},
fail: () => {
uni.showToast({title:'保存失败',icon:'error'})
}
});
}
})
} else {
wx.saveFile({
tempFilePath: src,
success:(wximg)=> {}
})
}
// #endif
},
/**
* @description 把base64转换成图片
* @param {String} data
*/
getBase64ImageUrl(data) {
/// 获取到base64Data
var base64Data = data;
/// 通过微信小程序自带方法将base64转为二进制去除特殊符号再转回base64
base64Data = wx.arrayBufferToBase64(wx.base64ToArrayBuffer(base64Data));
/// 拼接请求头data格式可以为image/png或者image/jpeg等看需求
const base64ImgUrl = "data:image/png;base64," + base64Data;
/// 刷新数据
return base64ImgUrl;
},
/**
* @description 小程序二维码解析
*/
analysis(val) {
// #ifdef MP-WEIXIN
let str = unescape(val);
str = str.split('invite_code=')[1];
uni.setStorageSync('invite_code_Other',str);
this.loginEv();// 调用登录事件
// #endif
},
timeToken:null,
// 开启一个半小时刷新token
refreshToken(){
clearInterval(this.timeToken);
// 调用登录事件
this.loginEv();
this.timeToken = setInterval(()=>{
// 调用登录事件
this.loginEv();
},600000*9)
},
// 登录事件
loginEv(){
let invite_code = uni.getStorageSync('invite_code_Other');
uni.login({
provider: 'weixin',
success: (res)=> {
var params = {code:res.code,invite_code:invite_code}
uni.request({
url: `${getApp().globalData.hostapi}/api/user/get-openid`,
method: 'post',
data: params,
success: result => {
if(result.data.data.openid!=''){
console.log('刷新了token');
uni.setStorageSync('token',result.data.data.token); // 缓存token
uni.setStorageSync('openid',result.data.data.openid)//缓存openid
uni.setStorageSync('expire',result.data.data.expire); // 缓存失效时间(时间戳格式)
uni.setStorageSync('phone_active',result.data.data.phone_active); // 是否绑定手机号
uni.setStorageSync('is_active',result.data.data.is_active)//是否第一次授权
uni.setStorageSync('invite_code',result.data.data.invite_code)//缓存用户邀请码
}
}
})
},
});
},
}
export default {
tools
}

34
jsFile/uqrcode.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,272 @@
/**
* 本模块封装了AndroidiOS的应用权限判断打开应用权限设置界面以及位置系统服务是否开启
*/
var isIos
// #ifdef APP-PLUS
isIos = (plus.os.name == "iOS")
// #endif
// 判断推送权限是否开启
function judgeIosPermissionPush() {
var result = false;
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
console.log("enabledTypes1:" + enabledTypes);
if (enabledTypes == 0) {
console.log("推送权限没有开启");
} else {
result = true;
console.log("已经开启推送功能!")
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if (enabledTypes == 0) {
console.log("推送权限没有开启!");
} else {
result = true;
console.log("已经开启推送功能!")
}
console.log("enabledTypes2:" + enabledTypes);
}
plus.ios.deleteObject(app);
plus.ios.deleteObject(UIApplication);
return result;
}
// 判断定位权限是否开启
function judgeIosPermissionLocation() {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var status = cllocationManger.authorizationStatus();
result = (status != 2)
console.log("定位权限开启:" + result);
// 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
/* var enable = cllocationManger.locationServicesEnabled();
var status = cllocationManger.authorizationStatus();
console.log("enable:" + enable);
console.log("status:" + status);
if (enable && status != 2) {
result = true;
console.log("手机定位服务已开启且已授予定位权限");
} else {
console.log("手机系统的定位没有打开或未给予定位权限");
} */
plus.ios.deleteObject(cllocationManger);
return result;
}
// 判断麦克风权限是否开启
function judgeIosPermissionRecord() {
var result = false;
var avaudiosession = plus.ios.import("AVAudioSession");
var avaudio = avaudiosession.sharedInstance();
var permissionStatus = avaudio.recordPermission();
console.log("permissionStatus:" + permissionStatus);
if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
console.log("麦克风权限没有开启");
} else {
result = true;
console.log("麦克风权限已经开启");
}
plus.ios.deleteObject(avaudiosession);
return result;
}
// 判断相机权限是否开启
function judgeIosPermissionCamera() {
var result = false;
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
console.log("authStatus:" + authStatus);
if (authStatus == 3) {
result = true;
console.log("相机权限已经开启");
} else {
console.log("相机权限没有开启");
}
plus.ios.deleteObject(AVCaptureDevice);
return result;
}
// 判断相册权限是否开启
function judgeIosPermissionPhotoLibrary() {
var result = false;
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
var authStatus = PHPhotoLibrary.authorizationStatus();
console.log("authStatus:" + authStatus);
if (authStatus == 3) {
result = true;
console.log("相册权限已经开启");
} else {
console.log("相册权限没有开启");
}
plus.ios.deleteObject(PHPhotoLibrary);
return result;
}
// 判断通讯录权限是否开启
function judgeIosPermissionContact() {
var result = false;
var CNContactStore = plus.ios.import("CNContactStore");
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
if (cnAuthStatus == 3) {
result = true;
console.log("通讯录权限已经开启");
} else {
console.log("通讯录权限没有开启");
}
plus.ios.deleteObject(CNContactStore);
return result;
}
// 判断日历权限是否开启
function judgeIosPermissionCalendar() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
if (ekAuthStatus == 3) {
result = true;
console.log("日历权限已经开启");
} else {
console.log("日历权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// 判断备忘录权限是否开启
function judgeIosPermissionMemo() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
if (ekAuthStatus == 3) {
result = true;
console.log("备忘录权限已经开启");
} else {
console.log("备忘录权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// Android权限查询
function requestAndroidPermission(permissionID) {
return new Promise((resolve, reject) => {
plus.android.requestPermissions(
[permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
function(resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log('已获取的权限:' + grantedPermission);
result = 1
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
result = 0
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
result = -1
}
resolve(result);
// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
// if (result != 1) {
// gotoAppPermissionSetting()
// }
},
function(error) {
console.log('申请权限错误:' + error.code + " = " + error.message);
resolve({
code: error.code,
message: error.message
});
}
);
});
}
// 使用一个方法,根据参数判断权限
function judgeIosPermission(permissionID) {
if (permissionID == "location") {
return judgeIosPermissionLocation()
} else if (permissionID == "camera") {
return judgeIosPermissionCamera()
} else if (permissionID == "photoLibrary") {
return judgeIosPermissionPhotoLibrary()
} else if (permissionID == "record") {
return judgeIosPermissionRecord()
} else if (permissionID == "push") {
return judgeIosPermissionPush()
} else if (permissionID == "contact") {
return judgeIosPermissionContact()
} else if (permissionID == "calendar") {
return judgeIosPermissionCalendar()
} else if (permissionID == "memo") {
return judgeIosPermissionMemo()
}
return false;
}
// 跳转到**应用**的权限页面
function gotoAppPermissionSetting() {
if (isIos) {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
// console.log(plus.device.vendor);
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
}
}
// 检查系统的设备服务是否开启
// var checkSystemEnableLocation = async function () {
function checkSystemEnableLocation() {
if (isIos) {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var result = cllocationManger.locationServicesEnabled();
console.log("系统定位开启:" + result);
plus.ios.deleteObject(cllocationManger);
return result;
} else {
var context = plus.android.importClass("android.content.Context");
var locationManager = plus.android.importClass("android.location.LocationManager");
var main = plus.android.runtimeMainActivity();
var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
console.log("系统定位开启:" + result);
return result
}
}
module.exports = {
judgeIosPermission: judgeIosPermission,
requestAndroidPermission: requestAndroidPermission,
checkSystemEnableLocation: checkSystemEnableLocation,
gotoAppPermissionSetting: gotoAppPermissionSetting
}

41
main.js Normal file
View File

@ -0,0 +1,41 @@
import Vue from 'vue';
import App from './App';
import store from './store'
Vue.prototype.$store = store
import nothingPage from './components/nothing/nothing-page.vue';//引入无内容组件
Vue.component('nothing-page',nothingPage);//全局注册无内容组件
import statusNav from './components/status-nav/status-nav.vue'; //引入头部组件
Vue.component('status-nav',statusNav);//全局注册头部组件
import footBar from './components/foot-bar/foot-bar.vue'; //引入尾部组件
Vue.component('foot-bar',footBar);//全局注册尾部组件
// 常用便捷式公共方法
import tools from '@/jsFile/tools.js';
Vue.prototype.$toolAll = tools;
// 响应数据
import requst from '@/jsFile/requst.js';
Vue.prototype.$requst = requst;
//不显示console.log
if (uni.getSystemInfoSync().platform !== "devtools") {
console.log = () => {}
}
// promise
Vue.prototype.$onLaunched = new Promise(resolve => {
Vue.prototype.$isResolve = resolve
})
App.mpType = 'app';
const app = new Vue({
store,
...App
})
app.$mount()

88
manifest.json Normal file
View File

@ -0,0 +1,88 @@
{
"name" : "翼笑倾成",
"appid" : "__UNI__CF91DCC",
"description" : "商城小程序",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"compilerVersion" : 3,
/* 5+App */
"modules" : {
"Payment" : {},
"Share" : {}
},
/* */
"distribute" : {
/* */
"android" : {
/* android */
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
/* ios */
"sdkConfigs" : {
"maps" : {},
"payment" : {
"weixin" : {
"__platform__" : [ "ios", "android" ],
"appid" : "wx2654bc27c419ada6",
"UniversalLinks" : ""
}
},
"push" : {},
"geolocation" : {},
"share" : {
"weixin" : {
"appid" : "wx2654bc27c419ada6",
"UniversalLinks" : ""
}
},
"ad" : {}
}
},
"splashscreen" : {
"alwaysShowBeforeRender" : false,
"waiting" : false
}
},
/* SDK */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wxa02e44170bc722cd",
"setting" : {
"urlCheck" : false,
"es6" : true,
"minified" : true
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "将用于查询当前位置是否有货以及配送情况!"
}
},
"requiredPrivateInfos" : [ "getLocation" ]
},
"mp-baidu" : {
"appid" : "24346353"
}
}

15
package-lock.json generated Normal file
View File

@ -0,0 +1,15 @@
{
"name": "轮播视频和图片",
"version": "1.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "轮播视频和图片",
"version": "1.0.1",
"dependencies": {
"moment": "^2.29.3"
}
}
}
}

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"id": "zhuge-swiper",
"name": "轮播视频和图片",
"version": "1.0.1",
"description": "自动轮播视频和图片组件。播放视频时停止轮播手动滑动swiper时视频停止播放",
"keywords": [
"vue",
"swiper",
"zhuge"
],
"uni-app": {
"scripts": {
"h5-weixin": {
"title":"微信小程序",
"browser":"",
"env": {
"UNI_PLATFORM": "mp-weixin"
},
"define": {
"H5-WEIXIN": true
}
}
}
}
}

51
pages.json Normal file
View File

@ -0,0 +1,51 @@
{
"pages": [
{ //
"path" : "pages/index/index",
"style" : {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": false
}
}
],
"subPackages": [{ //A
"root": "pagesA",
"pages": [
{
"path" : "login/login",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
]
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FFFFFF", //
"navigationStyle": "custom", //
"backgroundColor":"#FFFFFF",//
"backgroundTextStyle":"light",// loading dark / light
// "transparentTitle":"none",// always / auto / none
"app-plus": {
"titleNView": false, //APPH5
"bounce": "none",
"scrollIndicator": "none"
}
},
"condition" : { //
"current": 0, //(list )
"list": [
{
"name": "", //
"path": "", //
"query": "" //onLoad
}
]
}
}

549
pages/index/index.vue Normal file
View File

@ -0,0 +1,549 @@
<template>
<view class="main" v-if="loading">
<!-- 头部 -->
<status-nav :ifReturn="false" navBarTitle="我的二维码" :titleColor="titleColor" :backgroudColor="backgroudColor" :ifBold="true"></status-nav>
<block v-if="userInfo.nickname">
<!-- 已购买 -->
<view class="yes-buy" v-if="is_buy == 0">
<image src="/static/public/blue-bg.jpg" class="allbg" mode="cover"></image>
<view class="writeOff">
<view class="text-top">
<view class="title">
<view class="st">{{ticketInfo.name}}</view>
<view class="phone">{{ticketInfo.phone}}</view>
</view>
<image :src="userInfo.headimgurl" class="face" mode="cover"></image>
</view>
<view class="text-center">
<div class="boxs">
<div class="st">名称</div>
<div class="cont">{{ticketInfo.ticket_name}}</div>
</div>
<div class="boxs">
<div class="st">购票时间</div>
<div class="cont">{{ticketInfo.paid_at}}</div>
</div>
</view>
<!-- 生成二维码 -->
<view class="qrcode-boxs">
<canvas id="qrcode" canvas-id="qrcode" style="width: 100%;height: 100%;"></canvas>
<!-- <image :src="qrCode" class="qrcode-image" mode="widthFix"></image> -->
</view>
<view class="qrcode-text">凭码入场</view>
</view>
</view>
<!-- 未购买 -->
<view class="no-buy" v-if="is_buy == 1">
<image src="../../static/public/ling-icon.png" mode="widthFix" class="icon"></image>
<view class="title">没有查询到你的购买信息 <view>请购买</view></view>
<view class="buy-button" @tap="goBuy"></view>
</view>
</block>
<block v-else>
<tui-no-data imgUrl="/static/public/img_nodata.png" btnText="去登录" @click="goLogin" backgroundColor='#77A593'>
<text class="tui-color__black">您还没有授权~</text>
</tui-no-data>
</block>
<!-- 弹框 -->
<tui-modal :show="bottomDrawer" custom @cancel="hide">
<view class="tui-drawer__box">
<view class="title">选择购票类型</view>
<view class="list">
<view class="l-piao" :class="currIndex == index ? 'curr-piao': ''" v-for="(item,index) in piaoList" :key="index" @tap="xuan_piao(index)">
<view>{{item.name}}</view>
<view>{{item.price}}</view>
</view>
</view>
<view class="line"></view>
<view class="form">
<input type="text" placeholder="请填写手机号" v-model="buy_phone" class="input">
<input type="text" placeholder="填写姓名" v-model="buy_name" class="input">
</view>
<view class="bottom">
<view class="price"><text></text>{{last_price}}</view>
<view class="buy-vote" @tap="payment"></view>
</view>
</view>
</tui-modal>
</view>
</template>
<script>
import tuiNoData from "@/components/thorui/tui-no-data/tui-no-data.vue"
import tuiModal from "@/components/thorui/tui-modal/tui-modal.vue"
import UQRCode from '@/jsFile/uqrcode.js'
export default {
components:{
tuiNoData,
tuiModal
},
data() {
return {
statusHeight:uni.getSystemInfoSync().statusBarHeight, //
baseHttps:`${getApp().globalData.hostapi}`, //
backgroudColor:'none', //
titleColor:'#333333',
loading:false,
userInfo:{},//
ticketInfo:{}, //
first_enter:'', //
is_buy:'',//
bottomDrawer:false,
piaoList:[],
currIndex:0,
buy_phone:'',
buy_name:'',
last_price:'', //
ticket_id:'' ,// id
payment_params:{},//
coding:'',//coding
code:'',//code
qrCode:'', //
};
},
async onLoad(op) {
await this.$onLaunched;
this.getUserInfo();
},
onHide() {
},
methods: {
//
getUserInfo() {
this.$requst.post('/api/user/info').then(res => {
if(res.code == 0){
this.userInfo = res.data;
this.first_enter = uni.getStorageSync('first_enter') ? uni.getStorageSync('first_enter') : 0;
if(!this.userInfo.nickname && this.first_enter == 0) {
let first_enter = 1;
uni.setStorageSync('first_enter',first_enter)//openid
uni.navigateTo({
url:'/pagesA/login/login'
})
}else {
this.getTicket();
}
this.loading = true;
}
},error => {
})
},
//
getTicket() {
this.$requst.get('/api/ticket/info').then(res => {
if(res.code == 0){
if(res.data == '') {
this.is_buy = 1;
this.getFeeList();
}else {
this.is_buy = 0;
this.titleColor = '#ffffff';
this.ticketInfo = res.data;
this.code = res.data.coding;
this.getQrCode();
}
}
},error => {
})
},
//
getFeeList() {
this.$requst.get('/api/ticket/list').then(res => {
if(res.code == 0){
this.piaoList = res.data;
this.last_price = this.piaoList[0].price
}
},error => {
})
},
goLogin() {
uni.navigateTo({
url:'/pagesA/login/login'
})
},
hide() {
this.bottomDrawer = false;
},
goBuy() {
this.buy_phone = this.userInfo.mobile;
this.bottomDrawer = true;
},
xuan_piao(index) {
this.currIndex = index;
this.last_price = this.piaoList[index].price;
this.ticket_id = this.piaoList[index].id;
},
//
payment() {
if(this.buy_phone == '') {
this.$toolAll.tools.showToast('请填写手机号');
}else if(this.buy_name == '') {
this.$toolAll.tools.showToast('请填写姓名');
}else {
let params = {
ticket_id:this.ticket_id,
name:this.buy_name,
phone:this.buy_phone
}
this.$requst.post('/api/order/create',params).then(res => {
if(res.code == 0){
console.log(res)
this.coding = res.data.coding;
this.payment_params = res.data.payment_params;
this.payWay();
}
},error => {
})
}
},
//
payWay() {
let that = this;
uni.requestPayment({
provider: 'wxpay', //-
timeStamp: that.payment_params.timeStamp, //
nonceStr: that.payment_params.nonceStr, //
package: that.payment_params.package, //
signType: that.payment_params.signType, //
paySign: that.payment_params.sign, //
success: function (res) {
console.log("支付成功");
that.$requst.post('/api/order/paid',{order_coding:that.coding}).then(resdata => {
if(resdata.code == 0) {
uni.showToast({
icon: 'success',
title: '支付成功',
duration:1600
})
setTimeout(()=>{
that.hide();
that.getTicket();
},2000)
}else {
that.$toolAll.tools.showToast(resdata.msg)
}
})
},
fail: function (err) {
console.log("支付失败");
uni.showToast({
icon: 'none',
title: '支付失败',
duration:1000
})
setTimeout(()=>{
that.hide();
},1100)
}
});
},
getQrCode() {
let that = this;
// uQRCode
var qr = new UQRCode();
//
qr.data = that.code;
// canvas
qr.size = 180;
//
qr.make();
// canvas
var canvasContext = uni.createCanvasContext('qrcode', this); // this
// uQRCodecanvas
qr.canvasContext = canvasContext;
// canvas
qr.drawCanvas();
setTimeout(() => {
uni.canvasToTempFilePath(
{
canvasId: 'qrcode',
width: 180,
height: 180,
success: res => {
console.log(res);
},
fail: err => {
console.log(err);
}
},
// this // 使
);
}, 300);
}
}
}
</script>
<style scoped>
.main {
padding-bottom: 0;
}
.no-buy {
margin: 230rpx auto 0;
width: 630rpx;
padding: 50rpx 0;
background: #FFFFFF;
border-radius: 28rpx;
box-shadow: 0 0 30rpx rgba(0,0,0,0.1);
position: relative;
}
.no-buy .icon {
width: 192rpx;
height: 192rpx;
position: absolute;
left: 50%;
top: 0;
margin-top: -96rpx;
margin-left: -96rpx;
}
.no-buy .title {
margin-top:96rpx;
text-align: center;
font-size: 32rpx;
line-height: 65rpx;
}
.no-buy .buy-button {
width: 70%;
height: 84rpx;
background: #77A593;
border-radius: 16rpx;
margin:0 auto;
margin-top: 70rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
}
.yes-buy {
position: relative;
background-color: #77A593;
}
.allbg {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 9;
}
.writeOff {
position: relative;
z-index: 55;
margin: 50rpx 30rpx;
border-radius: 20rpx;
overflow: hidden;
background-color: #fff;
padding: 40rpx 46rpx 50rpx 46rpx;
}
.writeOff .text-top {
display: flex;
align-items: center;
justify-content: space-between;
}
.writeOff .text-top .title {
display: flex;
justify-content: center;
flex-direction: column;
height: 100%;
}
.writeOff .text-top .title .st {
font-size: 32rpx;
color: #000000;
font-weight: 800;
}
.writeOff .text-top .title .phone {
font-size: 28rpx;
font-weight: 500;
color: #000;
margin-top: 22rpx;
}
.writeOff .text-top .face {
width: 136rpx;
height: 136rpx;
background: #D9D9D9;
border-radius: 16rpx;
overflow: hidden;
}
.writeOff .text-center {
padding: 54rpx 0;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px dashed rgba(0,0,0,0.1);
}
.writeOff .text-center .boxs {
width: 48%;
}
.writeOff .text-center .boxs .st {
font-size: 26rpx;
color: #707070;
font-weight: 500;
}
.writeOff .text-center .boxs .cont {
margin-top: 18rpx;
font-size: 28rpx;
font-weight: 500;
color: #000000;
}
.qrcode-boxs {
width: 360rpx;
height: 360rpx;
margin: 64rpx auto 0rpx;
display: block;
position: relative;
}
#qrcode {
width: 100%;
height: 100%;
display: block;
position: absolute;
left: 0;
top: 0;
z-index: 9;
}
.qrcode-image {
position: relative;
width: 100%;
height: 100%;
display: block;
position: absolute;
left: 0;
top: 0;
z-index: 18;
}
.tui-drawer__box {
padding:2rpx 28rpx 30rpx 28rpx;
border-radius: 20rpx 20rpx 0 0;
position: relative;
background-color: #fff;
box-sizing: border-box;
}
.tui-drawer__box .title {
font-size: 32rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 600;
color: #000000;
line-height: 65rpx;
text-align: center;
}
.tui-drawer__box .list {
margin-top: 44rpx;
max-height: 400rpx;
overflow-x: hidden;
}
.tui-drawer__box .list .l-piao:last-child {
margin-bottom: 0;
}
.l-piao {
height: 70rpx;
border: 2rpx solid rgba(0,0,0,0.1);
margin-bottom: 34rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20rpx;
box-sizing: border-box;
font-size: 28rpx;
color: #888888;
}
.curr-piao {
background-color: #77A593;
color: #fff;
}
.tui-drawer__box .line {
display: block;
margin-top: 48rpx;
border-top: 1px dashed rgba(0,0,0,0.1);
width: calc(100% + 56rpx);
margin-left: -28rpx;
}
.tui-drawer__box .form {
padding-top: 24rpx;
}
.tui-drawer__box .form .input {
border:none;
border-bottom: 2rpx solid rgba(0,0,0,0.1);
font-size: 28rpx;
color: #888888;
height: 70rpx;
margin-bottom: 32rpx;
display: flex;
align-items: center;
padding-left: 14rpx;
box-sizing: border-box;
}
.tui-drawer__box .bottom {
padding-top: 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.tui-drawer__box .bottom .price {
font-size: 36rpx;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: bold;
color: #F44242;
}
.tui-drawer__box .bottom .price text {
font-size: 28rpx;
margin-right: 4rpx;
}
.tui-drawer__box .bottom .buy-vote {
width: 304rpx;
height: 70rpx;
background: #77A593;
border-radius: 16rpx;
font-size: 28rpx;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.qrcode-text {
color: #f00;
font-size: 28rpx;
margin-top: 34rpx;
text-align: center;
display: block;
}
</style>

360
pagesA/login/login.vue Normal file
View File

@ -0,0 +1,360 @@
<template>
<view>
<!-- 头部 -->
<status-nav :ifReturn="true" navBarTitle="登录" titleColor="#333" backgroudColor="#fff" :ifBold="true"></status-nav>
<view class='login-header'>
<image class="infoImg" mode="aspectFill" :src="userInfo.avatarUrl || imgSrc"></image>
<view class="logo-name">{{appletName}}</view>
</view>
<view class="login-footer">
<view class="login-boxs">
<button class="login-btn" @tap="goBack" style="background-color: #b3b3b3;box-shadow: 0 0 0 rgba(0,0,0,0);">暂不登录</button>
<button class="login-btn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber"></button>
</view>
<view class="agreement-box">如您点击授权您将同意授权<text @tap="toAgreement(1)" class="agreement">用户协议</text><text @tap="toAgreement(2)" class="agreement">隐私协议</text></view>
</view>
<!-- 获取头像&昵称 -->
<view class="pop-up-bg" v-if="empowerShow">
<view class="user-info-box">
<view class="info">
<view class="cover">
<image :src="imgSrc" mode="aspectFit"></image>
</view>
<view class="name">{{appletName}}</view>
<view class="tips">
<view>邀请您补全个人信息</view>
<view>(昵称头像)</view>
</view>
</view>
<view class="msg">
<view class="item">
<text>头像</text>
<button class="avatar" open-type="chooseAvatar" @chooseavatar="chooseAvatar">
<view class="img"><image :src="userInfo.avatarUrl || logoAvatar" mode="aspectFit"></image></view>
</button>
</view>
<view class="item">
<text>昵称</text>
<input class="nick-name" type="nickname" @blur="nickNameInput" v-model="userInfo.nickName" placeholder="请输入昵称" placeholder-style="color:#999"/>
</view>
</view>
<view class="empower-btns">
<view class="btn" @tap="refuseEv"></view>
<view class="btn" @tap="bindGetUserInfo('other')"></view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
userInfo: {
nickName:'',
avatarUrl:''
}, //
imgSrc: '/static/public/logo.png', //logo
logoAvatar:'/static/public/logo-avatar.png',//
appletName:'IBU读书会', //
empowerShow:false, //
isActive:false, //
};
},
onLoad() {
},
methods: {
goBack() {
uni.reLaunch({
url:'/pages/index/index'
})
},
getPhoneNumber(e) {
if(e.detail.code) {
let params = {
iv:e.detail.iv,
encryptedData:e.detail.encryptedData
}
this.$requst.post('/api/user/bind-phone',params).then(res => {
if(res.code == 0){
uni.setStorageSync('my_phone',res.data.phone) //token
this.empowerShow = true;
}else {
this.$toolAll.tools.showToast(res.msg);
}
},error => {
})
}else {
this.$toolAll.tools.showToast('您已拒绝授权');
}
},
// //
// uploadImg(url){
// uni.showLoading({
// title: ''
// });
// this.$requst.upload('/api/file/upload/image',{path:url}).then(res=>{
// if(res.code==0) {
// this.userInfo.avatarUrl = res.data.full_src;
// }
// uni.hideLoading();
// })
// },
//
chooseAvatar(e){
//
// this.uploadImg(e.detail.avatarUrl)
this.userInfo.avatarUrl = e.detail.avatarUrl
},
//
nickNameInput(e){
this.userInfo.nickName = e.detail.value
},
//
refuseEv(){
this.$toolAll.tools.showToast('您已拒绝授权');
this.empowerShow = false;
},
//
checkForm(){
if(this.userInfo.avatarUrl==''){
this.$toolAll.tools.showToast('请选择头像!')
return false;
}else if(this.userInfo.nickName==''){
this.$toolAll.tools.showToast('请输入昵称!')
return false;
}else{
this.isActive = true;
return true;
}
},
//
bindGetUserInfo(status) {
let ya = this;
ya.checkForm();
//
if(ya.isActive == true) {
ya.updateUserInfo(status);
}
},
//
updateUserInfo(status) {
let ya = this;
if(status=='other'){
uni.showToast({
title: '登录中...',
icon:'loading',
duration:10000
})
var params = {
nickname: ya.userInfo.nickName,//
headimgurl: ya.userInfo.avatarUrl,//
}
this.$requst.post('/api/user/editInfo',params).then(res => {
uni.hideToast();
if(res.code == 0){
uni.showToast({
title: '授权成功',
icon:'loading',
duration:1000
})
setTimeout(()=>{
uni.reLaunch({
url:'/pages/index/index'
})
},1500)
}
},error => {})
}
}
}
}
</script>
<style scoped>
.login-header {
justify-content: center;
display: flex;
align-items: center;
flex-direction: column;
margin-top: 0;
position: fixed;
left: 50%;
top: 40%;
transform: translate(-50%,-50%);
}
.infoImg {
width: 224rpx;
height: 224rpx;
border-radius: 100%;
border: 2rpx solid #d8d8d8;
}
.logo-name {
margin-top: 20rpx;
font-size: 30rpx;
font-weight: bold;
text-align: center;
letter-spacing: 4rpx;
text-indent: 4rpx;
}
.login-footer {
width: 100%;
padding: 0 2%;
box-sizing: border-box;
text-align: center;
position: fixed;
left: 0;
bottom: 120rpx;
}
.login-boxs {
display: flex;
align-items: center;
justify-content: space-between;
}
.login-btn {
width:45%;
line-height: 94rpx;
margin: 0 auto;
background-color: #77A593;
border-radius: 20rpx;
color: #ffffff;
font-size: 32rpx;
letter-spacing: 4rpx;
text-indent: 4rpx;
box-shadow: 0rpx 8rpx 20rpx rgba(5,103,184,.3);
}
.agreement-box{
margin-top: 25rpx;
font-size: 26rpx;
}
.agreement{
color: #77A593;
}
/* 授权弹窗 */
.pop-up-bg{
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100vw;
height: 100vh;
background-color: rgba(0,0,0,.5);
position: fixed;
left: 0;
top: 0;
z-index: 999;
}
.user-info-box{
box-sizing: border-box;
width: calc(100% - 200rpx);
border-radius: 10rpx;
padding: 40rpx 45rpx 20rpx 45rpx;
background-color: #ffffff;
}
.user-info-box .info{
font-size: 26rpx;
text-align: center;
}
.user-info-box .cover{
width: 144rpx;
height: 144rpx;
border-radius: 100%;
box-shadow: 0px 0px 20rpx 4rpx rgba(5,103,184,.1);
margin: 0 auto;
overflow: hidden;
}
.user-info-box .cover image{
width: 100%;
height: 100%;
}
.user-info-box .name{
font-size: 30rpx;
line-height: 1.5;
margin:22rpx 0 16rpx 0;
}
.user-info-box .tips{
font-size: 26rpx;
line-height: 1.6;
color: #666666;
}
.user-info-box .tips view:last-child{
font-size: 24rpx;
color: #e42417;
}
.user-info-box .msg{
font-size: 26rpx;
}
.user-info-box .item{
display: flex;
align-items: center;
justify-content: space-between;
padding: 10rpx 0;
border-bottom: 2rpx solid #f1f5f9;
}
.user-info-box .item text{
line-height: 1.8;
}
.user-info-box .avatar{
display: flex;
justify-content: flex-end;
width: calc(100% - 80rpx);
height: 100rpx;
padding: 0;
margin: 0;
background: none;
}
.user-info-box .avatar::after{
display: none;
}
.user-info-box .avatar .img{
width: 100rpx;
height: 100rpx;
border-radius: 100%;
overflow: hidden;
}
.user-info-box .avatar image{
width: 100%;
height: 100%;
}
.user-info-box .nick-name{
width: calc(100% - 80rpx);
height: 60rpx;
text-align: right;
}
.user-info-box .empower-btns{
display: flex;
align-items: center;
margin-top: 10rpx;
}
.user-info-box .empower-btns .btn{
width: 50%;
text-align: center;
align-items: 1.5;
color: #666666;
font-size: 30rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
}
.user-info-box .empower-btns .btn:nth-of-type(2){
color: #e42417;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/foot-bar/cart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/foot-bar/cate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/foot-bar/index.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
static/foot-bar/my.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
static/public/blue-bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
static/public/ling-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
static/public/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

1
store/actions.js Normal file
View File

@ -0,0 +1 @@
// 根级别的 action

16
store/index.js Normal file
View File

@ -0,0 +1,16 @@
// 组装模块并导出 store 的地方
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from '@/store/modules/moduleA'
import moduleB from '@/store/modules/moduleB'
Vue.use(Vuex);//vue的插件机制
//Vuex.modules 模块选项
const store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
export default store

112
store/modules/moduleA.js Normal file
View File

@ -0,0 +1,112 @@
// 购物车模块
export default {
state:{//存放状态
// 底部导航的高
footHeight:'',
token:'token已生成',
userInfo:{},
count:0,
publicColor:'',
todos: [{
id: 1,
text: '我是内容一',
done: true
},
{
id: 2,
text: '我是内容二',
done: false
}
],
obj:{
a:'吃鸡腿',
b:'吃自助餐'
},
titleList:[],
imgList:[],
onLineList:[],
cartNum:0,
cartPrice:0,
geList:[],
changeBusiness:false,
},
// Vuex中store数据改变的唯一方法就是mutations 不适合异步方法
mutations: {
setNum(state,num){
state.cartNum = num;
},
setPrice(state,price){
state.cartPrice = price;
},
setGe(state,payload){
state.geList = payload.geList;
},
footHeightEv(state,str){
state.footHeight = str;
},
add(state) {
state.count = 7;
},
add2(state, payload) {
state.count = payload.amount;
},
// 单个属性处理方法
setToken(state,str) {
state.token = str;
},
// 对象处理方法
updateUserInfo(state, payload) {
// 变更状态
state.userInfo = payload.userInfo;
},
// 新增字段方法
newProp(state,payload) {
state.obj = { ...state.obj, c: payload.c };
},
updateState(state, payload) {
state.onLineList = payload.list;
}
},
// 可以执行任意的同步和异步操作
actions:{
addCountAction ({commit}) {
commit('add')
},
addCountAction2 (context , payload) {
context.commit('add2', payload)
},
// 异步方法
addCountAction3 (context , payload) {
setTimeout(function () {
context.commit('add2', payload)
}, 2000)
},
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
},
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
},
// Vuex 允许我们在 store 中定义“getter”可以认为是 store 的计算属性),对 state 的加工,是派生出来的数据。 可以在多组件中共享 getter 函数,这样做还可以提高运行效率。
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => {
//state :可以访问数据
//getters访问其他函数等同于 store.getters
return getters.doneTodos.length
},
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
}

87
store/modules/moduleB.js Normal file
View File

@ -0,0 +1,87 @@
export default {
state:{//存放状态
token:'token已生成',
userInfo:{},
count:0,
publicColor:'',
todos: [{
id: 1,
text: '我是内容一',
done: true
},
{
id: 2,
text: '我是内容二',
done: false
}
],
obj:{
a:'吃鸡腿',
b:'吃自助餐'
}
},
// Vuex中store数据改变的唯一方法就是mutations 不适合异步方法
mutations: {
add(state) {
state.count = 7;
},
add2(state, payload) {
state.count = payload.amount;
},
// 单个属性处理方法
setToken(state,str) {
state.token = str;
},
// 对象处理方法
updateUserInfo(state, payload) {
// 变更状态
state.userInfo = payload.userInfo;
},
// 新增字段方法
newProp(state,payload) {
state.obj = { ...state.obj, c: payload.c };
}
},
// 可以执行任意的同步和异步操作
actions:{
addCountAction ({commit}) {
commit('add')
},
addCountAction2 (context , payload) {
context.commit('add2', payload)
},
// 异步方法
addCountAction3 (context , payload) {
setTimeout(function () {
context.commit('add2', payload)
}, 2000)
},
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
},
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
},
// Vuex 允许我们在 store 中定义“getter”可以认为是 store 的计算属性),对 state 的加工,是派生出来的数据。 可以在多组件中共享 getter 函数,这样做还可以提高运行效率。
getters: {
// doneTodos: state => {
// return state.todos.filter(todo => todo.done)
// },
// doneTodosCount: (state, getters) => {
// //state :可以访问数据
// //getters访问其他函数等同于 store.getters
// return getters.doneTodos.length
// },
// getTodoById: (state) => (id) => {
// return state.todos.find(todo => todo.id === id)
// }
}
}

1
store/mutations.js Normal file
View File

@ -0,0 +1 @@
// 根级别的 mutation

119
store/readme.md Normal file
View File

@ -0,0 +1,119 @@
#引入vuex状态机
在根目录创建store目录
#在main.js引入store、注册store、挂载store在程序上
import Vue from 'vue';
import App from './App';
#import store from './store'
#Vue.prototype.$store = store
const app = new Vue({
# store,
...App
})
app.$mount()
#在页面内使用store的属性
<view @tap="add"></view>
import { mapState,mapGetters,mapMutations } from 'vuex'//引入mapState
export default {
data() {
return {}
},
#单纯访问属性值
computed:{
tokenEv() {
return this.$store.state.token;
}
},
<!--
需要引入 import { mapState } from 'vuex'//引入mapState
-->
computed:mapState({
// 从state中拿到数据 箭头函数可使代码更简练
token: state => state.token,
}),
computed:mapState(['token']),
computed: {
...mapState({
token: function (state) {
return '追加的' + state.token
},
userInfo: state => state.userInfo,
})
},
computed:{
...mapState([
'token',
'userInfo',
'count',
'obj'
])
},
computed: {
...mapState({
token: state => state.moduleA.token,
count: state => state.moduleB.count
}),
},
#单纯访问方法
computed: {
todos() {
return this.$store.getters.doneTodos
}
},
computed: {
doneTodosCount() {
return this.$store.getters.doneTodosCount
}
},
<!-- 方法传值 -->
computed: {
getTodoById() {
return this.$store.getters.getTodoById(1)
}
},
<!--
需要引入 import { mapGetters } from 'vuex'//引入mapState
-->
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodos',
'doneTodosCount',
'getTodoById'
// ...
])
},
onLoad(options) {
#改变状态机里面的值
<!-- 传递字符串改变 -->
this.$store.commit('setToken', 'token已改变');
<!-- 传递对象 -->
this.$store.commit('updateUserInfo',{userInfo:'用户信息'})
this.$store.commit({
type: 'updateUserInfo',
userInfo: '新方式更新用户信息'
})
this.$store.commit('newProp',{c:'吃火锅'})
<!-- 输出值 -->
console.log(this.token);
<!-- 调用方法 -->
this.add();
<!-- 必须是同步方法 -->
this.$store.dispatch('addCountAction')
this.$store.dispatch('addCountAction2',{amount:10})
<!-- 异步方法 -->
this.$store.dispatch('addCountAction3',{amount:30})
setTimeout(()=>{
console.log(this.count,388);
},3000)
},
methods: {
<!--
需要引入 import { mapMutations } from 'vuex'//引入mapState
-->
...mapMutations(['add']),//对象展开运算符直接拿到add
}
}

4
unpackage/dist/build/mp-weixin/app.js vendored Normal file
View File

@ -0,0 +1,4 @@
require('./common/runtime.js')
require('./common/vendor.js')
require('./common/main.js')

34
unpackage/dist/build/mp-weixin/app.json vendored Normal file
View File

@ -0,0 +1,34 @@
{
"pages": [
"pages/index/index",
"pages/my/my"
],
"subPackages": [
{
"root": "pagesA",
"pages": [
"login/login"
]
}
],
"window": {
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FFFFFF",
"navigationStyle": "custom",
"backgroundColor": "#FFFFFF",
"backgroundTextStyle": "light"
},
"permission": {
"scope.userLocation": {
"desc": "将用于查询当前位置是否有货以及配送情况!"
}
},
"requiredPrivateInfos": [
"getLocation"
],
"usingComponents": {
"nothing-page": "/components/nothing/nothing-page",
"status-nav": "/components/status-nav/status-nav",
"foot-bar": "/components/foot-bar/foot-bar"
}
}

View File

@ -0,0 +1,3 @@
@import './common/main.wxss';
[data-custom-hidden="true"],[bind-data-custom-hidden="true"]{display: none !important;}

View File

@ -0,0 +1 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["common/main"],{"10fe":function(t,e,n){"use strict";var o=n("551e"),c=n.n(o);c.a},"551e":function(t,e,n){},"792b":function(t,e,n){"use strict";n.r(e);var o=n("847d"),c=n.n(o);for(var r in o)["default"].indexOf(r)<0&&function(t){n.d(e,t,(function(){return o[t]}))}(r);e["default"]=c.a},"847d":function(t,e,n){"use strict";(function(t){var o=n("4ea4");Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;o(n("8d0a"));var c={globalData:{projectname:"",lat:"",lng:"",hostapi:"https://votenew.scdxtc.cn"},onLaunch:function(){console.log=function(){},this.globalData.hostapi="https://www.guofuyunhuigou.com";t.getAccountInfoSync()},onShow:function(){},onHide:function(){}};e.default=c}).call(this,n("bc2e")["default"])},bced:function(t,e,n){"use strict";n.r(e);var o=n("792b");for(var c in o)["default"].indexOf(c)<0&&function(t){n.d(e,t,(function(){return o[t]}))}(c);n("10fe");var r=n("f0c5"),u=Object(r["a"])(o["default"],void 0,void 0,!1,null,null,null,!1,void 0,void 0);e["default"]=u.exports},be41:function(t,e,n){"use strict";(function(t,e,o){var c=n("4ea4"),r=c(n("9523"));n("cd27");var u=c(n("66fd")),a=c(n("bced")),f=c(n("6440")),l=c(n("8d0a")),i=c(n("2ddd"));function d(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,o)}return n}t.__webpack_require_UNI_MP_PLUGIN__=n,u.default.prototype.$store=f.default;u.default.component("nothing-page",(function(){n.e("components/nothing/nothing-page").then(function(){return resolve(n("d63d"))}.bind(null,n)).catch(n.oe)}));u.default.component("status-nav",(function(){n.e("components/status-nav/status-nav").then(function(){return resolve(n("ea47"))}.bind(null,n)).catch(n.oe)}));u.default.component("foot-bar",(function(){n.e("components/foot-bar/foot-bar").then(function(){return resolve(n("bb0a"))}.bind(null,n)).catch(n.oe)})),u.default.prototype.$toolAll=l.default,u.default.prototype.$requst=i.default,"devtools"!==e.getSystemInfoSync().platform&&(console.log=function(){}),a.default.mpType="app";var s=new u.default(function(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?d(Object(n),!0).forEach((function(e){(0,r.default)(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):d(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}({store:f.default},a.default));o(s).$mount()}).call(this,n("bc2e")["default"],n("543d")["default"],n("543d")["createApp"])}},[["be41","common/runtime","common/vendor"]]]);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,4 @@
!function(){try{var a=Function("return this")();a&&!a.Math&&(Object.assign(a,{isFinite:isFinite,Array:Array,Date:Date,Error:Error,Function:Function,Math:Math,Object:Object,RegExp:RegExp,String:String,TypeError:TypeError,setTimeout:setTimeout,clearTimeout:clearTimeout,setInterval:setInterval,clearInterval:clearInterval}),"undefined"!=typeof Reflect&&(a.Reflect=Reflect))}catch(a){}}();
(function(e){function t(t){for(var r,o,s=t[0],i=t[1],c=t[2],p=0,f=[];p<s.length;p++)o=s[p],Object.prototype.hasOwnProperty.call(a,o)&&a[o]&&f.push(a[o][0]),a[o]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);l&&l(t);while(f.length)f.shift()();return u.push.apply(u,c||[]),n()}function n(){for(var e,t=0;t<u.length;t++){for(var n=u[t],r=!0,o=1;o<n.length;o++){var i=n[o];0!==a[i]&&(r=!1)}r&&(u.splice(t--,1),e=s(s.s=n[0]))}return e}var r={},o={"common/runtime":0},a={"common/runtime":0},u=[];function s(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,s),n.l=!0,n.exports}s.e=function(e){var t=[];o[e]?t.push(o[e]):0!==o[e]&&{"components/foot-bar/foot-bar":1,"components/nothing/nothing-page":1,"components/status-nav/status-nav":1,"components/swipers/swiper-pu":1}[e]&&t.push(o[e]=new Promise((function(t,n){for(var r=({"components/foot-bar/foot-bar":"components/foot-bar/foot-bar","components/nothing/nothing-page":"components/nothing/nothing-page","components/status-nav/status-nav":"components/status-nav/status-nav","components/swipers/swiper-pu":"components/swipers/swiper-pu"}[e]||e)+".wxss",a=s.p+r,u=document.getElementsByTagName("link"),i=0;i<u.length;i++){var c=u[i],p=c.getAttribute("data-href")||c.getAttribute("href");if("stylesheet"===c.rel&&(p===r||p===a))return t()}var l=document.getElementsByTagName("style");for(i=0;i<l.length;i++){c=l[i],p=c.getAttribute("data-href");if(p===r||p===a)return t()}var f=document.createElement("link");f.rel="stylesheet",f.type="text/css",f.onload=t,f.onerror=function(t){var r=t&&t.target&&t.target.src||a,u=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");u.code="CSS_CHUNK_LOAD_FAILED",u.request=r,delete o[e],f.parentNode.removeChild(f),n(u)},f.href=a;var m=document.getElementsByTagName("head")[0];m.appendChild(f)})).then((function(){o[e]=0})));var n=a[e];if(0!==n)if(n)t.push(n[2]);else{var r=new Promise((function(t,r){n=a[e]=[t,r]}));t.push(n[2]=r);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,s.nc&&i.setAttribute("nonce",s.nc),i.src=function(e){return s.p+""+e+".js"}(e);var c=new Error;u=function(t){i.onerror=i.onload=null,clearTimeout(p);var n=a[e];if(0!==n){if(n){var r=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;c.message="Loading chunk "+e+" failed.\n("+r+": "+o+")",c.name="ChunkLoadError",c.type=r,c.request=o,n[1](c)}a[e]=void 0}};var p=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(t)},s.m=e,s.c=r,s.d=function(e,t,n){s.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},s.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s.t=function(e,t){if(1&t&&(e=s(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(s.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)s.d(n,r,function(t){return e[t]}.bind(null,r));return n},s.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return s.d(t,"a",t),t},s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},s.p="/",s.oe=function(e){throw console.error(e),e};var i=global["webpackJsonp"]=global["webpackJsonp"]||[],c=i.push.bind(i);i.push=t,i=i.slice();for(var p=0;p<i.length;p++)t(i[p]);var l=c;n()})([]);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["components/foot-bar/foot-bar"],{"18da":function(t,o,a){"use strict";a.r(o);var e=a("c847"),n=a.n(e);for(var i in e)["default"].indexOf(i)<0&&function(t){a.d(o,t,(function(){return e[t]}))}(i);o["default"]=n.a},"467b":function(t,o,a){"use strict";var e=a("7a29"),n=a.n(e);n.a},"58f2":function(t,o,a){"use strict";a.d(o,"b",(function(){return e})),a.d(o,"c",(function(){return n})),a.d(o,"a",(function(){}));var e=function(){var t=this.$createElement,o=(this._self._c,this.footBarList.length);this.$mp.data=Object.assign({},{$root:{g0:o}})},n=[]},"7a29":function(t,o,a){},bb0a:function(t,o,a){"use strict";a.r(o);var e=a("58f2"),n=a("18da");for(var i in n)["default"].indexOf(i)<0&&function(t){a.d(o,t,(function(){return n[t]}))}(i);a("467b");var c=a("f0c5"),r=Object(c["a"])(n["default"],e["b"],e["c"],!1,null,"32ac2a7c",null,!1,e["a"],void 0);o["default"]=r.exports},c847:function(t,o,a){"use strict";(function(t,a){Object.defineProperty(o,"__esModule",{value:!0}),o.default=void 0;var e={name:"foot-bar",props:{current:{type:Number,default:0}},data:function(){return{footBarList:[{normalPath:"/static/foot-bar/index.png",activePath:"/static/foot-bar/index-active.png",key:"home",title:"首页"},{normalPath:"/static/foot-bar/my.png",activePath:"/static/foot-bar/my-active.png",key:"my",title:"我的"}]}},mounted:function(){t.getStorageSync("footBarList")&&(this.footBarList=t.getStorageSync("footBarList"));var o=a.createSelectorQuery().in(this);o.select(".foot-bar").boundingClientRect((function(o){t.setStorageSync("footHeight",o.height)})).exec()},methods:{getFootBar:function(){var o=this;this.$requst.get("/api/index/mini-program-setting").then((function(a){if(0==a.code){console.log(a,"底部信息");var e=[];a.data.footBar.forEach((function(t){var o={normalPath:"".concat(getApp().globalData.hostapi)+t.icon[0],activePath:"".concat(getApp().globalData.hostapi)+t.icon[1],title:t.name};e.push(o)})),o.footBarList=e,t.setStorageSync("footBarList",o.footBarList)}else o.$toolAll.tools.showToast(a.msg)}))},chooseEv:function(o){switch(console.log(o),o){case 0:t.reLaunch({url:"/pages/index/index"});break;case 1:this.$toolAll.tools.judgeAuth()&&t.reLaunch({url:"/pages/my/my"});break}}}};o.default=e}).call(this,a("543d")["default"],a("bc2e")["default"])}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'components/foot-bar/foot-bar-create-component',
{
'components/foot-bar/foot-bar-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('543d')['createComponent'](__webpack_require__("bb0a"))
})
},
[['components/foot-bar/foot-bar-create-component']]
]);

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"component": true
}

View File

@ -0,0 +1 @@
<view class="foot-bar data-v-32ac2a7c"><block wx:for="{{footBarList}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view data-event-opts="{{[['tap',[['chooseEv',[index]]]]]}}" class="item data-v-32ac2a7c" style="{{'width:'+('calc(100%/'+$root.g0+')')+';'}}" bindtap="__e"><view class="icon data-v-32ac2a7c"><image src="{{current==index?item.activePath:item.normalPath}}" mode="heightFix" class="data-v-32ac2a7c"></image></view><view class="title data-v-32ac2a7c" style="{{'color:'+(current==index?'#0567b8':'#a0a5af')+';'}}">{{item.title}}</view></view></block></view>

View File

@ -0,0 +1 @@
.foot-bar.data-v-32ac2a7c{display:flex;justify-content:space-around;align-items:center;width:100%;height:98rpx;background-color:#fff;box-shadow:0 0 16rpx hsla(0,0%,57.3%,.06);position:fixed;left:0;bottom:0;z-index:99}.foot-bar .item.data-v-32ac2a7c{display:flex;flex-wrap:wrap;justify-items:center;text-align:center}.foot-bar .icon.data-v-32ac2a7c{justify-content:center;align-items:center;width:100%;height:39rpx}.foot-bar .icon image.data-v-32ac2a7c{height:100%}.foot-bar .title.data-v-32ac2a7c{width:100%;margin-top:6rpx;font-size:22rpx;line-height:1.3}

View File

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["components/nothing/nothing-page"],{"026c":function(n,t,e){"use strict";var u=e("bcca"),a=e.n(u);a.a},"89df":function(n,t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var u={name:"nothing-page",props:{imgSrc:{type:String,default:""},content:{type:String,default:"暂无内容"},currentType:{type:Number,default:0}},data:function(){return{}}};t.default=u},"8d4f":function(n,t,e){"use strict";e.d(t,"b",(function(){return u})),e.d(t,"c",(function(){return a})),e.d(t,"a",(function(){}));var u=function(){var n=this.$createElement;this._self._c},a=[]},b79a:function(n,t,e){"use strict";e.r(t);var u=e("89df"),a=e.n(u);for(var c in u)["default"].indexOf(c)<0&&function(n){e.d(t,n,(function(){return u[n]}))}(c);t["default"]=a.a},bcca:function(n,t,e){},d63d:function(n,t,e){"use strict";e.r(t);var u=e("8d4f"),a=e("b79a");for(var c in a)["default"].indexOf(c)<0&&function(n){e.d(t,n,(function(){return a[n]}))}(c);e("026c");var r=e("f0c5"),f=Object(r["a"])(a["default"],u["b"],u["c"],!1,null,"2f127f68",null,!1,u["a"],void 0);t["default"]=f.exports}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'components/nothing/nothing-page-create-component',
{
'components/nothing/nothing-page-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('543d')['createComponent'](__webpack_require__("d63d"))
})
},
[['components/nothing/nothing-page-create-component']]
]);

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"component": true
}

View File

@ -0,0 +1 @@
<view class="nothing data-v-2f127f68"><view class="nothing-box data-v-2f127f68"><block wx:if="{{imgSrc!=''}}"><image class="nothing-img data-v-2f127f68" src="{{imgSrc}}" mode="aspectFill" lazy-load="{{true}}"></image></block><view class="{{['iconImg','icon','_i','data-v-2f127f68',['icon-nothing-more','icon-nothing-data','icon-nothing-collection'][currentType]]}}"></view><block wx:if="{{currentType!=1}}"><view class="nothing-con data-v-2f127f68">{{content}}</view></block></view></view>

View File

@ -0,0 +1 @@
.nothing.data-v-2f127f68{position:fixed;top:0;bottom:0;left:0;right:0;display:flex;justify-content:center;align-items:center}.nothing-box.data-v-2f127f68{display:flex;justify-content:center;flex-direction:column;align-items:center}.nothing-box .nothing-img.data-v-2f127f68{width:470rpx;height:270rpx}.iconImg.data-v-2f127f68{font-size:280rpx;color:#999}.nothing-con.data-v-2f127f68{font-size:24rpx;font-family:PingFang SC;font-weight:500;color:#999}

View File

@ -0,0 +1,10 @@
(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["components/status-nav/status-nav"],{1042:function(t,e,n){"use strict";n.r(e);var a=n("6b4c"),i=n.n(a);for(var o in a)["default"].indexOf(o)<0&&function(t){n.d(e,t,(function(){return a[t]}))}(o);e["default"]=i.a},"6b4c":function(t,e,n){"use strict";(function(t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var n={name:"status-nav",props:{backgroudColor:{type:String,default:"#f7f7f7"},navBarHeight:{type:String,default:"50px"},ifReturn:{type:Boolean,default:!0},returnColor:{type:String,default:"#333333"},ifTitle:{type:Boolean,default:!0},navBarTitle:{type:String,default:""},clipNumber:{type:String,default:"1"},titleColor:{type:String,default:"#333333"},ifCenter:{type:Boolean,default:!0},ifBold:{type:Boolean,default:!1},marginBottom:{type:String,default:"0"}},data:function(){return{statusBarHeight:t.getSystemInfoSync().statusBarHeight,ifNet:!0,netText:"当前无网络",netTimer:null}},mounted:function(){var e=this;this.$toolAll.tools.networkStatus(),this.$toolAll.tools.obtainPagePath(),setTimeout((function(){e.ifNet=t.getStorageSync("isNet")}),500)},methods:{refreshEv:function(){var e=this;this.netText="正在刷新...";var n=0;this.netTimer=setInterval((function(){n++,e.$toolAll.tools.networkStatus(),t.getStorageSync("isNet")&&(clearInterval(e.netTimer),e.ifNet=!0),10==n&&(clearInterval(e.netTimer),e.netText="刷新失败",n=0)}),1e3)},backEv:function(){t.navigateBack({delta:1,fail:function(){t.reLaunch({url:"/pages/index/index"})}})}}};e.default=n}).call(this,n("543d")["default"])},"712b":function(t,e,n){"use strict";var a=n("c5b2"),i=n.n(a);i.a},"7a93":function(t,e,n){"use strict";n.d(e,"b",(function(){return a})),n.d(e,"c",(function(){return i})),n.d(e,"a",(function(){}));var a=function(){var t=this.$createElement;this._self._c},i=[]},c5b2:function(t,e,n){},ea47:function(t,e,n){"use strict";n.r(e);var a=n("7a93"),i=n("1042");for(var o in i)["default"].indexOf(o)<0&&function(t){n.d(e,t,(function(){return i[t]}))}(o);n("712b");var r=n("f0c5"),u=Object(r["a"])(i["default"],a["b"],a["c"],!1,null,"4508490a",null,!1,a["a"],void 0);e["default"]=u.exports}}]);
;(global["webpackJsonp"] = global["webpackJsonp"] || []).push([
'components/status-nav/status-nav-create-component',
{
'components/status-nav/status-nav-create-component':(function(module, exports, __webpack_require__){
__webpack_require__('543d')['createComponent'](__webpack_require__("ea47"))
})
},
[['components/status-nav/status-nav-create-component']]
]);

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"component": true
}

Some files were not shown because too many files have changed in this diff Show More