最新版

This commit is contained in:
Ling53666 2024-11-15 11:51:28 +08:00
parent d6bb5c6a12
commit 7dfe547728
2328 changed files with 119429 additions and 530 deletions

View File

@ -1,22 +1,14 @@
{ {
"modes": [ "modes": [
{ {
"title": "pages/dianpuzhuye/dianpuzhuye", "title": "上门预约",
"page": "pages/dianpuzhuye/dianpuzhuye",
"launchMode": "common",
"pageQuery": ""
},
{
"title": "pages/shouye/shouye",
"page": "pages/shouye/shouye",
"launchMode": "common",
"pageQuery": ""
},
{
"title": "pages/shangmenyuyue/shangmenyuyue",
"page": "pages/shangmenyuyue/shangmenyuyue", "page": "pages/shangmenyuyue/shangmenyuyue",
"launchMode": "common", "launchMode": "common"
"pageQuery": "" },
{
"title": "商品界面",
"page": "pages/shangpinjiemian/shangpinjiemian",
"launchMode": "common"
} }
] ]
} }

View File

@ -1,6 +1,8 @@
page { page {
background-color: #ffffff; background-color: #ffffff;
box-sizing: border-box; box-sizing: border-box;
position: relative;
overflow-x: hidden;
} }
.page { .page {

View File

@ -31,8 +31,8 @@
</view> </view>
<!-- 店铺 --> <!-- 店铺 -->
<!-- a店铺 --> <!-- a店铺 -->
<view a:for="{{sousuo}}" class="box3" > <view class="box3" >
<view class="adianpu" onTap="dianpu" > <view class="adianpu" a:for="{{sousuo}}" a:key="{{index}}" data-num="{{item}}" onTap="dianpu" >
<navigator open-type="navigate" url="../dianpuzhuye/dianpuzhuye" hover-class="navigator-hover" class="aname">{{item.businessName}}</navigator> <navigator open-type="navigate" url="../dianpuzhuye/dianpuzhuye" hover-class="navigator-hover" class="aname">{{item.businessName}}</navigator>
<view class="yy1"> <view class="yy1">
<text class="wyy1">{{item.businessImages}}</text> <text class="wyy1">{{item.businessImages}}</text>

View File

@ -49,9 +49,20 @@ Page({
console.log('doneSearch', this.data.search); console.log('doneSearch', this.data.search);
my.hideKeyboard(); my.hideKeyboard();
}, },
dianpu(){ dianpu(item){
const id = item.target.dataset.num
const ID = id.id
const userId = id.userId
const address = id.address
const businessName = id.businessName
const businessAvatar = id.businessAvatar
const endBusiness = id.endBusiness
const startBusiness = id.startBusiness
const storeStatus = id.storeStatus
console.log('Address being passed: ', ID,address,businessName,businessAvatar,endBusiness,startBusiness);
my.navigateTo({ my.navigateTo({
url:'/pages/dianpuzhuye/dianpuzhuye' url: `/pages/dianpuzhuye/dianpuzhuye?userId=${userId}&&address=${address}&&businessName=${businessName}&&businessAvatar=${businessAvatar}&&startBusiness=${startBusiness}&&endBusiness=${endBusiness}&&storeStatus=${storeStatus}&&id=${ID}`,
}) });
} }
}); });

View File

@ -1,4 +1,5 @@
{ {
"defaultTitle": "到店服务",
"usingComponents": {}, "usingComponents": {},
"styleIsolation": "apply-shared" "styleIsolation": "apply-shared"
} }

View File

@ -11,7 +11,7 @@ page {
display: block; display: block;
} }
.wenzi{ .wenzi{
font-size: 50rpx; font-size: 40rpx;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -36,3 +36,9 @@ page {
background-color: lightskyblue; background-color: lightskyblue;
color: #fff; color: #fff;
} }
.image{
width: 80rpx;
height: 80rpx;
position: relative;
left: 330rpx;
}

View File

@ -1,19 +1,7 @@
<view> <view>
<image class="tupian" mode="scaleToFill" src="../image/logo.png" /> <image class="tupian" mode="scaleToFill" src="../image/logo.png" />
<image mode="scaleToFill" class="image" src="/pages/image/login.png" />
<text class="wenzi">请完成授权以继续使用</text> <text class="wenzi">请完成授权以继续使用</text>
</view> </view>
<view class="form-line" />
<view class="form-row"> <button type="primary" onTap="Login">支付宝一键登录</button>
<view class="form-row-label">输入账号</view>
<view class="form-row-content">
<input class="input" type="number" placeholder="账号输入框" onInput="usernameInput"/>
</view>
</view>
<view class="form-line" />
<view class="form-row">
<view class="form-row-label">输入密码</view>
<view class="form-row-content">
<input class="input" password type="text" placeholder="密码输入框" onInput="passwordInput"/>
</view>
</view>
<button type="primary" onTap="onLogin">登录</button>

View File

@ -1,71 +1,48 @@
import {url} from '../request'
Page({ Page({
data:{ data:{
username:'', authCode:'',
password:''
}, },
getAuthCode: () => { Login(){
my.getAuthCode({ my.getAuthCode({
scopes: 'auth_user', scopes: 'auth_user',
success: ({ authCode }) => { success: res => {
console.log(`authCode:`, authCode); const authCode = res.authCode;
my.alert({ console.log(typeof authCode);
content: authCode, console.log(authCode)
}); my.request({
url: url+'/api/Alipay/parseCode',
data: {
authCode,
},
success(res){
const { username, avatarUrl } = res.data.data;
my.setStorageSync({
key: 'user_info',
data: {
username:username,
avatarUrl:avatarUrl,
}, },
}); });
}, console.log(res)
data: {}, console.log(username,avatarUrl)
onShareAppMessage() {
return {
title: 'view page',
path: 'page/component/view/view',
};
},
onSubmit() {
my.alert({ content: '登陆成功' });
},
usernameInput(e){
this.setData({
username:e.detail.value
})
},
passwordInput(e){
this.setData({
password:e.detail.value
})
},
onLogin(){
if(!this.data.username&&!this.data.password){
my.alert({ my.alert({
title:'账号或密码不能为空' title: '登录成功',
}) });
return
}
my.demo.callFunction({
name:'select',
data:{
username:this.data.username,
password:this.data.password
},
success:res=>{
if(res.result.data.length!=0){
console.log(res);
my.alert({
title:'登录成功'
})
my.switchTab({ my.switchTab({
url:'/pages/shouye/shouye' url:'/pages/wode/wode'
}) })
}else{
my.alert({
title:'账号或密码错误'
})
}
}, },
fail:err=>{ fail(res){
console.log("失败");
} }
}) })
} }
})
},
}); });

View File

@ -110,8 +110,6 @@
width: 185px; width: 185px;
height: 140px; height: 140px;
position: relative; position: relative;
top:0px;
left: 0px;
border-radius: 10px; border-radius: 10px;
} }
.zt2{ .zt2{
@ -172,95 +170,7 @@
left: 10px; left: 10px;
} }
/* 第一个美甲师 */ /* 第一个美甲师 */
.h5 image{
width: 80px;
height: 100px;
position: absolute;
top:530px;
left: 20px;
}
.wz2{
position: absolute;
top:635px;
left:45px;
}
/* 咨询框 */
.h6{
width: 40px;
height: 25px;
position: absolute;
background-color: #E89709;
top:656px;
left: 15px;
border-radius: 10px;
}
.wz3{
top:3px;
left: 4px;
position: absolute;
color: #ffffff;
}
/* 预约框 */
.h7{
width: 40px;
height: 25px;
position: absolute;
background-color: #58A55C;
top:656px;
left: 60px;
border-radius: 10px;
}
.wz4{
top:3px;
left: 4px;
position: absolute;
color: #ffffff;
}
/* 第二个美甲师 */
.h8 image{
width: 80px;
height: 100px;
position: absolute;
top:530px;
left: 110px;
}
.wz5{
position: absolute;
top:635px;
left:135px;
}
/* 咨询框 */
.h9{
width: 40px;
height: 25px;
position: absolute;
background-color: #E89709;
top:656px;
left: 110px;
border-radius: 10px;
}
.wz6{
top:3px;
left: 4px;
position: absolute;
color: #ffffff;
}
/* 预约框 */
.h10{
width: 40px;
height: 25px;
position: absolute;
background-color: #58A55C;
top:656px;
left: 155px;
border-radius: 10px;
}
.wz7{
top:3px;
left: 4px;
position: absolute;
color: #ffffff;
}
/* 底部框 */ /* 底部框 */
.Box6{ .Box6{
width: 390px; width: 390px;
@ -269,7 +179,7 @@
position: absolute; position: absolute;
top:700px; top:700px;
} }
.Box6 image{ .image12{
width: 35px; width: 35px;
height: 30px; height: 30px;
position: absolute; position: absolute;
@ -311,6 +221,31 @@
.h1{ .h1{
margin-left: 10rpx; margin-left: 10rpx;
display: flex; display: flex;
position: relative; position:relative;
top: 160rpx; top: 160rpx;
}
.box7 {
width: 100%;
flex-direction: column; /* 垂直方向弹性布局 */
white-space: nowrap; /* 强制内容不换行,确保图片在一行显示 */
position:relative;
top: 260rpx;
}
.image-container {
display: inline-block;
width: 180rpx;
height: 240rpx;
margin-right: 10rpx; /* 图片之间的间距 */
margin-left: 10rpx;
}
.image5 {
width: 100%;
height: 100%;
}
.text{
margin-left: 60rpx;
margin-top: 50rpx;
} }

View File

@ -26,8 +26,8 @@
</view> </view>
<!-- 第一个项目 --> <!-- 第一个项目 -->
<view class="h1"> <view class="h1" >
<view a:for="{{ tuijian }}" a:key="index"> <view a:for="{{ tuijian }}" a:key="index"data-num="{{item}}" onTap="shangpinjiemian">
<image class="image2" mode="scaleToFill" src="{{item.commoditiesImage}}" /> <image class="image2" mode="scaleToFill" src="{{item.commoditiesImage}}" />
<text class="zt2">{{item.commoditiesName}}</text> <text class="zt2">{{item.commoditiesName}}</text>
<text class="zt3">¥{{item.commoditiesPrice}}</text> <text class="zt3">¥{{item.commoditiesPrice}}</text>
@ -36,34 +36,23 @@
<!-- 推荐美甲师 --> <!-- 推荐美甲师 -->
<text class="wz1">推荐美甲师</text> <text class="wz1">推荐美甲师</text>
<!-- 第一个美甲师 --> <!-- 第一个美甲师 -->
<view class="h5"> <view class="box7">
<image mode="scaleToFill" src="../image/meijiashi1.png" /> <view a:for="{{meijiashi}}" a:for-item="item" class="image-container">
<text class="wz2">丽丽</text> <image class="image5" mode="scaleToFill" src="{{item.manicuristAvatar}}" />
<view class="h6"> <view>
<text class="wz3">咨询</text> <text class="text">{{item.manicuristName}}</text>
</view> </view>
<view class="h7"> </view>
<text class="wz4">预约</text>
</view> </view>
</view>
<!-- 第二个美甲师 --> <!-- 底部框 -->
<view class="h8"> <view class="Box6">
<image mode="scaleToFill" src="../image/meijiashi2.png" /> <image class="image12" mode="scaleToFill" src="../image/pingjia.png" />
<text class="wz5">清清</text> <view class="box5" ></view>
<view class="h9"> <text class="t1" onTap="pingjia">评价</text>
<text class="wz6">咨询</text> <view class="box6">
</view> <text class="t2" onTap="zixun">咨询</text>
<view class="h10">
<text class="wz7">预约</text>
</view>
</view>
<!-- 底部框 -->
<view class="Box6">
<image mode="scaleToFill" src="../image/pingjia.png" />
<view class="box5"></view>
<navigator open-type="navigate" url="../shangpinpingjia/shangpinpingjia" hover-class="navigator-hover" class="t1">评价</navigator>
<view class="box6">
<text class="t2">咨询</text>
</view> </view>
</view> </view>

View File

@ -16,7 +16,16 @@ Page({
sortField: "", sortField: "",
sortOrder: "", sortOrder: "",
status: "", status: "",
tuijian:[] tuijian:[],
meijiashi:[],
email: "",
gender: 0,
manicuristAvatar: "",
manicuristName: "",
phone: "",
rating: 0,
specialties: "",
id:''
}, },
onLoad(options) { onLoad(options) {
// Extract userId and address from options // Extract userId and address from options
@ -26,7 +35,8 @@ Page({
const businessAvatar = options.businessAvatar; const businessAvatar = options.businessAvatar;
const startBusiness = options.startBusiness; const startBusiness = options.startBusiness;
const endBusiness = options.endBusiness; const endBusiness = options.endBusiness;
const storeStatus = options.storeStatus const storeStatus = options.storeStatus;
const id = options.id
// Set them in data for use in the page // Set them in data for use in the page
this.setData({ this.setData({
userId: userId, userId: userId,
@ -36,13 +46,14 @@ Page({
endBusiness:endBusiness, endBusiness:endBusiness,
startBusiness:startBusiness, startBusiness:startBusiness,
storeStatus:storeStatus, storeStatus:storeStatus,
id:id,
}); });
my.request({ my.request({
url: url + '/api/commodities/list/page/commoditiesVO', url: url + '/api/commodities/list/page/commoditiesVO',
method: 'POST', method: 'POST',
data: { data: {
businessId: userId, businessId: id,
commoditiesGroupId: userId, commoditiesGroupId: id,
commoditiesName: "", commoditiesName: "",
current: 0, current: 0,
pageSize: 2, pageSize: 2,
@ -68,46 +79,54 @@ Page({
console.error('Request failed', error); console.error('Request failed', error);
} }
}); });
this.meijiahsi();
}, },
// meijiahsi(){ meijiahsi(){
// my.request({ my.request({
// url: url + '/api/manicurist/userQuery', url: url + '/api/manicurist/userQueryAll',
// method: 'POST', method: 'POST',
// data: { data: {
// "businessId": 0, businessId: this.data.id
// "current": 0, },
// "email": "", headers: {
// "employment_date": "", 'content-type': 'application/json',
// "gender": 0, },
// "id": 0, dataType: 'json',
// "manicuristAvatar": "", success: (res) => {
// "manicuristName": "", console.log('Request succeeded:', res);
// "pageSize": 0, if (res.data && res.data.data) {
// "phone": "", this.setData({
// "rating": 0, meijiashi: res.data.data, // 更新 tuijian 列表
// "salary": 0, });
// "sortField": "", } else {
// "sortOrder": "", console.log('shibaile')
// "specialties": "", }
// "userId": 0 },
// }, fail: (error) => {
// headers: { console.error('Request failed', error);
// 'content-type': 'application/json', }
// }, });
// dataType: 'json', },
// success: (res) => { pingjia(){
// console.log('Request succeeded:', res); my.navigateTo({
// if (res.data && res.data.data) { url:'/pages/shangpinpingjia/shangpinpingjia'
// this.setData({ })
// tuijian: res.data.data.records, // 更新 tuijian 列表 },
// }); zixun(){
// } else { my.navigateTo({
// console.log('shibaile') url:'/pages/zixunmeijiashi/zixunmeijiashi'
// } })
// }, },
// fail: (error) => { shangpinjiemian(item){
// console.error('Request failed', error); const id = item.target.dataset.num
// } const ID = id.id
// }); const commoditiesPrice = id.commoditiesPrice
// } const commoditiesName = id.commoditiesName
const commoditiesImage = id.commoditiesImage
const businessId = id.businessId
console.log('Address being passed: ',id,commoditiesPrice,commoditiesName,commoditiesImage,businessId);
my.navigateTo({
url:`/pages/shangpinjiemian/shangpinjiemian?commoditiesPrice=${commoditiesPrice}&&commoditiesName=${commoditiesName}&&commoditiesImage=${commoditiesImage}&&id=${ID}&&businessId=${businessId}`
})
}
}); });

View File

@ -1,4 +1,6 @@
{ {
"defaultTitle": "店铺主页",
"usingComponents": {}, "usingComponents": {},
"styleIsolation": "apply-shared" "styleIsolation": "apply-shared"
} }

View File

@ -1,4 +1,5 @@
{ {
"defaultTitle": "购物车",
"usingComponents": {}, "usingComponents": {},
"styleIsolation": "apply-shared" "styleIsolation": "apply-shared"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -1,5 +1,4 @@
<view class="sousuo"> <view class="sousuo">
<image mode="scaleToFill" src="/pages/image/aback.png" />
<view class="ssl"> <view class="ssl">
<image mode="scaleToFill" src="/pages/image/asearch.png" onTap="onSearch"/> <image mode="scaleToFill" src="/pages/image/asearch.png" onTap="onSearch"/>
<form> <form>

View File

@ -1,4 +1,5 @@
{ {
"defaultTitle": "上门预约",
"usingComponents": {}, "usingComponents": {},
"styleIsolation": "apply-shared" "styleIsolation": "apply-shared"
} }

View File

@ -1,5 +1,5 @@
/* 商品图背景 */ /* 商品图背景 */
.Box1 image{ .image{
width: 390px; width: 390px;
height: 300px; height: 300px;
} }
@ -8,57 +8,48 @@
width: 390px; width: 390px;
height: 80px; height: 80px;
background-color: #eec2c7; background-color: #eec2c7;
position: absolute; position: relative;
top:240px; top:0rpx;
border-radius: 15px; border-radius: 15px;
} }
.z1{ .z1{
top: 10px; top: 20rpx;
left: 10px; left: 20rpx;
position: absolute; position: relative;
} }
.z2{ .z2{
top: 30px; top: 80rpx;
left: 10px; right: 140rpx;
position: absolute; position: relative;
font-weight: bolder; font-weight: bolder;
font-size: 20px; font-size: 20px;
} }
/* 商品底部 */ /* 商品底部 */
/* 商品价格 */ /* 商品价格 */
.Box2{
width: 390px;
height: 400px;
background-color: #ffffff;
position: absolute;
top:295px;
border-radius: 15px;
}
.z3{ .z3{
font-size: 22px; font-size: 22px;
font-weight: bolder; font-weight: bolder;
position: absolute; position: relative;
top:15px; top:25rpx;
left: 10px; right: 60rpx;
} }
.z4{ .z4{
position: absolute; position: relative;
top:46px; color: rgb(29, 18, 18);
left: 20px; }
color: darkgrey; .box8{
width: 400rpx;
position: relative;
left: 240rpx;
top: 25rpx;
} }
/* 商品介绍 */ /* 商品介绍 */
.box2{
width: 390px;
height: 1px;
position: absolute;
top:78px;
background-color: rgba(169, 169, 169, 0.53);
}
.z5{ .z5{
font-size: 15px; font-size: 15px;
position: absolute; position: relative;
top:88px; top:20rpx;
color: darkgrey; color: darkgrey;
left: 5px; left: 5px;
} }
@ -108,32 +99,9 @@
left: 1px; left: 1px;
border-radius: 20px; border-radius: 20px;
} }
/* 内部介绍 */
.w1{
font-size: 13px;
position: absolute;
top:5px;
left: 10px;
}
.w2{
font-size: 13px;
position: absolute;
top:24px;
left: 10px;
}
.box5{
width: 390px;
height: 1px;
position: absolute;
background-color: rgb(169, 169, 169);
top:44px;
}
.w3{
font-size: 13px;
position: absolute;
top:50px;
left: 10px;
}
/* 内部盒子 */ /* 内部盒子 */
.Box5{ .Box5{
width: 340px; width: 340px;
@ -199,33 +167,48 @@
top:110px; top:110px;
left: 5px; left: 5px;
} }
/* 预约框 */ .box9{
.Box6{ position: relative;
top: 35rpx;
}
.container {
padding: 16px;
}
.box10{
display: block;
margin-top: 15rpx;
}
.box11{
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
/* Add this in your style section */
.button-container {
display: flex;
justify-content: space-between;
padding: 10px;
position: absolute;
top: 700px;
left: 28px;
}
.button {
background-color: #f3bfc1; /* Light pink background color */
color: #000000; /* Text color */
border-radius: 20px; /* Rounded edges */
padding: 10px 20px;
text-align: center;
font-size: 16px;
width: 100px; width: 100px;
height: 35px;
position: absolute;
background-color: #58A55C;
top:222px;
left: 260px;
border-radius: 10px;
} }
.zt1{
position: absolute; /* Additional styling for individual buttons if needed */
top:6px; .add-to-cart {
left: 20px; margin-right: 20px;
} }
/* 购物车框 */
.Box7{ .buy-now {
width: 100px; margin-left: 20px;
height: 35px;
position: absolute;
background-color: #E89709;
top:222px;
left: 140px;
border-radius: 10px;
}
.zt2{
position: absolute;
top:6px;
left: 10px;
} }

View File

@ -1,56 +1,68 @@
<view> <view>
<!-- 商品图 --> <!-- 商品图 -->
<view class="Box1"> <view class="Box1">
<image mode="scaleToFill" src="../image/xiangce1.jpg" /> <image class="image" mode="scaleToFill" src="{{commoditiesImage}}" />
<!-- 价格表 --> <!-- 价格表 -->
<view class="box1"> <view class="box1">
<text class="z1">年售1000+</text> <text class="z1">年售1000+</text>
<text class="z2">¥59.90</text> <text class="z2">¥{{commoditiesPrice}}</text>
</view> <text class="z3">【{{commoditiesName}}】</text>
<!-- 底部信息 --> <view class="box8">
<view class="Box2">
<!-- 商品介绍 -->
<text class="z3">【半贴短甲彩绘款】</text>
<text class="z4">款式随便做,饰品不限量,含甲片,含卸甲</text> <text class="z4">款式随便做,饰品不限量,含甲片,含卸甲</text>
<view class="box2"></view> </view>
</view>
<view style="width:100%">
<text class="z5">须知 需提前两小时预约 周一至周日全天可用 购买后30天内有效 购买前请仔细阅读</text> <text class="z5">须知 需提前两小时预约 周一至周日全天可用 购买后30天内有效 购买前请仔细阅读</text>
<!-- 底部框 -->
<text class="z6">项目详情</text>
<text class="z7">购买须知</text>
<text class="z8">评价</text>
<!-- 详情介绍 -->
<view class="box3"></view>
<view class="Box3">
<view class="Box4">
<!-- 内部介绍 -->
<text class="w1">商品介绍</text>
<text class="w2">适用部位 手部</text>
<view class="box5"></view>
<text class="w3">包含项目</text>
<!-- 小框介绍 -->
<view class="Box5">
<view class="box6">
<view class="box7">
<text class="w4">款式美甲</text>
<text class="w5">1份|59.90元</text>
</view> </view>
<text class="w6">美甲类型 全手任意款式(款式随便做,饰品随便贴)</text> <!-- 商品介绍 -->
<text class="w7">美甲饰品 随便选择饰品款式</text> <view class="box9">
<text class="w8">封层</text> <ant-tabs
<text class="w9"> 磨砂/亮面</text> items="{{ items }}"
<text class="w10">底胶品牌 PQ|甲胶油</text> current="{{ current }}"
onChange="onChange">
<swiper
current="{{ current }}"
autoplay="{{ false }}"
vertical="{{ false }}"
circular="{{ false }}"
onChange="onSwipeChange">
<block
a:for="{{ items }}"
a:for-index="index"
a:for-item="item"
a:key="{{ index }}">
<swiper-item>
<view class="box10">
<text class="box10">商品介绍</text>
<text class="box10">适用部位: 手部</text>
<text class="box10">包含项目</text>
<view class="box11">
<text class="box10">款式美甲</text>
<text style="margin-right:10rpx">1/{{commoditiesPrice}}</text>
</view>
<text class="box10">美甲类型: 全手任意款式(款式随便做,饰品随便贴)</text>
<text class="box10">美甲饰品: 随便选择饰品款式</text>
<text class="box10">封层 : 磨砂/亮面</text>
<text class="box10">底胶品牌: PQ|甲胶油</text>
</view>
</swiper-item>
<swiper-item>
<text>无</text>
</swiper-item>
<swiper-item>
<text>无</text>
</swiper-item>
</block>
</swiper>
</ant-tabs>
</view> </view>
</view> </view>
<!-- 预约框 -->
<view class="Box6">
<text class="zt1">立即预约</text>
</view>
<!-- 购物车框 --> <!-- 购物车框 -->
<view class="Box7"> <view class="button-container">
<text class="zt2">加入购物车</text> <view class="button add-to-cart" onTap="jiaru">加入购物车</view>
</view> <view class="button buy-now">立即购买</view>
</view>
</view>
</view>
</view> </view>
</view> </view>

View File

@ -1,4 +1,69 @@
import {url} from '../request'
Page({ Page({
data: {}, data: {
onLoad() {}, commoditiesImage:'',
commoditiesPrice:'',
commoditiesName:'',
businessId:'',
items: [
{
title: '项目详情',
},
{
title: '购买须知',
},
{
title: '评价',
},
],
},
onLoad(options) {
const commoditiesImage = options.commoditiesImage;
const commoditiesName = options.commoditiesName;
const commoditiesPrice = options.commoditiesPrice;
const id = options.id;
const businessId = options.businessId
// Set them in data for use in the page
this.setData({
commoditiesImage: commoditiesImage,
commoditiesName: commoditiesName,
commoditiesPrice:commoditiesPrice,
id:id,
businessId:businessId
});
},
// 切换标签
onChange(current) {
this.setData({
current,
});
},
jiaru(){
my.request({
url: url+'/api/cart/add',
method: 'POST',
data: {
businessId: 1,
commoditiesId: 1,
quantity: 1,
selectedOptions: ""
},
headers: {
'content-type': 'application/json', //默认值
},
dataType: 'json',
success:(res)=>{
console.log(res);
my.alert({ content: 'success' });
},
fail: function (error) {
console.error('fail: ', JSON.stringify(error));
},
complete: function (res) {
my.hideLoading();
my.alert({ content: 'complete' });
},
});
}
}); });

View File

@ -1,4 +1,8 @@
{ {
"usingComponents": {}, "defaultTitle": "商品界面",
"usingComponents": {
"ant-range-picker": "antd-mini/es/DatePicker/RangePicker/index",
"ant-tabs": "antd-mini/es/Tabs/index"
},
"styleIsolation": "apply-shared" "styleIsolation": "apply-shared"
} }

View File

@ -43,8 +43,8 @@
width: 100%; width: 100%;
height: 60px; height: 60px;
background-color: #efaab1b7; background-color: #efaab1b7;
top:400px; top:80rpx;
position: absolute; position: relative;
} }
.z1{ .z1{
@ -194,3 +194,30 @@
flex-wrap: wrap; /* 允许换行 */ flex-wrap: wrap; /* 允许换行 */
justify-content: space-between; /* 使子元素分布更均匀 */ justify-content: space-between; /* 使子元素分布更均匀 */
} }
.container {
display: flex;
flex-direction: row; /* 设为横向排列 */
align-items: center; /* 纵向居中对齐 */
}
.box4 {
display: inline-flex;
width: 160rpx;
height: 160rpx;
background-color: pink;
border-radius: 10%;
justify-content: center;
align-items: center;
box-shadow: -10px 10px 0px rgba(33, 2, 2, 0.1);
position: relative;
}
.box5 {
width: 100%;
position: relative;
margin-left: 30rpx;
top: 20rpx;
}
.text3{
color: white;
}

