Initial commit: 积分兑换电商平台多商户版 MER-2.2
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,358 @@
|
||||
<template>
|
||||
<view v-if="formsValue && formValue.length>0">
|
||||
<view v-for="(list,idx) in formValue" :key="idx" class="wrapper virtual_form bg-f boder-24">
|
||||
<!-- <view class="title">{{formsValue.name}}</view> -->
|
||||
<block v-for="(item,index) in list" :key="index">
|
||||
<view class='item acea-row row-between-wrapper'>
|
||||
<view class="name">
|
||||
<text class="item-require" v-if="item.titleShow.val">*</text>
|
||||
{{ item.titleConfig.value }}
|
||||
</view>
|
||||
<!-- radio -->
|
||||
<view v-if="item.name=='radios'" class="discount">
|
||||
<radio-group @change="radioChange($event, idx, index, item)" class="acea-row row-middle row-right">
|
||||
<label class="radio" v-for="(j,jindex) in item.wordsConfig.list" :key="jindex">
|
||||
<view class="acea-row row-middle">
|
||||
<!-- #ifndef MP -->
|
||||
<radio :value="jindex.toString()" :checked='j.show'/>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP -->
|
||||
<radio :value="jindex" :checked='j.show'/>
|
||||
<!-- #endif -->
|
||||
<view>{{j.val}}</view>
|
||||
</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<!-- checkbox -->
|
||||
<view v-if="item.name=='checkboxs'" class="discount acea-row">
|
||||
<checkbox-group @change="checkboxChange($event, idx, index, item)" class="acea-row row-middle row-right">
|
||||
<label class="radio" v-for="(j,jindex) in item.wordsConfig.list" :key="jindex">
|
||||
<view class="acea-row row-middle">
|
||||
<!-- #ifndef MP -->
|
||||
<checkbox :value="jindex.toString()" :checked="j.show" style="transform:scale(0.9)" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP -->
|
||||
<checkbox :value="jindex" :checked="j.show" style="transform:scale(0.9)" />
|
||||
<!-- #endif -->
|
||||
<view>{{j.val}}</view>
|
||||
</view>
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
<!-- text -->
|
||||
<view v-if="item.name=='texts' && item.valConfig.tabVal == 0" class="discount">
|
||||
<input type="text" :placeholder="item.tipConfig.value" placeholder-class="placeholderc" v-model="item.value" />
|
||||
</view>
|
||||
<!-- number -->
|
||||
<view v-if="item.name=='texts' && item.valConfig.tabVal == 4" class="discount">
|
||||
<input type="number" :placeholder="item.tipConfig.value" placeholder-class="placeholderc" v-model="item.value" />
|
||||
</view>
|
||||
<!-- email -->
|
||||
<view v-if="item.name=='texts' && item.valConfig.tabVal == 3" class="discount">
|
||||
<input type="text" :placeholder="item.tipConfig.value" placeholder-class="placeholderc" v-model="item.value" />
|
||||
</view>
|
||||
<!-- data -->
|
||||
<view v-if="item.name=='dates'" class="discount">
|
||||
<picker mode="date" :value="item.value" @change="bindDateChange($event,idx,index)">
|
||||
<view class="acea-row row-between-wrapper">
|
||||
<view v-if="item.value == ''">{{item.tipConfig.value}}</view>
|
||||
<view v-else>{{item.value}}</view>
|
||||
<text class='iconfont icon-ic_rightarrow'></text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<!-- dateranges -->
|
||||
<view v-if="item.name=='dateranges'" class="discount">
|
||||
<uni-datetime-picker v-model="item.value" type="daterange" @maskClick="maskClick">
|
||||
{{item.value.length?item.value[0]+' - '+item.value[1]:item.tipConfig.value}}
|
||||
<text class='iconfont icon-ic_rightarrow'></text>
|
||||
</uni-datetime-picker>
|
||||
</view>
|
||||
<!-- time -->
|
||||
<view v-if="item.name=='times'" class="discount">
|
||||
<picker mode="time" :value="item.value" @change="bindTimeChange($event, idx, index)"
|
||||
:placeholder="item.tipConfig.value">
|
||||
<view class="acea-row row-between-wrapper">
|
||||
<view v-if="item.value == ''">{{item.tipConfig.value}}</view>
|
||||
<view v-else>{{item.value}}</view>
|
||||
<text class='iconfont icon-ic_rightarrow'></text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<!-- timeranges -->
|
||||
<view v-if="item.name=='timeranges'" class="discount acea-row row-between-wrapper" @click="getTimeranges(idx,index)">
|
||||
<view v-if="item.value">{{item.value}}</view>
|
||||
<view v-else>{{item.tipConfig.value}}</view>
|
||||
<text class='iconfont icon-ic_rightarrow'></text>
|
||||
</view>
|
||||
<!-- select -->
|
||||
<view v-if="item.name=='selects'" class="discount">
|
||||
<picker :value="item.value" :range="item.wordsConfig.list" @change="bindSelectChange($event,idx,index,item)" range-key="val">
|
||||
<view class="acea-row row-between-wrapper">
|
||||
<view v-if="item.value">{{item.value}}</view>
|
||||
<view v-else>请选择</view>
|
||||
<text class='iconfont icon-ic_rightarrow'></text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<!-- city -->
|
||||
<view v-if="item.name=='citys'" class="discount" @click="changeRegion(idx,index)">
|
||||
<view class="acea-row row-middle row-right">
|
||||
<view class="city" v-if="item.value == ''">{{item.tipConfig.value}}</view>
|
||||
<view class="city" v-else>{{item.value}}</view>
|
||||
<text class='iconfont icon-ic_rightarrow'></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- id -->
|
||||
<view v-if="item.name=='texts' && item.valConfig.tabVal == 2" class="discount">
|
||||
<input type="idcard" :placeholder="item.tipConfig.value" placeholder-class="placeholderc" v-model="item.value" />
|
||||
</view>
|
||||
<!-- phone -->
|
||||
<view v-if="item.name=='texts' && item.valConfig.tabVal == 1" class="discount">
|
||||
<input type="number" :placeholder="item.tipConfig.value" placeholder-class="placeholderc" v-model="item.value" />
|
||||
</view>
|
||||
<!-- img -->
|
||||
<scroll-view scroll-x="true" show-scrollbar="false" class="item-scroll" :style="'width:'+item.scrollWidth" v-if="item.name=='uploadPicture'">
|
||||
<view class='upload' :style="'width:'+item.scrollWidth">
|
||||
<view class='pictrue acea-row row-center-wrapper row-column' @tap='uploadpic(idx,index)'
|
||||
v-if="item.value.length < item.numConfig.val">
|
||||
<image class="camera-icon" :src="`${domain}/static/images/ic_camera.png`"></image>
|
||||
<view>上传图片</view>
|
||||
</view>
|
||||
<view class='pictrue' v-for="(items,indexs) in item.value" :key="indexs">
|
||||
<image :src='items' mode="aspectFill"></image>
|
||||
<view class="close acea-row row-center-wrapper" @tap='DelPic(idx,index,indexs)'>
|
||||
<view class="iconfont icon-ic_close"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</block>
|
||||
<timeranges :isShow='isShow' :time='timeranges' @confrim="confrim" @cancel="cancels"></timeranges>
|
||||
<areaWindow ref="areaWindow" :display="display" :address='addressInfoArea' :cityShow='cityShow' @submit="OnAreaAddress" @changeClose="changeAddressClose"></areaWindow>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
const CACHE_CITY = {};
|
||||
import areaWindow from '@/components/areaWindow';
|
||||
import timeranges from '@/components/timeranges';
|
||||
import dayjs from "@/plugin/dayjs/dayjs.min.js";
|
||||
import { HTTP_REQUEST_URL } from '@/config/app';
|
||||
export default {
|
||||
components: {
|
||||
areaWindow,
|
||||
timeranges
|
||||
},
|
||||
props: {
|
||||
formsValue: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formValue: [],
|
||||
isShow: false,
|
||||
display: false,
|
||||
cityShow: 2,
|
||||
addressInfoArea: [],
|
||||
timeranges: [],
|
||||
timerangesIndex: 0,
|
||||
formIndex: 0,
|
||||
newImg: [],
|
||||
domain: HTTP_REQUEST_URL,
|
||||
};
|
||||
},
|
||||
mounted(){
|
||||
|
||||
},
|
||||
methods: {
|
||||
getFormList(form,count) {
|
||||
let arr = []
|
||||
let data = this.getFormData(form)
|
||||
for(var i=0; i<count; i++) {
|
||||
arr.push(JSON.parse(JSON.stringify(data)))
|
||||
}
|
||||
this.formValue = arr
|
||||
},
|
||||
getFormData(form) {
|
||||
let that = this;
|
||||
let formData = that.objToArr(form.value)
|
||||
formData.forEach((item, index, arr)=>{
|
||||
that.$set(item, 'value', "");
|
||||
CACHE_CITY[index] = ''; //清空省市区
|
||||
if(item.name == 'texts'){
|
||||
if(item.defaultValConfig.value){
|
||||
item.value = item.defaultValConfig.value
|
||||
}else{
|
||||
item.value = ''
|
||||
}
|
||||
}else if(item.name == 'radios'){
|
||||
item.value = item.wordsConfig.list[0].val
|
||||
}else if(item.name == 'uploadPicture'){
|
||||
item.value = [];
|
||||
item.scrollWidth = '106rpx'
|
||||
}else if(item.name == 'dateranges'){
|
||||
if(item.valConfig.tabVal==0){
|
||||
if(item.valConfig.tabData==0){
|
||||
let obj = dayjs(new Date(Number(new Date().getTime()))).format('YYYY-MM-DD');
|
||||
item.value = [obj,obj]
|
||||
}else{
|
||||
let data1 = dayjs(new Date(Number(new Date(item.valConfig.specifyDate[0]).getTime()))).format('YYYY-MM-DD');
|
||||
let data2 = dayjs(new Date(Number(new Date(item.valConfig.specifyDate[1]).getTime()))).format('YYYY-MM-DD');
|
||||
item.value = [data1,data2];
|
||||
}
|
||||
}else{
|
||||
item.value = [];
|
||||
}
|
||||
}else{
|
||||
if(['times','dates','timeranges'].indexOf(item.name) != -1){
|
||||
if(item.valConfig.tabVal==0){ //显示默认值
|
||||
if(item.valConfig.tabData==0){
|
||||
if(item.name == 'times'){
|
||||
item.value = dayjs(new Date(Number(new Date().getTime()))).format('HH:mm');
|
||||
}else if(item.name == 'dates'){
|
||||
item.value = dayjs(new Date(Number(new Date().getTime()))).format('YYYY-MM-DD');
|
||||
}else{
|
||||
let current = dayjs(new Date(Number(new Date().getTime()))).format('HH:mm');
|
||||
item.value = current+' - '+current;
|
||||
}
|
||||
}else{
|
||||
if(item.name == 'times' || item.name == 'dates'){
|
||||
item.value = item.valConfig.specifyDate;
|
||||
}else{
|
||||
item.value = item.valConfig.specifyDate[0]+' - '+item.valConfig.specifyDate[1];
|
||||
}
|
||||
}
|
||||
}else{
|
||||
item.value = '';
|
||||
}
|
||||
}else{
|
||||
item.value = '';
|
||||
}
|
||||
}
|
||||
})
|
||||
function sortNumber(a, b) {
|
||||
return a.timestamp - b.timestamp;
|
||||
}
|
||||
formData.sort(sortNumber);
|
||||
// that.$set(that, 'formValue', formData);
|
||||
return formData
|
||||
},
|
||||
// 对象转数组
|
||||
objToArr(data) {
|
||||
let obj = Object.keys(data);
|
||||
let m = obj.map(key => data[key]);
|
||||
return m;
|
||||
},
|
||||
// 单选
|
||||
radioChange(e, i, index, item){
|
||||
this.formValue[i][index].value = item.wordsConfig.list[e.detail.value].val
|
||||
},
|
||||
// 多选
|
||||
checkboxChange(e, i, index, item){
|
||||
let obj = e.detail.value;
|
||||
let val = '';
|
||||
item.wordsConfig.list.forEach((j,jindex)=>{
|
||||
obj.forEach(x=>{
|
||||
if(jindex == x){
|
||||
val = val +(val?',':'') + j.val;
|
||||
}
|
||||
})
|
||||
})
|
||||
this.formValue[i][index].value = val
|
||||
},
|
||||
bindDateChange(e, idx, index) {
|
||||
this.formValue[idx][index].value = e.target.value
|
||||
this.$forceUpdate()
|
||||
},
|
||||
bindTimeChange(e, i, index) {
|
||||
this.formValue[i][index].value = e.target.value
|
||||
},
|
||||
getTimeranges(i,index){
|
||||
this.isShow = true
|
||||
this.formIndex = i;
|
||||
this.timerangesIndex = index
|
||||
},
|
||||
bindSelectChange(e, i, index, item) {
|
||||
this.$set(this.formValue[i][index], 'value', item.wordsConfig.list[e.detail.value].val);
|
||||
},
|
||||
changeRegion(i,index){
|
||||
if(!this.formValue[i][index].value){
|
||||
this.addressInfoArea = [];
|
||||
}
|
||||
this.timerangesIndex = index;
|
||||
this.cityShow = Number(this.formValue[i][index].valConfig.tabVal) + 1;
|
||||
this.formIndex = i;
|
||||
this.display = true;
|
||||
if(CACHE_CITY[i]){
|
||||
this.addressInfoArea = CACHE_CITY[i];
|
||||
}
|
||||
},
|
||||
/**上传文件*/
|
||||
uploadpic: function(idx,index) {
|
||||
let that = this;
|
||||
this.$util.uploadImageOne('upload/image', function(res) {
|
||||
let arr = that.formValue[idx][index]['value'];
|
||||
arr.push(res.data.path);
|
||||
that.$set(that.formValue[idx][index], 'value', arr);
|
||||
that.$set(that.formValue[idx][index], 'scrollWidth', (arr.length+1)*118+'rpx');
|
||||
});
|
||||
},
|
||||
/** 删除图片*/
|
||||
DelPic: function(idx,index, indexs) {
|
||||
let that = this,
|
||||
pic = this.formValue[idx][index].value;
|
||||
that.formValue[idx][index].value.splice(indexs, 1);
|
||||
that.$set(that.formValue[idx][index], 'value', that.formValue[index].value);
|
||||
},
|
||||
OnAreaAddress(address){
|
||||
let addr = '';
|
||||
addr = address.map(v=>v.name).join('/');
|
||||
this.formValue[this.formIndex][this.timerangesIndex].value = addr;
|
||||
CACHE_CITY[this.timerangesIndex] = address;
|
||||
},
|
||||
// 关闭地址弹窗;
|
||||
changeAddressClose: function() {
|
||||
this.display = false;
|
||||
},
|
||||
confrim(e){
|
||||
this.isShow = false;
|
||||
this.$set(this.formValue[this.formIndex][this.timerangesIndex], 'value', e.time);
|
||||
let arrayNew = [];
|
||||
e.val.forEach(item=>{
|
||||
arrayNew.push(Number(item))
|
||||
})
|
||||
this.timeranges = arrayNew;
|
||||
},
|
||||
cancels(){
|
||||
this.isShow = false;
|
||||
},
|
||||
getFormValue() {
|
||||
return this.formValue
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.discount {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
*此函数的作用是根据传入的一个日期,返回这一周的日期或者这一个月的日期,
|
||||
* 如果是月的话注意还包含上个月和下个月的日期,月的话总共数据有 6 * 7 = 42个
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* 时间格式化函数
|
||||
* 重要提示,微信小程序new Date('2020-04-16')在ios中无法获取时间对象
|
||||
* 解决方式: 建议将时间都格式化成'2020/04/16 00:00:00'的格式
|
||||
* 函数示例: formatDate(new Date(), 'YYYY/MM/dd hh:mm:ss')
|
||||
*/
|
||||
export const formatDate = (date, fmt) => {
|
||||
if (/(y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
|
||||
}
|
||||
let o = {
|
||||
'M+': date.getMonth() + 1,
|
||||
'd+': date.getDate(),
|
||||
'h+': date.getHours(),
|
||||
'm+': date.getMinutes(),
|
||||
's+': date.getSeconds()
|
||||
}
|
||||
for (let k in o) {
|
||||
if (new RegExp(`(${k})`).test(fmt)) {
|
||||
let str = o[k] + ''
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str))
|
||||
}
|
||||
}
|
||||
return fmt
|
||||
}
|
||||
const padLeftZero = (str) => {
|
||||
return ('00' + str).substr(str.length)
|
||||
}
|
||||
export const judgeType = (s) => {
|
||||
// 函数返回数据的具体类型
|
||||
return Object.prototype.toString.call(s).slice(8,-1);
|
||||
}
|
||||
export const equalDate = (d1, d2) => {
|
||||
let result = false;
|
||||
if (d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate()) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* 比较时间,时间格式为2020-04-04
|
||||
*/
|
||||
export const dateEqual = (before, after) => {
|
||||
before = new Date(before.replace('-', '/').replace('-', '/'))
|
||||
after = new Date(after.replace('-', '/').replace('-', '/'))
|
||||
if (before.getTime() - after.getTime() === 0) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export const gegerateDates = (date = new Date(), type='week') => {
|
||||
const result = [];
|
||||
if (judgeType(date) === 'Date') {
|
||||
// 年,月,日
|
||||
const y = date.getFullYear();
|
||||
const m = date.getMonth();
|
||||
const d = date.getDate();
|
||||
const days = new Date(y, m+1, 0).getDate();
|
||||
// 获取日期是星期几
|
||||
let weekIndex = date.getDay() === 0 ? 7 : date.getDay();
|
||||
if (type === 'month') {
|
||||
const dobj = new Date(y,m,1);
|
||||
weekIndex = dobj.getDay() === 0 ? 7 : dobj.getDay();
|
||||
}
|
||||
if (type === 'week') {
|
||||
for(let i = weekIndex - 1; i >0; i--) {
|
||||
const dtemp = new Date(y,m,d);
|
||||
dtemp.setDate(dtemp.getDate() - i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: dtemp.getMonth()+1 == new Date(y,m,d).getMonth() + 1,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
})
|
||||
}
|
||||
for(let i = 0; i <= 7 - weekIndex; i++) {
|
||||
const dtemp = new Date(y,m,d);
|
||||
dtemp.setDate(dtemp.getDate() + i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: dtemp.getMonth()+1 == new Date(y,m,d).getMonth() + 1,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
})
|
||||
}
|
||||
} else if (type === 'month') {
|
||||
// 上个月
|
||||
for(let i = weekIndex - 1; i > 0; i--) {
|
||||
const dtemp = new Date(y,m,1);
|
||||
dtemp.setDate(dtemp.getDate() - i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: false,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
});
|
||||
}
|
||||
// 这个月的日期
|
||||
for (let i = 0; i < days; i++) {
|
||||
const dtemp = new Date(y,m,1);
|
||||
dtemp.setDate(dtemp.getDate() + i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: true,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
});
|
||||
}
|
||||
const len = 42 - result.length;
|
||||
// 下个月的日期
|
||||
for (let i = 1; i <= len;i++) {
|
||||
const dtemp = new Date(y,m+1,0);
|
||||
dtemp.setDate(dtemp.getDate() + i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: false,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,476 @@
|
||||
<template>
|
||||
<view class="zzx-calendar">
|
||||
<view class="calendar-heander acea-row row-center-wrapper">
|
||||
<view class="title">预约时间</view>
|
||||
<view class="iconfont icon-ic_left2" :class="ymArr?'':'text-w111-ddd'" @click="daysPre(1)"></view>
|
||||
<view class="dates">{{timeStr}}</view>
|
||||
<view class="iconfont icon-ic_right2" @click="daysNext(1)"></view>
|
||||
<view class="back-today" @click="goback" v-if="showBack">
|
||||
返回今日
|
||||
</view>
|
||||
</view>
|
||||
<view class="calendar-weeks">
|
||||
<view class="calendar-week" v-for="(week, index) in weeks" :key="index">
|
||||
{{week}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="calendar-content">
|
||||
<view class="calendar-swiper" :style="{
|
||||
width: '100%',
|
||||
height: sheight
|
||||
}" :indicator-dots="false" :autoplay="false" :duration="duration" :current="current" @change="changeSwp"
|
||||
:circular="true">
|
||||
<view class="calendar-item" v-for="sitem in swiper" :key="sitem">
|
||||
<view class="calendar-days">
|
||||
<template v-if="sitem === current">
|
||||
<view class="calendar-day" v-for="(item,index) in days" :key="index" :class="{
|
||||
'day-hidden': !item.show
|
||||
}" @click="clickItem(item)">
|
||||
<view class="date" :class="[
|
||||
dotListData.indexOf(item.fullDate)==-1?'text-w111-ccc':'',
|
||||
item.isToday ? todayClass : '',
|
||||
item.fullDate == selectedDate ? checkedClass : ''
|
||||
]">
|
||||
<text v-if="item.isToday">今</text>
|
||||
<text v-else>{{item.time.getDate()>9?item.time.getDate():'0'+item.time.getDate()}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="current - sitem === 1 || current-sitem ===-2">
|
||||
<view class="calendar-day" v-for="(item,index) in predays" :key="index" :class="{
|
||||
'day-hidden': !item.show
|
||||
}">
|
||||
<view class="date" :class="[
|
||||
item.isToday ? todayClass : ''
|
||||
]">
|
||||
{{item.time.getDate()}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="calendar-day" v-for="(item,index) in nextdays" :key="index" :class="{
|
||||
'day-hidden': !item.show
|
||||
}">
|
||||
<view class="date" :class="[
|
||||
item.isToday ? todayClass : ''
|
||||
]">
|
||||
{{item.time.getDate()}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mode-change" @click="changeMode">
|
||||
<view class="iconfont" :class="weekMode ? 'icon-ic_downarrow' : 'icon-ic_uparrow'">
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
gegerateDates,
|
||||
dateEqual,
|
||||
formatDate
|
||||
} from './generateDates.js';
|
||||
export default {
|
||||
props: {
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 500
|
||||
},
|
||||
dotList: {
|
||||
type: Array, /// 打点日期列表
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
reservationDefaultDate:{
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
showBack: {
|
||||
type: Boolean, // 是否返回今日
|
||||
default: false
|
||||
},
|
||||
todayClass: {
|
||||
type: String, // 今日的自定义样式class
|
||||
default: 'is-today'
|
||||
},
|
||||
checkedClass: {
|
||||
type: String, // 选中日期的样式class
|
||||
default: 'is-checked'
|
||||
},
|
||||
dotStyle: {
|
||||
type: Object, // 打点日期的自定义样式
|
||||
default () {
|
||||
return {
|
||||
background: '#c6c6c6'
|
||||
}
|
||||
}
|
||||
},
|
||||
initDay: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
dotList: function(newvalue) {
|
||||
const days = this.days.slice(0);
|
||||
this.days = days;
|
||||
},
|
||||
reservationDefaultDate: function(newvalue){
|
||||
this.selectedDate = newvalue
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
ymArr() {
|
||||
const nowY = new Date().getFullYear()
|
||||
const nowM = new Date().getMonth() + 1
|
||||
return nowY<this.currentYear || (nowY==this.currentYear && parseInt(nowM)<parseInt(this.currentMonth));
|
||||
},
|
||||
dotListData(){
|
||||
let data = [];
|
||||
this.dotList.forEach(item=>{
|
||||
data.push(item.date)
|
||||
})
|
||||
return data
|
||||
},
|
||||
sheight() {
|
||||
// 根据年月判断有多少行
|
||||
// 判断该月有多少天
|
||||
let h = '70rpx';
|
||||
if (!this.weekMode) {
|
||||
const d = new Date(this.currentYear, this.currentMonth, 0);
|
||||
const days = d.getDate(); // 判断本月有多少天
|
||||
let day = new Date(d.setDate(1)).getDay();
|
||||
if (day === 0) {
|
||||
day = 7;
|
||||
}
|
||||
const pre = 8 - day;
|
||||
const rows = Math.ceil((days - pre) / 7) + 1;
|
||||
h = 70 * rows + 'rpx'
|
||||
}
|
||||
return h
|
||||
},
|
||||
timeStr() {
|
||||
let str = '';
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate);
|
||||
const y = d.getFullYear();
|
||||
const m = (d.getMonth() + 1) <= 9 ? `0${d.getMonth()+1}` : d.getMonth() + 1;
|
||||
str = `${y}年${m}月`;
|
||||
return str;
|
||||
},
|
||||
predays() {
|
||||
let pres = [];
|
||||
if (this.weekMode) {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate)
|
||||
d.setDate(d.getDate() - 7);
|
||||
pres = gegerateDates(d, 'week')
|
||||
} else {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 2, 1)
|
||||
pres = gegerateDates(d, 'month')
|
||||
}
|
||||
return pres;
|
||||
},
|
||||
nextdays() {
|
||||
let nexts = [];
|
||||
if (this.weekMode) {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate)
|
||||
d.setDate(d.getDate() + 7);
|
||||
nexts = gegerateDates(d, 'week')
|
||||
} else {
|
||||
const d = new Date(this.currentYear, this.currentMonth, 1)
|
||||
nexts = gegerateDates(d, 'month')
|
||||
}
|
||||
return nexts;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
weeks: ['一', '二', '三', '四', '五', '六', '日'],
|
||||
current: 1,
|
||||
currentYear: '',
|
||||
currentMonth: '',
|
||||
currentDate: '',
|
||||
days: [],
|
||||
weekMode: true,
|
||||
swiper: [1],
|
||||
selectedDate: this.initDay
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
changeSwp(e) {
|
||||
const pre = this.current;
|
||||
const current = e.target.current;
|
||||
/* 根据前一个减去目前的值我们可以判断是下一个月/周还是上一个月/周
|
||||
*current - pre === 1, -2时是下一个月/周
|
||||
*current -pre === -1, 2时是上一个月或者上一周
|
||||
*/
|
||||
this.current = current;
|
||||
if (current - pre === 1 || current - pre === -2) {
|
||||
this.daysNext();
|
||||
} else {
|
||||
this.daysPre();
|
||||
}
|
||||
},
|
||||
// 初始化日历的方法
|
||||
initDate(cur) {
|
||||
let date = ''
|
||||
if (cur) {
|
||||
date = new Date(cur)
|
||||
} else {
|
||||
date = new Date()
|
||||
}
|
||||
this.currentDate = date.getDate() // 今日日期 几号
|
||||
this.currentYear = date.getFullYear() // 当前年份
|
||||
this.currentMonth = date.getMonth() + 1 // 当前月份
|
||||
this.currentWeek = date.getDay() === 0 ? 7 : date.getDay() // 1...6,0 // 星期几
|
||||
const nowY = new Date().getFullYear() // 当前年份
|
||||
const nowM = new Date().getMonth() + 1
|
||||
const nowD = new Date().getDate() // 今日日期 几号
|
||||
const nowW = new Date().getDay();
|
||||
this.days = [];
|
||||
let days = [];
|
||||
if (this.weekMode) {
|
||||
days = gegerateDates(date, 'week');
|
||||
} else {
|
||||
days = gegerateDates(date, 'month');
|
||||
}
|
||||
this.days = days;
|
||||
// 派发事件,时间发生改变
|
||||
let obj = {
|
||||
start: '',
|
||||
end: ''
|
||||
};
|
||||
if (this.weekMode) {
|
||||
obj.start = this.days[0].time;
|
||||
obj.end = this.days[6].time
|
||||
} else {
|
||||
const start = new Date(this.currentYear, this.currentMonth - 1, 1);
|
||||
const end = new Date(this.currentYear, this.currentMonth, 0);
|
||||
obj.start = start;
|
||||
obj.end = end;
|
||||
}
|
||||
this.$emit('days-change', obj)
|
||||
},
|
||||
// 上一个
|
||||
daysPre(num) {
|
||||
if(!this.ymArr) return
|
||||
if (this.weekMode && !num) {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate);
|
||||
d.setDate(d.getDate() - 7);
|
||||
this.initDate(d);
|
||||
} else {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 2, 1);
|
||||
this.initDate(d);
|
||||
}
|
||||
this.$emit('dateChange', this.currentYear + '-' + (this.currentMonth<10?'0'+this.currentMonth:this.currentMonth)); //传给调用模板页面去拿新数据
|
||||
},
|
||||
// 下一个
|
||||
daysNext(num) {
|
||||
if (this.weekMode && !num) {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate);
|
||||
d.setDate(d.getDate() + 7);
|
||||
this.initDate(d);
|
||||
} else {
|
||||
const d = new Date(this.currentYear, this.currentMonth, 1);
|
||||
this.initDate(d);
|
||||
}
|
||||
this.$emit('dateChange', this.currentYear + '-' + (this.currentMonth<10?'0'+this.currentMonth:this.currentMonth)); //传给调用模板页面去拿新数据
|
||||
},
|
||||
changeMode() {
|
||||
const premode = this.weekMode;
|
||||
let isweek = false;
|
||||
if (premode) {
|
||||
isweek = !!this.days.find(item => item.fullDate === this.selectedDate)
|
||||
}
|
||||
this.weekMode = !this.weekMode;
|
||||
let d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate)
|
||||
const sel = new Date(this.selectedDate.replace('-', '/').replace('-', '/'));
|
||||
const isMonth = sel.getFullYear() === this.currentYear && (sel.getMonth() + 1) === this.currentMonth;
|
||||
if ((this.selectedDate && isMonth) || isweek) {
|
||||
d = new Date(this.selectedDate.replace('-', '/').replace('-', '/'))
|
||||
}
|
||||
this.initDate(d)
|
||||
},
|
||||
// 点击日期
|
||||
clickItem(e) {
|
||||
if(this.dotListData.indexOf(e.fullDate)==-1 || e.fullDate == this.selectedDate) return
|
||||
this.selectedDate = e.fullDate;
|
||||
this.$emit('dayChange', e.fullDate);
|
||||
},
|
||||
goback() {
|
||||
const d = new Date();
|
||||
this.initDate(d);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initDate();
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.text-w111-ccc{
|
||||
color: #ccc !important;
|
||||
}
|
||||
.text-w111-ddd {
|
||||
color: #ddd;
|
||||
}
|
||||
.zzx-calendar {
|
||||
width: 710rpx;
|
||||
height: auto;
|
||||
background-color: #ffffff;
|
||||
margin: 20rpx auto 0 auto;
|
||||
border-radius: 16rpx;
|
||||
padding-top: 20rpx;
|
||||
.calendar-heander {
|
||||
text-align: center;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
position: relative;
|
||||
font-size: 30rpx;
|
||||
.iconfont{
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
text-align: center;
|
||||
line-height: 52rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.dates {
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
.title{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
padding-left: 24rpx;
|
||||
}
|
||||
.back-today {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 100rpx;
|
||||
height: 30rpx;
|
||||
line-height: 30rpx;
|
||||
font-size: 20rpx;
|
||||
top: 15rpx;
|
||||
border-radius: 15rpx 0 0 15rpx;
|
||||
color: #ffffff;
|
||||
background-color: #FF6633;
|
||||
}
|
||||
}
|
||||
.calendar-weeks {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
margin: 26rpx 0 14rpx 0;
|
||||
.calendar-week {
|
||||
width: calc(100% / 7);
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
swiper {
|
||||
width: 100%;
|
||||
height: 60rpx;
|
||||
}
|
||||
.calendar-content {
|
||||
min-height: 60rpx;
|
||||
}
|
||||
.calendar-swiper {
|
||||
min-height: 70rpx;
|
||||
transition: height ease-out 0.3s;
|
||||
}
|
||||
.calendar-item {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.calendar-days {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
.calendar-day {
|
||||
width: calc(100% / 7);
|
||||
height: 70rpx;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.day-hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
.mode-change {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 10rpx;
|
||||
.iconfont{
|
||||
width: 80rpx;
|
||||
height: 60rpx;
|
||||
line-height: 32rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.mode-arrow-top {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 12rpx solid transparent;
|
||||
border-right: 12rpx solid transparent;
|
||||
border-bottom: 10rpx solid #FF6633;
|
||||
}
|
||||
.mode-arrow-bottom {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 12rpx solid transparent;
|
||||
border-right: 12rpx solid transparent;
|
||||
border-top: 10rpx solid #FF6633;
|
||||
}
|
||||
}
|
||||
.is-today {
|
||||
background: #ffffff;
|
||||
border-radius: 50%;
|
||||
// color: var(--view-theme);
|
||||
}
|
||||
.is-checked {
|
||||
@include main_color(theme);
|
||||
@include coupons_light_color(theme);
|
||||
font-weight: 500;
|
||||
}
|
||||
.date {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
margin: 0 auto;
|
||||
border-radius: 50rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.dot-show {
|
||||
margin-top: 4rpx;
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
background: #c6c6c6;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user