Browse Source

feat: page-login;

pull/1/head
Fox-33 3 months ago
parent
commit
2644ffa1b5
29 changed files with 1215 additions and 232 deletions
  1. +7
    -0
      components/base/tabbar.vue
  2. +9
    -0
      pages.json
  3. +315
    -0
      pages/index/center.vue
  4. +115
    -0
      pages_order/auth/agreementConfirmPopup.vue
  5. +137
    -135
      pages_order/auth/wxLogin.vue
  6. +325
    -97
      pages_order/auth/wxUserInfo.vue
  7. +91
    -0
      pages_order/center/orderCard.vue
  8. +56
    -0
      pages_order/center/popupQrCode.vue
  9. +15
    -0
      pages_order/center/styles/card.scss
  10. +99
    -0
      pages_order/components/agreementModal.vue
  11. +46
    -0
      pages_order/components/formInput.vue
  12. BIN
      pages_order/static/auth/avatar.png
  13. BIN
      pages_order/static/center/avatar-default.png
  14. BIN
      pages_order/static/center/icon-aboutUs.png
  15. BIN
      pages_order/static/center/icon-change.png
  16. BIN
      pages_order/static/center/icon-comment.png
  17. BIN
      pages_order/static/center/icon-detectBook.png
  18. BIN
      pages_order/static/center/icon-instruc.png
  19. BIN
      pages_order/static/center/icon-logout.png
  20. BIN
      pages_order/static/center/icon-modifyInfo.png
  21. BIN
      pages_order/static/center/icon-service.png
  22. BIN
      pages_order/static/center/icon-userAgreement.png
  23. BIN
      pages_order/static/center/order-1.png
  24. BIN
      pages_order/static/center/order-2.png
  25. BIN
      pages_order/static/center/order-3.png
  26. BIN
      pages_order/static/center/order-4.png
  27. BIN
      pages_order/static/center/order-5.png
  28. BIN
      static/image/center-bg.png
  29. BIN
      static/image/temp-29.png

+ 7
- 0
components/base/tabbar.vue View File

@ -43,6 +43,13 @@
"title": "分类",
key: 'category',
},
{
"selectedIconPath": "/static/image/tabbar/user-center-active.png",
"iconPath": "/static/image/tabbar/user-center.png",
"pagePath": "/pages/index/center",
"title": "我的",
key: 'center',
},
]
};
},


+ 9
- 0
pages.json View File