View File

@ -1,20 +1,4 @@
<!-- 顶部 --> <view class="page-section">
<view>
<view class="shouyeBox1">
<navigator open-type="navigate" url="/pages/shangmenyuyue/shangmenyuyue">
<view class="box1">
<text class="text1">个人预约</text>
</view>
</navigator>
<view class="box2">
<navigator open-type="navigate" url="../daodianfuwu/daodianfuwu" hover-class="navigator-hover" class="text2">到店服务</navigator>
</view>
</view>
<!-- 轮播图 -->
<view class="page" style="padding:0px;">
<view class="page-section">
<view class="page-section-demo" style="padding:0px;"> <view class="page-section-demo" style="padding:0px;">
<swiper <swiper
style="top:0px" style="top:0px"
@ -34,6 +18,22 @@
</swiper> </swiper>
</view> </view>
</view> </view>
<view class="box5">
<view class="box4" onTap="shangmen">
<text class="text3">上门预约</text>
</view>
<view class="box4"onTap="daodian" style="margin-left:20rpx">
<text class="text3">到店服务</text>
</view>
<view class="box4" onTap="qiangdan" style="margin-left:20rpx">
<text class="text3">发布抢单</text>
</view>
<view class="box4"style="margin-left:20rpx" onTap="yuyue">
<text class="text3">我的预约</text>
</view>
</view>
<!-- 店铺 --> <!-- 店铺 -->
<view > <view >
<view class="k1"> <view class="k1">

View File

@ -57,6 +57,7 @@ Page({
}, },
dianpu(item) { dianpu(item) {
const id = item.target.dataset.num const id = item.target.dataset.num
const ID = id.id
const userId = id.userId const userId = id.userId
const address = id.address const address = id.address
const businessName = id.businessName const businessName = id.businessName
@ -64,13 +65,31 @@ Page({
const endBusiness = id.endBusiness const endBusiness = id.endBusiness
const startBusiness = id.startBusiness const startBusiness = id.startBusiness
const storeStatus = id.storeStatus const storeStatus = id.storeStatus
console.log('Address being passed: ', userId,address,businessName,businessAvatar,endBusiness,startBusiness); console.log('Address being passed: ', ID,address,businessName,businessAvatar,endBusiness,startBusiness);
my.navigateTo({ my.navigateTo({
url: `/pages/dianpuzhuye/dianpuzhuye?userId=${userId}&&address=${address}&&businessName=${businessName}&&businessAvatar=${businessAvatar}&&startBusiness=${startBusiness}&&endBusiness=${endBusiness}&&storeStatus=${storeStatus}`, url: `/pages/dianpuzhuye/dianpuzhuye?userId=${userId}&&address=${address}&&businessName=${businessName}&&businessAvatar=${businessAvatar}&&startBusiness=${startBusiness}&&endBusiness=${endBusiness}&&storeStatus=${storeStatus}&&id=${ID}`,
}); });
}, },
shangmen(){
my.navigateTo({
url:'/pages/shangmenyuyue/shangmenyuyue'
})
},
daodian(){
my.navigateTo({
url:'/pages/daodianfuwu/daodianfuwu'
})
},
qiangdan(){
my.navigateTo({
url:'/pages/kehushangmenyuyueqiangdan/kehushangmenyuyueqiangdan'
})
},
yuyue(){
my.navigateTo({
url:'/pages/wodeyuyue/wodeyuyue'
})
}
}) })

View File

@ -39,79 +39,13 @@
} }
.z1{ .z1{
font-size: 20px; font-size: 20px;
position: absolute; position: relative;
left:70px;
top:140px;
} }
.box3 image{ .image1{
max-width: 35px; max-width: 35px;
max-height: 25px; max-height: 25px;
position:absolute; position:relative;
top:140px;
left:330px;
}
/* 我的评价 */
.box4 image{
max-width: 35px;
max-height: 25px;
position:absolute;
top:200px;
left:25px;
}
.z2{
font-size: 20px;
position: absolute;
left:70px;
top:200px;
}
.box5 image{
max-width: 35px;
max-height: 25px;
position:absolute;
top:200px;
left:330px;
}
/* 个人信息 */
.box6 image{
max-width: 35px;
max-height: 25px;
position:absolute;
top:260px;
left:25px;
}
.z3{
font-size: 20px;
position: absolute;
left:70px;
top:260px;
}
.box7 image{
max-width: 35px;
max-height: 25px;
position:absolute;
top:260px;
left:330px;
}
/* 商家入驻 */
.box8 image{
max-width: 35px;
max-height: 25px;
position:absolute;
top:320px;
left:25px;
}
.z4{
font-size: 20px;
position: absolute;
left:70px;
top:320px;
}
.box9 image{
max-width: 35px;
max-height: 25px;
position:absolute;
top:320px;
left:330px;
} }
/* 退出登录 */ /* 退出登录 */
.box10 image{ .box10 image{
@ -134,3 +68,7 @@
top:380px; top:380px;
left:330px; left:330px;
} }
.box3{
width: 100%;
height: 100rpx;
}

View File

@ -1,50 +1,45 @@
<!-- 头像盒子 --> <!-- 头像盒子 -->
<view> <view>
<view class="box1"> <view class="box1"onTap="login" >
<image mode="aspectFill" src="/pages/image/1.png"></image> <image mode="aspectFill" src="{{avatarUrl}}"></image>
<text class="text1">爱美甲的仙女123</text> <text class="text1">{{username}}</text>
<text class="text2">设置</text>
<text class="text3">客服</text>
</view> </view>
</view> </view>
<!-- 信息盒子 --> <!-- 信息盒子 -->
<!--我的订单 --> <!--我的订单 -->
<view class="box2">
<image mode="aspectFill" src="/pages/image/我的订单.png"></image> <view class="box3" onTap="dingdan">
</view> <image class="image1"style="left:40rpx;top:25rpx" mode="aspectFill" src="/pages/image/我的订单.png"></image>
<view class="box3"> <image class="image1" style="top:23rpx;left:560rpx;" mode="aspectFill" src="/pages/image/跳转按钮.png"></image>
<image mode="aspectFill" src="/pages/image/跳转按钮.png"></image> <text class="z1" style="top:18rpx">我的订单</text>
<navigator open-type="navigate" url="../wodedingdan/wodedingdan" hover-class="navigator-hover" class="z1">我的订单</navigator>
</view> </view>
<!-- 我的评价--> <!-- 我的评价-->
<view class="box4"> <view class="box3" onTap="pingjia">
<image mode="aspectFill" src="/pages/image/我的评价.png"></image> <image class="image1"style="left:40rpx;top:25rpx" mode="aspectFill" src="/pages/image/我的评价.png"></image>
</view> <image class="image1" style="top:23rpx;left:560rpx;" mode="aspectFill" src="/pages/image/跳转按钮.png"></image>
<view class="box5"> <text class="z1" style="top:18rpx">我的评价</text>
<image mode="aspectFill" src="/pages/image/跳转按钮.png"></image>
<navigator open-type="navigate" url="../wodepingjia/wodepingjia" hover-class="navigator-hover" class="z2">我的评价</navigator>
</view> </view>
<!-- 个人信息 --> <!-- 个人信息 -->
<view class="box6"> <view class="box3" onTap="xinxi">
<image mode="aspectFill" src="/pages/image/我的个人信息.png"></image> <image class="image1"style="left:40rpx;top:25rpx" mode="aspectFill" src="/pages/image/我的个人信息.png"></image>
<navigator open-type="navigate" url="../gerenxinxi/gerenxinxi" hover-class="navigator-hover" class="z3">个人信息</navigator> <image class="image1" style="top:23rpx;left:560rpx;" mode="aspectFill" src="/pages/image/跳转按钮.png"></image>
<text class="z1" style="top:18rpx">个人信息</text>
</view> </view>
<view class="box7"> <!-- 我的收藏 -->
<image mode="aspectFill" src="/pages/image/跳转按钮.png"></image> <view class="box3" onTap="shoucang">
<image class="image1"style="left:40rpx;top:25rpx" mode="aspectFill" src="/pages/image/shoucang.png"></image>
<image class="image1" style="top:23rpx;left:560rpx;" mode="aspectFill" src="/pages/image/跳转按钮.png"></image>
<text class="z1" style="top:18rpx">我的收藏</text>
</view> </view>
<!-- 商家入驻 --> <!-- 商家入驻 -->
<view class="box8"> <view class="box3" onTap="ruzhu">
<image mode="aspectFill" src="/pages/image/商家入驻.png"></image> <image class="image1"style="left:40rpx;top:25rpx" mode="aspectFill" src="/pages/image/商家入驻.png"></image>
<navigator open-type="navigate" url="../shangjiaruzhu/shangjiaruzhu" hover-class="navigator-hover" class="z4">商家入驻</navigator> <image class="image1" style="top:23rpx;left:560rpx;" mode="aspectFill" src="/pages/image/跳转按钮.png"></image>
</view> <text class="z1" style="top:18rpx">商家入驻</text>
<view class="box9">
<image mode="aspectFill" src="/pages/image/跳转按钮.png"></image>
</view> </view>
<!-- 退出登录 --> <!-- 退出登录 -->
<view class="box10"> <view class="box3" >
<image mode="aspectFill" src="/pages/image/退出登录.png"></image> <image class="image1"style="left:40rpx;top:25rpx" mode="aspectFill" src="/pages/image/退出登录.png"></image>
<navigator open-type="navigate" url="../denglu/denglu" hover-class="navigator-hover" class="z5">退出登录</navigator> <image class="image1" style="top:23rpx;left:560rpx;" mode="aspectFill" src="/pages/image/跳转按钮.png"></image>
</view> <text class="z1" style="top:18rpx">退出登录</text>
<view class="box11">
<image mode="aspectFill" src="/pages/image/跳转按钮.png"></image>
</view> </view>

