静态页面

This commit is contained in:
2025-03-26 20:06:10 +08:00
commit 7ac96fd807
55 changed files with 2367 additions and 0 deletions

29
.gitignore vendored Normal file
View File

@ -0,0 +1,29 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
miniprogram_npm
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

5
api/common.js Normal file
View File

@ -0,0 +1,5 @@
import request from './request';
export default {
getConfig:()=>request.get('/api/config')
}

17
api/order.js Normal file
View File

@ -0,0 +1,17 @@
import request from './request';
export default {
status:{
created:"CREATED",pending:"PENDING",
delivering:"DELIVERING",pickupReady:"PICKUP_READY",completed:"COMPLETED",
cancelled:"CANCELLED",refunding:"REFUNDING",refunded:"REFUNDED"
},
statusKV:{
CREATED:'待支付',PENDING:'待接单',DELIVERING:'待配送',PICKUP_READY:'待自提',
COMPLETED:'已完成',CANCELLED:'已取消',REFUNDING:'退款中',REFUNDED:'已退款'
},
list:(params)=>request.get('/api/merchant/order/merchant',params),
test:(data)=>request.post('/api/merchant',data)
}

92
api/request.js Normal file
View File

@ -0,0 +1,92 @@
const { miniProgram } = wx.getAccountInfoSync();
const envVersion = miniProgram.envVersion;
let baseUrl = '';
if(envVersion=='develop'){
baseUrl = 'https://api-dev.beefast.co';
}else{
baseUrl = 'https://api.beefast.co'
}
let app = getApp();
let navLoginPromise = null;
const sendRequest = (options)=>{
if(!app)app = getApp();
return new Promise((rs,rj)=>{
wx.request({
url: `${baseUrl}${options.url}`,
success:(result)=>{
//Http Request的状态
if(result.statusCode==200){
//后端的自定义状态
if(result.data.code==200){
rs(result.data.data);
}else{
if(!options.options.noTips){
wx.showToast({
icon:'error',
title: result.data.message,
});
}
rj(result.data);
}
}else if(result.statusCode==401){
const pages = getCurrentPages();
const currentPages = pages[pages.length-1];
if(navLoginPromise){
return;
}
if(currentPages&&currentPages.route.indexOf('pages/login')>-1){
//用户先打开了小程序,然后又点开了朋友的分享页
navLoginPromise = wx.redirectTo({
url: '/pages/user/login/index',
});
return;
}
navLoginPromise = wx.navigateTo({
url: '/pages/user/login/index',
});
navLoginPromise.then(()=>{
navLoginPromise = null;
})
}else{
wx.showToast({
icon:'error',
title: result.data.message||result.data.detail||'发生错误',
})
rj(result.data);
}
},
method:options.method,
data:options.data,
header:{
Authorization: `Bearer ${app?.globalData?.accessToken}`
},
fail:(res)=>{
wx.showToast({
icon:'error',
title: 'Request Error',
})
rj(res);
}
})
})
}
export default {
baseUrl:baseUrl,
get(url,data,options){
return sendRequest({url,method:'get',data,options:options||{}});
},
post(url,data,options){
return sendRequest({url,method:'post',data,options:options||{}});
},
put(url,data,options){
return sendRequest({url,method:'put',data,options:options||{}});
},
delete(url,data,options){
return sendRequest({url,method:'delete',data,options:options||{}});
}
}

9
api/user.js Normal file
View File

@ -0,0 +1,9 @@
import request from './request';
export default {
genderKV:{
MALE:'先生',FEMALE:'女士'
},
login:(phone,password)=>request.post('/api/user/password-login',{phone,password,role:'deliveryman'}),
verifyCode:(phone)=>request.post('/api/user/send-code',{phone}),
}

32
app.js Normal file
View File

@ -0,0 +1,32 @@
import commonApi from './api/common';
const token = wx.getStorageSync('accessToken');
App({
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
},
async getAppConfig(){
if(!this.globalData.appConfig){
const data = await commonApi.getConfig();
this.globalData.appConfig = {};
data.map((item)=>{
this.globalData.appConfig[item.key] = item.value;
})
}
return this.globalData.appConfig;
},
globalData: {
userInfo: null,
accessToken:token
}
})

46
app.json Normal file
View File

@ -0,0 +1,46 @@
{
"pages": [
"pages/order/list/index",
"pages/index/index/index",
"pages/user/index/index",
"pages/user/login/index",
"pages/user/password/index",
"pages/product/list/index"
],
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#ffffff",
"backgroundColor": "#f5f5f5"
},
"style": "v2",
"tabBar": {
"color": "#222222",
"selectedColor": "#FFC300",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/index/index/index",
"text": "数据",
"iconPath": "assets/icon/tab-bar/tab1.png",
"selectedIconPath": "assets/icon/tab-bar/tab1-active.png"
},
{
"pagePath": "pages/order/list/index",
"text": "订单",
"iconPath": "assets/icon/tab-bar/tab2.png",
"selectedIconPath": "assets/icon/tab-bar/tab2-active.png"
},
{
"pagePath": "pages/user/index/index",
"text": "我的",
"iconPath": "assets/icon/tab-bar/tab3.png",
"selectedIconPath": "assets/icon/tab-bar/tab3-active.png"
}
]
},
"componentFramework": "glass-easel",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents"
}

415
app.wxss Normal file
View File