@ -11,6 +11,15 @@
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/index/center",
"style": {
"navigationBarTitleText": "",
"componentPlaceholder": {
"order-card": "view"
}
}
}
],
"preloadRule": {


+ 315
- 0
pages/index/center.vue View File

@ -0,0 +1,315 @@
<template>
<view class="page__view">
<image class="bg" src="@/static/image/center-bg.png" mode="widthFix"></image>
<view class="main">
<view class="content">
<view class="flex user">
<!-- 用户信息 -->
<template v-if="isLogin">
<view class="user-avatar">
<image class="user-avatar-img" :src="userInfo.avatar" mode="scaleToFill"></image>
</view>
<view class="user-info">
<view class="user-info-name">{{ userInfo.name }}</view>
<view class="user-info-desc">{{ userInfo.phone }}</view>
</view>
</template>
<template v-else>
<view class="user-avatar is-default">
<image class="user-avatar-img" src="@/pages_order/static/center/avatar-default.png" mode="scaleToFill"></image>
</view>
<view class="user-info">
<view class="user-info-tips">暂未登录 请先登录</view>
</view>
</template>
</view>
<!-- 订单信息 -->
<template v-if="isLogin">
<order-card :statistics="statistics"></order-card>
</template>
<!-- 用户菜单 -->
<template v-if="isLogin">
<view class="card">
<view v-for="item in list1" :key="item.id">
<template v-if="item.key === 'service'">
<button plain class="flex btn-service" open-type="contact">
<view class="flex row">
<view class="flex label">
<image class="icon" :src="item.icon" mode="scaleToFill"></image>
<view>{{ item.label }}</view>
</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="24rpx"></uv-icon>
</view>
</button>
</template>
<view v-else class="flex row" @click="onClick(item)">
<view class="flex label">
<image class="icon" :src="item.icon" mode="scaleToFill"></image>
<view>{{ item.label }}</view>
</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="24rpx"></uv-icon>
</view>
</view>
</view>
<view class="card">
<view v-for="item in list2" :key="item.id">
<view class="flex row" @click="onClick(item)">
<view class="flex label">
<image class="icon" :src="item.icon" mode="scaleToFill"></image>
<view>{{ item.label }}</view>
</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="24rpx"></uv-icon>
</view>
</view>
</view>
</template>
<!-- 用户登陆 -->
<template v-else>
<view class="login">
<button class="btn" @click="$utils.toLogin">立即登录</button>
<view class="tips">暂未登录 请先登录</view>
</view>
</template>
</view>
<tabber select="center" />
</view>
</view>
</template>
<script>
import { mapState } from 'vuex'
import tabber from '@/components/base/tabbar.vue'
import orderCard from '@/pages_order/center/orderCard.vue'
export default {
components: {
orderCard,
tabber,
},
data() {
return {
statistics: {},
list1: [
{ id: '001', label: '检测预约', icon: '/pages_order/static/center/icon-detectBook.png', path: '/pages_order/checkup/checkupRecords' },
{ id: '002', label: '联系客服', icon: '/pages_order/static/center/icon-service.png', key: 'service' },
// todo: check key
{ id: '003', label: '服用说明', icon: '/pages_order/static/center/icon-instruc.png', path: `/pages_order/common?key=instruc&title=服用说明` },
// todo: check key
{ id: '004', label: '用户须知', icon: '/pages_order/static/center/icon-userAgreement.png', path: `/pages_order/common?key=userAgreement&title=用户须知` },
],
list2: [
{ id: '005', label: '我的评价', icon: '/pages_order/static/center/icon-comment.png', key: 'comment' },
// todo: check key
{ id: '006', label: '关于我们', icon: '/pages_order/static/center/icon-aboutUs.png', path: `/pages_order/common?key=aboutUs&title=关于我们` },
{ id: '007', label: '修改信息', icon: '/pages_order/static/center/icon-modifyInfo.png', path: `/pages_order/auth/wxUserInfo?mode=edit` },
{ id: '008', label: '退出登录', icon: '/pages_order/static/center/icon-logout.png', key: 'logout' },
],
}
},
computed: {
...mapState(['userInfo', 'configList']),
isLogin() {
return this.userInfo && this.userInfo.id
}
},
onShow() {
if(uni.getStorageSync('token')){
this.$store.commit('getUserInfo')
this.fetchOrderStatistics()
}
},
methods: {
onClick(target) {
const { key, path } = target
switch(key) {
case 'comment':
this.$utils.navigateTo('/pages_order/comment/commentRecords')
break
case 'logout':
this.$store.commit('logout')
break
default:
path && this.$utils.navigateTo(path)
break
}
},
async fetchOrderStatistics() {
return
try {
this.statistics = await this.$fetch('getOrderStatistics', { id: '' })
} catch (err) {
}
},
},
}
</script>
<style scoped lang="scss">
.page__view {
width: 100vw;
min-height: 100vh;
background-color: $uni-bg-color;
position: relative;
/deep/ .nav-bar__view {
position: fixed;
top: 0;
left: 0;
}
.nav-icon {
width: 200rpx;
height: auto;
vertical-align: top;
}
}
.bg {
width: 100vw;
height: auto;
}
.main {
position: absolute;
top: 176rpx;
left: 0;
width: 100%;
}
.content {
width: 100%;
padding: 16rpx 32rpx 80rpx 32rpx;
box-sizing: border-box;
}
.user {
column-gap: 24rpx;
&-avatar {
flex: none;
width: 100rpx;
height: 100rpx;
border: 4rpx solid #FFFFFF;
border-radius: 50%;
overflow: hidden;
&.is-default {
width: 108rpx;
height: 108rpx;
border: none;
}
&-img {
width: 100%;
height: 100%;
}
}
&-info {
flex: 1;
&-name {
font-family: PingFang SC;
font-weight: 600;
font-size: 36rpx;
line-height: 1.2;
color: #FFFFFF;
}
&-desc {
margin-top: 8rpx;
font-family: PingFang SC;
font-weight: 400;
font-size: 24rpx;
line-height: 1.5;
color: #F4F4F4;
}
&-tips {
font-family: PingFang SC;
font-weight: 400;
font-size: 36rpx;
line-height: 1.2;
color: #FFFFFF;
}
}
}
.card {
margin-top: 32rpx;
width: 100%;
background: #FAFAFF;
border: 2rpx solid #FFFFFF;
border-radius: 32rpx;
box-sizing: border-box;
.row {
justify-content: space-between;
width: 100%;
padding: 40rpx;
box-sizing: border-box;
.label {
font-family: PingFang SC;
font-weight: 400;
font-size: 28rpx;
line-height: 1;
color: #252545;
.icon {
margin-right: 16rpx;
width: 40rpx;
height: 40rpx;
}
}
}
}
.btn-service {
border: none;
padding: 0;
}
.login {
margin-top: 307rpx;
padding: 0 128rpx;
.btn {
padding: 16rpx 0;
font-family: PingFang SC;
font-weight: 500;
font-size: 36rpx;
line-height: 1.4;
color: #FFFFFF;
background-image: linear-gradient(to right, #21FEEC, #019AF9);
border-radius: 41rpx;
}
.tips {
margin-top: 16rpx;
text-align: center;
font-family: PingFang SC;
font-weight: 400;
font-size: 26rpx;
line-height: 1.4;
color: #A3A3A3;
}
}
</style>

+ 115
- 0
pages_order/auth/agreementConfirmPopup.vue View File

@ -0,0 +1,115 @@
<template>
<view>
<uv-popup ref="popup" :round="24">
<view class="popup__view">
<view class="header">
用户隐私保护提示
</view>
<view class="content">
在你使用 鸿宇研学生服务之前请仔细阅读
<text class="highlight" @click="$refs.modal.open('user_ys', '用户服务协议')">用户服务协议</text>
<text class="highlight" @click="$refs.modal.open('user_bh', '隐私政策')">隐私政策</text>
如你同意该指引请点击同意开始使用本小程序
</view>
<view class="footer">
<button class="btn" @click="onConfirm(false)">拒绝</button>
<button class="btn btn-confirm" @click="onConfirm(true)">同意</button>
</view>
</view>
</uv-popup>
<agreementModal ref="modal" @confirm="onConfirmSingle"></agreementModal>
</view>
</template>
<script>
import agreementModal from '@/pages_order/components/agreementModal.vue'
export default {
name: 'agreementModal',
components: {
agreementModal,
},
data() {
return {
confirmSet: new Set(),
}
},
methods: {
open() {
this.$refs.popup.open('bottom');
},
onConfirm(confirm) {
this.$emit('confirm', confirm)
this.$refs.popup.close();
},
onConfirmSingle(confirm, key) {
if (!this.confirmSet.has(key) && confirm) {
this.confirmSet.add(key)
} else if (this.confirmSet.has(key) && !confirm) {
this.confirmSet.delete(key)
}
if (this.confirmSet.size === 2) {
this.onConfirm(true)
}
}
},
}
</script>
<style lang="scss" scoped>
.popup__view {
display: flex;
flex-direction: column;
padding: 44rpx 46rpx 128rpx 46rpx;
}
.header {
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 600;
line-height: 1.5;
color: #000000;
}
.content {
margin-top: 30rpx;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 1.5;
text-align: left;
color: #000000;
.highlight {
color: #4C6EAE;
}
}
.footer {
margin-top: 122rpx;
text-align: center;
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 8rpx;
width: 232rpx;
padding: 18rpx 84rpx;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 500;
background: #F5F5F5;
color: #07C160;
&-confirm {
background: #07C160;
color: #FFFFFF;
}
}
.btn + .btn {
margin-left: 30rpx;
}
}
</style>

+ 137
- 135
pages_order/auth/wxLogin.vue View File

@ -1,155 +1,157 @@
<template>
<view class="login">
<view class="logo">
<!-- <image src="/static/image/login/logo.png" mode=""></image> -->
</view>
<view class="title">
欢迎使用酒店桌布租赁平台
</view>
<view class="btn mt"
@click="wxLogin">
<view class="icon">
<image src="../static/auth/wx.png" mode=""></image>
</view>
<view class="">
微信授权登录
</view>
</view>
<!-- <view class="btn b2">
使用短信验证登录
</view> -->
<view class="btn b2"
@click="qux">
取消登录
</view>
<view class="config">
<uv-checkbox-group
v-model="checkboxValue"
shape="circle">
<view class="content">
<view
style="display: flex;">
<uv-checkbox
size="40rpx"
icon-size="30rpx"
activeColor="#FD5100"
:name="1"
></uv-checkbox>
阅读并同意我们的<text @click="$refs.popup.open('getPrivacyPolicy')">服务协议与隐私条款</text>
</view>
<view class="">
以及<text @click="$refs.popup.open('getUserAgreement')">个人信息保护指引</text>
</view>
<view class="page_view">
<view class="flex flex-column content">
<!-- todo: check key -->
<image class="logo" src="@/static/image/temp-29.png" mode="widthFix"></image>
<!-- todo: check key -->
<view class="name">鸿宇研学生</view>
<button class="btn btn-login flex" @click="wxLogin" > </button>
<button class="btn btn-cancel flex" @click="onCancel">取消登录</button>
<view class="agreement">
<uv-checkbox-group
v-model="checkboxValue"
shape="circle"
>
<uv-checkbox
size="36rpx"
icon-size="36rpx"
activeColor="#00A9FF"
:name="1"
></uv-checkbox>
</uv-checkbox-group>
<view class="desc">
我已阅读并同意
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('user_ys', '服务协议')">服务协议</text>
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('user_bh', '隐私政策')">隐私政策</text>
</view>
</uv-checkbox-group>
</view>
</view>
<configPopup ref="popup"></configPopup>
<agreementConfirmPopup ref="popup" @confirm="onConfirmAgreement"></agreementConfirmPopup>
<agreementModal ref="modal" @confirm="onConfirmAgreement"></agreementModal>
</view>
</template>
<script>
export default {
name : 'Login',
data() {
return {
checkboxValue : []
import agreementConfirmPopup from './agreementConfirmPopup.vue'
import agreementModal from '@/pages_order/components/agreementModal.vue'
export default {
name : 'Login',
components: {
agreementConfirmPopup,
agreementModal,
},
data() {
return {
checkboxValue : []
}
},
methods: {
wxLogin(){
if(!this.checkboxValue.length){
this.openAgreementConfirmPopup()
return
}
this.$store.commit('login')
},
openAgreementConfirmPopup() {
this.$refs.popup.open()
},
onConfirmAgreement(confirm) {
if (confirm) {
this.checkboxValue = [1]
} else {
this.checkboxValue = []
}
},
onCancel() {
uni.reLaunch({
url: '/pages/index/index'
})
},
methods: {
wxLogin(){
if(!this.checkboxValue.length){
return uni.showToast({
title: '请先同意隐私协议',
icon:'none'
})
}
this.$store.commit('login')
},
qux(){
uni.reLaunch({
url: '/pages/index/index'
})
},
}
}
}
</script>
<style scoped lang="scss">
.login{
display: flex;
justify-content: center;
align-items: center;
height: 80vh;
flex-direction: column;
position: relative;
.logo{
height: 140rpx;
width: 140rpx;
background-color: #ddd;
border-radius: 30rpx;
image{
height: 140rpx;
width: 140rpx;
border-radius: 30rpx;
}
margin-bottom: 20rpx;
}
.title{
position: relative;
font-weight: 900;
font-size: 45rpx;
&::after{
content: '';
position: absolute;
left: 0;
top: 100%;
display: block;
height: 8rpx;
width: 210rpx;
background: linear-gradient(to right,$uni-color, #fff);
}
}
.btn{
width: 80%;
height: 100rpx;
background-color: $uni-color;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
margin: 20rpx 0;
border-radius: 20rpx;
.icon{
margin-right: 10rpx;
image{
width: 40rpx;
height: 35rpx;
}
}
.page_view {
width: 100vw;
height: 100vh;
padding: 320rpx 116rpx 0 116rpx;
box-sizing: border-box;
background: #E5F2F9;
}
.content {
width: 100%;
}
.logo {
width: 248rpx;
height: auto;
}
.name {
margin-top: 20rpx;
font-family: Alimama ShuHeiTi;
font-size: 56rpx;
font-weight: 700;
color: #000000;
}
.btn {
width: 100%;
border-radius: 44rpx;
padding: 21rpx 0;
font-size: 30rpx;
line-height: 1.4;
font-family: PingFang SC;
border: 2rpx solid $uni-color;
&-login {
margin-top: 222rpx;
font-weight: 600;
color: #FFFFFF;
background: $uni-color;
}
.b2{
background-color: rgba($uni-color, 0.2);
&-cancel {
margin-top: 24rpx;
font-weight: 400;
color: $uni-color;
background: transparent;
}
.mt{
margin-top: 200rpx;
}
.config{
position: absolute;
bottom: 0;
}
.agreement {
margin-top: 24rpx;
display: flex;
.desc {
font-family: PingFang SC;
font-size: 24rpx;
text-align: center;
line-height: 40rpx;
text{
color: $uni-color;
}
font-weight: 400;
line-height: 1.4;
color: #8B8B8B;
}
.highlight {
color: $uni-color;
}
}
</style>

+ 325
- 97
pages_order/auth/wxUserInfo.vue View File

@ -1,133 +1,361 @@
<template>
<view class="login">
<view class="title">
酒店桌布租赁平台
</view>
<view class="title">
申请获取你的头像昵称
</view>
<view class="page__view">
<button class="chooseAvatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<view class="line">
<view class="">
头像
</view>
<view class="">
<image :src="userInfo.headImage" v-if="userInfo.headImage" style="width: 60rpx;height: 60rpx;"
mode=""></image>
<image src="../static/auth/headImage.png" v-else style="width: 50rpx;height: 50rpx;" mode=""></image>
</view>
</view>
</button>
<view class="line">
<view class="">
昵称
<navbar title="修改信息" leftClick @leftClick="$utils.navigateBack" color="#191919" bgColor="#FFFFFF" />
<view class="flex flex-column content">
<!-- todo: check key -->
<image class="logo" src="@/static/image/temp-29.png" mode="widthFix"></image>
<!-- todo: check key -->
<view class="name">鸿宇研学生</view>
<view class="title">
申请获取你的头像昵称
</view>
<view class="">
<input type="nickname" placeholder="请输入昵称" style="text-align: right;" id="nickName"
v-model="userInfo.nickName" />
<view class="form">
<uv-form
ref="form"
:model="form"
:rules="rules"
errorType="toast"
>
<view class="form-item">
<uv-form-item prop="phone" :customStyle="formItemStyle">
<view class="row">
<view class="form-item-label">头像</view>
<view class="form-item-content input">
<button class="btn btn-avatar" :plain="true" :hairline="false" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<view v-if="form.avatar" class="avatar">
<image class="img" :src="form.avatar" mode="aspectFill"></image>
<view class="flex mask">
<image class="icon" src="@/pages_order/static/center/icon-change.png" mode="widthFix" />
</view>
</view>
<view v-else class="flex avatar is-empty">
<image class="icon" src="@/pages_order/static/auth/avatar.png" mode="widthFix" />
</view>
</button>
</view>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="name" :customStyle="formItemStyle">
<view class="row">
<view class="form-item-label">昵称</view>
<view class="form-item-content input">
<input
type="nickname"
placeholder="请输入"
placeholderStyle="color: #C6C6C6; font-size: 32rpx; font-weight: 400;"
v-model="form.name"
style="text-align: right;"
/>
</view>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="phone" :customStyle="formItemStyle">
<view class="row">
<view class="form-item-label">电话</view>
<view class="form-item-content input">
<formInput v-if="form.phone" v-model="form.phone"></formInput>
<view v-else>
<button
class="btn btn-phone"
open-type="getPhoneNumber"
@getphonenumber="getPhone"
>
<view class="text placeholder">获取电话号码</view>
</button>
</view>
</view>
</view>
</uv-form-item>
</view>
</uv-form>
</view>
<button class="btn btn-save" @click="onSubmit">保存</button>
</view>
<view class="btn" @click="submit">
确认
</view>
</view>
</template>
<script>
import { mapState } from 'vuex'
import formInput from '@/pages_order/components/formInput.vue'
export default {
components: {
formInput,
},
props: {
mode: {
type: String,
default: null,
}
},
data() {
return {
userInfo: {
headImage: '',
nickName: '',
}
};
form: {
name: null,
phone: null,
avatar: null,
},
rules: {
'name': {
type: 'string',
required: true,
message: '请输入昵称',
},
'phone': {
type: 'string',
required: true,
message: '请输入手机号',
},
'avatar': {
type: 'array',
required: true,
message: '请选择头像',
},
},
formItemStyle: { padding: 0 },
}
},
computed: {
...mapState(['userInfo']),
},
onLoad(arg) {
this.mode = arg.mode
this.form.name = this.userInfo.name || ''
this.form.phone = this.userInfo.phone || ''
this.form.avatar = this.userInfo.avatar || ''
},
onShow() {},
computed: {},
methods: {
onChooseAvatar(res) {
let self = this
self.$Oss.ossUpload(res.target.avatarUrl)
.then(url => {
self.userInfo.headImage = url
})
this.$Oss.ossUpload(res.target.avatarUrl)
.then(url => {
this.form.avatar = url
})
},
submit() {
let self = this
uni.createSelectorQuery().in(this)
.select("#nickName")
.fields({
properties: ["value"],
})
.exec((res) => {
const nickName = res?.[0]?.value
self.userInfo.nickName = nickName
getPhone(e){
this.$api('bindPhone', {
code : e.detail.code
}, res => {
if(res.code == 200){
if (self.$utils.verificationAll(self.userInfo, {
headImage: '请选择头像',
nickName: '请填写昵称',
})) {
return
if(res.success){
this.form.phone = res.result
}else{
uni.showModal({
title: res.message
})
}
}
})
},
async onSubmit() {
try {
await this.$refs.form.validate()
const {
name,
phone,
avatar,
} = this.form
const params = {
name,
phone,
avatar,
}
// todo: check 415 Unsupported Media Type
const res = await this.$fetch('updateInfo', params, false)
if (res.code == 200) {
self.$api('updateInfo', self.userInfo, res => {
if (res.code == 200) {
uni.switchTab({
url:'/pages/index/index'
})
uni.showToast({
icon: 'success',
title: '保存成功',
});
this.$store.commit('getUserInfo')
setTimeout(() => {
if (this.mode === 'edit') {
this.$utils.navigateBack()
return
}
})
})
},
}
uni.reLaunch({
url:'/pages/index/index'
})
}, 800)
}
} catch (err) {
console.log('onSubmit err', err)
}
},
},
}
</script>
<style lang="scss" scoped>
.login {
.page__view {
width: 100vw;
min-height: 100vh;
padding: 0 40rpx;
box-sizing: border-box;
background: #FFFFFF;
}
.content {
margin-top: 52rpx;
}
.logo {
width: 248rpx;
height: auto;
}
.name {
margin-top: 20rpx;
font-family: Alimama ShuHeiTi;
font-size: 56rpx;
font-weight: 700;
color: #000000;
}
.title {
color: #333333;
font-size: 32rpx;
font-weight: 500;
margin-top: 20rpx;
}
.row {
display: flex;
flex-direction: column;
justify-content: center;
justify-content: space-between;
align-items: center;
height: 80vh;
font-family: PingFang SC;
font-weight: 400;
line-height: 1.4;
column-gap: 24rpx;
}
.title {
line-height: 45rpx;
font-weight: 900;
}
.form {
margin-top: 122rpx;
width: 100%;
&-item {
border-bottom: 2rpx solid #EEEEEE;
& + & {
margin-top: 20rpx;
}
&-label {
min-height: 96rpx;
font-family: PingFang SC;
font-size: 36rpx;
font-weight: 500;
line-height: 96rpx;
color: #181818;
}
.line {
display: flex;
justify-content: space-between;
align-items: center;
width: 80%;
border-bottom: 1px solid #00000023;
padding: 30rpx 0;
margin: 0 auto;
&-content {
margin-top: 14rpx;
padding: 6rpx 0;
.text {
padding: 2rpx 0;
font-family: PingFang SC;
font-weight: 400;
font-size: 32rpx;
line-height: 1.4;
&.placeholder {
color: #C6C6C6;
}
}
}
}
}
.btn-phone {
text-align: left;
font-family: PingFang SC;
font-weight: 400;
font-size: 32rpx;
line-height: 1.4;
color: #393939;
}
.chooseAvatar {
.btn-avatar {
display: inline-block;
width: auto;
border: none;
}
.avatar {
position: relative;
width: 96rpx;
height: 96rpx;
border-radius: 24rpx;
overflow: hidden;
.img {
width: 100%;
height: 100%;
}
.mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
padding: 0;
margin: 0;
margin-top: 10vh;
border: none;
height: 100%;
background: #00000080;
border-radius: 24rpx;
.icon {
width: 64rpx;
height: 64rpx;
}
}
.btn {
// background: $uni-linear-gradient-btn-color;
background: $uni-color;
color: #fff;
width: 80%;
padding: 20rpx 0;
text-align: center;
border-radius: 15rpx;
margin-top: 10vh;
&.is-empty {
background: #F3F2F7;
.icon {
width: 61rpx;
height: auto;
}
}
}
.btn-save {
margin-top: 100rpx;
width: 100%;
padding: 16rpx 0;
box-sizing: border-box;
font-family: PingFang SC;
font-weight: 500;
font-size: 36rpx;
line-height: 1;
color: #FFFFFF;
background-image: linear-gradient(to right, #21FEEC, #019AF9);
border-radius: 41rpx;
}
</style>

+ 91
- 0
pages_order/center/orderCard.vue View File

@ -0,0 +1,91 @@
<template>
<view class="flex card cols">
<view class="flex flex-column col" v-for="item in list" :key="item.id" @click="jumpToOrderList(item.index)">
<view class="icon">
<image class="icon-img" :src="item.icon" mode="scaleToFill"></image>
<view class="flex sup" v-if="item.value">{{ item.value }}</view>
</view>
<view class="label">{{ item.label }}</view>
</view>
</view>
</template>
<script>
export default {
props: {
statistics: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
}
},
computed: {
list() {
return [
{ id: '001', label: '待支付', value: this.statistics[0] || 0, index: 1, icon: '/pages_order/static/center/order-1.png' },
{ id: '002', label: '待发货', value: this.statistics[1] || 0, index: 2, icon: '/pages_order/static/center/order-2.png' },
{ id: '003', label: '待收货', value: this.statistics[2] || 0, index: 3, icon: '/pages_order/static/center/order-3.png' },
// todo: check
{ id: '004', label: '售后', value: this.statistics['afterSales'] || 0, index: 0, icon: '/pages_order/static/center/order-4.png' },
{ id: '005', label: '全部', index: 0, icon: '/pages_order/static/center/order-5.png' },
]
}
},
methods: {
jumpToOrderList(index) {
this.$utils.navigateTo(`/pages_order/order/orderList/index?index=${index}`)
}
},
}
</script>
<style scoped lang="scss">
@import './styles/card.scss';
.card {
padding: 32rpx;
column-gap: 16rpx;
}
.icon {
position: relative;
width: 48rpx;
height: 48rpx;
&-img {
width: 100%;
height: 100%;
}
.sup {
position: absolute;
top: 0;
right: 0;
transform: translate(50%, -50%);
min-width: 32rpx;
height: 32rpx;
font-family: PingFang SC;
font-weight: 500;
font-size: 24rpx;
line-height: 1.3;
color: #FFFFFF;
background: #F53F3F;
border-radius: 32rpx;
}
}
.label {
margin-top: 12rpx;
font-family: PingFang SC;
font-weight: 400;
font-size: 28rpx;
line-height: 1;
color: #252545;
}
</style>

+ 56
- 0
pages_order/center/popupQrCode.vue View File

@ -0,0 +1,56 @@
<template>
<uv-popup
ref="popup"
:overlayOpacity="0.8"
mode="bottom"
round="20rpx"
:zIndex="1000000"
>
<view class="flex qr-popup">
<text class="tips">即刻关注</text>
<image class="qr" :src="src" :show-menu-by-longpress="true"></image>
</view>
</uv-popup>
</template>
<script>
export default {
props: {
src: {
type: String,
default: null
}
},
data() {
return {
}
},
methods: {
open() {
this.$refs.popup.open();
},
close() {
this.$refs.popup.close();
},
},
}
</script>
<style scoped lang="scss">
.qr-popup {
flex-direction: column;
padding-bottom: 104rpx;
.tips {
margin-top: 75rpx;
color: #1B1B1B;
font-size: 32rpx;
}
.qr {
margin-top: 40rpx;
width: 350rpx;
height: 350rpx;
}
}
</style>

+ 15
- 0
pages_order/center/styles/card.scss View File

@ -0,0 +1,15 @@
.card {
margin-top: 32rpx;
width: 100%;
background: #FAFAFF;
border: 2rpx solid #FFFFFF;
border-radius: 32rpx;
box-sizing: border-box;
}
.cols {
.col {
flex: 1;
}
}

+ 99
- 0
pages_order/components/agreementModal.vue View File

@ -0,0 +1,99 @@
<template>
<view>
<uv-modal ref="modal" :showConfirmButton="false">
<view class="modal__view">
<view class="header">
{{ title }}
</view>
<view class="content">
<uv-parse :content="content"></uv-parse>
</view>
<view class="footer">
<button class="btn" @click="onConfirm(false)">拒绝</button>
<button class="btn btn-confirm" @click="onConfirm(true)">同意</button>
</view>
</view>
</uv-modal>
<configPopup ref="popup"></configPopup>
</view>
</template>
<script>
import { mapState } from 'vuex'
export default {
data() {
return {
key: '',
title : '',
content : '',
}
},
computed : {
...mapState(['configList'])
},
methods: {
open(key, title) {
this.key = key
this.title = title
this.content = this.configList[key]
this.$refs.modal.open()
},
onConfirm(confirm) {
this.$emit('confirm', confirm, this.key)
this.$refs.modal.close()
},
},
}
</script>
<style lang="scss" scoped>
.modal__view {
width: 100%;
display: flex;
flex-direction: column;
padding-top: 40rpx;
}
.header {
text-align: center;
font-size: 34rpx;
font-family: PingFang SC;
font-weight: 600;
line-height: 1.4;
color: #181818;
}
.content {
padding: 8rpx 32rpx 40rpx 32rpx;
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 1.7;
text-align: left;
color: #636465;
}
.footer {
display: flex;
border-top: 1rpx solid #EEEEEE;
.btn {
flex: 1;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 22rpx 32rpx;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 1.4;
color: #393939;
&-confirm {
color: $uni-color;
border-left: 1rpx solid #EEEEEE;
}
}
}
</style>

+ 46
- 0
pages_order/components/formInput.vue View File

@ -0,0 +1,46 @@
<template>
<uv-input
:type="type"
:inputAlign="inputAlign"
:value="value"
@input="$emit('input', $event)"
:placeholder="placeholder"
placeholderStyle="color: #C6C6C6; font-size: 32rpx; font-weight: 400;"
:customStyle="{
backgroundColor: 'transparent',
padding: '0',
boxSizing: 'border-box',
fontSize: '32rpx',
border: 'none',
transform: 'translateX(-4px)'
}"
fontSize="32rpx"
></uv-input>
</template>
<script>
export default {
props: {
value: {
default: null
},
placeholder: {
type: String,
default: '请输入'
},
type: {
type: String,
default: 'text'
},
inputAlign: {
type: String,
default: 'left'
},
},
data() {
return {
}
},
}
</script>

BIN
pages_order/static/auth/avatar.png View File

Before After
Width: 192  |  Height: 192  |  Size: 4.2 KiB

BIN
pages_order/static/center/avatar-default.png View File

Before After
Width: 156  |  Height: 156  |  Size: 7.8 KiB

BIN
pages_order/static/center/icon-aboutUs.png View File

Before After
Width: 60  |  Height: 60  |  Size: 1.8 KiB

BIN
pages_order/static/center/icon-change.png View File

Before After
Width: 96  |  Height: 96  |  Size: 542 B

BIN
pages_order/static/center/icon-comment.png View File

Before After
Width: 60  |  Height: 60  |  Size: 846 B

BIN
pages_order/static/center/icon-detectBook.png View File

Before After
Width: 60  |  Height: 60  |  Size: 963 B

BIN
pages_order/static/center/icon-instruc.png View File

Before After
Width: 60  |  Height: 60  |  Size: 954 B

BIN
pages_order/static/center/icon-logout.png View File

Before After
Width: 60  |  Height: 60  |  Size: 691 B

BIN
pages_order/static/center/icon-modifyInfo.png View File

Before After
Width: 60  |  Height: 60  |  Size: 1.3 KiB

BIN
pages_order/static/center/icon-service.png View File

Before After
Width: 60  |  Height: 60  |  Size: 1.5 KiB

BIN
pages_order/static/center/icon-userAgreement.png View File

Before After
Width: 60  |  Height: 60  |  Size: 1.1 KiB

BIN
pages_order/static/center/order-1.png View File

Before After
Width: 73  |  Height: 72  |  Size: 1.3 KiB

BIN
pages_order/static/center/order-2.png View File

Before After
Width: 73  |  Height: 72  |  Size: 1.5 KiB

BIN
pages_order/static/center/order-3.png View File

Before After
Width: 73  |  Height: 72  |  Size: 1.6 KiB

BIN
pages_order/static/center/order-4.png View File

Before After
Width: 73  |  Height: 72  |  Size: 1.1 KiB

BIN
pages_order/static/center/order-5.png View File

Before After
Width: 73  |  Height: 72  |  Size: 769 B

BIN
static/image/center-bg.png View File

Before After
Width: 1125  |  Height: 621  |  Size: 570 KiB

BIN
static/image/temp-29.png View File

Before After
Width: 125  |  Height: 124  |  Size: 2.8 KiB

Loading…
Cancel
Save