View File

@ -1,4 +1,54 @@
Page({ Page({
data: {}, data: {
onLoad() {}, username: '请登录', // 用户名
avatarUrl: 'https://tse2-mm.cn.bing.net/th/id/OIP-C.jHUH4s7TQ48X_B-1iozuJgHaHa?w=207&h=207&c=7&r=0&o=5&dpr=1.5&pid=1.7' // 用户头像
},
onShow() {
// 获取缓存中的数据
const userInfo = my.getStorageSync({ key: 'user_info' }).data;
// 判断是否存在 userInfo如果存在则更新页面数据
if (userInfo) {
this.setData({
username: userInfo.username,
avatarUrl: userInfo.avatarUrl
});
} else {
console.log('没有找到用户信息');
}
},
// 以下是一些页面跳转的示例函数
dingdan() {
my.navigateTo({
url: '/pages/wodedingdan/wodedingdan'
});
},
pingjia() {
my.navigateTo({
url: '/pages/wodepingjia/wodepingjia'
});
},
xinxi() {
my.navigateTo({
url: '/pages/gerenxinxi/gerenxinxi'
});
},
shoucang() {
my.navigateTo({
url: '/pages/wodeshoucang/wodeshoucang'
});
},
ruzhu() {
my.navigateTo({
url: '/pages/shangjiaruzhu/shangjiaruzhu'
});
},
login() {
my.navigateTo({
url: '/pages/denglu/denglu'
});
}
}); });

View File

@ -1,4 +1,5 @@
{ {
"defaultTitle": "我的",
"usingComponents": {}, "usingComponents": {},
"styleIsolation": "apply-shared" "styleIsolation": "apply-shared"
} }

View File

@ -1,4 +1,5 @@
{ {
"defaultTitle": "咨询",
"usingComponents": {}, "usingComponents": {},
"styleIsolation": "apply-shared" "styleIsolation": "apply-shared"
} }

59
甲情_甲意/node_modules/.package-lock.json generated vendored Normal file
View File

@ -0,0 +1,59 @@
{
"name": "alipay-ykf-xj",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/@mini-types/alipay": {
"version": "3.0.14",
"resolved": "https://registry.npmmirror.com/@mini-types/alipay/-/alipay-3.0.14.tgz",
"integrity": "sha512-FakzSsKvybtWlEIVTIRlr89kuQFn+XY86Ho9VUFFaKLplhW6Wx8FUxTDE7IzV7B9rT8DP/Icy637vUHlXPsw1g==",
"dependencies": {
"@mini-types/global": "3.0.14",
"@mini-types/my": "3.0.14"
}
},
"node_modules/@mini-types/global": {
"version": "3.0.14",
"resolved": "https://registry.npmmirror.com/@mini-types/global/-/global-3.0.14.tgz",
"integrity": "sha512-St2ucFRfKRskposOqV/9iNJTKn1MbyqDypQiy/0DaVJjEm2MFi82RJjX9sBz1uWhQIqzu741PgTjGSy7L/Qj9g=="
},
"node_modules/@mini-types/my": {
"version": "3.0.14",
"resolved": "https://registry.npmmirror.com/@mini-types/my/-/my-3.0.14.tgz",
"integrity": "sha512-aEgmM+rbEvEzTvqltCFRAg/h6KKs14M1y+FrOkz+hn2EyNpOVPesUzTjbRhSiFFsE3WdfBh54lHNYBahAmHq7w=="
},
"node_modules/antd-mini": {
"version": "2.36.8",
"resolved": "https://registry.npmmirror.com/antd-mini/-/antd-mini-2.36.8.tgz",
"integrity": "sha512-9eiCyeux4cMcRC9BeXzqE7p6Cua9YBMTaiU6nOiiuAzIDSI5NAoO9LIn0Vfo2N2UqhVgloBYyIWOE1M/iZLCCw==",
"dependencies": {
"@mini-types/alipay": "^3.0.5",
"async-validator": "^4.0.7",
"dayjs": "^1.11.3",
"fast-deep-equal": "3.1.3",
"tslib": "2.5.0"
}
},
"node_modules/async-validator": {
"version": "4.2.5",
"resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
},
"node_modules/dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/tslib": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
}
}
}

21
甲情_甲意/node_modules/@mini-types/alipay/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT LICENSE
Copyright (c) 2018-present Alipay.com, https://www.alipay.com/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION

View File

@ -0,0 +1,30 @@
{
"name": "@mini-types/alipay",
"version": "3.0.14",
"description": "TypeScript declarations for Alipay's mini program.",
"scripts": {},
"miniprogram": "./",
"repository": {
"type": "git",
"url": "git@github.com:ant-mini-program/api-typings.git"
},
"keywords": [
"tinyapp",
"miniprogram",
"types"
],
"license": "MIT",
"types": "./types/index.d.ts",
"files": [
"types"
],
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"dependencies": {
"@mini-types/global": "3.0.14",
"@mini-types/my": "3.0.14"
},
"gitHead": "f923cf356c26bf6c80ca640951683ba777d968f8"
}

View File

@ -0,0 +1,4 @@
///<reference types='@mini-types/my' />
///<reference types='@mini-types/global' />
export * from '@mini-types/global/types/lib.global';

21
甲情_甲意/node_modules/@mini-types/global/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT LICENSE
Copyright (c) 2018-present Alipay.com, https://www.alipay.com/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION

View File

@ -0,0 +1,26 @@
{
"name": "@mini-types/global",
"version": "3.0.14",
"description": "TypeScript declarations for Alipay's mini program.",
"scripts": {},
"miniprogram": "./",
"repository": {
"type": "git",
"url": "git@github.com:ant-mini-program/api-typings.git"
},
"keywords": [
"tinyapp",
"miniprogram",
"types"
],
"license": "MIT",
"types": "./types/index.d.ts",
"files": [
"types"
],
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"gitHead": "f923cf356c26bf6c80ca640951683ba777d968f8"
}

View File

@ -0,0 +1,68 @@
/// <reference path="./lib.app.d.ts" />
/// <reference path="./lib.page.d.ts" />
/// <reference path="./lib.component.d.ts" />
/// <reference path="./lib.mixin.d.ts" />
/// <reference path="./lib.shared.d.ts" />
/// <reference path="./lib.global.d.ts" />
declare namespace MiniProgram {
type UnknownRecord = Record<string, unknown>;
/**
* Get union key of two types
*/
type UnionKeys<T, U> = keyof T | keyof U;
/**
* Get unique keys of left type.
*/
type UniqueLeftKeys<T, U> = Exclude<UnionKeys<T, U>, keyof U>;
/**
* Extract left-only types.
*/
type UniqueLeft<T, U> = {
[P in UniqueLeftKeys<T, U>]: T[P];
};
// 获取 mixins 数组的每一个元素的类型
type TExtractValuesOfTuple<T extends any[]> = T[keyof T & number];
// 获取 methods、props、data 类型(主要就是这个三个)
type TGetMixinMethods<T> = T extends { methods?: infer M } ? M : never;
type TGetMixinData<T> = T extends { data?: infer D } ? D : never;
type TGetMixinProps<T> = T extends { props?: infer P } ? P : never;
// 整合一下类型
type UnionToIntersection<T> = (
T extends any ? (x: T) => any : never
) extends (x: infer R) => any
? R
: never;
/**
* Recursively map a type and make all properties optional.
*/
type RecursivePartial<T> = {
[P in keyof T]?: T[P] extends Array<infer U>
? Array<RecursivePartial<U>>
: T[P] extends object
? RecursivePartial<T[P]>
: T[P];
};
/**
* Recursively map a type and make all properties optional & dynamic.
*/
type RecursivePartialAndDynamic<T> = T extends object
? {
[P in keyof T]?: T[P] extends Array<infer U>
? Array<RecursivePartialAndDynamic<U>>
: T[P] extends Function
? T[P]
: T[P] extends object
? RecursivePartialAndDynamic<T[P]>
: T[P];
}
: T;
}

View File

@ -0,0 +1,141 @@
declare namespace MiniProgram.App {
interface ReferrerInfo {
/**
*
*/
appId: string;
/**
*
*/
sourceServiceId: string;
/**
*
*/
extraData: Record<string, any>;
}
interface LaunchOptions<
Query extends Record<string, string> = Record<string, string>
> {
/**
* query query
*/
query: Query;
/**
*
* @see https://opendocs.alipay.com/mini/framework/scene
*/
scene: number;
/**
* page page
*/
path: string;
/**
*
*/
referrerInfo: ReferrerInfo;
}
interface UnhandledRejectionRes {
/**
* reject
*/
reason: string;
/**
* reject Promise
*/
promise: Promise<unknown>;
}
/**
* app.js App(options) options
* ref: https://opendocs.alipay.com/mini/framework/app-detail
*/
interface Options<ExtraOptions extends UnknownRecord> {
/**
*
*
*/
onLaunch(options: LaunchOptions): void;
/**
*
*
*/
onShow(options: LaunchOptions): void;
/**
*
* Home
*/
onHide(): void;
/**
*
* js
*/
onError(error: string): void;
/**
*
*/
onShareAppMessage(): Page.IShareAppMessage;
/**
* unhandledrejection
* Promise reject reject onUnhandledRejection
*/
onUnhandledRejection(res: UnhandledRejectionRes): void;
/**
*
*/
globalData: object;
}
/**
* Additional properties in App instance, for module augmentation
*/
interface IInstanceAdditionalProperties<ExtraOptions extends UnknownRecord> {}
/**
* App
*/
interface IApp<ExtraThis, ExtraOptions extends UnknownRecord> {
(opts: UserAppOptions<ExtraThis, ExtraOptions>): any;
}
type IAppInstance<ExtraThis, ExtraOptions extends UnknownRecord> = Omit<
ExtraOptions,
keyof Options<ExtraOptions>
> &
ExtraThis &
IInstanceAdditionalProperties<ExtraOptions>;
/**
* App Options
*/
type UserAppOptions<ExtraThis, ExtraOptions extends UnknownRecord> = Partial<
Options<ExtraOptions>
> &
Partial<
UniqueLeft<UniqueLeft<ExtraThis, ExtraOptions>, Options<ExtraOptions>>
> & {
[P in keyof ExtraOptions]: P extends keyof Options<ExtraOptions>
? unknown
: ExtraOptions[P];
} & ThisType<IAppInstance<ExtraThis, ExtraOptions>>;
interface Constructor {
<ExtraThis = {}, ExtraOptions extends Record<string, unknown> = {}>(
opts: UserAppOptions<
ExtraThis & IGlobalMiniProgramExtraThis4App,
ExtraOptions
>
): void;
}
interface GetApp {
<
ExtraThis = {},
ExtraOptions extends Record<string, unknown> = {}
>(): IAppInstance<
ExtraThis & IGlobalMiniProgramExtraThis4App,
ExtraOptions
>;
}
}

View File

@ -0,0 +1,312 @@
declare namespace MiniProgram.Component {
/**
* Additional properties in Component instance, for module augmentation
*/
interface IComponentInstanceAdditionalProperties<
ExtraOptions extends UnknownRecord
> {}
interface ILifetimes {
/**
*
*/
created(): void;
/**
*
*/
attached(): void;
/**
*
*/
ready(): void;
/**
*
*/
moved(): void;
/**
*
*/
detached(): void;
}
interface IRelationOption {
/**
*
*/
type: 'parent' | 'child' | 'ancestor' | 'descendant';
/**
* attached
*/
linked?(target: BaseInstance): void;
/**
* moved
*/
linkChanged?(target: BaseInstance): void;
/**
* detached
*/
unlinked?(target: BaseInstance): void;
/**
* 使 Mixin
* Mixin实例Mixin实例的组件节点都会被关联
*/
target?: string;
}
/**
* component\/*\/index.js Component(options) options
* ref: https://opendocs.alipay.com/mini/framework/component_object
*/
interface IOptions<
Data,
Props,
Methods,
ExtraOptions extends UnknownRecord,
Mixins extends Array<Mixin.IMixin4Legacy | ReturnType<Mixin.Constructor>>
> {
/**
*
*/
data: Data | ((this: void) => Data);
/**
*
*/
props: Props;
/**
*
* @version 1.14.0+
*/
onInit(): void;
/**
*
* @version 1.14.0+
*/
deriveDataFromProps(nextProps: Partial<Props>): void;
/**
*
*/
didMount(): void;
/**
*
*/
didUpdate(prevProps: Partial<Props>, prevData: Partial<Data>): void;
/**
*
*/
didUnmount(): void;
/**
*
*/
mixins: Mixins;
/**
*
* Object of Functions
*/
methods: Methods;
/**
* ref引用时的返回值
* @version 1.18.0+
*/
ref(): void;
/**
* onShareAppMessage外的页面的生命周期函数以及页面事件处理函数
* @version 2.8.5
*/
pageEvents: Partial<Page.Events>;
/**
*
*/
options: Partial<{
/**
* true
* @version 2.8.0
*/
virtualHost: boolean;
/**
* observers
* @version 2.8.1
*/
observers: boolean;
/**
* lifetimes
* @version 2.8.5
*/
lifetimes: boolean;
/**
* relations
* @version 2.8.5
*/
relations: boolean;
/**
* externalClasses
* @version 2.8.5
*/
externalClasses: boolean;
}>;
/**
*
* @version 2.8.1
*/
observers: Record<string, (...args: any[]) => void>;
/**
*
* @version 2.8.5
*/
lifetimes: Partial<ILifetimes>;
/**
*
* @version 2.8.5
*/
relations: Record<string, IRelationOption>;
/**
*
* @version 2.8.5
*/
externalClasses: string[];
}
interface IInstanceProperties {
/**
*
*/
readonly is: string;
/**
* id axml
*/
readonly $id: number;
/**
*
*/
readonly $page: Record<string, any>;
/**
*
* @description
* @version 2.7.22
*/
readonly router: Shared.IRouter;
/**
*
* @description
* @version 2.7.22
*/
readonly pageRouter: Shared.IRouter;
}
interface IInstanceMethods<Data> {
/**
*
* @param data
* @param callback
*/
setData(
data: RecursivePartialAndDynamic<Data> & Record<string, unknown>,
callback?: () => void
): void;
/**
* $spliceData setData
* @param data
* @param callback
* @version 1.7.2+ 使 my.canIUse('page.$spliceData')
*/
$spliceData(
data: RecursivePartialAndDynamic<Data> & Record<string, unknown>,
callback?: () => void
): void;
/**
* AXML `ref`
*
* @version 2.7.22
* @returns undefined | null | | | ref Object
*/
selectOwnerComponent(): BaseInstance;
/**
* `ref`
*
* @version 2.7.22
* @returns undefined | null | | | ref Object
*/
selectComposedParentComponent(): BaseInstance;
/**
* mixin(Mixin()mixin实例)
* @description ref以指定组件返回值hasMixin('ref')
* @version 2.8.2
* @return boolean
* @see https://opendocs.alipay.com/mini/framework/component_object#%E7%BB%84%E4%BB%B6%E5%AE%9E%E4%BE%8B%E6%96%B9%E6%B3%95
*/
hasMixin(mixin: Mixin.IMixinIdentifier): boolean;
/**
*
* @version 2.8.5
*/
getRelationNodes(relationKey: string): BaseInstance[];
}
/**
* Public instance
*/
type IInstance<
Data,
Props,
Methods,
ExtraThis,
ExtraOptions extends UnknownRecord,
Mixins extends Array<Mixin.IMixin4Legacy | ReturnType<Mixin.Constructor>>
> = {
data: Data &
UnionToIntersection<TGetMixinData<TExtractValuesOfTuple<Mixins>>>;
props: Readonly<
Props & UnionToIntersection<TGetMixinProps<TExtractValuesOfTuple<Mixins>>>
>;
} & Methods &
UnionToIntersection<TGetMixinMethods<TExtractValuesOfTuple<Mixins>>> &
ExtraThis &
Omit<
ExtraOptions,
keyof IOptions<Data, Props, Methods, ExtraOptions, Mixins>
> &
IComponentInstanceAdditionalProperties<ExtraOptions> &
IInstanceProperties &
IInstanceMethods<Data> &
Shared.IInstanceSharedMethods<Data>;
type BaseInstance = IInstance<
UnknownRecord,
UnknownRecord,
UnknownRecord,
UnknownRecord,
UnknownRecord,
[]
>;
interface Constructor {
<
Data = UnknownRecord,
Props = UnknownRecord,
Methods = UnknownRecord,
ExtraThis = UnknownRecord,
ExtraOptions extends Record<string, unknown> = UnknownRecord,
Mixins extends Array<
Mixin.IMixin4Legacy | ReturnType<Mixin.Constructor>
> = any[]
>(
opts: {
[P in keyof ExtraOptions]: P extends keyof IOptions<
Data,
Props,
Methods,
ExtraOptions,
Mixins
>
? unknown
: ExtraOptions[P];
} & Partial<IOptions<Data, Props, Methods, ExtraOptions, Mixins>> &
ThisType<
IInstance<
Data,
Props,
Methods,
ExtraThis & IGlobalMiniProgramExtraThis4Component,
ExtraOptions,
Mixins
>
>
): void;
}
}