@ -0,0 +1,415 @@
@import './assets/style/svg-icon.wxss';
page{
font-size:30rpx;
line-height: 1;
--main-font-color:#000000;
--main-bgclolor:#F5F5F5;
--main-color:#FEC400;
--main-hover-color:#fcce39;
--safe-bottom:constant(safe-area-inset-bottom);
--safe-bottom:env(safe-area-inset-bottom);
color:var(--main-font-color);
background-color:var(--main-bgclolor);
overflow: hidden;
min-height: 100vh;
box-sizing: border-box;
}
view::-webkit-scrollbar{
display: none;
}
button{
border-radius: 12rpx;
box-sizing: border-box;
}
button label{
display: inline-block;
margin-left: 10rpx;
}
button .icon,button label{
vertical-align: middle;
}
button:not([size=mini]){
width:auto;
padding:30rpx 25rpx;
font-size: 36rpx;
}
button:not([size=mini]) .icon{
width:32rpx;height:32rpx;
}
button[type=primary]{
background-color:var(--main-color);
color:var(--main-font-color);
}
button[disabled]{
opacity: .7;
}
button[type=primary]:not([disabled]).button-hover{
background-color: var(--main-hover-color);
color:var(--main-font-color);
}
button[plain]{
border: 1rpx solid rgba(255, 195, 0, 0.5);
color: #FFC300;
}
button[type=default]{
color:var(--main-font-color);
font-size:32rpx;
line-height: 1;
}
button[type=default].button-hover{
color:#666;
}
button[type=primary][plain]{
border-color: var(--main-color);
color:var(--main-color);
padding:28rpx 25rpx;
}
button[loading][type=primary] {
background-color:var(--main-color);
color: hsla(0,0%,100%,.6);
}
radio-group{
line-height: 34rpx;
}
radio-group radio{
display: inline-block;
vertical-align: middle;
overflow: hidden;
}
radio-group label{
display: inline-block;
vertical-align: middle;
}
radio-group radio+label{
margin-left:10rpx;
}
radio-group label+label{
margin-left:20rpx;
}
radio{
width: 17px;
height: 17px;
position: relative;
}
radio .wx-radio-input{
border-radius: 50%;
border-color:var(--main-color);
box-sizing: border-box;
width: 100%;
height: 100%;
position: absolute;
top: 0;left:0;
}
radio .wx-radio-input.wx-radio-input-checked{
background-color:transparent;
border-color: var(--main-color);
}
radio .wx-radio-input.wx-radio-input-checked::after{
content: '';
position: absolute;
width: 11px;
height:11px;
left:2px;top:2px;
border-radius: 50%;
background: var(--main-color);
transform: none;
-webkit-transform:none;
}
checkbox .wx-checkbox-input{
width: 40rpx;
height: 40rpx;
border-radius: 50%;
}
page-container .content{
border-radius: 24rpx 24rpx 0 0;
background-color: #F5F5F5;
min-height: 200rpx;
/* padding:20rpx; */
}
.page-container{
background-color: #fff;
border-radius: 20rpx;
padding:30rpx;
margin:20rpx;
}
.page-container.shadow,.cells.shadow{
box-shadow: 0px 6px 6px 1px rgba(0, 0, 0, 0.05);
}
.tags{
display: flex;
gap: 10rpx;
}
.tags .tag{
font-size:20rpx;
padding:6rpx 10rpx;
color: #888888;
border: 0.5px solid rgba(153, 153, 153, 0.5);
border-radius: 6rpx;
}
.tags .tag.yellow{
color: #FFC300;
border-color:#FFC300;
}
.spliter{
border-bottom: 1rpx solid rgba(153, 153, 153, 0.2);
}
.spliter.dashed{
border-bottom: 1rpx dashed rgba(153, 153, 153, 0.2);
}
.money,.money-promation,.money-normal,.money-disable{
font-size: 36rpx;
font-weight: 500;
}
.money::before,.money-promation::before,.money-normal::before,.money-disable::before{
content: "¥ ";
font-size: 80%;
}
.money.minus::before{
content: '- ¥';
}
.money{
color:#ff0000;
}
.money-promation{
color:#FF8400;
}
.money-yellow{
color:var(--main-color);
}
.money-blue{
color:#1A4DEB;
}
.money-promation::before{
content: "-¥ ";
}
.money-normal{
color:unset;
}
.money-disable{
color:#888888;
text-decoration: line-through;
font-size: 28rpx;
font-weight:normal;
}
.bottom-bar{
padding:24rpx;
position:fixed;
bottom:0;
left:0;right:0;
background-color: #fff;
border-top: 0.5px solid rgba(153, 153, 153, 0.2);
padding-bottom:calc(constant(safe-area-inset-bottom) + 24rpx);
padding-bottom:calc(env(safe-area-inset-bottom) + 24rpx);
}
.bottom-bar.float,.bottom-bar-v2.float{
padding:0;
border:0;
margin: 0 24rpx;
margin-bottom:calc(constant(safe-area-inset-bottom) + 24rpx);
margin-bottom:calc(env(safe-area-inset-bottom) + 24rpx);
}
.custom-scroll-view{
height:100vh;
display: flex;
flex-direction: column;
}
.custom-scroll-view .main{
flex:1;
overflow: hidden;
}
.bottom-bar-v2{
padding:24rpx;
background-color: #fff;
border-top: 0.5px solid rgba(153, 153, 153, 0.2);
padding-bottom:calc(constant(safe-area-inset-bottom) + 24rpx);
padding-bottom:calc(env(safe-area-inset-bottom) + 24rpx);
}
.cells{
margin:20rpx;
border-radius: 24rpx;
background-color: #fff;
overflow: hidden;
}
.cells .cell{
display: flex;
align-items: center;
padding:0 40rpx;
font-size: 30rpx;
position: relative;
}
.cells .cell.cell-active{
background-color:rgba(0,0,0,.1);
}
.cells .cell::after{
content: '';
border-bottom: 1.2rpx solid rgba(153, 153, 153, 0.1);
position: absolute;
bottom:0;
left:40rpx;
right:40rpx;
}
.cells .cell:last-child::after,.cells .cell.no-border::after{
border:0;
}
.cells .cell-hd{
margin-right:20rpx;
}
.cells .cell-hd.not-empty::before{
content: '*';
color: #ff0000;
}
.cells .cell-hd .icon{
width:40rpx;height:40rpx;
vertical-align: middle;
}
.cells .cell-bd{
flex:1;
display: flex;
align-items: center;
position:relative;
min-height: 116rpx;
}
.cells .cell-bd .error{
color:red;
position: absolute;
left:0;bottom:10rpx;
font-size: 24rpx;
}
.cells .cell-bd input{
height:100rpx;
width:100%;
}
.cells picker{flex:1}
.cells .cell-ft{
display: flex;
align-items: center;
}
.cells .cell-ft,.right-arrow{
position: relative;
color:#999;
}
.cells.cells-access .cell-ft,.right-arrow{
padding-right: 40rpx;
}
.cells.cells-access .cell-ft::after,.cells .cell.cell-access .cell-ft::after,.right-arrow::after{
content:" ";
width:24rpx;height:48rpx;
-webkit-mask-position:0 0;
mask-position:0 0;
-webkit-mask-repeat:no-repeat;
mask-repeat:no-repeat;
-webkit-mask-size:100%;
mask-size:100%;
background-color:currentColor;
color:var(--weui-FG-2);
-webkit-mask-image:url(data:image/svg+xml,%3Csvg%20width%3D%2212%22%20height%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M2.454%206.58l1.06-1.06%205.78%205.779a.996.996%200%20010%201.413l-5.78%205.779-1.06-1.061%205.425-5.425-5.425-5.424z%22%20fill%3D%22%23B2B2B2%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E);
mask-image:url(data:image/svg+xml,%3Csvg%20width%3D%2212%22%20height%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M2.454%206.58l1.06-1.06%205.78%205.779a.996.996%200%20010%201.413l-5.78%205.779-1.06-1.061%205.425-5.425-5.425-5.424z%22%20fill%3D%22%23B2B2B2%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E);position:absolute;top:50%;right:0;margin-top:-24rpx
}
.tab-bar{
display: flex;
justify-content: space-between;
background-color: #fff;
font-size: 34rpx;
}
.tab-bar .item-container{
flex:1;
text-align: center;
}
.tab-bar .item{
position: relative;
padding:40rpx 0;
color: #555555;
transition-duration: .4s;
display: inline-block;
}
.tab-bar .item::before{
opacity: 0;
content: "";
height:8rpx;
width:100%;
position: absolute;
bottom:0;
background-color:var(--main-color);
transition-duration: .4s;
}
.tab-bar .current .item{
color: var(--main-font-color);
font-weight: 500;
}
.tab-bar .current .item::before{
opacity: 1;
}
navigator button{
vertical-align: middle;
}
.list-empty{
text-align: center;
padding:60rpx 0 30rpx 0;
}
.list-empty .icon{
width:132rpx;height:132rpx;
}
.list-empty .title{
font-size: 30rpx;
font-weight: 500;
}
.list-empty .sub-title{
font-size: 26rpx;
color: #A1A1A1;
margin-top:24rpx;
}
.scroll-view-dispatch{
height:100rpx;
}
.page-dispatch{
height:40rpx;
width:100%;
}
.navigator-hover{
background-color: transparent;
opacity: 1;
}
list-view{
display: block;
}
scroll-view .scroll-view-top-margin{
height:1rpx;
}
.weui-loading{
font-size:16px;width:1em;height:1em;display:inline-block;vertical-align:middle;
background:transparent url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='80px' height='80px' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23606060' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23606060' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23606060' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3CanimateTransform attributeName='transform' begin='0s' dur='1s' type='rotate' values='0 40 40;360 40 40' repeatCount='indefinite'/%3E%3C/g%3E%3C/svg%3E%0A") no-repeat;
background-size:100%
}
.weui-loading.white{
font-size:16px;width:1em;height:1em;display:inline-block;vertical-align:middle;
background:transparent url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='160rpx' height='160rpx' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23ededed' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23ededed' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23ededed' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23ededed' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23ededed' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3CanimateTransform attributeName='transform' begin='0s' dur='1s' type='rotate' values='0 40 40;360 40 40' repeatCount='indefinite'/%3E%3C/g%3E%3C/svg%3E%0A") no-repeat;
background-size:100%
}

