first commit
3
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"git.ignoreLimitWarning": true
|
||||
}
|
||||
28
app.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// app.js
|
||||
App({
|
||||
onLaunch() {
|
||||
|
||||
},
|
||||
globalData: {
|
||||
userInfo: null,
|
||||
usersaveinfo: null,
|
||||
baseimgurl: 'https://ndnd.duiduiedu.com/',
|
||||
// baseimgurl:'http://127.0.0.1:8081',
|
||||
// baseUrl: 'http://127.0.0.1:8006/addons/unishop',
|
||||
baseUrl: 'https://ndnd.duiduiedu.com/addons/unishop',
|
||||
wxopenid: '',
|
||||
session_key: '',
|
||||
currentuserinfo: null,
|
||||
wxuserid: 1,
|
||||
picspaht: 'https://ndnd.duiduiedu.com/uploads/pics'
|
||||
},
|
||||
islogin: function () {
|
||||
const userinfo = wx.getStorageSync('userinfo');
|
||||
if (userinfo == null || userinfo.length == 0) {
|
||||
wx.redirectTo({
|
||||
url: '/pages/userlogin/userlogin',
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
140
app.json
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
{
|
||||
"pages": [
|
||||
"pages/index/index",
|
||||
"pages/indexlives/indexlives",
|
||||
"pages/leftright/leftright",
|
||||
"pages/mine/mine",
|
||||
"pages/tarbar/tarbar",
|
||||
"pages/grid/grid",
|
||||
"pages/picsdisplay/picsdisplay",
|
||||
"pages/swipecell/swipecell",
|
||||
"pages/main/main",
|
||||
"pages/livelist/livelist",
|
||||
"pages/courselearning/courselearning",
|
||||
"pages/messageencyclopedias/messageencyclopedias",
|
||||
"pages/messagelist/messagelist",
|
||||
"pages/communityinfo/communityinfo",
|
||||
"pages/allpapers/allpapers",
|
||||
"pages/examlist/examlist",
|
||||
"pages/caogaozhi/caogaozhi",
|
||||
"pages/examing/examing",
|
||||
"pages/singledouble/singledouble",
|
||||
"pages/exampaper/exampaper",
|
||||
"pages/exampaper2/exampaper2",
|
||||
"pages/examanalysis/examanalysis",
|
||||
"pages/explainnote/explainnote",
|
||||
"pages/exammakings/exammakings",
|
||||
"pages/examproblem/examproblem",
|
||||
"pages/userlogin/userlogin",
|
||||
"pages/communitylist/communitylist",
|
||||
"pages/communityitemlist/communityitemlist",
|
||||
"pages/viprecharge/viprecharge",
|
||||
"pages/vipquanyi/vipquanyi",
|
||||
"pages/chargeshop/chargeshop",
|
||||
"pages/goodsinfo/goodsinfo",
|
||||
"pages/collectionsub/collectionsub",
|
||||
"pages/collectioncourse/collectioncourse",
|
||||
"pages/myaddress/myaddress",
|
||||
"pages/myorder/myorder",
|
||||
"pages/livetest/livetest",
|
||||
"pages/mycommunityinfo/mycommunityinfo",
|
||||
"pages/myexamanalysis/myexamanalysis",
|
||||
"pages/newtest/newtest",
|
||||
"pages/vipmonth/vipmonth",
|
||||
"pages/createwords/createwords",
|
||||
"pages/communityinfocomment/communityinfocomment",
|
||||
"pages/knowledge/knowledge",
|
||||
"pages/daitika/daitika",
|
||||
"pages/newmine/newmine",
|
||||
"pages/indexcourselearning/indexcourselearning",
|
||||
"pages/indexreslists/indexreslists",
|
||||
"pages/indexrespage/indexrespage",
|
||||
"pages/indexlivesvoid/indexlivesvoid",
|
||||
"pages/indexsq/indexsq",
|
||||
"pages/indexclass/indexclass",
|
||||
"pages/indexclassintro/indexclassintro",
|
||||
"pages/indexclasszx/indexclasszx",
|
||||
"pages/indexjobtask/indexjobtask",
|
||||
"pages/indexcreatewords/indexcreatewords",
|
||||
"pages/indexclassres/indexclassres",
|
||||
"pages/mytest/mytest",
|
||||
"pages/indexclasssubwork/indexclasssubwork",
|
||||
"pages/indexcreatewordssubwork/indexcreatewordssubwork",
|
||||
"pages/indexobjectivework/indexobjectivework",
|
||||
"pages/indexobjectactivelist/indexobjectactivelist",
|
||||
"pages/indexobjectactiveworkok/indexobjectactiveworkok",
|
||||
"pages/indexreslistsnew/indexreslistsnew",
|
||||
"pages/classindex/classindex",
|
||||
"pages/classcommunityitemlist/classcommunityitemlist",
|
||||
"pages/classcourselearning/classcourselearning",
|
||||
"pages/camp_list/index",
|
||||
"pages/camp_detail/index",
|
||||
"pages/camp_task_text_image/index",
|
||||
"pages/camp_task_subjective_question/index",
|
||||
"pages/camp_task_essay_question/index",
|
||||
"pages/camp_task_objective_questions/index",
|
||||
"pages/camp_task_objective_questions_result/index"
|
||||
],
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#fff",
|
||||
"navigationBarTitleText": "Weixin",
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"usingComponents": {
|
||||
"van-button": "@vant/weapp/button/index",
|
||||
"van-tab": "@vant/weapp/tab/index",
|
||||
"van-tabs": "@vant/weapp/tabs/index",
|
||||
"van-cell": "@vant/weapp/cell/index",
|
||||
"van-cell-group": "@vant/weapp/cell-group/index",
|
||||
"van-tabbar": "@vant/weapp/tabbar/index",
|
||||
"van-tabbar-item": "@vant/weapp/tabbar-item/index",
|
||||
"van-grid": "@vant/weapp/grid/index",
|
||||
"van-grid-item": "@vant/weapp/grid-item/index",
|
||||
"van-image": "@vant/weapp/image/index",
|
||||
"van-swipe-cell": "@vant/weapp/swipe-cell/index",
|
||||
"van-divider": "@vant/weapp/divider/index",
|
||||
"van-progress": "@vant/weapp/progress/index",
|
||||
"van-count-down": "@vant/weapp/count-down/index",
|
||||
"van-circle": "@vant/weapp/circle/index",
|
||||
"van-dialog": "@vant/weapp/dialog/index",
|
||||
"van-overlay": "@vant/weapp/overlay/index",
|
||||
"van-field": "@vant/weapp/field/index",
|
||||
"van-switch": "@vant/weapp/switch/index",
|
||||
"van-dropdown-menu": "@vant/weapp/dropdown-menu/index",
|
||||
"van-dropdown-item": "@vant/weapp/dropdown-item/index",
|
||||
"van-popup": "@vant/weapp/popup/index",
|
||||
"van-action-sheet": "@vant/weapp/action-sheet/index",
|
||||
"van-toast": "@vant/weapp/toast/index",
|
||||
"van-calendar": "@vant/weapp/calendar/index",
|
||||
"calendar": "/components/calendar/calendar",
|
||||
"van-checkbox": "@vant/weapp/checkbox/index",
|
||||
"van-checkbox-group": "@vant/weapp/checkbox-group/index",
|
||||
"pause-mask": "/components/pause-mask/index"
|
||||
},
|
||||
"sitemapLocation": "sitemap.json",
|
||||
"tabBar": {
|
||||
"color": "#66666",
|
||||
"selectedColor": "#f10b2e",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/index/index",
|
||||
"text": "怼学习",
|
||||
"iconPath": "./img/footerpic.png",
|
||||
"selectedIconPath": "./img/footerpic1.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/indexsq/indexsq",
|
||||
"text": "怼社区",
|
||||
"iconPath": "./img/footerpic.png",
|
||||
"selectedIconPath": "./img/footerpic2.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/mine/mine",
|
||||
"text": "怼自己",
|
||||
"iconPath": "./img/footerpic.png",
|
||||
"selectedIconPath": "./img/footerpic3.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
11
app.wxss
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
@import './miniprogram_npm/@vant/weapp/common/index.wxss';
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content:space-between;
|
||||
padding: 20rpx 10rpx;
|
||||
box-sizing: border-box;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
BIN
assets/icons/1.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
assets/icons/2.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
assets/icons/3.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
assets/icons/add-comment.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
assets/icons/close.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
assets/icons/courses.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
assets/icons/default.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
assets/icons/notpurchased.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
assets/icons/pause.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
assets/icons/play.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
assets/icons/unlock.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/images/背景.png
Normal file
|
After Width: | Height: | Size: 156 KiB |
149
components/calendar/calendar.js
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
// components/calendar/calendar.js
|
||||
const dayjs = require("./dayjs")
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
//底下需要展示小圆点的日期数组
|
||||
spot: {
|
||||
type: Array,
|
||||
value: []
|
||||
},
|
||||
//组件渲染时默认选中的时间
|
||||
defaultDate: {
|
||||
type: String,
|
||||
optionalTypes: [Date, Number],
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
dateList: [], //日历主体渲染数组
|
||||
selectDay: {}, //选中时间
|
||||
open: true, //日历是否展开
|
||||
transform: 0 //收起时日历高度偏移倍数
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
//picker设置月份
|
||||
editMonth(e) {
|
||||
const arr = e.detail.value.split("-")
|
||||
this.setDate(parseInt(arr[0]), parseInt(arr[1]) - 1)
|
||||
},
|
||||
//上月切换按钮点击
|
||||
lastMonth() {
|
||||
const lastMonth = dayjs(new Date(this.data.selectDay.year, this.data.selectDay.month - 1))
|
||||
this.setDate(lastMonth.year(), lastMonth.month())
|
||||
},
|
||||
//下月切换按钮点击
|
||||
nextMonth() {
|
||||
const nextMonth = dayjs(new Date(this.data.selectDay.year, this.data.selectDay.month + 1))
|
||||
this.setDate(nextMonth.year(), nextMonth.month())
|
||||
},
|
||||
//设置选中日期
|
||||
setDate(paramYear, paramMonth, paramDate) {
|
||||
const date = Math.min(dayjs(`${paramYear}-${paramMonth + 1}`).daysInMonth(), this.data.selectDay.date)
|
||||
const time = dayjs(`${paramYear}-${paramMonth + 1}-${paramDate || date}`)
|
||||
const selectDay = {
|
||||
year: paramYear,
|
||||
month: paramMonth,
|
||||
date: paramDate || date,
|
||||
dateString: time.format("YYYY-MM-DD"),
|
||||
}
|
||||
//设置收起时的日历主体偏移量
|
||||
let dateListStart = dayjs(`${paramYear}-${paramMonth + 1}`).day(0)
|
||||
this.setData({
|
||||
transform: dayjs(`${paramYear}-${paramMonth + 1}-${paramDate || date}`).day(0).diff(dateListStart, 'week')
|
||||
})
|
||||
if (paramYear !== this.data.selectDay.year) {
|
||||
this.setData({
|
||||
selectDay,
|
||||
open: true
|
||||
})
|
||||
this.dateListInit(paramYear, paramMonth)
|
||||
this.triggerEvent("dateChange", this.data.selectDay)
|
||||
this.triggerEvent("monthChange", this.data.selectDay)
|
||||
this.triggerEvent("yearChange", this.data.selectDay)
|
||||
return
|
||||
}
|
||||
if (paramMonth !== this.data.selectDay.month) {
|
||||
this.setData({
|
||||
selectDay,
|
||||
open: true
|
||||
})
|
||||
this.dateListInit(paramYear, paramMonth)
|
||||
this.triggerEvent("dateChange", this.data.selectDay)
|
||||
this.triggerEvent("monthChange", this.data.selectDay)
|
||||
return
|
||||
}
|
||||
if (paramDate && paramDate !== this.data.selectDay.date) {
|
||||
this.setData({
|
||||
selectDay
|
||||
})
|
||||
this.triggerEvent("dateChange", this.data.selectDay)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
//展开收起
|
||||
openChange() {
|
||||
this.setData({
|
||||
open: !this.data.open
|
||||
})
|
||||
},
|
||||
|
||||
//日历主体的渲染方法
|
||||
dateListInit(paramYear = this.data.selectDay.year, paramMonth = this.data.selectDay.month) {
|
||||
let dateList = []; //需要遍历的日历数组数据
|
||||
let startDate = dayjs(`${paramYear}-${paramMonth + 1}`).day(0) //日历渲染开始日期
|
||||
let endDate = dayjs(`${paramYear}-${paramMonth + 1}`).endOf('month').day(6) //日历主体渲染结束日期
|
||||
const timeArr = this.data.spot.map(item => {
|
||||
return dayjs(item).format('YYYY-MM-DD')
|
||||
}) //底部小圆点需要展示的数组
|
||||
while (startDate < endDate) {
|
||||
const dateString = startDate.format("YYYY-MM-DD")
|
||||
dateList.push({
|
||||
date: startDate.date(),
|
||||
month: startDate.month(),
|
||||
year: startDate.year(),
|
||||
dateString,
|
||||
spot: timeArr.indexOf(dateString) !== -1
|
||||
})
|
||||
startDate = startDate.add(1, 'day')
|
||||
}
|
||||
this.setData({
|
||||
dateList: dateList
|
||||
})
|
||||
},
|
||||
|
||||
//某一天被点击时
|
||||
selectChange(e) {
|
||||
const year = e.currentTarget.dataset.year
|
||||
const month = e.currentTarget.dataset.month
|
||||
const date = e.currentTarget.dataset.date
|
||||
this.setDate(year, month, date)
|
||||
}
|
||||
},
|
||||
//组件生命周期
|
||||
lifetimes: {
|
||||
attached() {
|
||||
let now = this.data.defaultDate ? dayjs(this.data.defaultDate) : dayjs()
|
||||
this.setDate(now.year(), now.month(), now.date())
|
||||
}
|
||||
},
|
||||
//监听参数变化
|
||||
observers: {
|
||||
spot: function (spot) {
|
||||
console.log("==========")
|
||||
console.log(spot);
|
||||
this.dateListInit()
|
||||
}
|
||||
}
|
||||
})
|
||||
4
components/calendar/calendar.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
38
components/calendar/calendar.wxml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<!--components/calendar/calendar.wxml-->
|
||||
<view class="calendar">
|
||||
<view class="title flex">
|
||||
<view class="flex">
|
||||
<picker value="{{selectDay.year+'-'+(selectDay.month+1)}}" bindchange="editMonth" mode="date" fields="month" class="year-month">{{selectDay.year}}.{{selectDay.month>8?selectDay.month+1:"0"+(selectDay.month+1)}}</picker>
|
||||
<view class="last-icon" bindtap="lastMonth"> </view>
|
||||
<view class="next-icon" bindtap="nextMonth"> </view>
|
||||
</view>
|
||||
<view catchtap="openChange" class="flex open">
|
||||
<view>{{open?"收起":"展开"}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 日历头部 -->
|
||||
<view class="flex-around calendar-week">
|
||||
<view class="view">日</view>
|
||||
<view class="view">一</view>
|
||||
<view class="view">二</view>
|
||||
<view class="view">三</view>
|
||||
<view class="view">四</view>
|
||||
<view class="view">五</view>
|
||||
<view class="view">六</view>
|
||||
</view>
|
||||
|
||||
<!-- 日历主体 -->
|
||||
<view class="calendar-main">
|
||||
<view class="date-group" style="height:{{open? dateList.length/7*72 : 72}}rpx;">
|
||||
<view class="flex-start flex-wrap date-transform" style="transform: translateY({{open?0:-72*transform}}rpx);">
|
||||
<view wx:for="{{dateList}}" wx:key="dateList" class="day">
|
||||
<view class="bg {{(item.year === selectDay.year && item.month === selectDay.month) ?'': 'other-month'}} {{item.dateString === selectDay.dateString?'select':''}}" catchtap="selectChange" data-date="{{item.date}}" data-year="{{item.year}}" data-month="{{item.month}}" data-date-string="{{item.dateString}}">
|
||||
{{item.date}}
|
||||
</view>
|
||||
<view class="spot" wx:if="{{item.spot}}"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
157
components/calendar/calendar.wxss
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/* components/calendar/calendar.wxss */
|
||||
.flex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-start {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-end {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-around {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.align-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.align-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.calendar {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.calendar .title {
|
||||
font-size: 40rpx;
|
||||
color: #333;
|
||||
padding: 30rpx;
|
||||
line-height: 60rpx;
|
||||
}
|
||||
|
||||
.calendar .title .year-month {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.calendar .title .last-icon {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-right: 24rpx solid #999;
|
||||
border-top: 12rpx solid transparent;
|
||||
border-bottom: 12rpx solid transparent;
|
||||
margin-left: 10rpx;
|
||||
|
||||
}
|
||||
|
||||
.calendar .title .next-icon {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 24rpx solid #999;
|
||||
border-top: 12rpx solid transparent;
|
||||
border-bottom: 12rpx solid transparent;
|
||||
margin-left: 40rpx;
|
||||
}
|
||||
|
||||
.calendar .title .open {
|
||||
background-color: #f6f6f6;
|
||||
color: #999;
|
||||
font-size: 22rpx;
|
||||
line-height: 36rpx;
|
||||
border-radius: 18rpx;
|
||||
padding: 0 14rpx;
|
||||
}
|
||||
|
||||
.calendar .calendar-week {
|
||||
line-height: 40rpx;
|
||||
padding: 0 25rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.calendar .calendar-week .view {
|
||||
width: 100rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.calendar .calendar-main {
|
||||
padding: 30rpx 25rpx;
|
||||
}
|
||||
|
||||
.calendar .calendar-main .date-group {
|
||||
transition: all 0.3s;
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
.calendar .calendar-main .date-transform {
|
||||
transition: all 0.3s;
|
||||
|
||||
}
|
||||
|
||||
.calendar .calendar-main .day {
|
||||
position: relative;
|
||||
width: 100rpx;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
height: 72rpx;
|
||||
}
|
||||
|
||||
.calendar .calendar-main .day .bg {
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.calendar .calendar-main .day .select {
|
||||
width: 56rpx;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background: #409eff;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.calendar .calendar-main .day .other-month {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.calendar .calendar-main .day .spot {
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
background-color: #409eff;
|
||||
border-radius: 50%;
|
||||
margin: 6rpx auto 0;
|
||||
}
|
||||
1
components/calendar/dayjs.js
Normal file
19
components/pause-mask/index.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Component({
|
||||
properties: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
timerText: {
|
||||
type: String,
|
||||
value: '00:00:00'
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleTap() {
|
||||
console.log('[pause-mask] handleTap triggered, show:', this.data.show);
|
||||
this.triggerEvent('resume');
|
||||
}
|
||||
}
|
||||
});
|
||||
7
components/pause-mask/index.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {},
|
||||
"options": {
|
||||
"virtualHost": true
|
||||
}
|
||||
}
|
||||
7
components/pause-mask/index.wxml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<view class="pause-mask {{show ? 'show' : ''}}" bindtap="handleTap">
|
||||
<view class="pause-content">
|
||||
<image class="pause-icon" src="https://duiduiminiprogram.oss-cn-hangzhou.aliyuncs.com/mini/pause.png"></image>
|
||||
<text class="timer-text">{{timerText}}</text>
|
||||
<text class="tip-text">点击继续答题</text>
|
||||
</view>
|
||||
</view>
|
||||
65
components/pause-mask/index.wxss
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
.pause-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
z-index: 1500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.pause-mask.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.pause-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
transform: translateY(20rpx);
|
||||
opacity: 0;
|
||||
transition: all 0.3s ease;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pause-mask.show .pause-content {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.pause-icon {
|
||||
/* width: 120rpx;
|
||||
height: 120rpx; */
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.pause-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.timer-text {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
93
components/question-display/index.js
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
Component({
|
||||
properties: {
|
||||
// 题目对象
|
||||
question: {
|
||||
type: Object,
|
||||
value: {}
|
||||
},
|
||||
// 题目索引
|
||||
questionIndex: {
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
// 用户答案数组(用于显示选中状态)
|
||||
answers: {
|
||||
type: Array,
|
||||
value: []
|
||||
},
|
||||
// 选项标记数组
|
||||
optionMarkers: {
|
||||
type: Array,
|
||||
value: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
|
||||
},
|
||||
// 是否显示答案解析
|
||||
showAnalysis: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
// 是否显示答案图标(正确/错误标记)
|
||||
showAnswerIcon: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
// 是否可点击选项
|
||||
clickable: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
}
|
||||
},
|
||||
|
||||
data: {
|
||||
// 组件内部数据
|
||||
},
|
||||
|
||||
attached() {
|
||||
// 组件挂载时,检查数据
|
||||
|
||||
},
|
||||
|
||||
observers: {
|
||||
// 监听 question 属性变化
|
||||
'question': function(question) {
|
||||
console.log('question-display 组件 question 属性变化:', question);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 选项点击事件
|
||||
onOptionClick(e) {
|
||||
if (!this.data.clickable) {
|
||||
return;
|
||||
}
|
||||
const index = e.currentTarget.dataset.index;
|
||||
this.triggerEvent('optionclick', {
|
||||
optionIndex: index,
|
||||
questionIndex: this.data.questionIndex
|
||||
});
|
||||
},
|
||||
|
||||
// 题目容器内触摸:catch 阻止冒泡到问题面板;横向滑动时通知页面切换题目(因 swiper 收不到被 catch 的触摸)
|
||||
onQuestionTouchStart(e) {
|
||||
if (e.touches && e.touches[0]) {
|
||||
this._touchStartX = e.touches[0].clientX;
|
||||
this._touchStartY = e.touches[0].clientY;
|
||||
this._swipeHorizontalEmitted = false;
|
||||
}
|
||||
},
|
||||
onQuestionTouchMove(e) {
|
||||
if (this._swipeHorizontalEmitted || !e.touches || !e.touches[0]) return;
|
||||
const dx = e.touches[0].clientX - this._touchStartX;
|
||||
const dy = e.touches[0].clientY - this._touchStartY;
|
||||
const threshold = 40;
|
||||
if (Math.abs(dx) > threshold && Math.abs(dx) > Math.abs(dy)) {
|
||||
this._swipeHorizontalEmitted = true;
|
||||
this.triggerEvent('swipehorizontal', { direction: dx > 0 ? 'right' : 'left' });
|
||||
}
|
||||
},
|
||||
onQuestionTouchEnd() {
|
||||
this._swipeHorizontalEmitted = false;
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
5
components/question-display/index.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
||||
79
components/question-display/index.wxml
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<view class="question-page">
|
||||
<!-- 题目容器内:纵向滑动由 scroll-view 滚动,横向滑动通过事件交给页面切换题目;使用 bind 以便选项 tap 能正常触发(问题面板已改为仅拖拽条可拖) -->
|
||||
<scroll-view scroll-y class="question-content no-material" enhanced="true" show-scrollbar="true" bounces="true" enable-flex="true"
|
||||
bindtouchstart="onQuestionTouchStart"
|
||||
bindtouchmove="onQuestionTouchMove"
|
||||
bindtouchend="onQuestionTouchEnd"
|
||||
bindtouchcancel="onQuestionTouchEnd">
|
||||
<view class="question-container">
|
||||
<view class="question-header" wx:if="{{question}}">
|
||||
<view class="question-type">{{questionIndex + 1}}. {{question.type === 'single_choice' || question.type === 1 || question.type === 2 ? '单选题' : '多选题'}}</view>
|
||||
</view>
|
||||
|
||||
<!-- 题目内容:使用 rich-text 支持 HTML 渲染 -->
|
||||
<view style="padding: 16rpx 0;" wx:if="{{question}}">
|
||||
<rich-text
|
||||
nodes="{{question.title || question.content || ''}}"
|
||||
selectable="{{true}}"
|
||||
style="color:#111;font-size:34rpx;line-height:1.6;"
|
||||
></rich-text>
|
||||
</view>
|
||||
|
||||
<!-- 选项列表 -->
|
||||
<view class="options-list" wx:if="{{question && question.options && question.options.length > 0}}">
|
||||
<view class="option-item {{answers && answers[questionIndex] && answers[questionIndex][optIndex] ? 'option-selected' : ''}} {{opt.cssClass || ''}}"
|
||||
wx:for="{{question.options}}"
|
||||
wx:key="id"
|
||||
wx:for-item="opt"
|
||||
wx:for-index="optIndex"
|
||||
bindtap="onOptionClick"
|
||||
data-index="{{optIndex}}">
|
||||
<view class="option-content">
|
||||
<text class="option-letter">{{optionMarkers && optionMarkers[optIndex] ? optionMarkers[optIndex] : String.fromCharCode(65 + optIndex)}}</text>
|
||||
<text class="separator">|</text>
|
||||
<rich-text
|
||||
class="option-text"
|
||||
nodes="{{opt.content || opt.option_content || opt.text || ''}}"
|
||||
selectable="{{true}}"
|
||||
></rich-text>
|
||||
</view>
|
||||
<image class="answer-icon"
|
||||
src="/assets/icons/{{(opt.label === question.correct_answer || opt.option_label === question.correct_answer) ? 'correct.png' : ((opt.label === question.user_answer || opt.option_label === question.user_answer) ? 'wrong.png' : '')}}"
|
||||
wx:if="{{showAnswerIcon && ((opt.label === question.correct_answer || opt.option_label === question.correct_answer) || (opt.label === question.user_answer || opt.option_label === question.user_answer))}}"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 调试信息:如果没有选项 -->
|
||||
<view wx:if="{{!question || !question.options || question.options.length === 0}}" style="padding: 20rpx; background: #fff3cd; margin: 20rpx; border-radius: 8rpx;">
|
||||
<text style="color: #856404; font-size: 28rpx;">⚠️ 题目没有选项数据</text>
|
||||
<text style="color: #856404; font-size: 24rpx; display: block; margin-top: 10rpx;">question: {{question ? '存在' : '不存在'}}</text>
|
||||
<text style="color: #856404; font-size: 24rpx; display: block;">options: {{question && question.options ? question.options.length : '无'}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 答案解析区域(可选) -->
|
||||
<view class="answer-analysis" wx:if="{{showAnalysis}}">
|
||||
<view class="analysis-header analysis-header-user">
|
||||
<text class="analysis-title">你的答案</text>
|
||||
<text class="user-answer" wx:if="{{question.user_answer}}">{{question.user_answer}}</text>
|
||||
</view>
|
||||
<view class="analysis-header">
|
||||
<text class="analysis-title">答案解析</text>
|
||||
<text class="correct-answer" wx:if="{{question.correct_answer}}">正确答案:{{question.correct_answer}}</text>
|
||||
</view>
|
||||
<view class="analysis-content" wx:if="{{question.answer_analysis}}">
|
||||
<rich-text
|
||||
nodes="{{question.answer_analysis}}"
|
||||
selectable="{{true}}"
|
||||
></rich-text>
|
||||
</view>
|
||||
<view class="analysis-content" wx:else>
|
||||
<text style="color: #999; font-size: 28rpx;">暂无解析</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom-spacing"></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
155
components/question-display/index.wxss
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
.question-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
position: relative;
|
||||
/* padding-top: 20rpx; */
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.question-content {
|
||||
flex: 1;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.question-content.no-material {
|
||||
/* 高度由父容器控制 */
|
||||
}
|
||||
|
||||
.question-container {
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
margin: 0 20rpx 30rpx 20rpx;
|
||||
padding: 30rpx;
|
||||
/* box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); */
|
||||
width: calc(100% - 40rpx) !important;
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.question-header {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.question-type {
|
||||
color: #666;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.options-list {
|
||||
margin-top: 30rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.option-item {
|
||||
margin: 20rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx 30rpx;
|
||||
background: #fff;
|
||||
border-radius: 8rpx;
|
||||
border: 2rpx solid #E5E5E5;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.option-selected {
|
||||
background-color: #E3F0FF !important;
|
||||
border-color: #1A7CFF !important;
|
||||
}
|
||||
|
||||
.option-selected .option-letter,
|
||||
.option-selected .option-text,
|
||||
.option-selected .separator {
|
||||
color: #1A7CFF !important;
|
||||
}
|
||||
|
||||
.option-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.option-letter {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
min-width: 40rpx;
|
||||
}
|
||||
|
||||
.option-text {
|
||||
flex: 1;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.separator {
|
||||
color: #E5E5E5;
|
||||
margin: 0 20rpx;
|
||||
}
|
||||
|
||||
.answer-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.answer-analysis {
|
||||
margin-top: 40rpx;
|
||||
padding: 20rpx;
|
||||
background: #F5F7FA;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.analysis-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.analysis-title {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 你的答案:蓝色,与正确答案的绿色区分 */
|
||||
.analysis-header-user .user-answer {
|
||||
font-size: 28rpx;
|
||||
color: #1890ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.correct-answer {
|
||||
font-size: 28rpx;
|
||||
color: #52C41A;
|
||||
}
|
||||
|
||||
.analysis-content {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.bottom-spacing {
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
105
components/resize-box/index.js
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
Component({
|
||||
properties: {
|
||||
// 当前高度
|
||||
height: {
|
||||
type: Number,
|
||||
value: 200
|
||||
},
|
||||
// 最小高度
|
||||
minHeight: {
|
||||
type: Number,
|
||||
value: 100
|
||||
},
|
||||
// 最大高度
|
||||
maxHeight: {
|
||||
type: Number,
|
||||
value: 400
|
||||
},
|
||||
// 预设高度点,用于自动吸附
|
||||
presetHeights: {
|
||||
type: Array,
|
||||
value: [100, 150, 200, 250, 300, 350, 400]
|
||||
},
|
||||
showHandle: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
}
|
||||
},
|
||||
|
||||
data: {
|
||||
isResizing: false,
|
||||
currentStyle: '',
|
||||
currentHeight: 200
|
||||
},
|
||||
|
||||
observers: {
|
||||
'height': function (val) {
|
||||
// 只有非拖动时才同步外部高度
|
||||
if (!this.data.isResizing) {
|
||||
this.setData({ currentHeight: val });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
startResize(e) {
|
||||
const touch = e.touches[0];
|
||||
this.startY = touch.clientY;
|
||||
this.startHeight = this.data.currentHeight;
|
||||
|
||||
this.setData({
|
||||
isResizing: true,
|
||||
currentStyle: 'transition: none;'
|
||||
});
|
||||
|
||||
// 触发开始事件
|
||||
this.triggerEvent('resizestart', {
|
||||
height: this.data.height
|
||||
});
|
||||
},
|
||||
|
||||
onResize(e) {
|
||||
if (!this.data.isResizing) return;
|
||||
|
||||
const touch = e.touches[0];
|
||||
const deltaY = touch.clientY - this.startY;
|
||||
let newHeight = this.startHeight + deltaY;
|
||||
|
||||
// 限制高度范围
|
||||
newHeight = Math.max(this.properties.minHeight,
|
||||
Math.min(newHeight, this.properties.maxHeight));
|
||||
|
||||
this.setData({
|
||||
currentHeight: newHeight
|
||||
});
|
||||
|
||||
// 触发改变事件
|
||||
this.triggerEvent('resize', {
|
||||
height: newHeight
|
||||
});
|
||||
},
|
||||
|
||||
endResize() {
|
||||
if (!this.data.isResizing) return;
|
||||
|
||||
const targetHeight = this.calculateTargetHeight(this.data.currentHeight);
|
||||
|
||||
this.setData({
|
||||
isResizing: false,
|
||||
currentStyle: 'transition: height 0.3s cubic-bezier(.4,0,.2,1);',
|
||||
currentHeight: targetHeight
|
||||
});
|
||||
|
||||
// 触发结束事件
|
||||
this.triggerEvent('resizeend', {
|
||||
height: targetHeight
|
||||
});
|
||||
},
|
||||
|
||||
calculateTargetHeight(currentHeight) {
|
||||
return this.properties.presetHeights.reduce((prev, curr) =>
|
||||
Math.abs(curr - currentHeight) < Math.abs(prev - currentHeight) ? curr : prev
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
4
components/resize-box/index.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
13
components/resize-box/index.wxml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<view class="resize-box {{isResizing ? 'resizing' : ''}}"
|
||||
style="height: {{currentHeight}}px; {{currentStyle}}">
|
||||
<slot></slot>
|
||||
<view wx:if="{{showHandle !== false && showHandle !== 'false'}}" class="resize-handle"
|
||||
catch:touchstart="startResize"
|
||||
catch:touchmove="onResize"
|
||||
catch:touchend="endResize"
|
||||
catch:touchcancel="endResize">
|
||||
<view class="resize-line">
|
||||
<view class="resize-dots"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
48
components/resize-box/index.wxss
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
.resize-box {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
/* background: #fff; // 由外层控制 */
|
||||
/* border-radius: 6px; // 由外层控制 */
|
||||
/* border: 1px solid #eee; // 可选 */
|
||||
will-change: height;
|
||||
transform: translateZ(0);
|
||||
-webkit-transform: translateZ(0);
|
||||
overflow: hidden; /* 也可以加一层保险 */
|
||||
}
|
||||
|
||||
.resize-box.resizing {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.resize-handle {
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 60px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
z-index: 100;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.resize-line {
|
||||
width: 20px;
|
||||
height: 2px;
|
||||
background: #D8D8D8;
|
||||
border-radius: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.resize-dots {
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: radial-gradient(circle, #999 1px, transparent 1px) 0 0 / 3px 3px;
|
||||
}
|
||||
6
config/api.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
//测试地址
|
||||
const ApiRootUrl = 'https://ndnd.duiduiedu.com/addons/unishop';
|
||||
module.exports={
|
||||
IndexBanner: ApiRootUrl + 'Banner/List', //获取列表
|
||||
IndexUrl: ApiRootUrl + 'News/GetNewsListByPageType', //首页数据接口
|
||||
};
|
||||
62
config/api_config.js
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// API 域名配置
|
||||
// 根据环境自动切换域名
|
||||
|
||||
// 判断是否为开发环境
|
||||
// 可以通过以下方式切换:
|
||||
// 1. 直接修改下面的 isDevMode 变量
|
||||
// 2. 或者通过微信开发者工具的编译条件设置环境变量
|
||||
const isDevMode = false; // 改为 true 使用本地开发环境(127.0.0.1:8080)
|
||||
|
||||
const isDev = () => {
|
||||
return isDevMode;
|
||||
};
|
||||
|
||||
// Fiber API 配置(新后端)
|
||||
const FIBER_API_CONFIG = {
|
||||
// 开发环境(本地调试)
|
||||
dev: {
|
||||
baseURL: 'http://127.0.0.1:8081/api/v1',
|
||||
},
|
||||
// 生产环境(线上部署)
|
||||
prod: {
|
||||
baseURL: 'https://api.duiduiedu.com/api/v1',
|
||||
}
|
||||
};
|
||||
|
||||
// PHP API 配置(旧后端,逐步迁移)
|
||||
const PHP_API_CONFIG = {
|
||||
// 开发环境
|
||||
dev: {
|
||||
baseURL: 'http://127.0.0.1:8006/addons/unishop',
|
||||
},
|
||||
// 生产环境
|
||||
prod: {
|
||||
baseURL: 'https://ndnd.duiduiedu.com/addons/unishop',
|
||||
}
|
||||
};
|
||||
|
||||
// 获取当前环境配置
|
||||
const getFiberApiBaseURL = () => {
|
||||
return isDev() ? FIBER_API_CONFIG.dev.baseURL : FIBER_API_CONFIG.prod.baseURL;
|
||||
};
|
||||
|
||||
const getPhpApiBaseURL = () => {
|
||||
return isDev() ? PHP_API_CONFIG.dev.baseURL : PHP_API_CONFIG.prod.baseURL;
|
||||
};
|
||||
|
||||
export default {
|
||||
// Fiber API(新后端)
|
||||
fiberApiBaseURL: getFiberApiBaseURL(),
|
||||
|
||||
// PHP API(旧后端)
|
||||
phpApiBaseURL: getPhpApiBaseURL(),
|
||||
|
||||
// 图片资源域名
|
||||
imageBaseURL: 'https://ndnd.duiduiedu.com/',
|
||||
|
||||
// 工具方法
|
||||
isDev,
|
||||
getFiberApiBaseURL,
|
||||
getPhpApiBaseURL,
|
||||
};
|
||||
|
||||
544
config/camp_api.js
Normal file
|
|
@ -0,0 +1,544 @@
|
|||
import request from '../utils/request';
|
||||
|
||||
/**
|
||||
* 打卡营相关 API 接口
|
||||
* 整合了打卡营、任务、订单、支付等所有相关接口
|
||||
*/
|
||||
export const campApi = {
|
||||
// ==================== 打卡营基础信息 ====================
|
||||
|
||||
/**
|
||||
* 获取打卡营分类列表
|
||||
*/
|
||||
getCampCategories: () => {
|
||||
const url = `/camp/categories?keyword=&page=1&page_size=10`;
|
||||
return request({
|
||||
url,
|
||||
method: 'GET'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取打卡营列表
|
||||
* @param {String} categoryId - 分类ID,如果为 undefined/null/-1 则返回推荐打卡营
|
||||
* @param {String} userId - 用户ID(可选,如果不传则从本地存储获取)
|
||||
*/
|
||||
getCamps: (categoryId, userId) => {
|
||||
const user_id = String(userId || wx.getStorageSync('wxuserid') || '');
|
||||
// 已加入打卡营:只返回当前用户已加入的营
|
||||
if (categoryId === 'joined') {
|
||||
return request({
|
||||
url: `/camp/camps?joined_only=1&page=1&page_size=50&user_id=${encodeURIComponent(user_id)}`,
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
// 推荐打卡营(与后端 RecommendFilter 约定:only_true = 只返回推荐的)
|
||||
if (!categoryId || categoryId === 'undefined' || categoryId === '-1') {
|
||||
return request({
|
||||
url: `/camp/camps?recommend_filter=only_true&page=1&page_size=20&user_id=${encodeURIComponent(user_id)}`,
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
// 按分类筛选
|
||||
const url = `/camp/camps?category_id=${categoryId}&page=1&page_size=20&user_id=${encodeURIComponent(user_id)}`;
|
||||
return request({
|
||||
url,
|
||||
method: 'GET'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取打卡营详情
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} userId - 用户ID(可选,如果不传则从本地存储获取)
|
||||
*/
|
||||
getCampDetail: (campId, userId) => {
|
||||
const user_id = String(userId || wx.getStorageSync('wxuserid') || '');
|
||||
// 根据 proto 定义,使用查询参数 id
|
||||
return request({
|
||||
url: `/camp/camps/detail?id=${campId}&user_id=${encodeURIComponent(user_id)}`,
|
||||
method: 'GET'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取打卡营详情及状态(聚合接口,包含用户状态、小节、任务等完整信息)
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} userId - 用户ID
|
||||
*/
|
||||
getCampDetailWithUserStatus: (campId, userId) => {
|
||||
return request({
|
||||
url: `/camp/camp_detail_with_user_status`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
camp_id: String(campId),
|
||||
user_id: String(userId || wx.getStorageSync('wxuserid') || '')
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// ==================== 用户打卡营操作 ====================
|
||||
|
||||
/**
|
||||
* 加入打卡营
|
||||
* @param {String} campId - 打卡营ID
|
||||
*/
|
||||
joinCamp: (campId) => {
|
||||
return request({
|
||||
url: `/camp/user_camp/join`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
user_id: String(wx.getStorageSync('wxuserid') || ''), // 从本地存储获取用户ID
|
||||
camp_id: campId
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查用户是否加入打卡营
|
||||
* @param {String} campId - 打卡营ID
|
||||
*/
|
||||
checkUserCampStatus: (campId) => {
|
||||
return request({
|
||||
url: `/camp/check_user_camp_status`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
user_id: String(wx.getStorageSync('wxuserid') || ''), // 从本地存储获取用户ID
|
||||
camp_id: campId
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置打卡营进度(新接口)
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} userId - 用户ID
|
||||
* @param {Boolean} confirm - 是否确认
|
||||
*/
|
||||
resetCampProgress: (campId, userId, confirm = true) => {
|
||||
return request({
|
||||
url: `/camp/user_camp/reset_progress`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
user_id: String(userId || wx.getStorageSync('wxuserid') || ''),
|
||||
camp_id: String(campId),
|
||||
confirm: confirm
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 重启打卡营(旧接口,已废弃)
|
||||
* @deprecated 请使用 resetCampProgress
|
||||
*/
|
||||
restartCamp: (campId) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/restart`,
|
||||
method: 'POST'
|
||||
});
|
||||
},
|
||||
|
||||
// ==================== 小节相关 ====================
|
||||
|
||||
/**
|
||||
* 获取打卡营的小节列表(课程列表)
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} userId - 用户ID(可选,如果不传则从本地存储获取)
|
||||
*/
|
||||
getCampCourses: (campId, userId) => {
|
||||
const user_id = String(userId || wx.getStorageSync('wxuserid') || '');
|
||||
// 根据 proto 定义,使用 /camp/sections 接口,通过 camp_id 查询参数
|
||||
return request({
|
||||
url: `/camp/sections?camp_id=${campId}&page=1&page_size=10&user_id=${encodeURIComponent(user_id)}`,
|
||||
method: 'GET'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查是否可开启小节(后端查库:上一小节是否完成等)
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} sectionId - 小节ID
|
||||
* @returns {Promise<{ success: boolean, can_unlock: boolean, message: string }>}
|
||||
*/
|
||||
canUnlockSection: (campId, sectionId) => {
|
||||
return request({
|
||||
url: `/camp/can_unlock_section`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
user_id: String(wx.getStorageSync('wxuserid') || ''),
|
||||
camp_id: campId,
|
||||
section_id: sectionId
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查任务是否可以开始(前置任务是否已完成)
|
||||
* @param {String} taskId - 任务ID
|
||||
* @returns {Promise<{ success: boolean, can_start: boolean, reason: string }>}
|
||||
*/
|
||||
canStartTask: (taskId) => {
|
||||
return request({
|
||||
url: `/camp/can_start_task`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
user_id: String(wx.getStorageSync('wxuserid') || ''),
|
||||
task_id: taskId
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 购买小节(开启第一小节)
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} sectionId - 小节ID
|
||||
*/
|
||||
purchaseSection: (campId, sectionId) => {
|
||||
return request({
|
||||
url: `/camp/purchase_section`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
user_id: String(wx.getStorageSync('wxuserid') || ''),
|
||||
camp_id: campId,
|
||||
section_id: sectionId
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取用户在某营的小节可访问/已购列表
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {Number} page - 页码
|
||||
* @param {Number} page_size - 每页数量
|
||||
*/
|
||||
listUserSectionAccess: (campId, page = 1, page_size = 1000) => {
|
||||
return request({
|
||||
url: `/camp/list_user_section_access`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
user_id: String(wx.getStorageSync('wxuserid') || ''),
|
||||
camp_id: campId,
|
||||
page,
|
||||
page_size
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取每个小节的完成状态
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} userId - 用户ID
|
||||
*/
|
||||
getSectionUserStatus: (campId, userId) => {
|
||||
return request({
|
||||
url: `/camp/section/user-status`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
camp_id: String(campId),
|
||||
user_id: String(userId || wx.getStorageSync('wxuserid') || '')
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 根据课程小节ID获取用户与课程小节的关联关系
|
||||
* @param {String} courseIds - 课程ID列表(逗号分隔)
|
||||
* @param {String} userId - 用户ID(可选,如果不传则从本地存储获取)
|
||||
*/
|
||||
getCourseUserRelations: (courseIds, userId) => {
|
||||
const user_id = String(userId || wx.getStorageSync('wxuserid') || '');
|
||||
return request({
|
||||
url: `/camp/course/user-course-relations?course_ids=${courseIds}&user_id=${encodeURIComponent(user_id)}`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取课程完成状态
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
*/
|
||||
getCourseCompleted: (campId, courseId) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/completed`,
|
||||
method: 'GET'
|
||||
});
|
||||
},
|
||||
|
||||
// ==================== 任务相关 ====================
|
||||
|
||||
/**
|
||||
* 获取任务详情(需要 campId 和 courseId)
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
* @param {String} taskType - 任务类型
|
||||
*/
|
||||
getTaskDetail: (campId, courseId, taskId, taskType) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}?task_type=${taskType.toUpperCase()}`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 按任务ID直接获取任务详情(无需 campId/courseId)
|
||||
* @param {String} taskId - 任务ID
|
||||
* @param {String} userId - 用户ID(可选,如果不传则从本地存储获取)
|
||||
*/
|
||||
getTaskDetailById: (taskId, userId) => {
|
||||
const user_id = String(userId || wx.getStorageSync('wxuserid') || '');
|
||||
return request({
|
||||
url: `/camp/tasks/detail?id=${taskId}&user_id=${encodeURIComponent(user_id)}`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 根据任务ID获取任务与用户的关联关系
|
||||
* @param {String} taskIds - 任务ID列表(逗号分隔)
|
||||
* @param {String} userId - 用户ID(可选,如果不传则从本地存储获取)
|
||||
*/
|
||||
getCampTaskUserRelations: (taskIds, userId) => {
|
||||
const user_id = String(userId || wx.getStorageSync('wxuserid') || '');
|
||||
return request({
|
||||
url: `/camp/task/user_task?task_ids=${taskIds}&user_id=${encodeURIComponent(user_id)}`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
|
||||
// ==================== 任务进度相关 ====================
|
||||
|
||||
/**
|
||||
* 获取用户任务进度详情
|
||||
* @param {String} userId - 用户ID
|
||||
* @param {String} taskId - 任务ID
|
||||
*/
|
||||
getProgressDetail: (userId, taskId) => {
|
||||
// GET 请求的参数作为 query 参数传递(兼容微信小程序,不使用 URLSearchParams)
|
||||
const user_id = encodeURIComponent(String(userId));
|
||||
const task_id = encodeURIComponent(String(taskId));
|
||||
return request({
|
||||
url: `/camp/progress/info?user_id=${user_id}&task_id=${task_id}`,
|
||||
method: 'GET'
|
||||
});
|
||||
// 注意:request.js 已处理,当 success=false 时不会显示错误提示(没有进度是正常情况)
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新任务通用进度
|
||||
* @param {Object} data - 进度数据
|
||||
*/
|
||||
updateCampProgress: (data) => {
|
||||
return request({
|
||||
url: `/camp/progress/update`,
|
||||
method: 'POST',
|
||||
data: data
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置任务进度(用户重新答题)
|
||||
* @param {Object} data - 重置数据
|
||||
*/
|
||||
resetTaskProgress: (data) => {
|
||||
return request({
|
||||
url: `/camp/reset_task_progress`,
|
||||
method: 'POST',
|
||||
data: data
|
||||
});
|
||||
},
|
||||
|
||||
// ==================== 任务类型特定接口 ====================
|
||||
|
||||
/**
|
||||
* 更新视频任务进度
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
* @param {Object} data - 进度数据
|
||||
*/
|
||||
updateVideoProgress: (campId, courseId, taskId, data) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}/video`,
|
||||
method: 'POST',
|
||||
data: data
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新文本图片任务进度
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
* @param {Object} data - 进度数据
|
||||
*/
|
||||
updateTextImageProgress: (campId, courseId, taskId, data) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}/text-image`,
|
||||
method: 'POST',
|
||||
data: data
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新主观题任务进度
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
* @param {Object} data - 进度数据
|
||||
*/
|
||||
updateSubjectiveQuestionProgress: (campId, courseId, taskId, data) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}/subjective`,
|
||||
method: 'POST',
|
||||
data: data
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新申论任务进度
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
* @param {Object} data - 进度数据
|
||||
*/
|
||||
updateEssayProgress: (campId, courseId, taskId, data) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}/essay-question/essay`,
|
||||
method: 'POST',
|
||||
data: data
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新客观题任务进度
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
* @param {Object} data - 进度数据
|
||||
*/
|
||||
updateObjectiveQuestionProgress: (campId, courseId, taskId, data) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}/objective`,
|
||||
method: 'POST',
|
||||
data: data
|
||||
});
|
||||
},
|
||||
|
||||
// ==================== 任务答案相关 ====================
|
||||
|
||||
/**
|
||||
* 获取主观题任务的用户答案
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
*/
|
||||
getSubjectiveTaskUserAnswer: (campId, courseId, taskId) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}/subjective/user-answer`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取申论题任务所有问题的用户答案
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
*/
|
||||
getEssayQuestionUserAnswer: (campId, courseId, taskId) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}/essay-question/user-answer`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取申论题任务是否需要审核
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
*/
|
||||
getEssayTaskReviewStatus: (campId, courseId, taskId) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}/essay-question/need-audit`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取客观题答题结算结果
|
||||
* @param {String} campId - 打卡营ID
|
||||
* @param {String} courseId - 课程ID
|
||||
* @param {String} taskId - 任务ID
|
||||
*/
|
||||
getObjectiveQuestionSettlementResult: (campId, courseId, taskId) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/tasks/${taskId}/objective/settlement-result`,
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
|
||||
// ==================== 订单相关 ====================
|
||||
|
||||
/**
|
||||
* 创建订单(打卡营小节)
|
||||
* @param {Object} orderData - 订单数据
|
||||
*/
|
||||
createOrder: (orderData) => {
|
||||
return request({
|
||||
url: `/order/create`,
|
||||
method: 'POST',
|
||||
data: orderData
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
* @param {Object} orderData - 订单数据
|
||||
*/
|
||||
cancelOrder: (orderData) => {
|
||||
return request({
|
||||
url: `/order/cancel`,
|
||||
method: 'POST',
|
||||
data: orderData
|
||||
});
|
||||
},
|
||||
|
||||
// ==================== 支付相关 ====================
|
||||
|
||||
/**
|
||||
* 创建支付(获取预支付ID)
|
||||
* @param {Object} paymentData - 支付数据
|
||||
*/
|
||||
createPayment: (paymentData) => {
|
||||
return request({
|
||||
url: `/pay/create`,
|
||||
method: 'POST',
|
||||
data: paymentData
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建打卡营小节支付请求订单(已废弃,使用 createOrder + createPayment)
|
||||
* @deprecated 请使用 createOrder + createPayment
|
||||
*/
|
||||
createCampPayment: (campId, courseId) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/course/${courseId}/order`,
|
||||
method: 'POST',
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消支付
|
||||
* @deprecated 请使用 cancelOrder
|
||||
*/
|
||||
cancelCampPayment: (campId, orderId) => {
|
||||
return request({
|
||||
url: `/camp/${campId}/order/${orderId}/cancel`,
|
||||
method: 'POST',
|
||||
});
|
||||
},
|
||||
};
|
||||
144
config/question_api.js
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
import apiConfig from './api_config.js';
|
||||
import request from '../utils/request.js';
|
||||
|
||||
// Fiber 后端请求函数
|
||||
// 注意:request 函数内部已经会拼接 baseURL,所以这里只需要传入相对路径
|
||||
function fiberRequest(options) {
|
||||
return request({
|
||||
url: options.url, // 只传入相对路径,request 函数会拼接 baseURL
|
||||
method: options.method || 'GET',
|
||||
data: options.data,
|
||||
header: options.header || {}
|
||||
});
|
||||
}
|
||||
|
||||
export const questionApi = {
|
||||
/**
|
||||
* 获取试卷详情(使用 Fiber 后端)
|
||||
* @param {string} paperId 试卷ID
|
||||
* @returns {Promise} 试卷数据
|
||||
*/
|
||||
getPaperDetail: (paperId) => {
|
||||
return fiberRequest({
|
||||
url: `/paper/detail?id=${paperId}`,
|
||||
method: 'GET'
|
||||
}).then(res => {
|
||||
// 转换 Fiber 后端返回格式为前端期望的格式
|
||||
if (res.success && res.paper) {
|
||||
return {
|
||||
success: true,
|
||||
code: 200,
|
||||
data: res.paper,
|
||||
paper: res.paper // 兼容旧格式
|
||||
};
|
||||
}
|
||||
return res;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取试卷(兼容旧接口,接受 paperId 和 taskId)
|
||||
* @param {string} paperId 试卷ID
|
||||
* @param {string} taskId 任务ID(可选)
|
||||
* @returns {Promise} 试卷数据
|
||||
*/
|
||||
getExamPaper: (paperId, taskId) => {
|
||||
return questionApi.getPaperDetail(paperId);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取试卷详情(包含答案和解析,用于答题结果页面)
|
||||
* @param {string} paperId 试卷ID
|
||||
* @returns {Promise} 试卷数据(包含答案和解析)
|
||||
*/
|
||||
getPaperWithAnswers: (paperId) => {
|
||||
return fiberRequest({
|
||||
url: `/paper/result?id=${paperId}`,
|
||||
method: 'GET'
|
||||
}).then(res => {
|
||||
// 转换 Fiber 后端返回格式为前端期望的格式
|
||||
if (res.success && (res.paper || res.data)) {
|
||||
const paper = res.paper || res.data;
|
||||
return {
|
||||
success: true,
|
||||
code: 200,
|
||||
data: paper,
|
||||
paper: paper // 兼容旧格式
|
||||
};
|
||||
}
|
||||
return res;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建答题记录(使用 Fiber 后端)
|
||||
* @param {object} data 答题记录数据
|
||||
* @param {string} data.user_id 用户ID
|
||||
* @param {string} data.paper_id 试卷ID
|
||||
* @param {number} data.start_time 开始时间(Unix时间戳,秒)
|
||||
* @param {number} data.end_time 结束时间(Unix时间戳,秒)
|
||||
* @param {array} data.answers 答案数组
|
||||
* @returns {Promise} 创建结果
|
||||
*/
|
||||
createAnswerRecord: (data) => {
|
||||
// 转换前端数据格式为 Fiber 后端期望的格式
|
||||
const fiberData = {
|
||||
user_id: String(data.user_id),
|
||||
paper_id: String(data.paper_id),
|
||||
task_id: data.task_id ? String(data.task_id) : '', // 打卡营任务ID,用于不同打卡营的答题隔离
|
||||
start_time: data.start_time || Math.floor(Date.now() / 1000),
|
||||
end_time: data.end_time || Math.floor(Date.now() / 1000),
|
||||
answers: (data.answers || []).map(answer => ({
|
||||
question_id: String(answer.question_id),
|
||||
user_answer: String(answer.user_answer || '')
|
||||
}))
|
||||
};
|
||||
|
||||
return fiberRequest({
|
||||
url: `/answer_record/create`,
|
||||
method: 'POST',
|
||||
data: fiberData
|
||||
}).then(res => {
|
||||
// 转换 Fiber 后端返回格式为前端期望的格式
|
||||
if (res.success) {
|
||||
return {
|
||||
success: true,
|
||||
code: 200,
|
||||
...res
|
||||
};
|
||||
}
|
||||
return res;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取答题记录(使用 Fiber 后端)
|
||||
* @param {string} userId 用户ID
|
||||
* @param {string} paperId 试卷ID
|
||||
* @param {number} page 页码
|
||||
* @param {number} pageSize 每页数量
|
||||
* @returns {Promise} 答题记录列表
|
||||
*/
|
||||
getAnswerRecord: (userId, paperId, page = 1, pageSize = 100, taskId = '') => {
|
||||
let url = `/answer_record/detail?user_id=${userId}&paper_id=${paperId}&page=${page}&page_size=${pageSize}`;
|
||||
if (taskId) {
|
||||
url += `&task_id=${taskId}`;
|
||||
}
|
||||
return fiberRequest({
|
||||
url: url,
|
||||
method: 'GET'
|
||||
}).then(res => {
|
||||
// 转换 Fiber 后端返回格式为前端期望的格式
|
||||
if (res.success) {
|
||||
return {
|
||||
success: true,
|
||||
code: 200,
|
||||
...res
|
||||
};
|
||||
}
|
||||
return res;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
59
config/util.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* GET请求封装
|
||||
*/
|
||||
function get(url, data = {}) {
|
||||
return request(url, data, 'GET')
|
||||
}
|
||||
|
||||
/**
|
||||
* POST请求封装
|
||||
*/
|
||||
function post(url, data = {}) {
|
||||
return request(url, data, 'POST')
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信的request
|
||||
*/
|
||||
function request(url, data = {}, method = "GET") {
|
||||
var contentType = 'application/json'
|
||||
return new Promise(function(resolve, reject) {
|
||||
wx.request({
|
||||
url: url,
|
||||
data: data,
|
||||
method: method,
|
||||
header: {
|
||||
'Content-Type': contentType
|
||||
},
|
||||
success: function(res) {
|
||||
console.log('===============================================================================================')
|
||||
console.log('== 接口地址:' + url)
|
||||
console.log('== 接口参数:' + JSON.stringify(data))
|
||||
console.log('== 请求类型:' + method)
|
||||
console.log("== 接口状态:" + res.statusCode);
|
||||
console.log('===============================================================================================')
|
||||
if (res.statusCode == 200) {
|
||||
resolve(res.data);
|
||||
} else {
|
||||
//请求失败
|
||||
reject("请求失败:" + res.statusCode)
|
||||
}
|
||||
},
|
||||
fail: function(err) {
|
||||
//服务器连接异常
|
||||
console.log('===============================================================================================')
|
||||
console.log('== 接口地址:' + url)
|
||||
console.log('== 接口参数:' + JSON.stringify(data))
|
||||
console.log('== 请求类型:' + method)
|
||||
console.log("== 服务器连接异常")
|
||||
console.log('===============================================================================================')
|
||||
reject("服务器连接异常,请检查网络再试")
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
module.exports = {
|
||||
request,
|
||||
get,
|
||||
post
|
||||
}
|
||||
BIN
img/cgz_03.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
img/cgz_05.png
Normal file
|
After Width: | Height: | Size: 963 B |
BIN
img/cgz_07.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
img/cgz_09.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
img/footerpic.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
img/footerpic1.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
img/footerpic2.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
img/footerpic3.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
img/minemainback.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
img/pause.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
img/play.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
76
miniprogram_npm/@vant/weapp/action-sheet/index.js
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var component_1 = require('../common/component');
|
||||
var button_1 = require('../mixins/button');
|
||||
component_1.VantComponent({
|
||||
mixins: [button_1.button],
|
||||
props: {
|
||||
show: Boolean,
|
||||
title: String,
|
||||
cancelText: String,
|
||||
description: String,
|
||||
round: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
value: 100,
|
||||
},
|
||||
actions: {
|
||||
type: Array,
|
||||
value: [],
|
||||
},
|
||||
overlay: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
closeOnClickOverlay: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
closeOnClickAction: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
safeAreaInsetBottom: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSelect: function (event) {
|
||||
var _this = this;
|
||||
var index = event.currentTarget.dataset.index;
|
||||
var _a = this.data,
|
||||
actions = _a.actions,
|
||||
closeOnClickAction = _a.closeOnClickAction,
|
||||
canIUseGetUserProfile = _a.canIUseGetUserProfile;
|
||||
var item = actions[index];
|
||||
if (item) {
|
||||
this.$emit('select', item);
|
||||
if (closeOnClickAction) {
|
||||
this.onClose();
|
||||
}
|
||||
if (item.openType === 'getUserInfo' && canIUseGetUserProfile) {
|
||||
wx.getUserProfile({
|
||||
desc: item.getUserProfileDesc || ' ',
|
||||
complete: function (userProfile) {
|
||||
_this.$emit('getuserinfo', userProfile);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
onCancel: function () {
|
||||
this.$emit('cancel');
|
||||
},
|
||||
onClose: function () {
|
||||
this.$emit('close');
|
||||
},
|
||||
onClickOverlay: function () {
|
||||
this.$emit('click-overlay');
|
||||
this.onClose();
|
||||
},
|
||||
},
|
||||
});
|
||||
8
miniprogram_npm/@vant/weapp/action-sheet/index.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-icon": "../icon/index",
|
||||
"van-popup": "../popup/index",
|
||||
"van-loading": "../loading/index"
|
||||
}
|
||||
}
|
||||
69
miniprogram_npm/@vant/weapp/action-sheet/index.wxml
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<wxs src="../wxs/utils.wxs" module="utils" />
|
||||
|
||||
<van-popup
|
||||
show="{{ show }}"
|
||||
position="bottom"
|
||||
round="{{ round }}"
|
||||
z-index="{{ zIndex }}"
|
||||
overlay="{{ overlay }}"
|
||||
custom-class="van-action-sheet"
|
||||
safe-area-inset-bottom="{{ safeAreaInsetBottom }}"
|
||||
close-on-click-overlay="{{ closeOnClickOverlay }}"
|
||||
bind:close="onClickOverlay"
|
||||
>
|
||||
<view wx:if="{{ title }}" class="van-action-sheet__header">
|
||||
{{ title }}
|
||||
<van-icon
|
||||
name="cross"
|
||||
custom-class="van-action-sheet__close"
|
||||
bind:click="onClose"
|
||||
/>
|
||||
</view>
|
||||
<view wx:if="{{ description }}" class="van-action-sheet__description van-hairline--bottom">
|
||||
{{ description }}
|
||||
</view>
|
||||
<view wx:if="{{ actions && actions.length }}">
|
||||
<!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 -->
|
||||
<button
|
||||
wx:for="{{ actions }}"
|
||||
wx:key="index"
|
||||
open-type="{{ item.disabled || item.loading || (canIUseGetUserProfile && item.openType === 'getUserInfo') ? '' : item.openType }}"
|
||||
style="{{ item.color ? 'color: ' + item.color : '' }}"
|
||||
class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} {{ item.className || '' }}"
|
||||
hover-class="van-action-sheet__item--hover"
|
||||
data-index="{{ index }}"
|
||||
bindtap="{{ item.disabled || item.loading ? '' : 'onSelect' }}"
|
||||
bindgetuserinfo="onGetUserInfo"
|
||||
bindcontact="onContact"
|
||||
bindgetphonenumber="onGetPhoneNumber"
|
||||
binderror="onError"
|
||||
bindlaunchapp="onLaunchApp"
|
||||
bindopensetting="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 }}"
|
||||
>
|
||||
<block wx:if="{{ !item.loading }}">
|
||||
{{ item.name }}
|
||||
<view wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</view>
|
||||
</block>
|
||||
<van-loading wx:else custom-class="van-action-sheet__loading" size="22px" />
|
||||
</button>
|
||||
</view>
|
||||
<slot />
|
||||
<block wx:if="{{ cancelText }}">
|
||||
<view class="van-action-sheet__gap" />
|
||||
<view
|
||||
class="van-action-sheet__cancel"
|
||||
hover-class="van-action-sheet__cancel--hover"
|
||||
hover-stay-time="70"
|
||||
bind:tap="onCancel"
|
||||
>
|
||||
{{ cancelText }}
|
||||
</view>
|
||||
</block>
|
||||
</van-popup>
|
||||
1
miniprogram_npm/@vant/weapp/action-sheet/index.wxss
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import '../common/index.wxss';.van-action-sheet{max-height:90%!important;max-height:var(--action-sheet-max-height,90%)!important;color:#323233;color:var(--action-sheet-item-text-color,#323233)}.van-action-sheet__cancel,.van-action-sheet__item{padding:14px 16px;text-align:center;font-size:16px;font-size:var(--action-sheet-item-font-size,16px);line-height:22px;line-height:var(--action-sheet-item-line-height,22px);background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-action-sheet__cancel:after,.van-action-sheet__item:after{border-width:0}.van-action-sheet__cancel{color:#646566;color:var(--action-sheet-cancel-text-color,#646566)}.van-action-sheet__gap{display:block;height:8px;height:var(--action-sheet-cancel-padding-top,8px);background-color:#f7f8fa;background-color:var(--action-sheet-cancel-padding-color,#f7f8fa)}.van-action-sheet__item--disabled{color:#c8c9cc;color:var(--action-sheet-item-disabled-text-color,#c8c9cc)}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__subname{margin-top:8px;margin-top:var(--padding-xs,8px);font-size:12px;font-size:var(--action-sheet-subname-font-size,12px);color:#969799;color:var(--action-sheet-subname-color,#969799);line-height:20px;line-height:var(--action-sheet-subname-line-height,20px)}.van-action-sheet__header{text-align:center;font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--action-sheet-header-font-size,16px);line-height:48px;line-height:var(--action-sheet-header-height,48px)}.van-action-sheet__description{text-align:center;padding:20px 16px;padding:20px var(--padding-md,16px);color:#969799;color:var(--action-sheet-description-color,#969799);font-size:14px;font-size:var(--action-sheet-description-font-size,14px);line-height:20px;line-height:var(--action-sheet-description-line-height,20px)}.van-action-sheet__close{position:absolute!important;top:0;right:0;line-height:inherit!important;padding:0 16px;padding:var(--action-sheet-close-icon-padding,0 16px);font-size:22px!important;font-size:var(--action-sheet-close-icon-size,22px)!important;color:#c8c9cc;color:var(--action-sheet-close-icon-color,#c8c9cc)}.van-action-sheet__loading{display:flex!important}
|
||||
266
miniprogram_npm/@vant/weapp/area/index.js
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
'use strict';
|
||||
var __assign =
|
||||
(this && this.__assign) ||
|
||||
function () {
|
||||
__assign =
|
||||
Object.assign ||
|
||||
function (t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s)
|
||||
if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var component_1 = require('../common/component');
|
||||
var shared_1 = require('../picker/shared');
|
||||
var utils_1 = require('../common/utils');
|
||||
var EMPTY_CODE = '000000';
|
||||
component_1.VantComponent({
|
||||
classes: ['active-class', 'toolbar-class', 'column-class'],
|
||||
props: __assign(__assign({}, shared_1.pickerProps), {
|
||||
value: {
|
||||
type: String,
|
||||
observer: function (value) {
|
||||
this.code = value;
|
||||
this.setValues();
|
||||
},
|
||||
},
|
||||
areaList: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer: 'setValues',
|
||||
},
|
||||
columnsNum: {
|
||||
type: null,
|
||||
value: 3,
|
||||
},
|
||||
columnsPlaceholder: {
|
||||
type: Array,
|
||||
observer: function (val) {
|
||||
this.setData({
|
||||
typeToColumnsPlaceholder: {
|
||||
province: val[0] || '',
|
||||
city: val[1] || '',
|
||||
county: val[2] || '',
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
}),
|
||||
data: {
|
||||
columns: [{ values: [] }, { values: [] }, { values: [] }],
|
||||
typeToColumnsPlaceholder: {},
|
||||
},
|
||||
mounted: function () {
|
||||
var _this = this;
|
||||
utils_1.requestAnimationFrame(function () {
|
||||
_this.setValues();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
getPicker: function () {
|
||||
if (this.picker == null) {
|
||||
this.picker = this.selectComponent('.van-area__picker');
|
||||
}
|
||||
return this.picker;
|
||||
},
|
||||
onCancel: function (event) {
|
||||
this.emit('cancel', event.detail);
|
||||
},
|
||||
onConfirm: function (event) {
|
||||
var index = event.detail.index;
|
||||
var value = event.detail.value;
|
||||
value = this.parseValues(value);
|
||||
this.emit('confirm', { value: value, index: index });
|
||||
},
|
||||
emit: function (type, detail) {
|
||||
detail.values = detail.value;
|
||||
delete detail.value;
|
||||
this.$emit(type, detail);
|
||||
},
|
||||
parseValues: function (values) {
|
||||
var columnsPlaceholder = this.data.columnsPlaceholder;
|
||||
return values.map(function (value, index) {
|
||||
if (
|
||||
value &&
|
||||
(!value.code || value.name === columnsPlaceholder[index])
|
||||
) {
|
||||
return __assign(__assign({}, value), { code: '', name: '' });
|
||||
}
|
||||
return value;
|
||||
});
|
||||
},
|
||||
onChange: function (event) {
|
||||
var _this = this;
|
||||
var _a;
|
||||
var _b = event.detail,
|
||||
index = _b.index,
|
||||
picker = _b.picker,
|
||||
value = _b.value;
|
||||
this.code = value[index].code;
|
||||
(_a = this.setValues()) === null || _a === void 0
|
||||
? void 0
|
||||
: _a.then(function () {
|
||||
_this.$emit('change', {
|
||||
picker: picker,
|
||||
values: _this.parseValues(picker.getValues()),
|
||||
index: index,
|
||||
});
|
||||
});
|
||||
},
|
||||
getConfig: function (type) {
|
||||
var areaList = this.data.areaList;
|
||||
return (areaList && areaList[type + '_list']) || {};
|
||||
},
|
||||
getList: function (type, code) {
|
||||
if (type !== 'province' && !code) {
|
||||
return [];
|
||||
}
|
||||
var typeToColumnsPlaceholder = this.data.typeToColumnsPlaceholder;
|
||||
var list = this.getConfig(type);
|
||||
var result = Object.keys(list).map(function (code) {
|
||||
return {
|
||||
code: code,
|
||||
name: list[code],
|
||||
};
|
||||
});
|
||||
if (code != null) {
|
||||
// oversea code
|
||||
if (code[0] === '9' && type === 'city') {
|
||||
code = '9';
|
||||
}
|
||||
result = result.filter(function (item) {
|
||||
return item.code.indexOf(code) === 0;
|
||||
});
|
||||
}
|
||||
if (typeToColumnsPlaceholder[type] && result.length) {
|
||||
// set columns placeholder
|
||||
var codeFill =
|
||||
type === 'province'
|
||||
? ''
|
||||
: type === 'city'
|
||||
? EMPTY_CODE.slice(2, 4)
|
||||
: EMPTY_CODE.slice(4, 6);
|
||||
result.unshift({
|
||||
code: '' + code + codeFill,
|
||||
name: typeToColumnsPlaceholder[type],
|
||||
});
|
||||
}
|
||||
return result;
|
||||
},
|
||||
getIndex: function (type, code) {
|
||||
var compareNum = type === 'province' ? 2 : type === 'city' ? 4 : 6;
|
||||
var list = this.getList(type, code.slice(0, compareNum - 2));
|
||||
// oversea code
|
||||
if (code[0] === '9' && type === 'province') {
|
||||
compareNum = 1;
|
||||
}
|
||||
code = code.slice(0, compareNum);
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (list[i].code.slice(0, compareNum) === code) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
setValues: function () {
|
||||
var picker = this.getPicker();
|
||||
if (!picker) {
|
||||
return;
|
||||
}
|
||||
var code = this.code || this.getDefaultCode();
|
||||
var provinceList = this.getList('province');
|
||||
var cityList = this.getList('city', code.slice(0, 2));
|
||||
var stack = [];
|
||||
var indexes = [];
|
||||
var columnsNum = this.data.columnsNum;
|
||||
if (columnsNum >= 1) {
|
||||
stack.push(picker.setColumnValues(0, provinceList, false));
|
||||
indexes.push(this.getIndex('province', code));
|
||||
}
|
||||
if (columnsNum >= 2) {
|
||||
stack.push(picker.setColumnValues(1, cityList, false));
|
||||
indexes.push(this.getIndex('city', code));
|
||||
if (cityList.length && code.slice(2, 4) === '00') {
|
||||
code = cityList[0].code;
|
||||
}
|
||||
}
|
||||
if (columnsNum === 3) {
|
||||
stack.push(
|
||||
picker.setColumnValues(
|
||||
2,
|
||||
this.getList('county', code.slice(0, 4)),
|
||||
false
|
||||
)
|
||||
);
|
||||
indexes.push(this.getIndex('county', code));
|
||||
}
|
||||
return Promise.all(stack)
|
||||
.catch(function () {})
|
||||
.then(function () {
|
||||
return picker.setIndexes(indexes);
|
||||
})
|
||||
.catch(function () {});
|
||||
},
|
||||
getDefaultCode: function () {
|
||||
var columnsPlaceholder = this.data.columnsPlaceholder;
|
||||
if (columnsPlaceholder.length) {
|
||||
return EMPTY_CODE;
|
||||
}
|
||||
var countyCodes = Object.keys(this.getConfig('county'));
|
||||
if (countyCodes[0]) {
|
||||
return countyCodes[0];
|
||||
}
|
||||
var cityCodes = Object.keys(this.getConfig('city'));
|
||||
if (cityCodes[0]) {
|
||||
return cityCodes[0];
|
||||
}
|
||||
return '';
|
||||
},
|
||||
getValues: function () {
|
||||
var picker = this.getPicker();
|
||||
if (!picker) {
|
||||
return [];
|
||||
}
|
||||
return this.parseValues(
|
||||
picker.getValues().filter(function (value) {
|
||||
return !!value;
|
||||
})
|
||||
);
|
||||
},
|
||||
getDetail: function () {
|
||||
var values = this.getValues();
|
||||
var area = {
|
||||
code: '',
|
||||
country: '',
|
||||
province: '',
|
||||
city: '',
|
||||
county: '',
|
||||
};
|
||||
if (!values.length) {
|
||||
return area;
|
||||
}
|
||||
var names = values.map(function (item) {
|
||||
return item.name;
|
||||
});
|
||||
area.code = values[values.length - 1].code;
|
||||
if (area.code[0] === '9') {
|
||||
area.country = names[1] || '';
|
||||
area.province = names[2] || '';
|
||||
} else {
|
||||
area.province = names[0] || '';
|
||||
area.city = names[1] || '';
|
||||
area.county = names[2] || '';
|
||||
}
|
||||
return area;
|
||||
},
|
||||
reset: function (code) {
|
||||
this.code = code || '';
|
||||
return this.setValues();
|
||||
},
|
||||
},
|
||||
});
|
||||
6
miniprogram_npm/@vant/weapp/area/index.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-picker": "../picker/index"
|
||||
}
|
||||
}
|
||||
20
miniprogram_npm/@vant/weapp/area/index.wxml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<wxs src="./index.wxs" module="computed" />
|
||||
|
||||
<van-picker
|
||||
class="van-area__picker"
|
||||
active-class="active-class"
|
||||
toolbar-class="toolbar-class"
|
||||
column-class="column-class"
|
||||
show-toolbar
|
||||
value-key="name"
|
||||
title="{{ title }}"
|
||||
loading="{{ loading }}"
|
||||
columns="{{ computed.displayColumns(columns, columnsNum) }}"
|
||||
item-height="{{ itemHeight }}"
|
||||
visible-item-count="{{ visibleItemCount }}"
|
||||
cancel-button-text="{{ cancelButtonText }}"
|
||||
confirm-button-text="{{ confirmButtonText }}"
|
||||
bind:change="onChange"
|
||||
bind:confirm="onConfirm"
|
||||
bind:cancel="onCancel"
|
||||
/>
|
||||
8
miniprogram_npm/@vant/weapp/area/index.wxs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* eslint-disable */
|
||||
function displayColumns(columns, columnsNum) {
|
||||
return columns.slice(0, +columnsNum);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
displayColumns: displayColumns,
|
||||
};
|
||||
1
miniprogram_npm/@vant/weapp/area/index.wxss
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import '../common/index.wxss';
|
||||
71
miniprogram_npm/@vant/weapp/button/index.js
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var component_1 = require('../common/component');
|
||||
var button_1 = require('../mixins/button');
|
||||
var version_1 = require('../common/version');
|
||||
var mixins = [button_1.button];
|
||||
if (version_1.canIUseFormFieldButton()) {
|
||||
mixins.push('wx://form-field-button');
|
||||
}
|
||||
component_1.VantComponent({
|
||||
mixins: mixins,
|
||||
classes: ['hover-class', 'loading-class'],
|
||||
data: {
|
||||
baseStyle: '',
|
||||
},
|
||||
props: {
|
||||
formType: String,
|
||||
icon: String,
|
||||
classPrefix: {
|
||||
type: String,
|
||||
value: 'van-icon',
|
||||
},
|
||||
plain: Boolean,
|
||||
block: Boolean,
|
||||
round: Boolean,
|
||||
square: Boolean,
|
||||
loading: Boolean,
|
||||
hairline: Boolean,
|
||||
disabled: Boolean,
|
||||
loadingText: String,
|
||||
customStyle: String,
|
||||
loadingType: {
|
||||
type: String,
|
||||
value: 'circular',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
},
|
||||
dataset: null,
|
||||
size: {
|
||||
type: String,
|
||||
value: 'normal',
|
||||
},
|
||||
loadingSize: {
|
||||
type: String,
|
||||
value: '20px',
|
||||
},
|
||||
color: String,
|
||||
},
|
||||
methods: {
|
||||
onClick: function (event) {
|
||||
var _this = this;
|
||||
this.$emit('click', event);
|
||||
var _a = this.data,
|
||||
canIUseGetUserProfile = _a.canIUseGetUserProfile,
|
||||
openType = _a.openType,
|
||||
getUserProfileDesc = _a.getUserProfileDesc,
|
||||
lang = _a.lang;
|
||||
if (openType === 'getUserInfo' && canIUseGetUserProfile) {
|
||||
wx.getUserProfile({
|
||||
desc: getUserProfileDesc || ' ',
|
||||
lang: lang || 'en',
|
||||
complete: function (userProfile) {
|
||||
_this.$emit('getuserinfo', userProfile);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
7
miniprogram_npm/@vant/weapp/button/index.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-icon": "../icon/index",
|
||||
"van-loading": "../loading/index"
|
||||
}
|
||||
}
|
||||
53
miniprogram_npm/@vant/weapp/button/index.wxml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<wxs src="../wxs/utils.wxs" module="utils" />
|
||||
<wxs src="./index.wxs" module="computed" />
|
||||
|
||||
<button
|
||||
id="{{ id }}"
|
||||
data-detail="{{ dataset }}"
|
||||
class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}"
|
||||
hover-class="van-button--active hover-class"
|
||||
lang="{{ lang }}"
|
||||
form-type="{{ formType }}"
|
||||
style="{{ computed.rootStyle({ plain, color, customStyle }) }}"
|
||||
open-type="{{ disabled || loading || (canIUseGetUserProfile && openType === 'getUserInfo') ? '' : openType }}"
|
||||
business-id="{{ businessId }}"
|
||||
session-from="{{ sessionFrom }}"
|
||||
send-message-title="{{ sendMessageTitle }}"
|
||||
send-message-path="{{ sendMessagePath }}"
|
||||
send-message-img="{{ sendMessageImg }}"
|
||||
show-message-card="{{ showMessageCard }}"
|
||||
app-parameter="{{ appParameter }}"
|
||||
aria-label="{{ ariaLabel }}"
|
||||
bindtap="{{ disabled || loading ? '' : 'onClick' }}"
|
||||
bindgetuserinfo="onGetUserInfo"
|
||||
bindcontact="onContact"
|
||||
bindgetphonenumber="onGetPhoneNumber"
|
||||
binderror="onError"
|
||||
bindlaunchapp="onLaunchApp"
|
||||
bindopensetting="onOpenSetting"
|
||||
>
|
||||
<block wx:if="{{ loading }}">
|
||||
<van-loading
|
||||
custom-class="loading-class"
|
||||
size="{{ loadingSize }}"
|
||||
type="{{ loadingType }}"
|
||||
color="{{ computed.loadingColor({ type, color, plain }) }}"
|
||||
/>
|
||||
<view wx:if="{{ loadingText }}" class="van-button__loading-text">
|
||||
{{ loadingText }}
|
||||
</view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<van-icon
|
||||
wx:if="{{ icon }}"
|
||||
size="1.2em"
|
||||
name="{{ icon }}"
|
||||
class-prefix="{{ classPrefix }}"
|
||||
class="van-button__icon"
|
||||
custom-style="line-height: inherit;"
|
||||
/>
|
||||
<view class="van-button__text">
|
||||
<slot />
|
||||
</view>
|
||||
</block>
|
||||
</button>
|
||||
39
miniprogram_npm/@vant/weapp/button/index.wxs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* eslint-disable */
|
||||
var style = require('../wxs/style.wxs');
|
||||
|
||||
function rootStyle(data) {
|
||||
if (!data.color) {
|
||||
return data.customStyle;
|
||||
}
|
||||
|
||||
var properties = {
|
||||
color: data.plain ? data.color : '#fff',
|
||||
background: data.plain ? null : data.color,
|
||||
};
|
||||
|
||||
// hide border when color is linear-gradient
|
||||
if (data.color.indexOf('gradient') !== -1) {
|
||||
properties.border = 0;
|
||||
} else {
|
||||
properties['border-color'] = data.color;
|
||||
}
|
||||
|
||||
return style([properties, data.customStyle]);
|
||||
}
|
||||
|
||||
function loadingColor(data) {
|
||||
if (data.plain) {
|
||||
return data.color ? data.color : '#c9c9c9';
|
||||
}
|
||||
|
||||
if (data.type === 'default') {
|
||||
return '#c9c9c9';
|
||||
}
|
||||
|
||||
return '#fff';
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
rootStyle: rootStyle,
|
||||
loadingColor: loadingColor,
|
||||
};
|
||||
1
miniprogram_npm/@vant/weapp/button/index.wxss
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import '../common/index.wxss';.van-button{position:relative;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;padding:0;text-align:center;vertical-align:middle;-webkit-appearance:none;-webkit-text-size-adjust:100%;height:44px;height:var(--button-default-height,44px);line-height:20px;line-height:var(--button-line-height,20px);font-size:16px;font-size:var(--button-default-font-size,16px);transition:opacity .2s;transition:opacity var(--animation-duration-fast,.2s);border-radius:2px;border-radius:var(--button-border-radius,2px)}.van-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;border:inherit;border-radius:inherit;transform:translate(-50%,-50%);opacity:0;content:" ";background-color:#000;background-color:var(--black,#000);border-color:#000;border-color:var(--black,#000)}.van-button:after{border-width:0}.van-button--active:before{opacity:.15}.van-button--unclickable:after{display:none}.van-button--default{color:#323233;color:var(--button-default-color,#323233);background:#fff;background:var(--button-default-background-color,#fff);border:1px solid #ebedf0;border:var(--button-border-width,1px) solid var(--button-default-border-color,#ebedf0)}.van-button--primary{color:#fff;color:var(--button-primary-color,#fff);background:#07c160;background:var(--button-primary-background-color,#07c160);border:1px solid #07c160;border:var(--button-border-width,1px) solid var(--button-primary-border-color,#07c160)}.van-button--info{color:#fff;color:var(--button-info-color,#fff);background:#1989fa;background:var(--button-info-background-color,#1989fa);border:1px solid #1989fa;border:var(--button-border-width,1px) solid var(--button-info-border-color,#1989fa)}.van-button--danger{color:#fff;color:var(--button-danger-color,#fff);background:#ee0a24;background:var(--button-danger-background-color,#ee0a24);border:1px solid #ee0a24;border:var(--button-border-width,1px) solid var(--button-danger-border-color,#ee0a24)}.van-button--warning{color:#fff;color:var(--button-warning-color,#fff);background:#ff976a;background:var(--button-warning-background-color,#ff976a);border:1px solid #ff976a;border:var(--button-border-width,1px) solid var(--button-warning-border-color,#ff976a)}.van-button--plain{background:#fff;background:var(--button-plain-background-color,#fff)}.van-button--plain.van-button--primary{color:#07c160;color:var(--button-primary-background-color,#07c160)}.van-button--plain.van-button--info{color:#1989fa;color:var(--button-info-background-color,#1989fa)}.van-button--plain.van-button--danger{color:#ee0a24;color:var(--button-danger-background-color,#ee0a24)}.van-button--plain.van-button--warning{color:#ff976a;color:var(--button-warning-background-color,#ff976a)}.van-button--large{width:100%;height:50px;height:var(--button-large-height,50px)}.van-button--normal{padding:0 15px;font-size:14px;font-size:var(--button-normal-font-size,14px)}.van-button--small{min-width:60px;min-width:var(--button-small-min-width,60px);height:30px;height:var(--button-small-height,30px);padding:0 8px;padding:0 var(--padding-xs,8px);font-size:12px;font-size:var(--button-small-font-size,12px)}.van-button--mini{display:inline-block;min-width:50px;min-width:var(--button-mini-min-width,50px);height:22px;height:var(--button-mini-height,22px);font-size:10px;font-size:var(--button-mini-font-size,10px)}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{display:flex;width:100%}.van-button--round{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--square{border-radius:0}.van-button--disabled{opacity:.5;opacity:var(--button-disabled-opacity,.5)}.van-button__text{display:inline}.van-button__icon+.van-button__text:not(:empty),.van-button__loading-text{margin-left:4px}.van-button__icon{min-width:1em;line-height:inherit!important;vertical-align:top}.van-button--hairline{padding-top:1px;border-width:0}.van-button--hairline:after{border-color:inherit;border-width:1px;border-radius:4px;border-radius:calc(var(--button-border-radius, 2px)*2)}.van-button--hairline.van-button--round:after{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--hairline.van-button--square:after{border-radius:0}
|
||||
68
miniprogram_npm/@vant/weapp/calendar/calendar.wxml
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<view class="van-calendar">
|
||||
<header
|
||||
title="{{ title }}"
|
||||
showTitle="{{ showTitle }}"
|
||||
subtitle="{{ subtitle }}"
|
||||
showSubtitle="{{ showSubtitle }}"
|
||||
firstDayOfWeek="{{ firstDayOfWeek }}"
|
||||
bind:click-subtitle="onClickSubtitle"
|
||||
>
|
||||
<slot name="title" slot="title"></slot>
|
||||
</header>
|
||||
|
||||
<scroll-view
|
||||
class="van-calendar__body"
|
||||
scroll-y
|
||||
scroll-into-view="{{ scrollIntoView }}"
|
||||
>
|
||||
<month
|
||||
wx:for="{{ computed.getMonths(minDate, maxDate) }}"
|
||||
wx:key="index"
|
||||
id="month{{ index }}"
|
||||
class="month"
|
||||
data-date="{{ item }}"
|
||||
date="{{ item }}"
|
||||
type="{{ type }}"
|
||||
color="{{ color }}"
|
||||
minDate="{{ minDate }}"
|
||||
maxDate="{{ maxDate }}"
|
||||
showMark="{{ showMark }}"
|
||||
formatter="{{ formatter }}"
|
||||
rowHeight="{{ rowHeight }}"
|
||||
currentDate="{{ currentDate }}"
|
||||
showSubtitle="{{ showSubtitle }}"
|
||||
allowSameDay="{{ allowSameDay }}"
|
||||
showMonthTitle="{{ index !== 0 || !showSubtitle }}"
|
||||
firstDayOfWeek="{{ firstDayOfWeek }}"
|
||||
bind:click="onClickDay"
|
||||
/>
|
||||
</scroll-view>
|
||||
|
||||
<view
|
||||
class="{{ utils.bem('calendar__footer', { safeAreaInsetBottom }) }}"
|
||||
>
|
||||
<slot name="footer"></slot>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="{{ utils.bem('calendar__footer', { safeAreaInsetBottom }) }}"
|
||||
>
|
||||
<van-button
|
||||
wx:if="{{ showConfirm }}"
|
||||
round
|
||||
block
|
||||
type="danger"
|
||||
color="{{ color }}"
|
||||
custom-class="van-calendar__confirm"
|
||||
disabled="{{ computed.getButtonDisabled(type, currentDate) }}"
|
||||
nativeType="text"
|
||||
bind:click="onConfirm"
|
||||
>
|
||||
{{
|
||||
computed.getButtonDisabled(type, currentDate)
|
||||
? confirmDisabledText
|
||||
: confirmText
|
||||
}}
|
||||
</van-button>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
'use strict';
|
||||
var __spreadArray =
|
||||
(this && this.__spreadArray) ||
|
||||
function (to, from) {
|
||||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||||
to[j] = from[i];
|
||||
return to;
|
||||
};
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var component_1 = require('../../../common/component');
|
||||
component_1.VantComponent({
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
value: '日期选择',
|
||||
},
|
||||
subtitle: String,
|
||||
showTitle: Boolean,
|
||||
showSubtitle: Boolean,
|
||||
firstDayOfWeek: {
|
||||
type: Number,
|
||||
observer: 'initWeekDay',
|
||||
},
|
||||
},
|
||||
data: {
|
||||
weekdays: [],
|
||||
},
|
||||
created: function () {
|
||||
this.initWeekDay();
|
||||
},
|
||||
methods: {
|
||||
initWeekDay: function () {
|
||||
var defaultWeeks = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
var firstDayOfWeek = this.data.firstDayOfWeek || 0;
|
||||
this.setData({
|
||||
weekdays: __spreadArray(
|
||||
__spreadArray([], defaultWeeks.slice(firstDayOfWeek, 7)),
|
||||
defaultWeeks.slice(0, firstDayOfWeek)
|
||||
),
|
||||
});
|
||||
},
|
||||
onClickSubtitle: function (event) {
|
||||
this.$emit('click-subtitle', event);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"component": true
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<view class="van-calendar__header">
|
||||
<block wx:if="{{ showTitle }}">
|
||||
<view class="van-calendar__header-title"><slot name="title"></slot></view>
|
||||
<view class="van-calendar__header-title">{{ title }}</view>
|
||||
</block>
|
||||
|
||||
<view wx:if="{{ showSubtitle }}" class="van-calendar__header-subtitle" bind:tap="onClickSubtitle">
|
||||
{{ subtitle }}
|
||||
</view>
|
||||
|
||||
<view class="van-calendar__weekdays">
|
||||
<view wx:for="{{ weekdays }}" wx:key="index" class="van-calendar__weekday">
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -0,0 +1 @@
|
|||
@import '../../../common/index.wxss';.van-calendar__header{flex-shrink:0;box-shadow:0 2px 10px rgba(125,126,128,.16);box-shadow:var(--calendar-header-box-shadow,0 2px 10px rgba(125,126,128,.16))}.van-calendar__header-subtitle,.van-calendar__header-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__header-title+.van-calendar__header-title,.van-calendar__header-title:empty{display:none}.van-calendar__header-title:empty+.van-calendar__header-title{display:block!important}.van-calendar__weekdays{display:flex}.van-calendar__weekday{flex:1;text-align:center;font-size:12px;font-size:var(--calendar-weekdays-font-size,12px);line-height:30px;line-height:var(--calendar-weekdays-height,30px)}
|
||||
173
miniprogram_npm/@vant/weapp/calendar/components/month/index.js
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var component_1 = require('../../../common/component');
|
||||
var utils_1 = require('../../utils');
|
||||
component_1.VantComponent({
|
||||
props: {
|
||||
date: {
|
||||
type: null,
|
||||
observer: 'setDays',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
observer: 'setDays',
|
||||
},
|
||||
color: String,
|
||||
minDate: {
|
||||
type: null,
|
||||
observer: 'setDays',
|
||||
},
|
||||
maxDate: {
|
||||
type: null,
|
||||
observer: 'setDays',
|
||||
},
|
||||
showMark: Boolean,
|
||||
rowHeight: null,
|
||||
formatter: {
|
||||
type: null,
|
||||
observer: 'setDays',
|
||||
},
|
||||
currentDate: {
|
||||
type: null,
|
||||
observer: 'setDays',
|
||||
},
|
||||
firstDayOfWeek: {
|
||||
type: Number,
|
||||
observer: 'setDays',
|
||||
},
|
||||
allowSameDay: Boolean,
|
||||
showSubtitle: Boolean,
|
||||
showMonthTitle: Boolean,
|
||||
},
|
||||
data: {
|
||||
visible: true,
|
||||
days: [],
|
||||
},
|
||||
methods: {
|
||||
onClick: function (event) {
|
||||
var index = event.currentTarget.dataset.index;
|
||||
var item = this.data.days[index];
|
||||
if (item.type !== 'disabled') {
|
||||
this.$emit('click', item);
|
||||
}
|
||||
},
|
||||
setDays: function () {
|
||||
var days = [];
|
||||
var startDate = new Date(this.data.date);
|
||||
var year = startDate.getFullYear();
|
||||
var month = startDate.getMonth();
|
||||
var totalDay = utils_1.getMonthEndDay(
|
||||
startDate.getFullYear(),
|
||||
startDate.getMonth() + 1
|
||||
);
|
||||
for (var day = 1; day <= totalDay; day++) {
|
||||
var date = new Date(year, month, day);
|
||||
var type = this.getDayType(date);
|
||||
var config = {
|
||||
date: date,
|
||||
type: type,
|
||||
text: day,
|
||||
bottomInfo: this.getBottomInfo(type),
|
||||
};
|
||||
if (this.data.formatter) {
|
||||
config = this.data.formatter(config);
|
||||
}
|
||||
days.push(config);
|
||||
}
|
||||
this.setData({ days: days });
|
||||
},
|
||||
getMultipleDayType: function (day) {
|
||||
var currentDate = this.data.currentDate;
|
||||
if (!Array.isArray(currentDate)) {
|
||||
return '';
|
||||
}
|
||||
var isSelected = function (date) {
|
||||
return currentDate.some(function (item) {
|
||||
return utils_1.compareDay(item, date) === 0;
|
||||
});
|
||||
};
|
||||
if (isSelected(day)) {
|
||||
var prevDay = utils_1.getPrevDay(day);
|
||||
var nextDay = utils_1.getNextDay(day);
|
||||
var prevSelected = isSelected(prevDay);
|
||||
var nextSelected = isSelected(nextDay);
|
||||
if (prevSelected && nextSelected) {
|
||||
return 'multiple-middle';
|
||||
}
|
||||
if (prevSelected) {
|
||||
return 'end';
|
||||
}
|
||||
return nextSelected ? 'start' : 'multiple-selected';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
getRangeDayType: function (day) {
|
||||
var _a = this.data,
|
||||
currentDate = _a.currentDate,
|
||||
allowSameDay = _a.allowSameDay;
|
||||
if (!Array.isArray(currentDate)) {
|
||||
return '';
|
||||
}
|
||||
var startDay = currentDate[0],
|
||||
endDay = currentDate[1];
|
||||
if (!startDay) {
|
||||
return '';
|
||||
}
|
||||
var compareToStart = utils_1.compareDay(day, startDay);
|
||||
if (!endDay) {
|
||||
return compareToStart === 0 ? 'start' : '';
|
||||
}
|
||||
var compareToEnd = utils_1.compareDay(day, endDay);
|
||||
if (compareToStart === 0 && compareToEnd === 0 && allowSameDay) {
|
||||
return 'start-end';
|
||||
}
|
||||
if (compareToStart === 0) {
|
||||
return 'start';
|
||||
}
|
||||
if (compareToEnd === 0) {
|
||||
return 'end';
|
||||
}
|
||||
if (compareToStart > 0 && compareToEnd < 0) {
|
||||
return 'middle';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
getDayType: function (day) {
|
||||
var _a = this.data,
|
||||
type = _a.type,
|
||||
minDate = _a.minDate,
|
||||
maxDate = _a.maxDate,
|
||||
currentDate = _a.currentDate;
|
||||
if (
|
||||
utils_1.compareDay(day, minDate) < 0 ||
|
||||
utils_1.compareDay(day, maxDate) > 0
|
||||
) {
|
||||
return 'disabled';
|
||||
}
|
||||
if (type === 'single') {
|
||||
return utils_1.compareDay(day, currentDate) === 0 ? 'selected' : '';
|
||||
}
|
||||
if (type === 'multiple') {
|
||||
return this.getMultipleDayType(day);
|
||||
}
|
||||
/* istanbul ignore else */
|
||||
if (type === 'range') {
|
||||
return this.getRangeDayType(day);
|
||||
}
|
||||
return '';
|
||||
},
|
||||
getBottomInfo: function (type) {
|
||||
if (this.data.type === 'range') {
|
||||
if (type === 'start') {
|
||||
return '开始';
|
||||
}
|
||||
if (type === 'end') {
|
||||
return '结束';
|
||||
}
|
||||
if (type === 'start-end') {
|
||||
return '开始/结束';
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"component": true
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<wxs src="./index.wxs" module="computed"></wxs>
|
||||
<wxs src="../../../wxs/utils.wxs" module="utils" />
|
||||
|
||||
<view class="van-calendar__month" style="{{ computed.getMonthStyle(visible, date, rowHeight) }}">
|
||||
<view wx:if="{{ showMonthTitle }}" class="van-calendar__month-title">
|
||||
{{ computed.formatMonthTitle(date) }}
|
||||
</view>
|
||||
|
||||
<view wx:if="{{ visible }}" class="van-calendar__days">
|
||||
<view wx:if="{{ showMark }}" class="van-calendar__month-mark">
|
||||
{{ computed.getMark(date) }}
|
||||
</view>
|
||||
|
||||
<view
|
||||
wx:for="{{ days }}"
|
||||
wx:key="index"
|
||||
style="{{ computed.getDayStyle(item.type, index, date, rowHeight, color, firstDayOfWeek) }}"
|
||||
class="{{ utils.bem('calendar__day', [item.type]) }} {{ item.className }}"
|
||||
data-index="{{ index }}"
|
||||
bindtap="onClick"
|
||||
>
|
||||
<view wx:if="{{ item.type === 'selected' }}" class="van-calendar__selected-day" style="background: {{ color }}">
|
||||
<view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
|
||||
{{ item.text }}
|
||||
<view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
|
||||
{{ item.bottomInfo }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view wx:else>
|
||||
<view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
|
||||
{{ item.text }}
|
||||
<view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
|
||||
{{ item.bottomInfo }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/* eslint-disable */
|
||||
var utils = require('../../utils.wxs');
|
||||
|
||||
function getMark(date) {
|
||||
return getDate(date).getMonth() + 1;
|
||||
}
|
||||
|
||||
var ROW_HEIGHT = 64;
|
||||
|
||||
function getDayStyle(type, index, date, rowHeight, color, firstDayOfWeek) {
|
||||
var style = [];
|
||||
var current = getDate(date).getDay() || 7;
|
||||
var offset = current < firstDayOfWeek ? (7 - firstDayOfWeek + current) :
|
||||
current === 7 && firstDayOfWeek === 0 ? 0 :
|
||||
(current - firstDayOfWeek);
|
||||
|
||||
if (index === 0) {
|
||||
style.push(['margin-left', (100 * offset) / 7 + '%']);
|
||||
}
|
||||
|
||||
if (rowHeight !== ROW_HEIGHT) {
|
||||
style.push(['height', rowHeight + 'px']);
|
||||
}
|
||||
|
||||
if (color) {
|
||||
if (
|
||||
type === 'start' ||
|
||||
type === 'end' ||
|
||||
type === 'start-end' ||
|
||||
type === 'multiple-selected' ||
|
||||
type === 'multiple-middle'
|
||||
) {
|
||||
style.push(['background', color]);
|
||||
} else if (type === 'middle') {
|
||||
style.push(['color', color]);
|
||||
}
|
||||
}
|
||||
|
||||
return style
|
||||
.map(function(item) {
|
||||
return item.join(':');
|
||||
})
|
||||
.join(';');
|
||||
}
|
||||
|
||||
function formatMonthTitle(date) {
|
||||
date = getDate(date);
|
||||
return date.getFullYear() + '年' + (date.getMonth() + 1) + '月';
|
||||
}
|
||||
|
||||
function getMonthStyle(visible, date, rowHeight) {
|
||||
if (!visible) {
|
||||
date = getDate(date);
|
||||
|
||||
var totalDay = utils.getMonthEndDay(
|
||||
date.getFullYear(),
|
||||
date.getMonth() + 1
|
||||
);
|
||||
var offset = getDate(date).getDay();
|
||||
var padding = Math.ceil((totalDay + offset) / 7) * rowHeight;
|
||||
|
||||
return 'padding-bottom:' + padding + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getMark: getMark,
|
||||
getDayStyle: getDayStyle,
|
||||
formatMonthTitle: formatMonthTitle,
|
||||
getMonthStyle: getMonthStyle
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
@import '../../../common/index.wxss';.van-calendar{display:flex;flex-direction:column;height:100%;background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__month-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);font-size:14px;font-size:var(--calendar-month-title-font-size,14px);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__days{position:relative;display:flex;flex-wrap:wrap;-webkit-user-select:none;user-select:none}.van-calendar__month-mark{position:absolute;top:50%;left:50%;z-index:0;transform:translate(-50%,-50%);pointer-events:none;color:rgba(242,243,245,.8);color:var(--calendar-month-mark-color,rgba(242,243,245,.8));font-size:160px;font-size:var(--calendar-month-mark-font-size,160px)}.van-calendar__day,.van-calendar__selected-day{display:flex;align-items:center;justify-content:center;text-align:center}.van-calendar__day{position:relative;width:14.285%;height:64px;height:var(--calendar-day-height,64px);font-size:16px;font-size:var(--calendar-day-font-size,16px)}.van-calendar__day--end,.van-calendar__day--multiple-middle,.van-calendar__day--multiple-selected,.van-calendar__day--start,.van-calendar__day--start-end{color:#fff;color:var(--calendar-range-edge-color,#fff);background-color:#ee0a24;background-color:var(--calendar-range-edge-background-color,#ee0a24)}.van-calendar__day--start{border-radius:4px 0 0 4px;border-radius:var(--border-radius-md,4px) 0 0 var(--border-radius-md,4px)}.van-calendar__day--end{border-radius:0 4px 4px 0;border-radius:0 var(--border-radius-md,4px) var(--border-radius-md,4px) 0}.van-calendar__day--multiple-selected,.van-calendar__day--start-end{border-radius:4px;border-radius:var(--border-radius-md,4px)}.van-calendar__day--middle{color:#ee0a24;color:var(--calendar-range-middle-color,#ee0a24)}.van-calendar__day--middle:after{position:absolute;top:0;right:0;bottom:0;left:0;background-color:currentColor;content:"";opacity:.1;opacity:var(--calendar-range-middle-background-opacity,.1)}.van-calendar__day--disabled{cursor:default;color:#c8c9cc;color:var(--calendar-day-disabled-color,#c8c9cc)}.van-calendar__bottom-info,.van-calendar__top-info{position:absolute;right:0;left:0;font-size:10px;font-size:var(--calendar-info-font-size,10px);line-height:14px;line-height:var(--calendar-info-line-height,14px)}@media (max-width:350px){.van-calendar__bottom-info,.van-calendar__top-info{font-size:9px}}.van-calendar__top-info{top:6px}.van-calendar__bottom-info{bottom:6px}.van-calendar__selected-day{width:54px;width:var(--calendar-selected-day-size,54px);height:54px;height:var(--calendar-selected-day-size,54px);color:#fff;color:var(--calendar-selected-day-color,#fff);background-color:#ee0a24;background-color:var(--calendar-selected-day-background-color,#ee0a24);border-radius:4px;border-radius:var(--border-radius-md,4px)}
|
||||
382
miniprogram_npm/@vant/weapp/calendar/index.js
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
'use strict';
|
||||
var __spreadArray =
|
||||
(this && this.__spreadArray) ||
|
||||
function (to, from) {
|
||||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||||
to[j] = from[i];
|
||||
return to;
|
||||
};
|
||||
var __importDefault =
|
||||
(this && this.__importDefault) ||
|
||||
function (mod) {
|
||||
return mod && mod.__esModule ? mod : { default: mod };
|
||||
};
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var component_1 = require('../common/component');
|
||||
var utils_1 = require('./utils');
|
||||
var toast_1 = __importDefault(require('../toast/toast'));
|
||||
var utils_2 = require('../common/utils');
|
||||
var initialMinDate = utils_1.getToday().getTime();
|
||||
var initialMaxDate = (function () {
|
||||
var now = utils_1.getToday();
|
||||
return new Date(
|
||||
now.getFullYear(),
|
||||
now.getMonth() + 6,
|
||||
now.getDate()
|
||||
).getTime();
|
||||
})();
|
||||
component_1.VantComponent({
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
value: '日期选择',
|
||||
},
|
||||
color: String,
|
||||
show: {
|
||||
type: Boolean,
|
||||
observer: function (val) {
|
||||
if (val) {
|
||||
this.initRect();
|
||||
this.scrollIntoView();
|
||||
}
|
||||
},
|
||||
},
|
||||
formatter: null,
|
||||
confirmText: {
|
||||
type: String,
|
||||
value: '确定',
|
||||
},
|
||||
rangePrompt: String,
|
||||
showRangePrompt: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
defaultDate: {
|
||||
type: null,
|
||||
observer: function (val) {
|
||||
this.setData({ currentDate: val });
|
||||
this.scrollIntoView();
|
||||
},
|
||||
},
|
||||
allowSameDay: Boolean,
|
||||
confirmDisabledText: String,
|
||||
type: {
|
||||
type: String,
|
||||
value: 'single',
|
||||
observer: 'reset',
|
||||
},
|
||||
minDate: {
|
||||
type: null,
|
||||
value: initialMinDate,
|
||||
},
|
||||
maxDate: {
|
||||
type: null,
|
||||
value: initialMaxDate,
|
||||
},
|
||||
position: {
|
||||
type: String,
|
||||
value: 'bottom',
|
||||
},
|
||||
rowHeight: {
|
||||
type: null,
|
||||
value: utils_1.ROW_HEIGHT,
|
||||
},
|
||||
round: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
poppable: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
showMark: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
showTitle: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
showConfirm: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
showSubtitle: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
safeAreaInsetBottom: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
closeOnClickOverlay: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
maxRange: {
|
||||
type: null,
|
||||
value: null,
|
||||
},
|
||||
firstDayOfWeek: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
subtitle: '',
|
||||
currentDate: null,
|
||||
scrollIntoView: '',
|
||||
},
|
||||
created: function () {
|
||||
this.setData({
|
||||
currentDate: this.getInitialDate(),
|
||||
});
|
||||
},
|
||||
mounted: function () {
|
||||
if (this.data.show || !this.data.poppable) {
|
||||
this.initRect();
|
||||
this.scrollIntoView();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reset: function () {
|
||||
this.setData({ currentDate: this.getInitialDate() });
|
||||
this.scrollIntoView();
|
||||
},
|
||||
initRect: function () {
|
||||
var _this = this;
|
||||
if (this.contentObserver != null) {
|
||||
this.contentObserver.disconnect();
|
||||
}
|
||||
var contentObserver = this.createIntersectionObserver({
|
||||
thresholds: [0, 0.1, 0.9, 1],
|
||||
observeAll: true,
|
||||
});
|
||||
this.contentObserver = contentObserver;
|
||||
contentObserver.relativeTo('.van-calendar__body');
|
||||
contentObserver.observe('.month', function (res) {
|
||||
if (res.boundingClientRect.top <= res.relativeRect.top) {
|
||||
// @ts-ignore
|
||||
_this.setData({
|
||||
subtitle: utils_1.formatMonthTitle(res.dataset.date),
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
limitDateRange: function (date, minDate, maxDate) {
|
||||
if (minDate === void 0) {
|
||||
minDate = null;
|
||||
}
|
||||
if (maxDate === void 0) {
|
||||
maxDate = null;
|
||||
}
|
||||
minDate = minDate || this.data.minDate;
|
||||
maxDate = maxDate || this.data.maxDate;
|
||||
if (utils_1.compareDay(date, minDate) === -1) {
|
||||
return minDate;
|
||||
}
|
||||
if (utils_1.compareDay(date, maxDate) === 1) {
|
||||
return maxDate;
|
||||
}
|
||||
return date;
|
||||
},
|
||||
getInitialDate: function (defaultDate) {
|
||||
var _this = this;
|
||||
if (defaultDate === void 0) {
|
||||
defaultDate = null;
|
||||
}
|
||||
var _a = this.data,
|
||||
type = _a.type,
|
||||
minDate = _a.minDate,
|
||||
maxDate = _a.maxDate;
|
||||
var now = utils_1.getToday().getTime();
|
||||
if (type === 'range') {
|
||||
if (!Array.isArray(defaultDate)) {
|
||||
defaultDate = [];
|
||||
}
|
||||
var _b = defaultDate || [],
|
||||
startDay = _b[0],
|
||||
endDay = _b[1];
|
||||
var start = this.limitDateRange(
|
||||
startDay || now,
|
||||
minDate,
|
||||
utils_1.getPrevDay(maxDate).getTime()
|
||||
);
|
||||
var end = this.limitDateRange(
|
||||
endDay || now,
|
||||
utils_1.getNextDay(minDate).getTime()
|
||||
);
|
||||
return [start, end];
|
||||
}
|
||||
if (type === 'multiple') {
|
||||
if (Array.isArray(defaultDate)) {
|
||||
return defaultDate.map(function (date) {
|
||||
return _this.limitDateRange(date);
|
||||
});
|
||||
}
|
||||
return [this.limitDateRange(now)];
|
||||
}
|
||||
if (!defaultDate || Array.isArray(defaultDate)) {
|
||||
defaultDate = now;
|
||||
}
|
||||
return this.limitDateRange(defaultDate);
|
||||
},
|
||||
scrollIntoView: function () {
|
||||
var _this = this;
|
||||
utils_2.requestAnimationFrame(function () {
|
||||
var _a = _this.data,
|
||||
currentDate = _a.currentDate,
|
||||
type = _a.type,
|
||||
show = _a.show,
|
||||
poppable = _a.poppable,
|
||||
minDate = _a.minDate,
|
||||
maxDate = _a.maxDate;
|
||||
// @ts-ignore
|
||||
var targetDate = type === 'single' ? currentDate : currentDate[0];
|
||||
var displayed = show || !poppable;
|
||||
if (!targetDate || !displayed) {
|
||||
return;
|
||||
}
|
||||
var months = utils_1.getMonths(minDate, maxDate);
|
||||
months.some(function (month, index) {
|
||||
if (utils_1.compareMonth(month, targetDate) === 0) {
|
||||
_this.setData({ scrollIntoView: 'month' + index });
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
},
|
||||
onOpen: function () {
|
||||
this.$emit('open');
|
||||
},
|
||||
onOpened: function () {
|
||||
this.$emit('opened');
|
||||
},
|
||||
onClose: function () {
|
||||
this.$emit('close');
|
||||
},
|
||||
onClosed: function () {
|
||||
this.$emit('closed');
|
||||
},
|
||||
onClickDay: function (event) {
|
||||
var date = event.detail.date;
|
||||
var _a = this.data,
|
||||
type = _a.type,
|
||||
currentDate = _a.currentDate,
|
||||
allowSameDay = _a.allowSameDay;
|
||||
if (type === 'range') {
|
||||
// @ts-ignore
|
||||
var startDay = currentDate[0],
|
||||
endDay = currentDate[1];
|
||||
if (startDay && !endDay) {
|
||||
var compareToStart = utils_1.compareDay(date, startDay);
|
||||
if (compareToStart === 1) {
|
||||
this.select([startDay, date], true);
|
||||
} else if (compareToStart === -1) {
|
||||
this.select([date, null]);
|
||||
} else if (allowSameDay) {
|
||||
this.select([date, date]);
|
||||
}
|
||||
} else {
|
||||
this.select([date, null]);
|
||||
}
|
||||
} else if (type === 'multiple') {
|
||||
var selectedIndex_1;
|
||||
// @ts-ignore
|
||||
var selected = currentDate.some(function (dateItem, index) {
|
||||
var equal = utils_1.compareDay(dateItem, date) === 0;
|
||||
if (equal) {
|
||||
selectedIndex_1 = index;
|
||||
}
|
||||
return equal;
|
||||
});
|
||||
if (selected) {
|
||||
// @ts-ignore
|
||||
var cancelDate = currentDate.splice(selectedIndex_1, 1);
|
||||
this.setData({ currentDate: currentDate });
|
||||
this.unselect(cancelDate);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
this.select(__spreadArray(__spreadArray([], currentDate), [date]));
|
||||
}
|
||||
} else {
|
||||
this.select(date, true);
|
||||
}
|
||||
},
|
||||
unselect: function (dateArray) {
|
||||
var date = dateArray[0];
|
||||
if (date) {
|
||||
this.$emit('unselect', utils_1.copyDates(date));
|
||||
}
|
||||
},
|
||||
select: function (date, complete) {
|
||||
if (complete && this.data.type === 'range') {
|
||||
var valid = this.checkRange(date);
|
||||
if (!valid) {
|
||||
// auto selected to max range if showConfirm
|
||||
if (this.data.showConfirm) {
|
||||
this.emit([
|
||||
date[0],
|
||||
utils_1.getDayByOffset(date[0], this.data.maxRange - 1),
|
||||
]);
|
||||
} else {
|
||||
this.emit(date);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.emit(date);
|
||||
if (complete && !this.data.showConfirm) {
|
||||
this.onConfirm();
|
||||
}
|
||||
},
|
||||
emit: function (date) {
|
||||
var getTime = function (date) {
|
||||
return date instanceof Date ? date.getTime() : date;
|
||||
};
|
||||
this.setData({
|
||||
currentDate: Array.isArray(date) ? date.map(getTime) : getTime(date),
|
||||
});
|
||||
this.$emit('select', utils_1.copyDates(date));
|
||||
},
|
||||
checkRange: function (date) {
|
||||
var _a = this.data,
|
||||
maxRange = _a.maxRange,
|
||||
rangePrompt = _a.rangePrompt,
|
||||
showRangePrompt = _a.showRangePrompt;
|
||||
if (maxRange && utils_1.calcDateNum(date) > maxRange) {
|
||||
if (showRangePrompt) {
|
||||
toast_1.default({
|
||||
duration: 0,
|
||||
context: this,
|
||||
message:
|
||||
rangePrompt ||
|
||||
'\u9009\u62E9\u5929\u6570\u4E0D\u80FD\u8D85\u8FC7 ' +
|
||||
maxRange +
|
||||
' \u5929',
|
||||
});
|
||||
}
|
||||
this.$emit('over-range');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
onConfirm: function () {
|
||||
var _this = this;
|
||||
if (
|
||||
this.data.type === 'range' &&
|
||||
!this.checkRange(this.data.currentDate)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
wx.nextTick(function () {
|
||||
// @ts-ignore
|
||||
_this.$emit('confirm', utils_1.copyDates(_this.data.currentDate));
|
||||
});
|
||||
},
|
||||
onClickSubtitle: function (event) {
|
||||
this.$emit('click-subtitle', event);
|
||||
},
|
||||
},
|
||||
});
|
||||
10
miniprogram_npm/@vant/weapp/calendar/index.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"header": "./components/header/index",
|
||||
"month": "./components/month/index",
|
||||
"van-button": "../button/index",
|
||||
"van-popup": "../popup/index",
|
||||
"van-toast": "../toast/index"
|
||||
}
|
||||
}
|
||||
25
miniprogram_npm/@vant/weapp/calendar/index.wxml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<wxs src="./index.wxs" module="computed" />
|
||||
<wxs src="../wxs/utils.wxs" module="utils" />
|
||||
|
||||
<import src="./calendar.wxml" />
|
||||
|
||||
<van-popup
|
||||
wx:if="{{ poppable }}"
|
||||
custom-class="van-calendar__popup--{{ position }}"
|
||||
close-icon-class="van-calendar__close-icon"
|
||||
show="{{ show }}"
|
||||
round="{{ round }}"
|
||||
position="{{ position }}"
|
||||
closeable="{{ showTitle || showSubtitle }}"
|
||||
close-on-click-overlay="{{ closeOnClickOverlay }}"
|
||||
bind:enter="onOpen"
|
||||
bind:close="onClose"
|
||||
bind:after-enter="onOpened"
|
||||
bind:after-leave="onClosed"
|
||||
>
|
||||
<include src="./calendar.wxml" />
|
||||
</van-popup>
|
||||
|
||||
<include wx:else src="./calendar.wxml" />
|
||||
|
||||
<van-toast id="van-toast" />
|
||||
37
miniprogram_npm/@vant/weapp/calendar/index.wxs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* eslint-disable */
|
||||
var utils = require('./utils.wxs');
|
||||
|
||||
function getMonths(minDate, maxDate) {
|
||||
var months = [];
|
||||
var cursor = getDate(minDate);
|
||||
|
||||
cursor.setDate(1);
|
||||
|
||||
do {
|
||||
months.push(cursor.getTime());
|
||||
cursor.setMonth(cursor.getMonth() + 1);
|
||||
} while (utils.compareMonth(cursor, getDate(maxDate)) !== 1);
|
||||
|
||||
return months;
|
||||
}
|
||||
|
||||
function getButtonDisabled(type, currentDate) {
|
||||
if (currentDate == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type === 'range') {
|
||||
return !currentDate[0] || !currentDate[1];
|
||||
}
|
||||
|
||||
if (type === 'multiple') {
|
||||
return !currentDate.length;
|
||||
}
|
||||
|
||||
return !currentDate;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getMonths: getMonths,
|
||||
getButtonDisabled: getButtonDisabled
|
||||
};
|
||||
1
miniprogram_npm/@vant/weapp/calendar/index.wxss
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import '../common/index.wxss';.van-calendar{display:flex;flex-direction:column;height:100%;height:var(--calendar-height,100%);background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__close-icon{top:11px}.van-calendar__popup--bottom,.van-calendar__popup--top{height:80%;height:var(--calendar-popup-height,80%)}.van-calendar__popup--left,.van-calendar__popup--right{height:100%}.van-calendar__body{flex:1;overflow:auto;-webkit-overflow-scrolling:touch}.van-calendar__footer{flex-shrink:0;padding:0 16px;padding:0 var(--padding-md,16px)}.van-calendar__footer--safe-area-inset-bottom{padding-bottom:env(safe-area-inset-bottom)}.van-calendar__footer+.van-calendar__footer,.van-calendar__footer:empty{display:none}.van-calendar__footer:empty+.van-calendar__footer{display:block!important}.van-calendar__confirm{height:36px!important;height:var(--calendar-confirm-button-height,36px)!important;margin:7px 0!important;margin:var(--calendar-confirm-button-margin,7px 0)!important;line-height:34px!important;line-height:var(--calendar-confirm-button-line-height,34px)!important}
|
||||
97
miniprogram_npm/@vant/weapp/calendar/utils.js
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
exports.getMonths = exports.getMonthEndDay = exports.copyDates = exports.calcDateNum = exports.getToday = exports.getNextDay = exports.getPrevDay = exports.getDayByOffset = exports.compareDay = exports.compareMonth = exports.formatMonthTitle = exports.ROW_HEIGHT = void 0;
|
||||
exports.ROW_HEIGHT = 64;
|
||||
function formatMonthTitle(date) {
|
||||
if (!(date instanceof Date)) {
|
||||
date = new Date(date);
|
||||
}
|
||||
return date.getFullYear() + '\u5E74' + (date.getMonth() + 1) + '\u6708';
|
||||
}
|
||||
exports.formatMonthTitle = formatMonthTitle;
|
||||
function compareMonth(date1, date2) {
|
||||
if (!(date1 instanceof Date)) {
|
||||
date1 = new Date(date1);
|
||||
}
|
||||
if (!(date2 instanceof Date)) {
|
||||
date2 = new Date(date2);
|
||||
}
|
||||
var year1 = date1.getFullYear();
|
||||
var year2 = date2.getFullYear();
|
||||
var month1 = date1.getMonth();
|
||||
var month2 = date2.getMonth();
|
||||
if (year1 === year2) {
|
||||
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
|
||||
}
|
||||
return year1 > year2 ? 1 : -1;
|
||||
}
|
||||
exports.compareMonth = compareMonth;
|
||||
function compareDay(day1, day2) {
|
||||
if (!(day1 instanceof Date)) {
|
||||
day1 = new Date(day1);
|
||||
}
|
||||
if (!(day2 instanceof Date)) {
|
||||
day2 = new Date(day2);
|
||||
}
|
||||
var compareMonthResult = compareMonth(day1, day2);
|
||||
if (compareMonthResult === 0) {
|
||||
var date1 = day1.getDate();
|
||||
var date2 = day2.getDate();
|
||||
return date1 === date2 ? 0 : date1 > date2 ? 1 : -1;
|
||||
}
|
||||
return compareMonthResult;
|
||||
}
|
||||
exports.compareDay = compareDay;
|
||||
function getDayByOffset(date, offset) {
|
||||
date = new Date(date);
|
||||
date.setDate(date.getDate() + offset);
|
||||
return date;
|
||||
}
|
||||
exports.getDayByOffset = getDayByOffset;
|
||||
function getPrevDay(date) {
|
||||
return getDayByOffset(date, -1);
|
||||
}
|
||||
exports.getPrevDay = getPrevDay;
|
||||
function getNextDay(date) {
|
||||
return getDayByOffset(date, 1);
|
||||
}
|
||||
exports.getNextDay = getNextDay;
|
||||
function getToday() {
|
||||
var today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
return today;
|
||||
}
|
||||
exports.getToday = getToday;
|
||||
function calcDateNum(date) {
|
||||
var day1 = new Date(date[0]).getTime();
|
||||
var day2 = new Date(date[1]).getTime();
|
||||
return (day2 - day1) / (1000 * 60 * 60 * 24) + 1;
|
||||
}
|
||||
exports.calcDateNum = calcDateNum;
|
||||
function copyDates(dates) {
|
||||
if (Array.isArray(dates)) {
|
||||
return dates.map(function (date) {
|
||||
if (date === null) {
|
||||
return date;
|
||||
}
|
||||
return new Date(date);
|
||||
});
|
||||
}
|
||||
return new Date(dates);
|
||||
}
|
||||
exports.copyDates = copyDates;
|
||||
function getMonthEndDay(year, month) {
|
||||
return 32 - new Date(year, month - 1, 32).getDate();
|
||||
}
|
||||
exports.getMonthEndDay = getMonthEndDay;
|
||||
function getMonths(minDate, maxDate) {
|
||||
var months = [];
|
||||
var cursor = new Date(minDate);
|
||||
cursor.setDate(1);
|
||||
do {
|
||||
months.push(cursor.getTime());
|
||||
cursor.setMonth(cursor.getMonth() + 1);
|
||||
} while (compareMonth(cursor, maxDate) !== 1);
|
||||
return months;
|
||||
}
|
||||
exports.getMonths = getMonths;
|
||||
25
miniprogram_npm/@vant/weapp/calendar/utils.wxs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* eslint-disable */
|
||||
function getMonthEndDay(year, month) {
|
||||
return 32 - getDate(year, month - 1, 32).getDate();
|
||||
}
|
||||
|
||||
function compareMonth(date1, date2) {
|
||||
date1 = getDate(date1);
|
||||
date2 = getDate(date2);
|
||||
|
||||
var year1 = date1.getFullYear();
|
||||
var year2 = date2.getFullYear();
|
||||
var month1 = date1.getMonth();
|
||||
var month2 = date2.getMonth();
|
||||
|
||||
if (year1 === year2) {
|
||||
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
|
||||
}
|
||||
|
||||
return year1 > year2 ? 1 : -1;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getMonthEndDay: getMonthEndDay,
|
||||
compareMonth: compareMonth
|
||||
};
|
||||
51
miniprogram_npm/@vant/weapp/card/index.js
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var link_1 = require('../mixins/link');
|
||||
var component_1 = require('../common/component');
|
||||
component_1.VantComponent({
|
||||
classes: [
|
||||
'num-class',
|
||||
'desc-class',
|
||||
'thumb-class',
|
||||
'title-class',
|
||||
'price-class',
|
||||
'origin-price-class',
|
||||
],
|
||||
mixins: [link_1.link],
|
||||
props: {
|
||||
tag: String,
|
||||
num: String,
|
||||
desc: String,
|
||||
thumb: String,
|
||||
title: String,
|
||||
price: {
|
||||
type: String,
|
||||
observer: 'updatePrice',
|
||||
},
|
||||
centered: Boolean,
|
||||
lazyLoad: Boolean,
|
||||
thumbLink: String,
|
||||
originPrice: String,
|
||||
thumbMode: {
|
||||
type: String,
|
||||
value: 'aspectFit',
|
||||
},
|
||||
currency: {
|
||||
type: String,
|
||||
value: '¥',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updatePrice: function () {
|
||||
var price = this.data.price;
|
||||
var priceArr = price.toString().split('.');
|
||||
this.setData({
|
||||
integerStr: priceArr[0],
|
||||
decimalStr: priceArr[1] ? '.' + priceArr[1] : '',
|
||||
});
|
||||
},
|
||||
onClickThumb: function () {
|
||||
this.jumpLink('thumbLink');
|
||||
},
|
||||
},
|
||||
});
|
||||
6
miniprogram_npm/@vant/weapp/card/index.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-tag": "../tag/index"
|
||||
}
|
||||
}
|
||||
56
miniprogram_npm/@vant/weapp/card/index.wxml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<wxs src="../wxs/utils.wxs" module="utils" />
|
||||
|
||||
<view class="custom-class van-card">
|
||||
<view class="{{ utils.bem('card__header', { center: centered }) }}">
|
||||
<view class="van-card__thumb" bind:tap="onClickThumb">
|
||||
<image
|
||||
wx:if="{{ thumb }}"
|
||||
src="{{ thumb }}"
|
||||
mode="{{ thumbMode }}"
|
||||
lazy-load="{{ lazyLoad }}"
|
||||
class="van-card__img thumb-class"
|
||||
/>
|
||||
<slot wx:else name="thumb" />
|
||||
<van-tag
|
||||
wx:if="{{ tag }}"
|
||||
mark
|
||||
type="danger"
|
||||
custom-class="van-card__tag"
|
||||
>
|
||||
{{ tag }}
|
||||
</van-tag>
|
||||
<slot wx:else name="tag" />
|
||||
</view>
|
||||
|
||||
<view class="van-card__content {{ utils.bem('card__content', { center: centered }) }}">
|
||||
<view>
|
||||
<view wx:if="{{ title }}" class="van-card__title title-class">{{ title }}</view>
|
||||
<slot wx:else name="title" />
|
||||
|
||||
<view wx:if="{{ desc }}" class="van-card__desc desc-class">{{ desc }}</view>
|
||||
<slot wx:else name="desc" />
|
||||
|
||||
<slot name="tags" />
|
||||
</view>
|
||||
|
||||
<view class="van-card__bottom">
|
||||
<slot name="price-top" />
|
||||
<view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">
|
||||
<text>{{ currency }}</text>
|
||||
<text class="van-card__price-integer">{{ integerStr }}</text>
|
||||
<text class="van-card__price-decimal">{{ decimalStr }}</text>
|
||||
</view>
|
||||
<slot wx:else name="price" />
|
||||
<view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view>
|
||||
<slot wx:else name="origin-price" />
|
||||
<view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view>
|
||||
<slot wx:else name="num" />
|
||||
<slot name="bottom" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="van-card__footer">
|
||||
<slot name="footer" />
|
||||
</view>
|
||||
</view>
|
||||
1
miniprogram_npm/@vant/weapp/card/index.wxss
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import '../common/index.wxss';.van-card{position:relative;box-sizing:border-box;padding:8px 16px;padding:var(--card-padding,8px 16px);font-size:12px;font-size:var(--card-font-size,12px);color:#323233;color:var(--card-text-color,#323233);background-color:#fafafa;background-color:var(--card-background-color,#fafafa)}.van-card__header{display:flex}.van-card__header--center{align-items:center;justify-content:center}.van-card__thumb{position:relative;flex:none;width:88px;width:var(--card-thumb-size,88px);height:88px;height:var(--card-thumb-size,88px);margin-right:8px;margin-right:var(--padding-xs,8px)}.van-card__thumb:empty{display:none}.van-card__img{width:100%;height:100%;border-radius:8px;border-radius:var(--border-radius-lg,8px)}.van-card__content{position:relative;display:flex;flex:1;flex-direction:column;justify-content:space-between;min-width:0;min-height:88px;min-height:var(--card-thumb-size,88px)}.van-card__content--center{justify-content:center}.van-card__desc,.van-card__title{word-wrap:break-word}.van-card__title{font-weight:700;line-height:16px;line-height:var(--card-title-line-height,16px)}.van-card__desc{line-height:20px;line-height:var(--card-desc-line-height,20px);color:#646566;color:var(--card-desc-color,#646566)}.van-card__bottom{line-height:20px}.van-card__price{display:inline-block;font-weight:700;color:#ee0a24;color:var(--card-price-color,#ee0a24);font-size:12px;font-size:var(--card-price-font-size,12px)}.van-card__price-integer{font-size:16px;font-size:var(--card-price-integer-font-size,16px)}.van-card__price-decimal,.van-card__price-integer{font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--card-price-font-family,Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif)}.van-card__origin-price{display:inline-block;margin-left:5px;text-decoration:line-through;font-size:10px;font-size:var(--card-origin-price-font-size,10px);color:#646566;color:var(--card-origin-price-color,#646566)}.van-card__num{float:right}.van-card__tag{position:absolute!important;top:2px;left:0}.van-card__footer{flex:none;width:100%;text-align:right}
|
||||
13
miniprogram_npm/@vant/weapp/cell-group/index.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var component_1 = require('../common/component');
|
||||
component_1.VantComponent({
|
||||
props: {
|
||||
title: String,
|
||||
border: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
inset: Boolean,
|
||||
},
|
||||
});
|
||||
3
miniprogram_npm/@vant/weapp/cell-group/index.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"component": true
|
||||
}
|
||||
11
miniprogram_npm/@vant/weapp/cell-group/index.wxml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<wxs src="../wxs/utils.wxs" module="utils" />
|
||||
|
||||
<view
|
||||
wx:if="{{ title }}"
|
||||
class="{{ utils.bem('cell-group__title', { inset }) }}"
|
||||
>
|
||||
{{ title }}
|
||||
</view>
|
||||
<view class="custom-class {{ utils.bem('cell-group', { inset }) }} {{ border ? 'van-hairline--top-bottom' : '' }}">
|
||||
<slot />
|
||||
</view>
|
||||
1
miniprogram_npm/@vant/weapp/cell-group/index.wxss
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import '../common/index.wxss';.van-cell-group--inset{margin:0 16px;margin:var(--cell-group-inset-padding,0 16px);border-radius:8px;border-radius:var(--cell-group-inset-border-radius,8px);overflow:hidden}.van-cell-group__title{padding:16px 16px 8px;padding:var(--cell-group-title-padding,16px 16px 8px);font-size:14px;font-size:var(--cell-group-title-font-size,14px);line-height:16px;line-height:var(--cell-group-title-line-height,16px);color:#969799;color:var(--cell-group-title-color,#969799)}.van-cell-group__title--inset{padding:16px 16px 8px 32px;padding:var(--cell-group-inset-title-padding,16px 16px 8px 32px)}
|
||||
40
miniprogram_npm/@vant/weapp/cell/index.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var link_1 = require('../mixins/link');
|
||||
var component_1 = require('../common/component');
|
||||
component_1.VantComponent({
|
||||
classes: [
|
||||
'title-class',
|
||||
'label-class',
|
||||
'value-class',
|
||||
'right-icon-class',
|
||||
'hover-class',
|
||||
],
|
||||
mixins: [link_1.link],
|
||||
props: {
|
||||
title: null,
|
||||
value: null,
|
||||
icon: String,
|
||||
size: String,
|
||||
label: String,
|
||||
center: Boolean,
|
||||
isLink: Boolean,
|
||||
required: Boolean,
|
||||
clickable: Boolean,
|
||||
titleWidth: String,
|
||||
customStyle: String,
|
||||
arrowDirection: String,
|
||||
useLabelSlot: Boolean,
|
||||
border: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
titleStyle: String,
|
||||
},
|
||||
methods: {
|
||||
onClick: function (event) {
|
||||
this.$emit('click', event.detail);
|
||||
this.jumpLink();
|
||||
},
|
||||
},
|
||||
});
|
||||
6
miniprogram_npm/@vant/weapp/cell/index.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-icon": "../icon/index"
|
||||
}
|
||||
}
|
||||
47
miniprogram_npm/@vant/weapp/cell/index.wxml
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<wxs src="../wxs/utils.wxs" module="utils" />
|
||||
<wxs src="./index.wxs" module="computed" />
|
||||
|
||||
<view
|
||||
class="custom-class {{ utils.bem('cell', [size, { center, required, borderless: !border, clickable: isLink || clickable }]) }}"
|
||||
hover-class="van-cell--hover hover-class"
|
||||
hover-stay-time="70"
|
||||
style="{{ customStyle }}"
|
||||
bind:tap="onClick"
|
||||
>
|
||||
<van-icon
|
||||
wx:if="{{ icon }}"
|
||||
name="{{ icon }}"
|
||||
class="van-cell__left-icon-wrap"
|
||||
custom-class="van-cell__left-icon"
|
||||
/>
|
||||
<slot wx:else name="icon" />
|
||||
|
||||
<view
|
||||
style="{{ computed.titleStyle({ titleWidth, titleStyle }) }}"
|
||||
class="van-cell__title title-class"
|
||||
>
|
||||
|
||||
<block wx:if="{{ title }}">{{ title }}</block>
|
||||
<slot wx:else name="title" />
|
||||
|
||||
<view wx:if="{{ label || useLabelSlot }}" class="van-cell__label label-class">
|
||||
<slot wx:if="{{ useLabelSlot }}" name="label" />
|
||||
<block wx:elif="{{ label }}">{{ label }}</block>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="van-cell__value value-class">
|
||||
<block wx:if="{{ value || value === 0 }}">{{ value }}</block>
|
||||
<slot wx:else />
|
||||
</view>
|
||||
|
||||
<van-icon
|
||||
wx:if="{{ isLink }}"
|
||||
name="{{ arrowDirection ? 'arrow' + '-' + arrowDirection : 'arrow' }}"
|
||||
class="van-cell__right-icon-wrap right-icon-class"
|
||||
custom-class="van-cell__right-icon"
|
||||
/>
|
||||
<slot wx:else name="right-icon" />
|
||||
|
||||
<slot name="extra" />
|
||||
</view>
|
||||
17
miniprogram_npm/@vant/weapp/cell/index.wxs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/* eslint-disable */
|
||||
var style = require('../wxs/style.wxs');
|
||||
var addUnit = require('../wxs/add-unit.wxs');
|
||||
|
||||
function titleStyle(data) {
|
||||
return style([
|
||||
{
|
||||
'max-width': addUnit(data.titleWidth),
|
||||
'min-width': addUnit(data.titleWidth),
|
||||
},
|
||||
data.titleStyle,
|
||||
]);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
titleStyle: titleStyle,
|
||||
};
|
||||
1
miniprogram_npm/@vant/weapp/cell/index.wxss
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import '../common/index.wxss';.van-cell{position:relative;display:flex;box-sizing:border-box;width:100%;padding:10px 16px;padding:var(--cell-vertical-padding,10px) var(--cell-horizontal-padding,16px);font-size:14px;font-size:var(--cell-font-size,14px);line-height:24px;line-height:var(--cell-line-height,24px);color:#323233;color:var(--cell-text-color,#323233);background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell:after{position:absolute;box-sizing:border-box;transform-origin:center;content:" ";pointer-events:none;right:16px;bottom:0;left:16px;border-bottom:1px solid #ebedf0;transform:scaleY(.5)}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell__label{margin-top:3px;margin-top:var(--cell-label-margin-top,3px);font-size:12px;font-size:var(--cell-label-font-size,12px);line-height:18px;line-height:var(--cell-label-line-height,18px);color:#969799;color:var(--cell-label-color,#969799)}.van-cell__value{overflow:hidden;text-align:right;vertical-align:middle;color:#969799;color:var(--cell-value-color,#969799)}.van-cell__title,.van-cell__value{flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:flex;align-items:center;height:24px;height:var(--cell-line-height,24px);font-size:16px;font-size:var(--cell-icon-size,16px)}.van-cell__left-icon-wrap{margin-right:4px;margin-right:var(--padding-base,4px)}.van-cell__right-icon-wrap{margin-left:4px;margin-left:var(--padding-base,4px);color:#969799;color:var(--cell-right-icon-color,#969799)}.van-cell__left-icon{vertical-align:middle}.van-cell__left-icon,.van-cell__right-icon{line-height:24px;line-height:var(--cell-line-height,24px)}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5;background-color:var(--cell-active-color,#f2f3f5)}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;content:"*";left:8px;left:var(--padding-xs,8px);font-size:14px;font-size:var(--cell-font-size,14px);color:#ee0a24;color:var(--cell-required-color,#ee0a24)}.van-cell--center{align-items:center}.van-cell--large{padding-top:12px;padding-top:var(--cell-large-vertical-padding,12px);padding-bottom:12px;padding-bottom:var(--cell-large-vertical-padding,12px)}.van-cell--large .van-cell__title{font-size:16px;font-size:var(--cell-large-title-font-size,16px)}.van-cell--large .van-cell__value{font-size:16px;font-size:var(--cell-large-value-font-size,16px)}.van-cell--large .van-cell__label{font-size:14px;font-size:var(--cell-large-label-font-size,14px)}
|
||||
44
miniprogram_npm/@vant/weapp/checkbox-group/index.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var relation_1 = require('../common/relation');
|
||||
var component_1 = require('../common/component');
|
||||
component_1.VantComponent({
|
||||
field: true,
|
||||
relation: relation_1.useChildren('checkbox', function (target) {
|
||||
this.updateChild(target);
|
||||
}),
|
||||
props: {
|
||||
max: Number,
|
||||
value: {
|
||||
type: Array,
|
||||
observer: 'updateChildren',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
observer: 'updateChildren',
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
value: 'vertical',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updateChildren: function () {
|
||||
var _this = this;
|
||||
this.children.forEach(function (child) {
|
||||
return _this.updateChild(child);
|
||||
});
|
||||
},
|
||||
updateChild: function (child) {
|
||||
var _a = this.data,
|
||||
value = _a.value,
|
||||
disabled = _a.disabled,
|
||||
direction = _a.direction;
|
||||
child.setData({
|
||||
value: value.indexOf(child.data.name) !== -1,
|
||||
parentDisabled: disabled,
|
||||
direction: direction,
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
3
miniprogram_npm/@vant/weapp/checkbox-group/index.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"component": true
|
||||
}
|
||||
5
miniprogram_npm/@vant/weapp/checkbox-group/index.wxml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<wxs src="../wxs/utils.wxs" module="utils" />
|
||||
|
||||
<view class="{{ utils.bem('checkbox-group', [{ horizontal: direction === 'horizontal' }]) }}">
|
||||
<slot />
|
||||
</view>
|
||||
1
miniprogram_npm/@vant/weapp/checkbox-group/index.wxss
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import '../common/index.wxss';.van-checkbox-group--horizontal{display:flex;flex-wrap:wrap}
|
||||
84
miniprogram_npm/@vant/weapp/checkbox/index.js
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
var relation_1 = require('../common/relation');
|
||||
var component_1 = require('../common/component');
|
||||
function emit(target, value) {
|
||||
target.$emit('input', value);
|
||||
target.$emit('change', value);
|
||||
}
|
||||
component_1.VantComponent({
|
||||
field: true,
|
||||
relation: relation_1.useParent('checkbox-group'),
|
||||
classes: ['icon-class', 'label-class'],
|
||||
props: {
|
||||
value: Boolean,
|
||||
disabled: Boolean,
|
||||
useIconSlot: Boolean,
|
||||
checkedColor: String,
|
||||
labelPosition: {
|
||||
type: String,
|
||||
value: 'right',
|
||||
},
|
||||
labelDisabled: Boolean,
|
||||
shape: {
|
||||
type: String,
|
||||
value: 'round',
|
||||
},
|
||||
iconSize: {
|
||||
type: null,
|
||||
value: 20,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
parentDisabled: false,
|
||||
direction: 'vertical',
|
||||
},
|
||||
methods: {
|
||||
emitChange: function (value) {
|
||||
if (this.parent) {
|
||||
this.setParentValue(this.parent, value);
|
||||
} else {
|
||||
emit(this, value);
|
||||
}
|
||||
},
|
||||
toggle: function () {
|
||||
var _a = this.data,
|
||||
parentDisabled = _a.parentDisabled,
|
||||
disabled = _a.disabled,
|
||||
value = _a.value;
|
||||
if (!disabled && !parentDisabled) {
|
||||
this.emitChange(!value);
|
||||
}
|
||||
},
|
||||
onClickLabel: function () {
|
||||
var _a = this.data,
|
||||
labelDisabled = _a.labelDisabled,
|
||||
parentDisabled = _a.parentDisabled,
|
||||
disabled = _a.disabled,
|
||||
value = _a.value;
|
||||
if (!disabled && !labelDisabled && !parentDisabled) {
|
||||
this.emitChange(!value);
|
||||
}
|
||||
},
|
||||
setParentValue: function (parent, value) {
|
||||
var parentValue = parent.data.value.slice();
|
||||
var name = this.data.name;
|
||||
var max = parent.data.max;
|
||||
if (value) {
|
||||
if (max && parentValue.length >= max) {
|
||||
return;
|
||||
}
|
||||
if (parentValue.indexOf(name) === -1) {
|
||||
parentValue.push(name);
|
||||
emit(parent, parentValue);
|
||||
}
|
||||
} else {
|
||||
var index = parentValue.indexOf(name);
|
||||
if (index !== -1) {
|
||||
parentValue.splice(index, 1);
|
||||
emit(parent, parentValue);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
6
miniprogram_npm/@vant/weapp/checkbox/index.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-icon": "../icon/index"
|
||||
}
|
||||
}
|
||||
31
miniprogram_npm/@vant/weapp/checkbox/index.wxml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<wxs src="../wxs/utils.wxs" module="utils" />
|
||||
<wxs src="./index.wxs" module="computed" />
|
||||
|
||||
<view class="{{ utils.bem('checkbox', [{ horizontal: direction === 'horizontal' }]) }} custom-class">
|
||||
<view
|
||||
wx:if="{{ labelPosition === 'left' }}"
|
||||
class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled: disabled || parentDisabled }]) }}"
|
||||
bindtap="onClickLabel"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
<view class="van-checkbox__icon-wrap" bindtap="toggle">
|
||||
<slot wx:if="{{ useIconSlot }}" name="icon" />
|
||||
<van-icon
|
||||
wx:else
|
||||
name="success"
|
||||
size="0.8em"
|
||||
class="{{ utils.bem('checkbox__icon', [shape, { disabled: disabled || parentDisabled, checked: value }]) }}"
|
||||
style="{{ computed.iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) }}"
|
||||
custom-class="icon-class"
|
||||
custom-style="line-height: 1.25em;"
|
||||
/>
|
||||
</view>
|
||||
<view
|
||||
wx:if="{{ labelPosition === 'right' }}"
|
||||
class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled: disabled || parentDisabled }]) }}"
|
||||
bindtap="onClickLabel"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||