View File

@ -0,0 +1,98 @@
export type IAppOnLaunchOptions<Query extends Record<string, string>> =
MiniProgram.App.LaunchOptions<Query>;
export interface IRequirePluginAsync<
Target extends Record<string, any> = Record<string, any>
> {
<K extends keyof Target>(pluginName: K): Promise<Target[K]>;
<Result extends any>(pluginName: string): Promise<Result>;
}
export interface IRequirePlugin<
Target extends Record<string, any> = Record<string, any>
> {
<K extends keyof Target>(pluginName: K): Target[K];
<Result extends any>(pluginName: string): Result;
async: IRequirePluginAsync;
}
export type IMixin4Legacy<
Data,
Props,
Methods,
ExtraThis = MiniProgram.UnknownRecord,
ExtraOptions extends MiniProgram.UnknownRecord = MiniProgram.UnknownRecord
> = MiniProgram.Mixin.IMixin4Legacy<
Data,
Props,
Methods,
ExtraThis,
ExtraOptions
>;
export interface Require {
<T extends any>(path: string): T;
<T extends any>(path: string, cb?: (o: T) => void): void;
async<T extends any>(path: string): Promise<T>;
}
declare global {
/**
* Extra `this` for Component instance.
*/
interface IGlobalMiniProgramExtraThis4Component {}
/**
* Extra `this` for Page instance.
*/
interface IGlobalMiniProgramExtraThis4Page {}
/**
* Extra `this` for App instance.
*/
interface IGlobalMiniProgramExtraThis4App {}
/**
* 使 JS \`插件\` 通过 \`main\` 字段暴露的 JS 接口。
*/
const requirePlugin: IRequirePlugin;
const require: Require;
/**
* App's constructor
* @link https://opendocs.alipay.com/mini/framework/app-detail
*/
const App: MiniProgram.App.Constructor;
/**
* Get App.
* @link https://opendocs.alipay.com/mini/framework/get-app
*/
const getApp: MiniProgram.App.GetApp;
/**
* Get Current Pages
* @link https://opendocs.alipay.com/mini/framework/getcurrentpages
*/
const getCurrentPages: MiniProgram.Page.GetCurrentPages;
/**
* Page's constructor
* @link https://opendocs.alipay.com/mini/framework/page-detail
*/
const Page: MiniProgram.Page.Constructor;
/**
* Component's constructor
* @link https://opendocs.alipay.com/mini/framework/component_object
*/
const Component: MiniProgram.Component.Constructor;
/**
* `mixin` `Object`
* @version 2.8.2
* @link https://opendocs.alipay.com/mini/05bchn
*/
const Mixin: MiniProgram.Mixin.Constructor;
}

View File

@ -0,0 +1,104 @@
declare namespace MiniProgram.Mixin {
/**
* Component的mixins参数支持传入Mixin参数mixins Mixin()
*/
type IMixin4Legacy<
Data extends UnknownRecord,
Props extends UnknownRecord,
Methods extends UnknownRecord,
ExtraThis extends UnknownRecord = UnknownRecord,
ExtraOptions extends UnknownRecord = UnknownRecord
> = Partial<
MiniProgram.Component.IOptions<Data, Props, Methods, ExtraOptions, []>
> &
ThisType<
MiniProgram.Component.IInstance<
Data,
Props,
Methods,
ExtraThis & IGlobalMiniProgramExtraThis4Component,
ExtraOptions,
[]
>
>;
/**
* Mixin()
*/
type IMixinIdentifier = string;
type IMixinDefinitionFilter = <
T extends
| Component.IOptions<any, any, any, any, any>
| IMixinOptions<any, any, any, any, any, any>
| Page.IOptions<any, any>
>(
/** 使用该 mixin 的 component/mixin 的定义对象 */
defFields: T,
/** 该 mixin 所使用的 mixin 的 definitionFilter 函数列表 */
definitionFilterArr?: IMixinDefinitionFilter[] | void
) => void;
/**
* Mixin构造器参数
*/
type IMixinOptions<
Data,
Props,
Methods,
ExtraThis,
ExtraOptions extends UnknownRecord,
Mixins extends Array<ReturnType<Constructor>>
> = {
[P in keyof ExtraOptions]: P extends
| keyof Component.IOptions<Data, Props, Methods, ExtraOptions, Mixins>
| 'definitionFilter'
| 'mixins'
? unknown
: ExtraOptions[P];
} & Omit<
Partial<
Component.IOptions<Data, Props, Methods, ExtraOptions, IMixinIdentifier[]>
>,
'ref' | 'options' | 'externalClasses'
> &
Partial<{
/**
*
*/
definitionFilter: IMixinDefinitionFilter;
/**
* Mixin()mixins Mixin() js Object
*/
mixins: Mixins;
}> &
ThisType<
Component.IInstance<
Data,
Props,
Methods,
ExtraThis,
ExtraOptions,
IMixinIdentifier[]
>
>;
interface Constructor {
<
Data = UnknownRecord,
Props = UnknownRecord,
Methods = UnknownRecord,
ExtraThis = UnknownRecord,
ExtraOptions extends UnknownRecord = UnknownRecord,
Mixins extends IMixinIdentifier[] = []
>(
options: IMixinOptions<
Data,
Props,
Methods,
ExtraThis & IGlobalMiniProgramExtraThis4Component,
ExtraOptions,
Mixins
>
): IMixinIdentifier;
}
}

View File

@ -0,0 +1,406 @@
declare namespace MiniProgram.Page {
interface IOnResizeEvent {
/**
*
*/
size: {
/**
*
*/
windowWidth: number;
/**
*
*/
windowHeight: number;
};
}
interface IKeyboardHeightEvent {
/**
*
*/
height: number;
}
interface ITabItemTapEvent {
/**
*
*/
from: string;
/**
* tabItem
*/
pagePath: string;
/**
* tabItem
*/
text: string;
/**
* tabItem 0
*/
index: number;
}
interface ISelectedTabItemTapEvent {
/**
* tabItem
*/
pagePath: string;
/**
* tabItem
*/
text: string;
/**
* tabItem 0
*/
index: number;
}
interface IPageScrollEvent {
/**
*
*/
scrollTop: number;
/**
*
*/
scrollHeight: number;
}
interface IPullDownRefreshEvent {
/**
*
* @description
* - manual: 下拉事件通过 my.startPullDownRefresh
* - code: 下拉事件用通过户下拉触发
*/
from: 'manual' | 'code';
}
interface IShareAppMessageEvent {
/**
*
* @description
* - button
* - menu
* - code my.showSharePanel
* @version 1.10.0
*/
from: 'button' | 'menu' | 'code';
/**
* from button target button undefined
* @version 1.10.0
*/
target: object;
/**
* web-view web-view URL
* @version 1.6.0
*/
webViewUrl: string;
}
interface IShareAppMessage {
title: string;
desc: string;
path: string;
}
/**
*
*/
interface Events {
/**
*
* @param query
* @see https://opendocs.alipay.com/mini/03durs
*/
onLoad(query: unknown): void;
/**
* /
*/
onShow(): void;
/**
*
*/
onReady(): void;
/**
* /
*/
onHide(): void;
/**
*
* @version 2.8.5
*/
onUnload(): void;
/**
*
*/
onTitleClick(): void;
/**
*
* @see 设置额外图标: https://opendocs.alipay.com/mini/api/optionmenu
*/
onOptionMenuClick(): void;
/**
*
* @description app.json window pullRefresh my.stopPullDownRefresh
* @param event
* @see https://opendocs.alipay.com/mini/framework/page-detail#onPullDownRefresh(%7Bfrom%3A%20manual%7Ccode%7D)
*/
onPullDownRefresh(event: IPullDownRefreshEvent): void;
/**
* tabItem
* @param event tabItem
*/
onTabItemTap: (event: ITabItemTapEvent) => void;
/**
*
* @param event
*/
onPageScroll: (event: IPageScrollEvent) => void;
/**
*
* @description
* - onReachBottom()
* - my.pageScrollTo onReachBottom()
* - app.json onReachBottomDistance px
*/
onReachBottom(): void;
/**
* tabItem
*/
beforeTabItemTap(): void;
/**
*
* @param event
*/
onKeyboardHeight(event: IKeyboardHeightEvent): void;
/**
* ( Android
*/
onBack: () => void;
/**
* window尺寸改变时触发
* @version 1.16.0
*/
onResize(event: IOnResizeEvent): void;
/**
* tabItem
* @param event tabItem
* @version 2.7.2
*/
onSelectedTabItemTap: (event: ISelectedTabItemTapEvent) => void;
}
/**
* pages\/*\/index.js Page(options) options
* ref: https://opendocs.alipay.com/mini/framework/app-detail
*/
interface IOptions<Data, ExtraOptions extends UnknownRecord> {
/**
*
*/
data: Data | ((this: void) => Data);
/**
*
* @param query
* @see https://opendocs.alipay.com/mini/03durs
*/
onLoad(query: unknown): void;
/**
* /
*/
onShow(): void;
/**
*
*/
onReady(): void;
/**
* /
*/
onHide(): void;
/**
*
*/
onUnload(): void;
/**
* Page onShareAppMessage
* @description
* QQ
* - Page
* -
* - Object使
* - Object
* - 60 > > >
* - 1.1.0 open-type share
* - 1.24.132.6.7 async my.canIUse('page.onShareAppMessage.async')
* @see https://opendocs.alipay.com/mini/framework/page-detail#onShareAppMessage(options%3A%20Object)
*/
onShareAppMessage(
event: IShareAppMessageEvent
): IShareAppMessage | Promise<IShareAppMessage>;
/**
*
*/
onTitleClick(): void;
/**
*
* @see 设置额外图标: https://opendocs.alipay.com/mini/api/optionmenu
* @version 1.3.0
*/
onOptionMenuClick: () => void;
/**
*
* @description app.json window pullRefresh my.stopPullDownRefresh
* @param event
* @see https://opendocs.alipay.com/mini/framework/page-detail#onPullDownRefresh(%7Bfrom%3A%20manual%7Ccode%7D)
*/
onPullDownRefresh(event: IPullDownRefreshEvent): void;
/**
* tabItem
* @param event tabItem
* @version 1.11.0
*/
onTabItemTap: (event: ITabItemTapEvent) => void;
/**
*
* @param event
*/
onPageScroll: (event: IPageScrollEvent) => void;
/**
*
* @description
* - onReachBottom()
* - my.pageScrollTo onReachBottom()
* - app.json onReachBottomDistance px
*/
onReachBottom(): void;
/**
*
* @version 1.13.7
*/
events: Partial<Events>;
/**
*
*/
options: {
/**
* observers
*/
observers: boolean;
};
/**
*
* @version 2.8.1
*/
observers: Record<string, (...args: any[]) => void>;
/**
* Mixin()
* @version 2.8.5
*/
mixins: Mixin.IMixinIdentifier[];
}
/**
* Additional properties in Page instance, for module augmentation
*/
interface IInstanceAdditionalProperties<ExtraOptions> {}
interface IInstanceProperties {
/**
* Page app.json String
* @readonly
*/
readonly route: string;
/**
*
* @description
* @version 2.7.22
*/
readonly router: Shared.IRouter;
/**
*
* @description router,
* @version 2.7.22
*/
readonly pageRouter: Shared.IRouter;
}
type IInstanceSharedMethods<Data> = Shared.IInstanceSharedMethods<Data>;
interface IInstanceMethods<Data> {
/**
*
* @param data
* @param callback
*/
setData(
data: RecursivePartialAndDynamic<Data>,
callback?: () => void
): void;
/**
* $spliceData setData
* @param data
* @param callback
* @version 1.7.2+ 使 my.canIUse('page.$spliceData')
*/
$spliceData(
data: RecursivePartialAndDynamic<Data>,
callback?: () => void
): void;
/**
*
* @param callback
* @version 1.14.0+ 使 my.canIUse('page.$batchedUpdates')
*/
$batchedUpdates(callback: () => void): void;
/**
* EventChannel
* @description
* - my.navigateTo
* - this.getOpenerEventChannel() EventChannel
* - my.navigateTo success EventChannel
* - EventChannel 使 emit on
* @version 2.7.7
* @see https://opendocs.alipay.com/mini/api/eventchannel
*/
getOpenerEventChannel(): Shared.EventChannel;
/**
* mixin(Mixin()mixin实例)
* @version 2.8.5
* @return boolean
* @see https://opendocs.alipay.com/mini/framework/page-detail#hasMixin
*/
hasMixin(mixin: Mixin.IMixinIdentifier): boolean;
}
/**
* `this` type of life cycle hooks in App.
*/
type IInstance<Data, ExtraThis, ExtraOptions extends UnknownRecord> = {
data: Data & UnknownRecord;
} & ExtraThis &
Omit<ExtraOptions, keyof IOptions<Data, ExtraOptions>> &
IInstanceProperties &
IInstanceSharedMethods<Data> &
IInstanceMethods<Data> &
IInstanceAdditionalProperties<ExtraOptions>;
interface Constructor {
<
Data = {},
ExtraThis = {},
ExtraOptions extends Record<string, unknown> = {}
>(
options: Partial<
UniqueLeft<
UniqueLeft<ExtraThis, ExtraOptions>,
IOptions<Data, ExtraOptions>
>
> & {
[P in keyof ExtraOptions]: P extends keyof IOptions<Data, ExtraOptions>
? unknown
: ExtraOptions[P];
} & Partial<IOptions<Data, ExtraOptions>> &
ThisType<IInstance<Data, ExtraThis, ExtraOptions>>
): void;
}
interface GetCurrentPages {
(): Array<IInstance<object, {}, {}>>;
}
}

View File