BIN
assets/icon/eyes-close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
assets/icon/eyes-open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
assets/icon/fengkuai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
assets/icon/index/cash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
assets/icon/index/scan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
assets/icon/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
assets/img/login-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@ -0,0 +1,15 @@
.icon-phone{
width:1em;height:1em;
-webkit-mask-position:0 0;
mask-position:0 0;
-webkit-mask-repeat:no-repeat;
mask-repeat:no-repeat;
-webkit-mask-size:100%;
mask-size:100%;
background-color:currentColor;
-webkit-mask-image:var(--source-phone-svg);
mask-image:var(--source-phone-svg);
}
page{
--source-phone-svg:url(data:image/svg+xml,%3Csvg%20t%3D%221742979064029%22%20class%3D%22icon%22%20viewBox%3D%220%200%201024%201024%22%20version%3D%221.1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20p-id%3D%223164%22%20width%3D%22128%22%20height%3D%22128%22%3E%3Cpath%20d%3D%22M954.596304%20817.598116c-7.899924%2027.202549-46.462195%20143.561673-209.685673%20143.561673-11.472286%200-184.794773%2019.045775-447.109084-233.991242C38.23072%20476.774731%2062.450331%20317.6762%2063.531965%20281.640472c0.024559-0.827855%200.081864-1.657756%200.165776-2.481518%204.835122-47.709605%2017.900695-92.078115%2032.373315-117.0386%2027.745924-47.848775%2082.784448-80.335676%20111.205754-91.039459s51.957349-18.207687%2073.958432%2021.089317l88.575338%20144.790664c8.630564%2014.104229%2015.913435%2061.488423%201.910513%2075.491345-6.371104%206.104021-25.279756%2024.3772-39.531342%2035.003212-14.245446%2010.621918-27.423583%2021.86703-39.531342%2033.738405-12.097526%2011.871375-17.769712%2021.651113-18.153452%2029.300326-1.072425%2021.396309%2035.443233%20104.038518%20135.808082%20204.403367%2096.027054%2096.027054%20178.549535%20129.896442%20204.629517%20135.660726%207.461949%201.64957%2017.417695-6.0416%2029.330002-18.134009%2011.913331-12.091386%2023.168676-25.249057%2033.775244-39.48427%2010.605545-14.240329%2022.286586-27.403117%2035.047214-39.489386%2012.753465-12.091386%2043.455721-11.416004%2057.748239-3.13541l162.434509%2094.122681C958.089871%20756.566088%20970.091206%20764.752538%20954.596304%20817.598116L954.596304%20817.598116C954.596304%20817.598116%20967.021288%20774.815731%20954.596304%20817.598116z%22%20fill%3D%22%23272636%22%20p-id%3D%223165%22%3E%3C/path%3E%3C/svg%3E)
}

36
package-lock.json generated Normal file
View File

@ -0,0 +1,36 @@
{
"name": "beefast-mini-merchant",
"version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "beefast-mini-merchant",
"version": "0.0.1",
"license": "ISC",
"dependencies": {
"@beefast-wxmp/list-view": "^0.0.1",
"@beefast-wxmp/nav-bar": "^0.0.1",
"@beefast-wxmp/swipe-button": "^0.0.3"
}
},
"node_modules/@beefast-wxmp/list-view": {
"version": "0.0.1",
"resolved": "https://packages.aliyun.com/6486fc420ce788fc1c0798b3/npm/repo-glpby/@beefast-wxmp/list-view/-/@beefast-wxmp/list-view-0.0.1.tgz",
"integrity": "sha512-XoTaXRqy8EuuHECGS2zFzAeDKoGDtC56VdahnVYTAcDLNo3fceQuXI2KhOSvjnn4Jbkt1UDch7IEuF9Eekf9eg==",
"license": "ISC"
},
"node_modules/@beefast-wxmp/nav-bar": {
"version": "0.0.1",
"resolved": "https://packages.aliyun.com/6486fc420ce788fc1c0798b3/npm/repo-glpby/@beefast-wxmp/nav-bar/-/@beefast-wxmp/nav-bar-0.0.1.tgz",
"integrity": "sha512-nXbwGu31795qoSnHi5pzOmUWY7cbN+WPbAaA7UsG45Iae1k5AWfh2i65HenjtsN+jkVb/OMLDUcMYnqqEUb6RQ==",
"license": "ISC"
},
"node_modules/@beefast-wxmp/swipe-button": {
"version": "0.0.3",
"resolved": "https://packages.aliyun.com/6486fc420ce788fc1c0798b3/npm/repo-glpby/@beefast-wxmp/swipe-button/-/@beefast-wxmp/swipe-button-0.0.3.tgz",
"integrity": "sha512-uFWoaLSUpV636T0tYo7Lky80HvSUceucQl+C5M0sEjDAQYglbhVVCO6V711cRfp8KxmsMhsaFQwvSDmyKDf5BA==",
"license": "ISC"
}
}
}

16
package.json Normal file
View File

