| @ -1,229 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <view class="bg"></view> | |||
| <view class="main"> | |||
| <view class="flex user"> | |||
| <!-- 用户信息 --> | |||
| <template v-if="isLogin"> | |||
| <view class="user-avatar"> | |||
| <image class="user-avatar-img" :src="userInfo.headImage" mode="scaleToFill"></image> | |||
| </view> | |||
| <view class="user-info"> | |||
| <view class="user-info-name">{{ userInfo.nickName }}</view> | |||
| <view class="user-info-desc">{{ `ID:${userInfo.id}` }}</view> | |||
| </view> | |||
| </template> | |||
| <template v-else> | |||
| <view class="user-avatar"> | |||
| <image class="user-avatar-img" src="@/static/image/avatar-default.png" mode="scaleToFill"></image> | |||
| </view> | |||
| <view class="user-info"> | |||
| <view class="user-info-tips">暂未登录 请先登录</view> | |||
| </view> | |||
| </template> | |||
| </view> | |||
| <!-- 用户菜单 --> | |||
| <template v-if="isLogin"> | |||
| <view class="card"> | |||
| <view class="card-header">常用功能</view> | |||
| <view class="card-content menu"> | |||
| <view class="flex flex-column menu-item" v-for="item in list" :key="item.id" @click="onClick(item)"> | |||
| <image class="icon" :src="item.icon" mode="widthFix"></image> | |||
| <view>{{ item.label }}</view> | |||
| </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> | |||
| </template> | |||
| <script> | |||
| import { mapState } from 'vuex' | |||
| import tabber from '@/components/base/tabbar.vue' | |||
| export default { | |||
| components: { | |||
| tabber, | |||
| }, | |||
| data() { | |||
| return { | |||
| list: [ | |||
| { id: '001', label: '我的答题', icon: '/static/image/icon-center-test.png', path: '/pages_order/test/list' }, | |||
| { id: '002', label: '咨询客服', icon: '/static/image/icon-center-service.png', path: '/pages_order/service/index' }, | |||
| { id: '003', label: '意见反馈', icon: '/static/image/icon-center-feedback.png', path: '/pages_order/feedback/index' }, | |||
| { id: '004', label: '个人信息', icon: '/static/image/icon-center-userinfo.png', path: '/pages_order/auth/infoModify' }, | |||
| { id: '008', label: '退出登录', icon: '/static/image/icon-center-logout.png', key: 'logout' }, | |||
| ], | |||
| } | |||
| }, | |||
| computed: { | |||
| ...mapState(['userInfo', 'configList']), | |||
| isLogin() { | |||
| return this.userInfo && this.userInfo.id | |||
| } | |||
| }, | |||
| onShow() { | |||
| if(uni.getStorageSync('token')){ | |||
| this.$store.commit('getUserInfo') | |||
| } | |||
| }, | |||
| methods: { | |||
| onClick(target) { | |||
| const { key, path } = target | |||
| switch(key) { | |||
| case 'logout': | |||
| this.$store.commit('logout') | |||
| break | |||
| default: | |||
| path && this.$utils.navigateTo(path) | |||
| break | |||
| } | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| background: #F5F5F5; | |||
| } | |||
| .bg { | |||
| width: 100%; | |||
| height: 501rpx; | |||
| background: linear-gradient(160deg, #014FA2 36%, #4C8FD6); | |||
| } | |||
| .main { | |||
| width: 100%; | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| padding: 216rpx 13rpx 26rpx 13rpx; | |||
| box-sizing: border-box; | |||
| } | |||
| .user { | |||
| padding: 0 33rpx; | |||
| column-gap: 22rpx; | |||
| &-avatar { | |||
| flex: none; | |||
| width: 118rpx; | |||
| height: 118rpx; | |||
| border-radius: 50%; | |||
| overflow: hidden; | |||
| &-img { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| &-info { | |||
| flex: 1; | |||
| color: #FFFFFF; | |||
| &-name { | |||
| font-size: 30rpx; | |||
| } | |||
| &-desc { | |||
| margin-top: 12rpx; | |||
| font-size: 28rpx; | |||
| } | |||
| &-tips { | |||
| font-size: 30rpx; | |||
| } | |||
| } | |||
| } | |||
| .card { | |||
| margin-top: 83rpx; | |||
| width: 100%; | |||
| min-height: 652rpx; | |||
| padding: 32rpx 30rpx; | |||
| box-sizing: border-box; | |||
| background: #FFFFFF; | |||
| border-radius: 16rpx; | |||
| &-header { | |||
| font-size: 32rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| } | |||
| &-content { | |||
| margin-top: 73rpx; | |||
| } | |||
| } | |||
| .menu { | |||
| width: 100%; | |||
| display: grid; | |||
| grid-template-columns: repeat(4, 1fr); | |||
| column-gap: 73rpx; | |||
| row-gap: 93rpx; | |||
| &-item { | |||
| min-width: 0; | |||
| row-gap: 10rpx; | |||
| font-size: 28rpx; | |||
| white-space: nowrap; | |||
| color: #000000; | |||
| .icon { | |||
| width: 50rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| .login { | |||
| margin-top: 307rpx; | |||
| width: 100%; | |||
| padding: 0 128rpx; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| padding: 16rpx 0; | |||
| font-family: PingFang SC; | |||
| font-weight: 500; | |||
| font-size: 36rpx; | |||
| line-height: 1.4; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| 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> | |||
| @ -1,153 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <view class="bg"></view> | |||
| <view class="main"> | |||
| <view class="swiper"> | |||
| <uv-swiper | |||
| :list="bannerList" keyName="image" | |||
| indicator | |||
| indicatorMode="dot" | |||
| indicatorActiveColor="#62BBFF" | |||
| indicatorInactiveColor="#FFFFFF" | |||
| height="340rpx" | |||
| ></uv-swiper> | |||
| </view> | |||
| <view class="flex flex-column card"> | |||
| <view class="title">公司风险检测</view> | |||
| <image class="icon" src="@/static/image/icon-index.png" mode="widthFix"></image> | |||
| <button class="btn" @click="onStartTest">开始测评</button> | |||
| </view> | |||
| <unfinishTestPopup ref="unfinishTestPopup"></unfinishTestPopup> | |||
| <tabber select="home" /> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import tabber from '@/components/base/tabbar.vue' | |||
| import unfinishTestPopup from '@/components/home/unfinishTestPopup.vue' | |||
| export default { | |||
| components: { | |||
| tabber, | |||
| unfinishTestPopup, | |||
| }, | |||
| data() { | |||
| return { | |||
| bannerList: [], | |||
| } | |||
| }, | |||
| onLoad() { | |||
| if(uni.getStorageSync('token')){ | |||
| this.$store.commit('getUserInfo') | |||
| } | |||
| this.fetchBanner() | |||
| }, | |||
| onShow() { | |||
| if(uni.getStorageSync('token')){ | |||
| this.fetchUnfinish() | |||
| } | |||
| }, | |||
| methods: { | |||
| async fetchBanner() { | |||
| try { | |||
| this.bannerList = (await this.$fetch('queryBannerList', { type: '0' }))?.records // type:0-首页 | |||
| } catch (err) { | |||
| } | |||
| }, | |||
| async fetchUnfinish() { | |||
| // todo: delete | |||
| // let data = { id: '001', unfinishCount: 15, current: 18, } | |||
| // this.$refs.unfinishTestPopup.open(data) | |||
| try { | |||
| const { records, total } = await this.$fetch('queryExamLogList', { pageNo: 1, pageSize: 1, isFinished: '0' }) | |||
| total && this.$refs.unfinishTestPopup.open(records[0]) | |||
| } catch (err) { | |||
| } | |||
| }, | |||
| onStartTest() { | |||
| uni.navigateTo({ | |||
| url: `/pages_order/test/start` | |||
| }) | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .bg { | |||
| width: 100%; | |||
| height: 376rpx; | |||
| background: linear-gradient(164deg, #014FA2 30%, #4C8FD6); | |||
| } | |||
| .main { | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| width: 100%; | |||
| padding: 174rpx 30rpx 0 30rpx; | |||
| box-sizing: border-box; | |||
| } | |||
| .swiper { | |||
| border-radius: 10rpx; | |||
| overflow: hidden; | |||
| /deep/ .uv-swiper-indicator__wrapper__dot, | |||
| /deep/ .uv-swiper-indicator__wrapper__dot--active { | |||
| width: 5px; | |||
| } | |||
| } | |||
| .card { | |||
| margin-top: 32rpx; | |||
| justify-content: space-between; | |||
| min-height: 803rpx; | |||
| padding: 135rpx 0 55rpx 0; | |||
| box-sizing: border-box; | |||
| background: linear-gradient(rgba($color: #FCFDFE, $alpha: 0.93), rgba($color: #FCFDFE, $alpha: 0.93) 180rpx, rgba($color: #3381D4, $alpha: 0.43)); | |||
| border-radius: 25rpx; | |||
| border: 3rpx solid #FFFFFF; | |||
| box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16); | |||
| .title { | |||
| font-size: 32rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| } | |||
| .icon { | |||
| margin: 99rpx 0 86rpx; | |||
| width: 285rpx; | |||
| height: auto; | |||
| } | |||
| .btn { | |||
| padding: 20rpx 212rpx; | |||
| font-size: 30rpx; | |||
| white-space: nowrap; | |||
| color: #FFFFFF; | |||
| line-height: 1.4; | |||
| background: #014FA2; | |||
| border-radius: 42rpx; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,113 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <view class="header"></view> | |||
| <template v-if="isLogin"> | |||
| <view class="list"> | |||
| <view class="list-item" v-for="item in list" :key="item.id"> | |||
| <reportCard :data="item"></reportCard> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <!-- 用户登陆 --> | |||
| <template v-else> | |||
| <view class="login"> | |||
| <button class="btn" @click="$utils.toLogin">立即登录</button> | |||
| <view class="tips">暂未登录 请先登录</view> | |||
| </view> | |||
| </template> | |||
| <tabber select="report" /> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import mixinsList from '@/mixins/list.js' | |||
| import tabber from '@/components/base/tabbar.vue' | |||
| import reportCard from '@/components/report/reportCard.vue' | |||
| export default { | |||
| mixins: [mixinsList], | |||
| components: { | |||
| tabber, | |||
| reportCard, | |||
| }, | |||
| data() { | |||
| return { | |||
| mixinsListApi: '', | |||
| } | |||
| }, | |||
| onLoad() { | |||
| if(uni.getStorageSync('token')){ | |||
| this.$store.commit('getUserInfo') | |||
| } | |||
| }, | |||
| computed: { | |||
| isLogin() { | |||
| return this.userInfo && this.userInfo.id | |||
| }, | |||
| }, | |||
| onShow() { | |||
| this.mixinsListApi = uni.getStorageSync('token') ? 'queryReportList' : '' | |||
| this.getData() | |||
| }, | |||
| methods: { | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| background: #F5F5F5; | |||
| } | |||
| .header { | |||
| width: 100%; | |||
| height: calc(var(--status-bar-height) + 120rpx); | |||
| background: linear-gradient(164deg, #014FA2, #4C8FD6); | |||
| } | |||
| .list { | |||
| width: 100%; | |||
| padding: 29rpx; | |||
| box-sizing: border-box; | |||
| background: #F5F5F5; | |||
| &-item { | |||
| & + & { | |||
| margin-top: 23rpx; | |||
| } | |||
| } | |||
| } | |||
| .login { | |||
| margin-top: 307rpx; | |||
| width: 100%; | |||
| padding: 0 128rpx; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| padding: 16rpx 0; | |||
| font-family: PingFang SC; | |||
| font-weight: 500; | |||
| font-size: 36rpx; | |||
| line-height: 1.4; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| 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> | |||
| @ -1,115 +0,0 @@ | |||
| <template> | |||
| <view> | |||
| <uv-popup ref="popup" :round="24"> | |||
| <view class="popup__view"> | |||
| <view class="header"> | |||
| 用户隐私保护提示 | |||
| </view> | |||
| <view class="content"> | |||
| 在你使用 {{ configList.app_name }}服务之前,请仔细阅读我已阅读并同意 | |||
| <text class="highlight" @click="$refs.modal.open('config_privacy', '服务协议与隐私条款')">《服务协议与隐私条款》</text> | |||
| 和 | |||
| <text class="highlight" @click="$refs.modal.open('config_agreement', '个人信息保护指引')">《个人信息保护指引》</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,276 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="资料修改" leftClick @leftClick="$utils.navigateBack" /> | |||
| <view class="form"> | |||
| <view class="flex form-header"> | |||
| <view class="line"></view> | |||
| <view>个人信息</view> | |||
| </view> | |||
| <uv-form | |||
| ref="form" | |||
| :model="form" | |||
| :rules="rules" | |||
| errorType="toast" | |||
| > | |||
| <view class="form-item"> | |||
| <uv-form-item prop="headImage" :customStyle="formItemStyle"> | |||
| <button class="btn btn-avatar" :plain="true" :hairline="false" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> | |||
| <view class="flex flex-column avatar-box"> | |||
| <view v-if="form.headImage" class="avatar"> | |||
| <image class="img" :src="form.headImage" mode="aspectFill"></image> | |||
| </view> | |||
| <view v-else class="flex avatar"> | |||
| <image class="img" src="@/static/image/avatar-default.png" mode="scaleToFill"></image> | |||
| </view> | |||
| <view>点击更换头像</view> | |||
| </view> | |||
| </button> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item"> | |||
| <uv-form-item prop="nickName" :customStyle="formItemStyle"> | |||
| <view class="flex row"> | |||
| <view class="row-label">昵称</view> | |||
| <view class="row-content input"> | |||
| <input | |||
| v-model="form.nickName" | |||
| type="nickname" | |||
| placeholder="请输入" | |||
| placeholderStyle="color: #999999; font-size: 30rpx; font-weight: 400;" | |||
| style="text-align: right;" | |||
| /> | |||
| </view> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item"> | |||
| <uv-form-item prop="phone" :customStyle="formItemStyle"> | |||
| <view class="flex row"> | |||
| <view class="row-label">手机号</view> | |||
| <view class="row-content input"> | |||
| <input | |||
| v-model="form.phone" | |||
| placeholder="请输入" | |||
| placeholderStyle="color: #999999; font-size: 30rpx; font-weight: 400;" | |||
| style="text-align: right;" | |||
| :disabled="!!userInfo.phone" | |||
| /> | |||
| </view> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| </uv-form> | |||
| </view> | |||
| <view class="bottom"> | |||
| <button class="btn" @click="onSubmit">保存</button> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import { mapState } from 'vuex' | |||
| export default { | |||
| props: { | |||
| mode: { | |||
| type: String, | |||
| default: null, | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| form: { | |||
| nickName: null, | |||
| phone: null, | |||
| headImage: null, | |||
| }, | |||
| rules: { | |||
| 'nickName': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请输入昵称', | |||
| }, | |||
| 'phone': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请输入手机号', | |||
| }, | |||
| 'headImage': { | |||
| type: 'string', | |||
| required: false, | |||
| message: '请选择头像', | |||
| }, | |||
| }, | |||
| formItemStyle: { padding: 0 }, | |||
| } | |||
| }, | |||
| computed: { | |||
| ...mapState(['userInfo']), | |||
| }, | |||
| onLoad(arg) { | |||
| this.mode = arg.mode | |||
| this.form.nickName = this.userInfo.nickName || '' | |||
| this.form.phone = this.userInfo.phone || '' | |||
| this.form.headImage = this.userInfo.headImage || '' | |||
| }, | |||
| methods: { | |||
| onChooseAvatar(res) { | |||
| this.$Oss.ossUpload(res.target.avatarUrl) | |||
| .then(url => { | |||
| this.form.headImage = url | |||
| }) | |||
| }, | |||
| getPhone(e){ | |||
| this.$api('bindPhone', { | |||
| code : e.detail.code | |||
| }, res => { | |||
| if(res.code == 200){ | |||
| if(res.success){ | |||
| this.form.phone = res.result | |||
| }else{ | |||
| uni.showModal({ | |||
| title: res.message | |||
| }) | |||
| } | |||
| } | |||
| }) | |||
| }, | |||
| async onSubmit() { | |||
| try { | |||
| await this.$refs.form.validate() | |||
| const { | |||
| nickName, | |||
| phone, | |||
| headImage, | |||
| } = this.form | |||
| const params = { | |||
| nickName, | |||
| phone, | |||
| headImage, | |||
| } | |||
| await this.$fetch('updateInfo', params, false) | |||
| uni.showToast({ | |||
| icon: 'success', | |||
| title: '保存成功', | |||
| }); | |||
| this.$store.commit('getUserInfo') | |||
| setTimeout(uni.navigateBack, 1000, -1) | |||
| } catch (err) { | |||
| console.log('onSubmit err', err) | |||
| } | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .form { | |||
| padding: 34rpx 22rpx; | |||
| &-header { | |||
| justify-content: flex-start; | |||
| padding: 0 18rpx; | |||
| column-gap: 7rpx; | |||
| font-family: PingFang SC; | |||
| font-weight: 600; | |||
| font-size: 36rpx; | |||
| line-height: 1.4; | |||
| color: #000000; | |||
| margin-bottom: 24rpx; | |||
| .line { | |||
| width: 9rpx; | |||
| height: 33rpx; | |||
| background: #014FA2; | |||
| border-radius: 5rpx; | |||
| } | |||
| } | |||
| &-item { | |||
| & + & { | |||
| margin-top: 34rpx; | |||
| border-bottom: 0.5rpx solid rgba($color: #707070, $alpha: 0.14); | |||
| } | |||
| } | |||
| } | |||
| .btn-avatar { | |||
| margin-bottom: 27rpx; | |||
| display: inline-block; | |||
| width: auto; | |||
| border: none; | |||
| } | |||
| .avatar-box { | |||
| box-sizing: border-box; | |||
| row-gap: 9rpx; | |||
| font-size: 28rpx; | |||
| color: rgba($color: #999999, $alpha: 0.5); | |||
| } | |||
| .avatar { | |||
| position: relative; | |||
| width: 157rpx; | |||
| height: 157rpx; | |||
| border-radius: 50%; | |||
| overflow: hidden; | |||
| .img { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| .row { | |||
| padding: 12rpx 69rpx 12rpx 23rpx; | |||
| justify-content: space-between; | |||
| font-family: PingFang SC; | |||
| font-weight: 400; | |||
| line-height: 1.4; | |||
| font-size: 30rpx; | |||
| color: #8B8B8B; | |||
| & + & { | |||
| margin-top: 32rpx; | |||
| } | |||
| } | |||
| .bottom { | |||
| position: fixed; | |||
| left: 0; | |||
| bottom: 0; | |||
| width: 100vw; | |||
| padding: 0 78rpx 231rpx 78rpx; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| width: 100%; | |||
| padding: 25rpx 0; | |||
| box-sizing: border-box; | |||
| font-size: 32rpx; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 41rpx; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,347 +0,0 @@ | |||
| <template> | |||
| <view class="refundsOrExchange"> | |||
| <navbar :title="titleList[titleIndex]" leftClick @leftClick="$utils.navigateBack" /> | |||
| <view class="frame"> | |||
| <!-- 登录和注册 --> | |||
| <view class="loginRegister" v-if='titleIndex!=2'> | |||
| <!-- 标题 --> | |||
| <view class="title">{{titleList[titleIndex]}}</view> | |||
| <!-- 头像 --> | |||
| <view class="userIamge"> | |||
| <view> | |||
| <img src="/static/image/center/11.svg" alt="" style="width: 100%;height: 100%;"> | |||
| </view> | |||
| </view> | |||
| <!-- 用户名&密码&隐私条款 --> | |||
| <view class="form"> | |||
| <view> | |||
| <uv-input v-model="form.account" placeholder="请输入账号" border="surround" shape='circle' | |||
| clearable :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input> | |||
| </view> | |||
| <view> | |||
| <uv-input v-model="form.password" password placeholder="请输入密码" border="surround" shape='circle' | |||
| clearable :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input> | |||
| </view> | |||
| <view> | |||
| <uv-checkbox-group v-model="checkboxValue" shape="circle"> | |||
| <view class="content"> | |||
| <view style="display: flex;flex-wrap: wrap;"> | |||
| <uv-checkbox size="30rpx" :name="1"></uv-checkbox> | |||
| 请你阅读并同意我们的<span style="color: #fd5100" | |||
| @click="$refs.popup.open('getPrivacyPolicy')">《隐私条款》</span>和<span | |||
| style="color: #fd5100" | |||
| @click="$refs.popup.open('getUserAgreement')">《服务协议》</span> | |||
| </view> | |||
| </view> | |||
| </uv-checkbox-group> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <!-- 忘记密码 --> | |||
| <view class='forgetPassword' v-if='titleIndex==2'> | |||
| <!-- 标题 --> | |||
| <view class="title">{{titleList[titleIndex]}}</view> | |||
| <!-- 表单 --> | |||
| <view class="form1"> | |||
| <view class="userName"> | |||
| <uv-input v-model="form1.userName" placeholder="请输入手机号/用户/邮箱" border="surround" shape='circle' | |||
| clearable :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input> | |||
| </view> | |||
| <view class="code"> | |||
| <view class="left"> | |||
| <uv-input v-model="form1.code" placeholder="请输入验证码" border="surround" shape='circle' | |||
| clearable :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input> | |||
| </view> | |||
| <view class="right"> | |||
| <view> | |||
| <uv-toast ref="toast"></uv-toast> | |||
| <uv-code :seconds="seconds" @end="end" @start="start" ref="code" | |||
| @change="codeChange"></uv-code> | |||
| <uv-button @tap="getCode" iconSize='10rpx' color='#fd5100' | |||
| shape='circle'>{{tips}}</uv-button> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="password1"> | |||
| <uv-input v-model="form1.password1" placeholder="设置您的新密码(6到50个字符)" password clearable | |||
| border="surround" shape='circle' :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input> | |||
| </view> | |||
| <view class="password2"> | |||
| <uv-input v-model="form1.password2" placeholder="重新确认密码" password clearable border="surround" | |||
| shape='circle' :customStyle="{ backgroundColor: '#f6f6f6'}"></uv-input> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <!-- 按钮 --> | |||
| <view class="btn" | |||
| @click="submit"> | |||
| <button class='a'>{{titleList[titleIndex]}}</button> | |||
| </view> | |||
| <!-- tab --> | |||
| <!-- <view class="bottomTab"> | |||
| <span :class="titleIndex==0 ? 'tabbarItemActive' : 'tabbarItemNoActive'" | |||
| @click='changePage(0)'>注册账号</span> | |||
| <span style="color: #9c9fa4">|</span> | |||
| <span :class="titleIndex==1 ? 'tabbarItemActive' : 'tabbarItemNoActive'" | |||
| @click='changePage(1)'>账号登录</span> | |||
| <span style="color: #9c9fa4">|</span> | |||
| <span :class="titleIndex==2 ? 'tabbarItemActive' : 'tabbarItemNoActive'" | |||
| @click='changePage(2)'>忘记密码</span> | |||
| </view> --> | |||
| </view> | |||
| <configPopup ref="popup"></configPopup> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import configPopup from '@/components/config/configPopup.vue'; | |||
| export default { | |||
| components: { | |||
| configPopup | |||
| }, | |||
| onLoad(option) { | |||
| this.titleIndex = option.index || 1 | |||
| }, | |||
| data() { | |||
| return { | |||
| titleIndex: 0, | |||
| titleList: ['注册', '登录', '重置密码'], | |||
| checkboxValue: [], | |||
| form: { | |||
| account: '13135294009', | |||
| password: 'lzx123456', | |||
| }, | |||
| form1: { | |||
| userName: '', | |||
| code: '', | |||
| password1: '', | |||
| password2: '', | |||
| }, | |||
| tips: '获取验证码', | |||
| seconds: 60, | |||
| } | |||
| }, | |||
| methods: { | |||
| submit(){ | |||
| if(!this.checkboxValue.length){ | |||
| return uni.showToast({ | |||
| title: '请先同意隐私协议', | |||
| icon:'none' | |||
| }) | |||
| } | |||
| if(this.$utils.verificationAll(this.form, { | |||
| account: '请输入账号', | |||
| password: '请输入密码', | |||
| })){ | |||
| return | |||
| } | |||
| this.$store.commit('accountLogin', this.form) | |||
| }, | |||
| // 切换页面 | |||
| changePage(index) { | |||
| this.titleIndex = index | |||
| }, | |||
| confirm() { | |||
| }, | |||
| codeChange(text) { | |||
| this.tips = text; | |||
| }, | |||
| getCode() { | |||
| if (this.$refs.code.canGetCode) { | |||
| // 模拟向后端请求验证码 | |||
| uni.showLoading({ | |||
| title: '正在获取验证码' | |||
| }) | |||
| setTimeout(() => { | |||
| uni.hideLoading(); | |||
| // 这里此提示会被this.start()方法中的提示覆盖 | |||
| uni.$uv.toast('验证码已发送'); | |||
| // 通知验证码组件内部开始倒计时 | |||
| this.$refs.code.start(); | |||
| }, 2000); | |||
| } else { | |||
| uni.$uv.toast('请勿重复发送'); | |||
| } | |||
| }, | |||
| end() { | |||
| // uni.$uv.toast('倒计时结束'); | |||
| }, | |||
| start() { | |||
| // uni.$uv.toast('倒计时开始'); | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| * { | |||
| box-sizing: border-box; | |||
| } | |||
| .refundsOrExchange { | |||
| background-color: #FFF; | |||
| height: 100vh; | |||
| .frame { | |||
| background-color: #FFF; | |||
| .loginRegister { | |||
| display: flex; | |||
| flex-direction: column; | |||
| gap: 40rpx; | |||
| .title { | |||
| display: flex; | |||
| justify-content: center; | |||
| align-items: flex-end; | |||
| height: 10vh; | |||
| color: #000; | |||
| font-size: 40rpx; | |||
| font-weight: 700; | |||
| } | |||
| .userIamge { | |||
| display: flex; | |||
| justify-content: center; | |||
| height: 10vh; | |||
| >view:nth-of-type(1) { | |||
| width: 25%; | |||
| height: 100%; | |||
| border-radius: 50%; | |||
| overflow: hidden; | |||
| } | |||
| } | |||
| .form { | |||
| line-height: 50rpx; | |||
| >view:nth-of-type(1) { | |||
| padding: 20rpx 100rpx; | |||
| } | |||
| >view:nth-of-type(2) { | |||
| padding: 0 100rpx; | |||
| } | |||
| >view:nth-of-type(3) { | |||
| display: flex; | |||
| padding: 30rpx 100rpx 0 100rpx; | |||
| font-size: 22rpx | |||
| } | |||
| } | |||
| } | |||
| .btn { | |||
| // height: 5vh; | |||
| display: flex; | |||
| justify-content: center; | |||
| margin: 90rpx 0 0 0; | |||
| .a { | |||
| display: flex; | |||
| justify-content: center; | |||
| align-items: center; | |||
| width: 70%; | |||
| height: 80rpx; | |||
| color: #FFF; | |||
| background-color: $uni-color; | |||
| border: 1px solid red; | |||
| border-radius: 100rpx; | |||
| font-size: 30rpx; | |||
| } | |||
| } | |||
| .bottomTab { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| height: 10vh; | |||
| padding: 0 80rpx; | |||
| margin-top: 30rpx; | |||
| .tabbarItemActive { | |||
| color: $uni-color; | |||
| } | |||
| .tabbarItemNoActive { | |||
| color: #9c9fa4; | |||
| } | |||
| } | |||
| .forgetPassword { | |||
| padding: 100rpx 40rpx 0 40rpx; | |||
| .title { | |||
| display: flex; | |||
| justify-content: center; | |||
| align-items: flex-end; | |||
| height: 10vh; | |||
| color: #000; | |||
| font-size: 40rpx; | |||
| font-weight: 700; | |||
| } | |||
| .form1 { | |||
| display: flex; | |||
| flex-direction: column; | |||
| gap: 30rpx; | |||
| margin-top: 20rpx; | |||
| padding: 20rpx 80rpx; | |||
| .userName { | |||
| // padding: 20rpx 100 rpx; | |||
| } | |||
| .code { | |||
| display: flex; | |||
| width: 100%; | |||
| .left { | |||
| width: 55%; | |||
| } | |||
| .right { | |||
| width: 45%; | |||
| height: 100%; | |||
| >view:nth-of-type(1) { | |||
| display: flex; | |||
| justify-content: center; | |||
| align-items: center; | |||
| width: 100%; | |||
| } | |||
| } | |||
| } | |||
| .password1 {} | |||
| .password2 {} | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,161 +0,0 @@ | |||
| <template> | |||
| <view class="page_view"> | |||
| <image class="bg" :src="configList.login_bg" mode="widthFix"></image> | |||
| <view class="content flex flex-column"> | |||
| <image class="logo" :src="configList.app_logo" mode="widthFix"></image> | |||
| <!-- <image class="logo" src="@/static/image/icon.png" mode="widthFix"></image> --> | |||
| <view class="name">{{ configList.app_name || '' }}</view> | |||
| <button class="btn btn-login flex" @click="wxLogin" >授权手机号登录</button> | |||
| <button class="btn btn-cancel flex" @click="onCancel">暂不登录</button> | |||
| <view class="agreement"> | |||
| <view> | |||
| <uv-checkbox-group | |||
| v-model="checkboxValue" | |||
| shape="circle" | |||
| > | |||
| <uv-checkbox | |||
| size="36rpx" | |||
| icon-size="36rpx" | |||
| activeColor="#014FA2" | |||
| :name="1" | |||
| ></uv-checkbox> | |||
| </uv-checkbox-group> | |||
| </view> | |||
| <view class="desc"> | |||
| 阅读并同意我们的 | |||
| <text class="highlight" @click="$refs.modal.open('config_privacy', '服务协议与隐私条款')">《服务协议与隐私条款》</text> | |||
| 以及 | |||
| <text class="highlight" @click="$refs.modal.open('config_agreement', '个人信息保护指引')">《个人信息保护指引》</text> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <agreementConfirmPopup ref="popup" @confirm="onConfirmAgreement"></agreementConfirmPopup> | |||
| <agreementModal ref="modal" @confirm="onConfirmAgreement"></agreementModal> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| 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' | |||
| }) | |||
| }, | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page_view { | |||
| width: 100vw; | |||
| height: 100vh; | |||
| } | |||
| .bg { | |||
| width: 100%; | |||
| height: auto; | |||
| } | |||
| .content { | |||
| transform: translateY(-8rpx); | |||
| width: 100%; | |||
| padding: 0 78rpx; | |||
| box-sizing: border-box; | |||
| } | |||
| .logo { | |||
| width: 100rpx; | |||
| height: auto; | |||
| } | |||
| .name { | |||
| margin-top: 20rpx; | |||
| font-size: 36rpx; | |||
| font-weight: 700; | |||
| color: #000000; | |||
| } | |||
| .btn { | |||
| width: 100%; | |||
| border-radius: 44rpx; | |||
| padding: 23rpx 0; | |||
| font-size: 32rpx; | |||
| line-height: 1.4; | |||
| font-family: PingFang SC; | |||
| &-login { | |||
| margin-top: 97rpx; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border: 2rpx solid #014FA2; | |||
| } | |||
| &-cancel { | |||
| margin-top: 66rpx; | |||
| color: #999999; | |||
| border: 2rpx solid #999999; | |||
| } | |||
| } | |||
| .agreement { | |||
| margin-top: 24rpx; | |||
| width: 100%; | |||
| display: flex; | |||
| justify-content: flex-start; | |||
| .desc { | |||
| font-family: PingFang SC; | |||
| font-size: 22rpx; | |||
| font-weight: 400; | |||
| line-height: 1.4; | |||
| color: #000000; | |||
| } | |||
| .highlight { | |||
| color: $uni-color; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,285 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar /> | |||
| <view class="flex flex-column header"> | |||
| <image class="icon" :src="configList.app_logo" mode="widthFix"></image> | |||
| <!-- <image class="icon" src="@/static/image/icon.png" mode="widthFix"></image> --> | |||
| <view class="name"> | |||
| {{ configList.app_name || '' }} | |||
| </view> | |||
| <view class="title"> | |||
| 申请获取你的头像、昵称 | |||
| </view> | |||
| </view> | |||
| <view class="form"> | |||
| <view class="form-item"> | |||
| <view class="label"> | |||
| 头像 | |||
| </view> | |||
| <view class="content"> | |||
| <button class="btn-avatar" :plain="true" :hairline="false" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> | |||
| <image class="avatar" v-if="userInfoForm.headImage" :src="userInfoForm.headImage" mode=""></image> | |||
| <image class="avatar" v-else src="@/pages_order/static/auth/avatar-default.png" mode="scaleToFill"></image> | |||
| </button> | |||
| </view> | |||
| </view> | |||
| <view class="form-item"> | |||
| <view class="label"> | |||
| 昵称 | |||
| </view> | |||
| <view class="content"> | |||
| <input type="nickname" placeholder="请输入昵称" style="text-align: right;" id="nickName" | |||
| placeholder-class="uni-placeholder" | |||
| v-model="userInfoForm.nickName" | |||
| /> | |||
| </view> | |||
| </view> | |||
| <view class="form-item"> | |||
| <view class="label"> | |||
| 手机号 | |||
| </view> | |||
| <view class="flex content" style="justify-content: flex-end; column-gap: 31rpx;"> | |||
| <input | |||
| v-model="userInfoForm.phone" | |||
| style="text-align: right;" | |||
| disabled | |||
| /> | |||
| <button | |||
| :plain="true" :hairline="false" | |||
| class="btn-phone" | |||
| open-type="getPhoneNumber" | |||
| @getphonenumber="getPhone" | |||
| > | |||
| 获取手机号 | |||
| </button> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="footer"> | |||
| <button class="btn" @click="submit"> | |||
| 确定 | |||
| </button> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| userInfoForm: { | |||
| headImage: '', | |||
| nickName: '', | |||
| phone: '', | |||
| } | |||
| }; | |||
| }, | |||
| onShow() {}, | |||
| onLoad() { | |||
| this.userInfoForm.nickName = this.userInfo.nickName || '' | |||
| this.userInfoForm.headImage = this.userInfo.headImage || '' | |||
| }, | |||
| computed: {}, | |||
| methods: { | |||
| onChooseAvatar(res) { | |||
| this.$Oss.ossUpload(res.target.avatarUrl) | |||
| .then(url => { | |||
| this.userInfoForm.headImage = url | |||
| }) | |||
| }, | |||
| getPhone(e){ | |||
| this.$api('bindPhone', { | |||
| phoneCode : e.detail.code | |||
| }, res => { | |||
| if(res.code == 200){ | |||
| let phoneObj = JSON.parse(res.result) | |||
| if(phoneObj.errmsg == 'ok'){ | |||
| this.userInfoForm.phone = phoneObj.phone_info.phoneNumber | |||
| }else{ | |||
| uni.showModal({ | |||
| title: phoneObj.errmsg | |||
| }) | |||
| } | |||
| } | |||
| }) | |||
| }, | |||
| submit() { | |||
| let self = this | |||
| uni.createSelectorQuery().in(this) | |||
| .select("#nickName") | |||
| .fields({ | |||
| properties: ["value"], | |||
| }) | |||
| .exec((res) => { | |||
| const nickName = res?.[0]?.value | |||
| self.userInfoForm.nickName = nickName | |||
| if (self.$utils.verificationAll(self.userInfoForm, { | |||
| headImage: '请选择头像', | |||
| nickName: '请填写昵称', | |||
| phone: '请填写手机号', | |||
| })) { | |||
| return | |||
| } | |||
| self.$api('updateInfo', { | |||
| headImage : self.userInfoForm.headImage, | |||
| nickName : self.userInfoForm.nickName, | |||
| phone : self.userInfoForm.phone, | |||
| }, res => { | |||
| if (res.code == 200) { | |||
| uni.reLaunch({ | |||
| url:'/pages/index/index' | |||
| }) | |||
| } | |||
| }) | |||
| }) | |||
| }, | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page__view { | |||
| display: flex; | |||
| justify-content: flex-start; | |||
| align-items: center; | |||
| height: 100vh; | |||
| flex-direction: column; | |||
| position: relative; | |||
| .header{ | |||
| padding: 187rpx 0 106rpx 0; | |||
| .icon { | |||
| width: 100rpx; | |||
| height: auto; | |||
| } | |||
| .name { | |||
| margin: 20rpx 0 14rpx 0; | |||
| font-size: 36rpx; | |||
| font-family: PingFang SC, PingFang SC-Bold; | |||
| font-weight: 700; | |||
| text-align: center; | |||
| color: #000000; | |||
| } | |||
| .title { | |||
| font-size: 30rpx; | |||
| font-family: PingFang SC, PingFang SC-Regular; | |||
| font-weight: 400; | |||
| color: #000000; | |||
| } | |||
| } | |||
| .form { | |||
| padding: 0 48rpx; | |||
| box-sizing: border-box; | |||
| width: 100%; | |||
| .form-item { | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: space-between; | |||
| width: 100%; | |||
| min-height: 119rpx; | |||
| padding: 0 22rpx 0 13rpx; | |||
| position: relative; | |||
| border-top: 1rpx solid rgba($color: #C7C7C7, $alpha: 0.33); | |||
| &:last-child { | |||
| border-bottom: 1rpx solid rgba($color: #C7C7C7, $alpha: 0.33); | |||
| } | |||
| .label { | |||
| white-space: nowrap; | |||
| font-size: 32rpx; | |||
| font-weight: 400; | |||
| text-align: left; | |||
| color: #000000; | |||
| } | |||
| .content { | |||
| flex: 1; | |||
| text-align: right; | |||
| } | |||
| } | |||
| .btn-avatar { | |||
| background: transparent; | |||
| border: none; | |||
| border-radius: none; | |||
| box-shadow: none; | |||
| padding: 0; | |||
| margin: 0; | |||
| font-size: 0; | |||
| text-align: right; | |||
| } | |||
| .avatar { | |||
| display: inline-block; | |||
| width: 97rpx; | |||
| height: 97rpx; | |||
| } | |||
| .btn-phone { | |||
| display: inline-block; | |||
| width: auto; | |||
| margin: 0; | |||
| padding: 23rpx 33rpx; | |||
| font-size: 30rpx; | |||
| line-height: 1.4; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border: none; | |||
| border-radius: 38rpx; | |||
| } | |||
| } | |||
| .btn { | |||
| text-align: center; | |||
| margin-top: 155rpx; | |||
| width: 80%; | |||
| height: 100rpx; | |||
| border-radius: 50rpx; | |||
| background-image: linear-gradient(to right, #84A73F, #D8FF8F); | |||
| color: #fff; | |||
| display: flex; | |||
| justify-content: center; | |||
| align-items: center; | |||
| border-radius: 50rpx; | |||
| border: none; | |||
| } | |||
| } | |||
| .footer { | |||
| margin-top: 200rpx; | |||
| width: 100%; | |||
| padding: 0 78rpx; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| width: 100%; | |||
| padding: 25rpx 0; | |||
| box-sizing: border-box; | |||
| font-size: 32rpx; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 41rpx; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,101 +0,0 @@ | |||
| <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; | |||
| max-height: 70vh; | |||
| overflow-y: scroll; | |||
| 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> | |||
| @ -1,47 +0,0 @@ | |||
| <template> | |||
| <uv-textarea | |||
| :value="value" | |||
| @input="$emit('input', $event)" | |||
| :placeholder="placeholder" | |||
| :height="height" | |||
| border="none" | |||
| :customStyle="{ | |||
| padding: '0', | |||
| }" | |||
| :placeholderStyle="{ | |||
| color: '#999999', | |||
| fontSize: '28rpx', | |||
| }" | |||
| :textStyle="{ | |||
| fontSize: '28rpx', | |||
| }" | |||
| ></uv-textarea> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| props: { | |||
| value: { | |||
| default: null | |||
| }, | |||
| placeholder: { | |||
| type: String, | |||
| default: '请输入' | |||
| }, | |||
| height: { | |||
| type: String, | |||
| default: '462rpx' | |||
| }, | |||
| }, | |||
| data() { | |||
| return { | |||
| } | |||
| }, | |||
| methods: { | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| </style> | |||
| @ -1,102 +0,0 @@ | |||
| <template> | |||
| <view> | |||
| <uv-upload | |||
| :fileList="displayFileList" | |||
| :accept="accept" | |||
| :maxCount="maxCount" | |||
| :width="width" | |||
| :height="height" | |||
| @afterRead="afterRead" | |||
| @delete="deleteFile" | |||
| > | |||
| <button class="flex btn"> | |||
| <image class="icon" src="@/pages_order/static/feedback/icon-camera.png" mode="widthFix"></image> | |||
| </button> | |||
| </uv-upload> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| props: { | |||
| value: { | |||
| type: Array, | |||
| default() { | |||
| return [] | |||
| } | |||
| }, | |||
| accept: { | |||
| type: String, | |||
| default: 'image' // all | media | image | file | video | |||
| }, | |||
| width: { | |||
| type: Number | String, | |||
| default: 133, | |||
| }, | |||
| height: { | |||
| type: Number | String, | |||
| default: 133, | |||
| }, | |||
| maxCount: { | |||
| type: Number | String, | |||
| default: 100, | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| } | |||
| }, | |||
| computed: { | |||
| fileList: { | |||
| set(val) { | |||
| this.$emit('input', val) | |||
| }, | |||
| get() { | |||
| return this.value | |||
| } | |||
| }, | |||
| displayFileList() { | |||
| return this.fileList.map(url => ({ url })) | |||
| }, | |||
| }, | |||
| watch: { | |||
| fileList: { | |||
| handler(val) { | |||
| console.log('watch fileList', val) | |||
| }, | |||
| deep: true, | |||
| }, | |||
| displayFileList: { | |||
| handler(val) { | |||
| console.log('watch displayFileList', val) | |||
| }, | |||
| deep: true, | |||
| }, | |||
| }, | |||
| methods: { | |||
| deleteFile(e){ | |||
| console.log('deleteFile', e) | |||
| const fileList = [...this.fileList] | |||
| fileList.splice(e.index, 1) | |||
| this.fileList = fileList | |||
| }, | |||
| afterRead(e){ | |||
| this.$Oss.ossUpload(e.file.url).then(url => { | |||
| this.fileList = this.fileList.concat(url) | |||
| }) | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .btn { | |||
| border-radius: 0; | |||
| .icon { | |||
| width: 133rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,301 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="意见反馈" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" /> | |||
| <view class="bg"> | |||
| <view class="title">Hello</view> | |||
| <view class="desc">有什么好的建议可以告诉我们哦~</view> | |||
| </view> | |||
| <view class="main"> | |||
| <view class="form"> | |||
| <uv-form | |||
| ref="form" | |||
| :model="form" | |||
| errorType="toast" | |||
| > | |||
| <view class="form-item"> | |||
| <uv-form-item prop="textDetails" :customStyle="formItemStyle"> | |||
| <view class="card"> | |||
| <view class="editor-header"> | |||
| <view class="editor-header-content"> | |||
| <view>反馈内容</view> | |||
| <view class="editor-icon"> | |||
| <uv-icon name="star-fill" color="#FFFFFF" size="26rpx"></uv-icon> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="editor__view"> | |||
| <editor id="editor" class="editor" | |||
| placeholder="请填写10个字以上的内容,以便我们为您提供更好的服务" | |||
| @ready="onEditorReady" | |||
| @input="onEditroInput" | |||
| ></editor> | |||
| <view class="editor-tools"> | |||
| <button @click="insertImage" plain class="flex btn"> | |||
| <!-- todo: 缺切图 --> | |||
| <uv-icon name="camera-fill" color="#014FA2" size="56rpx"></uv-icon> | |||
| </button> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item"> | |||
| <uv-form-item prop="phone" :customStyle="formItemStyle"> | |||
| <view class="flex card phone"> | |||
| <view class="label">联系电话</view> | |||
| <input | |||
| v-model="form.phone" | |||
| placeholder-style="color: #999999; font-size: 28rpx;" | |||
| placeholder="请输入手机号" | |||
| /> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| </uv-form> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| form: { | |||
| textDetails: null, | |||
| phone: null, | |||
| }, | |||
| formItemStyle: { padding: 0 }, | |||
| } | |||
| }, | |||
| onReady() { | |||
| this.$refs.form.setRules(this.getRules()); | |||
| }, | |||
| methods: { | |||
| onEditorReady() { | |||
| uni.createSelectorQuery().select('#editor').context((res) => { | |||
| this.editorCtx = res.context | |||
| }).exec() | |||
| }, | |||
| onEditroInput(e) { | |||
| const { text } = e.detail | |||
| this.descLen = text?.length || 0 | |||
| }, | |||
| insertImage() { | |||
| uni.chooseImage({ | |||
| count: 1, | |||
| success: (res) => { | |||
| // this.editorCtx.insertImage({ | |||
| // src: res.tempFilePaths[0], | |||
| // alt: '图像', | |||
| // }) | |||
| // todo: check | |||
| this.$Oss.ossUpload(res.tempFilePaths[0]).then(url => { | |||
| this.editorCtx.insertImage({ | |||
| src: url, | |||
| alt: '图像', | |||
| }) | |||
| }) | |||
| } | |||
| }) | |||
| }, | |||
| setEditorContents(html) { | |||
| if (!this.editorCtx) { | |||
| setTimeout(() => { | |||
| this.setEditorContents(html) | |||
| }, 200) | |||
| return | |||
| } | |||
| this.editorCtx.setContents({ html }) | |||
| }, | |||
| getEditorContents() { | |||
| return new Promise((resolve, reject) => { | |||
| this.editorCtx.getContents({ | |||
| success: (e) => { | |||
| const { html, text } = e | |||
| resolve({ html, text }) | |||
| }, | |||
| fail: () => { | |||
| reject() | |||
| } | |||
| }) | |||
| }) | |||
| }, | |||
| getRules() { | |||
| const textDetailsValidator = async (rule, value, callback) => { | |||
| const textDetails = (await this.getEditorContents())?.html | |||
| if (textDetails) { | |||
| callback() | |||
| return | |||
| } | |||
| callback(new Error('请填写10个字以上的内容,以便我们为您提供更好的服务')) | |||
| } | |||
| return { | |||
| 'phone': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请输入手机号', | |||
| }, | |||
| 'textDetails': { | |||
| asyncValidator: textDetailsValidator, | |||
| }, | |||
| } | |||
| }, | |||
| async onSubmit(headImage) { | |||
| try { | |||
| await this.$refs.form.validate() | |||
| const textDetails = (await this.getEditorContents())?.html | |||
| const { | |||
| phone, | |||
| } = this.form | |||
| const params = { | |||
| phone, | |||
| textDetails, | |||
| } | |||
| // todo | |||
| // await this.$fetch('saveOrUpdateArticleShare', params) | |||
| uni.showToast({ | |||
| title: '提交成功', | |||
| icon: 'none' | |||
| }) | |||
| setTimeout(uni.navigateBack, 1000, -1) | |||
| } catch (err) { | |||
| } | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| background: #F5F5F5; | |||
| /deep/ .nav-bar__view { | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| } | |||
| } | |||
| .bg { | |||
| width: 100%; | |||
| height: 501rpx; | |||
| padding-top: 203rpx; | |||
| box-sizing: border-box; | |||
| color: #FFFFFF; | |||
| background: linear-gradient(164deg, #014FA2 30%, #4C8FD6); | |||
| .title { | |||
| padding: 0 73rpx; | |||
| font-size: 64rpx; | |||
| font-weight: 600; | |||
| } | |||
| .desc { | |||
| margin-top: 18rpx; | |||
| padding: 0 68rpx; | |||
| box-sizing: border-box; | |||
| font-size: 28rpx; | |||
| } | |||
| } | |||
| .main { | |||
| width: 100%; | |||
| padding: 0 28rpx; | |||
| box-sizing: border-box; | |||
| background: #F5F5F5; | |||
| } | |||
| .form { | |||
| // transform: translateY(-98rpx); | |||
| transform: translateY(-46rpx); | |||
| &-item { | |||
| & + & { | |||
| margin-top: 36rpx; | |||
| } | |||
| } | |||
| } | |||
| .editor__view { | |||
| padding: 43rpx 30rpx; | |||
| background-color: #FFFFFF; | |||
| border-radius: 12rpx; | |||
| } | |||
| .editor-header { | |||
| position: absolute; | |||
| top: 0; | |||
| left: 12rpx; | |||
| transform: translateY(-100%); | |||
| // margin-left: 12rpx; | |||
| &-content { | |||
| position: relative; | |||
| padding: 9rpx 20rpx 3rpx 20rpx; | |||
| font-size: 28rpx; | |||
| font-weight: 600; | |||
| color: #FFFFFF; | |||
| border-top-left-radius: 30rpx; | |||
| background: linear-gradient(to right, #014FA2, #6A9ACE); | |||
| } | |||
| } | |||
| .editor-icon { | |||
| position: absolute; | |||
| top: 0; | |||
| right: 0; | |||
| transform: translate(30rpx, -4rpx); | |||
| } | |||
| .editor { | |||
| height: 462rpx; | |||
| &-tools { | |||
| padding: 0 7rpx; | |||
| .btn { | |||
| width: 133rpx; | |||
| height: 133rpx; | |||
| border: 2rpx dashed #014FA2; | |||
| } | |||
| } | |||
| } | |||
| .card { | |||
| position: relative; | |||
| } | |||
| .phone { | |||
| justify-content: flex-start; | |||
| padding: 44rpx 27rpx; | |||
| column-gap: 31rpx; | |||
| background: #FFFFFF; | |||
| border-radius: 15rpx; | |||
| .label { | |||
| font-size: 28rpx; | |||
| color: #000000; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,262 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="意见反馈" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" /> | |||
| <image class="bg" :src="configList.feedback_bg" mode="widthFix"></image> | |||
| <!-- <view class="bg"> | |||
| <view class="title">Hello</view> | |||
| <view class="desc">有什么好的建议可以告诉我们哦~</view> | |||
| </view> --> | |||
| <view class="main"> | |||
| <view class="form"> | |||
| <uv-form | |||
| ref="form" | |||
| :model="form" | |||
| :rules="rules" | |||
| errorType="toast" | |||
| > | |||
| <view class="form-item"> | |||
| <uv-form-item prop="content" :customStyle="formItemStyle"> | |||
| <view class="card feedback"> | |||
| <view class="feedback-header"> | |||
| <view class="feedback-header-content"> | |||
| <view>反馈内容</view> | |||
| <view class="feedback-icon"> | |||
| <image class="icon" src="@/pages_order/static/feedback/icon-star.png" mode="widthFix"></image> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view> | |||
| <formTextarea v-model="form.content" placeholder="请填写10个字以上的内容,以便我们为您提供更好的服务"></formTextarea> | |||
| </view> | |||
| <view> | |||
| <formUpload v-model="form.images"></formUpload> | |||
| </view> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item"> | |||
| <uv-form-item prop="phone" :customStyle="formItemStyle"> | |||
| <view class="flex card phone"> | |||
| <view class="label">联系电话</view> | |||
| <input | |||
| v-model="form.phone" | |||
| placeholder-style="color: #999999; font-size: 28rpx;" | |||
| placeholder="请输入手机号" | |||
| /> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| </uv-form> | |||
| </view> | |||
| </view> | |||
| <view class="bottom"> | |||
| <button class="btn" @click="onSubmit">提交</button> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import util from '@/utils/utils.js' | |||
| import formTextarea from '@/pages_order/components/formTextarea.vue' | |||
| import formUpload from '@/pages_order/components/formUpload.vue' | |||
| export default { | |||
| components: { | |||
| formTextarea, | |||
| formUpload, | |||
| }, | |||
| data() { | |||
| return { | |||
| form: { | |||
| content: null, | |||
| images: [], | |||
| phone: null, | |||
| }, | |||
| rules: { | |||
| 'content': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请填写10个字以上的内容,以便我们为您提供更好的服务', | |||
| }, | |||
| 'phone': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请输入正确的手机号', | |||
| validator: (rule, value, callback) => { | |||
| return util.verificationPhone(value) | |||
| }, | |||
| }, | |||
| }, | |||
| formItemStyle: { padding: 0 }, | |||
| } | |||
| }, | |||
| onReady() { | |||
| this.$refs.form.setRules(this.rules); | |||
| }, | |||
| methods: { | |||
| async onSubmit() { | |||
| try { | |||
| await this.$refs.form.validate() | |||
| const { | |||
| content, | |||
| images, | |||
| phone, | |||
| } = this.form | |||
| const params = { | |||
| content, | |||
| image: images.join(','), | |||
| phone, | |||
| } | |||
| await this.$fetch('addFeedback', params) | |||
| uni.showToast({ | |||
| title: '提交成功', | |||
| icon: 'none' | |||
| }) | |||
| setTimeout(uni.navigateBack, 1000, -1) | |||
| } catch (err) { | |||
| } | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| background: #F5F5F5; | |||
| /deep/ .nav-bar__view { | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| } | |||
| } | |||
| .bg { | |||
| width: 100%; | |||
| height: auto; | |||
| min-height: 501rpx; | |||
| // height: 501rpx; | |||
| // padding-top: 203rpx; | |||
| // box-sizing: border-box; | |||
| // color: #FFFFFF; | |||
| // background: linear-gradient(164deg, #014FA2 30%, #4C8FD6); | |||
| // .title { | |||
| // padding: 0 73rpx; | |||
| // font-size: 64rpx; | |||
| // font-weight: 600; | |||
| // } | |||
| // .desc { | |||
| // margin-top: 18rpx; | |||
| // padding: 0 68rpx; | |||
| // box-sizing: border-box; | |||
| // font-size: 28rpx; | |||
| // } | |||
| } | |||
| .main { | |||
| width: 100%; | |||
| padding: 0 28rpx 200rpx 28rpx; | |||
| box-sizing: border-box; | |||
| background: #F5F5F5; | |||
| } | |||
| .form { | |||
| // transform: translateY(-98rpx); | |||
| transform: translateY(-46rpx); | |||
| &-item { | |||
| & + & { | |||
| margin-top: 36rpx; | |||
| } | |||
| } | |||
| } | |||
| .card { | |||
| position: relative; | |||
| background: #FFFFFF; | |||
| border-radius: 15rpx; | |||
| } | |||
| .feedback { | |||
| padding: 43rpx 31rpx; | |||
| } | |||
| .feedback-header { | |||
| position: absolute; | |||
| top: 0; | |||
| left: 12rpx; | |||
| transform: translateY(-100%); | |||
| // margin-left: 12rpx; | |||
| &-content { | |||
| position: relative; | |||
| padding: 9rpx 20rpx 3rpx 20rpx; | |||
| font-size: 28rpx; | |||
| font-weight: 600; | |||
| color: #FFFFFF; | |||
| border-top-left-radius: 30rpx; | |||
| background: linear-gradient(to right, #014FA2, #6A9ACE); | |||
| } | |||
| } | |||
| .feedback-icon { | |||
| position: absolute; | |||
| top: 0; | |||
| right: 0; | |||
| transform: translate(30rpx, -10rpx); | |||
| .icon { | |||
| width: 26rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| .phone { | |||
| justify-content: flex-start; | |||
| padding: 44rpx 27rpx; | |||
| column-gap: 31rpx; | |||
| .label { | |||
| font-size: 28rpx; | |||
| color: #000000; | |||
| } | |||
| } | |||
| .bottom { | |||
| position: fixed; | |||
| left: 0; | |||
| bottom: 0; | |||
| width: 100vw; | |||
| padding: 0 35rpx 56rpx 35rpx; | |||
| padding-bottom: calc(env(safe-area-inset-bottom) + 35rpx); | |||
| box-sizing: border-box; | |||
| .btn { | |||
| width: 100%; | |||
| padding: 29rpx 0; | |||
| box-sizing: border-box; | |||
| font-size: 30rpx; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 50rpx; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,85 +0,0 @@ | |||
| <template> | |||
| <uv-popup | |||
| ref="popup" | |||
| :overlayOpacity="0" | |||
| mode="center" | |||
| bgColor="none" | |||
| > | |||
| <view class="flex flex-column popup__view"> | |||
| <text class="title">兑换码输入有误,请与客服确认~</text> | |||
| <text class="desc">联系客服获取抵扣码</text> | |||
| <image class="img" :src="configList.customer_service_qrcode" :show-menu-by-longpress="true" mode="widthFix"></image> | |||
| <button class="btn" @click="close">好的</button> | |||
| </view> | |||
| </uv-popup> | |||
| </template> | |||
| <script> | |||
| import { mapState } from 'vuex' | |||
| export default { | |||
| props: { | |||
| src: { | |||
| type: String, | |||
| default: null | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| } | |||
| }, | |||
| computed : { | |||
| ...mapState(['configList']) | |||
| }, | |||
| methods: { | |||
| open() { | |||
| this.$refs.popup.open(); | |||
| }, | |||
| close() { | |||
| this.$refs.popup.close(); | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .popup__view { | |||
| position: relative; | |||
| width: 600rpx; | |||
| min-height: 582rpx; | |||
| padding: 60rpx 59rpx 40rpx 59rpx; | |||
| box-sizing: border-box; | |||
| background: #FFFFFF; | |||
| border-radius: 16rpx; | |||
| } | |||
| .title { | |||
| font-size: 30rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| } | |||
| .desc { | |||
| margin-top: 48rpx; | |||
| font-size: 28rpx; | |||
| font-weight: 500; | |||
| color: #000000; | |||
| } | |||
| .img { | |||
| margin: 40rpx 0 75rpx 0; | |||
| width: 156rpx; | |||
| height: auto; | |||
| min-height: 156rpx; | |||
| } | |||
| .btn { | |||
| width: 100%; | |||
| padding: 18rpx 0; | |||
| box-sizing: border-box; | |||
| font-size: 30rpx; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 40rpx; | |||
| } | |||
| </style> | |||
| @ -1,299 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="支付" leftClick @leftClick="$utils.navigateBack" /> | |||
| <view class="flex flex-column info"> | |||
| <view>实付金额</view> | |||
| <view class="flex price"> | |||
| <view>¥</view> | |||
| <view class="highlight">{{ payAmount }}</view> | |||
| </view> | |||
| <view class="flex flex-column contact"> | |||
| <view>联系客服获取抵扣码</view> | |||
| <image class="qr" :src="configList.customer_service_qrcode" :show-menu-by-longpress="true" mode="widthFix"></image> | |||
| </view> | |||
| </view> | |||
| <view class="form"> | |||
| <uv-form | |||
| ref="form" | |||
| :model="form" | |||
| :rules="rules" | |||
| errorType="toast" | |||
| > | |||
| <view class="form-item"> | |||
| <uv-form-item prop="payment" :customStyle="formItemStyle"> | |||
| <view class="form-item-label">选择支付方式</view> | |||
| <view class="form-item-content"> | |||
| <uv-radio-group | |||
| v-model="form.payment" | |||
| placement="column" | |||
| shape="circle" | |||
| size="30rpx" | |||
| iconSize="30rpx" | |||
| activeColor="#014FA2" | |||
| > | |||
| <view class="payment"> | |||
| <view class="flex payment-content"> | |||
| <view class="flex payment-content-info"> | |||
| <image class="icon" src="@/pages_order/static/report/icon-wx.png" mode="widthFix"></image> | |||
| <view>微信支付</view> | |||
| </view> | |||
| <view> | |||
| <uv-radio :name="0"></uv-radio> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="payment"> | |||
| <view class="flex payment-content"> | |||
| <view class="flex payment-content-info"> | |||
| <image class="icon" src="@/pages_order/static/report/icon-coupon.png" mode="widthFix"></image> | |||
| <view>兑换码抵扣支付</view> | |||
| </view> | |||
| <view> | |||
| <uv-radio :name="1"></uv-radio> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </uv-radio-group> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item is-child" v-if="form.payment == 1"> | |||
| <uv-form-item prop="code" :customStyle="formItemStyle"> | |||
| <view class="flex row"> | |||
| <view class="form-item-label">兑换码</view> | |||
| <view class="form-item-content"> | |||
| <input | |||
| v-model="form.code" | |||
| placeholder="请输入兑换码" | |||
| placeholderStyle="color: #999999; font-size: 30rpx; font-weight: 400;" | |||
| /> | |||
| </view> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| </uv-form> | |||
| </view> | |||
| <view class="bottom"> | |||
| <button class="btn" @click="onPay">立即支付</button> | |||
| </view> | |||
| <codeErrorPopup ref="codeErrorPopup"></codeErrorPopup> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import codeErrorPopup from './codeErrorPopup.vue' | |||
| export default { | |||
| components: { | |||
| codeErrorPopup, | |||
| }, | |||
| data() { | |||
| return { | |||
| batchNo: null, | |||
| form: { | |||
| payment: 0, | |||
| code: null, | |||
| }, | |||
| rules: { | |||
| 'payment': { | |||
| type: 'number', | |||
| required: false, | |||
| message: '请选择支付方式', | |||
| }, | |||
| 'code': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请输入兑换码', | |||
| }, | |||
| }, | |||
| formItemStyle: { padding: 0 }, | |||
| } | |||
| }, | |||
| computed: { | |||
| payAmount() { | |||
| return Number(this.configList.pay_amount) | |||
| } | |||
| }, | |||
| onLoad(arg) { | |||
| const { batchNo } = arg | |||
| this.batchNo = batchNo | |||
| }, | |||
| methods: { | |||
| async onPay() { | |||
| try { | |||
| await this.$refs.form.validate() | |||
| const { | |||
| payment, | |||
| code, | |||
| } = this.form | |||
| const params = { | |||
| batchNo: this.batchNo, | |||
| payAmount: this.payAmount, | |||
| } | |||
| if (payment == 1) { // 兑换码 | |||
| const infoRes = await this.$fetch('queryCodeById', { code }, false, null, true) | |||
| const { result: infoResult } = infoRes | |||
| if (!infoResult || infoResult?.isUse !== '0') { | |||
| this.$refs.codeErrorPopup.open() | |||
| return | |||
| } | |||
| params.discountAmount = infoResult.discountAmount | |||
| params.payAmount -= params.discountAmount | |||
| params.code = code | |||
| } | |||
| const result = await this.$fetch('createOrder', params) | |||
| await uni.requestPaymentWxPay({ result }) | |||
| uni.showToast({ | |||
| title: '支付成功', | |||
| icon: 'none' | |||
| }) | |||
| setTimeout(() => { | |||
| uni.redirectTo({ | |||
| url: `/pages_order/report/userInfo?batchNo=${this.batchNo}` | |||
| }) | |||
| }, 700) | |||
| } catch (err) { | |||
| } | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .info { | |||
| width: 100%; | |||
| padding: 96rpx 62rpx 51rpx 62rpx; | |||
| box-sizing: border-box; | |||
| font-size: 28rpx; | |||
| line-height: 50rpx; | |||
| color: #000000; | |||
| .price { | |||
| margin-top: 23rpx; | |||
| align-items: baseline; | |||
| column-gap: 13rpx; | |||
| font-size: 51rpx; | |||
| line-height: 72rpx; | |||
| color: #000000; | |||
| .highlight { | |||
| font-size: 78rpx; | |||
| line-height: 110rpx; | |||
| } | |||
| } | |||
| .contact { | |||
| margin-top: 52rpx; | |||
| row-gap: 40rpx; | |||
| width: 100%; | |||
| padding: 30rpx 0 26rpx 0; | |||
| box-sizing: border-box; | |||
| border: 1rpx dashed #014FA2; | |||
| .qr { | |||
| width: 157rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| .form { | |||
| &-item { | |||
| &-label { | |||
| padding: 0 38rpx; | |||
| font-size: 28rpx; | |||
| line-height: 50rpx; | |||
| color: #000000; | |||
| } | |||
| &-content { | |||
| } | |||
| } | |||
| } | |||
| .payment { | |||
| &:first-child { | |||
| margin-top: 24rpx; | |||
| } | |||
| & + & { | |||
| border-top: 20rpx solid #F7F7F7; | |||
| } | |||
| &-content { | |||
| justify-content: space-between; | |||
| padding: 32rpx 60rpx 32rpx 50rpx; | |||
| &-info { | |||
| column-gap: 15rpx; | |||
| font-size: 30rpx; | |||
| color: #000000; | |||
| .icon { | |||
| width: 58rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .form-item.is-child { | |||
| padding: 22rpx 60rpx 0 123rpx; | |||
| .form-item-label, | |||
| .form-item-content { | |||
| padding: 0; | |||
| } | |||
| .form-item-label { | |||
| padding-right: 16rpx; | |||
| font-size: 30rpx; | |||
| } | |||
| .form-item-content { | |||
| flex: 1; | |||
| padding: 11rpx; | |||
| background: #F7F7F7; | |||
| } | |||
| } | |||
| .bottom { | |||
| position: fixed; | |||
| left: 0; | |||
| bottom: 0; | |||
| width: 100%; | |||
| padding: 35rpx 56rpx; | |||
| padding-bottom: calc(env(safe-area-inset-bottom) + 35rpx); | |||
| background: #FFFFFF; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| width: 100%; | |||
| padding: 29rpx 0; | |||
| font-size: 30rpx; | |||
| line-height: 1.5; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 50rpx; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,262 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="支付" leftClick @leftClick="$utils.navigateBack" /> | |||
| <view class="status"> | |||
| <view class="flex status-content"> | |||
| <uv-icon name="checkmark-circle-fill" color="#014FA2" size="48rpx"></uv-icon> | |||
| <view>支付成功</view> | |||
| </view> | |||
| </view> | |||
| <view class="tips"> | |||
| <view class="flex tips-content"> | |||
| <!-- <uv-icon name="error-circle" color="#014FA2" size="36rpx"></uv-icon> --> | |||
| <image class="icon" src="@/pages_order/static/report/icon-info.png" mode="widthFix"></image> | |||
| <view>请如实填写以下信息,方可获取答题情况生成风险测评报告!</view> | |||
| </view> | |||
| </view> | |||
| <view class="form"> | |||
| <view class="flex form-header"> | |||
| <view class="line"></view> | |||
| <view>基本信息</view> | |||
| </view> | |||
| <uv-form | |||
| ref="form" | |||
| :model="form" | |||
| :rules="rules" | |||
| errorType="toast" | |||
| > | |||
| <view class="form-item"> | |||
| <uv-form-item prop="name" :customStyle="formItemStyle"> | |||
| <view class="flex row"> | |||
| <view class="row-label">姓名</view> | |||
| <view class="row-content"> | |||
| <input | |||
| v-model="form.name" | |||
| placeholder="请输入您的姓名" | |||
| :placeholderStyle="placeholderStyle" | |||
| /> | |||
| </view> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item"> | |||
| <uv-form-item prop="phone" :customStyle="formItemStyle"> | |||
| <view class="flex row"> | |||
| <view class="row-label">手机号码</view> | |||
| <view class="row-content"> | |||
| <input | |||
| v-model="form.phone" | |||
| placeholder="请输入您的手机号" | |||
| :placeholderStyle="placeholderStyle" | |||
| /> | |||
| </view> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item"> | |||
| <uv-form-item prop="company" :customStyle="formItemStyle"> | |||
| <view class="flex row"> | |||
| <view class="row-label is-required">公司名称</view> | |||
| <view class="row-content"> | |||
| <input | |||
| v-model="form.company" | |||
| placeholder="请选输入公司全称" | |||
| :placeholderStyle="placeholderStyle" | |||
| /> | |||
| </view> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| </uv-form> | |||
| </view> | |||
| <view class="bottom"> | |||
| <button :class="['btn', disabled ? 'is-disabled' : '']" @click="onCreateReport">生成报告</button> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| id: null, | |||
| form: { | |||
| name: '', | |||
| phone: '', | |||
| company: '', | |||
| }, | |||
| rules: { | |||
| 'company': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请填写公司名称~', | |||
| }, | |||
| }, | |||
| formItemStyle: { padding: 0 }, | |||
| placeholderStyle: 'color: #BDBDBD; font-size: 28rpx; font-weight: 400;' | |||
| } | |||
| }, | |||
| computed: { | |||
| disabled() { | |||
| const { name, phone, company } = this.form | |||
| return !company | |||
| } | |||
| }, | |||
| onLoad(arg) { | |||
| const { batchNo } = arg | |||
| this.batchNo = batchNo | |||
| }, | |||
| methods: { | |||
| async onCreateReport() { | |||
| try { | |||
| await this.$refs.form.validate() | |||
| const { name, phone, company } = this.form | |||
| const params = { | |||
| batchNo: this.batchNo, | |||
| name, | |||
| phone, | |||
| company, | |||
| } | |||
| await this.$fetch('addReport', params) | |||
| uni.redirectTo({ | |||
| url: `/pages_order/report/index?batchNo=${this.batchNo}` | |||
| }) | |||
| } catch (err) { | |||
| } | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .status { | |||
| width: 100%; | |||
| padding: 0 20rpx; | |||
| box-sizing: border-box; | |||
| &-content { | |||
| width: 100%; | |||
| padding: 157rpx 0 84rpx 0; | |||
| box-sizing: border-box; | |||
| column-gap: 18rpx; | |||
| font-size: 48rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| border-bottom: 1rpx dashed #E2EAF1; | |||
| } | |||
| } | |||
| .tips { | |||
| width: 100%; | |||
| padding: 68rpx 24rpx 35rpx 24rpx; | |||
| box-sizing: border-box; | |||
| &-content { | |||
| justify-content: flex-start; | |||
| column-gap: 15rpx; | |||
| width: 100%; | |||
| padding: 13rpx 22rpx; | |||
| box-sizing: border-box; | |||
| font-size: 22rpx; | |||
| line-height: 40rpx; | |||
| color: #014FA2; | |||
| background: rgba($color: #014FA2, $alpha: 0.16); | |||
| border-radius: 11rpx; | |||
| .icon { | |||
| width: 36rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| .form { | |||
| padding: 0 18rpx; | |||
| &-header { | |||
| margin-bottom: 28rpx; | |||
| padding: 0 18rpx; | |||
| justify-content: flex-start; | |||
| column-gap: 7rpx; | |||
| font-size: 30rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| .line { | |||
| width: 9rpx; | |||
| height: 33rpx; | |||
| background: #014FA2; | |||
| border-radius: 6rpx; | |||
| } | |||
| } | |||
| &-item { | |||
| border-bottom: 0.5rpx solid rgba($color: #707070, $alpha: 0.14); | |||
| } | |||
| } | |||
| .row { | |||
| justify-content: space-between; | |||
| padding: 36rpx 30rpx 22rpx 24rpx; | |||
| &-label { | |||
| position: relative; | |||
| font-size: 30rpx; | |||
| color: #000000; | |||
| &.is-required:after { | |||
| content: '*'; | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| font-size: 15rpx; | |||
| line-height: 42rpx; | |||
| color: #FF3838; | |||
| } | |||
| } | |||
| &-content { | |||
| /deep/ input { | |||
| text-align: right; | |||
| } | |||
| } | |||
| } | |||
| .bottom { | |||
| position: fixed; | |||
| left: 0; | |||
| bottom: 0; | |||
| width: 100%; | |||
| padding: 35rpx 56rpx; | |||
| padding-bottom: calc(env(safe-area-inset-bottom) + 35rpx); | |||
| background: #FFFFFF; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| width: 100%; | |||
| padding: 29rpx 0; | |||
| font-size: 30rpx; | |||
| line-height: 1.5; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 50rpx; | |||
| &.is-disabled { | |||
| background: #999999; | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,55 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="常见问题" leftClick @leftClick="$utils.navigateBack" /> | |||
| <view class="main"> | |||
| <view class="title">{{ commonQuestion.question }}</view> | |||
| <view class="content"> | |||
| <uv-parse :content="commonQuestion.answer"></uv-parse> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import { mapState } from 'vuex' | |||
| export default { | |||
| data() { | |||
| return { | |||
| detail: {}, | |||
| } | |||
| }, | |||
| computed: { | |||
| ...mapState(['commonQuestion']), | |||
| }, | |||
| onLoad(arg) { | |||
| const { id } = arg | |||
| this.getData(id) | |||
| }, | |||
| methods: { | |||
| async getData(id) { | |||
| // todo: fetch by id | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .main { | |||
| padding: 39rpx 30rpx; | |||
| } | |||
| .title { | |||
| text-align: center; | |||
| font-size: 30rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| } | |||
| .content { | |||
| margin-top: 50rpx; | |||
| } | |||
| </style> | |||
| @ -1,198 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="咨询客服" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" /> | |||
| <image class="bg" :src="configList.customer_service_bg" mode="widthFix"></image> | |||
| <!-- <view class="flex bg"> | |||
| <view class="flex bg-content"> | |||
| <view class="text"> | |||
| <view class="title">Hi~,有什么可以帮您!</view> | |||
| <view class="desc"> | |||
| <view class="line">工作时间:</view> | |||
| <view class="line">8:00-12:00 13:00-17:30</view> | |||
| </view> | |||
| </view> | |||
| <image class="icon" src="@/pages_order/static/service/icon-service.png" mode="widthFix"></image> | |||
| </view> | |||
| </view> --> | |||
| <view class="main"> | |||
| <view class="content"> | |||
| <view class="flex card concat"> | |||
| <button plain class="flex flex-column btn" open-type="contact"> | |||
| <image class="icon" src="@/pages_order/static/service/icon-message.png" mode="widthFix"></image> | |||
| <view>联系客服</view> | |||
| </button> | |||
| <button plain class="flex flex-column btn" @click="openQrPopup"> | |||
| <image class="icon" src="@/pages_order/static/service/icon-wx.png" mode="widthFix"></image> | |||
| <view>添加微信</view> | |||
| </button> | |||
| <button plain class="flex flex-column btn" @click="openPhonePopup"> | |||
| <image class="icon" src="@/pages_order/static/service/icon-phone.png" mode="widthFix"></image> | |||
| <view>电话咨询</view> | |||
| </button> | |||
| </view> | |||
| <view class="card question"> | |||
| <view class="card-header">常见问题</view> | |||
| <view class="flex row" v-for="item in list" :key="item.id" @click="jumpToQuestion(item.id)"> | |||
| <view>{{ item.question }}</view> | |||
| <uv-icon name="arrow-right" color="#999999" size="33rpx"></uv-icon> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <popupQrCode ref="popupQrCode"></popupQrCode> | |||
| <popupPhone ref="popupPhone"></popupPhone> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import mixinsList from '@/mixins/list.js' | |||
| import popupQrCode from './popupQrCode.vue' | |||
| import popupPhone from './popupPhone.vue' | |||
| export default { | |||
| mixins: [mixinsList], | |||
| components: { | |||
| popupQrCode, | |||
| popupPhone, | |||
| }, | |||
| data() { | |||
| return { | |||
| list: [], | |||
| mixinsListApi: 'queryFaqList', | |||
| } | |||
| }, | |||
| methods: { | |||
| openQrPopup() { | |||
| this.$refs.popupQrCode.open() | |||
| }, | |||
| openPhonePopup() { | |||
| this.$refs.popupPhone.open() | |||
| }, | |||
| jumpToQuestion(id) { | |||
| let data = this.list.find(item => item.id === id) | |||
| this.$store.commit('setCommonQuestion', data) | |||
| uni.navigateTo({ | |||
| url: `/pages_order/service/commonQuestion?id=${id}` | |||
| }) | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| background: #F5F5F5; | |||
| /deep/ .nav-bar__view { | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| } | |||
| } | |||
| .bg { | |||
| width: 100%; | |||
| height: auto; | |||
| min-height: 501rpx; | |||
| // width: 100%; | |||
| // height: 501rpx; | |||
| // background: linear-gradient(160deg, #014FA2 36%, #4C8FD6); | |||
| // padding: 0 104rpx 90rpx 65rpx; | |||
| // box-sizing: border-box; | |||
| // align-items: flex-end; | |||
| // &-content { | |||
| // width: 100%; | |||
| // justify-content: space-between; | |||
| // } | |||
| // .text { | |||
| // padding: 26rpx 0 34rpx 0; | |||
| // color: #FFFFFF; | |||
| // .title { | |||
| // font-size: 36rpx; | |||
| // font-weight: 600; | |||
| // } | |||
| // .desc { | |||
| // margin-top: 13rpx; | |||
| // font-size: 22rpx; | |||
| // .line + .line { | |||
| // margin-top: 11rpx; | |||
| // } | |||
| // } | |||
| // } | |||
| // .icon { | |||
| // width: 168rpx; | |||
| // height: auto; | |||
| // } | |||
| } | |||
| .main { | |||
| width: 100%; | |||
| padding: 0 28rpx 28rpx 28rpx; | |||
| box-sizing: border-box; | |||
| background: #F5F5F5; | |||
| .content { | |||
| transform: translateY(-64rpx); | |||
| } | |||
| } | |||
| .card { | |||
| width: 100%; | |||
| background: #FFFFFF; | |||
| border-radius: 15rpx; | |||
| } | |||
| .card.concat { | |||
| justify-content: space-between; | |||
| width: 100%; | |||
| padding: 55rpx 64rpx 26rpx 64rpx; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| justify-content: space-between; | |||
| font-size: 28rpx; | |||
| color: #000000; | |||
| border: none; | |||
| .icon { | |||
| width: 66rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| .card.question { | |||
| margin-top: 25rpx; | |||
| padding: 34rpx 19rpx; | |||
| box-sizing: border-box; | |||
| .card-header { | |||
| padding: 0 11rpx 11rpx 11rpx; | |||
| font-size: 32rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| } | |||
| .row { | |||
| margin-top: 22rpx; | |||
| justify-content: space-between; | |||
| padding: 17rpx 14rpx 17rpx 23rpx; | |||
| font-size: 30rpx; | |||
| color: #000000; | |||
| border-bottom: 0.5rpx solid rgba($color: #707070, $alpha: 0.1); | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,119 +0,0 @@ | |||
| <template> | |||
| <uv-popup | |||
| ref="popup" | |||
| :overlayOpacity="0" | |||
| mode="center" | |||
| bgColor="none" | |||
| > | |||
| <view class="popup__view"> | |||
| <image class="bg" src="@/pages_order/static/service/bg-popup-phone.png" mode="widthFix"></image> | |||
| <view class="flex flex-column content"> | |||
| <text class="title">电话咨询</text> | |||
| <view class="flex phone"> | |||
| <view class="flex icon" @click="onCall"> | |||
| <image class="img" src="@/pages_order/static/service/icon-phone.png" mode="widthFix"></image> | |||
| </view> | |||
| <view>{{ phone }}</view> | |||
| </view> | |||
| <button class="btn" @click="onCopy()">复制手机号</button> | |||
| </view> | |||
| </view> | |||
| </uv-popup> | |||
| </template> | |||
| <script> | |||
| import { mapState } from 'vuex' | |||
| import utils from '@/utils/utils.js' | |||
| export default { | |||
| data() { | |||
| return { | |||
| phone: '', | |||
| } | |||
| }, | |||
| computed : { | |||
| ...mapState(['configList']) | |||
| }, | |||
| methods: { | |||
| open() { | |||
| this.phone = this.configList.customer_service_phone | |||
| this.$refs.popup.open(); | |||
| }, | |||
| close() { | |||
| this.$refs.popup.close(); | |||
| }, | |||
| onCall() { | |||
| uni.makePhoneCall({ | |||
| phoneNumber: this.phone, | |||
| success() { | |||
| console.log('安卓拨打成功'); | |||
| }, | |||
| fail() { | |||
| console.log('安卓拨打失败'); | |||
| } | |||
| }) | |||
| }, | |||
| onCopy() { | |||
| utils.copyText(this.phone) | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .popup__view { | |||
| position: relative; | |||
| width: 684rpx; | |||
| min-height: 701rpx; | |||
| background: #FFFFFF; | |||
| border-radius: 16rpx; | |||
| } | |||
| .bg { | |||
| width: 100%; | |||
| height: auto; | |||
| } | |||
| .content { | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| width: 100%; | |||
| height: 100%; | |||
| padding: 69rpx 0; | |||
| box-sizing: border-box; | |||
| justify-content: space-between; | |||
| } | |||
| .title { | |||
| font-size: 32rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| } | |||
| .phone { | |||
| margin: 238rpx 0 122rpx 0; | |||
| column-gap: 21rpx; | |||
| font-size: 32rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| .icon { | |||
| width: 60rpx; | |||
| height: 60rpx; | |||
| .img { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| } | |||
| .btn { | |||
| padding: 29rpx 202rpx; | |||
| font-size: 30rpx; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 50rpx; | |||
| } | |||
| </style> | |||
| @ -1,86 +0,0 @@ | |||
| <template> | |||
| <uv-popup | |||
| ref="popup" | |||
| :overlayOpacity="0" | |||
| mode="center" | |||
| bgColor="none" | |||
| > | |||
| <view class="popup__view"> | |||
| <image class="bg" src="@/pages_order/static/service/bg-popup-qr.png" mode="widthFix"></image> | |||
| <view class="flex flex-column content"> | |||
| <text class="title">扫码添加微信</text> | |||
| <image class="img" :src="configList.customer_service_qrcode" :show-menu-by-longpress="true"></image> | |||
| <button class="btn" @click="close">已截图</button> | |||
| </view> | |||
| </view> | |||
| </uv-popup> | |||
| </template> | |||
| <script> | |||
| import { mapState } from 'vuex' | |||
| export default { | |||
| data() { | |||
| return { | |||
| } | |||
| }, | |||
| computed : { | |||
| ...mapState(['configList']) | |||
| }, | |||
| methods: { | |||
| open() { | |||
| this.$refs.popup.open(); | |||
| }, | |||
| close() { | |||
| this.$refs.popup.close(); | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .popup__view { | |||
| position: relative; | |||
| width: 684rpx; | |||
| min-height: 826rpx; | |||
| background: #FFFFFF; | |||
| border-radius: 16rpx; | |||
| } | |||
| .bg { | |||
| width: 100%; | |||
| height: auto; | |||
| } | |||
| .content { | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| width: 100%; | |||
| height: 100%; | |||
| padding: 71rpx 0 23rpx 0; | |||
| box-sizing: border-box; | |||
| justify-content: space-between; | |||
| } | |||
| .title { | |||
| font-size: 32rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| } | |||
| .img { | |||
| margin: 156rpx 0 73rpx 0; | |||
| width: 360rpx; | |||
| height: auto; | |||
| min-height: 360rpx; | |||
| } | |||
| .btn { | |||
| padding: 29rpx 202rpx; | |||
| font-size: 30rpx; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 50rpx; | |||
| } | |||
| </style> | |||
| @ -1,428 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="答题测评" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" /> | |||
| <!-- 答题完成 --> | |||
| <template v-if="total && current === total"> | |||
| <view class="flex main is-finish"> | |||
| <view class="card"> | |||
| <image class="card-bg" src="@/pages_order/static/test/bg-test-finsih.png" mode="widthFix"></image> | |||
| <view class="flex flex-column card-content"> | |||
| <view class="text">恭喜你~</view> | |||
| <view class="text">您已完成所有测评题目!</view> | |||
| <button class="btn" @click="onCreateReport">生成报告</button> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <!-- 答题中 --> | |||
| <template v-else-if="currentQuestion"> | |||
| <view class="bar"> | |||
| <view class="flex info"> | |||
| <view>答题进度</view> | |||
| <view> | |||
| <text class="highlight">{{ current + 1 }}</text> | |||
| <text>{{ `/${total}` }}</text> | |||
| </view> | |||
| </view> | |||
| <view class="progress"> | |||
| <view class="progress-bar" :style="{ width: `${progress}%` }"></view> | |||
| </view> | |||
| </view> | |||
| <view class="main"> | |||
| <view class="card"> | |||
| <view class="card-header"> | |||
| <view class="flex tips"> | |||
| <image class="icon" src="@/pages_order/static/test/icon-warning.png" mode="widthFix"></image> | |||
| <view>请根据真实情况谨慎作答,点击下一题提交答案无法更改</view> | |||
| </view> | |||
| <view class="question">{{ currentQuestion.question }}</view> | |||
| </view> | |||
| <view class="card-content"> | |||
| <view class="select"> | |||
| <view | |||
| v-for="item in currentQuestion.options" | |||
| :key="item.id" | |||
| :class="['select-option', item.id === value ? 'is-active' : '']" | |||
| @click="onSelect(item.id)" | |||
| > | |||
| {{ item.content }} | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="bottom"> | |||
| <button v-if="isLast" class="btn" @click="finish">提交</button> | |||
| <button v-else class="btn" @click="next">下一题</button> | |||
| </view> | |||
| </template> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| current: null, | |||
| tabs: [], | |||
| value: null, | |||
| answers: [], | |||
| batchNo: null, | |||
| questionsList: [], | |||
| total: 0, | |||
| } | |||
| }, | |||
| computed: { | |||
| preIdx() { | |||
| let index = this.tabs.findIndex(index => index === this.current) | |||
| return index - 1 | |||
| }, | |||
| progress() { | |||
| return 100 * (this.current + 1) / this.total | |||
| }, | |||
| isLast() { | |||
| return this.progress === 100 | |||
| }, | |||
| currentQuestion() { | |||
| return this.questionsList[this.current] | |||
| }, | |||
| }, | |||
| onLoad(arg) { | |||
| const { ids, examId, current } = arg | |||
| this.current = parseInt(current || 0) | |||
| this.fetchQuestionList(ids, examId) | |||
| this.value = this.answers[this.current] | |||
| console.log('currentQuestion', this.currentQuestion) | |||
| }, | |||
| methods: { | |||
| async fetchQuestionList(categories, examId) { | |||
| let result | |||
| if (examId) { | |||
| result = await this.$fetch('queryExamById', { examId }) | |||
| } else { | |||
| result = await this.$fetch('queryQuestionList', { categories }) | |||
| } | |||
| const { batchNo, pageList } = result | |||
| this.batchNo = batchNo | |||
| this.questionsList = pageList.map((item, index) => { | |||
| const { id, question, answerList } = item | |||
| return { | |||
| id, | |||
| // question: `${index + 1}、${question}`, | |||
| question, | |||
| options: answerList.map((option, oIdx) => { | |||
| return { | |||
| id: option.id, | |||
| // content: `${String.fromCharCode(oIdx+65)}、${option.answer}` | |||
| content: `${option.answerNo}、${option.answer}` | |||
| } | |||
| }), | |||
| } | |||
| }) | |||
| this.total = this.questionsList.length | |||
| this.answers = this.questionsList.map(() => null) | |||
| console.log('questionsList', this.questionsList) | |||
| console.log('answers', this.answers) | |||
| }, | |||
| async fetchAnswer() { | |||
| try { | |||
| const { id: questionId } = this.currentQuestion | |||
| console.log('currentQuestion', this.currentQuestion) | |||
| console.log('value', this.value) | |||
| if (!this.value) { | |||
| console.log('未答题') | |||
| uni.showToast({ | |||
| title: '请答题', | |||
| icon:'none' | |||
| }) | |||
| return false | |||
| } | |||
| let params = { | |||
| batchNo: this.batchNo, | |||
| questionId, | |||
| answerId: this.value, | |||
| } | |||
| await this.$fetch('updateAnswer', params) | |||
| this.answers[this.current] = this.value | |||
| return true | |||
| } catch (err) { | |||
| console.log('fetchAnswer', err) | |||
| return false | |||
| } | |||
| }, | |||
| async fetchFinish() { | |||
| // todo: delete | |||
| // todo | |||
| // await this.$fetch('submitPaper', { id: this.paperInfo.reportId }) | |||
| this.current = this.total | |||
| console.log('fetchFinish', this.current, this.currentQuestion) | |||
| // todo | |||
| // uni.reLaunch({ | |||
| // url: '/pages/index/report' | |||
| // }) | |||
| }, | |||
| async next() { | |||
| let succ = await this.fetchAnswer() | |||
| if (!succ) { | |||
| return | |||
| } | |||
| this.current += 1 | |||
| this.value = this.answers[this.current] | |||
| }, | |||
| async finish() { | |||
| let succ = await this.fetchAnswer() | |||
| if (!succ) { | |||
| return | |||
| } | |||
| this.fetchFinish() | |||
| }, | |||
| async onSelect(id) { | |||
| this.value = id | |||
| }, | |||
| async onSelectMulitple(id) { | |||
| this.value = this.value.includes(id) ? this.value.filter(item => item !== id) : this.value.concat(id) | |||
| }, | |||
| onCreateReport() { | |||
| uni.redirectTo({ | |||
| url: `/pages_order/report/pay?batchNo=${this.batchNo}` | |||
| }) | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| width: 100vw; | |||
| min-height: 100vh; | |||
| background: linear-gradient(164deg, #014FA2, #014FA2, #2E8AED); | |||
| position: relative; | |||
| } | |||
| .bar { | |||
| margin-top: 42rpx; | |||
| width: 100%; | |||
| padding: 0 47rpx; | |||
| box-sizing: border-box; | |||
| .info { | |||
| justify-content: flex-start; | |||
| column-gap: 13rpx; | |||
| font-size: 28rpx; | |||
| color: #A1D6FF; | |||
| .highlight { | |||
| color: #FFFFFF; | |||
| margin-right: 8rpx; | |||
| } | |||
| } | |||
| .progress { | |||
| margin-top: 20rpx; | |||
| width: 100%; | |||
| height: 16rpx; | |||
| background: rgba($color: #FFFFFF, $alpha: 0.35); | |||
| border-radius: 8rpx; | |||
| &-bar { | |||
| height: 100%; | |||
| background: #FFFFFF; | |||
| border-radius: 8rpx; | |||
| } | |||
| } | |||
| } | |||
| .main { | |||
| width: 100%; | |||
| padding: 73rpx 33rpx; | |||
| box-sizing: border-box; | |||
| } | |||
| .card { | |||
| position: relative; | |||
| width: 100%; | |||
| min-height: 876rpx; | |||
| padding: 27rpx 0; | |||
| box-sizing: border-box; | |||
| background: #FFFFFF; | |||
| border-radius: 16rpx; | |||
| &:after { | |||
| content: ' '; | |||
| position: absolute; | |||
| bottom: 0; | |||
| left: 50%; | |||
| transform: translate(-50%, 100%); | |||
| width: calc(100% - 20rpx * 2); | |||
| height: 28rpx; | |||
| background: rgba($color: #E9EFF2, $alpha: 0.29); | |||
| border-bottom-left-radius: 16rpx; | |||
| border-bottom-right-radius: 16rpx; | |||
| } | |||
| &-header { | |||
| padding: 0 33rpx; | |||
| .tips { | |||
| column-gap: 3rpx; | |||
| padding: 12rpx 5rpx; | |||
| font-size: 22rpx; | |||
| color: #DB5742; | |||
| border: 3rpx solid #DB5742; | |||
| border-radius: 7rpx; | |||
| margin-bottom: 26rpx; | |||
| .icon { | |||
| width: 31rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| &-content { | |||
| padding: 0 24rpx; | |||
| } | |||
| } | |||
| .question { | |||
| font-family: PingFang SC; | |||
| font-weight: 400; | |||
| font-size: 28rpx; | |||
| line-height: 50rpx; | |||
| color: #000000; | |||
| margin-bottom: 64rpx; | |||
| } | |||
| .select { | |||
| &-option { | |||
| margin-top: 44rpx; | |||
| padding: 22rpx 28rpx; | |||
| line-height: 1.3; | |||
| font-size: 28rpx; | |||
| color: #707070; | |||
| background: #F3F3F3; | |||
| border-radius: 28rpx; | |||
| &.is-active { | |||
| color: #014FA2; | |||
| background: rgba($color: #014FA2, $alpha: 0.22); | |||
| } | |||
| } | |||
| } | |||
| .bottom { | |||
| position: fixed; | |||
| left: 0; | |||
| bottom: 0; | |||
| width: 100%; | |||
| padding: 17rpx 72rpx; | |||
| padding-bottom: calc(env(safe-area-inset-bottom) + 17rpx); | |||
| background: #FFFFFF; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| width: 100%; | |||
| padding: 26rpx 0; | |||
| font-size: 30rpx; | |||
| line-height: 1.4; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 42rpx; | |||
| } | |||
| } | |||
| .desc { | |||
| margin-top: 220rpx; | |||
| font-family: PingFang SC; | |||
| font-weight: 400; | |||
| line-height: 1.4; | |||
| font-size: 26rpx; | |||
| color: #989898; | |||
| } | |||
| .main.is-finish { | |||
| height: calc(100vh - (var(--status-bar-height) + 120rpx)); | |||
| padding: 0 33rpx; | |||
| padding-bottom: calc(var(--status-bar-height) + 120rpx); | |||
| .card { | |||
| min-height: 745rpx; | |||
| padding: 0; | |||
| background: transparent; | |||
| &-bg { | |||
| width: 100%; | |||
| height: auto; | |||
| } | |||
| &-content { | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| justify-content: flex-end; | |||
| width: 100%; | |||
| height: 100%; | |||
| padding: 69rpx 94rpx; | |||
| box-sizing: border-box; | |||
| .text { | |||
| font-size: 32rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| } | |||
| .text + .text { | |||
| margin-top: 45rpx; | |||
| } | |||
| .btn { | |||
| margin-top: 139rpx; | |||
| padding: 29rpx 183rpx; | |||
| box-sizing: border-box; | |||
| line-height: 1.4; | |||
| white-space: nowrap; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 50rpx; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,51 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="我的答题" leftClick @leftClick="$utils.navigateBack" /> | |||
| <view class="list"> | |||
| <view class="list-item" v-for="item in list" :key="item.id"> | |||
| <testCard :data="item"></testCard> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import mixinsList from '@/mixins/list.js' | |||
| import testCard from './testCard.vue' | |||
| export default { | |||
| mixins: [mixinsList], | |||
| components: { | |||
| testCard, | |||
| }, | |||
| data() { | |||
| return { | |||
| list: [], | |||
| mixinsListApi: 'queryExamLogList', | |||
| } | |||
| }, | |||
| methods: { | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| background: #F5F5F5; | |||
| } | |||
| .list { | |||
| width: 100%; | |||
| padding: 29rpx; | |||
| box-sizing: border-box; | |||
| &-item { | |||
| & + & { | |||
| margin-top: 20rpx; | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,162 +0,0 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="答题测评" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" /> | |||
| <view class="main"> | |||
| <view class="card"> | |||
| <view class="flex flex-column card-header"> | |||
| <view>您好 !</view> | |||
| <view>请选择您要答题的题库(可多选)</view> | |||
| </view> | |||
| <view class="card-content list"> | |||
| <uv-checkbox-group | |||
| v-model="selectedArr" | |||
| shape="circle" | |||
| > | |||
| <view class="flex list-item" v-for="item in list" :key="item.id"> | |||
| <view class="flex left"> | |||
| <image class="icon" src="@/static/image/icon.png" mode="widthFix"></image> | |||
| <view>{{ item.title }}</view> | |||
| </view> | |||
| <view> | |||
| <uv-checkbox | |||
| size="40rpx" | |||
| icon-size="40rpx" | |||
| activeColor="#014FA2" | |||
| :name="item.id" | |||
| ></uv-checkbox> | |||
| </view> | |||
| </view> | |||
| </uv-checkbox-group> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="bottom"> | |||
| <button class="btn" @click="onStart">开始答题</button> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import mixinsList from '@/mixins/list.js' | |||
| export default { | |||
| mixins: [mixinsList], | |||
| data() { | |||
| return { | |||
| list: [], | |||
| selectedArr: [], | |||
| mixinsListApi: 'queryCategoryList', | |||
| } | |||
| }, | |||
| computed: { | |||
| }, | |||
| onLoad() { | |||
| }, | |||
| methods: { | |||
| onStart() { | |||
| if (!this.selectedArr.length) { | |||
| uni.showToast({ | |||
| title: '请选择您要答题的题库(可多选)', | |||
| icon:'none' | |||
| }) | |||
| return | |||
| } | |||
| let ids = this.selectedArr.join(';') | |||
| uni.redirectTo({ | |||
| url: `/pages_order/test/answer?ids=${ids}` | |||
| }) | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| width: 100vw; | |||
| min-height: 100vh; | |||
| background: linear-gradient(164deg, #014FA2, #014FA2, #2E8AED); | |||
| position: relative; | |||
| } | |||
| .main { | |||
| width: 100%; | |||
| padding: 54rpx 36rpx; | |||
| padding-bottom: calc(env(safe-area-inset-bottom) + 152rpx + 73rpx); | |||
| box-sizing: border-box; | |||
| } | |||
| .card { | |||
| padding: 34rpx 43rpx 34rpx 19rpx; | |||
| background: linear-gradient(rgba($color: #3381D4, $alpha: 0.50), rgba($color: #FCFDFE, $alpha: 0.90) 281rpx, rgba($color: #FCFDFE, $alpha: 0.90)); | |||
| border-radius: 25rpx; | |||
| // border: 3rpx solid #FFFFFF; | |||
| box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16); | |||
| &-header { | |||
| align-items: flex-start; | |||
| row-gap: 10rpx; | |||
| padding: 0 0 27rpx 5rpx; | |||
| font-size: 30rpx; | |||
| line-height: 1.4; | |||
| color: #FFFFFF; | |||
| } | |||
| &-content { | |||
| // padding: 0 16rpx; | |||
| } | |||
| } | |||
| .list { | |||
| &-item { | |||
| width: 100%; | |||
| justify-content: space-between; | |||
| padding: 30rpx 42rpx 30rpx 24rpx; | |||
| box-sizing: border-box; | |||
| font-size: 30rpx; | |||
| color: #000000; | |||
| background: rgba($color: #62BBFF, $alpha: 0.06); | |||
| border-radius: 16rpx; | |||
| & + & { | |||
| margin-top: 17rpx; | |||
| } | |||
| .left { | |||
| column-gap: 18rpx; | |||
| } | |||
| .icon { | |||
| width: 48rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| .bottom { | |||
| position: fixed; | |||
| left: 0; | |||
| bottom: 0; | |||
| width: 100%; | |||
| padding: 17rpx 72rpx; | |||
| padding-bottom: calc(env(safe-area-inset-bottom) + 17rpx); | |||
| background: #FFFFFF; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| width: 100%; | |||
| padding: 26rpx 0; | |||
| font-size: 30rpx; | |||
| line-height: 1.4; | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| border-radius: 42rpx; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,124 +0,0 @@ | |||
| <template> | |||
| <view class="card"> | |||
| <view class="flex card-header"> | |||
| <!-- todo: 缺切图 --> | |||
| <image class="icon" src="@/static/image/icon.png" mode="widthFix"></image> | |||
| <view>{{ unfinishCount ? `您还有${unfinishCount}道题未完成` : '您已完成测评,还未获取报告' }}</view> | |||
| </view> | |||
| <view class="card-content"> | |||
| <view class="row"> | |||
| <view class="row-label">答题时间</view> | |||
| <view class="row-content">{{ $dayjs(data.createTime).format('YYYY-MM-DD HH:mm') }}</view> | |||
| </view> | |||
| </view> | |||
| <view class="flex card-footer"> | |||
| <button class="btn" @click="onRestart">重新测评</button> | |||
| <button v-if="unfinishCount" class="btn btn-primary" @click="onContinue">继续答题</button> | |||
| <button v-else class="btn btn-primary" @click="onCreateReport">获取报告</button> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| props: { | |||
| data: { | |||
| type: Object, | |||
| default() { | |||
| return {} | |||
| } | |||
| } | |||
| }, | |||
| computed: { | |||
| unfinishCount() { | |||
| const { allNum, finishNum } = this.data | |||
| return allNum - finishNum | |||
| }, | |||
| }, | |||
| methods: { | |||
| onRestart() { | |||
| // todo: fetch by this.data.paperId | |||
| // let id | |||
| // uni.navigateTo({ | |||
| // url: `/pages_order/test/answer?id=${id}` | |||
| // }) | |||
| uni.navigateTo({ | |||
| url: `/pages_order/test/start` | |||
| }) | |||
| }, | |||
| onContinue() { | |||
| uni.navigateTo({ | |||
| url: `/pages_order/test/answer?examId=${this.data.id}`, | |||
| }) | |||
| }, | |||
| onCreateReport() { | |||
| // todo: check | |||
| uni.navigateTo({ | |||
| url: `/pages_order/report/pay?batchNo=${this.data.batchNo}` | |||
| }) | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .card { | |||
| position: relative; | |||
| padding: 17rpx 0 22rpx 0; | |||
| color: #000000; | |||
| background: #FFFFFF; | |||
| border-radius: 15rpx; | |||
| overflow: hidden; | |||
| &-header { | |||
| justify-content: flex-start; | |||
| column-gap: 24rpx; | |||
| padding: 0 26rpx; | |||
| font-size: 30rpx; | |||
| .icon { | |||
| width: 48rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| &-content { | |||
| padding-left: 94rpx; | |||
| } | |||
| &-footer { | |||
| padding: 22rpx 35rpx 0 35rpx; | |||
| column-gap: 25rpx; | |||
| } | |||
| } | |||
| .row { | |||
| margin-top: 12rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: flex-start; | |||
| column-gap: 26rpx; | |||
| font-size: 28rpx; | |||
| color: #999999; | |||
| } | |||
| .btn { | |||
| flex: 1; | |||
| padding: 17rpx 0; | |||
| box-sizing: border-box; | |||
| font-family: PingFang SC; | |||
| font-size: 22rpx; | |||
| line-height: 1.4; | |||
| color: #014FA2; | |||
| border: 3rpx solid #014FA2; | |||
| border-radius: 35rpx; | |||
| &-primary { | |||
| color: #FFFFFF; | |||
| background: #014FA2; | |||
| } | |||
| } | |||
| </style> | |||