@ -0,0 +1,309 @@
declare namespace MiniProgram.Shared {
interface SetUpdatePerformanceListenerOption<WithDataPath extends boolean> {
/**
* data
*/
withDataPaths?: WithDataPath;
}
interface UpdatePerformanceListener<WithDataPath extends boolean> {
(res: ISetUpdatePerformanceListenerResult<WithDataPath>): void;
}
interface ISingleSetDataPerformanceInfo<WithDataPath extends boolean> {
/** setData ID */
id: number;
/** 加入到队列的时间 */
pendingStartTimestamp: number;
/** 本次更新的 data所包含的 key 值 */
dataPaths?: WithDataPath extends true ? string[] : undefined;
}
interface ISetUpdatePerformanceListenerResult<WithDataPath extends boolean> {
/** 其他组件更新,而导致的更新 */
isMergedUpdate: boolean;
/** 更新批次 ID */
updateProcessId: number;
/** 父更新批次 ID */
parentUpdateProcessId?: number;
/**
* data key
*/
dataPaths?: WithDataPath extends true ? string[] : undefined;
/** 组件第一条数据,加入到队列的时间 */
pendingStartTimestamp?: number;
/** render 侧接收到data 数据的时间 */
updateStartTimestamp?: number;
/** render 侧完成 UI 更新的时间 */
updateEndTimestamp?: number;
/**
* setData
*/
dataList: ISingleSetDataPerformanceInfo<WithDataPath>[];
}
interface IMediaQueryObserver {
/**
* media query
* @param descriptor media query
* @param callback media query
* @see https://opendocs.alipay.com/mini/05awpq
*/
observe: (
descriptor: IMediaQueryObserveDescriptor,
callback: IMediaQueryObserveCallback
) => void;
/**
*
* @see https://opendocs.alipay.com/mini/05bb9o
*/
disconnect: () => void;
}
type IMediaQueryObserveCallback = (
payload: IMediaQueryObserveCallbackResponse
) => void;
interface IMediaQueryObserveCallbackResponse {
/**
* media query
*/
matches: boolean;
}
interface IMediaQueryObserveDescriptor {
/**
* px
*/
minWidth?: number;
/**
* px
*/
maxWidth?: number;
/**
* px
*/
width?: number;
/**
* px
*/
minHeight?: number;
/**
* px
*/
maxHeight?: number;
/**
* px
*/
height?: number;
/**
* landscape portrait
* - landscape viewport
* - portrait viewport
*/
orientation?: 'landscape' | 'portrait';
}
interface IRouter {
navigateTo: (object: {
/**
*
* @description , tabbar 使 ?=&
*/
url: string;
/**
*
*/
events?: IMyNavigateToEvents;
/**
*
*/
success?(data: {
/**
*
*/
eventChannel: EventChannel;
}): void;
/**
*
*/
fail?(err: { error?: number; errorMessage?: string }): void;
/**
*
*/
complete?(
arg:
| {
/**
*
*/
eventChannel: EventChannel;
}
| {
error?: number;
errorMessage?: string;
}
): void;
}) => Promise<{
/**
*
*/
eventChannel: EventChannel;
}>;
redirectTo: (object: {
/**
*
* , tabbar 使 ?=&
*/
url: string;
/**
*
*/
success?(data: {}): void;
/**
*
*/
fail?(err: { error?: number; errorMessage?: string }): void;
/**
*
*/
complete?(arg: { error?: number; errorMessage?: string }): void;
}) => Promise<void>;
navigateBack: (object?: {
/**
*
* @description delta
* @default 1
*/
delta?: number | string;
/**
*
*/
success?(data: {}): void;
/**
*
*/
fail?(err: { error?: number; errorMessage?: string }): void;
/**
*
*/
complete?(arg: { error?: number; errorMessage?: string }): void;
}) => Promise<void>;
switchTab: (object: {
/**
* tab
* @description tabbar
*/
url: string;
/**
*
*/
success?(data: {}): void;
/**
*
*/
fail?(err: { error?: number; errorMessage?: string }): void;
/**
*
*/
complete?(arg: { error?: number; errorMessage?: string }): void;
}) => Promise<void>;
reLaunch: (object: {
/**
*
* @description
* Tab
* Tab 使 `?` `=` `&`
*/
url: string;
/**
*
*/
success?(data: {}): void;
/**
*
*/
fail?(err: { error?: number; errorMessage?: string }): void;
/**
*
*/
complete?(arg: { error?: number; errorMessage?: string }): void;
}) => Promise<void>;
}
interface IMyNavigateToEvents {
/**
*
*/
[eventName: string]: (...args: unknown[]) => void;
}
interface EventChannel {
/**
*
* @see https://opendocs.alipay.com/mini/api/eventchannel.emit
*/
emit(eventName: string, args?: unknown): void;
/**
*
* @see https://opendocs.alipay.com/mini/api/eventchannel.off
*/
off(eventName: string, callback: (...args: unknown[]) => void): void;
/**
*
* @see https://opendocs.alipay.com/mini/api/eventchannel.on
*/
on(eventName: string, callback: (...args: unknown[]) => void): void;
/**
*
* @description
* @see https://opendocs.alipay.com/mini/api/eventchannel.once
*/
once(eventName: string, callback: (...args: unknown[]) => void): void;
}
interface IInstanceSharedMethods<Data> {
/**
* SelectorQuery
* @version 2.7.4
*/
createSelectorQuery(): any;
/**
* IntersectionObserver
* @version 2.7.4
*/
createIntersectionObserver(): any;
/**
* MediaQueryObserver media query
* @version 2.8.2
* @see https://opendocs.alipay.com/mini/framework/component_object#createMediaQueryObserver
*/
createMediaQueryObserver(): IMediaQueryObserver;
/**
* tabBar `this.getTabBar`
* @version 2.7.20
* @see https://opendocs.alipay.com/mini/framework/page-detail#Page.getTabBar
*/
getTabBar<T extends any = Component.BaseInstance>(): T | undefined;
/**
*
* @description selector ref
* @version 2.8.0
* @see https://opendocs.alipay.com/mini/framework/component_object#%24selectComponent%2F%24selectAllComponents
*/
$selectComponent(selector: string): Component.BaseInstance | void;
/**
*
* @description selector ref
* @version 2.8.0
* @see https://opendocs.alipay.com/mini/framework/component_object#%24selectComponent%2F%24selectAllComponents
*/
$selectAllComponents(selector: string): Component.BaseInstance[];
/**
* setData
* @version 2.8.5
* @see https://opendocs.alipay.com/mini/069xfk
*/
setUpdatePerformanceListener<WithDataPath extends boolean = false>(
option: SetUpdatePerformanceListenerOption<WithDataPath>,
callback?: UpdatePerformanceListener<WithDataPath>
): void;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

21
甲情_甲意/node_modules/@mini-types/my/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT LICENSE
Copyright (c) 2018-present Alipay.com, https://www.alipay.com/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION

26
甲情_甲意/node_modules/@mini-types/my/package.json generated vendored Normal file
View File

@ -0,0 +1,26 @@
{
"name": "@mini-types/my",
"version": "3.0.14",
"description": "TypeScript declarations for Alipay's mini program.",
"scripts": {},
"miniprogram": "./",
"repository": {
"type": "git",
"url": "git@github.com:ant-mini-program/api-typings.git"
},
"keywords": [
"tinyapp",
"miniprogram",
"types"
],
"license": "MIT",
"types": "./types/index.d.ts",
"files": [
"types"
],
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"gitHead": "f923cf356c26bf6c80ca640951683ba777d968f8"
}

View File

@ -0,0 +1,2 @@
///<reference path='./lib.my.d.ts' />
///<reference path='./lib.my.extra.d.ts' />

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
declare namespace my {
/**
* @description
* @param name JSAPI
* @param opt JSAPI
* @param callback
*/
export function call(
name: string,
opt: any,
callback: (resp: any) => void
): void;
/**
* @description
* @param name JSAPI
* @param callback
*/
export function call(name: string, callback: (resp: any) => void): void;
/**
* @description Promise
* @param name JSAPI
* @param opt JSAPI
*/
export function call(name: string, opt?: any): Promise<any>;
/**
* @param eventName
* @param callback
*/
export function on(
eventName: string,
callback: (...args: any) => any
): {
/**
* @description
*/
remove: () => void;
};
/**
* @param eventName
* @param callback
*/
export function off(eventName: string, callback: (...args: any) => any): void;
export function canIUse(name: string): boolean;
}

21
甲情_甲意/node_modules/antd-mini/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Ant Design Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

21
甲情_甲意/node_modules/antd-mini/README.md generated vendored Normal file
View File

@ -0,0 +1,21 @@
<img src="https://gw.alipayobjects.com/zos/bmw-prod/0350261f-bac2-443d-9580-d25f3365a26e.svg" alt="logo" width="100%" />
![npm (tag)](https://img.shields.io/npm/v/antd-mini)
&nbsp;
![npm](https://img.shields.io/npm/dw/antd-mini)
&nbsp;
![GitHub](https://img.shields.io/github/license/ant-design/ant-design-mini)
```bash
$ npm i antd-mini -S
```
antd-mini 是支付宝小程序 UI 组件库,遵循 Ant Design 规范。你可以扫描下方的支付宝二维码体验,或者访问[官网](https://mini.ant.design/)以获取更多信息。
<img src="https://mdn.alipayobjects.com/huamei_jlgevq/afts/img/A*2ZAZR7NQQJ4AAAAAAAAAAAAADtSSAQ/original" alt="logo" width="220" />
如果你发现了 bug 或者是希望 antd-mini 增加一些特性,可以[提交 issue](https://github.com/ant-design/ant-design-mini/issues)。也欢迎参与共建,这里有一份[贡献指南](/docs/guide/contribute.md)。
如果你想深入参与讨论可以加入我们的社区钉钉群62730003177
<img src="https://mdn.alipayobjects.com/huamei_trbi3h/afts/img/A*UMWdT5yaPqsAAAAAAAAAAAAADpDJAQ/original" width="220" alt="dingding" />

View File

@ -0,0 +1,14 @@
import { Component, triggerEventOnly, triggerEventValues } from '../_util/simply';
import { ActionSheetDefaultProps } from './props';
Component(ActionSheetDefaultProps, {
onAction: function (e) {
var _a = e.currentTarget.dataset, item = _a.item, index = _a.index;
if (item === null || item === void 0 ? void 0 : item.disabled)
return;
triggerEventOnly(this, 'close', e);
triggerEventValues(this, 'action', [item, index], e);
},
onClose: function (e) {
triggerEventOnly(this, 'close', e);
}
});

View File

@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"ant-popup": "../Popup/index"
}
}

View File

@ -0,0 +1,45 @@
---
nav:
path: /components
group:
title: 反馈
order: 12
toc: 'content'
---
# ActionSheet 动作面板
<code src="../../docs/components/compatibility.tsx" inline="true"></code>
从底部弹出的动作菜单面板。
## 何时使用
由用户操作触发,提供一组与操作相关的两个或多个选项,让用户在不离场的情况下完成操作。相比于对话框,动作面板的位置更适合于在大屏幕时代单手操作的场景。
## 代码示例
<code src='pages/ActionSheet/index'></code>
## API
| 属性 | 说明 | 类型 | 默认值 |
| ---------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| actions | 面板选项列表 | `[ActionSheetItem](#actionshetitem)`[] | [] |
| cancelText | 取消按钮文字 | string | 取消 |
| className | 类名 | string | - |
| style | 样式 | string | - |
| title | 标题 | string | - |
| visible | 是否展开 | boolean | false |
| zIndex | 弹窗层级 | number | 998 |
| onClose | 关闭时触发 | `(event: [Event](https://opendocs.alipay.com/mini/framework/event-object))` => void | - |
| onAction | 点击选项时触发,禁用状态下不会触发 | `(item: [ActionSheetItem](#actionsheetitem), index: number, event: [Event](https://opendocs.alipay.com/mini/framework/event-object))` => void | - |
### ActionSheetItem
| 属性 | 说明 | 类型 | 默认值 |
| ----------- | ------------ | ------- | ------ |
| icon | 图标 | - | - |
| danger | 是否危险模式 | boolean | false |
| description | 描述 | string | - |
| disabled | 是否禁用 | boolean | false |

View File

@ -0,0 +1,57 @@
<wxs
src="./index.wxs"
module="helper"
></wxs>
<ant-popup
className="ant-actionsheet-popup"
visible="{{visible}}"
position="bottom"
zIndex="{{zIndex}}"
bind:close="onClose"
>
<view
style="{{style}}"
class="ant-actionsheet {{className ? className : ''}} {{helper.isIconMode(actions) ? 'ant-actionsheet-icon' : ''}}"
>
<view
wx:if="{{title}}"
class="ant-actionsheet-title-wrap"
>
<view class="ant-actionsheet-title-content">{{title}}</view>
</view>
<view class="ant-actionsheet-list">
<block
wx:for="{{actions}}"
wx:for-index="index"
wx:for-item="item"
key="{{index}}"
>
<view
class="ant-actionsheet-list-item {{item.disabled ? 'ant-actionsheet-list-item-disabled' : ''}}"
hoverClass="{{item.disabled ? '' : 'ant-actionsheet-list-item-active'}}"
bind:tap="onAction"
data-index="{{index}}"
data-item="{{item}}"
>
<view
wx:if="{{helper.isIconMode(actions)}}"
class="ant-actionsheet-list-item-icon"
style="background-image: url('{{item.icon}}')"
></view>
<view class="ant-actionsheet-list-item-content">
<view class="ant-actionsheet-list-item-title {{item.danger ? 'ant-actionsheet-list-item-title-danger' : ''}}">{{item.text}}</view>
<view
wx:if="{{item.description}}"
class="ant-actionsheet-list-item-description"
>{{item.description}}</view>
</view>
</view>
</block>
</view>
<view class="ant-actionsheet-cancel-gap"></view>
<view
class="ant-actionsheet-cancel"
bind:tap="onClose"
>{{cancelText}}</view>
</view>
</ant-popup>

View File

@ -0,0 +1,8 @@
function isIconMode(actions) {
return actions.some(function (action) {
return !!action.icon;
});
}
module.exports = {
isIconMode: isIconMode
};

View File

@ -0,0 +1,105 @@
.ant-actionsheet {
padding-left: 12px;
padding-right: 12px;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
.ant-actionsheet-title-wrap {
text-align: center;
position: relative;
margin: 0 -12px;
}
.ant-actionsheet-title-content {
display: inline-block;
text-align: left;
padding: 18px 15px;
font-size: 15px;
color: #999999;
}
.ant-actionsheet-title-content::after {
content: '';
position: absolute;
background-color: #eeeeee;
display: block;
top: auto;
right: 0;
bottom: 0;
left: 0;
height: 1px;
transform: scaleY(0.5);
}
.ant-actionsheet-list {
margin: 0 -12px;
}
.ant-actionsheet-list-item {
color: #333333;
padding: 16px 15px;
text-align: center;
position: relative;
font-size: 18px;
}
.ant-actionsheet-list-item::after {
content: '';
position: absolute;
background-color: #eeeeee;
display: block;
top: auto;
right: 0;
bottom: 0;
left: 0;
height: 1px;
transform: scaleY(0.5);
}
.ant-actionsheet-list-item-title-danger {
color: #ff3141;
font-weight: bold;
}
.ant-actionsheet-list-item-description {
color: #999999;
font-size: 14px;
line-height: 20px;
margin-top: 4px;
}
.ant-actionsheet-list-item-active {
background-color: #eeeeee;
}
.ant-actionsheet-list-item:last-child.ant-actionsheet-list-item:last-child:after {
display: none;
}
.ant-actionsheet-list-item-disabled .ant-actionsheet-list-item-icon,
.ant-actionsheet-list-item-disabled .ant-actionsheet-list-item-content {
opacity: 0.4;
}
.ant-actionsheet-cancel-gap {
height: 8px;
background: #f5f5f5;
margin: 0 -12px;
}
.ant-actionsheet-cancel {
color: #333333;
padding: 16px 15px;
font-size: 18px;
text-align: center;
margin: 0 -12px;
}
.ant-actionsheet-cancel:active {
background-color: #eeeeee;
}
.ant-actionsheet-icon .ant-actionsheet-title-wrap {
text-align: left;
}
.ant-actionsheet-icon .ant-actionsheet-list-item {
display: flex;
align-items: center;
}
.ant-actionsheet-icon .ant-actionsheet-list-item-icon {
height: 24px;
flex: 0 0 24px;
margin-right: 12px;
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
}
.ant-actionsheet-icon .ant-actionsheet-list-item-content {
text-align: left;
}

View File

@ -0,0 +1,8 @@
export var ActionSheetDefaultProps = {
title: '',
actions: [],
cancelText: '取消',
visible: false,
// 弹窗层级
zIndex: 998,
};

View File

@ -0,0 +1,4 @@
import '../_util/assert-component2';
import { Component } from '../_util/simply';
import { AvatarDefaultProps } from './props';
Component(AvatarDefaultProps);

View File

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

View File

@ -0,0 +1,31 @@
---
nav:
path: /components
group:
title: 信息展示
order: 8
toc: content
---
# Avatar 头像
<code src="../../docs/components/compatibility.tsx" inline="true"></code>
用来代表用户或事物。
## 何时使用
需要更加直观地展现人物或事物特征时。
## 代码示例
<code src='pages/Avatar/index'></code>
## API
| 属性 | 说明 | 类型 | 默认值 |
|---------|----------|------|-----------|
| className | 类名 | string | - |
| size | 大小,可选 `x-small`、`small`、`medium`、`large` | string | `medium` |
| src | 头像地址 | string | 灰色的内置图片 |
| style | 样式 | string | - |

View File

@ -0,0 +1,13 @@
<wxs
src="./index.wxs"
module="utils"
></wxs>
<view
class="ant-avatar {{className ? className : ''}}"
style="{{style}}"
>
<image
class="ant-avatar-image {{utils.getClass(size)}}"
src="{{src || utils.defaultSrc}}"
></image>
</view>

View File

@ -0,0 +1,12 @@
function getClass(size) {
var list = ['x-small', 'small', 'medium', 'large'];
if (list.indexOf(size) >= 0) {
return "ant-avatar-image-".concat(size);
}
return 'ant-avatar-image-medium';
}
var defaultSrc = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTIwcHgiIGhlaWdodD0iMTIwcHgiIHZpZXdCb3g9IjAgMCAxMjAgMTIwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPHRpdGxlPuS/oeaBr+Wxleekujo0MC/lpLTlg49BdmF0YXIv5Y2V5Zu+OjEv5bC65a+4OuWkpzwvdGl0bGU+CiAgICA8ZGVmcz4KICAgICAgICA8cGF0aCBkPSJNOCwwIEwxMTIsMCBDMTE2LjQxODI3OCwtOC4xMTYyNDUwMWUtMTYgMTIwLDMuNTgxNzIyIDEyMCw4IEwxMjAsMTEyIEMxMjAsMTE2LjQxODI3OCAxMTYuNDE4Mjc4LDEyMCAxMTIsMTIwIEw4LDEyMCBDMy41ODE3MjIsMTIwIDUuNDEwODMwMDFlLTE2LDExNi40MTgyNzggMCwxMTIgTDAsOCBDLTUuNDEwODMwMDFlLTE2LDMuNTgxNzIyIDMuNTgxNzIyLDguMTE2MjQ1MDFlLTE2IDgsMCBaIiBpZD0icGF0aC0xIj48L3BhdGg+CiAgICA8L2RlZnM+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0i5aS05YOPIj4KICAgICAgICAgICAgPG1hc2sgaWQ9Im1hc2stMiIgZmlsbD0id2hpdGUiPgogICAgICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgPC9tYXNrPgogICAgICAgICAgICA8dXNlIGlkPSJNYXNrIiBmaWxsPSIjRUVFRUVFIiBmaWxsLXJ1bGU9Im5vbnplcm8iIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPgogICAgICAgICAgICA8cGF0aCBkPSJNNjAuNzc4Mjk5MywyMS44MTgxODE4IEw1OS4yMjE2NTIzLDIxLjgxODE4MTggTDU4LjU3ODQzNTksMjEuODI5OTY0MSBMNTguNTc4NDM1NywyMS44Mjk5NjQxIEM0OS44MDIxNTI3LDIyLjE3NDgzNiA0Mi44NjQ3OTEzLDI5LjQxMDY0NyA0Mi44NjUyMDQzLDM4LjIxOTE2MzMgTDQyLjg2NTIwNDMsNDcuNDI0MDc1MSBMNDIuODg1NzYzNyw0OC4yMzQxMDc0IEw0Mi44ODU3NjI3LDQ4LjIzNDA4NTYgQzQzLjA5MDQ4MjMsNTIuNTUwMjgwNCA0NC45MjExODc0LDU2LjYyNzYzNTUgNDguMDA3OTc5LDU5LjY0MjI3OTQgTDUyLjExMTA1ODEsNjMuNjUxMjA1MiBMNTIuMzc1MzkzNiw2My45NDI4MTY3IEM1Mi44NzQ2OTQ0LDY0LjU1MjU0OTcgNTMuMTQ3ODQxMSw2NS4zMTgzOTg0IDUzLjE0Nzg0MTEsNjYuMTEzNzA2NiBMNTMuMTQ3ODQxMSw2Ni42NzMzNjQ1IEw1My4xMjE0MDc2LDY3LjA3NjkwODEgTDUzLjEyMTQwNzYsNjcuMDc2OTA3OSBDNTIuOTg3ODc0NSw2OC4xNTYyNzIxIDUyLjMzMDE4ODEsNjkuMDk5MzI3MyA1MS4zNjUwNDk2LDY5LjU5NTM3MDUgTDI1LjU1MTE3Myw4Mi44MzI3NjM1IEwyNS4xMDQ3MzkzLDgzLjA4MzEzNjUgTDI1LjEwNDczOTUsODMuMDgzMTM2NCBDMjMuMDY0NzcxNSw4NC4zMjk4MTQgMjEuODE5NDYyMiw4Ni41NTIwMDEgMjEuODE4MTgxOCw4OC45NDc3ODUyIEwyMS44MTgxODE4LDkwLjA5NjU1NzcgTDIxLjgzNTgwNDIsOTAuNTM4MzkzMiBDMjIuMDU5MDIwNCw5My4yODk1NTEzIDI0LjM1NTgwMjcsOTUuNDU0NTQ1NSAyNy4xNTc3NTksOTUuNDU0NTQ1NSBMOTIuODQyMjQxLDk1LjQ1NDU0NTUgTDkyLjg0MjI0MSw5NS40NTQ1NDU1IEM5NS43OTAwNjM3LDk1LjQ1NDU0NTUgOTguMTgwMTkzNiw5My4wNTg4MDI3IDk4LjE4MTgxODIsOTAuMTAyNDM5NiBMOTguMTgxODE4Miw4OC45NTM2NjcyIEM5OC4xODE4MTgyLDg2LjM3MDQwNjYgOTYuNzQyNjYyOCw4NC4wMDUxMDkxIDk0LjQ0ODgwODgsODIuODMyNzY3NSBMNjguNjM0OTMyMyw2OS41OTUzNzQ1IEw2OC42MzQ5MzIsNjkuNTk1Mzc0NCBDNjcuNTM5NzExNSw2OS4wMzM5NjU3IDY2Ljg1MDk3MDIsNjcuOTAzOTcyNyA2Ni44NTIxNDA0LDY2LjY3MDQyMyBMNjYuODUyMTQwNCw2Ni4xMTA3NjUxIEM2Ni44NTIxNDA0LDY1LjE4NTg1NTYgNjcuMjI4MDg0Nyw2NC4yOTkyMzk0IDY3Ljg4ODkyMzUsNjMuNjUxMjE4NSBMNzEuOTkyMDAyNSw1OS42NDIyOTI3IEw3MS45OTIwMDI5LDU5LjY0MjI5MjQgQzc1LjI3ODYwMTksNTYuNDMxNjgwNiA3Ny4xMzIxODU3LDUyLjAyNTQyMDQgNzcuMTMxODU1Myw0Ny40MjQwNjIyIEw3Ny4xMzE4NTUzLDM4LjIxOTE1MDQgTDc3LjEzMTg1NTMsMzguMjE5MTUxIEM3Ny4xMzE4NTUzLDI5LjE2MTE2MzMgNjkuODEwMTE5OCwyMS44MTgxODE4IDYwLjc3ODI5ODcsMjEuODE4MTgxOCBMNjAuNzc4Mjk5MywyMS44MTgxODE4IFoiIGlkPSLlvaLnirYiIGZpbGw9IiNDQ0NDQ0MiIGZpbGwtcnVsZT0ibm9uemVybyIgbWFzaz0idXJsKCNtYXNrLTIpIj48L3BhdGg+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=';
module.exports = {
getClass: getClass,
defaultSrc: defaultSrc
};

View File

@ -0,0 +1,28 @@
.ant-avatar {
display: inline-flex;
align-items: center;
}
.ant-avatar-image {
width: 52px;
height: 52px;
border-radius: 4px;
}
.ant-avatar-image-x-small {
width: 40px;
height: 40px;
}
.ant-avatar-image-small {
width: 44px;
height: 44px;
}
.ant-avatar-image-medium {
width: 52px;
height: 52px;
}
.ant-avatar-image-large {
width: 60px;
height: 60px;
}
.ant-avatar-circle {
border-radius: 100vh;
}

View File

@ -0,0 +1,4 @@
export var AvatarDefaultProps = {
size: 'medium',
src: '',
};

View File

@ -0,0 +1,3 @@
import { Component } from '../_util/simply';
import { BadgeFunctionalProps } from './props';
Component(BadgeFunctionalProps);

View File

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

View File

@ -0,0 +1,34 @@
---
nav:
path: /components
group:
title: 引导提示
order: 14
toc: 'content'
---
# Badge 徽标
<code src="../../docs/components/compatibility.tsx" inline="true"></code>
徽标,显示红点、数字或文字。用于提醒用户,有待处理的事项或者新的更新数量。
## 何时使用
当需要在右上角展示数字、文字或小红点时使用。适合于提示产品化的新消息、功能或服务等内容,通过显眼的视觉形式吸引用户注意,并促使其进行相关操作。
## 代码示例
<code src="pages/Badge/index"></code>
## API
| 属性 | 说明 | 类型 | 默认值 |
| --------- | ------------------------------------ | -------------------- | ------------ |
| bgColor | 自定义背景色CSS 色值 | string | - |
| className | 组件根节点的类名 | string | - |
| offsetX | 水平方向偏移量 | string | '-50%' |
| offsetY | 垂直方向的偏移量 | string | '-50%' |
| position | 徽标相对于容器的位置,选项包括:`top-left`、`top-right`、`top-center`、`left`、`right`、`bottom-left`、`bottom-center` 和 `bottom-right` | string | `top-right` |
| stroke | 徽标是否带有描边 | boolean | false |
| style | 自定义样式 | object | - |
| text | 徽标内容,为空代表仅展示红点;可以是数字或文字;若是数字且超过 99则显示为 `...` | string \| number \| slot | - |
| type | 徽标类型,选项包括:`dot`(红点)、`number`(数字类型,超过 99 会自动转换)、`text`(文字气泡)和 `bubble`(气泡形态,带有箭头) | string | `dot` |

View File

@ -0,0 +1,54 @@
<wxs
src="./index.wxs"
module="_sjs"
></wxs>
<view
class="ant-badge {{className || ''}}"
style="{{style}}"
>
<view class="ant-badge-body">
<slot></slot>
</view>
<view
wx:if="{{type === 'dot'}}"
class="ant-badge-content"
style="{{_sjs.setPositionStyle(position, offsetX, offsetY)}}"
>
<view
class="ant-badge-dot {{stroke ? 'ant-badge-dot-stroke' : ''}}"
style="{{bgColor ? 'background-color: ' + bgColor + ';' : ''}}"
></view>
</view>
<view
wx:else
class="ant-badge-content ant-badge-content-not-dot {{type === 'bubble' ? 'ant-badge-content-' + position + '-bubble' : ''}} {{stroke ? 'ant-badge-content-stroke' : ''}}"
style="{{bgColor ? 'background-color: ' + bgColor + ';' : ''}} {{_sjs.setBubbleStyle(type, position)}};{{_sjs.setPositionStyle(position, offsetX, offsetY)}}"
>
<view class="ant-badge-icon-container"></view>
<view class="ant-badge-content-text">
<slot
name="text"
wx:if="{{!text}}"
></slot>
<block wx:if="{{text}}">
<view
wx:if="{{type === 'number'}}"
class="ant-badge-number"
>
<!--display: inline-->
<text wx:if="{{_sjs.getOverCount(text)}}">99+</text>
<!--display: inline-->
<text wx:else>{{text}}</text>
</view>
<view
wx:if="{{type === 'text'}}"
class="ant-badge-text"
>{{text}}</view>
<view
wx:if="{{type === 'bubble'}}"
class="ant-badge-bubble"
>{{text}}</view>
</block>
</view>
</view>
</view>

View File

@ -0,0 +1,54 @@
function setPositionStyle(position) {
var offsetX = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '-50%';
var offsetY = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '-50%';
var transformStyle = "transform: translate(calc(".concat(offsetX, "), calc(").concat(offsetY, "));");
switch (position) {
case 'top-left':
return "top: 0; left: 0; ".concat(transformStyle);
case 'top-center':
return "top: 0; left: 50%; ".concat(transformStyle);
case 'top-right':
return "top: 0; left: 100%; ".concat(transformStyle);
case 'left':
return "top: 50%; left: 0; ".concat(transformStyle);
case 'right':
return "top: 50%; left: 100%; ".concat(transformStyle);
case 'bottom-left':
return "top: 100%; left: 0; ".concat(transformStyle);
case 'bottom-center':
return "top: 100%; left: 50%; ".concat(transformStyle);
case 'bottom-right':
return "top: 100%; left: 100%; ".concat(transformStyle);
default:
return "top: 0; left: 0; ".concat(transformStyle);
}
}
function setBubbleStyle(type, position) {
if (type !== 'bubble') return '';
switch (position) {
case 'top-left':
return 'border-bottom-right-radius: 0;';
case 'top-right':
return 'border-bottom-left-radius: 0;';
case 'bottom-left':
return 'border-top-right-radius: 0;';
case 'bottom-right':
return 'border-top-left-radius: 0;';
default:
return '';
}
}
function getOverCount(text) {
var overCount = false;
if (typeof text === 'number') {
if (text >= 100) {
overCount = true;
}
}
return overCount;
}
module.exports = {
setPositionStyle: setPositionStyle,
setBubbleStyle: setBubbleStyle,
getOverCount: getOverCount
};

View File

@ -0,0 +1,53 @@
.ant-badge {
display: inline-block;
position: relative;
}
.ant-badge-content {
position: absolute;
display: flex;
height: 14px;
align-self: center;
align-items: center;
font-size: 9px;
padding: 2px 4px;
box-sizing: border-box;
word-break: keep-all;
justify-content: center;
top: 0;
left: 100%;
transform: translate(-50%, -50%);
}
.ant-badge-content-stroke {
border: 1px solid #ffffff;
}
.ant-badge-content-text {
padding-left: 2px;
}
.ant-badge-content-text:empty {
display: none;
}
.ant-badge-content .ant-icon {
font-size: 9px;
color: #ffffff;
}
.ant-badge-content-not-dot {
min-width: 14px;
height: 14px;
border-radius: 14px;
display: flex;
background-color: #ff3141;
}
.ant-badge-dot {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #ff3141;
}
.ant-badge-dot-stroke {
border: 1px solid #ffffff;
}
.ant-badge-number,
.ant-badge-text,
.ant-badge-bubble {
color: #ffffff;
}

View File

@ -0,0 +1,15 @@
export var BadgeDefaultProps = {
position: 'top-right',
stroke: false,
type: 'dot',
bgColor: '',
};
export var BadgeFunctionalProps = {
type: 'dot',
text: null,
position: 'top-right',
offsetX: null,
offsetY: null,
stroke: false,
bgColor: '',
};

View File

@ -0,0 +1,74 @@
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);
};
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { ButtonDefaultProps } from './props';
Component({
properties: {
className: String,
style: String,
disabled: Boolean,
activeClassName: String,
subText: String,
inline: Boolean,
size: {
type: String,
value: 'medium',
},
icon: String,
loading: Boolean,
danger: Boolean,
formType: {
type: String,
value: 'button',
},
publicId: String,
openType: String,
scope: String,
type: {
type: String,
value: 'default',
},
},
options: {
styleIsolation: 'shared',
},
props: ButtonDefaultProps,
methods: __assign({
onGetUserInfo: function (event) {
this.triggerEvent('getuserinfo', event.detail);
},
onContact: function (event) {
this.triggerEvent('contact', event.detail);
},
onGetPhoneNumber: function (event) {
this.triggerEvent('getphonenumber', event.detail);
},
onGetRealTimePhoneNumber: function (event) {
this.triggerEvent('getrealtimephonenumber', event.detail);
},
onError: function (event) {
this.triggerEvent('error', event.detail);
},
onLaunchApp: function (event) {
this.triggerEvent('launchapp', event.detail);
},
onOpenSetting: function (event) {
this.triggerEvent('opensetting', event.detail);
},
onAgreePrivacyAuthorization: function (event) {
this.triggerEvent('agreeprivacyauthorization', event.detail);
},
onChooseAvatar: function (event) {
this.triggerEvent('chooseavatar', event.detail);
},
}),
});

View File

@ -0,0 +1,7 @@
{
"component": true,
"usingComponents": {
"loading": "../Loading/index",
"ant-icon": "../Icon/index"
}
}

View File

@ -0,0 +1,77 @@
---
nav:
path: /components
group:
title: 通用
order: 2
toc: 'content'
---
# Button 按钮
<code src="../../docs/components/compatibility.tsx" inline="true"></code>
用于开始一个即时操作。
## 何时使用
标记了一个(或封装一组)操作命令,响应用户点击行为,触发相应的业务逻辑。
## 代码示例
### 基本使用
<code src='pages/Button/index'></code>
### Inline
<code src='pages/ButtonInline/index'></code>
### Icon
<code src='pages/ButtonIcon/index'></code>
### 更多自定义
<code src='pages/ButtonCustom/index'></code>
## API
### Button
以下表格介绍了 Button 组件的 API 属性:
| 属性 | 说明 | 类型 | 默认值 |
| --------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------- | --------- |
| type | 按钮类型,可选 `primary`、`default`、`text` | string | `default` |
| danger | 是否为危险按钮 | boolean | false |
| disabled | 是否为失效按钮 | boolean | false |
| activeClassName | 按下时的类名 | string | - |
| className | 类名 | string | - |
| style | 样式 | string | - |
| inline | 是否为内联按钮 | boolean | false |
| icon | 按钮左侧图标 | string | - |
| loading | 是否加载中,加载中时不可点击 | boolean | - |
| size | 按钮大小。仅在 `inline` 下生效,可选 `small`、`medium`、`large` | string | `medium` |
| subText | 辅助文字,显示在第二行。`inline` 下不生效 | string | - |
| catchTap | 点击按钮,触发此回调,非冒泡 | (e: [Event](https://opendocs.alipay.com/mini/framework/event-object)) => void | - |
| onTap | 点击按钮,触发此回调 | (e: [Event](https://opendocs.alipay.com/mini/framework/event-object)) => void | - |
| onDisabledTap | 禁用时点击出发回调(微信不支持) | (e: [Event](https://opendocs.alipay.com/mini/framework/event-object)) => void | - |
### 更多属性
以下是 Button 组件支持的其他属性:
- `public-id`
- `open-type`
- `scope`
- `form-type`
- `onGetAuthorize`
- `onFollowLifestyle`
- `onError`
- `onGetUserInfo`
- `onGetPhoneNumber`
具体的属性说明,请参考支付宝小程序的官方文档。
[Button 组件属性说明](https://opendocs.alipay.com/mini/component/button#%E5%B1%9E%E6%80%A7%E8%AF%B4%E6%98%8E)

View File

@ -0,0 +1,46 @@
<wxs
src="./index.wxs"
module="utils"
></wxs>
<button
formType="{{formType}}"
hoverClass="{{utils.getHoverClass(loading, type, activeClassName)}}"
scope="{{scope}}"
bindgetuserinfo="onGetUserInfo"
bindcontact="onContact"
bindgetphonenumber="onGetPhoneNumber"
bindgetrealtimephonenumber="onGetRealTimePhoneNumber"
binderror="onError"
bindlaunchapp="onLaunchApp"
bindopensetting="onOpenSetting"
bindagreeprivacyauthorization="onAgreePrivacyAuthorization"
bindchooseavatar="onChooseAvatar"
publicId="{{publicId}}"
openType="{{openType}}"
class="ant-button {{inline ? 'ant-button-inline ' + utils.getClass(size) : ''}} {{'ant-button-' + type + (danger ? '-danger' : '')}} {{disabled || loading ? 'ant-button-disabled' : ''}} {{className ? className : ''}}"
style="{{style}}"
>
<view class="ant-button-wrap">
<ant-icon
wx:if="{{!!icon}}"
type="{{icon}}"
></ant-icon>
<view class="ant-button-content-text {{icon ? 'ant-button-content-text-margin' : ''}}">
<slot></slot>
<view
wx:if="{{!inline && subText}}"
class="ant-button-content-subtext"
>{{subText}}</view>
</view>
<view
wx:if="{{loading}}"
class="ant-button-content-loading-container"
>
<loading
type="mini"
color="currentColor"
className="ant-button-content-loading"
></loading>
</view>
</view>
</button>

View File

@ -0,0 +1,24 @@
function getClass(size) {
var list = ['small', 'medium', 'large'];
if (list.indexOf(size) >= 0) {
return "ant-button-".concat(size);
}
return 'ant-button-medium';
}
function getHoverClass(loading, type, activeClassName) {
if (loading) {
return '';
}
var className = 'ant-button-active';
if (type === 'text') {
className += ' ant-button-text-active';
}
if (activeClassName) {
className += ' ' + activeClassName;
}
return className;
}
module.exports = {
getClass: getClass,
getHoverClass: getHoverClass
};

View File

@ -0,0 +1,112 @@
.ant-button {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: auto;
line-height: normal;
padding: 12px;
border-radius: 4px;
border: 0 none;
box-sizing: border-box;
font-size: 18px;
z-index: 2;
}
.ant-button-large {
font-size: 18px;
padding: 12px 12px 12px 12px;
}
.ant-button-medium {
font-size: 17px;
padding: 8px 12px 8px 12px;
}
.ant-button-small {
font-size: 15px;
padding: 4px 12px 4px 12px;
}
.ant-button-primary {
color: #ffffff;
background-color: #1677ff;
box-shadow: inset 0 0 0 1px #1677ff;
}
.ant-button-default {
color: #1677ff;
background-color: #ffffff;
box-shadow: inset 0 0 0 1px #1677ff;
}
.ant-button-text {
color: #1677ff;
background-color: transparent;
box-shadow: none;
}
.ant-button-primary-danger {
color: #ffffff;
background-color: #ff3141;
box-shadow: inset 0 0 0 1px #ff3141;
}
.ant-button-default-danger {
color: #ff3141;
background-color: #ffffff;
box-shadow: inset 0 0 0 1px #ff3141;
}
.ant-button-text-danger {
color: #ff3141;
background-color: transparent;
box-shadow: none;
}
.ant-button-text-active {
background-color: rgba(255, 255, 255, 0.92);
}
.ant-button-active {
filter: brightness(0.92);
}
.ant-button-disabled {
opacity: 0.4;
}
.ant-button-wrap {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.ant-button-content-text-margin {
margin-left: 8px;
}
.ant-button-content-text:empty {
margin-left: 0;
width: 0;
opacity: 0;
}
.ant-button-content-text:empty::after {
content: '\00a0';
}
.ant-button-content-subtext {
font-size: 12px;
opacity: 0.6;
}
.ant-button-content-loading-container {
display: flex;
justify-content: center;
align-items: center;
width: 33px;
height: 16px;
margin-left: 8px;
}
.ant-button-content-loading {
position: relative;
}
.ant-button-inline {
display: inline-block;
border-radius: 4px;
}
.ant-button-inline .ant-button-content-loading-container {
width: 16px;
height: 16px;
}
.ant-button-inline .ant-button-content-loading {
transform: scale(0.5);
}
.ant-button::after {
border-width: 0;
}

View File

@ -0,0 +1,5 @@
export var ButtonDefaultProps = {
type: 'default',
formType: 'button',
size: 'medium',
};

View File

@ -0,0 +1,28 @@
/* size | 按钮内间距 */
/* corner-radius| 按钮圆角 */
/* font-size | 副标题字号 */
/* color | 按钮边框宽度 */
/* opacity | disable状态不透明度 */
/* color | 默认按钮文字色 */
/* color | 默认按钮背景色 */
/* color | 默认按钮边框色 */
/* color |primary按钮背景色 */
/* color |primary按钮边框色 */
/* color |primary按钮文字色 */
/* color |ghost按钮边框色 */
/* color |ghost按钮文字色 */
/* color |danger按钮背景色 */
/* color |danger按钮边框色 */
/* color |danger按钮文字色 */
/* color |danger-ghost按钮边框色 */
/* color |danger-ghost按钮文字色 */
/* color |light按钮背景色 */
/* color |light按钮边框色 */
/* color |light按钮文字色 */
/* size | 胶囊按钮圆角 */
/* size | 胶囊按钮水平内间距 */
/* size | 胶囊按钮垂直内间距 */
/* font-size | 胶囊按钮大字号 */
/* font-size | 胶囊按钮中字号 */
/* font-size | 胶囊按钮小字号 */
/* 图标尺寸 */

View File

@ -0,0 +1,84 @@
function keys(obj) {
return JSON.stringify(obj).replace(getRegExp('{|}|"', 'g'), '').split(',').map(function (item) {
return item.split(':')[0];
});
}
function getClassName(value, index, showSelectableDatesOnly) {
var isSelected = value.isSelected,
isSelectedBegin = value.isSelectedBegin,
isSelectedEnd = value.isSelectedEnd,
isRowBegin = value.isRowBegin,
isRowEnd = value.isRowEnd,
inThisMonth = value.inThisMonth,
isToday = value.isToday,
disabled = value.disabled,
className = value.className,
isRange = value.isRange;
var classNames = {
disabled: disabled,
today: inThisMonth && isToday,
selected: inThisMonth && isSelected,
'selected-begin': inThisMonth && isSelectedBegin,
'selected-end': inThisMonth && isSelectedEnd,
'selected-row-begin': inThisMonth && isRowBegin && isSelected,
'selected-row-end': inThisMonth && isRowEnd && isSelected,
hidden: !inThisMonth || showSelectableDatesOnly && !isRange,
'row-end': index % 7 === 6
};
var result = "ant-calendar-cell ".concat(className || '');
keys(classNames).forEach(function (key) {
if (classNames[key]) {
result += " ant-calendar-cell-".concat(key);
}
});
return result;
}
function getSpaceClassName(index, items) {
var isNotEnd = index % 7 !== 6;
var nextItem = items[index + 1];
var nextSelected = nextItem && nextItem.isSelected && nextItem.inThisMonth;
var isSelected = items[index].isSelected;
var classNames = {
active: isNotEnd && isSelected && nextSelected
};
var result = 'ant-calendar-cell-space';
keys(classNames).forEach(function (key) {
if (classNames[key]) {
result += " ant-calendar-cell-space-".concat(key);
}
});
return result;
}
function getMarkCellClassName(index, items) {
if (items[index].length - 1 === index) {
return "ant-calendar-mark-cell ant-calendar-mark-cell-last";
}
return 'ant-calendar-mark-cell';
}
function isDisplay(index, items) {
// 找到需要当前月需要展示的日期最大最小索引
var _items_reduce = items.reduce(function (res, item) {
// !item.inThisMonth 被隐藏掉的日期
// !item.isRange 不在传入范围内的日期
if (!(!item.inThisMonth || !item.isRange)) {
if (res.minIndex === null || res.maxIndex === null) {
res.minIndex = item.index;
res.maxIndex = item.index;
}
res.minIndex = Math.min(res.minIndex, item.index);
res.maxIndex = Math.max(res.maxIndex, item.index);
}
return res;
}, {
minIndex: null,
maxIndex: null
});
if (_items_reduce.maxIndex === null || _items_reduce.maxIndex === null) return true;
return index >= Math.floor(_items_reduce.minIndex / 7) * 7 && index < Math.ceil(_items_reduce.maxIndex / 7) * 7;
}
module.exports = {
getSpaceClassName: getSpaceClassName,
getClassName: getClassName,
getMarkCellClassName: getMarkCellClassName,
isDisplay: isDisplay
};

View File

@ -0,0 +1,300 @@
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);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import dayjs from 'dayjs';
import equal from 'fast-deep-equal';
import { Component, triggerEvent, getValueFromProps } from '../_util/simply';
import { defaultLocaleText, CalendarDefaultProps, } from './props';
import { getMonthListFromRange, getSelectionModeFromValue, renderCells, getScrollIntoViewId, } from './utils';
import mixinValue from '../mixins/value';
import { getInstanceBoundingClientRect } from '../_util/jsapi/get-instance-bounding-client-rect';
Component(CalendarDefaultProps, {
getInstance: function () {
if (this.$id) {
return my;
}
return this;
},
getBoundingClientRect: function (query) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getInstanceBoundingClientRect(this.getInstance(), query)];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
},
scrollIntoView: function (value) {
this.updateScrollIntoViewId(getScrollIntoViewId(value));
},
clickCell: function (e) {
var _a, _b;
var time = e.currentTarget.dataset.time;
var clickDate = dayjs(time.time);
if (time.disabled) {
return;
}
var value = this.getValue();
var selectionModeFromValue = getSelectionModeFromValue(value);
var selectionMode = (_b = (_a = getValueFromProps(this, 'selectionMode')) !== null && _a !== void 0 ? _a : selectionModeFromValue) !== null && _b !== void 0 ? _b : 'range';
if (selectionMode === 'range') {
if (Array.isArray(value)) {
if (value.length === 1) {
var current = value[0];
if (dayjs(clickDate.toDate().getTime()).isBefore(dayjs(current))) {
this.updateValue([clickDate.toDate().getTime()]);
}
else {
this.updateValue([value[0], clickDate.toDate().getTime()]);
}
}
else {
this.updateValue([clickDate.toDate().getTime()]);
}
}
else {
this.updateValue([clickDate.toDate().getTime()]);
}
}
else if (selectionMode === 'single') {
this.updateValue(clickDate.toDate().getTime());
}
},
setCurrentMonth: function (e) {
this.setData({ headerState: e.month });
},
measurement: function () {
var elementSize = this.data.elementSize;
// 组件如果内嵌在 slot 里, 一定会被渲染出来, 但是此时 cellHight 为 0
// 此时需要重新计算
if (!elementSize || elementSize.cellHight === 0) {
this.measurementFn();
}
},
measurementFn: function () {
var _this = this;
Promise.all([
this.getBoundingClientRect('.ant-calendar-body-container'),
this.getBoundingClientRect('.ant-calendar-cells'),
this.getBoundingClientRect('.ant-calendar-title-container'),
])
.then(function (_a) {
var bodyContainer = _a[0], cellContainer = _a[1], Title = _a[2];
// 滚动的时候 top 和 bottom 等尺寸会变
// 所以只能依赖 height 来计算
var paddingHeight = bodyContainer.height - cellContainer.height - Title.height;
var monthTitleHeight = Title.height + paddingHeight;
var cellHight = cellContainer.height / (_this.data.monthList[0].cells.length / 7);
_this.setData({
elementSize: {
monthTitleHeight: monthTitleHeight,
cellHight: cellHight,
paddingHeight: paddingHeight,
},
});
})
.catch(function () {
_this.setData({ elementSize: null });
});
},
// scroll 触发滚动之后需要重置 scrollIntoViewId
updateScrollIntoViewId: function (id) {
var _this = this;
this.setData({ scrollIntoViewId: id });
var timer = setTimeout(function () {
_this.setData({ scrollIntoViewId: '' });
clearTimeout(timer);
});
},
updateValue: function (newValue) {
triggerEvent(this, 'change', newValue);
if (!this.isControlled()) {
this.update(newValue);
}
},
updateData: function () {
var _a = getValueFromProps(this, [
'monthRange',
'localeText',
'weekStartsOn',
'onFormatter',
'onMonthFormatter',
]), monthRange = _a[0], plocaleText = _a[1], pweekStartsOn = _a[2], onFormatter = _a[3], onMonthFormatter = _a[4];
var localeText = Object.assign({}, defaultLocaleText, plocaleText);
var markItems = __spreadArray([], localeText.weekdayNames, true);
var weekStartsOn = pweekStartsOn;
if (weekStartsOn === 'Sunday') {
var item = markItems.pop();
if (item)
markItems.unshift(item);
}
var value = this.getValue();
var start = dayjs(monthRange === null || monthRange === void 0 ? void 0 : monthRange[0]).startOf('d');
var end = dayjs(monthRange === null || monthRange === void 0 ? void 0 : monthRange[1]).startOf('d');
var monthRangeList = getMonthListFromRange(start, end);
var monthList = monthRangeList.map(function (p) {
var cells = renderCells(p, weekStartsOn, value, localeText,
// 如果monthRange传入异常用内置的时间范围
start.isAfter(end) || start.isSame(end)
? [monthRangeList[0], dayjs(monthRangeList[1]).endOf('month')]
: [start, end]);
if (onFormatter && typeof onFormatter === 'function') {
cells = cells.map(function (o) {
var _a;
var time = o.time, top = o.top, bottom = o.bottom, disabled = o.disabled, isSelectedBegin = o.isSelectedBegin, isSelectedEnd = o.isSelectedEnd, isSelected = o.isSelected, className = o.className, isRange = o.isRange;
var newState = (_a = onFormatter({
time: time,
top: top ? __assign({}, top) : undefined,
bottom: bottom ? __assign({}, bottom) : undefined,
disabled: disabled,
isSelectedBegin: isSelectedBegin,
isSelectedEnd: isSelectedEnd,
isSelected: isSelected,
className: className,
isRange: isRange,
}, value)) !== null && _a !== void 0 ? _a : {};
var result = __assign({}, o);
if (typeof newState === 'object') {
// 只允许修改的字段字段
['top', 'bottom', 'disabled', 'className'].forEach(function (key) {
if (key in newState) {
result[key] = newState[key];
}
});
}
return result;
});
}
var month = {
title: p.format(localeText.title),
className: '',
cells: cells,
};
if (onMonthFormatter && typeof onMonthFormatter === 'function') {
month = __assign(__assign({}, month), onMonthFormatter(p));
}
return month;
});
this.setData({ markItems: markItems, monthList: monthList });
},
}, {
elementSize: null,
markItems: [],
monthList: [],
headerState: 0,
scrollIntoViewId: '',
}, [mixinValue()], {
didMount: function () {
this.updateData();
this.measurementFn();
// 初始化默认值时,滚动到选中位置
var _a = getValueFromProps(this, [
'value',
'defaultValue',
]), value = _a[0], defaultValue = _a[1];
if (this.isControlled()) {
this.updateScrollIntoViewId(getScrollIntoViewId(value));
}
else {
defaultValue &&
this.updateScrollIntoViewId(getScrollIntoViewId(defaultValue));
}
},
didUpdate: function (prevProps, prevData) {
if (!this.isEqualValue(prevData)) {
// 滚动到已选的位置
var changedScrollIntoView = getValueFromProps(this, 'changedScrollIntoView');
changedScrollIntoView &&
this.updateScrollIntoViewId(getScrollIntoViewId(this.getValue()));
}
if (!equal(prevProps, this.props) || !this.isEqualValue(prevData)) {
this.updateData();
}
},
attached: function () {
this.updateData();
this.measurementFn();
// 初始化默认值时,滚动到选中位置
var _a = getValueFromProps(this, [
'value',
'defaultValue',
]), value = _a[0], defaultValue = _a[1];
if (this.isControlled()) {
this.updateScrollIntoViewId(getScrollIntoViewId(value));
}
else {
defaultValue &&
this.updateScrollIntoViewId(getScrollIntoViewId(defaultValue));
}
this.triggerEvent('ref', this);
},
observers: {
'**': function (data) {
var prevData = this._prevData || this.data;
this._prevData = __assign({}, data);
if (!equal(prevData, data)) {
this.updateData();
}
},
'mixin.value': function () {
// 滚动到已选的位置
var changedScrollIntoView = getValueFromProps(this, 'changedScrollIntoView');
changedScrollIntoView &&
this.updateScrollIntoViewId(getScrollIntoViewId(this.getValue()));
},
},
});

View File

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

View File

@ -0,0 +1,175 @@
---
nav:
path: /components
group:
title: 信息展示
order: 8
toc: 'content'
---
# Calendar 日历
<code src="../../docs/components/compatibility.tsx" inline="true"></code>
日历组件
## 代码示例
<code src='pages/Calendar/index' ></code>
## API
以下为日历组件的属性及描述:
| 属性 | 说明 | 类型 | 默认值 |
| ----------------------- | ---------------------------------------------- | ----------------------------------------------------------- | ----------- |
| defaultValue | 初始值 | CalendarValue | 无 |
| value | 日历选择的日期,传入后即为受控模式 | CalendarValue | 无 |
| selectionMode | 设置选择模式,单选或者连续区间,默认为 `range` | `single` \| `range` | `range` |
| monthRange | 月份范围,默认为最近 3 个月 | `[number, number]` | 最近 3 个月 |
| weekStartsOn | 星期栏,以周几作为第一天显示。默认为 `Sunday` | `Sunday` \| `Monday` | `Sunday` |
| onChange | 日期变化回调 | (date: CalendarValue) => void | 无 |
| onFormatter | 用于设置单元格的自定义数据 | (cell: CellState, currentValue: CalendarValue) => CellState | 无 |
| onMonthFormatter | 用于设置月份的自定义数据 | (month: any) => CellState | 无 |
| localeText | 国际化文案 | Partial`<LocaleText>` | 无 |
| changedScrollIntoView | 选中值改变后是否滚动视图 | boolean | 无 |
| showSelectableDatesOnly | 只展示在可选范围内的日期 | boolean | false |
### 类型
**CalendarValue** : 日历的值类型,为数字或数字元组 `number | [number,number]`,表示单选或连续日期区间。单位为毫秒的时间戳。
**CellState** : 定义了日历单元格的各种状态。
```typescript
interface CellState {
/**
* 是否禁用
*/
disabled: boolean;
/**
* 日历单元格的顶部内容
*/
top?: { label: string; className?: string };
/**
* 日历单元格的底部内容
*/
bottom?: { label: string; className?: string };
/**
* 时间戳
*/
time: number;
/**
* 日期
*/
date: number;
/**
* 是否选中
*/
isSelected: boolean;
}
```
**LocaleText** : 提供国际化支持的文案结构。
```typescript
interface LocaleText {
/**
* 星期的名称,从周一至周日
* 默认为 ['一', '二', '三', '四', '五', '六', '日']
*/
weekdayNames: string[];
/**
* 月份标题的格式,默认为 'YYYY年MM月'
*/
title: string;
/**
* 今天的文案,默认为 '今日'
*/
today: string;
/**
* 开始的文案,默认为 '开始'
*/
start: string;
/**
* 结束的文案,默认为 '结束'
*/
end: string;
/**
* 开始与结束的文案,默认为 '开始/结束'
*/
startAndEnd: string;
}
```
## FAQ
### 如何设置默认的开始与结束时间?
通过 `defaultValue` 可以设置默认的时间。`defaultValue` 的类型是 `CalendarValue`
`CalendarValue` 的类型是 `number | [number, number]`,代表单选或者连续区间的日期。它是一个时间戳,单位是毫秒。
例如,如果我们想设置默认的开始时间为今天,结束时间为七天后,我们可以在 `defaultValue` 中传入以下代码:
```ts
[dayjs().startOf('date'), dayjs().add(7, 'days').startOf('date')];
```
### 通过 `onFormatter` 设置单元格的自定义数据
我们可以通过 `onFormatter` 方法设置单元格的自定义数据,`onFormatter` 的格式是 `(cell: CellState, currentValue: CalendarValue) => CellState`
这个函数会获取每个单元格的状态以及当前的值。通过返回新的单元格数据,我们可以自定义单元格的状态。
以下是一些常见的使用场景:
#### 如何让当天之前的时间不可选?
在支付宝小程序中,我们可以通过页面上的方法设置,需要在 axml 文件中传入一个方法名字符串。
axml 文件:
```xml
<calendar onFormatter="handleFormat" />
```
ts 文件:
```ts
import dayjs from 'dayjs';
Page({
handleFormat(cell: CellState) {
// 如果单元格代表的时间早于今天的开始时间,则禁止选择
return {
disabled: dayjs(cell.time).isBefore(dayjs().startOf('date')),
};
},
});
```
在微信小程序,我们也可以通过 data 中的函数来设置,此时在 wxml 文件中需要传入一个变量名。
wxml 文件:
```xml
<calendar onFormatter="{{ handleFormat }}" />
```
ts 文件:
```ts
import dayjs from 'dayjs';
Page({
data: {
handleFormat: (cell: CellState) => {
// 如果单元格代表的时间早于今天的开始时间,则禁止选择
return {
disabled: dayjs(cell.time).isBefore(dayjs().startOf('date')),
};
},
},
});
```

View File

@ -0,0 +1,99 @@
<wxs
src="./helper.wxs"
module="helper"
></wxs>
<wxs
src="./scroll.wxs"
module="scroll"
></wxs>
<view
class="ant-calendar {{className ? className : ''}}"
style="{{style}}"
>
<view class="ant-calendar-mark">
<block
wx:for="{{markItems}}"
wx:for-index="index"
wx:for-item="item"
>
<view class="{{helper.getMarkCellClassName(index, markItems)}}">
<!--display: inline-->
<text>{{item}}</text>
</view>
</block>
</view>
<view
wx:if="{{!!elementSize}}"
class="ant-calendar-sticky"
>
<view class="ant-calendar-sticky-title">
<view class="ant-calendar-title">{{monthList[headerState].title}}</view>
</view>
</view>
<scroll-view
scrollY="{{true}}"
class="ant-calendar-body"
data-elementsize="{{elementSize}}"
data-monthlist="{{monthList}}"
bind:scroll="{{scroll.handleScroll}}"
scrollIntoView="{{scrollIntoViewId}}"
scrollWithAnimation
scrollAnimationDuration="{{300}}"
disableLowerScroll="out-of-bounds"
disableUpperScroll="out-of-bounds"
bind:ref="handleRef"
>
<block
wx:for="{{monthList}}"
wx:for-index="index"
wx:for-item="currentMonth"
>
<view
class="ant-calendar-body-container {{currentMonth.className || ''}}"
style="{{currentMonth.style || ''}}"
>
<view class="ant-calendar-title-container">
<view class="ant-calendar-title">{{currentMonth.title}}</view>
</view>
<view class="ant-calendar-cells">
<block
wx:for="{{currentMonth.cells}}"
wx:for-index="index"
wx:for-item="item"
>
<block wx:if="{{helper.isDisplay(index, currentMonth.cells)}}">
<view
class="{{helper.getClassName(item, index, showSelectableDatesOnly)}}"
id="id_{{item.time}}"
data-time="{{item}}"
bind:tap="clickCell"
>
<view class="ant-calendar-cell-container">
<view class="ant-calendar-cell-top">
<!--display: inline-->
<text
wx:if="{{item.top}}"
class="ant-calendar-cell-top-text {{item.top.className ? item.top.className : ''}}"
>{{item.top.label}}</text>
</view>
<view class="ant-calendar-cell-center">{{item.date}}</view>
<view class="ant-calendar-cell-bottom">
<!--display: inline-->
<text
wx:if="{{item.bottom}}"
class="{{item.bottom.className}}"
>{{item.bottom.label}}</text>
</view>
</view>
</view>
<view
wx:if="{{index % 7 !== 6}}"
class="{{helper.getSpaceClassName(index, currentMonth.cells)}}"
></view>
</block>
</block>
</view>
</view>
</block>
</scroll-view>
</view>

View File

@ -0,0 +1,146 @@
.ant-calendar {
color: #333333;
position: relative;
display: flex;
flex-direction: column;
height: 100%;
}
.ant-calendar-body {
flex: 1;
overflow: hidden;
}
.ant-calendar-sticky {
position: absolute;
top: 0px;
left: 0px;
max-height: 41px;
width: 100%;
overflow: hidden;
top: 44px;
z-index: 1000;
}
.ant-calendar-mark {
height: 44px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
box-sizing: border-box;
font-size: 14px;
padding: 0 8px;
}
.ant-calendar-mark .ant-calendar-mark-cell {
flex: 1;
text-align: center;
width: calc((100% - 6 * 5px) / 7);
margin-right: 5px;
}
.ant-calendar-mark .ant-calendar-mark-cell-last {
margin-right: 0;
}
.ant-calendar-title {
color: #333333;
font-size: 18px;
height: 41px;
line-height: 41px;
padding-left: 20px;
margin-bottom: 4px;
background: #f8f8f8;
}
.ant-calendar-cells {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: stretch;
padding: 0 8px;
}
.ant-calendar-cell-space {
width: 5px;
height: 55px;
}
.ant-calendar-cell-space-active {
background: rgba(22, 119, 255, 0.1);
}
.ant-calendar-cell {
box-sizing: border-box;
width: calc((100% - 6 * 5px) / 7);
height: 55px;
margin-bottom: 4px;
position: relative;
}
.ant-calendar-cell-container {
box-sizing: border-box;
padding-top: 3.5px;
height: 100%;
}
.ant-calendar-cell-top {
color: #999999;
text-align: center;
font-size: 9px;
height: 12.5px;
}
.ant-calendar-cell-top-text {
white-space: nowrap;
}
.ant-calendar-cell-center {
text-align: center;
height: 22.5px;
font-size: 16px;
}
.ant-calendar-cell-bottom {
color: #999999;
text-align: center;
font-size: 9px;
height: 12.5px;
}
.ant-calendar-cell-selected {
background: rgba(22, 119, 255, 0.1);
}
.ant-calendar-cell-selected-begin {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
background: rgba(22, 119, 255, 0.1);
}
.ant-calendar-cell-selected-end {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
color: #ffffff;
}
.ant-calendar-cell-selected-row-end {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.ant-calendar-cell-selected-row-begin {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.ant-calendar-cell-selected-begin .ant-calendar-cell-container {
background: #1677ff;
border-radius: 4px;
color: #ffffff;
}
.ant-calendar-cell-selected-end .ant-calendar-cell-container {
background: #1677ff;
border-radius: 4px;
color: #ffffff;
}
.ant-calendar-cell-selected-end .ant-calendar-cell-top {
color: #ffffff;
}
.ant-calendar-cell-selected-begin .ant-calendar-cell-top {
color: #ffffff;
}
.ant-calendar-cell-selected-end .ant-calendar-cell-bottom {
color: #ffffff;
}
.ant-calendar-cell-selected-begin .ant-calendar-cell-bottom {
color: #ffffff;
}
.ant-calendar-cell-disabled {
opacity: 0.4;
}
.ant-calendar-cell-hidden {
opacity: 0;
pointer-events: none;
}

View File

@ -0,0 +1,21 @@
import { defaultMonthRange } from './utils';
export var defaultLocaleText = {
weekdayNames: ['一', '二', '三', '四', '五', '六', '日'],
title: 'YYYY年MM月',
today: '今日',
start: '开始',
end: '结束',
startAndEnd: '开始/结束',
};
export var CalendarDefaultProps = {
defaultValue: null,
value: null,
selectionMode: 'range',
monthRange: defaultMonthRange(),
weekStartsOn: 'Sunday',
localeText: defaultLocaleText,
onFormatter: null,
onMonthFormatter: null,
changedScrollIntoView: null,
showSelectableDatesOnly: false,
};

View File

@ -0,0 +1,45 @@
function handleScroll(event, ownerComponent) {
var currentScroll = event.detail.scrollTop;
var dataset = event.instance.getDataset();
var elementSize = dataset.elementsize,
monthList = dataset.monthlist;
if (!elementSize) {
return;
}
// 组件如果内嵌在 slot 里, 一定会被渲染出来, 但是此时 cellHight 为 0
if (elementSize.cellHight === 0) {
ownerComponent.callMethod('measurement');
return;
}
var instance = ownerComponent.selectComponent('.ant-calendar-sticky-title');
var sticky = ownerComponent.selectComponent('.ant-calendar-sticky');
if (sticky) {
sticky.setStyle({
display: currentScroll < 0 ? 'none' : 'block'
});
}
var monthHeight = elementSize.monthTitleHeight;
var paddingHeight = elementSize.paddingHeight;
var cellHeight = elementSize.cellHight;
var heightList = monthList.map(function (p) {
return monthHeight + cellHeight * p.cells.length / 7;
});
for (var i = 0; i < heightList.length; i++) {
if (currentScroll < heightList[i]) {
var topHeight = currentScroll - heightList[i] + monthHeight - paddingHeight;
topHeight = Math.max(topHeight, 0);
instance.setStyle({
transform: "translateY(-".concat(topHeight, "px)")
});
ownerComponent.callMethod('setCurrentMonth', {
month: topHeight > monthHeight * 0.8 ? i + 1 : i
});
break;
} else {
currentScroll = currentScroll - heightList[i];
}
}
}
module.exports = {
handleScroll: handleScroll
};

View File

@ -0,0 +1,157 @@
import dayjs from 'dayjs';
import { isoWeekday } from '../_util/dayjs/iso-weekday';
export function getMonthListFromRange(start, end) {
if (start.isAfter(end))
throw new Error("Start time can't be later than end time.");
var result = [];
var current = start.date(1);
while (!current.isAfter(end)) {
result.push(current.date(1));
current = current.add(1, 'month');
}
return result;
}
export function defaultMonthRange() {
var start = dayjs().startOf('date');
var end = dayjs().startOf('date').add(2, 'month');
return [start.toDate().getTime(), end.toDate().getTime()];
}
/**
*
* @param month 月份的某一天
* @param weekStartsOn 日历以星期几开始
* @returns 获取当月日历所有的日子
*/
export function getDate(month, weekStartsOn) {
var startOfMonth = month.date(1);
var cells = [];
var iterator = startOfMonth
.subtract(isoWeekday(startOfMonth) % 7, 'day')
.startOf('day');
if (weekStartsOn === 'Monday') {
iterator = iterator.add(1, 'day');
if (iterator.isSame(startOfMonth, 'month') &&
!iterator.isSame(startOfMonth.startOf('date'), 'date')) {
iterator = iterator.add(-7, 'days');
}
}
var diffDay = startOfMonth.date(1).add(1, 'month').diff(iterator, 'day');
var lintCount = Math.ceil(diffDay / 7);
while (cells.length < lintCount * 7) {
cells.push(iterator);
iterator = iterator.add(1, 'day');
}
return cells;
}
export function renderCells(cellsMonth, weekStartsOn, value, localeText, monthRangeList) {
var _a;
var rangeStartDate = monthRangeList[0], rangeEndDate = monthRangeList[1];
var rowBeginDay = 0;
var rowEndDay = 6;
if (weekStartsOn === 'Monday') {
rowBeginDay = 1;
rowEndDay = 0;
}
var dates = getDate(cellsMonth, weekStartsOn);
if (!value) {
return dates.map(function (d, index) {
var isToday = dayjs().isSame(d, 'day');
var isRowBegin = d.isSame(cellsMonth.startOf('month'), 'date') ||
d.day() === rowBeginDay;
var isRowEnd = d.isSame(cellsMonth.endOf('month'), 'date') || d.day() === rowEndDay;
var top;
if (isToday) {
top = {
label: localeText.today,
};
}
return {
index: index,
disabled: false,
time: d.toDate().getTime(),
date: d.get('date'),
isSelected: false,
isSelectedBegin: false,
top: top,
isSelectedEnd: false,
inThisMonth: d.month() === cellsMonth.month(),
isRowBegin: isRowBegin,
isRowEnd: isRowEnd,
isRange: (d.isSame(rangeStartDate) || d.isAfter(rangeStartDate)) &&
(d.isSame(rangeEndDate) || d.isBefore(rangeEndDate)),
};
});
}
var selectBegin;
var selectEnd;
if (Array.isArray(value)) {
selectBegin = dayjs(value[0]);
selectEnd = dayjs((_a = value[1]) !== null && _a !== void 0 ? _a : value[0]);
}
else {
selectBegin = dayjs(value);
selectEnd = dayjs(value);
}
return dates.map(function (d, index) {
var isToday = dayjs().isSame(d, 'day');
var isRowBegin = d.isSame(cellsMonth.startOf('month'), 'date') || d.day() === rowBeginDay;
var isRowEnd = d.isSame(cellsMonth.endOf('month'), 'date') || d.day() === rowEndDay;
var isSelectedBegin = selectBegin.isSame(d, 'day');
var isSelectedEnd = selectEnd.isSame(d, 'day');
var isSelected = (!!selectBegin.isBefore(d, 'day') && !!selectEnd.isAfter(d, 'day')) ||
isSelectedBegin ||
isSelectedEnd;
var inThisMonth = d.month() === cellsMonth.month();
var time = d.toDate().getTime();
var topLabel = isToday ? localeText.today : '';
if (Array.isArray(value)) {
if (isSelectedBegin) {
if (isSelectedEnd && value.length === 2) {
topLabel = localeText.startAndEnd;
}
else {
topLabel = localeText.start;
}
}
else {
if (isSelectedEnd) {
topLabel = localeText.end;
}
}
}
return {
index: index,
disabled: false,
time: time,
date: d.get('date'),
isSelected: isSelected,
isSelectedBegin: isSelectedBegin,
top: { label: topLabel },
isSelectedEnd: isSelectedEnd,
inThisMonth: inThisMonth,
isRowBegin: isRowBegin,
isRowEnd: isRowEnd,
isRange: (d.isSame(rangeStartDate) || d.isAfter(rangeStartDate)) &&
(d.isSame(rangeEndDate) || d.isBefore(rangeEndDate)),
};
});
}
export function getSelectionModeFromValue(value) {
if (Array.isArray(value)) {
return 'range';
}
if (typeof value === 'number') {
return 'single';
}
return null;
}
// 获取滚动视图的元素id
export function getScrollIntoViewId(value) {
// 已选中时间滚动到可视区域内微信不支持id为数字开头
return "id_".concat(value &&
dayjs(Array.isArray(value) ? value[0] : value)
.startOf('d')
.subtract(7, 'd') // 需要定位的地方往前推7天让已选中时间定位到中间位置
.toDate()
.getTime());
}

View File

@ -0,0 +1 @@
/* size | 按钮内间距 */

View File

@ -0,0 +1,44 @@
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import { Component, triggerEvent, getValueFromProps } from '../../_util/simply';
import { CheckboxGroupDefaultProps } from './props';
import mixinValue from '../../mixins/value';
Component(CheckboxGroupDefaultProps, {
onChange: function (args, e) {
if (getValueFromProps(this, 'disabled')) {
return;
}
var event;
event = args;
var currentValue = this.getValue();
var index = event.currentTarget.dataset.index;
var selectValue = getValueFromProps(this, 'options')[index].value;
if (currentValue.indexOf(selectValue) > -1) {
currentValue = currentValue.filter(function (v) { return v !== selectValue; });
}
else {
currentValue = __spreadArray(__spreadArray([], currentValue, true), [selectValue], false);
}
if (!this.isControlled()) {
this.update(currentValue);
}
triggerEvent(this, 'change', currentValue, e);
},
}, null, [
mixinValue({
transformValue: function (val) {
var value = val || [];
return {
needUpdate: true,
value: value,
};
},
}),
]);

View File

@ -0,0 +1,8 @@
{
"component": true,
"usingComponents": {
"list": "../../List/index",
"list-item": "../../List/ListItem/index",
"ant-checkbox": "../index"
}
}

View File

@ -0,0 +1,54 @@
<wxs
src="../index.wxs"
module="componentUtils"
></wxs>
<list
className="ant-checkbox-group {{className ? className : ''}} ant-checkbox-group-{{position}}"
style="{{style}}"
>
<checkbox-group
name="{{name}}"
value="{{mixin.value}}"
>
<view class="ant-checkbox-group-body">
<block wx:if="{{position === 'vertical'}}">
<block
wx:for="{{options}}"
wx:for-index="index"
wx:for-item="item"
>
<list-item>
<ant-checkbox
color="{{color}}"
checked="{{componentUtils.getCheckboxChecked(item, mixin.value)}}"
data-index="{{index}}"
value="{{item.value}}"
disabled="{{disabled || item.disabled}}"
bind:change="onChange"
>
<view class="ant-checkbox-group-item-label-default">{{item.label}}</view>
</ant-checkbox>
</list-item>
</block>
</block>
<block wx:else>
<block
wx:for="{{options}}"
wx:for-index="index"
wx:for-item="item"
>
<ant-checkbox
color="{{color}}"
checked="{{componentUtils.getCheckboxChecked(item, mixin.value)}}"
data-index="{{index}}"
value="{{item.value}}"
disabled="{{disabled || item.disabled}}"
bind:change="onChange"
>
<view class="ant-checkbox-group-item-label-default">{{item.label}}</view>
</ant-checkbox>
</block>
</block>
</view>
</checkbox-group>
</list>

View File

@ -0,0 +1,34 @@
.ant-checkbox-group-horizontal .ant-checkbox-group-body {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.ant-checkbox-group-horizontal .ant-checkbox-group-body .ant-list-item-line {
padding-right: 0;
}
.ant-checkbox-group-horizontal .ant-checkbox-group-body .ant-checkbox-item {
flex-flow: 0;
}
.ant-checkbox-group-horizontal .ant-checkbox-group-body .ant-list-item-line::after {
display: none;
}
.ant-checkbox-group-header:empty,
.ant-checkbox-group-footer:empty {
display: none;
}
.ant-checkbox-group-header,
.ant-checkbox-group-footer {
display: flex;
align-items: center;
padding: 8px 12px;
line-height: 1.4;
font-size: 15px;
color: #999999;
}
.ant-checkbox-group-body {
position: relative;
overflow: hidden;
}
.ant-checkbox-group-body .ant-checkbox-item-content .ant-checkbox-group-item-label-default:not(:nth-child(1)) {
display: none;
}

View File

@ -0,0 +1,8 @@
export var CheckboxGroupDefaultProps = {
value: null,
defaultValue: [],
disabled: false,
position: 'vertical',
color: '',
options: [],
};

View File

@ -0,0 +1,17 @@
import { CheckboxDefaultProps } from './props';
import { Component, triggerEvent } from '../_util/simply';
import mixinValue from '../mixins/value';
Component(CheckboxDefaultProps, {
onChange: function (e) {
var value = !this.getValue();
if (!this.isControlled()) {
this.update(value);
}
triggerEvent(this, 'change', value, e);
},
}, null, [
mixinValue({
valueKey: 'checked',
defaultValueKey: 'defaultChecked',
}),
]);

View File

@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"ant-icon": "../Icon/index"
}
}

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