@ -0,0 +1,16 @@
{
"name": "beefast-mini-merchant",
"version": "0.0.1",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@beefast-wxmp/list-view": "^0.0.1",
"@beefast-wxmp/nav-bar": "^0.0.1",
"@beefast-wxmp/swipe-button": "^0.0.3"
}
}

View File

@ -0,0 +1,66 @@
// pages/index/index/index.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationStyle": "custom"
}

View File

@ -0,0 +1,33 @@
<view class="head">
<navigator url="/pages/product/list/index" class="items">
<image class="icon" src="/assets/icon/index/cash.png"/>
<view class="text">商品管理</view>
</navigator>
<view class="items">
<image class="icon" src="/assets/icon/index/scan.png"/>
<view class="text">扫一扫</view>
</view>
</view>
<view class="main">
<view class="row1">
<view class="cell row1-1">
<view class="title right-arrow">累计收益 (元)</view>
<view class="number">88</view>
</view>
<view class="cell row1-2">
<view class="title">订单笔数</view>
<view class="number">12</view>
</view>
</view>
<view class="row2">
<view class="cell">
<view class="title">昨日收益 (元)</view>
<view class="number">88</view>
</view>
<view class="spliter"></view>
<view class="cell">
<view class="title">今日收益 (元)</view>
<view class="number">88</view>
</view>
</view>
</view>

View File

@ -0,0 +1,75 @@
.head{
background-color: var(--main-color);
display: flex;
padding:220rpx 0 64rpx 0;
}
.head .items{
flex:1;
text-align: center;
}
.head .icon{
width:80rpx;height:80rpx;
}
.head .text{
font-size: 28rpx;
margin-top:30rpx;
}
.main{
background-color: var(--main-bgclolor);
padding:20rpx;
border-radius: 30rpx 30rpx 0 0;
margin-top:-22rpx;
}
.main .row1{
display: flex;
gap: 20rpx;
}
.main .row1 .cell{
border-radius: 16rpx;
background-color: #fff;
padding:40rpx 30rpx;
box-sizing: border-box;
}
.main .row1 .title{
color: #222222;
display: inline-block;
}
.main .row1 .number{
font-size: 60rpx;
font-weight: 600;
margin-top:40rpx;
}
.main .row1-1{
flex:1;
}
.main .row1-2{
width:250rpx;height:220rpx;
text-align: center;
}
.main .row2{
display: flex;
background-color: #fff;
border-radius: 16rpx;
margin-top:20rpx;
}
.main .row2 .cell{
flex:1;
text-align: center;
padding:50rpx 60rpx;
}
.main .row2 .title{
font-size: 27rpx;
color: #222222;
}
.main .row2 .spliter{
width:1rpx;height:auto;
background-color:rgba(153, 153, 153, 0.3);
margin:50rpx 0;
}
.main .row2 .number{
margin-top:40rpx;
font-size: 44rpx;
font-weight: 500;
}

89
pages/order/list/index.js Normal file
View File

