更新商城的演示地址
@ -62,7 +62,7 @@
|
||||
| [yudao-ui-admin](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin) | [![Gitee star](https://gitee.com/zhijiantianya/ruoyi-vue-pro/badge/star.svg?theme=white)](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin) [![GitHub stars](https://img.shields.io/github/stars/YunaiV/ruoyi-vue-pro.svg?style=social&label=Stars)](https://github.com/YunaiV/ruoyi-vue-pro/tree/master/yudao-ui-admin) | 基于 Vue2 + element-ui 实现的管理后台 |
|
||||
| [yudao-ui-admin-uniapp](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin-uniapp) | [![Gitee star](https://gitee.com/zhijiantianya/ruoyi-vue-pro/badge/star.svg?theme=white)](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin-uniapp) [![GitHub stars](https://img.shields.io/github/stars/YunaiV/ruoyi-vue-pro.svg?style=social&label=Stars)](https://github.com/YunaiV/ruoyi-vue-pro/tree/master/yudao-ui-admin-uniapp) | 基于 uni-app + uni-ui 实现的管理后台的小程序 |
|
||||
| [yudao-ui-go-view](https://gitee.com/yudaocode/yudao-ui-go-view) | [![Gitee star](https://gitee.com/yudaocode/yudao-ui-go-view/badge/star.svg?theme=white)](https://gitee.com/yudaocode/yudao-ui-go-view) [![GitHub stars](https://img.shields.io/github/stars/yudaocode/yudao-ui-go-view.svg?style=social&label=Stars)](https://github.com/yudaocode/yudao-ui-go-view) | 基于 Vue3 + naive-ui 实现的大屏报表 |
|
||||
| [yudao-ui-app](https://gitee.com/yudaocode/yudao-mall-uniapp) | [![Gitee star](https://gitee.com/yudaocode/yudao-mall-uniapp/badge/star.svg?theme=white)](https://gitee.com/yudaocode/yudao-mall-uniapp) [![GitHub stars](https://img.shields.io/github/stars/yudaocode/yudao-mall-uniapp.svg?style=social&label=Stars)](https://github.com/yudaocode/yudao-mall-uniapp) | 基于 uni-app 实现的商城小程序 |
|
||||
| [yudao-mall-uniapp](https://gitee.com/yudaocode/yudao-mall-uniapp) | [![Gitee star](https://gitee.com/yudaocode/yudao-mall-uniapp/badge/star.svg?theme=white)](https://gitee.com/yudaocode/yudao-mall-uniapp) [![GitHub stars](https://img.shields.io/github/stars/yudaocode/yudao-mall-uniapp.svg?style=social&label=Stars)](https://github.com/yudaocode/yudao-mall-uniapp) | 基于 uni-app 实现的商城小程序 |
|
||||
|
||||
## 🐰 分支说明
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
# 告诉EditorConfig插件,这是根文件,不用继续往上查找
|
||||
root = true
|
||||
|
||||
# 匹配全部文件
|
||||
[*]
|
||||
# 设置字符集
|
||||
charset = utf-8
|
||||
# 缩进风格,可选space、tab
|
||||
indent_style = space
|
||||
# 缩进的空格数
|
||||
indent_size = 2
|
||||
# 结尾换行符,可选lf、cr、crlf
|
||||
end_of_line = lf
|
||||
# 在文件结尾插入新行
|
||||
insert_final_newline = true
|
||||
# 删除一行中的前后空格
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# 匹配md结尾的文件
|
||||
[*.md]
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = false
|
7
yudao-ui-app/.gitignore
vendored
@ -1,7 +0,0 @@
|
||||
/unpackage/dist/*
|
||||
/unpackage/cache/*
|
||||
/unpackage/release/*
|
||||
/node_modules/*
|
||||
/.idea/*
|
||||
/.hbuilderx/
|
||||
/.vscode/
|
@ -1,34 +0,0 @@
|
||||
<script>
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
console.log('App Launch')
|
||||
// #ifdef H5
|
||||
//在页面加载时读取sessionStorage里的状态信息
|
||||
if (sessionStorage.getItem('store')) {
|
||||
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))))
|
||||
}
|
||||
//在页面刷新时将vuex里的信息保存到sessionStorage里
|
||||
window.addEventListener('beforeunload', () => {
|
||||
sessionStorage.setItem('store', JSON.stringify(this.$store.state))
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
onShow: function () {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function () {
|
||||
console.log('App Hide')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/** 引入全局基本样式 */
|
||||
@import 'styles/base.scss';
|
||||
|
||||
/* 引入 uView 基础样式 */
|
||||
@import '@/uni_modules/uview-ui/index.scss';
|
||||
|
||||
/*每个页面公共scss */
|
||||
@import 'app.scss';
|
||||
</style>
|
1
yudao-ui-app/README.md
Normal file
@ -0,0 +1 @@
|
||||
迁移至 <https://github.com/yudaocode/yudao-mall-uniapp> 仓库
|
@ -1,15 +0,0 @@
|
||||
//请求工具参考https://ext.dcloud.net.cn/plugin?id=392
|
||||
const { http } = uni.$u
|
||||
|
||||
//获得用户收件地址列表
|
||||
export const getAddressList = params => http.get('/member/address/list', params)
|
||||
//创建用户收件地址
|
||||
export const createAddress = data => http.post('/member/address/create', data)
|
||||
//通过ID获得用户收件地址
|
||||
export const getAddressById = params => http.get('/member/address/get', { params })
|
||||
//获得默认的用户收件地址
|
||||
export const getDefaultUserAddress = params => http.get('/member/address/get-default', { params })
|
||||
//更新用户收件地址
|
||||
export const updateAddress = params => http.put('/member/address/update', params)
|
||||
//删除用户收件地址
|
||||
export const deleteAddress = params => http.delete('/member/address/delete', {}, { params })
|
@ -1,15 +0,0 @@
|
||||
//请求工具参考https://ext.dcloud.net.cn/plugin?id=392
|
||||
const { http } = uni.$u
|
||||
|
||||
//使用手机 + 密码登录
|
||||
export const passwordLogin = data => http.post('/member/auth/login', data)
|
||||
//发送手机验证码
|
||||
export const sendSmsCode = data => http.post('/member/auth/send-sms-code', data)
|
||||
//使用手机 + 验证码登录
|
||||
export const smsLogin = data => http.post('/member/auth/sms-login', data)
|
||||
//微信小程序的一键登录
|
||||
export const weixinMiniAppLogin = data => http.post('/member/auth/weixin-mini-app-login', data)
|
||||
//刷新令牌
|
||||
export const refreshToken = data => http.post('/member/auth/refresh-token', {data})
|
||||
//退出登录
|
||||
export const logout = data => http.post('/member/auth/logout', data)
|
@ -1,5 +0,0 @@
|
||||
const { http } = uni.$u
|
||||
|
||||
//获取购物车数据
|
||||
export const getCartProductDetail = () => http.get('/trade/cart/get-detail')
|
||||
|
@ -1,5 +0,0 @@
|
||||
//请求工具参考https://ext.dcloud.net.cn/plugin?id=392
|
||||
const { http } = uni.$u
|
||||
|
||||
// 查询分类列表
|
||||
export const categoryListData = params => http.get('product/category/list', { params })
|
@ -1,7 +0,0 @@
|
||||
//请求工具参考https://ext.dcloud.net.cn/plugin?id=392
|
||||
const { http } = uni.$u
|
||||
|
||||
// 获取滚动图数据
|
||||
export const getBannerData = params => http.get('/index', { params })
|
||||
// 获取滚动通知数据
|
||||
export const getNoticeData = params => http.get('/notice', { params })
|
@ -1,6 +0,0 @@
|
||||
const { http } = uni.$u
|
||||
|
||||
// 获得订单交易分页
|
||||
export const getOrderPage = params => http.get('/trade/order/page', { params })
|
||||
// 获得交易订单详情
|
||||
export const getOrderDetail = params => http.get('/trade/order/get-detail', { params })
|
@ -1,8 +0,0 @@
|
||||
//请求工具参考https://ext.dcloud.net.cn/plugin?id=392
|
||||
const { http } = uni.$u
|
||||
|
||||
// 查询商品spu列表
|
||||
export const productSpuPage = params => http.get('product/spu/page', { params })
|
||||
|
||||
// 查询商品
|
||||
export const getSpuDetail = id => http.get('product/spu/get-detail?id=' + id, { })
|
@ -1,14 +0,0 @@
|
||||
//请求工具参考https://ext.dcloud.net.cn/plugin?id=392
|
||||
const { http } = uni.$u
|
||||
|
||||
//获取用户信息
|
||||
export const getUserInfo = params => http.get('/member/user/get', params)
|
||||
//修改用户头像
|
||||
export const updateAvatar = filePath =>
|
||||
http.upload('/member/user/update-avatar', {
|
||||
name: 'avatarFile',
|
||||
fileType: 'image',
|
||||
filePath: filePath
|
||||
})
|
||||
//修改用户昵称
|
||||
export const updateNickname = params => http.put('/member/user/update-nickname', {}, { params })
|
@ -1,8 +0,0 @@
|
||||
/* 页面公共scss */
|
||||
.container {
|
||||
background-color: $custom-bg-color;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
module.exports = {
|
||||
//后端接口地址
|
||||
baseUrl: 'http://127.0.0.1:48080/app-api',
|
||||
// baseUrl: 'http://api-dashboard.yudao.iocoder.cn/app-api',
|
||||
// 超时
|
||||
timeout: 30000,
|
||||
// 禁用 Cookie 等信息
|
||||
withCredentials: false,
|
||||
header: {
|
||||
//租户ID
|
||||
'tenant-id': 1
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
export default {
|
||||
'0': { name: '待付款', icon: 'red-packet'},
|
||||
'10': { name: '待发货', icon: 'car'},
|
||||
'20': { name: '待收货', icon: 'order'},
|
||||
'30': { name: '已完成', icon: 'integral'},
|
||||
'40': { name: '已取消', icon: 'close-circle'}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
/* uView组件全局属性 */
|
||||
uni.$u.props.gap.bgColor = '#ffffff'
|
||||
uni.$u.props.gap.height = '10'
|
@ -1,742 +0,0 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view v-if="fields=='year'" class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.years" :key="index">{{item}}年</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<picker-view v-if="fields=='month'" class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.years" :key="index">{{item}}年</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.months" :key="index">{{item}}月</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<picker-view v-if="fields=='day'" class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.years" :key="index">{{item}}年</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.months" :key="index">{{item}}月</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.days" :key="index">{{item}}日</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<picker-view v-if="fields=='hour'" class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.years" :key="index">{{item}}年</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.months" :key="index">{{item}}月</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.days" :key="index">{{item}}日</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.hours" :key="index">{{item}}时</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<picker-view v-if="fields=='minute'" class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.years" :key="index">{{item}}年</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.months" :key="index">{{item}}月</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.days" :key="index">{{item}}日</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.hours" :key="index">{{item}}时</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.minutes" :key="index">{{item}}分</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<picker-view v-if="fields=='second'" class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.years" :key="index">{{item}}年</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.months" :key="index">{{item}}月</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.days" :key="index">{{item}}日</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.hours" :key="index">{{item}}时</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.minutes" :key="index">{{item}}分</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.seconds" :key="index">{{item}}秒</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickVal:[],
|
||||
range:{
|
||||
years:[],
|
||||
months:[],
|
||||
days:[],
|
||||
hours:[],
|
||||
minutes:[],
|
||||
seconds:[]
|
||||
},
|
||||
checkObj:{}
|
||||
};
|
||||
},
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
startYear:{
|
||||
type:[String,Number],
|
||||
default:""
|
||||
},
|
||||
endYear:{
|
||||
type:[String,Number],
|
||||
default:""
|
||||
},
|
||||
value:{
|
||||
type:[String,Array,Number],
|
||||
default:""
|
||||
},
|
||||
current:{//是否默认选中当前日期
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
disabledAfter:{//是否禁用当前之后的日期
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
fields:{
|
||||
type:String,
|
||||
default:"day"
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
fields(val){
|
||||
this.initData();
|
||||
},
|
||||
value(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods:{
|
||||
formatNum(n){
|
||||
return (Number(n)<10?'0'+Number(n):Number(n)+'');
|
||||
},
|
||||
checkValue(value){
|
||||
let strReg,example
|
||||
switch(this.fields){
|
||||
case "year":
|
||||
strReg=/^\d{4}$/;
|
||||
example="2019";
|
||||
break;
|
||||
case "month":
|
||||
strReg=/^\d{4}-\d{2}$/;
|
||||
example="2019-02";
|
||||
break;
|
||||
case "day":
|
||||
strReg=/^\d{4}-\d{2}-\d{2}$/;
|
||||
example="2019-02-01";
|
||||
break;
|
||||
case "hour":
|
||||
strReg=/^\d{4}-\d{2}-\d{2} \d{2}(:\d{2}){1,2}?$/;
|
||||
example="2019-02-01 18:00:00或2019-02-01 18";
|
||||
break;
|
||||
case "minute":
|
||||
strReg=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}(:\d{2}){0,1}?$/;
|
||||
example="2019-02-01 18:06:00或2019-02-01 18:06";
|
||||
break;
|
||||
case "second":
|
||||
strReg=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
|
||||
example="2019-02-01 18:06:01";
|
||||
break;
|
||||
}
|
||||
if(!strReg.test(value)){
|
||||
console.log(new Error("请传入与mode、fields匹配的value值,例value="+example+""))
|
||||
}
|
||||
return strReg.test(value);
|
||||
},
|
||||
resetData(year,month,day,hour,minute){
|
||||
let curDate=this.getCurrenDate();
|
||||
let curFlag=this.current;
|
||||
let curYear=curDate.curYear;
|
||||
let curMonth=curDate.curMonth;
|
||||
let curDay=curDate.curDay;
|
||||
let curHour=curDate.curHour;
|
||||
let curMinute=curDate.curMinute;
|
||||
let curSecond=curDate.curSecond;
|
||||
let months=[],days=[],hours=[],minutes=[],seconds=[];
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let monthsLen=disabledAfter?(year*1<curYear?12:curMonth):12;
|
||||
let totalDays=new Date(year,month,0).getDate();//计算当月有几天;
|
||||
let daysLen=disabledAfter?((year*1<curYear||month*1<curMonth)?totalDays:curDay):totalDays;
|
||||
let hoursLen=disabledAfter?((year*1<curYear||month*1<curMonth||day*1<curDay)?24:curHour+1):24;
|
||||
let minutesLen=disabledAfter?((year*1<curYear||month*1<curMonth||day*1<curDay||hour*1<curHour)?60:curMinute+1):60;
|
||||
let secondsLen=disabledAfter?((year*1<curYear||month*1<curMonth||day*1<curDay||hour*1<curHour||minute*1<curMinute)?60:curSecond+1):60;
|
||||
for(let month=1;month<=monthsLen;month++){
|
||||
months.push(this.formatNum(month));
|
||||
};
|
||||
for(let day=1;day<=daysLen;day++){
|
||||
days.push(this.formatNum(day));
|
||||
}
|
||||
for(let hour=0;hour<hoursLen;hour++){
|
||||
hours.push(this.formatNum(hour));
|
||||
}
|
||||
for(let minute=0;minute<minutesLen;minute++){
|
||||
minutes.push(this.formatNum(minute));
|
||||
}
|
||||
for(let second=0;second<secondsLen;second++){
|
||||
seconds.push(this.formatNum(second));
|
||||
}
|
||||
return{
|
||||
months,
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds
|
||||
}
|
||||
},
|
||||
isLeapYear (Year) {
|
||||
if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
getData(dVal){
|
||||
//用来处理初始化数据
|
||||
let curFlag=this.current;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let fields=this.fields;
|
||||
let curDate=this.getCurrenDate();
|
||||
let curYear=curDate.curYear;
|
||||
let curMonthdays=curDate.curMonthdays;
|
||||
let curMonth=curDate.curMonth;
|
||||
let curDay=curDate.curDay;
|
||||
let curHour=curDate.curHour;
|
||||
let curMinute=curDate.curMinute;
|
||||
let curSecond=curDate.curSecond;
|
||||
let defaultDate=this.getDefaultDate();
|
||||
let startYear=this.getStartDate().getFullYear();
|
||||
let endYear=this.getEndDate().getFullYear();
|
||||
//颗粒度,禁用当前之后日期仅对year,month,day,hour生效;分钟秒禁用没有意义,
|
||||
let years=[],months=[],days=[],hours=[],minutes=[],seconds=[];
|
||||
let year=dVal[0]*1;
|
||||
let month=dVal[1]*1;
|
||||
let day=dVal[2]*1;
|
||||
let hour=dVal[3]*1;
|
||||
let minute=dVal[4]*1;
|
||||
let monthsLen=disabledAfter?(year<curYear?12:curDate.curMonth):12;
|
||||
let daysLen=disabledAfter?((year<curYear||month<curMonth)?defaultDate.defaultDays:curDay):(curFlag?curMonthdays:defaultDate.defaultDays);
|
||||
let hoursLen=disabledAfter?((year<curYear||month<curMonth||day<curDay)?24:curHour+1):24;
|
||||
let minutesLen=disabledAfter?((year<curYear||month<curMonth||day<curDay||hour<curHour)?60:curMinute+1):60;
|
||||
let secondsLen=disabledAfter?((year<curYear||month<curMonth||day<curDay||hour<curHour||minute<curMinute)?60:curSecond+1):60;
|
||||
for(let year=startYear;year<=(disabledAfter?curYear:endYear);year++){
|
||||
years.push(year.toString())
|
||||
}
|
||||
for(let month=1;month<=monthsLen;month++){
|
||||
months.push(this.formatNum(month));
|
||||
}
|
||||
for(let day=1;day<=daysLen;day++){
|
||||
days.push(this.formatNum(day));
|
||||
}
|
||||
for(let hour=0;hour<hoursLen;hour++){
|
||||
hours.push(this.formatNum(hour));
|
||||
}
|
||||
for(let minute=0;minute<minutesLen;minute++){
|
||||
minutes.push(this.formatNum(minute));
|
||||
}
|
||||
// for(let second=0;second<(disabledAfter?curDate.curSecond+1:60);second++){
|
||||
// seconds.push(this.formatNum(second));
|
||||
// }
|
||||
for(let second=0;second<60;second++){
|
||||
seconds.push(this.formatNum(second));
|
||||
}
|
||||
return {
|
||||
years,
|
||||
months,
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds
|
||||
}
|
||||
},
|
||||
getCurrenDate(){
|
||||
let curDate=new Date();
|
||||
let curYear=curDate.getFullYear();
|
||||
let curMonth=curDate.getMonth()+1;
|
||||
let curMonthdays=new Date(curYear,curMonth,0).getDate();
|
||||
let curDay=curDate.getDate();
|
||||
let curHour=curDate.getHours();
|
||||
let curMinute=curDate.getMinutes();
|
||||
let curSecond=curDate.getSeconds();
|
||||
return{
|
||||
curDate,
|
||||
curYear,
|
||||
curMonth,
|
||||
curMonthdays,
|
||||
curDay,
|
||||
curHour,
|
||||
curMinute,
|
||||
curSecond
|
||||
}
|
||||
},
|
||||
getDefaultDate(){
|
||||
let value=this.value;
|
||||
let reg=/-/g;
|
||||
let defaultDate=value?new Date(value.replace(reg,"/")):new Date();
|
||||
let defaultYear=defaultDate.getFullYear();
|
||||
let defaultMonth=defaultDate.getMonth()+1;
|
||||
let defaultDay=defaultDate.getDate();
|
||||
let defaultDays=new Date(defaultYear,defaultMonth,0).getDate()*1;
|
||||
return{
|
||||
defaultDate,
|
||||
defaultYear,
|
||||
defaultMonth,
|
||||
defaultDay,
|
||||
defaultDays
|
||||
}
|
||||
},
|
||||
getStartDate(){
|
||||
let start=this.startYear;
|
||||
let startDate="";
|
||||
let reg=/-/g;
|
||||
if(start){
|
||||
startDate=new Date(start+"/01/01");
|
||||
}else{
|
||||
startDate=new Date("1970/01/01");
|
||||
}
|
||||
return startDate;
|
||||
},
|
||||
getEndDate(){
|
||||
let end=this.endYear;
|
||||
let reg=/-/g;
|
||||
let endDate="";
|
||||
if(end){
|
||||
endDate=new Date(end+"/12/01");
|
||||
}else{
|
||||
endDate=new Date();
|
||||
}
|
||||
return endDate;
|
||||
},
|
||||
getDval(){
|
||||
let value=this.value;
|
||||
let fields=this.fields;
|
||||
let dVal=null;
|
||||
let aDate=new Date();
|
||||
let year=this.formatNum(aDate.getFullYear());
|
||||
let month=this.formatNum(aDate.getMonth()+1);
|
||||
let day=this.formatNum(aDate.getDate());
|
||||
let hour=this.formatNum(aDate.getHours());
|
||||
let minute=this.formatNum(aDate.getMinutes());
|
||||
let second=this.formatNum(aDate.getSeconds());
|
||||
if(value){
|
||||
let flag=this.checkValue(value);
|
||||
if(!flag){
|
||||
dVal=[year,month,day,hour,minute,second]
|
||||
}else{
|
||||
switch(this.fields){
|
||||
case "year":
|
||||
dVal=value?[value]:[];
|
||||
break;
|
||||
case "month":
|
||||
dVal=value?value.split("-"):[];
|
||||
break;
|
||||
case "day":
|
||||
dVal=value?value.split("-"):[];
|
||||
break;
|
||||
case "hour":
|
||||
dVal=[...value.split(" ")[0].split("-"),...value.split(" ")[1].split(":")];
|
||||
break;
|
||||
case "minute":
|
||||
dVal=value?[...value.split(" ")[0].split("-"),...value.split(" ")[1].split(":")]:[];
|
||||
break;
|
||||
case "second":
|
||||
dVal=[...value.split(" ")[0].split("-"),...value.split(" ")[1].split(":")];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
dVal=[year,month,day,hour,minute,second]
|
||||
}
|
||||
return dVal;
|
||||
},
|
||||
initData(){
|
||||
let startDate,endDate,startYear,endYear,startMonth,endMonth,startDay,endDay;
|
||||
let years=[],months=[],days=[],hours=[],minutes=[],seconds=[];
|
||||
let dVal=[],pickVal=[];
|
||||
let value=this.value;
|
||||
let reg=/-/g;
|
||||
let range={};
|
||||
let result="",full="",year,month,day,hour,minute,second,obj={};
|
||||
let defaultDate=this.getDefaultDate();
|
||||
let defaultYear=defaultDate.defaultYear;
|
||||
let defaultMonth=defaultDate.defaultMonth;
|
||||
let defaultDay=defaultDate.defaultDay;
|
||||
let defaultDays=defaultDate.defaultDays;
|
||||
let curFlag=this.current;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let curDate=this.getCurrenDate();
|
||||
let curYear=curDate.curYear;
|
||||
let curMonth=curDate.curMonth;
|
||||
let curMonthdays=curDate.curMonthdays;
|
||||
let curDay=curDate.curDay;
|
||||
let curHour=curDate.curHour;
|
||||
let curMinute=curDate.curMinute;
|
||||
let curSecond=curDate.curSecond;
|
||||
let dateData=[];
|
||||
dVal=this.getDval();
|
||||
|
||||
startDate=this.getStartDate();
|
||||
endDate=this.getEndDate();
|
||||
startYear=startDate.getFullYear();
|
||||
startMonth=startDate.getMonth();
|
||||
startDay=startDate.getDate();
|
||||
endYear=endDate.getFullYear();
|
||||
endMonth=endDate.getMonth();
|
||||
endDay=endDate.getDate();
|
||||
dateData=this.getData(dVal);
|
||||
years=dateData.years;
|
||||
months=dateData.months;
|
||||
days=dateData.days;
|
||||
hours=dateData.hours;
|
||||
minutes=dateData.minutes;
|
||||
seconds=dateData.seconds;
|
||||
switch(this.fields){
|
||||
case "year":
|
||||
pickVal=disabledAfter?[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0
|
||||
]:(curFlag?[
|
||||
years.indexOf(curYear+'')
|
||||
]:[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0
|
||||
]);
|
||||
range={years};
|
||||
year=dVal[0]?dVal[0]:years[0];
|
||||
result=full=`${year}`;
|
||||
obj={
|
||||
year
|
||||
}
|
||||
break;
|
||||
case "month":
|
||||
pickVal=disabledAfter?[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0
|
||||
]:(curFlag?[
|
||||
years.indexOf(curYear+''),
|
||||
months.indexOf(this.formatNum(curMonth))
|
||||
]:[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0
|
||||
]);
|
||||
range={years,months};
|
||||
year=dVal[0]?dVal[0]:years[0];
|
||||
month=dVal[1]?dVal[1]:months[0];
|
||||
result=full=`${year+'-'+month}`;
|
||||
obj={
|
||||
year,
|
||||
month
|
||||
}
|
||||
break;
|
||||
case "day":
|
||||
pickVal=disabledAfter?[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0
|
||||
]:(curFlag?[
|
||||
years.indexOf(curYear+''),
|
||||
months.indexOf(this.formatNum(curMonth)),
|
||||
days.indexOf(this.formatNum(curDay)),
|
||||
]:[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0
|
||||
]);
|
||||
range={years,months,days};
|
||||
year=dVal[0]?dVal[0]:years[0];
|
||||
month=dVal[1]?dVal[1]:months[0];
|
||||
day=dVal[2]?dVal[2]:days[0];
|
||||
result=full=`${year+'-'+month+'-'+day}`;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day
|
||||
}
|
||||
break;
|
||||
case "hour":
|
||||
pickVal=disabledAfter?[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0,
|
||||
dVal[3]&&hours.indexOf(dVal[3])!=-1?hours.indexOf(dVal[3]):0
|
||||
]:(curFlag?[
|
||||
years.indexOf(curYear+''),
|
||||
months.indexOf(this.formatNum(curMonth)),
|
||||
days.indexOf(this.formatNum(curDay)),
|
||||
hours.indexOf(this.formatNum(curHour)),
|
||||
]:[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0,
|
||||
dVal[3]&&hours.indexOf(dVal[3])!=-1?hours.indexOf(dVal[3]):0
|
||||
]);
|
||||
range={years,months,days,hours};
|
||||
year=dVal[0]?dVal[0]:years[0];
|
||||
month=dVal[1]?dVal[1]:months[0];
|
||||
day=dVal[2]?dVal[2]:days[0];
|
||||
hour=dVal[3]?dVal[3]:hours[0];
|
||||
result=`${year+'-'+month+'-'+day+' '+hour}`;
|
||||
full=`${year+'-'+month+'-'+day+' '+hour+':00:00'}`;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour
|
||||
}
|
||||
break;
|
||||
case "minute":
|
||||
pickVal=disabledAfter?[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0,
|
||||
dVal[3]&&hours.indexOf(dVal[3])!=-1?hours.indexOf(dVal[3]):0,
|
||||
dVal[4]&&minutes.indexOf(dVal[4])!=-1?minutes.indexOf(dVal[4]):0
|
||||
]:(curFlag?[
|
||||
years.indexOf(curYear+''),
|
||||
months.indexOf(this.formatNum(curMonth)),
|
||||
days.indexOf(this.formatNum(curDay)),
|
||||
hours.indexOf(this.formatNum(curHour)),
|
||||
minutes.indexOf(this.formatNum(curMinute)),
|
||||
]:[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0,
|
||||
dVal[3]&&hours.indexOf(dVal[3])!=-1?hours.indexOf(dVal[3]):0,
|
||||
dVal[4]&&minutes.indexOf(dVal[4])!=-1?minutes.indexOf(dVal[4]):0
|
||||
]);
|
||||
range={years,months,days,hours,minutes};
|
||||
year=dVal[0]?dVal[0]:years[0];
|
||||
month=dVal[1]?dVal[1]:months[0];
|
||||
day=dVal[2]?dVal[2]:days[0];
|
||||
hour=dVal[3]?dVal[3]:hours[0];
|
||||
minute=dVal[4]?dVal[4]:minutes[0];
|
||||
full=`${year+'-'+month+'-'+day+' '+hour+':'+minute+':00'}`;
|
||||
result=`${year+'-'+month+'-'+day+' '+hour+':'+minute}`;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute
|
||||
}
|
||||
break;
|
||||
case "second":
|
||||
pickVal=disabledAfter?[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0,
|
||||
dVal[3]&&hours.indexOf(dVal[3])!=-1?hours.indexOf(dVal[3]):0,
|
||||
dVal[4]&&minutes.indexOf(dVal[4])!=-1?minutes.indexOf(dVal[4]):0,
|
||||
dVal[5]&&seconds.indexOf(dVal[5])!=-1?seconds.indexOf(dVal[5]):0
|
||||
]:(curFlag?[
|
||||
years.indexOf(curYear+''),
|
||||
months.indexOf(this.formatNum(curMonth)),
|
||||
days.indexOf(this.formatNum(curDay)),
|
||||
hours.indexOf(this.formatNum(curHour)),
|
||||
minutes.indexOf(this.formatNum(curMinute)),
|
||||
seconds.indexOf(this.formatNum(curSecond)),
|
||||
]:[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0,
|
||||
dVal[3]&&hours.indexOf(dVal[3])!=-1?hours.indexOf(dVal[3]):0,
|
||||
dVal[4]&&minutes.indexOf(dVal[4])!=-1?minutes.indexOf(dVal[4]):0,
|
||||
dVal[5]&&seconds.indexOf(dVal[5])!=-1?seconds.indexOf(dVal[5]):0
|
||||
]);
|
||||
range={years,months,days,hours,minutes,seconds};
|
||||
year=dVal[0]?dVal[0]:years[0];
|
||||
month=dVal[1]?dVal[1]:months[0];
|
||||
day=dVal[2]?dVal[2]:days[0];
|
||||
hour=dVal[3]?dVal[3]:hours[0];
|
||||
minute=dVal[4]?dVal[4]:minutes[0];
|
||||
second=dVal[5]?dVal[5]:seconds[0];
|
||||
result=full=`${year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second}`;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
second
|
||||
}
|
||||
break;
|
||||
default:
|
||||
range={years,months,days};
|
||||
break;
|
||||
}
|
||||
this.range=range;
|
||||
this.checkObj=obj;
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:full,
|
||||
obj:obj
|
||||
});
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=pickVal;
|
||||
})
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let data=this.range;
|
||||
let year="",month="",day="",hour="",minute="",second="";
|
||||
let result="",full="",obj={};
|
||||
let months=null,days=null,hours=null,minutes=null,seconds=null;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let leapYear=false,resetData={};
|
||||
year=(arr[0]||arr[0]==0)?data.years[arr[0]]||data.years[data.years.length-1]:"";
|
||||
month=(arr[1]||arr[1]==0)?data.months[arr[1]]||data.months[data.months.length-1]:"";
|
||||
day=(arr[2]||arr[2]==0)?data.days[arr[2]]||data.days[data.days.length-1]:"";
|
||||
hour=(arr[3]||arr[3]==0)?data.hours[arr[3]]||data.hours[data.hours.length-1]:"";
|
||||
minute=(arr[4]||arr[4]==0)?data.minutes[arr[4]]||data.minutes[data.minutes.length-1]:"";
|
||||
second=(arr[5]||arr[5]==0)?data.seconds[arr[5]]||data.seconds[data.seconds.length-1]:"";
|
||||
resetData=this.resetData(year,month,day,hour,minute);//重新拉取当前日期数据;
|
||||
leapYear=this.isLeapYear(year);//判断是否为闰年;
|
||||
switch(this.fields){
|
||||
case "year":
|
||||
result=full=`${year}`;
|
||||
obj={
|
||||
year
|
||||
};
|
||||
break;
|
||||
case "month":
|
||||
result=full=`${year+'-'+month}`;
|
||||
if(this.disabledAfter)months=resetData.months;
|
||||
if(months)this.range.months=months;
|
||||
obj={
|
||||
year,
|
||||
month
|
||||
}
|
||||
break;
|
||||
case "day":
|
||||
result=full=`${year+'-'+month+'-'+day}`;
|
||||
if(this.disabledAfter){
|
||||
months=resetData.months;
|
||||
days=resetData.days;
|
||||
}else{
|
||||
if(leapYear||(month!=this.checkObj.month)||month==2){
|
||||
days=resetData.days;
|
||||
}
|
||||
}
|
||||
if(months)this.range.months=months;
|
||||
if(days)this.range.days=days;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day
|
||||
}
|
||||
break;
|
||||
case "hour":
|
||||
result=`${year+'-'+month+'-'+day+' '+hour}`;
|
||||
full=`${year+'-'+month+'-'+day+' '+hour+':00:00'}`;
|
||||
if(this.disabledAfter){
|
||||
months=resetData.months;
|
||||
days=resetData.days;
|
||||
hours=resetData.hours;
|
||||
}else{
|
||||
if(leapYear||(month!=this.checkObj.month)||month==2){
|
||||
days=resetData.days;
|
||||
}
|
||||
}
|
||||
if(months)this.range.months=months;
|
||||
if(days)this.range.days=days;
|
||||
if(hours)this.range.hours=hours;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour
|
||||
}
|
||||
break;
|
||||
case "minute":
|
||||
full=`${year+'-'+month+'-'+day+' '+hour+':'+minute+':00'}`;
|
||||
result=`${year+'-'+month+'-'+day+' '+hour+':'+minute}`;
|
||||
if(this.disabledAfter){
|
||||
months=resetData.months;
|
||||
days=resetData.days;
|
||||
hours=resetData.hours;
|
||||
minutes=resetData.minutes;
|
||||
}else{
|
||||
if(leapYear||(month!=this.checkObj.month)||month==2){
|
||||
days=resetData.days;
|
||||
}
|
||||
}
|
||||
if(months)this.range.months=months;
|
||||
if(days)this.range.days=days;
|
||||
if(hours)this.range.hours=hours;
|
||||
if(minutes)this.range.minutes=minutes;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute
|
||||
};
|
||||
break;
|
||||
case "second":
|
||||
result=full=`${year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second}`;
|
||||
if(this.disabledAfter){
|
||||
months=resetData.months;
|
||||
days=resetData.days;
|
||||
hours=resetData.hours;
|
||||
minutes=resetData.minutes;
|
||||
//seconds=resetData.seconds;
|
||||
}else{
|
||||
if(leapYear||(month!=this.checkObj.month)||month==2){
|
||||
days=resetData.days;
|
||||
}
|
||||
}
|
||||
if(months)this.range.months=months;
|
||||
if(days)this.range.days=days;
|
||||
if(hours)this.range.hours=hours;
|
||||
if(minutes)this.range.minutes=minutes;
|
||||
//if(seconds)this.range.seconds=seconds;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
second
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.checkObj=obj;
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:full,
|
||||
obj:obj
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
@ -1,345 +0,0 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.years" :key="index">{{item}}年</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.months" :key="index">{{item}}月</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.days" :key="index">{{item}}日</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.sections" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickVal:[],
|
||||
range:{},
|
||||
checkObj:{}
|
||||
};
|
||||
},
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
startYear:{
|
||||
type:String,
|
||||
default:""
|
||||
},
|
||||
endYear:{
|
||||
type:String,
|
||||
default:""
|
||||
},
|
||||
value:{
|
||||
type:[String,Array,Number],
|
||||
default:""
|
||||
},
|
||||
current:{//是否默认选中当前日期
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
disabledAfter:{//是否禁用当前之后的日期
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods:{
|
||||
formatNum(n){
|
||||
return (Number(n)<10?'0'+Number(n):Number(n)+'');
|
||||
},
|
||||
checkValue(value){
|
||||
let strReg=/^\d{4}-\d{2}-\d{2} [\u4e00-\u9fa5]{2}$/,example;
|
||||
if(!strReg.test(value)){
|
||||
console.log(new Error("请传入与mode、fields匹配的value值,例value="+example+""))
|
||||
}
|
||||
return strReg.test(value);
|
||||
},
|
||||
resetData(year,month,day){
|
||||
let curDate=this.getCurrenDate();
|
||||
let curFlag=this.current;
|
||||
let curYear=curDate.curYear;
|
||||
let curMonth=curDate.curMonth;
|
||||
let curDay=curDate.curDay;
|
||||
let curHour=curDate.curHour;
|
||||
let months=[],days=[],sections=[];
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let monthsLen=disabledAfter?(year*1<curYear?12:curMonth):12;
|
||||
let totalDays=new Date(year,month,0).getDate();//计算当月有几天;
|
||||
let daysLen=disabledAfter?((year*1<curYear||month*1<curMonth)?totalDays:curDay):totalDays;
|
||||
let sectionFlag=disabledAfter?((year*1<curYear||month*1<curMonth||day*1<curDay)==true?false:true):(curHour>12==true?true:false);
|
||||
sections=["上午","下午"];
|
||||
for(let month=1;month<=monthsLen;month++){
|
||||
months.push(this.formatNum(month));
|
||||
};
|
||||
for(let day=1;day<=daysLen;day++){
|
||||
days.push(this.formatNum(day));
|
||||
}
|
||||
if(sectionFlag){
|
||||
sections=["上午"];
|
||||
}
|
||||
return{
|
||||
months,
|
||||
days,
|
||||
sections
|
||||
}
|
||||
},
|
||||
getData(dVal){
|
||||
//用来处理初始化数据
|
||||
let curFlag=this.current;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let curDate=this.getCurrenDate();
|
||||
let curYear=curDate.curYear;
|
||||
let curMonthdays=curDate.curMonthdays;
|
||||
let curMonth=curDate.curMonth;
|
||||
let curDay=curDate.curDay;
|
||||
let curHour=curDate.curHour;
|
||||
let defaultDate=this.getDefaultDate();
|
||||
let startYear=this.getStartDate().getFullYear();
|
||||
let endYear=this.getEndDate().getFullYear();
|
||||
let years=[],months=[],days=[],sections=[];
|
||||
let year=dVal[0]*1;
|
||||
let month=dVal[1]*1;
|
||||
let day=dVal[2]*1;
|
||||
let monthsLen=disabledAfter?(year<curYear?12:curDate.curMonth):12;
|
||||
let daysLen=disabledAfter?((year<curYear||month<curMonth)?defaultDate.defaultDays:curDay):(curFlag?curMonthdays:defaultDate.defaultDays);
|
||||
let sectionFlag=disabledAfter?((year*1<curYear||month*1<curMonth||day*1<curDay)==true?false:true):(curHour>12==true?true:false);
|
||||
for(let year=startYear;year<=(disabledAfter?curYear:endYear);year++){
|
||||
years.push(year.toString())
|
||||
}
|
||||
for(let month=1;month<=monthsLen;month++){
|
||||
months.push(this.formatNum(month));
|
||||
}
|
||||
for(let day=1;day<=daysLen;day++){
|
||||
days.push(this.formatNum(day));
|
||||
}
|
||||
if(sectionFlag){
|
||||
sections=["下午"];
|
||||
}else{
|
||||
sections=["上午","下午"];
|
||||
}
|
||||
return {
|
||||
years,
|
||||
months,
|
||||
days,
|
||||
sections
|
||||
}
|
||||
},
|
||||
getCurrenDate(){
|
||||
let curDate=new Date();
|
||||
let curYear=curDate.getFullYear();
|
||||
let curMonth=curDate.getMonth()+1;
|
||||
let curMonthdays=new Date(curYear,curMonth,0).getDate();
|
||||
let curDay=curDate.getDate();
|
||||
let curHour=curDate.getHours();
|
||||
let curSection="上午";
|
||||
if(curHour>=12){
|
||||
curSection="下午";
|
||||
}
|
||||
return{
|
||||
curDate,
|
||||
curYear,
|
||||
curMonth,
|
||||
curMonthdays,
|
||||
curDay,
|
||||
curHour,
|
||||
curSection
|
||||
}
|
||||
},
|
||||
getDefaultDate(){
|
||||
let value=this.value;
|
||||
let reg=/-/g;
|
||||
let defaultDate=value?new Date(value.split(" ")[0].replace(reg,"/")):new Date();
|
||||
let defaultYear=defaultDate.getFullYear();
|
||||
let defaultMonth=defaultDate.getMonth()+1;
|
||||
let defaultDay=defaultDate.getDate();
|
||||
let defaultDays=new Date(defaultYear,defaultMonth,0).getDate()*1;
|
||||
return{
|
||||
defaultDate,
|
||||
defaultYear,
|
||||
defaultMonth,
|
||||
defaultDay,
|
||||
defaultDays
|
||||
}
|
||||
},
|
||||
getStartDate(){
|
||||
let start=this.startYear;
|
||||
let startDate="";
|
||||
let reg=/-/g;
|
||||
if(start){
|
||||
startDate=new Date(start+"/01/01");
|
||||
}else{
|
||||
startDate=new Date("1970/01/01");
|
||||
}
|
||||
return startDate;
|
||||
},
|
||||
getEndDate(){
|
||||
let end=this.endYear;
|
||||
let reg=/-/g;
|
||||
let endDate="";
|
||||
if(end){
|
||||
endDate=new Date(end+"/12/31");
|
||||
}else{
|
||||
endDate=new Date();
|
||||
}
|
||||
return endDate;
|
||||
},
|
||||
getDval(){
|
||||
let value=this.value;
|
||||
let dVal=null;
|
||||
let aDate=new Date();
|
||||
let year=this.formatNum(aDate.getFullYear());
|
||||
let month=this.formatNum(aDate.getMonth()+1);
|
||||
let day=this.formatNum(aDate.getDate());
|
||||
let hour=aDate.getHours();
|
||||
let section="上午";
|
||||
if(hour>=12)section="下午";
|
||||
if(value){
|
||||
let flag=this.checkValue(value);
|
||||
if(!flag){
|
||||
dVal=[year,month,day,section]
|
||||
}else{
|
||||
let v=value.split(" ");
|
||||
dVal=[...v[0].split("-"),v[1]];
|
||||
}
|
||||
}else{
|
||||
dVal=[year,month,day,section]
|
||||
}
|
||||
return dVal;
|
||||
},
|
||||
initData(){
|
||||
let startDate,endDate,startYear,endYear,startMonth,endMonth,startDay,endDay;
|
||||
let years=[],months=[],days=[],sections=[];
|
||||
let dVal=[],pickVal=[];
|
||||
let value=this.value;
|
||||
let reg=/-/g;
|
||||
let range={};
|
||||
let result="",full="",year,month,day,section,obj={};
|
||||
let defaultDate=this.getDefaultDate();
|
||||
let defaultYear=defaultDate.defaultYear;
|
||||
let defaultMonth=defaultDate.defaultMonth;
|
||||
let defaultDay=defaultDate.defaultDay;
|
||||
let defaultDays=defaultDate.defaultDays;
|
||||
let curFlag=this.current;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let curDate=this.getCurrenDate();
|
||||
let curYear=curDate.curYear;
|
||||
let curMonth=curDate.curMonth;
|
||||
let curMonthdays=curDate.curMonthdays;
|
||||
let curDay=curDate.curDay;
|
||||
let curSection=curDate.curSection;
|
||||
let dateData=[];
|
||||
dVal=this.getDval();
|
||||
startDate=this.getStartDate();
|
||||
endDate=this.getEndDate();
|
||||
startYear=startDate.getFullYear();
|
||||
startMonth=startDate.getMonth();
|
||||
startDay=startDate.getDate();
|
||||
endYear=endDate.getFullYear();
|
||||
endMonth=endDate.getMonth();
|
||||
endDay=endDate.getDate();
|
||||
dateData=this.getData(dVal);
|
||||
years=dateData.years;
|
||||
months=dateData.months;
|
||||
days=dateData.days;
|
||||
sections=dateData.sections;
|
||||
pickVal=disabledAfter?[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0,
|
||||
dVal[3]&§ions.indexOf(dVal[3])!=-1?sections.indexOf(dVal[3]):0
|
||||
]:(curFlag?[
|
||||
years.indexOf(curYear+''),
|
||||
months.indexOf(this.formatNum(curMonth)),
|
||||
days.indexOf(this.formatNum(curDay)),
|
||||
sections.indexOf(curSection),
|
||||
]:[
|
||||
dVal[0]&&years.indexOf(dVal[0])!=-1?years.indexOf(dVal[0]):0,
|
||||
dVal[1]&&months.indexOf(dVal[1])!=-1?months.indexOf(dVal[1]):0,
|
||||
dVal[2]&&days.indexOf(dVal[2])!=-1?days.indexOf(dVal[2]):0,
|
||||
dVal[3]&§ions.indexOf(dVal[3])!=-1?sections.indexOf(dVal[3]):0
|
||||
]);
|
||||
range={years,months,days,sections};
|
||||
year=dVal[0]?dVal[0]:years[0];
|
||||
month=dVal[1]?dVal[1]:months[0];
|
||||
day=dVal[2]?dVal[2]:days[0];
|
||||
section=dVal[3]?dVal[3]:sections[0];
|
||||
result=full=`${year+'-'+month+'-'+day+' '+section}`;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
section
|
||||
}
|
||||
this.range=range;
|
||||
this.checkObj=obj;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=pickVal;
|
||||
});
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:full,
|
||||
obj:obj
|
||||
})
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let data=this.range;
|
||||
let year="",month="",day="",section="";
|
||||
let result="",full="",obj={};
|
||||
let months=null,days=null,sections=null;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
year=(arr[0]||arr[0]==0)?data.years[arr[0]]||data.years[data.years.length-1]:"";
|
||||
month=(arr[1]||arr[1]==0)?data.months[arr[1]]||data.months[data.months.length-1]:"";
|
||||
day=(arr[2]||arr[2]==0)?data.days[arr[2]]||data.days[data.days.length-1]:"";
|
||||
section=(arr[3]||arr[3]==0)?data.sections[arr[3]]||data.sections[data.sections.length-1]:"";
|
||||
result=full=`${year+'-'+month+'-'+day+' '+section}`;
|
||||
let resetData=this.resetData(year,month,day);
|
||||
if(this.disabledAfter){
|
||||
months=resetData.months;
|
||||
days=resetData.days;
|
||||
sections=resetData.sections;
|
||||
}else{
|
||||
if(year%4==0||(month!=this.checkObj.month)){
|
||||
days=resetData.days;
|
||||
}
|
||||
}
|
||||
if(months)this.range.months=months;
|
||||
if(days)this.range.days=days;
|
||||
if(sections)this.range.sections=sections;
|
||||
obj={
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
section
|
||||
}
|
||||
this.checkObj=obj;
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:full,
|
||||
obj:obj
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
@ -1,274 +0,0 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column v-for="(group,gIndex) in range" :key="gIndex">
|
||||
<view class="w-picker-item" v-for="(item,index) in group" :key="index">{{item[nodeKey]}}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickVal:[],
|
||||
range:[],
|
||||
checkObj:{}
|
||||
};
|
||||
},
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
value:{
|
||||
type:[Array,String],
|
||||
default:""
|
||||
},
|
||||
defaultType:{
|
||||
type:String,
|
||||
default:"label"
|
||||
},
|
||||
options:{
|
||||
type:Array,
|
||||
default(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
defaultProps:{
|
||||
type:Object,
|
||||
default(){
|
||||
return{
|
||||
lable:"label",
|
||||
value:"value",
|
||||
children:"children"
|
||||
}
|
||||
}
|
||||
},
|
||||
level:{
|
||||
//多级联动层级,表示几级联动
|
||||
type:[Number,String],
|
||||
default:2
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
nodeKey(){
|
||||
return this.defaultProps.label;
|
||||
},
|
||||
nodeVal(){
|
||||
return this.defaultProps.value;
|
||||
},
|
||||
nodeChild(){
|
||||
return this.defaultProps.children;
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
if(this.options.length!=0){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
options(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if(this.options.length!=0){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getData(){
|
||||
//用来处理初始化数据
|
||||
let options=this.options;
|
||||
let col1={},col2={},col3={},col4={};
|
||||
let arr1=options,arr2=[],arr3=[],arr4=[];
|
||||
let col1Index=0,col2Index=0,col3Index=0,col4Index=0;
|
||||
let a1="",a2="",a3="",a4="";
|
||||
let dVal=[],obj={};
|
||||
let value=this.value;
|
||||
let data=[];
|
||||
a1=value[0];
|
||||
a2=value[1];
|
||||
if(this.level>2){
|
||||
a3=value[2];
|
||||
}
|
||||
if(this.level>3){
|
||||
a4=value[3];
|
||||
};
|
||||
/*第1列*/
|
||||
col1Index=arr1.findIndex((v)=>{
|
||||
return v[this.defaultType]==a1
|
||||
});
|
||||
col1Index=value?(col1Index!=-1?col1Index:0):0;
|
||||
col1=arr1[col1Index];
|
||||
|
||||
/*第2列*/
|
||||
arr2=arr1[col1Index][this.nodeChild];
|
||||
col2Index=arr2.findIndex((v)=>{
|
||||
return v[this.defaultType]==a2
|
||||
});
|
||||
col2Index=value?(col2Index!=-1?col2Index:0):0;
|
||||
col2=arr2[col2Index];
|
||||
|
||||
/*第3列*/
|
||||
if(this.level>2){
|
||||
arr3=arr2[col2Index][this.nodeChild];
|
||||
col3Index=arr3.findIndex((v)=>{
|
||||
return v[this.defaultType]==a3;
|
||||
});
|
||||
col3Index=value?(col3Index!=-1?col3Index:0):0;
|
||||
col3=arr3[col3Index];
|
||||
};
|
||||
|
||||
|
||||
/*第4列*/
|
||||
if(this.level>3){
|
||||
arr4=arr3[col4Index][this.nodeChild];
|
||||
col4Index=arr4.findIndex((v)=>{
|
||||
return v[this.defaultType]==a4;
|
||||
});
|
||||
col4Index=value?(col4Index!=-1?col4Index:0):0;
|
||||
col4=arr4[col4Index];
|
||||
};
|
||||
switch(this.level*1){
|
||||
case 2:
|
||||
dVal=[col1Index,col2Index];
|
||||
obj={
|
||||
col1,
|
||||
col2
|
||||
}
|
||||
data=[arr1,arr2];
|
||||
break;
|
||||
case 3:
|
||||
dVal=[col1Index,col2Index,col3Index];
|
||||
obj={
|
||||
col1,
|
||||
col2,
|
||||
col3
|
||||
}
|
||||
data=[arr1,arr2,arr3];
|
||||
break;
|
||||
case 4:
|
||||
dVal=[col1Index,col2Index,col3Index,col4Index];
|
||||
obj={
|
||||
col1,
|
||||
col2,
|
||||
col3,
|
||||
col4
|
||||
}
|
||||
data=[arr1,arr2,arr3,arr4];
|
||||
break
|
||||
}
|
||||
return {
|
||||
data,
|
||||
dVal,
|
||||
obj
|
||||
}
|
||||
},
|
||||
initData(){
|
||||
let dataData=this.getData();
|
||||
let data=dataData.data;
|
||||
let arr1=data[0];
|
||||
let arr2=data[1];
|
||||
let arr3=data[2]||[];
|
||||
let arr4=data[3]||[];
|
||||
let obj=dataData.obj;
|
||||
let col1=obj.col1,col2=obj.col2,col3=obj.col3||{},col4=obj.col4||{};
|
||||
let result="",value=[];
|
||||
let range=[];
|
||||
switch(this.level){
|
||||
case 2:
|
||||
value=[col1[this.nodeVal],col2[this.nodeVal]];
|
||||
result=`${col1[this.nodeKey]+col2[this.nodeKey]}`;
|
||||
range=[arr1,arr2];
|
||||
break;
|
||||
case 3:
|
||||
value=[col1[this.nodeVal],col2[this.nodeVal],col3[this.nodeVal]];
|
||||
result=`${col1[this.nodeKey]+col2[this.nodeKey]+col3[this.nodeKey]}`;
|
||||
range=[arr1,arr2,arr3];
|
||||
break;
|
||||
case 4:
|
||||
value=[col1[this.nodeVal],col2[this.nodeVal],col3[this.nodeVal],col4[this.nodeVal]];
|
||||
result=`${col1[this.nodeKey]+col2[this.nodeKey]+col3[this.nodeKey]+col4[this.nodeKey]}`;
|
||||
range=[arr1,arr2,arr3,arr4];
|
||||
break;
|
||||
}
|
||||
this.range=range;
|
||||
this.checkObj=obj;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=dataData.dVal;
|
||||
});
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:value,
|
||||
obj:obj
|
||||
})
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let col1Index=arr[0],col2Index=arr[1],col3Index=arr[2]||0,col4Index=arr[3]||0;
|
||||
let arr1=[],arr2=[],arr3=[],arr4=[];
|
||||
let col1,col2,col3,col4,obj={};
|
||||
let result="",value=[];
|
||||
arr1=this.options;
|
||||
arr2=(arr1[col1Index]&&arr1[col1Index][this.nodeChild])||arr1[arr1.length-1][this.nodeChild]||[];
|
||||
col1=arr1[col1Index]||arr1[arr1.length-1]||{};
|
||||
col2=arr2[col2Index]||arr2[arr2.length-1]||{};
|
||||
if(this.level>2){
|
||||
arr3=(arr2[col2Index]&&arr2[col2Index][this.nodeChild])||arr2[arr2.length-1][this.nodeChild];
|
||||
col3=arr3[col3Index]||arr3[arr3.length-1]||{};
|
||||
}
|
||||
if(this.level>3){
|
||||
arr4=(arr3[col3Index]&&arr3[col3Index][this.nodeChild])||arr3[arr3.length-1][this.nodeChild]||[];
|
||||
col4=arr4[col4Index]||arr4[arr4.length-1]||{};
|
||||
}
|
||||
switch(this.level){
|
||||
case 2:
|
||||
obj={
|
||||
col1,
|
||||
col2
|
||||
}
|
||||
this.range=[arr1,arr2];
|
||||
result=`${(col1[this.nodeKey]||'')+(col2[this.nodeKey]||'')}`;
|
||||
value=[col1[this.nodeVal]||'',col2[this.nodeVal]||''];
|
||||
break;
|
||||
case 3:
|
||||
obj={
|
||||
col1,
|
||||
col2,
|
||||
col3
|
||||
}
|
||||
this.range=[arr1,arr2,arr3];
|
||||
result=`${(col1[this.nodeKey]||'')+(col2[this.nodeKey]||'')+(col3[this.nodeKey]||'')}`;
|
||||
value=[col1[this.nodeVal]||'',col2[this.nodeVal]||'',col3[this.nodeVal]||''];
|
||||
break;
|
||||
case 4:
|
||||
obj={
|
||||
col1,
|
||||
col2,
|
||||
col3,
|
||||
col4
|
||||
}
|
||||
this.range=[arr1,arr2,arr3,arr4];
|
||||
result=`${(col1[this.nodeKey]||'')+(col2[this.nodeKey]||'')+(col3[this.nodeKey]||'')+(col4[this.nodeKey]||'')}`;
|
||||
value=[col1[this.nodeVal]||'',col2[this.nodeVal]||'',col3[this.nodeVal]||'',col4[this.nodeVal]||''];
|
||||
break;
|
||||
}
|
||||
this.checkObj=obj;
|
||||
this.pickVal=arr;
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:value,
|
||||
obj:obj
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
||||
|
@ -1,344 +0,0 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column class="w-picker-flex2">
|
||||
<view class="w-picker-item" v-for="(item,index) in range.fyears" :key="index">{{item}}年</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column class="w-picker-flex2">
|
||||
<view class="w-picker-item" v-for="(item,index) in range.fmonths" :key="index">{{item}}月</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column class="w-picker-flex2">
|
||||
<view class="w-picker-item" v-for="(item,index) in range.fdays" :key="index">{{item}}日</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column class="w-picker-flex1">
|
||||
<view class="w-picker-item">-</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column class="w-picker-flex2">
|
||||
<view class="w-picker-item" v-for="(item,index) in range.tyears" :key="index">{{item}}年</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column class="w-picker-flex2">
|
||||
<view class="w-picker-item" v-for="(item,index) in range.tmonths" :key="index">{{item}}月</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column class="w-picker-flex2">
|
||||
<view class="w-picker-item" v-for="(item,index) in range.tdays" :key="index">{{item}}日</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickVal:[],
|
||||
range:{},
|
||||
checkObj:{}
|
||||
};
|
||||
},
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
value:{
|
||||
type:[String,Array],
|
||||
default(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
current:{//是否默认选中当前日期
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
startYear:{
|
||||
type:[String,Number],
|
||||
default:1970
|
||||
},
|
||||
endYear:{
|
||||
type:[String,Number],
|
||||
default:new Date().getFullYear()
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods:{
|
||||
formatNum(n){
|
||||
return (Number(n)<10?'0'+Number(n):Number(n)+'');
|
||||
},
|
||||
checkValue(value){
|
||||
let strReg=/^\d{4}-\d{2}-\d{2}$/,example="2020-04-03";
|
||||
if(!strReg.test(value[0])||!strReg.test(value[1])){
|
||||
console.log(new Error("请传入与mode匹配的value值,例["+example+","+example+"]"))
|
||||
}
|
||||
return strReg.test(value[0])&&strReg.test(value[1]);
|
||||
},
|
||||
resetToData(fmonth,fday,tyear,tmonth){
|
||||
let range=this.range;
|
||||
let tmonths=[],tdays=[];
|
||||
let yearFlag=tyear!=range.tyears[0];
|
||||
let monthFlag=tyear!=range.tyears[0]||tmonth!=range.tmonths[0];
|
||||
let ttotal=new Date(tyear,tmonth,0).getDate();
|
||||
for(let i=yearFlag?1:fmonth*1;i<=12;i++){
|
||||
tmonths.push(this.formatNum(i))
|
||||
}
|
||||
for(let i=monthFlag?1:fday*1;i<=ttotal;i++){
|
||||
tdays.push(this.formatNum(i))
|
||||
}
|
||||
return{
|
||||
tmonths,
|
||||
tdays
|
||||
}
|
||||
},
|
||||
resetData(fyear,fmonth,fday,tyear,tmonth){
|
||||
let fyears=[],fmonths=[],fdays=[],tyears=[],tmonths=[],tdays=[];
|
||||
let startYear=this.startYear;
|
||||
let endYear=this.endYear;
|
||||
let ftotal=new Date(fyear,fmonth,0).getDate();
|
||||
let ttotal=new Date(tyear,tmonth,0).getDate();
|
||||
for(let i=startYear*1;i<=endYear;i++){
|
||||
fyears.push(this.formatNum(i))
|
||||
}
|
||||
for(let i=1;i<=12;i++){
|
||||
fmonths.push(this.formatNum(i))
|
||||
}
|
||||
for(let i=1;i<=ftotal;i++){
|
||||
fdays.push(this.formatNum(i))
|
||||
}
|
||||
for(let i=fyear*1;i<=endYear;i++){
|
||||
tyears.push(this.formatNum(i))
|
||||
}
|
||||
for(let i=fmonth*1;i<=12;i++){
|
||||
tmonths.push(this.formatNum(i))
|
||||
}
|
||||
for(let i=fday*1;i<=ttotal;i++){
|
||||
tdays.push(this.formatNum(i))
|
||||
}
|
||||
return {
|
||||
fyears,
|
||||
fmonths,
|
||||
fdays,
|
||||
tyears,
|
||||
tmonths,
|
||||
tdays
|
||||
}
|
||||
},
|
||||
getData(dVal){
|
||||
let start=this.startYear*1;
|
||||
let end=this.endYear*1;
|
||||
let value=dVal;
|
||||
let flag=this.current;
|
||||
let aToday=new Date();
|
||||
let tYear,tMonth,tDay,tHours,tMinutes,tSeconds,pickVal=[];
|
||||
let initstartDate=new Date(start.toString());
|
||||
let endDate=new Date(end.toString());
|
||||
if(start>end){
|
||||
initstartDate=new Date(end.toString());
|
||||
endDate=new Date(start.toString());
|
||||
};
|
||||
let startYear=initstartDate.getFullYear();
|
||||
let startMonth=initstartDate.getMonth()+1;
|
||||
let endYear=endDate.getFullYear();
|
||||
let fyears=[],fmonths=[],fdays=[],tyears=[],tmonths=[],tdays=[],returnArr=[],startDVal=[],endDVal=[];
|
||||
let curMonth=flag?value[1]*1:(startDVal[1]*1+1);
|
||||
let curMonth1=flag?value[5][1]*1:(value[5]*1+1);
|
||||
let totalDays=new Date(value[0],value[1],0).getDate();
|
||||
let totalDays1=new Date(value[4],value[5],0).getDate();
|
||||
for(let s=startYear;s<=endYear;s++){
|
||||
fyears.push(this.formatNum(s));
|
||||
};
|
||||
for(let m=1;m<=12;m++){
|
||||
fmonths.push(this.formatNum(m));
|
||||
};
|
||||
for(let d=1;d<=totalDays;d++){
|
||||
fdays.push(this.formatNum(d));
|
||||
};
|
||||
for(let s=value[0]*1;s<=endYear;s++){
|
||||
tyears.push(this.formatNum(s));
|
||||
};
|
||||
|
||||
if(value[4]*1>value[0]*1){
|
||||
for(let m=1;m<=12;m++){
|
||||
tmonths.push(this.formatNum(m));
|
||||
};
|
||||
for(let d=1;d<=totalDays1;d++){
|
||||
tdays.push(this.formatNum(d));
|
||||
};
|
||||
}else{
|
||||
for(let m=value[1]*1;m<=12;m++){
|
||||
tmonths.push(this.formatNum(m));
|
||||
};
|
||||
for(let d=value[2]*1;d<=totalDays1;d++){
|
||||
tdays.push(this.formatNum(d));
|
||||
};
|
||||
};
|
||||
|
||||
pickVal=[
|
||||
fyears.indexOf(value[0])==-1?0:fyears.indexOf(value[0]),
|
||||
fmonths.indexOf(value[1])==-1?0:fmonths.indexOf(value[1]),
|
||||
fdays.indexOf(value[2])==-1?0:fdays.indexOf(value[2]),
|
||||
0,
|
||||
tyears.indexOf(value[4])==-1?0:tyears.indexOf(value[4]),
|
||||
tmonths.indexOf(value[5])==-1?0:tmonths.indexOf(value[5]),
|
||||
tdays.indexOf(value[6])==-1?0:tdays.indexOf(value[6])
|
||||
];
|
||||
return {
|
||||
fyears,
|
||||
fmonths,
|
||||
fdays,
|
||||
tyears,
|
||||
tmonths,
|
||||
tdays,
|
||||
pickVal
|
||||
}
|
||||
},
|
||||
getDval(){
|
||||
let value=this.value;
|
||||
let fields=this.fields;
|
||||
let dVal=null;
|
||||
let aDate=new Date();
|
||||
let fyear=this.formatNum(aDate.getFullYear());
|
||||
let fmonth=this.formatNum(aDate.getMonth()+1);
|
||||
let fday=this.formatNum(aDate.getDate());
|
||||
let tyear=this.formatNum(aDate.getFullYear());
|
||||
let tmonth=this.formatNum(aDate.getMonth()+1);
|
||||
let tday=this.formatNum(aDate.getDate());
|
||||
if(value&&value.length>0){
|
||||
let flag=this.checkValue(value);
|
||||
if(!flag){
|
||||
dVal=[fyear,fmonth,fday,"-",tyear,tmonth,tday]
|
||||
}else{
|
||||
dVal=[...value[0].split("-"),"-",...value[1].split("-")];
|
||||
}
|
||||
}else{
|
||||
dVal=[fyear,fmonth,fday,"-",tyear,tmonth,tday]
|
||||
}
|
||||
return dVal;
|
||||
},
|
||||
initData(){
|
||||
let range=[],pickVal=[];
|
||||
let result="",full="",obj={};
|
||||
let dVal=this.getDval();
|
||||
let dateData=this.getData(dVal);
|
||||
let fyears=[],fmonths=[],fdays=[],tyears=[],tmonths=[],tdays=[];
|
||||
let fyear,fmonth,fday,tyear,tmonth,tday;
|
||||
pickVal=dateData.pickVal;
|
||||
fyears=dateData.fyears;
|
||||
fmonths=dateData.fmonths;
|
||||
fdays=dateData.fdays;
|
||||
tyears=dateData.tyears;
|
||||
tmonths=dateData.tmonths;
|
||||
tdays=dateData.tdays;
|
||||
range={
|
||||
fyears,
|
||||
fmonths,
|
||||
fdays,
|
||||
tyears,
|
||||
tmonths,
|
||||
tdays,
|
||||
}
|
||||
fyear=range.fyears[pickVal[0]];
|
||||
fmonth=range.fmonths[pickVal[1]];
|
||||
fday=range.fdays[pickVal[2]];
|
||||
tyear=range.tyears[pickVal[4]];
|
||||
tmonth=range.tmonths[pickVal[5]];
|
||||
tday=range.tdays[pickVal[6]];
|
||||
obj={
|
||||
fyear,
|
||||
fmonth,
|
||||
fday,
|
||||
tyear,
|
||||
tmonth,
|
||||
tday
|
||||
}
|
||||
result=`${fyear+'-'+fmonth+'-'+fday+'至'+tyear+'-'+tmonth+'-'+tday}`;
|
||||
this.range=range;
|
||||
this.checkObj=obj;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=pickVal;
|
||||
});
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:result.split("至"),
|
||||
obj:obj
|
||||
})
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let result="",full="",obj={};
|
||||
let year="",month="",day="",hour="",minute="",second="",note=[],province,city,area;
|
||||
let checkObj=this.checkObj;
|
||||
let days=[],months=[],endYears=[],endMonths=[],endDays=[],startDays=[];
|
||||
let mode=this.mode;
|
||||
let col1,col2,col3,d,a,h,m;
|
||||
let xDate=new Date().getTime();
|
||||
let range=this.range;
|
||||
let fyear=range.fyears[arr[0]]||range.fyears[range.fyears.length-1];
|
||||
let fmonth=range.fmonths[arr[1]]||range.fmonths[range.fmonths.length-1];
|
||||
let fday=range.fdays[arr[2]]||range.fdays[range.fdays.length-1];
|
||||
let tyear=range.tyears[arr[4]]||range.tyears[range.tyears.length-1];
|
||||
let tmonth=range.tmonths[arr[5]]||range.tmonths[range.tmonths.length-1];
|
||||
let tday=range.tdays[arr[6]]||range.tdays[range.tdays.length-1];
|
||||
let resetData=this.resetData(fyear,fmonth,fday,tyear,tmonth);
|
||||
if(fyear!=checkObj.fyear||fmonth!=checkObj.fmonth||fday!=checkObj.fday){
|
||||
arr[4]=0;
|
||||
arr[5]=0;
|
||||
arr[6]=0;
|
||||
range.tyears=resetData.tyears;
|
||||
range.tmonths=resetData.tmonths;
|
||||
range.tdays=resetData.tdays;
|
||||
tyear=range.tyears[0];
|
||||
checkObj.tyears=range.tyears[0];
|
||||
tmonth=range.tmonths[0];
|
||||
checkObj.tmonths=range.tmonths[0];
|
||||
tday=range.tdays[0];
|
||||
checkObj.tdays=range.tdays[0];
|
||||
}
|
||||
if(fyear!=checkObj.fyear||fmonth!=checkObj.fmonth){
|
||||
range.fdays=resetData.fdays;
|
||||
};
|
||||
if(tyear!=checkObj.tyear){
|
||||
arr[5]=0;
|
||||
arr[6]=0;
|
||||
let toData=this.resetToData(fmonth,fday,tyear,tmonth);
|
||||
range.tmonths=toData.tmonths;
|
||||
range.tdays=toData.tdays;
|
||||
tmonth=range.tmonths[0];
|
||||
checkObj.tmonths=range.tmonths[0];
|
||||
tday=range.tdays[0];
|
||||
checkObj.tdays=range.tdays[0];
|
||||
};
|
||||
if(tmonth!=checkObj.tmonth){
|
||||
arr[6]=0;
|
||||
let toData=this.resetToData(fmonth,fday,tyear,tmonth);
|
||||
range.tdays=toData.tdays;
|
||||
tday=range.tdays[0];
|
||||
checkObj.tdays=range.tdays[0];
|
||||
};
|
||||
result=`${fyear+'-'+fmonth+'-'+fday+'至'+tyear+'-'+tmonth+'-'+tday}`;
|
||||
obj={
|
||||
fyear,fmonth,fday,tyear,tmonth,tday
|
||||
}
|
||||
this.checkObj=obj;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=arr;
|
||||
})
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:result.split("至"),
|
||||
obj:obj
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
@ -1,183 +0,0 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.provinces" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.citys" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column v-if="!hideArea">
|
||||
<view class="w-picker-item" v-for="(item,index) in range.areas" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import areaData from "./areadata/areadata.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickVal:[],
|
||||
range:{
|
||||
provinces:[],
|
||||
citys:[],
|
||||
areas:[]
|
||||
},
|
||||
checkObj:{}
|
||||
};
|
||||
},
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
value:{
|
||||
type:[Array,String],
|
||||
default:""
|
||||
},
|
||||
defaultType:{
|
||||
type:String,
|
||||
default:"label"
|
||||
},
|
||||
hideArea:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods:{
|
||||
getData(){
|
||||
//用来处理初始化数据
|
||||
let provinces=areaData;
|
||||
let dVal=[];
|
||||
let value=this.value;
|
||||
let a1=value[0];//默认值省
|
||||
let a2=value[1];//默认值市
|
||||
let a3=value[2];//默认值区、县
|
||||
let province,city,area;
|
||||
let provinceIndex=provinces.findIndex((v)=>{
|
||||
return v[this.defaultType]==a1
|
||||
});
|
||||
provinceIndex=value?(provinceIndex!=-1?provinceIndex:0):0;
|
||||
let citys=provinces[provinceIndex].children;
|
||||
let cityIndex=citys.findIndex((v)=>{
|
||||
return v[this.defaultType]==a2
|
||||
});
|
||||
cityIndex=value?(cityIndex!=-1?cityIndex:0):0;
|
||||
let areas=citys[cityIndex].children;
|
||||
let areaIndex=areas.findIndex((v)=>{
|
||||
return v[this.defaultType]==a3;
|
||||
});
|
||||
areaIndex=value?(areaIndex!=-1?areaIndex:0):0;
|
||||
dVal=this.hideArea?[provinceIndex,cityIndex]:[provinceIndex,cityIndex,areaIndex];
|
||||
province=provinces[provinceIndex];
|
||||
city=citys[cityIndex];
|
||||
area=areas[areaIndex];
|
||||
let obj=this.hideArea?{
|
||||
province,
|
||||
city
|
||||
}:{
|
||||
province,
|
||||
city,
|
||||
area
|
||||
}
|
||||
return this.hideArea?{
|
||||
provinces,
|
||||
citys,
|
||||
dVal,
|
||||
obj
|
||||
}:{
|
||||
provinces,
|
||||
citys,
|
||||
areas,
|
||||
dVal,
|
||||
obj
|
||||
}
|
||||
},
|
||||
initData(){
|
||||
let dataData=this.getData();
|
||||
let provinces=dataData.provinces;
|
||||
let citys=dataData.citys;
|
||||
let areas=this.hideArea?[]:dataData.areas;
|
||||
let obj=dataData.obj;
|
||||
let province=obj.province,city=obj.city,area=this.hideArea?{}:obj.area;
|
||||
let value=this.hideArea?[province.value,city.value]:[province.value,city.value,area.value];
|
||||
let result=this.hideArea?`${province.label+city.label}`:`${province.label+city.label+area.label}`;
|
||||
this.range=this.hideArea?{
|
||||
provinces,
|
||||
citys,
|
||||
}:{
|
||||
provinces,
|
||||
citys,
|
||||
areas
|
||||
};
|
||||
this.checkObj=obj;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=dataData.dVal;
|
||||
});
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:value,
|
||||
obj:obj
|
||||
})
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let provinceIndex=arr[0],cityIndex=arr[1],areaIndex=this.hideArea?0:arr[2];
|
||||
let provinces=areaData;
|
||||
let citys=(provinces[provinceIndex]&&provinces[provinceIndex].children)||provinces[provinces.length-1].children||[];
|
||||
let areas=this.hideArea?[]:((citys[cityIndex]&&citys[cityIndex].children)||citys[citys.length-1].children||[]);
|
||||
let province=provinces[provinceIndex]||provinces[provinces.length-1],
|
||||
city=citys[cityIndex]||[citys.length-1],
|
||||
area=this.hideArea?{}:(areas[areaIndex]||[areas.length-1]);
|
||||
let obj=this.hideArea?{
|
||||
province,
|
||||
city
|
||||
}:{
|
||||
province,
|
||||
city,
|
||||
area
|
||||
}
|
||||
if(this.checkObj.province.label!=province.label){
|
||||
//当省更新的时候需要刷新市、区县的数据;
|
||||
this.range.citys=citys;
|
||||
if(!this.hideArea){
|
||||
this.range.areas=areas;
|
||||
}
|
||||
|
||||
}
|
||||
if(this.checkObj.city.label!=city.label){
|
||||
//当市更新的时候需要刷新区县的数据;
|
||||
if(!this.hideArea){
|
||||
this.range.areas=areas;
|
||||
}
|
||||
}
|
||||
this.checkObj=obj;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=arr;
|
||||
})
|
||||
let result=this.hideArea?`${province.label+city.label}`:`${province.label+city.label+area.label}`;
|
||||
let value=this.hideArea?[province.value,city.value]:[province.value,city.value,area.value];
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:value,
|
||||
obj:obj
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
||||
|
@ -1,129 +0,0 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range" :key="index">{{item[nodeKey]}}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
options:{
|
||||
type:[Array,Object],
|
||||
default(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
value:{
|
||||
type:String,
|
||||
default:""
|
||||
},
|
||||
defaultType:{
|
||||
type:String,
|
||||
default:"label"
|
||||
},
|
||||
defaultProps:{
|
||||
type:Object,
|
||||
default(){
|
||||
return{
|
||||
label:"label",
|
||||
value:"value"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pickVal:[]
|
||||
};
|
||||
},
|
||||
computed:{
|
||||
nodeKey(){
|
||||
return this.defaultProps.label;
|
||||
},
|
||||
nodeValue(){
|
||||
return this.defaultProps.value;
|
||||
},
|
||||
range(){
|
||||
return this.options
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
if(this.options.length!=0){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
options(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if(this.options.length!=0){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
initData(){
|
||||
let dVal=this.value||"";
|
||||
let data=this.range;
|
||||
let pickVal=[0];
|
||||
let cur=null;
|
||||
let label="";
|
||||
let value,idx;
|
||||
if(this.defaultType==this.nodeValue){
|
||||
value=data.find((v)=>v[this.nodeValue]==dVal);
|
||||
idx=data.findIndex((v)=>v[this.nodeValue]==dVal);
|
||||
}else{
|
||||
value=data.find((v)=>v[this.nodeKey]==dVal);
|
||||
idx=data.findIndex((v)=>v[this.nodeKey]==dVal);
|
||||
}
|
||||
pickVal=[idx!=-1?idx:0];
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=pickVal;
|
||||
});
|
||||
if(this.defaultType==this.nodeValue){
|
||||
this.$emit("change",{
|
||||
result:value?value[this.nodeKey]:data[0][this.nodeKey],
|
||||
value:dVal||data[0][this.nodeKey],
|
||||
obj:value?value:data[0]
|
||||
})
|
||||
}else{
|
||||
this.$emit("change",{
|
||||
result:dVal||data[0][this.nodeKey],
|
||||
value:value?value[this.nodeValue]:data[0][this.nodeValue],
|
||||
obj:value?value:data[0]
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let pickVal=[arr[0]||0];
|
||||
let data=this.range;
|
||||
let cur=data[arr[0]];
|
||||
let label="";
|
||||
let value="";
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=pickVal;
|
||||
});
|
||||
this.$emit("change",{
|
||||
result:cur[this.nodeKey],
|
||||
value:cur[this.nodeValue],
|
||||
obj:cur
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
@ -1,250 +0,0 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.dates" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.hours" :key="index">{{item.label}}时</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.minutes" :key="index">{{item.label}}分</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickVal:[],
|
||||
range:{},
|
||||
checkObj:{}
|
||||
};
|
||||
},
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
value:{
|
||||
type:[String,Array,Number],
|
||||
default:""
|
||||
},
|
||||
current:{//是否默认选中当前日期
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
expand:{
|
||||
type:[Number,String],
|
||||
default:30
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods:{
|
||||
formatNum(n){
|
||||
return (Number(n)<10?'0'+Number(n):Number(n)+'');
|
||||
},
|
||||
checkValue(value){
|
||||
let strReg=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}(:\d{2})?$/,example="2019-12-12 18:05:00或者2019-12-12 18:05";
|
||||
if(!strReg.test(value)){
|
||||
console.log(new Error("请传入与mode、fields匹配的value值,例value="+example+""))
|
||||
}
|
||||
return strReg.test(value);
|
||||
},
|
||||
resetData(year,month,day){
|
||||
let curDate=this.getCurrenDate();
|
||||
let curFlag=this.current;
|
||||
let curYear=curDate.curYear;
|
||||
let curMonth=curDate.curMonth;
|
||||
let curDay=curDate.curDay;
|
||||
let curHour=curDate.curHour;
|
||||
let months=[],days=[],sections=[];
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let monthsLen=disabledAfter?(year*1<curYear?12:curMonth):12;
|
||||
let totalDays=new Date(year,month,0).getDate();//计算当月有几天;
|
||||
for(let month=1;month<=monthsLen;month++){
|
||||
months.push(this.formatNum(month));
|
||||
};
|
||||
for(let day=1;day<=daysLen;day++){
|
||||
days.push(this.formatNum(day));
|
||||
}
|
||||
return{
|
||||
months,
|
||||
days,
|
||||
sections
|
||||
}
|
||||
},
|
||||
getData(dVal){
|
||||
//用来处理初始化数据
|
||||
let curFlag=this.current;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let dates=[],hours=[],minutes=[];
|
||||
let curDate=new Date();
|
||||
let curYear=curDate.getFullYear();
|
||||
let curMonth=curDate.getMonth();
|
||||
let curDay=curDate.getDate();
|
||||
let aDate=new Date(curYear,curMonth,curDay);
|
||||
for(let i=0;i<this.expand*1;i++){
|
||||
aDate=new Date(curYear,curMonth,curDay+i);
|
||||
let year=aDate.getFullYear();
|
||||
let month=aDate.getMonth()+1;
|
||||
let day=aDate.getDate();
|
||||
let label=year+"-"+this.formatNum(month)+"-"+this.formatNum(day);
|
||||
switch(i){
|
||||
case 0:
|
||||
label="今天";
|
||||
break;
|
||||
case 1:
|
||||
label="明天";
|
||||
break;
|
||||
case 2:
|
||||
label="后天";
|
||||
break
|
||||
}
|
||||
dates.push({
|
||||
label:label,
|
||||
value:year+"-"+this.formatNum(month)+"-"+this.formatNum(day)
|
||||
})
|
||||
};
|
||||
for(let i=0;i<24;i++){
|
||||
hours.push({
|
||||
label:this.formatNum(i),
|
||||
value:this.formatNum(i)
|
||||
})
|
||||
}
|
||||
for(let i=0;i<60;i++){
|
||||
minutes.push({
|
||||
label:this.formatNum(i),
|
||||
value:this.formatNum(i)
|
||||
})
|
||||
}
|
||||
return {
|
||||
dates,
|
||||
hours,
|
||||
minutes
|
||||
}
|
||||
},
|
||||
getDefaultDate(){
|
||||
let value=this.value;
|
||||
let reg=/-/g;
|
||||
let defaultDate=value?new Date(value.replace(reg,"/")):new Date();
|
||||
let defaultYear=defaultDate.getFullYear();
|
||||
let defaultMonth=defaultDate.getMonth()+1;
|
||||
let defaultDay=defaultDate.getDate();
|
||||
let defaultDays=new Date(defaultYear,defaultMonth,0).getDate()*1;
|
||||
return{
|
||||
defaultDate,
|
||||
defaultYear,
|
||||
defaultMonth,
|
||||
defaultDay,
|
||||
defaultDays
|
||||
}
|
||||
},
|
||||
getDval(){
|
||||
let value=this.value;
|
||||
let dVal=null;
|
||||
let aDate=new Date();
|
||||
let year=this.formatNum(aDate.getFullYear());
|
||||
let month=this.formatNum(aDate.getMonth()+1);
|
||||
let day=this.formatNum(aDate.getDate());
|
||||
let date=this.formatNum(year)+"-"+this.formatNum(month)+"-"+this.formatNum(day);
|
||||
let hour=aDate.getHours();
|
||||
let minute=aDate.getMinutes();
|
||||
if(value){
|
||||
let flag=this.checkValue(value);
|
||||
if(!flag){
|
||||
dVal=[date,hour,minute]
|
||||
}else{
|
||||
let v=value.split(" ");
|
||||
dVal=[v[0],...v[1].split(":")];
|
||||
}
|
||||
}else{
|
||||
dVal=[date,hour,minute]
|
||||
}
|
||||
return dVal;
|
||||
},
|
||||
initData(){
|
||||
let startDate,endDate,startYear,endYear,startMonth,endMonth,startDay,endDay;
|
||||
let dates=[],hours=[],minutes=[];
|
||||
let dVal=[],pickVal=[];
|
||||
let value=this.value;
|
||||
let reg=/-/g;
|
||||
let range={};
|
||||
let result="",full="",date,hour,minute,obj={};
|
||||
let defaultDate=this.getDefaultDate();
|
||||
let defaultYear=defaultDate.defaultYear;
|
||||
let defaultMonth=defaultDate.defaultMonth;
|
||||
let defaultDay=defaultDate.defaultDay;
|
||||
let defaultDays=defaultDate.defaultDays;
|
||||
let curFlag=this.current;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let dateData=[];
|
||||
dVal=this.getDval();
|
||||
dateData=this.getData(dVal);
|
||||
dates=dateData.dates;
|
||||
hours=dateData.hours;
|
||||
minutes=dateData.minutes;
|
||||
pickVal=[
|
||||
dates.findIndex(n => n.value == dVal[0])!=-1?dates.findIndex(n => n.value == dVal[0]):0,
|
||||
hours.findIndex(n => n.value == dVal[1])!=-1?hours.findIndex(n => n.value == dVal[1]):0,
|
||||
minutes.findIndex(n => n.value == dVal[2])!=-1?minutes.findIndex(n => n.value == dVal[2]):0,
|
||||
];
|
||||
range={dates,hours,minutes};
|
||||
date=dVal[0]?dVal[0]:dates[0].label;
|
||||
hour=dVal[1]?dVal[1]:hours[0].label;
|
||||
minute=dVal[2]?dVal[2]:minutes[0].label;
|
||||
result=full=`${date+' '+hour+':'+minute}`;
|
||||
obj={
|
||||
date,
|
||||
hour,
|
||||
minute
|
||||
}
|
||||
this.range=range;
|
||||
this.checkObj=obj;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=pickVal;
|
||||
});
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:full,
|
||||
obj:obj
|
||||
})
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let data=this.range;
|
||||
let date="",hour="",minute="";
|
||||
let result="",full="",obj={};
|
||||
let disabledAfter=this.disabledAfter;
|
||||
date=(arr[0]||arr[0]==0)?data.dates[arr[0]]||data.dates[data.dates.length-1]:"";
|
||||
hour=(arr[1]||arr[1]==0)?data.hours[arr[1]]||data.hours[data.hours.length-1]:"";
|
||||
minute=(arr[2]||arr[2]==0)?data.minutes[arr[2]]||data.minutes[data.minutes.length-1]:"";
|
||||
result=full=`${date.label+' '+hour.label+':'+minute.label+':00'}`;
|
||||
obj={
|
||||
date,
|
||||
hour,
|
||||
minute
|
||||
}
|
||||
this.checkObj=obj;
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:full,
|
||||
obj:obj
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
@ -1,218 +0,0 @@
|
||||
<template>
|
||||
<view class="w-picker-view">
|
||||
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.hours" :key="index">{{item}}时</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="w-picker-item" v-for="(item,index) in range.minutes" :key="index">{{item}}分</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column v-if="second">
|
||||
<view class="w-picker-item" v-for="(item,index) in range.seconds" :key="index">{{item}}秒</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickVal:[],
|
||||
range:{},
|
||||
checkObj:{}
|
||||
};
|
||||
},
|
||||
props:{
|
||||
itemHeight:{
|
||||
type:String,
|
||||
default:"44px"
|
||||
},
|
||||
value:{
|
||||
type:[String,Array,Number],
|
||||
default:""
|
||||
},
|
||||
current:{//是否默认选中当前日期
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
second:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initData();
|
||||
},
|
||||
methods:{
|
||||
formatNum(n){
|
||||
return (Number(n)<10?'0'+Number(n):Number(n)+'');
|
||||
},
|
||||
checkValue(value){
|
||||
let strReg=/^\d{2}:\d{2}:\d{2}$/,example="18:00:05";
|
||||
if(!strReg.test(value)){
|
||||
console.log(new Error("请传入与mode、fields匹配的value值,例value="+example+""))
|
||||
}
|
||||
return strReg.test(value);
|
||||
},
|
||||
resetData(year,month,day,hour,minute){
|
||||
let curDate=this.getCurrenDate();
|
||||
let curFlag=this.current;
|
||||
let curHour=curDate.curHour;
|
||||
let curMinute=curDate.curMinute;
|
||||
let curSecond=curDate.curSecond;
|
||||
for(let hour=0;hour<24;hour++){
|
||||
hours.push(this.formatNum(hour));
|
||||
}
|
||||
for(let minute=0;minute<60;minute++){
|
||||
minutes.push(this.formatNum(minute));
|
||||
}
|
||||
for(let second=0;second<60;second++){
|
||||
seconds.push(this.formatNum(second));
|
||||
}
|
||||
return{
|
||||
hours,
|
||||
minutes,
|
||||
seconds
|
||||
}
|
||||
},
|
||||
getData(curDate){
|
||||
//用来处理初始化数据
|
||||
let hours=[],minutes=[],seconds=[];
|
||||
let curFlag=this.current;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let fields=this.fields;
|
||||
let curHour=curDate.curHour;
|
||||
let curMinute=curDate.curMinute;
|
||||
let curSecond=curDate.curSecond;
|
||||
for(let hour=0;hour<24;hour++){
|
||||
hours.push(this.formatNum(hour));
|
||||
}
|
||||
for(let minute=0;minute<60;minute++){
|
||||
minutes.push(this.formatNum(minute));
|
||||
}
|
||||
for(let second=0;second<60;second++){
|
||||
seconds.push(this.formatNum(second));
|
||||
}
|
||||
return this.second?{
|
||||
hours,
|
||||
minutes,
|
||||
seconds
|
||||
}:{
|
||||
hours,
|
||||
minutes
|
||||
}
|
||||
},
|
||||
getCurrenDate(){
|
||||
let curDate=new Date();
|
||||
let curHour=curDate.getHours();
|
||||
let curMinute=curDate.getMinutes();
|
||||
let curSecond=curDate.getSeconds();
|
||||
return this.second?{
|
||||
curHour,
|
||||
curMinute,
|
||||
curSecond
|
||||
}:{
|
||||
curHour,
|
||||
curMinute,
|
||||
}
|
||||
},
|
||||
getDval(){
|
||||
let value=this.value;
|
||||
let fields=this.fields;
|
||||
let dVal=null;
|
||||
let aDate=new Date();
|
||||
let hour=this.formatNum(aDate.getHours());
|
||||
let minute=this.formatNum(aDate.getMinutes());
|
||||
let second=this.formatNum(aDate.getSeconds());
|
||||
if(value){
|
||||
let flag=this.checkValue(value);
|
||||
if(!flag){
|
||||
dVal=[hour,minute,second]
|
||||
}else{
|
||||
dVal=value?value.split(":"):[];
|
||||
}
|
||||
}else{
|
||||
dVal=this.second?[hour,minute,second]:[hour,minute]
|
||||
}
|
||||
return dVal;
|
||||
},
|
||||
initData(){
|
||||
let curDate=this.getCurrenDate();
|
||||
let dateData=this.getData(curDate);
|
||||
let pickVal=[],obj={},full="",result="",hour="",minute="",second="";
|
||||
let dVal=this.getDval();
|
||||
let curFlag=this.current;
|
||||
let disabledAfter=this.disabledAfter;
|
||||
let hours=dateData.hours;
|
||||
let minutes=dateData.minutes;
|
||||
let seconds=dateData.seconds;
|
||||
let defaultArr=this.second?[
|
||||
dVal[0]&&hours.indexOf(dVal[0])!=-1?hours.indexOf(dVal[0]):0,
|
||||
dVal[1]&&minutes.indexOf(dVal[1])!=-1?minutes.indexOf(dVal[1]):0,
|
||||
dVal[2]&&seconds.indexOf(dVal[2])!=-1?seconds.indexOf(dVal[2]):0
|
||||
]:[
|
||||
dVal[0]&&hours.indexOf(dVal[0])!=-1?hours.indexOf(dVal[0]):0,
|
||||
dVal[1]&&minutes.indexOf(dVal[1])!=-1?minutes.indexOf(dVal[1]):0
|
||||
];
|
||||
pickVal=disabledAfter?defaultArr:(curFlag?(this.second?[
|
||||
hours.indexOf(this.formatNum(curDate.curHour)),
|
||||
minutes.indexOf(this.formatNum(curDate.curMinute)),
|
||||
seconds.indexOf(this.formatNum(curDate.curSecond)),
|
||||
]:[
|
||||
hours.indexOf(this.formatNum(curDate.curHour)),
|
||||
minutes.indexOf(this.formatNum(curDate.curMinute))
|
||||
]):defaultArr);
|
||||
this.range=dateData;
|
||||
this.checkObj=obj;
|
||||
hour=dVal[0]?dVal[0]:hours[0];
|
||||
minute=dVal[1]?dVal[1]:minutes[0];
|
||||
if(this.second)second=dVal[2]?dVal[2]:seconds[0];
|
||||
result=this.second?`${hour+':'+minute+':'+second}`:`${hour+':'+minute}`;
|
||||
full=this.second?`${hour+':'+minute+':'+second}`:`${hour+':'+minute+':00'}`;
|
||||
this.$nextTick(()=>{
|
||||
this.pickVal=pickVal;
|
||||
});
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:full,
|
||||
obj:obj
|
||||
})
|
||||
},
|
||||
handlerChange(e){
|
||||
let arr=[...e.detail.value];
|
||||
let data=this.range;
|
||||
let hour="",minute="",second="",result="",full="",obj={};
|
||||
hour=(arr[0]||arr[0]==0)?data.hours[arr[0]]||data.hours[data.hours.length-1]:"";
|
||||
minute=(arr[1]||arr[1]==0)?data.minutes[arr[1]]||data.minutes[data.minutes.length-1]:"";
|
||||
if(this.second)second=(arr[2]||arr[2]==0)?data.seconds[arr[2]]||data.seconds[data.seconds.length-1]:"";
|
||||
obj=this.second?{
|
||||
hour,
|
||||
minute,
|
||||
second
|
||||
}:{
|
||||
hour,
|
||||
minute
|
||||
};
|
||||
this.checkObj=obj;
|
||||
result=this.second?`${hour+':'+minute+':'+second}`:`${hour+':'+minute}`;
|
||||
full=this.second?`${hour+':'+minute+':'+second}`:`${hour+':'+minute+':00'}`;
|
||||
this.$emit("change",{
|
||||
result:result,
|
||||
value:full,
|
||||
obj:obj
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./w-picker.css";
|
||||
</style>
|
||||
|
@ -1,26 +0,0 @@
|
||||
.w-picker-flex2{
|
||||
flex:2;
|
||||
}
|
||||
.w-picker-flex1{
|
||||
flex:1;
|
||||
}
|
||||
.w-picker-view {
|
||||
width: 100%;
|
||||
height: 476upx;
|
||||
overflow: hidden;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
z-index: 666;
|
||||
}
|
||||
.d-picker-view{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.w-picker-item {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 88upx;
|
||||
line-height: 88upx;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 30upx;
|
||||
}
|
@ -1,340 +0,0 @@
|
||||
<template name="w-picker">
|
||||
<view class="w-picker" :key="createKey" :data-key="createKey">
|
||||
<view class="mask" :class="{'visible':visible}" @tap="onCancel" @touchmove.stop.prevent catchtouchmove="true"></view>
|
||||
<view class="w-picker-cnt" :class="{'visible':visible}">
|
||||
<view class="w-picker-header" @touchmove.stop.prevent catchtouchmove="true">
|
||||
<text @tap.stop.prevent="onCancel">取消</text>
|
||||
<slot></slot>
|
||||
<text :style="{'color':themeColor}" @tap.stop.prevent="pickerConfirm">确定</text>
|
||||
</view>
|
||||
<date-picker
|
||||
v-if="mode=='date'"
|
||||
class="w-picker-wrapper"
|
||||
:startYear="startYear"
|
||||
:endYear="endYear"
|
||||
:value="value"
|
||||
:fields="fields"
|
||||
:item-height="itemHeight"
|
||||
:current="current"
|
||||
:disabled-after="disabledAfter"
|
||||
@change="handlerChange"
|
||||
@touchstart="touchStart"
|
||||
@touchend="touchEnd">
|
||||
</date-picker>
|
||||
|
||||
<range-picker
|
||||
v-if="mode=='range'"
|
||||
class="w-picker-wrapper"
|
||||
:startYear="startYear"
|
||||
:endYear="endYear"
|
||||
:value="value"
|
||||
:item-height="itemHeight"
|
||||
:current="current"
|
||||
@change="handlerChange"
|
||||
@touchstart="touchStart"
|
||||
@touchend="touchEnd">
|
||||
</range-picker>
|
||||
|
||||
<half-picker
|
||||
v-if="mode=='half'"
|
||||
class="w-picker-wrapper"
|
||||
:startYear="startYear"
|
||||
:endYear="endYear"
|
||||
:value="value"
|
||||
:item-height="itemHeight"
|
||||
:current="current"
|
||||
:disabled-after="disabledAfter"
|
||||
@change="handlerChange"
|
||||
@touchstart="touchStart"
|
||||
@touchend="touchEnd">
|
||||
</half-picker>
|
||||
|
||||
<shortterm-picker
|
||||
v-if="mode=='shortTerm'"
|
||||
class="w-picker-wrapper"
|
||||
:startYear="startYear"
|
||||
:endYear="endYear"
|
||||
:value="value"
|
||||
:item-height="itemHeight"
|
||||
:current="current"
|
||||
expand="60"
|
||||
:disabled-after="disabledAfter"
|
||||
@change="handlerChange"
|
||||
@touchstart="touchStart"
|
||||
@touchend="touchEnd">
|
||||
</shortterm-picker>
|
||||
|
||||
<time-picker
|
||||
v-if="mode=='time'"
|
||||
class="w-picker-wrapper"
|
||||
:value="value"
|
||||
:item-height="itemHeight"
|
||||
:current="current"
|
||||
:disabled-after="disabledAfter"
|
||||
:second="second"
|
||||
@change="handlerChange"
|
||||
@touchstart="touchStart"
|
||||
@touchend="touchEnd">
|
||||
</time-picker>
|
||||
|
||||
<selector-picker
|
||||
v-if="mode=='selector'"
|
||||
class="w-picker-wrapper"
|
||||
:value="value"
|
||||
:item-height="itemHeight"
|
||||
:options="options"
|
||||
:default-type="defaultType"
|
||||
:default-props="defaultProps"
|
||||
@change="handlerChange"
|
||||
@touchstart="touchStart"
|
||||
@touchend="touchEnd">
|
||||
</selector-picker>
|
||||
|
||||
<region-picker
|
||||
v-if="mode=='region'"
|
||||
class="w-picker-wrapper"
|
||||
:value="value"
|
||||
:hide-area="hideArea"
|
||||
:default-type="defaultType"
|
||||
:item-height="itemHeight"
|
||||
@change="handlerChange"
|
||||
@touchstart="touchStart"
|
||||
@touchend="touchEnd">
|
||||
</region-picker>
|
||||
|
||||
<linkage-picker
|
||||
v-if="mode=='linkage'"
|
||||
class="w-picker-wrapper"
|
||||
:value="value"
|
||||
:options="options"
|
||||
:level="level"
|
||||
:default-type="defaultType"
|
||||
:default-props="defaultProps"
|
||||
:item-height="itemHeight"
|
||||
@change="handlerChange"
|
||||
@touchstart="touchStart"
|
||||
@touchend="touchEnd">
|
||||
</linkage-picker>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import datePicker from "./date-picker.vue"
|
||||
import rangePicker from "./range-picker.vue"
|
||||
import halfPicker from "./half-picker.vue"
|
||||
import shorttermPicker from "./shortterm-picker.vue"
|
||||
import timePicker from "./time-picker.vue"
|
||||
import selectorPicker from "./selector-picker.vue"
|
||||
import regionPicker from "./region-picker.vue"
|
||||
import linkagePicker from "./linkage-picker.vue"
|
||||
export default {
|
||||
name:"w-picker",
|
||||
components:{
|
||||
datePicker,
|
||||
rangePicker,
|
||||
halfPicker,
|
||||
timePicker,
|
||||
selectorPicker,
|
||||
shorttermPicker,
|
||||
regionPicker,
|
||||
linkagePicker
|
||||
},
|
||||
props:{
|
||||
mode:{
|
||||
type:String,
|
||||
default:"date"
|
||||
},
|
||||
value:{//默认值
|
||||
type:[String,Array,Number],
|
||||
default:""
|
||||
},
|
||||
current:{//是否默认显示当前时间,如果是,传的默认值将失效
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
themeColor:{//确认按钮主题颜色
|
||||
type:String,
|
||||
default:"#f5a200"
|
||||
},
|
||||
fields:{//日期颗粒度:year、month、day、hour、minute、second
|
||||
type:String,
|
||||
default:"date"
|
||||
},
|
||||
disabledAfter:{//是否禁用当前之后的日期
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
second:{//time-picker是否显示秒
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
options:{//selector,region数据源
|
||||
type:[Array,Object],
|
||||
default(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
defaultProps:{//selector,linkagle字段转换配置
|
||||
type:Object,
|
||||
default(){
|
||||
return{
|
||||
label:"label",
|
||||
value:"value",
|
||||
children:"children"
|
||||
}
|
||||
}
|
||||
},
|
||||
defaultType:{
|
||||
type:String,
|
||||
default:"label"
|
||||
},
|
||||
hideArea:{//mode=region时,是否隐藏区县列
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
level:{
|
||||
//多级联动层级,表示几级联动,区间2-4;
|
||||
type:[Number,String],
|
||||
default:2
|
||||
},
|
||||
timeout:{//是否开启点击延迟,当快速滚动 还没有滚动完毕点击关闭时得到的值是不准确的
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
expand:{//mode=shortterm 默认往后拓展天数
|
||||
type:[Number,String],
|
||||
default:30
|
||||
},
|
||||
startYear:{
|
||||
type:[String,Number],
|
||||
default:1970
|
||||
},
|
||||
endYear:{
|
||||
type:[String,Number],
|
||||
default:new Date().getFullYear()
|
||||
},
|
||||
visible:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.createKey=Math.random()*1000;
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
itemHeight:`height: ${uni.upx2px(88)}px;`,
|
||||
result:{},
|
||||
confirmFlag:true
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
touchStart(){
|
||||
if(this.timeout){
|
||||
this.confirmFlag=false;
|
||||
}
|
||||
},
|
||||
touchEnd(){
|
||||
if(this.timeout){
|
||||
setTimeout(()=>{
|
||||
this.confirmFlag=true;
|
||||
},500)
|
||||
}
|
||||
},
|
||||
handlerChange(res){
|
||||
let _this=this;
|
||||
this.result={...res};
|
||||
},
|
||||
show(){
|
||||
this.$emit("update:visible",true);
|
||||
},
|
||||
hide(){
|
||||
this.$emit("update:visible",false);
|
||||
},
|
||||
onCancel(res){
|
||||
this.$emit("update:visible",false);
|
||||
this.$emit("cancel");
|
||||
},
|
||||
pickerConfirm(){
|
||||
if(!this.confirmFlag){
|
||||
return;
|
||||
};
|
||||
this.$emit("confirm",this.result);
|
||||
this.$emit("update:visible",false);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.w-picker-item {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 88upx;
|
||||
line-height: 88upx;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 30upx;
|
||||
}
|
||||
.w-picker{
|
||||
z-index: 888;
|
||||
.mask {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.mask.visible{
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
.w-picker-cnt {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
transition: all 0.3s ease;
|
||||
transform: translateY(100%);
|
||||
z-index: 3000;
|
||||
background-color: #fff;
|
||||
}
|
||||
.w-picker-cnt.visible {
|
||||
transform: translateY(0);
|
||||
}
|
||||
.w-picker-header{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 30upx;
|
||||
height: 88upx;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
font-size: 32upx;
|
||||
justify-content: space-between;
|
||||
border-bottom: solid 1px #eee;
|
||||
.w-picker-btn{
|
||||
font-size: 30upx;
|
||||
}
|
||||
}
|
||||
|
||||
.w-picker-hd:after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
color: #e5e5e5;
|
||||
transform-origin: 0 100%;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,106 +0,0 @@
|
||||
<template>
|
||||
<view class="address-box">
|
||||
<view v-if="!address.area" class="address-empty">
|
||||
<view class="address-tips">
|
||||
<u--text :lines="1" size="14px" color="#333" bold="true" text="请选择收货地址"></u--text>
|
||||
<u-icon class="icon-arrow-right" name="arrow-right"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="address-selected">
|
||||
<view class="address-area">
|
||||
<view class="default-tag">默认</view>
|
||||
<u--text :lines="1" size="12px" color="#666" :text="address.area"></u--text>
|
||||
</view>
|
||||
<view class="address-detail">
|
||||
<u--text :lines="2" size="14px" color="#333" :bold="true" :text="address.detail"></u--text>
|
||||
<u-icon class="icon-arrow-right" name="arrow-right"></u-icon>
|
||||
</view>
|
||||
<view class="address-user">
|
||||
<view class="user-text">{{ address.name }}</view>
|
||||
<view class="user-text">{{ address.mobile }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<image class="address-line" src="/static/images/address-line.png"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 地址选择
|
||||
*/
|
||||
export default {
|
||||
name: 'yd-address-select',
|
||||
props: {
|
||||
address: {
|
||||
type: Object,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.address-box {
|
||||
padding: 0 10rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 0 0 30rpx 30rpx;
|
||||
|
||||
.address-empty {
|
||||
padding: 20rpx 20rpx 0;
|
||||
.address-tips {
|
||||
@include flex-space-between;
|
||||
padding: 10rpx 0;
|
||||
|
||||
.icon-arrow-right {
|
||||
margin-left: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address-selected {
|
||||
padding: 20rpx 20rpx 0;
|
||||
.address-area {
|
||||
@include flex-left;
|
||||
|
||||
.default-tag {
|
||||
font-size: 22rpx;
|
||||
color: $u-primary;
|
||||
border: 1rpx solid $u-primary;
|
||||
padding: 0 6rpx;
|
||||
margin-right: 10rpx;
|
||||
border-radius: 5rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.address-detail {
|
||||
@include flex-space-between;
|
||||
padding: 10rpx 0;
|
||||
|
||||
.icon-arrow-right {
|
||||
margin-left: 50rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.address-user {
|
||||
@include flex-left;
|
||||
|
||||
.user-text {
|
||||
color: #666;
|
||||
font-size: 24rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address-line {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
height: 5rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,58 +0,0 @@
|
||||
<template>
|
||||
<u-swiper :list="bannerList" :keyName="keyName" previousMargin="20" nextMargin="20" circular height="150" @change="e => (current = e.current)" :autoplay="true" @click="handleSwiperClick">
|
||||
<view slot="indicator" class="indicator">
|
||||
<view class="indicator__dot" v-for="(item, index) in bannerList" :key="index" :class="[index === current && 'indicator__dot--active']"></view>
|
||||
</view>
|
||||
</u-swiper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 广告滚动图
|
||||
*/
|
||||
export default {
|
||||
name: 'yd-banner',
|
||||
components: {},
|
||||
props: {
|
||||
keyName: {
|
||||
type: String,
|
||||
default: 'url'
|
||||
},
|
||||
bannerList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
current: 0,
|
||||
currentNum: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSwiperClick(index) {
|
||||
console.log('点击了图片索引值:', index)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.indicator {
|
||||
@include flex(row);
|
||||
justify-content: center;
|
||||
|
||||
&__dot {
|
||||
height: 15rpx;
|
||||
width: 15rpx;
|
||||
border-radius: 100rpx;
|
||||
background-color: rgba(255, 255, 255, 0.35);
|
||||
margin: 0 10rpx;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&--active {
|
||||
background-color: $custom-bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="product-item" v-for="(item, index) in productList" :key="item.productId" @click="handleProductItemClick(item.productId)">
|
||||
<view class="product-check" @click.stop="handleCheckProduct(item.productId, item.checked)">
|
||||
<u-icon v-if="item.checked" name="checkmark-circle-fill" color="#3c9cff" size="22"></u-icon>
|
||||
<view v-else class="un-check-box"></view>
|
||||
</view>
|
||||
<image class="product-image" :src="item.coverUrl"></image>
|
||||
<view class="item-info">
|
||||
<view class="info-text">
|
||||
<u--text :lines="1" size="15px" color="#333333" :text="item.productTitle"></u--text>
|
||||
<u-gap height="2px"></u-gap>
|
||||
<u--text class="info-tips" :lines="1" size="12px" color="#939393" :text="item.tips"></u--text>
|
||||
</view>
|
||||
<view class="price-number-box">
|
||||
<view class="price-box">
|
||||
<yd-text-price color="red" size="13" intSize="20" :price="item.sellPrice"></yd-text-price>
|
||||
<yd-text-price v-if="item.strikePrice" style="margin-left: 5px" decoration="line-through" color="#999" size="12" :price="item.sellPrice"></yd-text-price>
|
||||
</view>
|
||||
<view class="number-box" @click.stop>
|
||||
<u-number-box min="1" max="999" bgColor="#fff" integer :disableMinus="false" :disabledInput="true" :name="item.productId" :value="item.productCount" @change="handleProductCountChange"></u-number-box>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 购物车商品列表
|
||||
*/
|
||||
export default {
|
||||
name: 'yd-cart-product',
|
||||
props: {
|
||||
productList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//status: 'nomore',
|
||||
loadingText: '加载中...',
|
||||
loadmoreText: '上拉加载更多',
|
||||
nomoreText: '没有更多了'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleProductItemClick(productId) {
|
||||
uni.$u.route('/pages/product/product', {
|
||||
id: productId
|
||||
})
|
||||
},
|
||||
handleItemCartClick(productId) {
|
||||
this.$store.dispatch('CartProductCountChange', { productIds: [productId], productCount: 1, addition: true }).then(res => {
|
||||
uni.$u.toast('已添加到购物车')
|
||||
})
|
||||
},
|
||||
handleCheckProduct(productId, checked) {
|
||||
this.$emit('productCheckedChange', productId, !checked)
|
||||
},
|
||||
handleProductCountChange({ name, value }) {
|
||||
this.$emit('productCartProductCountChange', name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.product-item {
|
||||
background: #ffffff;
|
||||
@include flex-space-between;
|
||||
border-bottom: $custom-border-style;
|
||||
padding: 10rpx 0 0 5rpx;
|
||||
|
||||
.product-check {
|
||||
padding: 20rpx;
|
||||
|
||||
.un-check-box {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid #939393;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
flex: 1;
|
||||
padding: 20rpx 20rpx 0;
|
||||
|
||||
.info-text {
|
||||
height: 70rpx;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.price-number-box {
|
||||
@include flex-space-between;
|
||||
|
||||
.price-box {
|
||||
@include flex-left();
|
||||
}
|
||||
|
||||
.number-box {
|
||||
height: 100rpx;
|
||||
@include flex-center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,100 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="product-item" v-for="(item, index) in productList" :key="item.productId">
|
||||
<image class="product-image" :src="item.coverUrl"></image>
|
||||
<view class="item-info">
|
||||
<view class="info-text">
|
||||
<u--text :lines="1" size="15px" color="#333333" :text="item.productTitle"></u--text>
|
||||
<u-gap height="10"></u-gap>
|
||||
<yd-text-price class="product-price" size="13" intSize="16" :price="item.sellPrice"></yd-text-price>
|
||||
</view>
|
||||
<view class="price-number-box">
|
||||
<view class="number-box">
|
||||
<view class="product-number">共 {{ item.productCount }} 件</view> 小计:
|
||||
</view>
|
||||
<view class="number-box" @click.stop>
|
||||
<yd-text-price size="13" intSize="18" :price="item.totalPrice"></yd-text-price>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 订单商品列表
|
||||
*/
|
||||
export default {
|
||||
name: 'yd-order-product',
|
||||
props: {
|
||||
productList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
handleProductItemClick(productId) {
|
||||
uni.$u.route('/pages/product/product', {
|
||||
id: productId
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.product-item {
|
||||
background: #ffffff;
|
||||
@include flex-space-between;
|
||||
border-bottom: $custom-border-style;
|
||||
padding: 10rpx 0 0 5rpx;
|
||||
|
||||
.product-check {
|
||||
padding: 20rpx;
|
||||
|
||||
.un-check-box {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid #939393;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
flex: 1;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.info-text {
|
||||
padding-bottom: 10rpx;
|
||||
.product-price {
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.price-number-box {
|
||||
@include flex-space-between;
|
||||
|
||||
.number-box {
|
||||
font-size: 24rpx;
|
||||
.product-number {
|
||||
width: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.number-box {
|
||||
height: 60rpx;
|
||||
@include flex-center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,173 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-if="showType === 'normal'">
|
||||
<u-gap height="180" bgColor="#398ade"></u-gap>
|
||||
<view class="prod-block">
|
||||
<view class="bloc-header">
|
||||
<text class="bloc-title">{{title}}</text>
|
||||
<text class="see-more">查看更多</text>
|
||||
</view>
|
||||
<view class="prod-grid">
|
||||
<view class="prod-item" v-for="(item, index) in productList" :key="item.id" @click="handleProdItemClick(item.id)">
|
||||
<image class="prod-image" :src="item.image"></image>
|
||||
<view class="item-info">
|
||||
<view class="info-text">
|
||||
<u--text :lines="2" size="14px" color="#333333" :text="item.title"></u--text>
|
||||
</view>
|
||||
<view class="price-and-cart">
|
||||
<yd-text-price color="red" size="12" intSize="18" :price="item.price"></yd-text-price>
|
||||
<u-icon name="shopping-cart" color="#2979ff" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="showType === 'half'">
|
||||
<view class="prod-block half">
|
||||
<view class="bloc-header">
|
||||
<text class="bloc-title">{{title}}</text>
|
||||
<text class="more">更多 ></text>
|
||||
</view>
|
||||
<view class="prod-grid half">
|
||||
<view class="prod-item" v-for="(item, index) in productList" :key="item.id" @click="handleProdItemClick(item.id)">
|
||||
<image class="prod-image" :src="item.image"></image>
|
||||
<view class="item-info">
|
||||
<view class="info-text">
|
||||
<u--text :lines="1" size="14px" color="#333333" :text="item.title"></u--text>
|
||||
<u--text :lines="1" size="12px" color="#939393" :text="item.desc"></u--text>
|
||||
</view>
|
||||
<view class="price-and-cart">
|
||||
<yd-text-price color="red" size="12" intSize="18" :price="item.price"></yd-text-price>
|
||||
<u-icon name="shopping-cart" color="#2979ff" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 商品列表
|
||||
*/
|
||||
export default {
|
||||
name: 'yd-product-box',
|
||||
components: {},
|
||||
props: {
|
||||
showType: {
|
||||
type: String,
|
||||
default: 'normal'
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '商品推荐'
|
||||
},
|
||||
productList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
handleProdItemClick(productId) {
|
||||
uni.$u.route('/pages/product/product', {
|
||||
id: productId
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.prod-block {
|
||||
margin-top: -160px;
|
||||
|
||||
.bloc-header {
|
||||
@include flex-space-between;
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
.bloc-title {
|
||||
color: $custom-bg-color;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.see-more {
|
||||
color: $custom-bg-color;
|
||||
background: $u-primary;
|
||||
padding: 0 30rpx;
|
||||
height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
border-radius: 50rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.half {
|
||||
margin-top: 0;
|
||||
|
||||
.bloc-header {
|
||||
margin-top: 50rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.bloc-title {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.prod-grid {
|
||||
width: 730rpx;
|
||||
margin: 0 auto;
|
||||
@include flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: left;
|
||||
|
||||
&.half {
|
||||
.prod-item {
|
||||
width: 345rpx;
|
||||
margin: 10rpx;
|
||||
|
||||
.prod-image {
|
||||
width: 345rpx;
|
||||
height: 345rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.prod-item {
|
||||
width: 223rpx;
|
||||
margin: 10rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
box-shadow: 0rpx 6rpx 8rpx rgba(58, 134, 185, 0.2);
|
||||
|
||||
.prod-image {
|
||||
width: 223rpx;
|
||||
height: 223rpx;
|
||||
border-radius: 10rpx 10rpx 0 0;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
padding: 15rpx;
|
||||
|
||||
.info-text {
|
||||
height: 70rpx;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.price-and-cart {
|
||||
@include flex-space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,114 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="prod-block list">
|
||||
<view class="bloc-header">
|
||||
<text class="bloc-title">更多宝贝</text>
|
||||
<text></text>
|
||||
</view>
|
||||
|
||||
<view class="prod-list" v-for="(item, index) in productList" :key="item.id">
|
||||
<view class="prod-item" @click="handleProdItemClick(item.id)">
|
||||
<image class="prod-image" :src="item.image"></image>
|
||||
<view class="item-info">
|
||||
<view class="info-text">
|
||||
<u--text :lines="1" size="14px" color="#333333" :text="item.title"></u--text>
|
||||
<u-gap height="2px"></u-gap>
|
||||
<u--text class="info-desc" :lines="2" size="12px" color="#939393" :text="item.desc"></u--text>
|
||||
</view>
|
||||
<view class="price-and-cart">
|
||||
<yd-text-price color="red" size="12" intSize="18" :price="item.price"></yd-text-price>
|
||||
<u-icon name="shopping-cart" color="#2979ff" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!--加载更多-->
|
||||
<u-loadmore fontSize="28rpx" :line="true" :status="moreStatus" :loading-text="loadingText" :loadmore-text="loadmoreText" :nomore-text="nomoreText" />
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 商品列表(加载更多)
|
||||
*/
|
||||
export default {
|
||||
name: 'yd-product-more',
|
||||
components: {},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '商品推荐'
|
||||
},
|
||||
productList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
moreStatus: {
|
||||
type: String,
|
||||
default: 'nomore'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//status: 'nomore',
|
||||
loadingText: '加载中...',
|
||||
loadmoreText: '上拉加载更多',
|
||||
nomoreText: '已经到底了'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleProdItemClick(productId) {
|
||||
uni.$u.route('/pages/product/product', {
|
||||
id: productId
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.prod-block {
|
||||
margin-top: 0;
|
||||
|
||||
.bloc-header {
|
||||
margin-top: 50rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.bloc-title {
|
||||
margin-left: 20rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.prod-list {
|
||||
.prod-item {
|
||||
background: #ffffff;
|
||||
@include flex-space-between;
|
||||
border-bottom: $custom-border-style;
|
||||
padding: 20rpx;
|
||||
|
||||
.prod-image {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
flex: 1;
|
||||
padding: 20rpx 20rpx 0;
|
||||
|
||||
.info-text {
|
||||
height: 100rpx;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.price-and-cart {
|
||||
@include flex-space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<text v-for="(item, index) in textArray" :key="index" :style="{ fontSize: (index === 1 ? integerSize : size) + 'px', color, textDecoration }">
|
||||
{{ item }}
|
||||
</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 此组件简单的显示(驼峰式)的价格
|
||||
*/
|
||||
export default {
|
||||
name: 'yd-text-price',
|
||||
components: {},
|
||||
props: {
|
||||
//货币符号
|
||||
symbol: {
|
||||
type: String,
|
||||
default: '¥'
|
||||
},
|
||||
price: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#333333'
|
||||
},
|
||||
//字体大小
|
||||
size: {
|
||||
type: [String, Number],
|
||||
default: 15
|
||||
},
|
||||
//整形部分字体大小可单独定义
|
||||
intSize: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
//文字装饰,下划线,中划线等
|
||||
decoration: {
|
||||
type: String,
|
||||
default: 'none'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
textDecoration: this.decoration
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
textArray() {
|
||||
let array = []
|
||||
if (this.price === '' || this.price === undefined) {
|
||||
return []
|
||||
}
|
||||
array.push(this.symbol)
|
||||
if (!/^\d+(\.\d+)?$/.test(this.price)) {
|
||||
console.error('组件<yd-text-price :text="???" 此处参数应为金额数字')
|
||||
} else {
|
||||
let arr = parseFloat(this.price).toFixed(2).split('.')
|
||||
array.push(arr[0])
|
||||
array.push('.' + arr[1])
|
||||
}
|
||||
return array
|
||||
},
|
||||
integerSize() {
|
||||
return this.intSize ? this.intSize : this.size
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped></style>
|
@ -1,20 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
let coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,26 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
|
||||
// 引入全局uView
|
||||
import uView from '@/uni_modules/uview-ui'
|
||||
|
||||
// vuex
|
||||
import store from './store'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$store = store
|
||||
|
||||
|
||||
|
||||
App.mpType = 'app'
|
||||
Vue.use(uView)
|
||||
|
||||
const app = new Vue({
|
||||
store,
|
||||
...App
|
||||
})
|
||||
|
||||
// 引入请求封装
|
||||
require('./utils/request/index')(app)
|
||||
|
||||
app.$mount()
|
@ -1,72 +0,0 @@
|
||||
{
|
||||
"name" : "yudao-ui-app",
|
||||
"appid" : "__UNI__CA099E3",
|
||||
"description" : "yudao-ui-app for ruoyi-vue-pro",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios" : {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "wx48d7c38b46f2e81c",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
},
|
||||
"vueVersion" : "2"
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
{
|
||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "首页"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/category/category",
|
||||
"style": {
|
||||
"navigationBarTitleText": "分类"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/category/product-list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/cart/cart",
|
||||
"style": {
|
||||
"navigationBarTitleText": "购物车"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/user",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/social",
|
||||
"style": {
|
||||
"navigationBarTitleText": "授权登录"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/mobile",
|
||||
"style": {
|
||||
"navigationBarTitleText": "手机登录"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/forgot/forgot",
|
||||
"style": {
|
||||
"navigationBarTitleText": "忘记密码"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/profile/profile",
|
||||
"style": {
|
||||
"navigationBarTitleText": "个人资料"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/setting/setting",
|
||||
"style": {
|
||||
"navigationBarTitleText": "账户设置"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/product/product",
|
||||
"style": {
|
||||
"navigationBarTitleText": "商品详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/checkout/checkout",
|
||||
"style": {
|
||||
"navigationBarTitleText": "填写订单"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/order/list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的订单"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/order/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "订单详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/order/confirm",
|
||||
"style": {
|
||||
"navigationBarTitleText": "确认订单"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/address/list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "收货地址"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/search/search",
|
||||
"style": {
|
||||
"navigationBarTitleText": "搜索"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/address/create",
|
||||
"style": {
|
||||
"navigationBarTitleText": "新增地址"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/address/update",
|
||||
"style": {
|
||||
"navigationBarTitleText": "修改地址"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tabBar": {
|
||||
"selectedColor": "#333333",
|
||||
"color": "#bfbfbf",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/index/index",
|
||||
"text": "首页",
|
||||
"iconPath": "/static/images/tabbar/index.png",
|
||||
"selectedIconPath": "/static/images/tabbar/index-active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/category/category",
|
||||
"text": "分类",
|
||||
"iconPath": "/static/images/tabbar/category.png",
|
||||
"selectedIconPath": "/static/images/tabbar/category-active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/cart/cart",
|
||||
"text": "购物车",
|
||||
"iconPath": "/static/images/tabbar/cart.png",
|
||||
"selectedIconPath": "/static/images/tabbar/cart-active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/user/user",
|
||||
"text": "我的",
|
||||
"iconPath": "/static/images/tabbar/user.png",
|
||||
"selectedIconPath": "/static/images/tabbar/user-active.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "yudao-ui-app",
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"backgroundColor": "#ffffff"
|
||||
}
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="address-box">
|
||||
<u--form labelPosition="left" :model="formData" :rules="rules" ref="form">
|
||||
<u-form-item label="收件人名称" prop="name" labelWidth="90" borderBottom ref="item-name">
|
||||
<u-input type="text" maxlength="11" v-model="formData.name" clearable placeholder="请填写收件人名称" border="none"></u-input>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="手机号" prop="mobile" labelWidth="90" borderBottom ref="item-mobile">
|
||||
<u-input type="number" maxlength="11" v-model="formData.mobile" clearable placeholder="请填写手机号" border="none"></u-input>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="省市地区" prop="areaText" labelWidth="90" borderBottom @click=" regionVisible = true; hideKeyboard()" ref="item-areaText">
|
||||
<u--input v-model="formData.areaText" disabled disabledColor="#ffffff" placeholder="请选择省市地区" border="none"></u--input>
|
||||
<u-icon slot="right" name="arrow-right"></u-icon>
|
||||
<w-picker :visible.sync="regionVisible" mode="region" :value="defaultRegion" default-type="value" :hide-area="false" @confirm="onConfirm($event, 'region')" @cancel="onCancel" ref="region"></w-picker>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="详细地址" prop="detail" labelWidth="90" borderBottom ref="item-detail">
|
||||
<u--textarea placeholder="请输入街道门牌号不低于6个字" v-model="formData.detail" count></u--textarea>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="默认地址" prop="type" labelWidth="90" borderBottom ref="item-type">
|
||||
<u-radio-group v-model="formData.type">
|
||||
<u-radio :customStyle="{ marginRight: '16px' }" v-for="(item, index) in typeList" :key="index" :label="item.name" :name="item.value"></u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
|
||||
<view class="btn-group">
|
||||
<u-button type="primary" text="保存地址" customStyle="margin-top: 50px" @click="handleSubmit"></u-button>
|
||||
</view>
|
||||
</u--form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createAddress } from '../../api/address'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
regionVisible: false,
|
||||
defaultRegion: ['110000', '110100', '110101'],
|
||||
typeList: [
|
||||
{
|
||||
name: '是',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: '否',
|
||||
value: 2
|
||||
}
|
||||
],
|
||||
formData: {
|
||||
name: '',
|
||||
mobile: '',
|
||||
areaText: '',
|
||||
areaCode: '',
|
||||
detail: '',
|
||||
detailAddress: '',
|
||||
type: 1
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
type: 'string',
|
||||
min: 2,
|
||||
max: 12,
|
||||
required: true,
|
||||
message: '请填写收件人名称',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
{
|
||||
message: '收件人名称不能为空',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
mobile: [
|
||||
{
|
||||
type: 'integer',
|
||||
required: true,
|
||||
message: '请填写手机号',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// uni.$u.test.mobile()就是返回true或者false的
|
||||
return uni.$u.test.mobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
areaText: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
message: '请选择省市地区',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
detailAddress: {
|
||||
type: 'string',
|
||||
min: 6,
|
||||
max: 30,
|
||||
required: true,
|
||||
message: '请填写详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
onConfirm(res) {
|
||||
this.formData.areaText = res.result
|
||||
this.formData.areaCode = res.value[2]
|
||||
},
|
||||
onCancel() {},
|
||||
hideKeyboard() {
|
||||
uni.hideKeyboard()
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate().then(res => {
|
||||
this.formData.detailAddress = this.formData.areaText + this.formData.detail
|
||||
console.log(this.formData)
|
||||
createAddress(this.formData).then(res => {
|
||||
uni.$u.toast('地址已保存')
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 300)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.address-box {
|
||||
width: 690rpx;
|
||||
margin: 0 auto;
|
||||
padding-top: 30rpx;
|
||||
}
|
||||
</style>
|
@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="address-list" v-for="(item, index) in addressList" :key="item.id">
|
||||
<view class="address-item" @click="handleClick" @longpress="handleLongPress(item)">
|
||||
<view class="left">
|
||||
<u-avatar :text="item.name ? item.name.slice(0, 1) : 'U'" fontSize="18" randomBgColor></u-avatar>
|
||||
</view>
|
||||
<view class="middle">
|
||||
<view class="info">
|
||||
<view class="name">{{ item.name }}</view>
|
||||
<view class="mobile">{{ item.mobile }}</view>
|
||||
<u-tag class="type" v-if="item.type === 1" text="默认" plain size="mini" type="success"></u-tag>
|
||||
</view>
|
||||
<view class="detail">
|
||||
<u--text :lines="2" size="14" color="#939393" :text="item.detailAddress"></u--text>
|
||||
</view>
|
||||
</view>
|
||||
<navigator class="right" :url="`/pages/address/update?addressId=${item.id}`" open-type="navigate" hover-class="none">
|
||||
<u-icon name="edit-pen" size="28"></u-icon>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<navigator class="fixed-btn-box" url="/pages/address/create" open-type="navigate" hover-class="none">
|
||||
<u-button type="primary" size="large" text="新增地址"></u-button>
|
||||
</navigator>
|
||||
<u-safe-bottom customStyle="background: #ffffff"></u-safe-bottom>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAddressList, deleteAddress } from '../../api/address'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
addressList: []
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {
|
||||
this.loadAddressListData()
|
||||
},
|
||||
methods: {
|
||||
loadAddressListData() {
|
||||
getAddressList().then(res => {
|
||||
this.addressList = res.data
|
||||
})
|
||||
},
|
||||
handleLongPress(item) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: `删除收件人[${item.name}${item.mobile}]\n地址:${item.detailAddress.slice(0, 5)}......${item.detailAddress.slice(-6)}?`,
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
deleteAddress({ id: item.id }).then(res => {
|
||||
uni.$u.toast('地址已删除')
|
||||
this.loadAddressListData();
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
//console.log('用户点击取消')
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
handleClick(){
|
||||
// TODO 提交订单时选择地址逻辑
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.address-list {
|
||||
.address-item {
|
||||
padding: 10rpx 0;
|
||||
border-bottom: $custom-border-style;
|
||||
@include flex-space-between;
|
||||
.left {
|
||||
margin: 20rpx;
|
||||
}
|
||||
.middle {
|
||||
flex: 1;
|
||||
margin: 20rpx;
|
||||
@include flex(column);
|
||||
.info {
|
||||
@include flex-left;
|
||||
.name {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.mobile {
|
||||
font-size: 28rpx;
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
.type {
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
}
|
||||
.detail {
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
margin: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fixed-btn-box {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 750rpx;
|
||||
}
|
||||
</style>
|
@ -1,178 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="address-box">
|
||||
<u--form labelPosition="left" :model="formData" :rules="rules" ref="form">
|
||||
<u-form-item label="收件人名称" prop="name" labelWidth="90" borderBottom ref="item-name">
|
||||
<u-input type="text" maxlength="11" v-model="formData.name" clearable placeholder="请填写收件人名称" border="none"></u-input>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="手机号" prop="mobile" labelWidth="90" borderBottom ref="item-mobile">
|
||||
<u-input type="number" maxlength="11" v-model="formData.mobile" clearable placeholder="请填写手机号" border="none"></u-input>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="省市地区" prop="areaText" labelWidth="90" borderBottom @click=" regionVisible = true; hideKeyboard()" ref="item-areaText">
|
||||
<u--input v-model="formData.areaText" disabled disabledColor="#ffffff" placeholder="请选择省市地区" border="none"></u--input>
|
||||
<u-icon slot="right" name="arrow-right"></u-icon>
|
||||
<w-picker :visible.sync="regionVisible" mode="region" :value="defaultRegion" default-type="value" :hide-area="false" @confirm="onConfirm($event, 'region')" @cancel="onCancel" ref="region"></w-picker>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="详细地址" prop="detail" labelWidth="90" borderBottom ref="item-detail">
|
||||
<u--textarea placeholder="请输入街道门牌号不低于6个字" v-model="formData.detail" count></u--textarea>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="默认地址" prop="type" labelWidth="90" borderBottom ref="item-type">
|
||||
<u-radio-group v-model="formData.type">
|
||||
<u-radio :customStyle="{ marginRight: '16px' }" v-for="(item, index) in typeList" :key="index" :label="item.name" :name="item.value"></u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
|
||||
<view class="btn-group">
|
||||
<u-button type="primary" text="更新地址" customStyle="margin-top: 50px" @click="handleSubmit"></u-button>
|
||||
</view>
|
||||
</u--form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAddressById, updateAddress } from '../../api/address'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
regionVisible: false,
|
||||
defaultRegion: ['110000', '110100', '110101'],
|
||||
typeList: [
|
||||
{
|
||||
name: '是',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: '否',
|
||||
value: 2
|
||||
}
|
||||
],
|
||||
formData: {
|
||||
id: '',
|
||||
name: '',
|
||||
mobile: '',
|
||||
areaText: '',
|
||||
areaCode: '',
|
||||
detail: '',
|
||||
detailAddress: '',
|
||||
type: 1
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
type: 'string',
|
||||
min: 2,
|
||||
max: 12,
|
||||
required: true,
|
||||
message: '请填写收件人名称',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
{
|
||||
message: '收件人名称不能为空',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
mobile: [
|
||||
{
|
||||
type: 'integer',
|
||||
required: true,
|
||||
message: '请填写手机号',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// uni.$u.test.mobile()就是返回true或者false的
|
||||
return uni.$u.test.mobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
areaText: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
message: '请选择省市地区',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
detailAddress: {
|
||||
type: 'string',
|
||||
min: 6,
|
||||
max: 30,
|
||||
required: true,
|
||||
message: '请填写详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
if (!e.addressId) {
|
||||
uni.$u.toast('请求参数错误')
|
||||
} else {
|
||||
this.id = e.addressId
|
||||
this.loadAddressData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadAddressData() {
|
||||
getAddressById({ id: this.id }).then(res => {
|
||||
this.formData = res.data
|
||||
this.initRegionData()
|
||||
})
|
||||
},
|
||||
initRegionData(){
|
||||
//回显 【省市地区】 和 【详细地址】 信息
|
||||
if (this.formData.areaCode) {
|
||||
const areaCode = this.formData.areaCode + ''
|
||||
//通过地区code反解析出【省-市-地区】code
|
||||
this.defaultRegion.splice(0, 3, areaCode.substring(0,2).padEnd(6, '0'), areaCode.substring(0,4).padEnd(6, '0'), areaCode)
|
||||
this.$nextTick(res => {
|
||||
let areaText = this.$refs.region._data.result.result
|
||||
this.formData.areaText = areaText
|
||||
//通过从完整详细地址除去【省-市-地区】得到后半段地址信息
|
||||
this.formData.detail = this.formData.detailAddress.replace(areaText, '')
|
||||
this.$forceUpdate();
|
||||
})
|
||||
}
|
||||
},
|
||||
onConfirm(res) {
|
||||
this.formData.areaText = res.result
|
||||
this.formData.areaCode = res.value[2]
|
||||
},
|
||||
onCancel() {},
|
||||
hideKeyboard() {
|
||||
uni.hideKeyboard()
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate().then(res => {
|
||||
this.formData.detailAddress = this.formData.areaText + this.formData.detail
|
||||
console.log(this.formData)
|
||||
updateAddress(this.formData).then(res => {
|
||||
uni.$u.toast('地址已更新')
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 300)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.address-box {
|
||||
width: 690rpx;
|
||||
margin: 0 auto;
|
||||
padding-top: 30rpx;
|
||||
}
|
||||
</style>
|
@ -1,225 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 购物车为空 -->
|
||||
<view v-if="!hasLogin || cartList.length === 0">
|
||||
<view class="cart-empty">
|
||||
<u-empty text="去逛逛添点什么吧" width="500rpx" height="500rpx" icon="/static/images/empty/cart.png"></u-empty>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 购物车列表 -->
|
||||
<scroll-view v-if="hasLogin && cartList.length > 0" class="cart-product" scroll-y="true">
|
||||
<yd-cart-product :product-list="cartList" @productCheckedChange="handleProductCheckedChange" @productCountChange="handleProductCountChange"></yd-cart-product>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 未登录 -->
|
||||
<view v-if="!hasLogin" class="login-tips-box">
|
||||
<view class="login-tips">
|
||||
<navigator url="/pages/login/social" open-type="navigate" hover-class="none">
|
||||
<view class="login-link">登录查看</view>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部菜单 -->
|
||||
<view class="cart-btn-container">
|
||||
<view class="btn-box">
|
||||
<view class="product-check-info">
|
||||
<view class="check-all-btn" @click.stop="handleCheckAllProduct">
|
||||
<u-icon v-if="isCheckAll" name="checkmark-circle-fill" color="#3c9cff" size="22"></u-icon>
|
||||
<view v-else class="un-check-box"></view>
|
||||
</view>
|
||||
<view class="info-text">合计:</view>
|
||||
<view>
|
||||
<yd-text-price color="red" size="15" intSize="20" :price="totalAmount"></yd-text-price>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="checkedProduct.length > 0" class="cart-btn-group">
|
||||
<u-button type="warning" shape="circle" size="small" text="移除" @click="handleRemoveProduct"></u-button>
|
||||
<view class="btn-gap"></view>
|
||||
<u-button style="margin-left: 10px" class="main-btn" type="primary" shape="circle" size="small" text="去结算" @click="handleCheckoutProduct"></u-button>
|
||||
</view>
|
||||
<view v-else class="cart-btn-group">
|
||||
<u-button type="warning" shape="circle" size="small" text="移除" disabled></u-button>
|
||||
<view class="btn-gap"></view>
|
||||
<u-button style="margin-left: 10px" class="main-btn" type="primary" shape="circle" size="small" text="去结算" disabled></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
cartList: [],
|
||||
checkedNumber: 0,
|
||||
totalAmount: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
checkedProduct() {
|
||||
return this.cartList.filter(item => {
|
||||
return item.checked
|
||||
})
|
||||
},
|
||||
isCheckAll() {
|
||||
if (this.cartList.length < 1) {
|
||||
return false
|
||||
}
|
||||
return this.cartList.every(item => {
|
||||
return item.checked
|
||||
})
|
||||
},
|
||||
hasLogin() {
|
||||
return this.$store.getters.hasLogin
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
if (this.hasLogin) {
|
||||
this.loadCartDetailData()
|
||||
} else {
|
||||
this.cartList =[]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadCartDetailData() {
|
||||
this.$store.dispatch('CartProductDetail').then(res => {
|
||||
this.cartList = res.data || []
|
||||
})
|
||||
},
|
||||
/** 商品全选/取消全选 */
|
||||
handleCheckAllProduct() {
|
||||
if (this.cartList.length < 1) {
|
||||
return
|
||||
}
|
||||
const productIds = this.cartList.map(item => {
|
||||
return item.productId
|
||||
})
|
||||
this.$store.dispatch('CartProductCheckChange', { productIds, checked: !this.isCheckAll }).then(res => {
|
||||
this.cartList = res.data || []
|
||||
})
|
||||
},
|
||||
/** 商品单选/取消单选 */
|
||||
handleProductCheckedChange(productId, checked) {
|
||||
this.$store.dispatch('CartProductCheckChange', { productIds: [productId], checked: checked }).then(res => {
|
||||
this.cartList = res.data || []
|
||||
})
|
||||
},
|
||||
/** 修改购物车商品数量 */
|
||||
handleProductCountChange(productId, number) {
|
||||
this.$store.dispatch('CartProductCountChange', { productIds: [productId], productCount: number }).then(res => {
|
||||
this.cartList = res.data || []
|
||||
})
|
||||
},
|
||||
/** 移除购物车商品 */
|
||||
handleRemoveProduct() {
|
||||
if (this.checkedProduct < 1) {
|
||||
return
|
||||
}
|
||||
const productIds = this.checkedProduct.map(item => {
|
||||
return item.productId
|
||||
})
|
||||
|
||||
uni.showModal({
|
||||
title: '确定要移除选中的商品?',
|
||||
cancelText: '取消',
|
||||
confirmText: '移除',
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
this.$store.dispatch('CartProductCountChange', { productIds: productIds, productCount: 0 }).then(res => {
|
||||
this.cartList = res.data || []
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
//console.log('用户点击取消')
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
/** 购物车提交结算 */
|
||||
handleCheckoutProduct() {
|
||||
if (this.checkedProduct < 1) {
|
||||
return
|
||||
}
|
||||
const checkedProduct = this.checkedProduct.map(item => {
|
||||
return { productId: item.productId, productCount: item.productCount, sellPrice: item.sellPrice }
|
||||
})
|
||||
uni.$u.route('/pages/checkout/checkout', {
|
||||
checkedProduct: JSON.stringify(checkedProduct)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login-tips-box {
|
||||
padding-top: 100rpx;
|
||||
|
||||
.login-tips {
|
||||
@include flex-center;
|
||||
color: #939393;
|
||||
font-size: 24rpx;
|
||||
letter-spacing: 5rpx;
|
||||
}
|
||||
|
||||
.login-link {
|
||||
width: 160rpx;
|
||||
height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
border-radius: 50rpx;
|
||||
border: 1px solid #777;
|
||||
color: #777;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.cart-btn-container {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
.btn-box {
|
||||
background: $custom-bg-color;
|
||||
border-top: $custom-border-style;
|
||||
|
||||
width: 750rpx;
|
||||
@include flex-space-between();
|
||||
height: 100rpx;
|
||||
|
||||
.product-check-info {
|
||||
@include flex-left;
|
||||
|
||||
.check-all-btn {
|
||||
padding: 20rpx;
|
||||
|
||||
.un-check-box {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid #939393;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.info-text {
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.cart-btn-group {
|
||||
@include flex-right();
|
||||
width: 360rpx;
|
||||
padding-right: 10px;
|
||||
|
||||
.btn-gap {
|
||||
width: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,205 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-wrap">
|
||||
<u-search placeholder="搜索" disabled height="32" bgColor="#f2f2f2" margin="0 20rpx" :show-action="false"
|
||||
@click="handleSearchClick"></u-search>
|
||||
</view>
|
||||
|
||||
<!-- 分类内容 -->
|
||||
<view class="category-box">
|
||||
<!-- 左侧导航栏 -->
|
||||
<scroll-view scroll-y="true" class='box-left'>
|
||||
<view class="category-item" v-for="(item, index) in categoryList" :key="item.id">
|
||||
<view class="item-title" :class="{ active: currentIndex === index }" @click="handleCategoryClick(index)">
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 右侧分类内容 -->
|
||||
<scroll-view scroll-y="true" class="box-right">
|
||||
<view class="category-image">
|
||||
<image :showLoading="true" :src="categoryList[currentIndex].picUrl" mode='widthFix' @click="click"></image>
|
||||
</view>
|
||||
|
||||
<view class="sub-category-box" v-for="(item, index) in categoryList[currentIndex].children" :key="item.id">
|
||||
<view class="sub-category-header">
|
||||
<view class="title">{{ item.name }}</view>
|
||||
<view class="more" @click="handleCategory(item, 0)">查看更多</view>
|
||||
</view>
|
||||
|
||||
<view class="sub-category-grid">
|
||||
<u-grid col="3">
|
||||
<u-grid-item v-for="(subItem, subIndex) in item.children" :key="subItem.id">
|
||||
<view class="sub-category-item" @click="handleCategory(item, subIndex)">
|
||||
<u-icon name="photo" :size="80" v-if="subItem.picUrl === null"></u-icon>
|
||||
<image :src="subItem.picUrl" v-if="subItem.picUrl != null" mode='widthFix' />
|
||||
<text class="sub-category-title">{{ subItem.name }}</text>
|
||||
</view>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { categoryListData } from '../../api/category';
|
||||
import { handleTree, convertTree } from '../../utils/tree.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentIndex: 0,
|
||||
categoryList: []
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.handleCategoryList();
|
||||
},
|
||||
methods: {
|
||||
// 点击搜索框
|
||||
handleSearchClick(e) {
|
||||
uni.$u.route('/pages/search/search')
|
||||
},
|
||||
// 点击左侧导航栏
|
||||
handleCategoryClick(index) {
|
||||
if (this.currentIndex !== index) {
|
||||
this.currentIndex = index
|
||||
}
|
||||
},
|
||||
// 获取分类列表并构建树形结构
|
||||
handleCategoryList() {
|
||||
categoryListData().then(res => {
|
||||
this.categoryList = handleTree(res.data, "id", "parentId");
|
||||
})
|
||||
},
|
||||
handleCategory(item, index){
|
||||
// console.log(item)
|
||||
// console.log(index)
|
||||
uni.navigateTo({
|
||||
url:"./product-list?item="+encodeURIComponent(JSON.stringify(item))+"&index="+index
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-wrap {
|
||||
background: #ffffff;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.07);
|
||||
padding: 20rpx 0;
|
||||
width: 100%;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.category-box {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
margin-top: 100rpx;
|
||||
height: calc(100% - 100rpx);
|
||||
|
||||
.box-left {
|
||||
width: 200rpx;
|
||||
padding-top: 5rpx;
|
||||
overflow: scroll;
|
||||
z-index: 2;
|
||||
background-color: #f2f2f2;
|
||||
|
||||
.category-item {
|
||||
line-height: 80rpx;
|
||||
height: 80rpx;
|
||||
text-align: center;
|
||||
color: #777;
|
||||
|
||||
.item-title {
|
||||
font-size: 28rpx;
|
||||
|
||||
&.active {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
color: $u-primary;
|
||||
}
|
||||
|
||||
&.active::before {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
content: "";
|
||||
width: 8rpx;
|
||||
height: 32rpx;
|
||||
top: 25rpx;
|
||||
background: $u-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.box-right {
|
||||
width: 550rpx;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
z-index: 1;
|
||||
|
||||
.category-image {
|
||||
width: 510rpx;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin: 30rpx 20rpx 0;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-category-box {
|
||||
.sub-category-header {
|
||||
@include flex-space-between;
|
||||
padding: 20rpx 20rpx;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 22rpx;
|
||||
color: #939393;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-category-grid {
|
||||
padding: 0 15rpx;
|
||||
|
||||
.sub-category-item {
|
||||
@include flex-center(column);
|
||||
background: #fff;
|
||||
|
||||
image {
|
||||
text-align: center;
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
line-height: 150rpx;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.sub-category-title {
|
||||
margin: 15rpx 0;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,164 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<u-navbar :title="title" :autoBack="true" placeholder="true" titleStyle="font-size: 28rpx">
|
||||
</u-navbar>
|
||||
<view class="context">
|
||||
<!-- 分类列表 -->
|
||||
<!-- TODO @Luowenfeng:不应该展示商品分类;应该是上面一个筛选;之后是【综合】【销量】【价格】的排序 -->
|
||||
<view class="tabs-top">
|
||||
<u-tabs :list="categoryList" @click="changeTabs" :current="current" lineHeight="2" lineWidth="85rpx"
|
||||
itemStyle="padding-left: 15px; padding-right: 15px; height: 85rpx;"></u-tabs>
|
||||
</view>
|
||||
<!-- 商品列表 -->
|
||||
<scroll-view scroll-y="true" class="product-list" enable-flex="true">
|
||||
<view class="flex-box">
|
||||
<block v-for="(item, index) in productList[current]" :key="index">
|
||||
<view class="product-item">
|
||||
<view class="product-image">
|
||||
<image :src="item.picUrls[0]" mode='widthFix' />
|
||||
</view>
|
||||
<view class="product-button">
|
||||
<view class="product-text">{{ item.name }}</view>
|
||||
<view class="product-price-button">
|
||||
<text class="product-price">¥
|
||||
<text class="price-size">{{ towNumber(item.minPrice) }}</text></text>
|
||||
<text class="product-like-count">销量 {{ item.salesCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
productSpuPage
|
||||
} from '../../api/product';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: "",
|
||||
current: 0,
|
||||
categoryList: [],
|
||||
productList: {}
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
const item = JSON.parse(decodeURIComponent(option.item))
|
||||
this.title = item.name
|
||||
this.categoryList = item.children
|
||||
this.handleProductSpu(option.index);
|
||||
},
|
||||
methods: {
|
||||
changeTabs(item) {
|
||||
if (item.index !== this.current) {
|
||||
this.handleProductSpu(item.index)
|
||||
}
|
||||
},
|
||||
handleProductSpu(index) {
|
||||
let param = {}
|
||||
param.categoryId = this.categoryList[index].id
|
||||
console.log(this.categoryList)
|
||||
console.log(index)
|
||||
productSpuPage(param).then(res => {
|
||||
this.productList[index] = res.data.list
|
||||
this.current = index
|
||||
})
|
||||
},
|
||||
towNumber(val) {
|
||||
return (val / 100).toFixed(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.context {
|
||||
width: 100vw;
|
||||
position: fixed;
|
||||
top: 160rpx;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.tabs-top {
|
||||
position: relative;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 85rpx;
|
||||
}
|
||||
|
||||
.product-list {
|
||||
position: relative;
|
||||
background-color: #f2f2f2;
|
||||
height: calc(100vh - 88rpx - 100rpx - var(--status-bar-height));
|
||||
width: 100%;
|
||||
|
||||
.flex-box {
|
||||
width: 730rpx;
|
||||
margin: 0 auto;
|
||||
@include flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: left;
|
||||
|
||||
.product-item {
|
||||
width: 345rpx;
|
||||
height: 450rpx;
|
||||
background-color: #ffffff;
|
||||
margin: 20rpx 10rpx 0;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 20rpx;
|
||||
image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.product-button {
|
||||
width: 330rpx;
|
||||
margin: 15rpx auto 0;
|
||||
|
||||
.product-text {
|
||||
font-size: 25rpx;
|
||||
height: 70rpx;
|
||||
overflow: hidden;
|
||||
-webkit-line-clamp: 2;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.product-price-button {
|
||||
font-size: 20rpx;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.product-price {
|
||||
color: red;
|
||||
|
||||
.price-size {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.product-like-count {
|
||||
font-size: 16rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
}
|
||||
</style>
|
@ -1,219 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 收货地址选择 -->
|
||||
<yd-address-select :address="address"></yd-address-select>
|
||||
|
||||
<!-- 订单商品信息 -->
|
||||
<view class="checkout-goods">
|
||||
<yd-order-goods :goods-list="checkoutList"></yd-order-goods>
|
||||
</view>
|
||||
|
||||
<view class="freight-coupon-box">
|
||||
<vidw class="box-row">
|
||||
<view class="title">运费</view>
|
||||
<yd-text-price class="freight-fee" size="15" :price="freightAmount"></yd-text-price>
|
||||
</vidw>
|
||||
<vidw class="box-row">
|
||||
<view class="coupon-wrap">
|
||||
<view class="coupon-title-tag">
|
||||
<view class="title">优惠券</view>
|
||||
<scroll-view class="coupon-tag-list" scroll-x="true">
|
||||
<view v-for="item in couponList" :key="item.couponId" class="coupon-tag-item">{{ item.couponTag }}</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<yd-text-price class="coupon-fee" color="red" size="15" symbol="-¥" :price="couponAmount"></yd-text-price>
|
||||
</view>
|
||||
<u-icon name="arrow-right"></u-icon>
|
||||
</vidw>
|
||||
</view>
|
||||
|
||||
<!-- 订单备注信息 -->
|
||||
<view class="user-remark-box">
|
||||
<view class="title">订单备注</view>
|
||||
<u--input maxlength="50" border="none" fontSize="14" v-model="remark" placeholder="如您需要请备注"></u--input>
|
||||
</view>
|
||||
|
||||
<view class="cart-btn-container">
|
||||
<view class="order-total-wrap">
|
||||
<view class="order-total-info">
|
||||
<view class="info-text">合计:</view>
|
||||
<view>
|
||||
<yd-text-price color="red" size="15" intSize="20" :price="totalAmount"></yd-text-price>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="cart-btn-group">
|
||||
<u-button style="margin-left: 10px" class="main-btn" type="primary" shape="circle" size="small" text="提交订单" @click="handleSubmitOrder"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
<u-safe-bottom customStyle="background: #ffffff"></u-safe-bottom>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { checkoutCartProduct } from '../../api/order'
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
checkedProduct: [],
|
||||
address: {
|
||||
name: '客户',
|
||||
mobile: '139****6563',
|
||||
area: 'XXX市XXX区',
|
||||
detail: 'XXX街道XXX小区XXX号楼XX-XXX'
|
||||
},
|
||||
checkoutList: [],
|
||||
couponList: [
|
||||
{
|
||||
couponId: 3,
|
||||
couponTag: '6元运费券'
|
||||
}
|
||||
],
|
||||
totalAmount: 0,
|
||||
freightAmount: 6,
|
||||
couponAmount: 6,
|
||||
remark: ''
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
const checkedProduct = e.checkedProduct
|
||||
if (checkedProduct) {
|
||||
this.checkedProduct = JSON.parse(checkedProduct)
|
||||
this.loadCheckoutProductData()
|
||||
} else {
|
||||
uni.$u.toast('请求参数错误')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadCheckoutProductData() {
|
||||
checkoutCartProduct(this.checkedProduct)
|
||||
.then(res => {
|
||||
this.checkoutList = res.data.checkoutList || []
|
||||
this.totalAmount = res.data.totalAmount || 0
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: $custom-bg-color;
|
||||
height: 100vh;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.checkout-goods {
|
||||
background-color: #fff;
|
||||
margin-top: 20rpx;
|
||||
padding: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.freight-coupon-box {
|
||||
background-color: #fff;
|
||||
margin-top: 20rpx;
|
||||
padding: 20rpx 30rpx;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.box-row {
|
||||
@include flex-space-between;
|
||||
padding: 10rpx 0;
|
||||
|
||||
.coupon-wrap {
|
||||
@include flex-space-between;
|
||||
width: 670rpx;
|
||||
|
||||
.coupon-title-tag {
|
||||
@include flex-left;
|
||||
|
||||
.coupon-tag-list {
|
||||
@include flex-left;
|
||||
overflow-x: scroll;
|
||||
width: 360rpx;
|
||||
.coupon-tag-item {
|
||||
display: inline-block;
|
||||
font-size: 22rpx;
|
||||
color: red;
|
||||
border: 1rpx solid red;
|
||||
padding: 1px 6rpx;
|
||||
margin-right: 10rpx;
|
||||
border-radius: 5rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 700;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.freight-fee {
|
||||
margin-right: 50rpx;
|
||||
}
|
||||
|
||||
.coupon-fee {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-remark-box {
|
||||
@include flex-space-between;
|
||||
background-color: #fff;
|
||||
margin-top: 20rpx;
|
||||
padding: 30rpx;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.title {
|
||||
font-weight: 700;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.cart-btn-container {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
.order-total-wrap {
|
||||
background: $custom-bg-color;
|
||||
border-top: $custom-border-style;
|
||||
|
||||
width: 750rpx;
|
||||
@include flex-space-between();
|
||||
height: 100rpx;
|
||||
|
||||
.order-total-info {
|
||||
@include flex-left;
|
||||
.info-text {
|
||||
margin-left: 20rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.cart-btn-group {
|
||||
@include flex-right();
|
||||
width: 360rpx;
|
||||
padding-right: 10px;
|
||||
|
||||
.btn-gap {
|
||||
width: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,157 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="unp-header">
|
||||
<view class="unp-logo">
|
||||
<u-avatar size="80" icon="github-circle-fill" fontSize="80"></u-avatar>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="unp-box">
|
||||
<u--form class="unp-form" labelPosition="left" :model="formData" :rules="rules" ref="form">
|
||||
<u-form-item label="账号" prop="username" borderBottom ref="item-username">
|
||||
<u-input type="text" maxlength="20" v-model="formData.username" clearable placeholder="账号由数字和字母组成" border="none" @change="handleUsernameChange"></u-input>
|
||||
</u-form-item>
|
||||
|
||||
<u-gap height="20"></u-gap>
|
||||
|
||||
<u-form-item label="验证码" prop="code" labelWidth="80" borderBottom>
|
||||
<u--input type="number" maxlength="6" v-model="formData.code" border="none" placeholder="请填写验证码"></u--input>
|
||||
<u-button slot="right" @tap="getCode" :text="tips" type="success" size="mini" :disabled="codeDisabled"></u-button>
|
||||
<u-code ref="uCode" @change="codeChange" seconds="60" @start="codeDisabled = true" @end="codeDisabled = false"></u-code>
|
||||
</u-form-item>
|
||||
|
||||
<u-gap height="20"></u-gap>
|
||||
|
||||
<u-form-item label="密码" prop="password" borderBottom ref="item-password">
|
||||
<u-input :type="inputType" maxlength="20" v-model="formData.password" placeholder="新密码由数字、字母和符号组成" border="none" @change="handlePasswordChange">
|
||||
<template slot="suffix">
|
||||
<u-icon v-if="inputType === 'password'" size="20" color="#666666" name="eye-fill" @click="inputType = 'text'"></u-icon>
|
||||
<u-icon v-if="inputType === 'text'" size="20" color="#666666" name="eye-off" @click="inputType = 'password'"></u-icon>
|
||||
</template>
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
|
||||
<view class="lk-group">
|
||||
<!-- 占位 -->
|
||||
</view>
|
||||
|
||||
<u-button type="error" text="重置密码" customStyle="margin-top: 50px" @click="handleSubmit"></u-button>
|
||||
|
||||
<u-gap height="20"></u-gap>
|
||||
<u-button type="info" text="返回" @click="navigateBack()"></u-button>
|
||||
</u--form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
codeDisabled: false,
|
||||
tips: '',
|
||||
inputType: 'password',
|
||||
formData: {
|
||||
username: '',
|
||||
code: '',
|
||||
password: ''
|
||||
},
|
||||
rules: {
|
||||
username: {
|
||||
type: 'string',
|
||||
max: 20,
|
||||
required: true,
|
||||
message: '请输入您的账号',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
code: {
|
||||
type: 'number',
|
||||
max: 6,
|
||||
required: true,
|
||||
message: '请输入验证码',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
max: 20,
|
||||
required: true,
|
||||
message: '请输入您的新密码',
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
handleUsernameChange(e) {
|
||||
let str = uni.$u.trim(e, 'all')
|
||||
this.$nextTick(() => {
|
||||
this.formData.username = str
|
||||
})
|
||||
},
|
||||
handlePasswordChange(e) {
|
||||
let str = uni.$u.trim(e, 'all')
|
||||
this.$nextTick(() => {
|
||||
this.formData.password = str
|
||||
})
|
||||
},
|
||||
codeChange(text) {
|
||||
this.tips = text
|
||||
},
|
||||
getCode() {
|
||||
if (this.$refs.uCode.canGetCode) {
|
||||
// 模拟向后端请求验证码
|
||||
uni.showLoading({
|
||||
title: '正在获取验证码'
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
// 这里此提示会被this.start()方法中的提示覆盖
|
||||
uni.$u.toast('验证码已发送')
|
||||
// 通知验证码组件内部开始倒计时
|
||||
this.$refs.uCode.start()
|
||||
}, 2000)
|
||||
} else {
|
||||
uni.$u.toast('倒计时结束后再发送')
|
||||
}
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.form
|
||||
.validate()
|
||||
.then(res => {
|
||||
uni.$u.toast('点击了重置密码')
|
||||
})
|
||||
},
|
||||
navigateBack() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.unp-header {
|
||||
height: 400rpx;
|
||||
@include flex-center;
|
||||
.unp-logo {
|
||||
@include flex-center;
|
||||
}
|
||||
}
|
||||
|
||||
.unp-box {
|
||||
@include flex-center(column);
|
||||
.unp-form {
|
||||
width: 560rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.lk-group {
|
||||
height: 40rpx;
|
||||
margin-top: 40rpx;
|
||||
@include flex-space-between;
|
||||
font-size: 12rpx;
|
||||
|
||||
color: $u-primary;
|
||||
text-decoration: $u-primary;
|
||||
}
|
||||
</style>
|
@ -1,149 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!--搜索栏-->
|
||||
<u-sticky style="top: 0" offset-top="0">
|
||||
<view class="search-wrap">
|
||||
<u-search placeholder="搜索" disabled height="32" :show-action="false" @click="handleSearchClick"></u-search>
|
||||
</view>
|
||||
</u-sticky>
|
||||
|
||||
<!--轮播图-->
|
||||
<yd-banner :banner-list="bannerList"></yd-banner>
|
||||
|
||||
<u-gap height="20px"></u-gap>
|
||||
|
||||
<!--宫格菜单按钮-->
|
||||
<u-grid :border="false" col="4">
|
||||
<u-grid-item v-for="(item, index) in menuList" :key="index">
|
||||
<u-icon :name="item.icon" :size="40"></u-icon>
|
||||
<text class="grid-title">{{ item.title }}</text>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
|
||||
<u-gap height="15px"></u-gap>
|
||||
|
||||
<!--消息滚动栏-->
|
||||
<u-notice-bar style="padding: 13px 12px" :text="noticeList" mode="link" direction="column" @click="click"></u-notice-bar>
|
||||
|
||||
<!--商品展示栏-->
|
||||
<yd-product-box :product-list="productList" :title="'每日上新'" show-type="normal"></yd-product-box>
|
||||
<yd-product-box :product-list="productList" :title="'热卖商品'" show-type="half"></yd-product-box>
|
||||
<yd-product-more :product-list="productList" :more-status="moreStatus"></yd-product-more>
|
||||
|
||||
<u-gap height="5px"></u-gap>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getBannerData, getNoticeData } from '../../api/index'
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
bannerList: [
|
||||
{
|
||||
id: 1,
|
||||
title: '山不在高,有仙则名',
|
||||
url: 'https://cdn.uviewui.com/uview/swiper/swiper1.png'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '水不在深,有龙则灵',
|
||||
url: 'https://cdn.uviewui.com/uview/swiper/swiper2.png'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '斯是陋室,惟吾德馨',
|
||||
url: 'https://cdn.uviewui.com/uview/swiper/swiper3.png'
|
||||
}
|
||||
],
|
||||
menuList: [
|
||||
{ icon: 'gift', title: '热门推荐' },
|
||||
{ icon: 'star', title: '收藏转发' },
|
||||
{ icon: 'thumb-up', title: '点赞投币' },
|
||||
{ icon: 'heart', title: '感谢支持' }
|
||||
],
|
||||
noticeList: ['寒雨连江夜入吴', '平明送客楚山孤', '洛阳亲友如相问', '一片冰心在玉壶'],
|
||||
productList: [
|
||||
{
|
||||
id: 1,
|
||||
image: 'https://cdn.uviewui.com/uview/album/1.jpg',
|
||||
title: '山不在高,有仙则名。水不在深,有龙则灵。斯是陋室,惟吾德馨。',
|
||||
desc: '山不在于高,有了神仙就会有名气。水不在于深,有了龙就会有灵气。这是简陋的房子,只是我品德好就感觉不到简陋了。',
|
||||
price: '13.00'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
image: 'https://cdn.uviewui.com/uview/album/2.jpg',
|
||||
title: '商品222',
|
||||
desc: '',
|
||||
price: '23.00'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
image: 'https://cdn.uviewui.com/uview/album/3.jpg',
|
||||
title: '商品333',
|
||||
desc: '商品描述信息2',
|
||||
price: '33.00'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
image: 'https://cdn.uviewui.com/uview/album/4.jpg',
|
||||
title: '商品444',
|
||||
desc: '商品描述信息4',
|
||||
price: '43.00'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
image: 'https://cdn.uviewui.com/uview/album/5.jpg',
|
||||
title: '商品555',
|
||||
desc: '商品描述信息5',
|
||||
price: '53.00'
|
||||
}
|
||||
],
|
||||
moreStatus: 'nomore'
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.loadBannerData()
|
||||
this.loadNoticeData()
|
||||
},
|
||||
methods: {
|
||||
loadBannerData() {
|
||||
getBannerData().then(res => {
|
||||
this.bannerList = res.data
|
||||
})
|
||||
},
|
||||
loadNoticeData() {
|
||||
getNoticeData().then(res => {
|
||||
this.noticeList = res.data
|
||||
})
|
||||
},
|
||||
handleSearchClick(e) {
|
||||
uni.$u.route('/pages/search/search')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
noticeTextList() {
|
||||
return this.noticeList.map(item => {
|
||||
if (item.title) {
|
||||
return item.title
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-wrap {
|
||||
background: $custom-bg-color;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.grid-title {
|
||||
line-height: 50rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
</style>
|
@ -1,197 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="auth-header">
|
||||
<view class="auth-logo">
|
||||
<u-avatar size="100" icon="github-circle-fill" fontSize="100"></u-avatar>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="auth-box">
|
||||
<!-- 登录方式选择 -->
|
||||
<view class="mode-section">
|
||||
<u-subsection class="subsection" mode="subsection" fontSize="15" :list="loginModeList" :current="currentModeIndex" @change="handleModeChange"></u-subsection>
|
||||
</view>
|
||||
<u-gap height="40"></u-gap>
|
||||
|
||||
<!-- 登录表单 -->
|
||||
<u--form labelPosition="left" :model="formData" :rules="rules" ref="form">
|
||||
<u-form-item label="手机号" prop="mobile" labelWidth="60" borderBottom ref="item-mobile">
|
||||
<u-input type="number" maxlength="11" v-model="formData.mobile" clearable placeholder="请填写手机号" border="none"></u-input>
|
||||
</u-form-item>
|
||||
|
||||
<u-gap height="20"></u-gap>
|
||||
|
||||
<u-form-item v-if="currentModeIndex === 0" label="密码" prop="password" labelWidth="60" borderBottom ref="item-password">
|
||||
<u-input :type="inputType" maxlength="16" v-model="formData.password" placeholder="请填写密码" border="none">
|
||||
<template slot="suffix">
|
||||
<u-icon v-if="inputType === 'password'" size="20" color="#666666" name="eye-fill" @click="inputType = 'text'"></u-icon>
|
||||
<u-icon v-if="inputType === 'text'" size="20" color="#666666" name="eye-off" @click="inputType = 'password'"></u-icon>
|
||||
</template>
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item v-else label="验证码" prop="code" labelWidth="60" borderBottom>
|
||||
<u--input type="number" maxlength="4" v-model="formData.code" border="none" placeholder="请填写验证码"></u--input>
|
||||
<u-button slot="right" @tap="getCode" :text="codeTips" type="success" size="mini" :disabled="codeDisabled"></u-button>
|
||||
<u-code ref="uCode" @change="codeChange" seconds="60" @start="codeDisabled = true" @end="codeDisabled = false"></u-code>
|
||||
</u-form-item>
|
||||
|
||||
<view class="btn-group">
|
||||
<u-button class="auth-btn" type="primary" customStyle="margin-top: 50px" @click="handleSubmit">立即登录</u-button>
|
||||
</view>
|
||||
</u--form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { sendSmsCode } from '../../api/auth'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentModeIndex: 0,
|
||||
loginModeList: ['密码登录', '验证码登录'],
|
||||
inputType: 'password',
|
||||
codeDisabled: false,
|
||||
codeTips: '',
|
||||
formData: {
|
||||
mobile: '',
|
||||
password: '',
|
||||
code: ''
|
||||
},
|
||||
rules: {
|
||||
mobile: [
|
||||
{
|
||||
type: 'integer',
|
||||
required: true,
|
||||
message: '请填写手机号',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// uni.$u.test.mobile()就是返回true或者false的
|
||||
return uni.$u.test.mobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
password: {
|
||||
type: 'string',
|
||||
min: 4,
|
||||
max: 16,
|
||||
required: true,
|
||||
message: '密码长度4-16位密码',
|
||||
trigger: ['blur', 'change']
|
||||
},
|
||||
code: {
|
||||
type: 'integer',
|
||||
len: 4,
|
||||
required: true,
|
||||
message: '请填写4位验证码',
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
onReady() {
|
||||
// 如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则
|
||||
this.$refs.form.setRules(this.rules)
|
||||
},
|
||||
methods: {
|
||||
handleModeChange(index) {
|
||||
if (index !== this.currentModeIndex) {
|
||||
this.currentModeIndex = index
|
||||
this.$refs.form.clearValidate()
|
||||
}
|
||||
},
|
||||
codeChange(text) {
|
||||
this.codeTips = text
|
||||
},
|
||||
getCode() {
|
||||
const mobile = this.formData.mobile
|
||||
if (!mobile) {
|
||||
uni.$u.toast('请填写手机号')
|
||||
} else if (!uni.$u.test.mobile(mobile)) {
|
||||
uni.$u.toast('手机号格式不正确')
|
||||
} else if (this.$refs.uCode.canGetCode) {
|
||||
// 模拟向后端请求验证码
|
||||
uni.showLoading({
|
||||
title: '正在获取验证码'
|
||||
})
|
||||
|
||||
//scene:1登陆获取验证码场景
|
||||
sendSmsCode({ mobile: mobile, scene: 1 }).then(res => {
|
||||
//console.log(res)
|
||||
uni.hideLoading()
|
||||
uni.$u.toast('验证码已发送')
|
||||
// 通知验证码组件内部开始倒计时
|
||||
this.$refs.uCode.start()
|
||||
})
|
||||
} else {
|
||||
uni.$u.toast('倒计时结束后再发送')
|
||||
}
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate().then(res => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: res => {
|
||||
let data = this.formData
|
||||
data.socialType = 34 //WECHAT_MINI_APP 先指定固定值
|
||||
data.socialCode = res.code
|
||||
data.socialState = Math.random() // 该参数没有实际意义暂时传随机数
|
||||
this.mobileLogin(data)
|
||||
},
|
||||
fail: res => {
|
||||
this.mobileLogin(this.formData)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
mobileLogin(data){
|
||||
this.$store.dispatch('Login', { type: this.currentModeIndex, data: data }).then(res => {
|
||||
uni.$u.toast('登录成功')
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: '/pages/user/user'
|
||||
})
|
||||
}, 300)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.auth-header {
|
||||
height: 400rpx;
|
||||
@include flex-center;
|
||||
.auth-logo {
|
||||
@include flex-center(column);
|
||||
}
|
||||
}
|
||||
|
||||
.auth-box {
|
||||
@include flex-center(column);
|
||||
|
||||
.mode-section {
|
||||
width: 600rpx;
|
||||
.subsection {
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
.btn-group {
|
||||
width: 600rpx;
|
||||
.auth-btn {
|
||||
height: 90rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,117 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="auth-header">
|
||||
<view class="auth-logo">
|
||||
<u-avatar size="100" icon="github-circle-fill" fontSize="100"></u-avatar>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="auth-box">
|
||||
<view class="btn-group">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<u-button class="auth-btn" open-type="getPhoneNumber" type="primary" @getphonenumber="getPhoneNumber">一键登录</u-button>
|
||||
<navigator class="reg-login-link" url="/pages/login/mobile" open-type="navigate" hover-class="none">手机号登录/注册 ></navigator>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<u-button type="primary" text="手机号登录/注册" @click="handleJump"></u-button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="auth-footer">
|
||||
<view>登录即表示同意<text class="lk-text">《用户协议》</text> 和 <text class="lk-text">《隐私政策》</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
onLoad() {},
|
||||
onReady() {},
|
||||
methods: {
|
||||
getPhoneNumber(e) {
|
||||
let phoneCode = e.detail.code
|
||||
if (!e.detail.code) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: '您已拒绝获取绑定手机号登录授权,可以使用其他手机号验证登录',
|
||||
cancelText: '知道了',
|
||||
confirmText: '验证登录',
|
||||
confirmColor: '#3C9CFFFF',
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
uni.$u.route('/pages/login/mobile')
|
||||
} else if (res.cancel) {
|
||||
//console.log('用户点击取消')
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: res => {
|
||||
this.$store.dispatch('Login', { type: 2, data: { phoneCode: phoneCode, loginCode: res.code } }).then(res => {
|
||||
uni.$u.toast('登录成功')
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: '/pages/user/user'
|
||||
})
|
||||
}, 300)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
handleJump() {
|
||||
uni.$u.route('/pages/login/mobile')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
height: calc(100vh - 70px);
|
||||
@include flex-space-between(column);
|
||||
}
|
||||
|
||||
.auth-header {
|
||||
flex: 2;
|
||||
@include flex-center;
|
||||
.auth-logo {
|
||||
@include flex-center(column);
|
||||
}
|
||||
}
|
||||
|
||||
.auth-box {
|
||||
@include flex-center(column);
|
||||
|
||||
.btn-group {
|
||||
width: 600rpx;
|
||||
margin-bottom: 200rpx;
|
||||
.auth-btn {
|
||||
height: 90rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.reg-login-link {
|
||||
margin-top: 32rpx;
|
||||
text-align: center;
|
||||
color: #636363;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.auth-footer {
|
||||
font-size: 26rpx;
|
||||
color: #939393;
|
||||
.lk-text {
|
||||
color: $u-primary;
|
||||
text-decoration: $u-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="confirm-con">
|
||||
<!-- TODO 收货地址 -->
|
||||
<navigator url="/pages/address/list?type=1">
|
||||
<yd-address-select :address="address"></yd-address-select>
|
||||
</navigator>
|
||||
|
||||
<!-- TODO 商品信息 -->
|
||||
<view class="goods contain">
|
||||
<yd-order-product :productList="productList"></yd-order-product>
|
||||
<view class="item row-between">
|
||||
<view>买家留言</view>
|
||||
<u-input v-model="remark" :clearable="false"
|
||||
placeholder="请添加备注(150 字以内)"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- TODO 优惠劵 -->
|
||||
|
||||
<!-- TODO 价格信息 -->
|
||||
|
||||
<!-- TODO 底部:提交订单 -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
address: { // 选中的收货地址
|
||||
name: 'test',
|
||||
mobile: '15601691300',
|
||||
area: '奥特曼奥特曼'
|
||||
},
|
||||
productList: [{ // 购买的商品列表
|
||||
coverUrl: '',
|
||||
productTitle: '奥特曼',
|
||||
sellPrice: 1024,
|
||||
productCount: 2048,
|
||||
totalPrice: 1024
|
||||
}],
|
||||
remark: '', // 备注
|
||||
x
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.confirm-con {
|
||||
overflow: hidden;
|
||||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.contain {
|
||||
border-radius: 14rpx;
|
||||
margin: 20rpx 20rpx 0;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
@ -1,252 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<viwe class="detail-header">
|
||||
<view class="order-status">{{ order.status | getStatusName }}</view>
|
||||
</viwe>
|
||||
|
||||
<view class="order-product">
|
||||
<view class="order-item" v-for="item in order.items" :key="item.id">
|
||||
<image class="product-image" :src="item.picUrl"></image>
|
||||
<view class="item-info">
|
||||
<view class="info-text">
|
||||
<u--text :lines="1" size="15px" color="#333333" :text="item.spuName"></u--text>
|
||||
<u-gap height="10"></u-gap>
|
||||
<yd-text-price class="product-price" size="13" intSize="14" :price="item.originalUnitPrice"></yd-text-price>
|
||||
</view>
|
||||
<view class="price-number-box">
|
||||
<view class="number-box">
|
||||
<view class="product-number">共 {{ item.count }} 件</view>
|
||||
小计:
|
||||
</view>
|
||||
<view class="number-box" @click.stop>
|
||||
<yd-text-price size="13" intSize="16" :price="item.originalPrice"></yd-text-price>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="order.no" >
|
||||
<view v-if="order.no" class="base-info">
|
||||
<view class="info-item">
|
||||
<view class="item-name">订单编号:</view>
|
||||
<view class="item-value">{{ order.no }}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="item-name">下单时间:</view>
|
||||
<view class="item-value">{{ order.createTime }}</view>
|
||||
</view>
|
||||
<view v-if="order.payOrderId" class="info-item">
|
||||
<view class="item-name">支付方式:</view>
|
||||
<view class="item-value">{{ order.payOrderId }}</view>
|
||||
</view>
|
||||
<view v-if="order.payTime" class="info-item">
|
||||
<view class="item-name">支付时间:</view>
|
||||
<view class="item-value">{{ order.payTime }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="delivery-info">
|
||||
<view class="info-item">
|
||||
<view class="item-name">收货地址:</view>
|
||||
<view class="item-value">{{ order.receiverAreaName + order.receiverDetailAddress + order.receiverDetailAddress + order.receiverDetailAddress }}</view>
|
||||
</view>
|
||||
<view v-if="order.receiverName" class="info-item">
|
||||
<view class="item-name">收货人:</view>
|
||||
<view class="item-value">{{ order.receiverName }}</view>
|
||||
</view>
|
||||
<view v-if="order.receiverMobile" class="info-item">
|
||||
<view class="item-name">联系电话:</view>
|
||||
<view class="item-value">{{ order.receiverMobile }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="delivery-info">
|
||||
<view class="info-item">
|
||||
<view class="item-name">商品总额:</view>
|
||||
<yd-text-price class="product-price" size="13" intSize="16" :price="order.originalPrice"></yd-text-price>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="item-name">运费:</view>
|
||||
<yd-text-price class="product-price" size="13" intSize="16" :price="order.deliveryPrice"></yd-text-price>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="item-name">优惠:</view>
|
||||
<yd-text-price class="product-price" size="13" intSize="16" symbol="-¥" :price="order.discountPrice"></yd-text-price>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="item-name">订单金额:</view>
|
||||
<yd-text-price class="product-price" size="15" intSize="20" :price="order.orderPrice"></yd-text-price>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getOrderDetail } from '../../api/order'
|
||||
import orderStatus from '@/common/orderStatus'
|
||||
|
||||
export default {
|
||||
name: 'orderDetail',
|
||||
filters: {
|
||||
getStatusName(status) {
|
||||
return orderStatus[status + ''].name
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
orderId: undefined,
|
||||
order: {}
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
this.orderId = e.orderId
|
||||
if (!this.orderId) {
|
||||
uni.$u.toast('请求参数错误')
|
||||
} else {
|
||||
this.loadOrderDetailData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadOrderDetailData() {
|
||||
getOrderDetail({ id: this.orderId })
|
||||
.then(res => {
|
||||
this.order = res.data || {}
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #f3f3f3;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
@include flex-center();
|
||||
background-color: $custom-bg-color;
|
||||
padding: 10rpx 0;
|
||||
border-radius: 0 0 20rpx 20rpx;
|
||||
}
|
||||
|
||||
.order-product {
|
||||
background-color: $custom-bg-color;
|
||||
border-radius: 20rpx;
|
||||
margin: 20rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
.order-item {
|
||||
background: #ffffff;
|
||||
@include flex-space-between;
|
||||
padding: 10rpx 0 10rpx 5rpx;
|
||||
|
||||
.product-check {
|
||||
padding: 20rpx;
|
||||
|
||||
.un-check-box {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid #939393;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
flex: 1;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.info-text {
|
||||
padding-bottom: 10rpx;
|
||||
|
||||
.product-price {
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.price-number-box {
|
||||
@include flex-space-between;
|
||||
|
||||
.number-box {
|
||||
font-size: 24rpx;
|
||||
|
||||
.product-number {
|
||||
width: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.number-box {
|
||||
height: 60rpx;
|
||||
@include flex-center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.base-info {
|
||||
background-color: $custom-bg-color;
|
||||
border-radius: 20rpx;
|
||||
margin: 20rpx;
|
||||
padding: 20rpx;
|
||||
.info-item {
|
||||
@include flex-left();
|
||||
padding: 10rpx 0;
|
||||
.item-name {
|
||||
color: #999;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
.item-value {
|
||||
color: #333;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.delivery-info {
|
||||
background-color: $custom-bg-color;
|
||||
border-radius: 20rpx;
|
||||
margin: 20rpx;
|
||||
padding: 20rpx;
|
||||
.info-item {
|
||||
@include flex-left();
|
||||
padding: 10rpx 0;
|
||||
.item-name {
|
||||
color: #999;
|
||||
font-size: 26rpx;
|
||||
width: 260rpx;
|
||||
}
|
||||
.item-value {
|
||||
color: #333;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.delivery-info {
|
||||
background-color: $custom-bg-color;
|
||||
border-radius: 20rpx;
|
||||
margin: 20rpx;
|
||||
padding: 20rpx;
|
||||
.info-item {
|
||||
@include flex-space-between();
|
||||
padding: 10rpx 0;
|
||||
.item-name {
|
||||
color: #999;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -1,195 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<u-sticky style="top: 0" offset-top="0">
|
||||
<u-tabs :list="tabArray" :current="tabIndex" itemStyle="padding-left: 18px; padding-right: 18px; height: 36px;" @change="handleStatusChange"></u-tabs>
|
||||
</u-sticky>
|
||||
<view class="order-list">
|
||||
<view v-for="order in orderList" :key="order.no" class="order-item">
|
||||
<view class="order-header">
|
||||
<view class="order-no">订单编号:{{ order.no }}</view>
|
||||
<view class="order-status">{{ order.status | getStatusName }}</view>
|
||||
</view>
|
||||
|
||||
<view v-if="order.items.length === 1" class="order-single-item" @click="handleOrderClick(order.id)">
|
||||
<view class="item-wrap" v-for="item in order.items" :key="item.id">
|
||||
<view class="item-info">
|
||||
<image class="item-cover" :src="item.picUrl"></image>
|
||||
<u--text :lines="2" size="15px" color="#333333" :text="item.spuName"></u--text>
|
||||
</view>
|
||||
<view class="item-count">共{{ item.count }}件</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="order-multi-item" @click="handleOrderClick(order.id)">
|
||||
<u-scroll-list :indicator="false">
|
||||
<view class="item-wrap" v-for="item in order.items" :key="item.id">
|
||||
<image class="item-image" :src="item.picUrl"></image>
|
||||
</view>
|
||||
</u-scroll-list>
|
||||
<view class="product-count">共{{ order.productCount }}件</view>
|
||||
</view>
|
||||
|
||||
<view class="order-btn-group">
|
||||
<view class="order-btn">再次购买</view>
|
||||
<view class="order-btn">其他操作</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getOrderPage } from '../../api/order'
|
||||
import orderStatus from '@/common/orderStatus'
|
||||
|
||||
export default {
|
||||
name: 'orderList',
|
||||
filters: {
|
||||
getStatusName(status) {
|
||||
return orderStatus[status + ''].name
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageNo: 1,
|
||||
tabIndex: 0,
|
||||
orderList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tabArray() {
|
||||
let tabArray = [{ name: '全部', status: 'all' }]
|
||||
for (let status in orderStatus) {
|
||||
if (status !== '40') {
|
||||
tabArray.push({ name: orderStatus[status].name, status: status })
|
||||
}
|
||||
}
|
||||
return tabArray
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
const status = e.status
|
||||
if (status !== undefined) {
|
||||
this.tabArray.forEach((item, index) => {
|
||||
if (item.status === status) {
|
||||
this.tabIndex = index
|
||||
}
|
||||
})
|
||||
}
|
||||
this.loadOrderPageData()
|
||||
},
|
||||
methods: {
|
||||
handleStatusChange({ index }) {
|
||||
this.tabIndex = index
|
||||
this.loadOrderPageData()
|
||||
},
|
||||
loadOrderPageData() {
|
||||
let params = { pageNo: this.pageNo }
|
||||
const status = this.tabArray[this.tabIndex].status
|
||||
if (status !== 'all') {
|
||||
params.orderStatus = status
|
||||
}
|
||||
getOrderPage(params)
|
||||
.then(res => {
|
||||
this.orderList = res.data.list || []
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
handleOrderClick(orderId) {
|
||||
uni.$u.route('/pages/order/detail', {
|
||||
orderId: orderId
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order-list {
|
||||
background-color: #f3f3f3;
|
||||
|
||||
.order-item {
|
||||
padding: 20rpx;
|
||||
background-color: #ffffff;
|
||||
border-bottom: $custom-border-style;
|
||||
|
||||
.order-header {
|
||||
@include flex-space-between;
|
||||
height: 80rpx;
|
||||
|
||||
.order-no {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.order-status {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.order-single-item {
|
||||
.item-wrap {
|
||||
@include flex-space-between();
|
||||
|
||||
.item-info {
|
||||
@include flex-left();
|
||||
|
||||
.item-cover {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.item-count {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
width: 120rpx;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order-multi-item {
|
||||
@include flex-space-between();
|
||||
|
||||
.item-wrap {
|
||||
margin-right: 20rpx;
|
||||
|
||||
.item-image {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.product-count {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
width: 120rpx;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.order-btn-group {
|
||||
margin-top: 10rpx;
|
||||
@include flex-right();
|
||||
|
||||
.order-btn {
|
||||
width: 120rpx;
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
border-radius: 36rpx;
|
||||
border: 1px solid #777;
|
||||
color: #777;
|
||||
font-size: 22rpx;
|
||||
text-align: center;
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,576 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 商品轮播图 -->
|
||||
<u-swiper :list="spu.picUrls" @change="e => (currentNum = e.current)" :autoplay="false"
|
||||
height="750rpx" radius="0" indicatorStyle="right: 20px">
|
||||
<view slot="indicator" class="indicator-num">
|
||||
<text class="indicator-num__text">{{ currentNum + 1 }}/{{ spu.picUrls.length }}</text>
|
||||
</view>
|
||||
</u-swiper>
|
||||
|
||||
<view class="product-box">
|
||||
<!-- TODO @Sfmind:样式讨论,要不要改成类似 likeshop 的样子?第一栏:价格 + 分享;第二栏:商品名;第三栏:库存、销量、浏览量 -->
|
||||
<view class="prod-info">
|
||||
<view class="info-text">
|
||||
<u--text :lines="2" size="14px" color="#333333" :text="spu.name"></u--text>
|
||||
</view>
|
||||
<view class="price-and-cart">
|
||||
<!-- TODO @Sfmind:custom-text-price 会报错 -->
|
||||
<custom-text-price color="red" size="16" intSize="26" :price="spu.minPrice"></custom-text-price>
|
||||
</view>
|
||||
</view>
|
||||
<view class="prod-favor">
|
||||
<u-icon name="star" color="#2979ff" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-gap height="8" bgColor="#f3f3f3"></u-gap>
|
||||
<view class="row-box">
|
||||
<view class="row-left">规格</view>
|
||||
<view class="row-right" @click="skuPopup = true">
|
||||
<view class="row-content">
|
||||
<view class="sku-box">
|
||||
<view v-if="spu.skus.length > 0" class="sku-item">
|
||||
<view class="sku-desc">{{ spu.skus[currentSkuIndex].desc }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row-more">
|
||||
<u-icon name="more-dot-fill" color="#939393" size="14"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品 SKU 选择弹窗 -->
|
||||
<u-popup :show="skuPopup" :round="10" :closeable="true" :closeOnClickOverlay="false" @close="skuPopup = false">
|
||||
<view class="sku-popup-slot">
|
||||
<view class="current-sku-info">
|
||||
<u--image class="current-sku-img" :showLoading="true" :src="spu.skus[currentSkuIndex].picUrl"
|
||||
width="120rpx" height="120rpx"></u--image>
|
||||
<view class="current-sku-desc">
|
||||
<!-- TODO @Sfmind:name 这里的选择规格值的拼接 -->
|
||||
<view class="name">{{ spu.skus[currentSkuIndex].desc }}</view>
|
||||
<custom-text-price color="red" size="12" intSize="18" :price="spu.skus[currentSkuIndex].price"></custom-text-price>
|
||||
<view class="current-sku-stock">库存: {{ 1 }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="sku-selection">
|
||||
<!-- TODO @Sfmind:name 这里是规格的具体选项 -->
|
||||
<view class="sku-item" :class="{ active: currentSkuIndex === index }" v-for="(item, index) in spu.skus"
|
||||
:key="item.id" @click="handleSkuItemClick(index)">{{ item.desc }}</view>
|
||||
</view>
|
||||
<view class="sku-num-box">
|
||||
<view class="text">选择数量</view>
|
||||
<u-number-box integer></u-number-box>
|
||||
</view>
|
||||
<view class="sku-btn-group">
|
||||
<view class="btn-item-main">
|
||||
<u-button type="warning" shape="circle" size="small" text="加入购物车"></u-button>
|
||||
</view>
|
||||
<view class="btn-item-main">
|
||||
<u-button type="error" shape="circle" size="small" text="立即购买"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<u-gap height="8" bgColor="#f3f3f3"></u-gap>
|
||||
<view class="row-box">
|
||||
<view class="row-left">促销</view>
|
||||
<view class="row-right" v-if="promotionList.length > 0" @click="promotionPopup = true">
|
||||
<view class="row-content">
|
||||
<view class="prom-box">
|
||||
<view class="prom-item">
|
||||
<view class="prom-title">{{ promotionList[0].title }}</view>
|
||||
<text class="prom-desc">{{ promotionList[0].desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row-more">
|
||||
<u-icon name="more-dot-fill" color="#939393" size="14"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 促销信息弹窗 -->
|
||||
<u-popup :show="promotionPopup" :round="10" :closeable="true" :closeOnClickOverlay="false" @close="promotionPopup = false">
|
||||
<view class="prom-popup-slot">
|
||||
<view class="prom-info">促销信息</view>
|
||||
<view class="prom-list">
|
||||
<view v-for="(item, index) in promotionList" :key="index.id" class="prom-item">
|
||||
<view class="prom-title">{{ item.title }}</view>
|
||||
<text class="prom-desc">{{ item.desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<u-gap height="8" bgColor="#f3f3f3"></u-gap>
|
||||
<view class="row-box">
|
||||
<view class="row-left">领券</view>
|
||||
<view class="row-right" @click="handleCouponClick">
|
||||
<view class="row-content">
|
||||
<view class="coupon-box">
|
||||
<view v-if="couponList.length > 0" class="coupon-list">
|
||||
<view v-for="(item, index) in couponList" :key="item.id" class="coupon-item">
|
||||
<view v-if="index < 2" class="coupon-desc">{{ item.desc }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="coupon-total">共 {{ couponList.length }} 张</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row-more">
|
||||
<u-icon name="more-dot-fill" color="#939393" size="14"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-gap height="8" bgColor="#f3f3f3"></u-gap>
|
||||
<view class="evaluation-box-wrap">
|
||||
<view class="evaluation-box">
|
||||
<view class="evaluation-title">评价</view>
|
||||
<view class="evaluation-info">
|
||||
<view class="evan-type-list">
|
||||
<view class="evan-type-item" :class="{ active: currentEvanIndex === index }" v-for="(item, index) in evanTypeList" :key="item.id" @click="handleEvanTypeClick(index)"> {{ item.name }}({{ item.count }}) </view>
|
||||
</view>
|
||||
<view class="comment-empty" v-if="true">
|
||||
<u-empty mode="comment" width="350rpx" height="350rpx" icon="/static/images/empty/comment.png"></u-empty>
|
||||
</view>
|
||||
<view v-else class="comment-list" style="min-height: 50px"> </view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- TODO @Sfmind:缺个商品详情 -->
|
||||
|
||||
<view class="fixed-btn-box">
|
||||
<view class="btn-group">
|
||||
<navigator class="btn-item" url="/pages/index/index" open-type="switchTab" hover-class="none">
|
||||
<u-icon name="home" :size="24"></u-icon>
|
||||
<view class="btn-text">首页</view>
|
||||
</navigator>
|
||||
<navigator class="btn-item" url="/pages/xxx/xxx" open-type="navigate" hover-class="none">
|
||||
<u-icon name="server-man" :size="24"></u-icon>
|
||||
<view class="btn-text">客服</view>
|
||||
</navigator>
|
||||
<!-- TODO @Sfmind:改成收藏 -->
|
||||
<navigator class="btn-item" url="/pages/cart/cart" open-type="switchTab" hover-class="none">
|
||||
<u-icon name="star" :size="24"></u-icon>
|
||||
<view class="btn-text">收藏</view>
|
||||
</navigator>
|
||||
<view class="btn-item-main">
|
||||
<u-button type="warning" shape="circle" size="small" text="加入购物车"></u-button>
|
||||
</view>
|
||||
<view class="btn-item-main">
|
||||
<u-button type="error" color="#ea322b" shape="circle" size="small" text="立即购买"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
<u-safe-bottom customStyle="background: #ffffff"></u-safe-bottom>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getSpuDetail } from '../../api/product';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
current: 0,
|
||||
currentNum: 0,
|
||||
currentSkuIndex: 0,
|
||||
skuPopup: false,
|
||||
spu: {
|
||||
id: '',
|
||||
picUrls: [],
|
||||
minPrice: '13.00',
|
||||
sku: [
|
||||
{
|
||||
id: 0,
|
||||
picUrl: 'https://cdn.uviewui.com/uview/album/1.jpg',
|
||||
price: 13.0,
|
||||
desc: '山不在高,有仙则名。'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
picUrl: 'https://cdn.uviewui.com/uview/album/2.jpg',
|
||||
price: 11.0,
|
||||
desc: '水不在深,有龙则灵。'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
picUrl: 'https://cdn.uviewui.com/uview/album/3.jpg',
|
||||
price: 10.0,
|
||||
desc: '斯是陋室,惟吾德馨。'
|
||||
}
|
||||
]
|
||||
},
|
||||
promotionPopup: false,
|
||||
promotionList: [
|
||||
{
|
||||
id: 0,
|
||||
title: '满额减',
|
||||
desc: '全场满500减100'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
title: '满额减',
|
||||
desc: '全场满300减50'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '满额减',
|
||||
desc: '全场满200减20'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '满额减',
|
||||
desc: '全场满100减5'
|
||||
}
|
||||
],
|
||||
couponList: [
|
||||
{
|
||||
id: 0,
|
||||
title: '优惠券',
|
||||
desc: '满50减10'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
title: '优惠券',
|
||||
desc: '满30减5'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '优惠券',
|
||||
desc: '满20减2'
|
||||
}
|
||||
],
|
||||
currentEvanIndex: 0,
|
||||
evanTypeList: [
|
||||
{
|
||||
id: '0',
|
||||
name: '全部',
|
||||
count: 0
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
name: '好评',
|
||||
count: 0
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '中评',
|
||||
count: 0
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: '差评',
|
||||
count: 0
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
name: '有图',
|
||||
count: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
if (!e.id) {
|
||||
uni.$u.toast('请求参数错误')
|
||||
return;
|
||||
}
|
||||
|
||||
// 加载商品详情
|
||||
this.spu.id = e.id
|
||||
this.loadProductData()
|
||||
},
|
||||
methods: {
|
||||
loadProductData() {
|
||||
getSpuDetail(this.spu.id).then(res => {
|
||||
// this.spu.desc = res.data.description.replace(/<[^>]*>/g,'');
|
||||
// console.log(res)
|
||||
this.spu = res.data;
|
||||
})
|
||||
},
|
||||
handleSkuItemClick(index) {
|
||||
this.currentSkuIndex = index
|
||||
},
|
||||
handleCouponClick() {
|
||||
// TODO 未登录去登录,登录则跳转优惠券页面
|
||||
},
|
||||
handleEvanTypeClick(index) {
|
||||
this.currentEvanIndex = index
|
||||
// TODO 展示评论
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasLogin() {
|
||||
return this.$store.getters.hasLogin
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.indicator-num {
|
||||
@include flex-center;
|
||||
padding: 2px 0;
|
||||
background-color: rgba(0, 0, 0, 0.35);
|
||||
border-radius: 100px;
|
||||
width: 35px;
|
||||
|
||||
&__text {
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.product-box {
|
||||
padding: 40rpx 40rpx 10rpx 40rpx;
|
||||
@include flex;
|
||||
border-bottom: $custom-border-style;
|
||||
.prod-info {
|
||||
padding-right: 30rpx;
|
||||
.info-text {
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
.price-and-cart {
|
||||
@include flex-space-between;
|
||||
}
|
||||
}
|
||||
.prod-favor {
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.row-box {
|
||||
@include flex-left;
|
||||
padding: 0 30rpx;
|
||||
height: 70rpx;
|
||||
.row-left {
|
||||
width: 70rpx;
|
||||
font-size: 24rpx;
|
||||
color: #939393;
|
||||
}
|
||||
|
||||
.row-right {
|
||||
@include flex-space-between;
|
||||
flex: 1;
|
||||
|
||||
.row-content {
|
||||
flex: 1;
|
||||
|
||||
.prom-box {
|
||||
@include flex-left;
|
||||
.prom-item {
|
||||
@include flex-left;
|
||||
font-size: 22rpx;
|
||||
.prom-title {
|
||||
padding: 1rpx 10rpx;
|
||||
border: 1rpx solid red;
|
||||
border-radius: 5rpx;
|
||||
color: red;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
.prom-desc {
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-box {
|
||||
@include flex-space-between;
|
||||
.coupon-list {
|
||||
@include flex-left;
|
||||
.coupon-item {
|
||||
@include flex-left;
|
||||
font-size: 22rpx;
|
||||
.coupon-desc {
|
||||
padding: 2rpx 15rpx;
|
||||
margin-right: 15rpx;
|
||||
background: red;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.coupon-total {
|
||||
color: #939393;
|
||||
font-size: 12rpx;
|
||||
padding: 0 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.sku-box {
|
||||
@include flex-space-between;
|
||||
.sku-item {
|
||||
@include flex-left;
|
||||
font-size: 22rpx;
|
||||
.sku-desc {
|
||||
margin-left: 15rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.row-more {
|
||||
@include flex-right;
|
||||
width: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sku-popup-slot {
|
||||
width: 750rpx;
|
||||
.current-sku-info {
|
||||
@include flex;
|
||||
padding: 30rpx 100rpx 0 30rpx;
|
||||
.current-sku-img {
|
||||
border-radius: 10rpx;
|
||||
/deep/ * {
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
.current-sku-desc {
|
||||
padding: 0 30rpx;
|
||||
font-size: 28rpx;
|
||||
.current-sku-stock {
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
color: #666666;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.sku-selection {
|
||||
margin: 30rpx;
|
||||
font-size: 26rpx;
|
||||
color: #939393;
|
||||
.sku-item {
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 6rpx;
|
||||
padding: 5rpx 15rpx;
|
||||
border: 1rpx solid #e3e3e3;
|
||||
width: fit-content !important;
|
||||
&.active {
|
||||
color: #666666;
|
||||
border: 1rpx solid #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
.sku-num-box {
|
||||
@include flex-space-between padding: 30rpx;
|
||||
.text {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
.sku-btn-group {
|
||||
@include flex-space-around;
|
||||
height: 100rpx;
|
||||
.btn-item-main {
|
||||
width: 350rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.prom-popup-slot {
|
||||
width: 750rpx;
|
||||
min-height: 500rpx;
|
||||
.prom-info {
|
||||
background: #f3f3f3;
|
||||
line-height: 90rpx;
|
||||
padding-left: 30rpx;
|
||||
font-size: 36rpx;
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
.prom-list {
|
||||
padding: 30rpx;
|
||||
.prom-item {
|
||||
@include flex-left;
|
||||
font-size: 22rpx;
|
||||
margin-bottom: 15rpx;
|
||||
.prom-title {
|
||||
padding: 1rpx 10rpx;
|
||||
border: 1rpx solid red;
|
||||
border-radius: 5rpx;
|
||||
color: red;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
.prom-desc {
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.evaluation-box-wrap {
|
||||
background: #f3f3f3;
|
||||
|
||||
.evaluation-box {
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
background: $custom-bg-color;
|
||||
padding-bottom: 120rpx;
|
||||
|
||||
.evaluation-title {
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
padding: 20rpx 30rpx;
|
||||
border-bottom: $custom-border-style;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.evaluation-info {
|
||||
}
|
||||
|
||||
.evan-type-list {
|
||||
padding: 20rpx;
|
||||
@include flex-space-around;
|
||||
|
||||
.evan-type-item {
|
||||
border-radius: 8rpx;
|
||||
padding: 7rpx 12rpx;
|
||||
background: #f3f3f3;
|
||||
font-size: 22rpx;
|
||||
text-align: center;
|
||||
&.active {
|
||||
background: #ffffff;
|
||||
border: 1rpx solid red;
|
||||
padding: 5rpx 10rpx;
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comment-empty {
|
||||
margin-bottom: 100rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fixed-btn-box {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
.btn-group {
|
||||
background: $custom-bg-color;
|
||||
border-top: $custom-border-style;
|
||||
|
||||
width: 750rpx;
|
||||
@include flex-space-around;
|
||||
height: 100rpx;
|
||||
|
||||
.btn-item {
|
||||
width: 80rpx;
|
||||
@include flex-center(column);
|
||||
.btn-text {
|
||||
font-size: 18rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
width: 200rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,128 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="user-info">
|
||||
<view class="info-item">
|
||||
<view class="label">头像:</view>
|
||||
<view class="info" @click="handleAvatarClick">
|
||||
<u-avatar size="50" shape="square" :src="userInfo.avatar"></u-avatar>
|
||||
<u-icon class="btn" name="arrow-right"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="label">昵称:</view>
|
||||
<view class="info">
|
||||
<u--input maxlength="10" border="none" v-model="userInfo.nickname" inputAlign="right" @change="handleNameChange"></u--input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<view class="label">手机:</view>
|
||||
<view class="info">
|
||||
<view class="value">{{ userInfo.mobile }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="nameUpdateVisible" class="btn-group">
|
||||
<u-button type="primary" text="保存" customStyle="margin-top: 50px" @click="handleSaveBtnClick"></u-button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getUserInfo, updateAvatar, updateNickname } from '../../api/user'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: {
|
||||
nickname: '',
|
||||
avatar: '',
|
||||
mobile: ''
|
||||
},
|
||||
avatarFiles: [],
|
||||
tempName: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
nameUpdateVisible: function () {
|
||||
return this.userInfo.nickname !== this.tempName
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.loadUserInfoData()
|
||||
},
|
||||
methods: {
|
||||
loadUserInfoData() {
|
||||
getUserInfo().then(res => {
|
||||
this.userInfo = res.data
|
||||
this.tempName = this.userInfo.nickname
|
||||
})
|
||||
},
|
||||
handleAvatarClick() {
|
||||
uni.chooseImage({
|
||||
success: chooseImageRes => {
|
||||
const tempFilePaths = chooseImageRes.tempFilePaths
|
||||
updateAvatar(tempFilePaths[0]).then(res => {
|
||||
this.userInfo.avatar = res.data
|
||||
this.$store.commit('SET_USER_INFO', this.userInfo)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleNameChange(val) {
|
||||
let str = uni.$u.trim(val, 'all')
|
||||
this.$nextTick(() => {
|
||||
this.userInfo.nickname = str
|
||||
})
|
||||
},
|
||||
handleSaveBtnClick() {
|
||||
updateNickname({ nickname: this.userInfo.nickname }).then(res => {
|
||||
this.tempName = this.userInfo.nickname
|
||||
this.$store.commit('SET_USER_INFO', this.userInfo)
|
||||
uni.$u.toast('已保存')
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: '/pages/user/user'
|
||||
})
|
||||
}, 300)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.user-info {
|
||||
.info-item {
|
||||
padding: 20rpx 60rpx;
|
||||
border-bottom: $custom-border-style;
|
||||
@include flex-space-between;
|
||||
.label {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.info {
|
||||
@include flex-left;
|
||||
.value {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.btn {
|
||||
margin-left: 30rpx;
|
||||
}
|
||||
}
|
||||
.name-edit {
|
||||
@include flex-left;
|
||||
.edit-btn-group {
|
||||
@include flex;
|
||||
.edit-btn {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
</style>
|
@ -1,19 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
搜索页面
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: ''
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -1,62 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<u-gap height="20"></u-gap>
|
||||
<u-cell-group class="setting-list" :border="false">
|
||||
<u-cell class="setting-item" icon="lock" title="修改密码" isLink></u-cell>
|
||||
<u-cell class="setting-item" icon="phone" title="换绑手机" isLink></u-cell>
|
||||
<u-cell v-if="hasLogin" class="setting-item" icon="minus-circle" title="用户登出" @click="logout" isLink></u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UGap from '../../uni_modules/uview-ui/components/u-gap/u-gap'
|
||||
|
||||
export default {
|
||||
components: { UGap },
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
hasLogin() {
|
||||
return this.$store.getters.hasLogin
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
logout() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您确定要退出登录吗',
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
this.$store.dispatch('Logout').then(res => {
|
||||
uni.switchTab({
|
||||
url: '/pages/user/user'
|
||||
})
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
//console.log('用户点击取消')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.setting-list {
|
||||
padding: 10rpx 0;
|
||||
background-color: #fff;
|
||||
border-radius: 15rpx;
|
||||
|
||||
.setting-item {
|
||||
padding: 10rpx 0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,203 +0,0 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="user-header">
|
||||
<view class="user-info" @click="pageRouter('/pages/profile/profile')">
|
||||
<u-avatar size="60" shape="square" :src="userInfo.avatar"></u-avatar>
|
||||
<view class="info-text">
|
||||
<view class="user-nickname">{{ hasLogin ? userInfo.nickname || '会员用户' : '匿名用户' }}</view>
|
||||
<view class="user-mobile">{{ hasLogin ? userInfo.mobile || ' ' : '登录/注册' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="user-setting">
|
||||
<u-icon v-if="hasLogin" name="setting" color="#939393" size="22" @click="pageRouter('/pages/setting/setting')"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-gap height="10" bgColor="#f3f3f3"></u-gap>
|
||||
|
||||
<view>
|
||||
<view class="order-header">
|
||||
<text class="order-title">我的订单</text>
|
||||
<view class="see-all" @click="pageRouter(orderPage, -1)">
|
||||
<text>查看全部</text>
|
||||
<u-icon name="arrow-right"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="order-status-box">
|
||||
<u-grid :border="false" :col="orderStatusList.length">
|
||||
<u-grid-item v-for="(item, index) in orderStatusList" :key="index" @click="pageRouter(orderPage, item.status)">
|
||||
<u-icon :name="item.icon" :size="32"></u-icon>
|
||||
<text class="grid-title">{{ item.name }}</text>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-gap height="10" bgColor="#f3f3f3"></u-gap>
|
||||
|
||||
<view class="stat-box">
|
||||
<u-grid :border="false" col="3">
|
||||
<u-grid-item v-for="(item, index) in statList" :key="index">
|
||||
<text class="grid-value">{{ item.value }}</text>
|
||||
<text class="grid-title">{{ item.title }}</text>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
|
||||
<u-gap height="10" bgColor="#f3f3f3"></u-gap>
|
||||
|
||||
<u-cell-group class="fun-list">
|
||||
<u-cell class="fun-item" :border="false" icon="gift" title="分销中心" isLink></u-cell>
|
||||
<u-cell class="fun-item" :border="false" icon="tags" title="领券中心" isLink></u-cell>
|
||||
<u-cell class="fun-item" :border="false" icon="coupon" title="我的优惠券" isLink></u-cell>
|
||||
<u-cell class="fun-item" :border="false" icon="map" title="收货地址" @click="pageRouter('/pages/address/list')" isLink></u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import orderStatus from '@/common/orderStatus'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
orderPage: '/pages/order/list',
|
||||
statList: [
|
||||
{ value: '0', title: '我的收藏' },
|
||||
{ value: '0', title: '我的消息' },
|
||||
{ value: '0', title: '我的足迹' }
|
||||
]
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
if (this.hasLogin) {
|
||||
this.$store.dispatch('ObtainUserInfo')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
userInfo() {
|
||||
return this.$store.getters.userInfo
|
||||
},
|
||||
hasLogin() {
|
||||
return this.$store.getters.hasLogin
|
||||
},
|
||||
orderStatusList() {
|
||||
let orderStatusList = []
|
||||
for (let status in orderStatus) {
|
||||
if (status !== '40') {
|
||||
orderStatusList.push({ name: orderStatus[status].name, status: status, icon: orderStatus[status].icon })
|
||||
}
|
||||
}
|
||||
return orderStatusList
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
pageRouter(pageUrl, param) {
|
||||
if (!this.hasLogin) {
|
||||
uni.$u.route('/pages/login/social')
|
||||
} else if (pageUrl === this.orderPage) {
|
||||
uni.$u.route(this.orderPage, {
|
||||
status: param
|
||||
})
|
||||
} else {
|
||||
uni.$u.route(pageUrl)
|
||||
}
|
||||
},
|
||||
logout() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您确定要退出登录吗',
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
this.$store.dispatch('Logout')
|
||||
} else if (res.cancel) {
|
||||
//console.log('用户点击取消')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.user-header {
|
||||
background-color: #fff;
|
||||
@include flex-space-between;
|
||||
padding: 30rpx;
|
||||
height: 200rpx;
|
||||
|
||||
.user-info {
|
||||
@include flex-left;
|
||||
align-items: center;
|
||||
|
||||
.info-text {
|
||||
margin-left: 20rpx;
|
||||
|
||||
.user-nickname {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
line-height: 50rpx;
|
||||
}
|
||||
|
||||
.user-mobile {
|
||||
font-size: 24rpx;
|
||||
font-weight: 700;
|
||||
color: #939393;
|
||||
line-height: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-setting {
|
||||
margin-right: 5rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.order-header {
|
||||
@include flex-space-between;
|
||||
padding: 20rpx 30rpx;
|
||||
border-bottom: $custom-border-style;
|
||||
|
||||
.order-title {
|
||||
color: #333333;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.see-all {
|
||||
height: 40rpx;
|
||||
@include flex-right;
|
||||
color: #666666;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.order-status-box {
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
|
||||
.stat-box {
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.grid-title {
|
||||
line-height: 50rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.grid-value {
|
||||
line-height: 50rpx;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #2b85e4;
|
||||
}
|
||||
|
||||
.fun-list {
|
||||
.fun-item {
|
||||
padding-top: 10rpx;
|
||||
padding-bottom: 10rpx;
|
||||
border-bottom: $custom-border-style;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 7.9 KiB |
@ -1,7 +0,0 @@
|
||||
const getters = {
|
||||
accessToken: state => state.user.accessToken,
|
||||
refreshToken: state => state.user.refreshToken,
|
||||
userInfo: state => state.user.userInfo,
|
||||
hasLogin: state => !!state.user.accessToken
|
||||
}
|
||||
export default getters
|
@ -1,17 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import user from './mudules/user'
|
||||
import cart from './mudules/cart'
|
||||
import getters from './getters'
|
||||
|
||||
Vue.use(Vuex) // vue的插件机制
|
||||
|
||||
// Vuex.Store 构造器选项
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
user,
|
||||
cart
|
||||
},
|
||||
getters
|
||||
})
|
||||
export default store
|
@ -1,28 +0,0 @@
|
||||
import { getCartDetail } from '@/api/cart'
|
||||
|
||||
const cart = {
|
||||
state: {
|
||||
cartCount: 0
|
||||
},
|
||||
mutations: {
|
||||
//记录购物车商品数量
|
||||
SET_CART_COUNT(state, data) {
|
||||
const arr = data.length || []
|
||||
state.cartNumber = arr.length
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
//获取购物车数据
|
||||
CartProductDetail({ state, commit }) {
|
||||
return getCartDetail()
|
||||
.then(res => {
|
||||
commit('SET_CART_COUNT', res.data)
|
||||
return Promise.resolve(res)
|
||||
})
|
||||
.catch(err => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
export default cart
|
@ -1,101 +0,0 @@
|
||||
import { getUserInfo } from '@/api/user'
|
||||
import { passwordLogin, smsLogin, weixinMiniAppLogin, logout } from '@/api/auth'
|
||||
|
||||
const AccessTokenKey = 'ACCESS_TOKEN'
|
||||
const RefreshTokenKey = 'REFRESH_TOKEN'
|
||||
|
||||
const user = {
|
||||
state: {
|
||||
accessToken: uni.getStorageSync(AccessTokenKey), // 访问令牌
|
||||
refreshToken: uni.getStorageSync(RefreshTokenKey), // 刷新令牌
|
||||
userInfo: {}
|
||||
},
|
||||
mutations: {
|
||||
// 更新 state 的通用方法
|
||||
SET_STATE_ATTR(state, param) {
|
||||
if (param instanceof Array) {
|
||||
for (let item of param) {
|
||||
state[item.key] = item.val
|
||||
}
|
||||
} else {
|
||||
state[param.key] = param.val
|
||||
}
|
||||
},
|
||||
// 更新令牌
|
||||
SET_TOKEN(state, data) {
|
||||
// 设置令牌
|
||||
const { accessToken, refreshToken } = data
|
||||
state.accessToken = accessToken
|
||||
state.refreshToken = refreshToken
|
||||
uni.setStorageSync(AccessTokenKey, accessToken)
|
||||
uni.setStorageSync(RefreshTokenKey, refreshToken)
|
||||
|
||||
// 加载用户信息
|
||||
this.dispatch('ObtainUserInfo')
|
||||
},
|
||||
// 更新用户信息
|
||||
SET_USER_INFO(state, data) {
|
||||
state.userInfo = data
|
||||
},
|
||||
// 清空令牌 和 用户信息
|
||||
CLEAR_LOGIN_INFO(state) {
|
||||
uni.removeStorageSync(AccessTokenKey)
|
||||
uni.removeStorageSync(RefreshTokenKey)
|
||||
state.accessToken = ''
|
||||
state.refreshToken = ''
|
||||
state.userInfo = {}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
//账号登录
|
||||
Login({ state, commit }, { type, data }) {
|
||||
if (type === 0) {
|
||||
return passwordLogin(data)
|
||||
.then(res => {
|
||||
commit('SET_TOKEN', res.data)
|
||||
return Promise.resolve(res)
|
||||
})
|
||||
.catch(err => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
} else if (type === 1) {
|
||||
return smsLogin(data)
|
||||
.then(res => {
|
||||
commit('SET_TOKEN', res.data)
|
||||
return Promise.resolve(res)
|
||||
})
|
||||
.catch(err => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
} else {
|
||||
return weixinMiniAppLogin(data)
|
||||
.then(res => {
|
||||
commit('SET_TOKEN', res.data)
|
||||
return Promise.resolve(res)
|
||||
})
|
||||
.catch(err => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
},
|
||||
// 退出登录
|
||||
Logout({ state, commit }) {
|
||||
return logout()
|
||||
.then(res => {
|
||||
return Promise.resolve(res)
|
||||
})
|
||||
.catch(err => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
.finally(() => {
|
||||
commit('CLEAR_LOGIN_INFO')
|
||||
})
|
||||
},
|
||||
// 获得用户基本信息
|
||||
async ObtainUserInfo({ state, commit }) {
|
||||
const res = await getUserInfo()
|
||||
commit('SET_USER_INFO', res.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
export default user
|
@ -1,5 +0,0 @@
|
||||
.row-between {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/**
|
||||
* 这里是uni-app内置的常用样式变量
|
||||
*
|
||||
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||
*
|
||||
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||
*/
|
||||
|
||||
/* 引入uView主题样式 */
|
||||
@import '@/uni_modules/uview-ui/theme.scss';
|
||||
|
||||
/* 全局自定义scss变量 */
|
||||
|
||||
/* 页面背景颜色 */
|
||||
$custom-bg-color: #ffffff;
|
||||
|
||||
/* 边框样式 */
|
||||
$custom-border-style: 1rpx solid #f3f3f3;
|
||||
|
||||
|
||||
@mixin flex-left($direction: row) {
|
||||
display: flex;
|
||||
flex-direction: $direction;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
@mixin flex-right($direction: row) {
|
||||
display: flex;
|
||||
flex-direction: $direction;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@mixin flex-center($direction: row) {
|
||||
display: flex;
|
||||
flex-direction: $direction;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@mixin flex-space-between($direction: row) {
|
||||
display: flex;
|
||||
flex-direction: $direction;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
@mixin flex-space-around($direction: row) {
|
||||
display: flex;
|
||||
flex-direction: $direction;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 www.uviewui.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,66 +0,0 @@
|
||||
<p align="center">
|
||||
<img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
|
||||
</p>
|
||||
<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView 2.0</h3>
|
||||
<h3 align="center">多平台快速开发的UI框架</h3>
|
||||
|
||||
[![stars](https://img.shields.io/github/stars/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
|
||||
[![forks](https://img.shields.io/github/forks/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
|
||||
[![issues](https://img.shields.io/github/issues/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0/issues)
|
||||
[![Website](https://img.shields.io/badge/uView-up-blue?style=flat-square)](https://uviewui.com)
|
||||
[![release](https://img.shields.io/github/v/release/umicro/uView2.0?style=flat-square)](https://gitee.com/umicro/uView2.0/releases)
|
||||
[![license](https://img.shields.io/github/license/umicro/uView2.0?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)
|
||||
|
||||
## 说明
|
||||
|
||||
uView UI,是[uni-app](https://uniapp.dcloud.io/)全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
|
||||
|
||||
## [官方文档:https://uviewui.com](https://uviewui.com)
|
||||
|
||||
|
||||
## 预览
|
||||
|
||||
您可以通过**微信**扫码,查看最佳的演示效果。
|
||||
<br>
|
||||
<br>
|
||||
<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
|
||||
|
||||
|
||||
## 链接
|
||||
|
||||
- [官方文档](https://www.uviewui.com/)
|
||||
- [更新日志](https://www.uviewui.com/components/changelog.html)
|
||||
- [升级指南](https://www.uviewui.com/components/changeGuide.html)
|
||||
- [关于我们](https://www.uviewui.com/cooperation/about.html)
|
||||
|
||||
## 交流反馈
|
||||
|
||||
欢迎加入我们的QQ群交流反馈:[点此跳转](https://www.uviewui.com/components/addQQGroup.html)
|
||||
|
||||
## 关于PR
|
||||
|
||||
> 我们非常乐意接受各位的优质PR,但在此之前我希望您了解uView2.0是一个需要兼容多个平台的(小程序、h5、ios app、android app)包括nvue页面、vue页面。
|
||||
> 所以希望在您修复bug并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢!
|
||||
|
||||
## 安装
|
||||
|
||||
#### **uni-app插件市场链接** —— [https://ext.dcloud.net.cn/plugin?id=1593](https://ext.dcloud.net.cn/plugin?id=1593)
|
||||
|
||||
请通过[官网安装文档](https://www.uviewui.com/components/install.html)了解更详细的内容
|
||||
|
||||
## 快速上手
|
||||
|
||||
请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容
|
||||
|
||||
## 使用方法
|
||||
配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
|
||||
|
||||
```html
|
||||
<template>
|
||||
<u-button text="按钮"></u-button>
|
||||
</template>
|
||||
```
|
||||
|
||||
## 版权信息
|
||||
uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。
|
||||
|
@ -1,357 +0,0 @@
|
||||
## 2.0.34(2022-09-25)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. `u-input`、`u-textarea`增加`ignoreCompositionEvent`属性
|
||||
2. 修复`route`方法调用可能报错的问题
|
||||
3. 修复`u-no-network`组件`z-index`无效的问题
|
||||
4. 修复`textarea`组件在h5上confirmType=""报错的问题
|
||||
5. `u-rate`适配`nvue`
|
||||
6. 优化验证手机号码的正则表达式(根据工信部发布的《电信网编号计划(2017年版)》进行修改。)
|
||||
7. `form-item`添加`labelPosition`属性
|
||||
8. `u-calendar`修复`maxDate`设置为当前日期,并且当前时间大于08:00时无法显示日期列表的问题 (#724)
|
||||
9. `u-radio`增加一个默认插槽用于自定义修改label内容 (#680)
|
||||
10. 修复`timeFormat`函数在safari重的兼容性问题 (#664)
|
||||
## 2.0.33(2022-06-17)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复`loadmore`组件`lineColor`类型错误问题
|
||||
2. 修复`u-parse`组件`imgtap`、`linktap`不生效问题
|
||||
## 2.0.32(2022-06-16)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
1. `u-loadmore`新增自定义颜色、虚/实线
|
||||
2. 修复`u-swiper-action`组件部分平台不能上下滑动的问题
|
||||
3. 修复`u-list`回弹问题
|
||||
4. 修复`notice-bar`组件动画在低端安卓机可能会抖动的问题
|
||||
5. `u-loading-page`添加控制图标大小的属性`iconSize`
|
||||
6. 修复`u-tooltip`组件`color`参数不生效的问题
|
||||
7. 修复`u--input`组件使用`blur`事件输出为`undefined`的bug
|
||||
8. `u-code-input`组件新增键盘弹起时,是否自动上推页面参数`adjustPosition`
|
||||
9. 修复`image`组件`load`事件无回调对象问题
|
||||
10. 修复`button`组件`loadingSize`设置无效问题
|
||||
10. 其他修复
|
||||
## 2.0.31(2022-04-19)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复`upload`在`vue`页面上传成功后没有成功标志的问题
|
||||
2. 解决演示项目中微信小程序模拟上传图片一直出于上传中问题
|
||||
3. 修复`u-code-input`组件在`nvue`页面编译到`app`平台上光标异常问题(`app`去除此功能)
|
||||
4. 修复`actionSheet`组件标题关闭按钮点击事件名称错误的问题
|
||||
5. 其他修复
|
||||
## 2.0.30(2022-04-04)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. `u-rate`增加`readonly`属性
|
||||
2. `tabs`滑块支持设置背景图片
|
||||
3. 修复`u-subsection` `mode`为`subsection`时,滑块样式不正确的问题
|
||||
4. `u-code-input`添加光标效果动画
|
||||
5. 修复`popup`的`open`事件不触发
|
||||
6. 修复`u-flex-column`无效的问题
|
||||
7. 修复`u-datetime-picker`索引在特定场合异常问题
|
||||
8. 修复`u-datetime-picker`最小时间字符串模板错误问题
|
||||
9. `u-swiper`添加`m3u8`验证
|
||||
10. `u-swiper`修改判断image和video逻辑
|
||||
11. 修复`swiper`无法使用本地图片问题,增加`type`参数
|
||||
12. 修复`u-row-notice`格式错误问题
|
||||
13. 修复`u-switch`组件当`unit`为`rpx`时,`nodeStyle`消失的问题
|
||||
14. 修复`datetime-picker`组件`showToolbar`与`visibleItemCount`属性无效的问题
|
||||
15. 修复`upload`组件条件编译位置判断错误,导致`previewImage`属性设置为`false`时,整个组件都会被隐藏的问题
|
||||
16. 修复`u-checkbox-group`设置`shape`属性无效的问题
|
||||
17. 修复`u-upload`的`capture`传入字符串的时候不生效的问题
|
||||
18. 修复`u-action-sheet`组件,关闭事件逻辑错误的问题
|
||||
19. 修复`u-list`触顶事件的触发错误的问题
|
||||
20. 修复`u-text`只有手机号可拨打的问题
|
||||
21. 修复`u-textarea`不能换行的问题
|
||||
22. 其他修复
|
||||
## 2.0.29(2022-03-13)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复`u--text`组件设置`decoration`属性未生效的问题
|
||||
2. 修复`u-datetime-picker`使用`formatter`后返回值不正确
|
||||
3. 修复`u-datetime-picker` `intercept` 可能为undefined
|
||||
4. 修复已设置单位 uni..config.unit = 'rpx'时,线型指示器 `transform` 的位置翻倍,导致指示器超出宽度
|
||||
5. 修复mixin中bem方法生成的类名在支付宝和字节小程序中失效
|
||||
6. 修复默认值传值为空的时候,打开`u-datetime-picker`报错,不能选中第一列时间的bug
|
||||
7. 修复`u-datetime-picker`使用`formatter`后返回值不正确
|
||||
8. 修复`u-image`组件`loading`无效果的问题
|
||||
9. 修复`config.unit`属性设为`rpx`时,导航栏占用高度不足导致塌陷的问题
|
||||
10. 修复`u-datetime-picker`组件`itemHeight`无效问题
|
||||
11. 其他修复
|
||||
## 2.0.28(2022-02-22)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. search组件新增searchIconSize属性
|
||||
2. 兼容Safari/Webkit中传入时间格式如2022-02-17 12:00:56
|
||||
3. 修复text value.js 判断日期出format错误问题
|
||||
4. priceFormat格式化金额出现精度错误
|
||||
5. priceFormat在部分情况下出现精度损失问题
|
||||
6. 优化表单rules提示
|
||||
7. 修复avatar组件src为空时,展示状态不对
|
||||
8. 其他修复
|
||||
## 2.0.27(2022-01-28)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1.样式修复
|
||||
## 2.0.26(2022-01-28)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1.样式修复
|
||||
## 2.0.25(2022-01-27)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复text组件mode=price时,可能会导致精度错误的问题
|
||||
2. 添加$u.setConfig()方法,可设置uView内置的config, props, zIndex, color属性,详见:[修改uView内置配置方案](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
|
||||
3. 优化form组件在errorType=toast时,如果输入错误页面会有抖动的问题
|
||||
4. 修复$u.addUnit()对配置默认单位可能无效的问题
|
||||
## 2.0.24(2022-01-25)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复swiper在current指定非0时缩放有误
|
||||
2. 修复u-icon添加stop属性的时候报错
|
||||
3. 优化遗留的通过正则判断rpx单位的问题
|
||||
4. 优化Layout布局 vue使用gutter时,会超出固定区域
|
||||
5. 优化search组件高度单位问题(rpx -> px)
|
||||
6. 修复u-image slot 加载和错误的图片失去了高度
|
||||
7. 修复u-index-list中footer插槽与header插槽存在性判断错误
|
||||
8. 修复部分机型下u-popup关闭时会闪烁
|
||||
9. 修复u-image在nvue-app下失去宽高
|
||||
10. 修复u-popup运行报错
|
||||
11. 修复u-tooltip报错
|
||||
12. 修复box-sizing在app下的警告
|
||||
13. 修复u-navbar在小程序中报运行时错误
|
||||
14. 其他修复
|
||||
## 2.0.23(2022-01-24)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复image组件在hx3.3.9的nvue下可能会显示异常的问题
|
||||
2. 修复col组件gutter参数带rpx单位处理不正确的问题
|
||||
3. 修复text组件单行时无法显示省略号的问题
|
||||
4. navbar添加titleStyle参数
|
||||
5. 升级到hx3.3.9可消除nvue下控制台样式警告的问题
|
||||
## 2.0.22(2022-01-19)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. $u.page()方法优化,避免在特殊场景可能报错的问题
|
||||
2. picker组件添加immediateChange参数
|
||||
3. 新增$u.pages()方法
|
||||
## 2.0.21(2022-01-19)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 优化:form组件在用户设置rules的时候提示用户model必传
|
||||
2. 优化遗留的通过正则判断rpx单位的问题
|
||||
3. 修复微信小程序环境中tabbar组件开启safeAreaInsetBottom属性后,placeholder高度填充不正确
|
||||
4. 修复swiper在current指定非0时缩放有误
|
||||
5. 修复u-icon添加stop属性的时候报错
|
||||
6. 修复upload组件在accept=all的时候没有作用
|
||||
7. 修复在text组件mode为phone时call属性无效的问题
|
||||
8. 处理u-form clearValidate方法
|
||||
9. 其他修复
|
||||
## 2.0.20(2022-01-14)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复calendar默认会选择一个日期,如果直接点确定的话,无法取到值的问题
|
||||
2. 修复Slider缺少disabled props 还有注释
|
||||
3. 修复u-notice-bar点击事件无法拿到index索引值的问题
|
||||
4. 修复u-collapse-item在vue文件下,app端自定义插槽不生效的问题
|
||||
5. 优化头像为空时显示默认头像
|
||||
6. 修复图片地址赋值后判断加载状态为完成问题
|
||||
7. 修复日历滚动到默认日期月份区域
|
||||
8. search组件暴露点击左边icon事件
|
||||
9. 修复u-form clearValidate方法不生效
|
||||
10. upload h5端增加返回文件参数(文件的name参数)
|
||||
11. 处理upload选择文件后url为blob类型无法预览的问题
|
||||
12. u-code-input 修复输入框没有往左移出一半屏幕
|
||||
13. 修复Upload上传 disabled为true时,控制台报hoverClass类型错误
|
||||
14. 临时处理ios app下grid点击坍塌问题
|
||||
15. 其他修复
|
||||
## 2.0.19(2021-12-29)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 优化微信小程序包体积可在微信中预览,请升级HbuilderX3.3.4,同时在“运行->运行到小程序模拟器”中勾选“运行时是否压缩代码”
|
||||
2. 优化微信小程序setData性能,处理某些方法如$u.route()无法在模板中使用的问题
|
||||
3. navbar添加autoBack参数
|
||||
4. 允许avatar组件的事件冒泡
|
||||
5. 修复cell组件报错问题
|
||||
6. 其他修复
|
||||
## 2.0.18(2021-12-28)
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复app端编译报错问题
|
||||
2. 重新处理微信小程序端setData过大的性能问题
|
||||
3. 修复边框问题
|
||||
4. 修复最大最小月份不大于0则没有数据出现的问题
|
||||
5. 修复SwipeAction微信小程序端无法上下滑动问题
|
||||
6. 修复input的placeholder在小程序端默认显示为true问题
|
||||
7. 修复divider组件click事件无效问题
|
||||
8. 修复u-code-input maxlength 属性值为 String 类型时显示异常
|
||||
9. 修复当 grid只有 1到2时 在小程序端algin设置无效的问题
|
||||
10. 处理form-item的label为top时,取消错误提示的左边距
|
||||
11. 其他修复
|
||||
## 2.0.17(2021-12-26)
|
||||
## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 解决HBuilderX3.3.3.20211225版本导致的样式问题
|
||||
2. calendar日历添加monthNum参数
|
||||
3. navbar添加center slot
|
||||
## 2.0.16(2021-12-25)
|
||||
## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 解决微信小程序setData性能问题
|
||||
2. 修复count-down组件change事件不触发问题
|
||||
## 2.0.15(2021-12-21)
|
||||
## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复Cell单元格titleWidth无效
|
||||
2. 修复cheakbox组件ischecked不更新
|
||||
3. 修复keyboard是否显示"."按键默认值问题
|
||||
4. 修复number-keyboard是否显示键盘的"."符号问题
|
||||
5. 修复Input输入框 readonly无效
|
||||
6. 修复u-avatar 导致打包app、H5时候报错问题
|
||||
7. 修复Upload上传deletable无效
|
||||
8. 修复upload当设置maxSize时无效的问题
|
||||
9. 修复tabs lineWidth传入带单位的字符串的时候偏移量计算错误问题
|
||||
10. 修复rate组件在有padding的view内,显示的星星位置和可触摸区域不匹配,无法正常选中星星
|
||||
## 2.0.13(2021-12-14)
|
||||
## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复配置默认单位为rpx可能会导致自定义导航栏高度异常的问题
|
||||
## 2.0.12(2021-12-14)
|
||||
## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复tabs组件在vue环境下划线消失的问题
|
||||
2. 修复upload组件在安卓小程序无法选择视频的问题
|
||||
3. 添加uni.$u.config.unit配置,用于配置参数默认单位,详见:[默认单位配置](https://www.uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
|
||||
4. 修复textarea组件在没绑定v-model时,字符统计不生效问题
|
||||
5. 修复nvue下控制是否出现滚动条失效问题
|
||||
## 2.0.11(2021-12-13)
|
||||
## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. text组件align参数无效的问题
|
||||
2. subsection组件添加keyName参数
|
||||
3. upload组件无法判断[Object file]类型的问题
|
||||
4. 处理notify层级过低问题
|
||||
5. codeInput组件添加disabledDot参数
|
||||
6. 处理actionSheet组件round参数无效的问题
|
||||
7. calendar组件添加round参数用于控制圆角值
|
||||
8. 处理swipeAction组件在vue环境下默认被打开的问题
|
||||
9. button组件的throttleTime节流参数无效的问题
|
||||
10. 解决u-notify手动关闭方法close()无效的问题
|
||||
11. input组件readonly不生效问题
|
||||
12. tag组件type参数为info不生效问题
|
||||
## 2.0.10(2021-12-08)
|
||||
## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复button sendMessagePath属性不生效
|
||||
2. 修复DatetimePicker选择器title无效
|
||||
3. 修复u-toast设置loading=true不生效
|
||||
4. 修复u-text金额模式传0报错
|
||||
5. 修复u-toast组件的icon属性配置不生效
|
||||
6. button的icon在特殊场景下的颜色优化
|
||||
7. IndexList优化,增加#
|
||||
## 2.0.9(2021-12-01)
|
||||
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 优化swiper的height支持100%值(仅vue有效),修复嵌入视频时click事件无法触发的问题
|
||||
2. 优化tabs组件对list值为空的判断,或者动态变化list时重新计算相关尺寸的问题
|
||||
3. 优化datetime-picker组件逻辑,让其后续打开的默认值为上一次的选中值,需要通过v-model绑定值才有效
|
||||
4. 修复upload内嵌在其他组件中,选择图片可能不会换行的问题
|
||||
## 2.0.8(2021-12-01)
|
||||
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复toast的position参数无效问题
|
||||
2. 处理input在ios nvue上无法获得焦点的问题
|
||||
3. avatar-group组件添加extraValue参数,让剩余展示数量可手动控制
|
||||
4. tabs组件添加keyName参数用于配置从对象中读取的键名
|
||||
5. 处理text组件名字脱敏默认配置无效的问题
|
||||
6. 处理picker组件item文本太长换行问题
|
||||
## 2.0.7(2021-11-30)
|
||||
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 修复radio和checkbox动态改变v-model无效的问题。
|
||||
2. 优化form规则validator在微信小程序用法
|
||||
3. 修复backtop组件mode参数在微信小程序无效的问题
|
||||
4. 处理Album的previewFullImage属性无效的问题
|
||||
5. 处理u-datetime-picker组件mode='time'在选择改变时间时,控制台报错的问题
|
||||
## 2.0.6(2021-11-27)
|
||||
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. 处理tag组件在vue下边框无效的问题。
|
||||
2. 处理popup组件圆角参数可能无效的问题。
|
||||
3. 处理tabs组件lineColor参数可能无效的问题。
|
||||
4. propgress组件在值很小时,显示异常的问题。
|
||||
## 2.0.5(2021-11-25)
|
||||
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. calendar在vue下显示异常问题。
|
||||
2. form组件labelPosition和errorType参数无效的问题
|
||||
3. input组件inputAlign无效的问题
|
||||
4. 其他一些修复
|
||||
## 2.0.4(2021-11-23)
|
||||
## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
0. input组件缺失@confirm事件,以及subfix和prefix无效问题
|
||||
1. component.scss文件样式在vue下干扰全局布局问题
|
||||
2. 修复subsection在vue环境下表现异常的问题
|
||||
3. tag组件的bgColor等参数无效的问题
|
||||
4. upload组件不换行的问题
|
||||
5. 其他的一些修复处理
|
||||
## 2.0.3(2021-11-16)
|
||||
## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. uView2.0已实现全面兼容nvue
|
||||
2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
|
||||
3. 目前uView2.0为公测阶段,相关细节可能会有变动
|
||||
4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
|
||||
5. 处理modal的confirm回调事件拼写错误问题
|
||||
6. 处理input组件@input事件参数错误问题
|
||||
7. 其他一些修复
|
||||
## 2.0.2(2021-11-16)
|
||||
## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. uView2.0已实现全面兼容nvue
|
||||
2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
|
||||
3. 目前uView2.0为公测阶段,相关细节可能会有变动
|
||||
4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
|
||||
5. 修复input组件formatter参数缺失问题
|
||||
6. 优化loading-icon组件的scss写法问题,防止不兼容新版本scss
|
||||
## 2.0.0(2020-11-15)
|
||||
## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
|
||||
|
||||
# uView2.0重磅发布,利剑出鞘,一统江湖
|
||||
|
||||
1. uView2.0已实现全面兼容nvue
|
||||
2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
|
||||
3. 目前uView2.0为公测阶段,相关细节可能会有变动
|
||||
4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
|
||||
5. 修复input组件formatter参数缺失问题
|
||||
|
||||
|
@ -1,78 +0,0 @@
|
||||
<template>
|
||||
<uvForm
|
||||
ref="uForm"
|
||||
:model="model"
|
||||
:rules="rules"
|
||||
:errorType="errorType"
|
||||
:borderBottom="borderBottom"
|
||||
:labelPosition="labelPosition"
|
||||
:labelWidth="labelWidth"
|
||||
:labelAlign="labelAlign"
|
||||
:labelStyle="labelStyle"
|
||||
:customStyle="customStyle"
|
||||
>
|
||||
<slot />
|
||||
</uvForm>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 此组件存在的理由是,在nvue下,u-form被uni-app官方占用了,u-form在nvue中相当于form组件
|
||||
* 所以在nvue下,取名为u--form,内部其实还是u-form.vue,只不过做一层中转
|
||||
*/
|
||||
import uvForm from '../u-form/u-form.vue';
|
||||
import props from '../u-form/props.js'
|
||||
export default {
|
||||
// #ifdef MP-WEIXIN
|
||||
name: 'u-form',
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
name: 'u--form',
|
||||
// #endif
|
||||
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
|
||||
components: {
|
||||
uvForm
|
||||
},
|
||||
created() {
|
||||
this.children = []
|
||||
},
|
||||
methods: {
|
||||
// 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
|
||||
setRules(rules) {
|
||||
this.$refs.uForm.setRules(rules)
|
||||
},
|
||||
validate() {
|
||||
/**
|
||||
* 在微信小程序中,通过this.$parent拿到的父组件是u--form,而不是其内嵌的u-form
|
||||
* 导致在u-form组件中,拿不到对应的children数组,从而校验无效,所以这里每次调用u-form组件中的
|
||||
* 对应方法的时候,在小程序中都先将u--form的children赋值给u-form中的children
|
||||
*/
|
||||
// #ifdef MP-WEIXIN
|
||||
this.setMpData()
|
||||
// #endif
|
||||
return this.$refs.uForm.validate()
|
||||
},
|
||||
validateField(value, callback) {
|
||||
// #ifdef MP-WEIXIN
|
||||
this.setMpData()
|
||||
// #endif
|
||||
return this.$refs.uForm.validateField(value, callback)
|
||||
},
|
||||
resetFields() {
|
||||
// #ifdef MP-WEIXIN
|
||||
this.setMpData()
|
||||
// #endif
|
||||
return this.$refs.uForm.resetFields()
|
||||
},
|
||||
clearValidate(props) {
|
||||
// #ifdef MP-WEIXIN
|
||||
this.setMpData()
|
||||
// #endif
|
||||
return this.$refs.uForm.clearValidate(props)
|
||||
},
|
||||
setMpData() {
|
||||
this.$refs.uForm.children = this.children
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<uvImage
|
||||
:src="src"
|
||||
:mode="mode"
|
||||
:width="width"
|
||||
:height="height"
|
||||
:shape="shape"
|
||||
:radius="radius"
|
||||
:lazyLoad="lazyLoad"
|
||||
:showMenuByLongpress="showMenuByLongpress"
|
||||
:loadingIcon="loadingIcon"
|
||||
:errorIcon="errorIcon"
|
||||
:showLoading="showLoading"
|
||||
:showError="showError"
|
||||
:fade="fade"
|
||||
:webp="webp"
|
||||
:duration="duration"
|
||||
:bgColor="bgColor"
|
||||
:customStyle="customStyle"
|
||||
@click="$emit('click')"
|
||||
@error="$emit('error')"
|
||||
@load="$emit('load')"
|
||||
>
|
||||
<template v-slot:loading>
|
||||
<slot name="loading"></slot>
|
||||
</template>
|
||||
<template v-slot:error>
|
||||
<slot name="error"></slot>
|
||||
</template>
|
||||
</uvImage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 此组件存在的理由是,在nvue下,u-image被uni-app官方占用了,u-image在nvue中相当于image组件
|
||||
* 所以在nvue下,取名为u--image,内部其实还是u-iamge.vue,只不过做一层中转
|
||||
*/
|
||||
import uvImage from '../u-image/u-image.vue';
|
||||
import props from '../u-image/props.js';
|
||||
export default {
|
||||
name: 'u--image',
|
||||
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
|
||||
components: {
|
||||
uvImage
|
||||
},
|
||||
}
|
||||
</script>
|
@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<uvInput
|
||||
:value="value"
|
||||
:type="type"
|
||||
:fixed="fixed"
|
||||
:disabled="disabled"
|
||||
:disabledColor="disabledColor"
|
||||
:clearable="clearable"
|
||||
:password="password"
|
||||
:maxlength="maxlength"
|
||||
:placeholder="placeholder"
|
||||
:placeholderClass="placeholderClass"
|
||||
:placeholderStyle="placeholderStyle"
|
||||
:showWordLimit="showWordLimit"
|
||||
:confirmType="confirmType"
|
||||
:confirmHold="confirmHold"
|
||||
:holdKeyboard="holdKeyboard"
|
||||
:focus="focus"
|
||||
:autoBlur="autoBlur"
|
||||
:disableDefaultPadding="disableDefaultPadding"
|
||||
:cursor="cursor"
|
||||
:cursorSpacing="cursorSpacing"
|
||||
:selectionStart="selectionStart"
|
||||
:selectionEnd="selectionEnd"
|
||||
:adjustPosition="adjustPosition"
|
||||
:inputAlign="inputAlign"
|
||||
:fontSize="fontSize"
|
||||
:color="color"
|
||||
:prefixIcon="prefixIcon"
|
||||
:suffixIcon="suffixIcon"
|
||||
:suffixIconStyle="suffixIconStyle"
|
||||
:prefixIconStyle="prefixIconStyle"
|
||||
:border="border"
|
||||
:readonly="readonly"
|
||||
:shape="shape"
|
||||
:customStyle="customStyle"
|
||||
:formatter="formatter"
|
||||
:ignoreCompositionEvent="ignoreCompositionEvent"
|
||||
@focus="$emit('focus')"
|
||||
@blur="e => $emit('blur', e)"
|
||||
@keyboardheightchange="$emit('keyboardheightchange')"
|
||||
@change="e => $emit('change', e)"
|
||||
@input="e => $emit('input', e)"
|
||||
@confirm="e => $emit('confirm', e)"
|
||||
@clear="$emit('clear')"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<!-- #ifdef MP -->
|
||||
<slot name="prefix"></slot>
|
||||
<slot name="suffix"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP -->
|
||||
<slot name="prefix" slot="prefix"></slot>
|
||||
<slot name="suffix" slot="suffix"></slot>
|
||||
<!-- #endif -->
|
||||
</uvInput>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 此组件存在的理由是,在nvue下,u-input被uni-app官方占用了,u-input在nvue中相当于input组件
|
||||
* 所以在nvue下,取名为u--input,内部其实还是u-input.vue,只不过做一层中转
|
||||
*/
|
||||
import uvInput from '../u-input/u-input.vue';
|
||||
import props from '../u-input/props.js'
|
||||
export default {
|
||||
name: 'u--input',
|
||||
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
|
||||
components: {
|
||||
uvInput
|
||||
},
|
||||
}
|
||||
</script>
|
@ -1,44 +0,0 @@
|
||||
<template>
|
||||
<uvText
|
||||
:type="type"
|
||||
:show="show"
|
||||
:text="text"
|
||||
:prefixIcon="prefixIcon"
|
||||
:suffixIcon="suffixIcon"
|
||||
:mode="mode"
|
||||
:href="href"
|
||||
:format="format"
|
||||
:call="call"
|
||||
:openType="openType"
|
||||
:bold="bold"
|
||||
:block="block"
|
||||
:lines="lines"
|
||||
:color="color"
|
||||
:decoration="decoration"
|
||||
:size="size"
|
||||
:iconStyle="iconStyle"
|
||||
:margin="margin"
|
||||
:lineHeight="lineHeight"
|
||||
:align="align"
|
||||
:wordWrap="wordWrap"
|
||||
:customStyle="customStyle"
|
||||
@click="$emit('click')"
|
||||
></uvText>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 此组件存在的理由是,在nvue下,u-text被uni-app官方占用了,u-text在nvue中相当于input组件
|
||||
* 所以在nvue下,取名为u--input,内部其实还是u-text.vue,只不过做一层中转
|
||||
* 不使用v-bind="$attrs",而是分开独立写传参,是因为微信小程序不支持此写法
|
||||
*/
|
||||
import uvText from "../u-text/u-text.vue";
|
||||
import props from "../u-text/props.js";
|
||||
export default {
|
||||
name: "u--text",
|
||||
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
|
||||
components: {
|
||||
uvText,
|
||||
},
|
||||
};
|
||||
</script>
|
@ -1,48 +0,0 @@
|
||||
<template>
|
||||
<uvTextarea
|
||||
:value="value"
|
||||
:placeholder="placeholder"
|
||||
:height="height"
|
||||
:confirmType="confirmType"
|
||||
:disabled="disabled"
|
||||
:count="count"
|
||||
:focus="focus"
|
||||
:autoHeight="autoHeight"
|
||||
:fixed="fixed"
|
||||
:cursorSpacing="cursorSpacing"
|
||||
:cursor="cursor"
|
||||
:showConfirmBar="showConfirmBar"
|
||||
:selectionStart="selectionStart"
|
||||
:selectionEnd="selectionEnd"
|
||||
:adjustPosition="adjustPosition"
|
||||
:disableDefaultPadding="disableDefaultPadding"
|
||||
:holdKeyboard="holdKeyboard"
|
||||
:maxlength="maxlength"
|
||||
:border="border"
|
||||
:customStyle="customStyle"
|
||||
:formatter="formatter"
|
||||
:ignoreCompositionEvent="ignoreCompositionEvent"
|
||||
@focus="e => $emit('focus')"
|
||||
@blur="e => $emit('blur')"
|
||||
@linechange="e => $emit('linechange', e)"
|
||||
@confirm="e => $emit('confirm')"
|
||||
@input="e => $emit('input', e)"
|
||||
@keyboardheightchange="e => $emit('keyboardheightchange')"
|
||||
></uvTextarea>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 此组件存在的理由是,在nvue下,u--textarea被uni-app官方占用了,u-textarea在nvue中相当于textarea组件
|
||||
* 所以在nvue下,取名为u--textarea,内部其实还是u-textarea.vue,只不过做一层中转
|
||||
*/
|
||||
import uvTextarea from '../u-textarea/u-textarea.vue';
|
||||
import props from '../u-textarea/props.js'
|
||||
export default {
|
||||
name: 'u--textarea',
|
||||
mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
|
||||
components: {
|
||||
uvTextarea
|
||||
},
|
||||
}
|
||||
</script>
|
@ -1,54 +0,0 @@
|
||||
export default {
|
||||
props: {
|
||||
// 操作菜单是否展示 (默认false)
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: uni.$u.props.actionSheet.show
|
||||
},
|
||||
// 标题
|
||||
title: {
|
||||
type: String,
|
||||
default: uni.$u.props.actionSheet.title
|
||||
},
|
||||
// 选项上方的描述信息
|
||||
description: {
|
||||
type: String,
|
||||
default: uni.$u.props.actionSheet.description
|
||||
},
|
||||
// 数据
|
||||
actions: {
|
||||
type: Array,
|
||||
default: uni.$u.props.actionSheet.actions
|
||||
},
|
||||
// 取消按钮的文字,不为空时显示按钮
|
||||
cancelText: {
|
||||
type: String,
|
||||
default: uni.$u.props.actionSheet.cancelText
|
||||
},
|
||||
// 点击某个菜单项时是否关闭弹窗
|
||||
closeOnClickAction: {
|
||||
type: Boolean,
|
||||
default: uni.$u.props.actionSheet.closeOnClickAction
|
||||
},
|
||||
// 处理底部安全区(默认true)
|
||||
safeAreaInsetBottom: {
|
||||
type: Boolean,
|
||||
default: uni.$u.props.actionSheet.safeAreaInsetBottom
|
||||
},
|
||||
// 小程序的打开方式
|
||||
openType: {
|
||||
type: String,
|
||||
default: uni.$u.props.actionSheet.openType
|
||||
},
|
||||
// 点击遮罩是否允许关闭 (默认true)
|
||||
closeOnClickOverlay: {
|
||||
type: Boolean,
|
||||
default: uni.$u.props.actionSheet.closeOnClickOverlay
|
||||
},
|
||||
// 圆角值
|
||||
round: {
|
||||
type: [Boolean, String, Number],
|
||||
default: uni.$u.props.actionSheet.round
|
||||
}
|
||||
}
|
||||
}
|
@ -1,278 +0,0 @@
|
||||
|
||||
<template>
|
||||
<u-popup
|
||||
:show="show"
|
||||
mode="bottom"
|
||||
@close="closeHandler"
|
||||
:safeAreaInsetBottom="safeAreaInsetBottom"
|
||||
:round="round"
|
||||
>
|
||||
<view class="u-action-sheet">
|
||||
<view
|
||||
class="u-action-sheet__header"
|
||||
v-if="title"
|
||||
>
|
||||
<text class="u-action-sheet__header__title u-line-1">{{title}}</text>
|
||||
<view
|
||||
class="u-action-sheet__header__icon-wrap"
|
||||
@tap.stop="cancel"
|
||||
>
|
||||
<u-icon
|
||||
name="close"
|
||||
size="17"
|
||||
color="#c8c9cc"
|
||||
bold
|
||||
></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<text
|
||||
class="u-action-sheet__description"
|
||||
:style="[{
|
||||
marginTop: `${title && description ? 0 : '18px'}`
|
||||
}]"
|
||||
v-if="description"
|
||||
>{{description}}</text>
|
||||
<slot>
|
||||
<u-line v-if="description"></u-line>
|
||||
<view class="u-action-sheet__item-wrap">
|
||||
<template v-for="(item, index) in actions">
|
||||
<!-- #ifdef MP -->
|
||||
<button
|
||||
:key="index"
|
||||
class="u-reset-button"
|
||||
:openType="item.openType"
|
||||
@getuserinfo="onGetUserInfo"
|
||||
@contact="onContact"
|
||||
@getphonenumber="onGetPhoneNumber"
|
||||
@error="onError"
|
||||
@launchapp="onLaunchApp"
|
||||
@opensetting="onOpenSetting"
|
||||
:lang="lang"
|
||||
:session-from="sessionFrom"
|
||||
:send-message-title="sendMessageTitle"
|
||||
:send-message-path="sendMessagePath"
|
||||
:send-message-img="sendMessageImg"
|
||||
:show-message-card="showMessageCard"
|
||||
:app-parameter="appParameter"
|
||||
@tap="selectHandler(index)"
|
||||
:hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
|
||||
>
|
||||
<!-- #endif -->
|
||||
<view
|
||||
class="u-action-sheet__item-wrap__item"
|
||||
@tap.stop="selectHandler(index)"
|
||||
:hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
|
||||
:hover-stay-time="150"
|
||||
>
|
||||
<template v-if="!item.loading">
|
||||
<text
|
||||
class="u-action-sheet__item-wrap__item__name"
|
||||
:style="[itemStyle(index)]"
|
||||
>{{ item.name }}</text>
|
||||
<text
|
||||
v-if="item.subname"
|
||||
class="u-action-sheet__item-wrap__item__subname"
|
||||
>{{ item.subname }}</text>
|
||||
</template>
|
||||
<u-loading-icon
|
||||
v-else
|
||||
custom-class="van-action-sheet__loading"
|
||||
size="18"
|
||||
mode="circle"
|
||||
/>
|
||||
</view>
|
||||
<!-- #ifdef MP -->
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
<u-line v-if="index !== actions.length - 1"></u-line>
|
||||
</template>
|
||||
</view>
|
||||
</slot>
|
||||
<u-gap
|
||||
bgColor="#eaeaec"
|
||||
height="6"
|
||||
v-if="cancelText"
|
||||
></u-gap>
|
||||
<view hover-class="u-action-sheet--hover">
|
||||
<text
|
||||
@touchmove.stop.prevent
|
||||
:hover-stay-time="150"
|
||||
v-if="cancelText"
|
||||
class="u-action-sheet__cancel-text"
|
||||
@tap="cancel"
|
||||
>{{cancelText}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import openType from '../../libs/mixin/openType'
|
||||
import button from '../../libs/mixin/button'
|
||||
import props from './props.js';
|
||||
/**
|
||||
* ActionSheet 操作菜单
|
||||
* @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
|
||||
* @tutorial https://www.uviewui.com/components/actionSheet.html
|
||||
*
|
||||
* @property {Boolean} show 操作菜单是否展示 (默认 false )
|
||||
* @property {String} title 操作菜单标题
|
||||
* @property {String} description 选项上方的描述信息
|
||||
* @property {Array<Object>} actions 按钮的文字数组,见官方文档示例
|
||||
* @property {String} cancelText 取消按钮的提示文字,不为空时显示按钮
|
||||
* @property {Boolean} closeOnClickAction 点击某个菜单项时是否关闭弹窗 (默认 true )
|
||||
* @property {Boolean} safeAreaInsetBottom 处理底部安全区 (默认 true )
|
||||
* @property {String} openType 小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )
|
||||
* @property {Boolean} closeOnClickOverlay 点击遮罩是否允许关闭 (默认 true )
|
||||
* @property {Number|String} round 圆角值,默认无圆角 (默认 0 )
|
||||
* @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
|
||||
* @property {String} sessionFrom 会话来源,openType="contact"时有效
|
||||
* @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
|
||||
* @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
|
||||
* @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
|
||||
* @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )
|
||||
* @property {String} appParameter 打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效
|
||||
*
|
||||
* @event {Function} select 点击ActionSheet列表项时触发
|
||||
* @event {Function} close 点击取消按钮时触发
|
||||
* @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
|
||||
* @event {Function} contact 客服消息回调,openType="contact"时有效
|
||||
* @event {Function} getphonenumber 获取用户手机号回调,openType="getPhoneNumber"时有效
|
||||
* @event {Function} error 当使用开放能力时,发生错误的回调,openType="error"时有效
|
||||
* @event {Function} launchapp 打开 APP 成功的回调,openType="launchApp"时有效
|
||||
* @event {Function} opensetting 在打开授权设置页后回调,openType="openSetting"时有效
|
||||
* @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>
|
||||
*/
|
||||
export default {
|
||||
name: "u-action-sheet",
|
||||
// 一些props参数和methods方法,通过mixin混入,因为其他文件也会用到
|
||||
mixins: [openType, button, uni.$u.mixin, props],
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 操作项目的样式
|
||||
itemStyle() {
|
||||
return (index) => {
|
||||
let style = {};
|
||||
if (this.actions[index].color) style.color = this.actions[index].color
|
||||
if (this.actions[index].fontSize) style.fontSize = uni.$u.addUnit(this.actions[index].fontSize)
|
||||
// 选项被禁用的样式
|
||||
if (this.actions[index].disabled) style.color = '#c0c4cc'
|
||||
return style;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
closeHandler() {
|
||||
// 允许点击遮罩关闭时,才发出close事件
|
||||
if(this.closeOnClickOverlay) {
|
||||
this.$emit('close')
|
||||
}
|
||||
},
|
||||
// 点击取消按钮
|
||||
cancel() {
|
||||
this.$emit('close')
|
||||
},
|
||||
selectHandler(index) {
|
||||
const item = this.actions[index]
|
||||
if (item && !item.disabled && !item.loading) {
|
||||
this.$emit('select', item)
|
||||
if (this.closeOnClickAction) {
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../../libs/css/components.scss";
|
||||
$u-action-sheet-reset-button-width:100% !default;
|
||||
$u-action-sheet-title-font-size: 16px !default;
|
||||
$u-action-sheet-title-padding: 12px 30px !default;
|
||||
$u-action-sheet-title-color: $u-main-color !default;
|
||||
$u-action-sheet-header-icon-wrap-right:15px !default;
|
||||
$u-action-sheet-header-icon-wrap-top:15px !default;
|
||||
$u-action-sheet-description-font-size:13px !default;
|
||||
$u-action-sheet-description-color:14px !default;
|
||||
$u-action-sheet-description-margin: 18px 15px !default;
|
||||
$u-action-sheet-item-wrap-item-padding:15px !default;
|
||||
$u-action-sheet-item-wrap-name-font-size:16px !default;
|
||||
$u-action-sheet-item-wrap-subname-font-size:13px !default;
|
||||
$u-action-sheet-item-wrap-subname-color: #c0c4cc !default;
|
||||
$u-action-sheet-item-wrap-subname-margin-top:10px !default;
|
||||
$u-action-sheet-cancel-text-font-size:16px !default;
|
||||
$u-action-sheet-cancel-text-color:$u-content-color !default;
|
||||
$u-action-sheet-cancel-text-font-size:15px !default;
|
||||
$u-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
|
||||
|
||||
.u-reset-button {
|
||||
width: $u-action-sheet-reset-button-width;
|
||||
}
|
||||
|
||||
.u-action-sheet {
|
||||
text-align: center;
|
||||
&__header {
|
||||
position: relative;
|
||||
padding: $u-action-sheet-title-padding;
|
||||
&__title {
|
||||
font-size: $u-action-sheet-title-font-size;
|
||||
color: $u-action-sheet-title-color;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__icon-wrap {
|
||||
position: absolute;
|
||||
right: $u-action-sheet-header-icon-wrap-right;
|
||||
top: $u-action-sheet-header-icon-wrap-top;
|
||||
}
|
||||
}
|
||||
|
||||
&__description {
|
||||
font-size: $u-action-sheet-description-font-size;
|
||||
color: $u-tips-color;
|
||||
margin: $u-action-sheet-description-margin;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__item-wrap {
|
||||
|
||||
&__item {
|
||||
padding: $u-action-sheet-item-wrap-item-padding;
|
||||
@include flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
&__name {
|
||||
font-size: $u-action-sheet-item-wrap-name-font-size;
|
||||
color: $u-main-color;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__subname {
|
||||
font-size: $u-action-sheet-item-wrap-subname-font-size;
|
||||
color: $u-action-sheet-item-wrap-subname-color;
|
||||
margin-top: $u-action-sheet-item-wrap-subname-margin-top;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__cancel-text {
|
||||
font-size: $u-action-sheet-cancel-text-font-size;
|
||||
color: $u-action-sheet-cancel-text-color;
|
||||
text-align: center;
|
||||
padding: $u-action-sheet-cancel-text-font-size;
|
||||
}
|
||||
|
||||
&--hover {
|
||||
background-color: $u-action-sheet-cancel-text-hover-background-color;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,59 +0,0 @@
|
||||
export default {
|
||||
props: {
|
||||
// 图片地址,Array<String>|Array<Object>形式
|
||||
urls: {
|
||||
type: Array,
|
||||
default: uni.$u.props.album.urls
|
||||
},
|
||||
// 指定从数组的对象元素中读取哪个属性作为图片地址
|
||||
keyName: {
|
||||
type: String,
|
||||
default: uni.$u.props.album.keyName
|
||||
},
|
||||
// 单图时,图片长边的长度
|
||||
singleSize: {
|
||||
type: [String, Number],
|
||||
default: uni.$u.props.album.singleSize
|
||||
},
|
||||
// 多图时,图片边长
|
||||
multipleSize: {
|
||||
type: [String, Number],
|
||||
default: uni.$u.props.album.multipleSize
|
||||
},
|
||||
// 多图时,图片水平和垂直之间的间隔
|
||||
space: {
|
||||
type: [String, Number],
|
||||
default: uni.$u.props.album.space
|
||||
},
|
||||
// 单图时,图片缩放裁剪的模式
|
||||
singleMode: {
|
||||
type: String,
|
||||
default: uni.$u.props.album.singleMode
|
||||
},
|
||||
// 多图时,图片缩放裁剪的模式
|
||||
multipleMode: {
|
||||
type: String,
|
||||
default: uni.$u.props.album.multipleMode
|
||||
},
|
||||
// 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量
|
||||
maxCount: {
|
||||
type: [String, Number],
|
||||
default: uni.$u.props.album.maxCount
|
||||
},
|
||||
// 是否可以预览图片
|
||||
previewFullImage: {
|
||||
type: Boolean,
|
||||
default: uni.$u.props.album.previewFullImage
|
||||
},
|
||||
// 每行展示图片数量,如设置,singleSize和multipleSize将会无效
|
||||
rowCount: {
|
||||
type: [String, Number],
|
||||
default: uni.$u.props.album.rowCount
|
||||
},
|
||||
// 超出maxCount时是否显示查看更多的提示
|
||||
showMore: {
|
||||
type: Boolean,
|
||||
default: uni.$u.props.album.showMore
|
||||
}
|
||||
}
|
||||
}
|