| @ -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> | |||
| @ -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> | |||
| @ -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> | |||
| @ -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> | |||
| @ -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> | |||
| @ -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> | |||
| @ -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; | |||
| } | |||
| } | |||
| @ -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> | |||
| @ -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> | |||