@ -0,0 +1,89 @@
import orderApi from '../../../api/order';
import userApi from '../../../api/user';
Page({
/**
* 页面的初始数据
*/
data: {
orderCategory:['及时达','定时达'],
categoryIndex:0,
list:[{
status:'PENDING',
packages:[{},{}]
}],
pager:{limit:10,loading:false,loadAll:false,pageIndex:0,refreshTrigger:false},
orderStatus:orderApi.status,
genderKV:userApi.genderKV
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// orderApi.test({
// community_id:1,
// "user_id":3,"category_id":2,"name":"一乐拉面","business_hours":"08:00 - 21:00","address":"四川省成都市双流区怡心街道天府滨河湾(3号门)","longitude":104.046831,"latitude":30.518607,"phone":"13438370499","brand_image_url":"https://dman-1311994147.cos.ap-chengdu.myqcloud.com/uploads/1/ecb77b5a2d4075f6ff320070ac55f81c085e54b0_1e8ba893-9966-436e-90a4-63361f1fdf79.jpg"
// })
orderApi.list();
},
changeOrderCategory(event){
const index = event.currentTarget.dataset.index;
this.setData({
categoryIndex:index
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,8 @@
{
"usingComponents": {
"nav-bar":"/miniprogram_npm/@beefast-wxmp/nav-bar",
"list-view":"/miniprogram_npm/@beefast-wxmp/list-view",
"swipe-button":"/miniprogram_npm/@beefast-wxmp/swipe-button"
},
"navigationStyle": "custom"
}

View File

@ -0,0 +1,87 @@
<nav-bar>
<view class="order-category active{{categoryIndex}}" slot="left">
<view class="item {{categoryIndex==index?'current':''}}" data-index="{{index}}"
bind:tap="changeOrderCategory" wx:for="{{orderCategory}}" wx:key="index">{{item}}</view>
</view>
</nav-bar>
<view class="top-bar">
<view class="item">待接单(0)</view>
<view class="item">待配送(0)</view>
<view class="item">已送达(0)</view>
</view>
<view class="search">
<input class="input" placeholder="手机尾号查询"/>
<button class="button">搜索</button>
</view>
<list-view class="package-list main" bind:refresh="refreshList"
bind:loadMore="loadList" refresher-triggered="{{pager.refreshTrigger}}"
show-load-more="{{!(list.length==0&&pager.loadAll)}}"
loading="{{pager.loading}}" load-all="{{pager.loadAll}}">
<view wx:for="{{list}}" wx:key="index"
class="item {{item.status==orderStatus.unpaid||item.status==orderStatus.completed?'no-btns':''}} {{item.is_first_order?'is-new-order':''}} {{item.order_additional_fees.length>0?'has-markup':''}}">
<view bind:tap="navToOrderDetail" data-id="{{item.orderid}}" >
<view class="item-head">
<view class="tag">自营商品</view>
<view class="deliver-time">
剩余<label class="time">{{'59分钟'}}</label>(19:30前送达)
</view>
</view>
<view class="merchant">
<view class="name">
<view class="text">家庭私厨烤串【鲜货】</view>
<view class="count">x 1</view>
</view>
<view class="money">9.9</view>
</view>
<view class="address">
<view class="title">佳兆业丽晶公馆3栋2单元2702</view>
<view class="sub-title">
<view>{{'仙人模斗'}}{{genderKV['MALE']}}{{'13438370499'}}</view>
<view class="make-phone-tap-area">
<view class="make-phone">
<view class="icon-phone"/>
</view>
</view>
</view>
</view>
<view class="markup" wx:if="{{item.order_additional_fees.length>0}}">
<view class="mu-item" wx:for="{{item.order_additional_fees}}"
wx:for-item="mItem" wx:key="index">
【<label class="bold">{{markupStatusKV[mItem.result]}}</label>】加价金额:<label class="bold">{{mItem.additional_fee_amount}}元</label>
</view>
</view>
</view>
<view class="btns" wx:if="{{item.status==orderStatus.pending}}">
<button disabled="{{item.receiving}}" class="button more-btn" plain
capture-catch:tap="showMoreAS" data-item="{{item}}" data-index="{{index}}">
退单
</button>
<swipe-button class="swipe-button" loading="{{item.receiving}}" bind:done="getOrder"
data-item="{{item}}" data-index="{{index}}" button-text="我要接单"
button-loading-text="接单中..." capture-catch:tap="emptyFun"/>
</view>
<view class="btns" wx:if="{{item.status==orderStatus.received}}">
<button disabled="{{item.receiving}}" class="button more-btn" plain
capture-catch:tap="showMoreAS" data-item="{{item}}" data-index="{{index}}">
<view class="icon"></view>
</button>
<swipe-button class="swipe-button" loading="{{item.receiving}}" bind:done="receivedOrder"
data-item="{{item}}" data-index="{{index}}" button-text="我已取货"
button-loading-text="取货中..." capture-catch:tap="emptyFun"/>
</view>
<view class="btns" wx:if="{{item.status==orderStatus.delivering}}">
<!-- <button class="button concat-user-btn" capture-catch:tap="concatUser"
data-item="{{item}}">
<image class="icon" src="/assets/icon/phone.png"></image>
<label>联系用户</label>
</button> -->
<button disabled="{{item.receiving}}" class="button more-btn" plain
capture-catch:tap="showMoreAS" data-item="{{item}}" data-index="{{index}}">
<view class="icon"></view>
</button>
<button type="primary" class="confirm-send-btn"
capture-catch:tap="confirmSend" data-item="{{item}}">我已送达</button>
</view>
</view>
</list-view>

286
pages/order/list/index.wxss Normal file
View File

@ -0,0 +1,286 @@
.order-category{
background-color: rgba(153, 153, 153, 0.3);
display: flex;
border-radius: 12rpx;
position: relative;
padding:0 12rpx;
}
.order-category::before{
content: '';
position: absolute;
top:6rpx;bottom:6rpx;
width:140rpx;
background-color: #fff;
border-radius: 8rpx;
transition-duration: .4s;
/* transition-timing-function:cubic-bezier(0.215, 0.61, 0.355, 1); */
transition-timing-function:cubic-bezier(.26,.9,.31,.97);
}
.order-category.active0::before{
right:auto;left:6rpx;
}
.order-category.active1::before{
left:126rpx;
}
.order-category .item{
padding:16rpx 22rpx;
position: relative;
white-space: nowrap;
font-size: 28rpx;
}
.order-category .item.current{
font-weight: 600;
}
.top-bar{
display: flex;
justify-content: space-between;
padding:40rpx 0;
}
.top-bar .item{
font-size: 28rpx;
padding:0 50rpx
}
.top-bar .item.current{
font-weight: 500;
font-size: 32rpx;
}
.search{
margin:0 16rpx;
background-color: #fff;
padding:10rpx 10rpx 10rpx 40rpx;
display: flex;
align-items: center;
border-radius: 60rpx;
}
.search .input{
flex:1;
height:56rpx;
}
.search .button{
border-radius: 60rpx;
font-size: 28rpx;
padding:14rpx 30rpx;
line-height: 1;
font-weight: normal;
background-color: rgba(153, 153, 153, 0.3);
}
.package-list .item{
margin:16rpx;
background-color: #ffffff;
border-radius: 18rpx;
color: #555555;
padding:20rpx;
position: relative;
}
.package-list .item .item-head{
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom:50rpx;
}
.package-list .item .item-head .tag{
background-color: rgba(153, 153, 153, 0.1);
border-radius: 12rpx;
padding:16rpx 20rpx;
font-weight: 500;
color:#555555;
}
.package-list .item .item-head .deliver-time{
color:#222222;
}
.package-list .item .item-head .time{
color:#ff0000;
font-weight: 500;
}
.package-list .item::before{
content: '';
position: absolute;
width:1.2rpx;
background-color: rgba(85, 85, 85, 0.5);
left:38.5rpx;top:160rpx;
bottom:250rpx;
}
.package-list .item.has-markup::before{
bottom:200rpx;
}
.package-list .item.no-btns::before{
bottom:100rpx;
}
.package-list .item.no-btns.has-markup::before{
bottom:50rpx;
}
.package-list .item .name{
font-size: 40rpx;
display: flex;
white-space: nowrap;
}
.package-list .item .name .text{
overflow: hidden;
text-overflow: ellipsis;
font-weight: 600;
flex:1;
}
.package-list .item .received-status{
border-left: 1rpx solid #999999;
padding-left:18rpx;
color:var(--main-color);
}
.package-list .item .received-status.done{
color:unset;
}
.package-list .item .merchant{
position: relative;
padding-left:64rpx;
padding-bottom:80rpx;
}
.package-list .item .merchant .money{
font-size: 40rpx;
margin-top:24rpx;
}
.package-list .item .merchant::before{
position: absolute;
left:12rpx;top:12rpx;
width:16rpx;height:16rpx;
content: '';
background-color: #555555;
border-radius: 50%;
display: inline-block;
}
.package-list .item .merchant::before,
.package-list .item .address::before,
.package-list .item .markup .mu-item::before{
position: absolute;
content: '商';
left:0;top:0;
width:40rpx;height:40rpx;
color:#fff;
font-size: 24rpx;
text-align: center;
line-height: 40rpx;
border-radius: 50%;
}
.package-list .item .address::before{
content: '送';
background-color: var(--main-color);
}
.package-list .item .markup{
font-size: 34rpx;
line-height: 40rpx;
padding-bottom:20rpx;
color: var(--main-font-color);
}
.package-list .item .markup .bold{
font-weight: 500;
}
.package-list .item .markup .mu-item{
padding-left:48rpx;
position: relative;
display: flex;
align-items: center;
margin-top:30rpx;
}
.package-list .item .markup .mu-item::before{
content: '加';
background-color:#ff0000;
}
/* .package-list .item .package .value{
flex:1;
display: flex;
flex-wrap: wrap;
gap: 16rpx;
} */
.package-list .item .address{
padding-left:64rpx;
position: relative;
padding-bottom:20rpx;
}
.package-list .item .address .title{
color:var(--main-font-color);
font-size: 40rpx;
font-weight: 600;
}
.package-list .item .address .sub-title{
font-size: 32rpx;
margin-top:14rpx;
display:flex;
justify-content: space-between;
align-items: center;
}
.package-list .item .address .sub-title .make-phone-tap-area{
padding:10rpx
}
.package-list .item .address .sub-title .make-phone{
border:1.2rpx solid rgba(254, 196, 0, 0.5);
border-radius: 50%;
color: rgb(255, 195, 0);
padding:10rpx;
font-size:24rpx;
}
.package-list .item.is-new-order .address .sub-title::before{
content:'新';
background-color:#ff0000;
color:#fff;
font-size: 24rpx;
margin-right: 12rpx;
border-radius: 8rpx;
padding:6rpx 8rpx;
}
.package-list .item .btns{
display: flex;
gap:24rpx;
margin-top:30rpx;
}
.package-list .item .btns .button{
height:96rpx;
line-height: 1;
border-radius: 12rpx;
border: 1.2px solid rgba(85, 85, 85, 0.5);
color: #555555;
font-weight: normal;
padding:30rpx 40rpx;
margin:0;
}
.package-list .item .btns .more-btn{
width:200rpx;
display: flex;
align-items: center;
justify-content: center;
}
.package-list .item .btns .more-btn .icon,
.package-list .item .btns .more-btn .icon::before,
.package-list .item .btns .more-btn .icon::after{
width:16rpx;height:16rpx;
background: #555555;
border-radius: 50%;
position: relative;
overflow: visible;
}
.package-list .item .btns .more-btn .icon::before{
content:'';
position:absolute;
left:-36rpx;top:0;
}
.package-list .item .btns .more-btn .icon::after{
content:'';
position:absolute;
left:36rpx;top:0;
}
.package-list .item .btns .more-btn[disabled]{
color:#999;
border-color:rgb(221, 219, 219);
}
.package-list .item .btns .swipe-button{
height:96rpx;
flex:1;
}

View File

@ -0,0 +1,66 @@
// pages/product/list/index.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,6 @@
{
"usingComponents": {
"list-view":"/miniprogram_npm/@beefast-wxmp/list-view"
},
"navigationBarTitleText": "商品列表"
}

View File

@ -0,0 +1,53 @@
<list-view class="product-list">
<view class="item off">
<view class="info">
<image class="avatar" src="https://dman-1311994147.cos.ap-chengdu.myqcloud.com/uploads/1/u=1903565391,3902265682&fm=253&fmt=auto&app=138&f=JPEG_27e027fc-fa01-42a8-821d-d2ba31706f86.webp?imageMogr2/thumbnail/800x800/format/webp"/>
<view class="right">
<view class="name">家庭私厨烤串【鲜货】</view>
<view class="tags">及时达丨配送</view>
<view class="money">9.9</view>
</view>
</view>
<view class="stat">
<view class="s-item">
<view class="value">0.0</view>
<view class="key">累计销售额 (元)</view>
</view>
<view class="s-item">
<view class="value">0.0</view>
<view class="key">累计收益(元)</view>
</view>
<view class="s-item">
<view class="value">1/4</view>
<view class="key">已售出/库存量</view>
</view>
</view>
<view class="actions">
<button size="mini" type="primary" class="button">操作</button>
</view>
</view>
<view class="item">
<view class="info">
<image class="avatar" src="https://dman-1311994147.cos.ap-chengdu.myqcloud.com/uploads/1/u=1903565391,3902265682&fm=253&fmt=auto&app=138&f=JPEG_27e027fc-fa01-42a8-821d-d2ba31706f86.webp?imageMogr2/thumbnail/800x800/format/webp"/>
<view class="right">
<view class="name">家庭私厨烤串【鲜货】</view>
<view class="tags">及时达丨配送</view>
<view class="money">9.9</view>
</view>
</view>
<view class="stat">
<view class="s-item">
<view class="value">0.0</view>
<view class="key">累计销售额 (元)</view>
</view>
<view class="s-item">
<view class="value">0.0</view>
<view class="key">累计收益(元)</view>
</view>
<view class="s-item">
<view class="value">1/4</view>
<view class="key">已售出/库存量</view>
</view>
</view>
</view>
</list-view>

View File

@ -0,0 +1,73 @@
.product-list .item{
background-color: #fff;
margin:20rpx;
padding:30rpx;
border-radius: 18rpx;
}
.product-list .item .info{
display: flex;
}
.product-list .item .avatar{
width:180rpx;height:140rpx;
border-radius: 10rpx;
position: relative;
}
.product-list .item.off .avatar::before{
content: '已下架';
position: absolute;
width:100%;height:100%;
background-color: rgba(0, 0, 0, .5);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
font-weight: 500;
}
.product-list .item .right{
margin-left:20rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 140rpx;
}
.product-list .item .name{
font-weight: 500;
font-size: 32rpx;
}
.product-list .item .tags{
color:#555;
font-size:26rpx;
}
.product-list .item .stat{
display: flex;
justify-content: space-between;
padding:40rpx 0 60rpx 0;
}
.product-list .item .s-item{
text-align: center;
}
.product-list .item .s-item .key{
margin-top:20rpx;
font-size: 26rpx;
color: #555;
}
.product-list .item .s-item .value{
font-size: 40rpx;
font-weight: 600;
}
.actions{
display: flex;
justify-content: flex-end;
gap: 20rpx;
}
.actions .button{
background-color: #000;
font-size: 28rpx;
color:#fff;
padding:18rpx 52rpx;
line-height: 1;
margin:0;
}

66
pages/user/index/index.js Normal file
View File

@ -0,0 +1,66 @@
// pages/user/index/index.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationStyle": "custom"
}

View File

@ -0,0 +1,25 @@
<view class="head">
<view class="user">
<image src="/assets/icon/logo.png" class="avatar"/>
<view class="name">仙人模斗</view>
</view>
</view>
<view class="page-container actions">
<view class="item">
<image class="icon" src="/assets/icon/user/service.png"/>
<view class="text">在线客服</view>
</view>
<navigator url="/pages/user/password/index" class="item">
<image class="icon" src="/assets/icon/user/password.png"/>
<view class="text">修改密码</view>
</navigator>
<view class="item">
<image class="icon" src="/assets/icon/user/agreement.png"/>
<view class="text">用户协议</view>
</view>
</view>
<view class="page-container bg-notice">
<view class="">语音播报</view>
<switch/>
</view>
<button class="btn-logout" type="primary">退出登录</button>

View File

@ -0,0 +1,51 @@
.head{
background-color: var(--main-color);
height:480rpx;
position: relative;
border-radius: 0 0 40rpx 40rpx;
}
.head .user{
display: flex;
align-items: center;
position: absolute;
bottom:144rpx;
font-size: 36rpx;
padding:0 40rpx;
}
.head .user .avatar{
width:120rpx;height:120rpx;
border:3rpx solid #fff;
border-radius: 50%;
margin-right: 28rpx;
}
.actions{
display: flex;
align-items: center;
justify-content: space-between;
padding:48rpx 0;
margin-top:-120rpx;
position: relative;
}
.actions .item{
padding:0 50rpx;
text-align: center;
}
.actions .icon{
width:56rpx;height:56rpx;
}
.actions .text{
margin-top:40rpx;
}
.bg-notice{
display:flex;
align-items: center;
justify-content: space-between;
}
.btn-logout{
margin:20rpx!important;
background-color: #fff!important;
font-weight: normal;
color: #555555;
}

137
pages/user/login/index.js Normal file
View File

@ -0,0 +1,137 @@
import userApi from '../../../api/user';
import {validateForm} from '../../../utils/util';
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
phone:'',
password:'',
logining:false,
isAgree:false,
isEyesOpen:false,
appConfig:{}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.validator = {
phone:{type:'phone',message:'请输入正确的手机号',shake:true,autoFocus:true},
password:{minLength:6,message:'请输入 6 位数密码',shake:true,autoFocus:true}
}
app.getAppConfig().then((data)=>{
this.setData({
appConfig:data
})
})
},
login(){
if(this.data.isAgree){
const valid = validateForm(this.validator,this);
console.log(valid,this.validator);
if(valid.length==0){
this.setData({
logining:true
})
userApi.login(this.data.phone,this.data.password).then((data)=>{
this.setData({
logining:false
})
app.globalData.userInfo = data.user;
app.globalData.accessToken = data.access_token;
wx.setStorage({
key:'accessToken',
data:data.access_token,
success:()=>{
wx.reLaunch({
url: '/pages/index/index/index',
})
}
})
}).catch(()=>{
console.log('catch');
this.setData({
logining:false
})
})
}
}else{
validateForm({
shake:{required:true,shake:true}
},this);
}
},
handleAgreeChange(event){
this.setData({
isAgree:!!event.detail
})
},
toggleEyes(){
this.setData({
isEyesOpen:!this.data.isEyesOpen
})
},
navToAgreement(){
wx.navigateTo({
url: `/pages/browser/index?url=${encodeURIComponent(this.data.appConfig.url_user_agreement)}`,
})
},
navToPrivacy(){
wx.navigateTo({
url: `/pages/browser/index?url=${encodeURIComponent(this.data.appConfig.url_user_privacy)}`,
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationStyle": "custom"
}

View File

@ -0,0 +1,36 @@
<view class="login">
<view class="head">
<image src="/assets/img/login-bg.png" class="bg"/>
<image src="/assets/icon/logo.png" class="logo"/>
<view class="title">
欢迎使用
<image src="/assets/icon/fengkuai.png" class="t-logo" mode="heightFix"/>
</view>
</view>
<view class="input-area">
<view class="input-container">
<input class="input" model:value="{{phone}}" placeholder="请输入手机号"
animation="{{phoneAnimation}}" focus="{{phoneFocus}}" placeholder-class="ph-class"/>
</view>
<view class="input-container">
<input class="input" model:value="{{password}}" placeholder="请输入密码"
animation="{{passwordAnimation}}" focus="{{passwordFocus}}"
placeholder-class="ph-class" password="{{!isEyesOpen}}"/>
<image src="{{isEyesOpen?'/assets/icon/eyes-open.png':'/assets/icon/eyes-close.png'}}" class="icon" bind:tap="toggleEyes"/>
</view>
<view class="forgot-pwd">
<navigator url="/pages/user/password/index" class="forgot">忘记密码</navigator>
</view>
<button bind:tap="login" type="primary" class="button" loading="{{logining}}"
disabled="{{logining}}">登录</button>
<radio-group bindchange="handleAgreeChange" class="agree" animation="{{shakeAnimation}}">
<label class="policy">
<radio class="radio" value="agree"></radio>
<label>我已阅读并同意</label>
<label capture-catch:tap="navToAgreement" class="yellow">《用户协议》</label>与
<label capture-catch:tap="navToPrivacy" class="yellow">《隐私政策》</label>
</label>
</radio-group>
</view>
</view>

View File

@ -0,0 +1,95 @@
.login{
background-color: #fff;
height:100vh;
}
.login .head{
background-color: var(--main-color);
position: relative;
height:554rpx;
}
.login .head .bg{
width: 450rpx;height:486rpx;
position: absolute;
right:-40rpx;top:204rpx;
}
.login .head .title{
font-size: 40rpx;
position: absolute;
left:40rpx;
font-weight: 500;
bottom:140rpx;
display: flex;
align-items: center;
}
.login .head .title .t-logo{
height: 36rpx;
margin-left: 10rpx;
}
.login .head .logo{
position: absolute;
width: 136rpx;height: 136rpx;
bottom:218rpx;left:54rpx;
}
.login .input-area{
border-radius: 30rpx 30rpx 0px 0px;
margin-top:-80rpx;
background-color: #fff;
position: relative;
padding:16rpx 50rpx 40rpx 50rpx;
}
.input-container{
display: flex;
align-items: center;
background-color:#F7F7F7;
border-radius: 18rpx;
margin-top:24rpx;
padding-left:30rpx;
}
.login .input-area .input{
height: 100rpx;
font-weight: 500;
font-size: 36rpx;
}
.login .input-area .ph-class{
font-weight: normal;
font-size: 32rpx;
}
.input-container .input{
flex: 1;
}
.input-container .icon{
width:44rpx;height:44rpx;
padding:20rpx;
}
.login .input-area .input.error{
background-color: rgb(252, 198, 198);
}
.login .input-area .forgot-pwd{
display:flex;
justify-content: flex-end;
}
.login .input-area .forgot{
color:#888888;
font-size:24rpx;
padding:30rpx 0 30rpx 30rpx;
}
.login .input-area .button{
border-radius: 20rpx;
}
.agree{
font-size: 28rpx;
margin-top:50rpx;
text-align: center;
}
.agree .yellow{
color:var(--main-color);
margin: 0;
}
.agree .policy{
display: inline-flex;
align-items: center;
}

View File

@ -0,0 +1,165 @@
const app = getApp();
import userApi from '../../../api/user';
Page({
verifyCodeTimer:null,
/**
* 页面的初始数据
*/
data: {
phone:'',
isLogin:false,
verifyCode:'',
password:'',
rePassword:'',
codeLoading:false,
getCodeBtnText:'获取验证码',
waitingTime:app.verifyCodeWaitingTime,
modifyLoading:false
},
validator:{
phone:{
type:'phone',autoFocus:true,shake:true,message:'请输入正确的手机号码'
},
verifyCode:[
{required:true,message:'请输入验证码',shake:true,autoFocus:true},
// {length:6,message:'请输入 6 位数验证码',shake:true,autoFocus:true}
],
password:{minLength:6,message:'请输入至少 6 位新密码',shake:true,autoFocus:true},
rePassword:{minLength:true,message:'请输入确认新密码',shake:true,autoFocus:true},
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.setData({
phone:app.globalData.userInfo?.phone||'',
isLogin:!!app.globalData.userInfo?.phone
})
let time = wx.getStorageSync('password-verify-code-time');
if(time){
let remainTime = app.verifyCodeWaitingTime*1000 - ((new Date()).getTime() - time);
if(remainTime>0){
this.setData({
waitingTime:parseInt(remainTime/1000),
codeLoading:true
})
this.startTimer();
}else{
wx.removeStorageSync('password-verify-code-time')
}
}
},
getVerifyCode(){
if(this.data.codeLoading)return;
this.setData({
codeLoading:true
});
userApi.verifyCode(this.data.phone).then((data)=>{
this.setData({
getCodeBtnText:`${this.data.waitingTime}S`
});
const time = new Date();
wx.setStorageSync('password-verify-code-time', time.getTime());
this.startTimer();
})
},
startTimer(){
if(this.data.waitingTime<=0){
this.setData({
codeLoading:false,
getCodeBtnText:'获取验证码',
waitingTime:app.verifyCodeWaitingTime
});
wx.removeStorageSync('password-verify-code-time')
}else{
this.setData({
getCodeBtnText:`${this.data.waitingTime--}S`
});
this.verifyCodeTimer = setTimeout(this.startTimer,1000);
}
},
save(){
if(this.data.modifyLoading)return;
const valid = app.validateForm(this.validator,this);
if(valid.length==0){
if(this.data.password==this.data.rePassword){
this.setData({
rePasswordMessage:''
});
this.setData({
modifyLoading:true
});
userApi.modifyPassword(this.data.phone,this.data.rePassword,this.data.verifyCode).then((data)=>{
wx.navigateBack({
success(){
wx.showToast({
icon:'success',
title: '修改成功',
})
}
})
}).catch(()=>{
console.log(11111,'errro');
this.setData({
modifyLoading:false
})
})
}else{
this.setData({
rePasswordMessage:'两次密码不一致'
})
}
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
clearTimeout(this.verifyCodeTimer);
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationBarTitleText": "修改密码"
}

View File

@ -0,0 +1,41 @@
<view class="cells">
<view class="cell">
<view class="cell-hd">手机号码</view>
<view class="cell-bd">
<input placeholder="请输入手机号码" model:value="{{phone}}" disabled="{{isLogin}}"
animation="{{phoneAnimation}}" focus="{{phoneFocus}}"/>
<view class="error">{{phoneMessage}}</view>
</view>
</view>
<view class="cell">
<view class="cell-hd">验证码</view>
<view class="cell-bd">
<input placeholder="请输入验证码" model:value="{{verifyCode}}"
animation="{{verifyCodeAnimation}}" focus="{{verifyCodeFocus}}"/>
<view class="error">{{verifyCodeMessage}}</view>
</view>
<view class="cell-ft">
<button size="mini" type="primary" disabled="{{codeLoading}}"
bind:tap="getVerifyCode" class="verify-btn">
{{getCodeBtnText}}
</button>
</view>
</view>
<view class="cell">
<view class="cell-hd">新密码</view>
<view class="cell-bd">
<input placeholder="请输入新密码" model:value="{{password}}"
animation="{{passwordAnimation}}" focus="{{passwordFocus}}"/>
<view class="error">{{passwordMessage}}</view>
</view>
</view>
<view class="cell">
<view class="cell-hd">确认新密码</view>
<view class="cell-bd">
<input placeholder="请确认新密码" model:value="{{rePassword}}"
animation="{{rePasswordAnimation}}" focus="{{rePasswordFocus}}"/>
<view class="error">{{rePasswordMessage}}</view>
</view>
</view>
<button type="primary" class="save-btn" bind:tap="save" loading="{{modifyLoading}}">修改并保存</button>
</view>

View File

@ -0,0 +1,15 @@
.verify-btn{
font-weight: normal;
}
.verify-btn[disabled]{
background-color: #fff;
border: 2rpx solid var(--main-color);
color:var(--main-color)!important;
}
.cells .cell-hd{
width:155rpx;
}
.save-btn{
margin:60rpx 30rpx 30rpx!important;
}

41
project.config.json Normal file
View File

@ -0,0 +1,41 @@
{
"appid": "wx786f8357a4a09fd1",
"compileType": "miniprogram",
"libVersion": "trial",
"packOptions": {
"ignore": [],
"include": []
},
"setting": {
"coverView": true,
"es6": true,
"postcss": true,
"minified": true,
"enhance": true,
"showShadowRootInWxmlPanel": true,
"packNpmRelationList": [],
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"compileWorklet": false,
"uglifyFileName": false,
"uploadWithSourceMap": true,
"packNpmManually": true,
"minifyWXSS": true,
"minifyWXML": true,
"localPlugins": false,
"condition": false,
"swc": false,
"disableSWC": true,
"disableUseStrict": false,
"useCompilerPlugins": false
},
"condition": {},
"editorSetting": {
"tabIndent": "auto",
"tabSize": 2
},
"simulatorPluginLibVersion": {}
}

View File

@ -0,0 +1,23 @@
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "beefast-mini-merchant",
"setting": {
"compileHotReLoad": true,
"skylineRenderEnable": true,
"urlCheck": true,
"coverView": true,
"lazyloadPlaceholderEnable": false,
"preloadBackgroundData": false,
"autoAudits": false,
"useApiHook": true,
"useApiHostProcess": true,
"showShadowRootInWxmlPanel": true,
"useStaticServer": false,
"useLanDebug": false,
"showES6CompileOption": false,
"bigPackageSizeSupport": false,
"checkInvalidKey": true,
"ignoreDevUnusedFiles": true
},
"libVersion": "3.7.11"
}

7
sitemap.json Normal file
View File

@ -0,0 +1,7 @@
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}

95
utils/util.js Normal file
View File

@ -0,0 +1,95 @@
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : `0${n}`
}
const validateForm = (rules,page)=>{
const result = [];
for(var key in rules){
((rules[key] instanceof Array)?rules[key]:[rules[key]]).map((item)=>{
let valid = true;
let value = page.data[key];
if(typeof value=='string'){
value = value.trim();
}
//非空
if(item.required){
if(!value){
valid = false;
}
}else if(item.length){
//绝对长度
if(value.length!=item.length){
valid = false;
}
}else if(item.type=='phone'){
if(value.length!=11){
valid = false;
}
}else if(item.maxLength||item.minLength){
if(value.length>(item.maxLength||Infinity)||value.length<item.minLength||0){
valid = false
}
}else if(item.min){
if(value<item.min){
valid = false;
}
}
if(valid){
page.setData({
[`${key}Message`]:''
});
}else{
if(item.message){
page.setData({
[`${key}Message`]:item.message
});
}
result.push({
[key]:item.message,autoFocus:item.autoFocus,key:key,shake:item.shake
})
}
})
}
const focusInput = result.find((item)=>item.autoFocus);
if(focusInput){
page.setData({
[`${focusInput.key}Focus`]:true
})
}
const shakeInput = result.find((item)=>item.shake);
if(shakeInput){
if(!shakeInput.animation){
shakeInput.animation = wx.createAnimation({
duration: 20,
})
}
shakeInput.animation.translateX(10).step();
shakeInput.animation.translateX(-10).step();
shakeInput.animation.translateX(10).step();
shakeInput.animation.translateX(-10).step();
shakeInput.animation.translateX(5).step();
shakeInput.animation.translateX(0).step();
// needSetData[`${key}Animation`] = item.animation.export();
page.setData({
[`${shakeInput.key}Animation`]:shakeInput.animation.export()
})
}
return result;
}
module.exports = {
formatTime,
validateForm
}