| @ -0,0 +1,455 @@ | |||
| <template> | |||
| <uv-popup | |||
| ref="popup" | |||
| :overlayOpacity="0.6" | |||
| mode="center" | |||
| bgColor="none" | |||
| :zIndex="1000000" | |||
| @change="onPopupChange" | |||
| > | |||
| <view class="popup__view"> | |||
| <view class="canvas" style="width: 566rpx; height: 1060rpx; overflow: hidden;"> | |||
| <canvas id="myCanvas" canvas-id="firstCanvas1" type="2d" style="width: 100%; height: 100%;"></canvas> | |||
| </view> | |||
| <button class="btn" @click="saveImg"> | |||
| <view class="content">保存到相册</view> | |||
| </button> | |||
| </view> | |||
| </uv-popup> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| wxCodeImage: '', | |||
| baseUrl: 'https://image.hhlm1688.com/', | |||
| canvas: {}, | |||
| retry: 10, | |||
| } | |||
| }, | |||
| async onLoad() { | |||
| }, | |||
| methods: { | |||
| open() { | |||
| this.retry = 10 | |||
| this.$refs.popup.open(); | |||
| }, | |||
| close() { | |||
| this.$refs.popup.close(); | |||
| }, | |||
| async fetchQrCode(path) { | |||
| // todo: delete | |||
| this.wxCodeImage = 'https://uploadfile.bizhizu.cn/up/e3/64/e0/e364e0f7f6af11f11abdafc22d17b15c.jpg' | |||
| return | |||
| try { | |||
| this.wxCodeImage = (await this.$fetch('getInviteCode', { path }))?.url | |||
| } catch (err) { | |||
| } | |||
| }, | |||
| // 生成有圆角的矩形 | |||
| drawBg(ctx, x, y, width, height, radius) { | |||
| ctx.beginPath(); | |||
| ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2); | |||
| ctx.lineTo(width - radius + x, y); | |||
| ctx.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2); | |||
| ctx.lineTo(width + x, height + y - radius); | |||
| ctx.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2); | |||
| ctx.lineTo(radius + x, height + y); | |||
| ctx.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI); | |||
| ctx.closePath(); | |||
| ctx.fillStyle = '#fff' | |||
| ctx.fill() | |||
| }, | |||
| drawCoverImg(canvas, ctx, x, y, width, height, radius, lineWidth) { | |||
| return new Promise(resolve => { | |||
| // 海报图片 | |||
| const paperImage = canvas.createImage() | |||
| console.log('paperImage', paperImage) | |||
| // todo: fetch | |||
| paperImage.src = 'https://i1.hdslb.com/bfs/archive/c0101b4ce06e6bdda803728408e79c8f8b8d0725.jpg' | |||
| paperImage.onload = () => { | |||
| console.log('paperImage onload') | |||
| ctx.beginPath(); | |||
| ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2); | |||
| ctx.lineTo(width - radius + x, y); | |||
| ctx.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2); | |||
| ctx.lineTo(width + x, height + y); | |||
| ctx.lineTo(x, height + y); | |||
| ctx.closePath(); | |||
| ctx.lineWidth = lineWidth; | |||
| ctx.strokeStyle = '#F8F8F8'; | |||
| ctx.stroke(); | |||
| ctx.clip(); | |||
| ctx.drawImage(paperImage, x, y, width, height) | |||
| resolve() | |||
| } | |||
| }) | |||
| }, | |||
| drawContentBg(ctx, x, y, width, height, radius) { | |||
| ctx.beginPath(); | |||
| // ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2); | |||
| ctx.moveTo(x, y); | |||
| ctx.lineTo(width + x, y); | |||
| ctx.lineTo(width + x, height + y - radius); | |||
| ctx.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2); | |||
| ctx.lineTo(radius + x, height + y); | |||
| ctx.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI); | |||
| ctx.closePath(); | |||
| let gradient = ctx.createLinearGradient(x, y, x, y + height); | |||
| gradient.addColorStop('0', '#DAF3FF'); | |||
| gradient.addColorStop('0.2', '#FBFEFF'); | |||
| gradient.addColorStop('1.0', '#FBFEFF'); | |||
| ctx.fillStyle = gradient | |||
| ctx.fill() | |||
| }, | |||
| drawAvatar(canvas, ctx, x, y, r) { | |||
| console.log('drawAvatar', 'x', x, 'y', y, 'r', r) | |||
| return new Promise(resolve => { | |||
| // 头像图片 | |||
| const avatarImage = canvas.createImage() | |||
| // todo: fetch | |||
| avatarImage.src = 'https://i1.hdslb.com/bfs/archive/c0101b4ce06e6bdda803728408e79c8f8b8d0725.jpg' | |||
| avatarImage.onload = () => { | |||
| console.log('avatarImage onload') | |||
| ctx.beginPath(); | |||
| console.log('arc', 'x', x + r, 'y', y + r, 'r', r) | |||
| ctx.arc(x + r, y + r, r, 0, 2 * Math.PI); | |||
| ctx.clip(); | |||
| const size = r*2 | |||
| console.log('size', size) | |||
| ctx.drawImage(avatarImage, x, y, size, size) | |||
| resolve() | |||
| } | |||
| }) | |||
| }, | |||
| drawMultilineText(ctx, text, x, y, maxWidth, lineHeight) { | |||
| console.log('drawMultilineText', 'x', x, 'y', y) | |||
| let line = ''; | |||
| for (let n = 0; n < text.length; n++) { | |||
| const testLine = line + text[n]; | |||
| const metrics = ctx.measureText(testLine); | |||
| const testWidth = metrics.width; | |||
| if (testWidth > maxWidth && n > 0) { | |||
| ctx.fillText(line, x, y); | |||
| console.log(n, 'line', line, 'x', x, 'y', y) | |||
| line = text[n]; | |||
| y += lineHeight; | |||
| } else { | |||
| line = testLine; | |||
| } | |||
| } | |||
| console.log('line', line, 'x', x, 'y', y) | |||
| ctx.fillText(line, x, y); | |||
| }, | |||
| drawQrCodeImg(canvas, ctx, x, y, size) { | |||
| return new Promise(resolve => { | |||
| //二维码图片 | |||
| const coderImage = canvas.createImage() | |||
| coderImage.src = this.wxCodeImage | |||
| coderImage.onload = () => { | |||
| console.log('coderImage onload') | |||
| ctx.drawImage(coderImage, x, y, size, size) | |||
| resolve() | |||
| } | |||
| }) | |||
| }, | |||
| draw() { | |||
| wx.createSelectorQuery().in(this) | |||
| .select('#myCanvas') // 绘制的canvas的id | |||
| .fields({ | |||
| node: true, | |||
| size: true | |||
| }) | |||
| .exec(async (res) => { | |||
| console.log('res', res) | |||
| if (!res?.[0]?.node) { | |||
| if (!this.retry) { | |||
| console.log('retry fail') | |||
| return | |||
| } | |||
| console.log('retry') | |||
| this.retry -= 1 | |||
| setTimeout(() => { | |||
| this.draw() | |||
| }, 200) | |||
| return | |||
| } | |||
| const canvas = res[0].node | |||
| // 渲染上下文 | |||
| const ctx = canvas.getContext('2d') | |||
| // Canvas 画布的实际绘制宽高 | |||
| const width = res[0].width | |||
| const height = res[0].height | |||
| // 初始化画布大小 | |||
| const dpr = wx.getWindowInfo().pixelRatio | |||
| //根据dpr调整 | |||
| // dpr 2 4 | |||
| // 3 6 | |||
| console.log("--dpr", dpr) | |||
| canvas.width = width * dpr | |||
| canvas.height = height * dpr | |||
| let Ratio = canvas.width / 566 | |||
| this.canvas = canvas | |||
| ctx.scale(dpr, dpr) | |||
| ctx.clearRect(0, 0, width, height) | |||
| ctx.fillStyle = 'transparent' | |||
| ctx.fillRect(0, 0, canvas.width, canvas.height) | |||
| ctx.save() | |||
| let radius = 48 * Ratio / dpr | |||
| let w = 566 * Ratio / dpr | |||
| let h = 1060 * Ratio / dpr | |||
| this.drawBg(ctx, 0, 0, w, h, radius) | |||
| ctx.restore(); | |||
| ctx.save() | |||
| let lineWidth = 2 * Ratio / dpr | |||
| let x = lineWidth | |||
| let y = lineWidth | |||
| w = 566 * Ratio / dpr - lineWidth * 2 | |||
| h = 400 * Ratio / dpr - lineWidth * 2 | |||
| await this.drawCoverImg(canvas, ctx, x, y, w, h, radius, lineWidth) | |||
| ctx.restore(); | |||
| ctx.save() | |||
| x = lineWidth | |||
| y = 400 * Ratio / dpr + lineWidth | |||
| h = 660 * Ratio / dpr - lineWidth * 2 | |||
| this.drawContentBg(ctx, x, y, w, h, radius, lineWidth) | |||
| ctx.restore(); | |||
| ctx.save() | |||
| radius = Math.floor(27 * Ratio / dpr) | |||
| x = Math.floor(40 * Ratio / dpr) | |||
| y = Math.floor(440 * Ratio / dpr) | |||
| await this.drawAvatar(canvas, ctx, x, y, radius) | |||
| ctx.restore(); | |||
| ctx.save() | |||
| let text = '战斗世界' | |||
| let maxWidth = 220 * Ratio / dpr | |||
| let lineHeight = 17 * Ratio / dpr | |||
| x = 100 * Ratio / dpr | |||
| y = 474 * Ratio / dpr | |||
| ctx.font = "normal normal normal 11px normal"; | |||
| ctx.fillStyle = "#7D7D7D"; | |||
| this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight) | |||
| ctx.restore(); | |||
| ctx.save() | |||
| maxWidth = 540 * Ratio / dpr | |||
| lineHeight = 60 * Ratio / dpr | |||
| ctx.font = "normal normal 600 17px normal"; | |||
| ctx.fillStyle = "#181818"; | |||
| text = '邀请您' | |||
| x = 40 * Ratio / dpr | |||
| y = 564 * Ratio / dpr | |||
| this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight) | |||
| y += lineHeight | |||
| text = '探索新世界,开启研学之旅!' | |||
| this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight) | |||
| ctx.restore(); | |||
| ctx.save() | |||
| text = '是否渴望一场充满知识与乐趣的冒险?现在,我们诚挚邀请你加入我们的研学小程序,开启一场别开生面的学习之旅!' | |||
| maxWidth = 486 * Ratio / dpr | |||
| lineHeight = 30 * Ratio / dpr | |||
| ctx.font = "normal normal normal 10px normal"; | |||
| ctx.fillStyle = "#7D7D7D"; | |||
| x = 40 * Ratio / dpr | |||
| y = 690 * Ratio / dpr | |||
| this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight) | |||
| ctx.restore(); | |||
| ctx.save() | |||
| // 设置虚线样式 | |||
| ctx.setLineDash([4, 4]); // 第一个参数是实线长度, 第二个参数是间隔长度 | |||
| ctx.lineDashOffset = 2; // 设置虚线的起始偏移量 | |||
| ctx.lineWidth = lineWidth; | |||
| ctx.strokeStyle = '#DADADA'; | |||
| // 开始绘制 | |||
| ctx.beginPath(); | |||
| x = 40 * Ratio / dpr | |||
| y = 778 * Ratio / dpr | |||
| ctx.moveTo(x, y); | |||
| x += 486 * Ratio / dpr | |||
| ctx.lineTo(x, y); | |||
| ctx.stroke(); | |||
| ctx.restore(); | |||
| ctx.save() | |||
| maxWidth = 250 * Ratio / dpr | |||
| lineHeight = 44 * Ratio / dpr | |||
| ctx.font = "normal normal 600 13px normal"; | |||
| ctx.fillStyle = "#181818"; | |||
| text = '立即加入我们,' | |||
| x = 40 * Ratio / dpr | |||
| y = 879 * Ratio / dpr | |||
| this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight) | |||
| text = '开启你的研学之旅!' | |||
| y += lineHeight | |||
| this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight) | |||
| ctx.restore(); | |||
| ctx.save() | |||
| x = 316 * Ratio / dpr | |||
| y = 810 * Ratio / dpr | |||
| let size = 210 * Ratio / dpr | |||
| await this.drawQrCodeImg(canvas, ctx, x, y, size) | |||
| uni.hideLoading() | |||
| return | |||
| // 海报图片 | |||
| const paperImage = canvas.createImage() | |||
| console.log('paperImage', paperImage) | |||
| // todo: fetch | |||
| paperImage.src = 'https://i1.hdslb.com/bfs/archive/c0101b4ce06e6bdda803728408e79c8f8b8d0725.jpg' | |||
| paperImage.onload = () => { | |||
| console.log('paperImage onload') | |||
| const w = 566 * Ratio / dpr | |||
| const h = 400 * Ratio / dpr | |||
| ctx.drawImage(paperImage, 0, 0, w, h) | |||
| //二维码图片 | |||
| const coderImage = canvas.createImage() | |||
| coderImage.src = this.wxCodeImage | |||
| coderImage.onload = () => { | |||
| console.log('coderImage onload') | |||
| const x = 316 * Ratio / dpr | |||
| const y = 910 * Ratio / dpr | |||
| const size = 210 * Ratio / dpr | |||
| ctx.drawImage(coderImage, x, y, size, size) | |||
| uni.hideLoading() | |||
| } | |||
| } | |||
| }) | |||
| }, | |||
| async init() { | |||
| uni.showLoading({ | |||
| title: '加载中...' | |||
| }); | |||
| await this.fetchQrCode() | |||
| uni.hideLoading(); | |||
| uni.showLoading({ | |||
| title: "拼命绘画中..." | |||
| }) | |||
| this.draw() | |||
| }, | |||
| saveImg() { | |||
| this.$authorize('scope.writePhotosAlbum').then((res) => { | |||
| this.imgApi() | |||
| }) | |||
| }, | |||
| imgApi() { | |||
| uni.showLoading({ | |||
| title: '保存中...' | |||
| }); | |||
| wx.canvasToTempFilePath({ | |||
| x: 0, | |||
| y: 0, | |||
| width: this.canvas.width, | |||
| height: this.canvas.height, | |||
| canvas: this.canvas, | |||
| success: (res) => { | |||
| let tempFilePath = res.tempFilePath; | |||
| this.saveImgToPhone(tempFilePath) | |||
| }, | |||
| fail: (err) => { | |||
| console.log('--canvasToTempFilePath--fail', err) | |||
| uni.hideLoading(); | |||
| } | |||
| }, this); | |||
| }, | |||
| saveImgToPhone(image) { | |||
| /* 获取图片的信息 */ | |||
| uni.getImageInfo({ | |||
| src: image, | |||
| success: function(image) { | |||
| /* 保存图片到手机相册 */ | |||
| uni.saveImageToPhotosAlbum({ | |||
| filePath: image.path, | |||
| success: function() { | |||
| uni.showModal({ | |||
| title: '保存成功', | |||
| content: '图片已成功保存到相册', | |||
| showCancel: false | |||
| }); | |||
| }, | |||
| complete(res) { | |||
| console.log(res); | |||
| uni.hideLoading(); | |||
| } | |||
| }); | |||
| } | |||
| }); | |||
| }, | |||
| onPopupChange(e) { | |||
| if (!e.show) { | |||
| return | |||
| } | |||
| this.init() | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .canvas { | |||
| border-radius: 48rpx; | |||
| } | |||
| .btn { | |||
| margin-top: 32rpx; | |||
| width: 100%; | |||
| padding: 22rpx 0; | |||
| box-sizing: border-box; | |||
| font-family: PingFang SC; | |||
| font-weight: 500; | |||
| font-size: 36rpx; | |||
| line-height: 1; | |||
| color: #FFFFFF; | |||
| background: linear-gradient(to right, #21FEEC, #019AF9); | |||
| border: 2rpx solid #00A9FF; | |||
| border-radius: 41rpx; | |||
| } | |||
| </style> | |||
| @ -1,21 +1,453 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar> | |||
| <image class="icon-nav" src="@/static/image/partner/icon-nav.png" mode="widthFix"></image> | |||
| </navbar> | |||
| <view class="main"> | |||
| <view class="advantage"> | |||
| <view class="flex advantage-content"> | |||
| <view class="flex advantage-item" v-for="(item, aIdx) in advantages" :key="aIdx"> | |||
| <image class="icon" src="@/static/image/icon-checkmark-circle-fill.png" mode="widthFix"></image> | |||
| <view>{{ item }}</view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="card"> | |||
| <view class="flex user"> | |||
| <view class="avatar"> | |||
| <image class="img" src="@/static/image/temp-30.png" mode="scaleToFill"></image> | |||
| <view :class="['tag', `tag-1`]">家长</view> | |||
| </view> | |||
| <view class="flex summary"> | |||
| <view class="flex flex-column summary-item name"> | |||
| <view class="summary-item-content">战斗世界</view> | |||
| <view class="summary-item-label">ID:5625354</view> | |||
| </view> | |||
| <template v-if="isPartner"> | |||
| <view class="flex flex-column summary-item" @click="jumpToAchievement"> | |||
| <view class="summary-item-content">888</view> | |||
| <view class="summary-item-label">推广人数</view> | |||
| </view> | |||
| <view class="flex flex-column summary-item"> | |||
| <view class="summary-item-content">341</view> | |||
| <view class="summary-item-label">总佣金</view> | |||
| </view> | |||
| </template> | |||
| <template v-else> | |||
| <view class="flex summary-item operate"> | |||
| <button class="btn" @click="onApplyPartner">成为合伙人</button> | |||
| </view> | |||
| </template> | |||
| </view> | |||
| </view> | |||
| <view class="flex bar" v-if="isPartner"> | |||
| <button class="flex col btn" @click="jumpToTeam"> | |||
| <image class="icon" src="@/static/image/partner/icon-team.png" mode="widthFix"></image> | |||
| <view>我的团队</view> | |||
| </button> | |||
| <view class="flex divider"> | |||
| <view class="line"></view> | |||
| </view> | |||
| <button class="flex col btn" @click="openPosterPopup"> | |||
| <image class="icon" src="@/static/image/partner/icon-qrcode.png" mode="widthFix"></image> | |||
| <view>邀请二维码</view> | |||
| </button> | |||
| <view class="flex divider"> | |||
| <view class="line"></view> | |||
| </view> | |||
| <button class="flex col btn" @click="jumpToWithdraw"> | |||
| <image class="icon" src="@/static/image/partner/icon-cash.png" mode="widthFix"></image> | |||
| <view>提现</view> | |||
| </button> | |||
| </view> | |||
| <!-- todo: check --> | |||
| <button class="btn-apply" @click="onApplyPartner"> | |||
| <image class="bg" src="@/static/image/partner/apply.png" mode="widthFix"></image> | |||
| </button> | |||
| <view class="list" v-if="isPartner && list.length"> | |||
| <view class="flex list-item" v-for="item in list" :key="item.id"> | |||
| <view class="flex col info"> | |||
| <view class="avatar"> | |||
| <image class="img" :src="item.avatar" mode="scaleToFill"></image> | |||
| </view> | |||
| <view>{{ item.name }}</view> | |||
| </view> | |||
| <view class="col price">{{ `+¥${item.price}` }}</view> | |||
| <view class="col desc">{{ item.createTime }}</view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <posterPopup ref="posterPopup"></posterPopup> | |||
| <tabber select="partner" /> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import mixinsList from '@/mixins/list.js' | |||
| import tabber from '@/components/base/tabbar.vue' | |||
| import posterPopup from '@/components/partner/posterPopup.vue' | |||
| export default { | |||
| mixins: [mixinsList], | |||
| components: { | |||
| tabber, | |||
| posterPopup, | |||
| }, | |||
| data() { | |||
| return { | |||
| advantages: ['收益高', '品类全', '到账快', '城市多'], | |||
| // todo: fetch | |||
| isPartner: true, | |||
| // todo | |||
| mixinsListApi: '', | |||
| } | |||
| }, | |||
| onShow() { | |||
| // todo: refresh is partner? | |||
| }, | |||
| methods: { | |||
| // todo: delete | |||
| getData() { | |||
| this.list = [ | |||
| { | |||
| id: '001', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李世海', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '002', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '周静', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '003', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '周海', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '004', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '冯启彬', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '005', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李娉', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '006', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李书萍', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '007', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李世海', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '008', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '周静', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '009', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '周海', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '010', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '冯启彬', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '011', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李娉', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '012', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李书萍', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| ] | |||
| }, | |||
| onApplyPartner() { | |||
| this.$utils.navigateTo(`/pages_order/partner/apply`) | |||
| }, | |||
| jumpToTeam() { | |||
| this.$utils.navigateTo(`/pages_order/partner/team`) | |||
| }, | |||
| openPosterPopup() { | |||
| this.$refs.posterPopup.open() | |||
| }, | |||
| jumpToWithdraw() { | |||
| this.$utils.navigateTo(`/pages_order/partner/withdraw`) | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| @import '/components/member/styles/tag.scss'; | |||
| @import '../../components/member/styles/tag.scss'; | |||
| .page__view { | |||
| min-height: 100vh; | |||
| background: linear-gradient(to right, #21FEEC, #019AF9); | |||
| /deep/ .nav-bar__view { | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| } | |||
| .icon-nav { | |||
| width: 168rpx; | |||
| height: auto; | |||
| } | |||
| /deep/ .tabbar-box { | |||
| height: auto; | |||
| padding-bottom: 0; | |||
| } | |||
| } | |||
| .main { | |||
| // min-height: 100vh; | |||
| // padding: calc(var(--status-bar-height) + 130rpx) 0 calc(120rpx + env(safe-area-inset-bottom)) 0; | |||
| padding-top: calc(var(--status-bar-height) + 130rpx); | |||
| box-sizing: border-box; | |||
| } | |||
| .advantage { | |||
| padding: 0 40rpx 32rpx 40rpx; | |||
| &-content { | |||
| justify-content: space-between; | |||
| padding: 16rpx; | |||
| background: #1FB2FD99; | |||
| border: 2rpx solid #FFFFFF4D; | |||
| border-radius: 16rpx; | |||
| } | |||
| &-item { | |||
| column-gap: 8rpx; | |||
| padding-right: 16rpx; | |||
| font-size: 26rpx; | |||
| color: #FFFFFF; | |||
| .icon { | |||
| width: 40rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| .card { | |||
| width: 100%; | |||
| // height: 100%; | |||
| $advantage-height: 54px; | |||
| // min-height: calc(100vh - #{$advantage-height} - (var(--status-bar-height) + 130rpx) - (120rpx + env(safe-area-inset-bottom))); | |||
| min-height: calc(100vh - #{$advantage-height} - (var(--status-bar-height) + 130rpx)); | |||
| padding: 40rpx; | |||
| padding-bottom: calc(40rpx + 120rpx + env(safe-area-inset-bottom)); | |||
| box-sizing: border-box; | |||
| font-family: PingFang SC; | |||
| font-weight: 400; | |||
| line-height: 1.4; | |||
| background: linear-gradient(#DAF3FF, #FBFEFF 400rpx, #FBFEFF); | |||
| border: 2rpx solid #FFFFFF; | |||
| border-top-left-radius: 48rpx; | |||
| border-top-right-radius: 48rpx; | |||
| } | |||
| .user { | |||
| justify-content: space-between; | |||
| padding: 32rpx 40rpx; | |||
| background: linear-gradient(#DAF3FF, #FBFEFF 70%, #FBFEFF); | |||
| border: 2rpx solid #FFFFFF; | |||
| border-radius: 48rpx; | |||
| column-gap: 24rpx; | |||
| .avatar { | |||
| flex: none; | |||
| position: relative; | |||
| width: 128rpx; | |||
| height: 128rpx; | |||
| border-radius: 24rpx; | |||
| overflow: hidden; | |||
| .img { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| .summary { | |||
| flex: 1; | |||
| column-gap: 26rpx; | |||
| &-item { | |||
| flex: 1; | |||
| row-gap: 8rpx; | |||
| &.name { | |||
| flex: none; | |||
| align-items: flex-start; | |||
| } | |||
| &.operate { | |||
| justify-content: flex-end; | |||
| } | |||
| &-content { | |||
| font-size: 32rpx; | |||
| font-weight: 600; | |||
| color: #000000; | |||
| } | |||
| &-label { | |||
| font-size: 24rpx; | |||
| color: #939393; | |||
| } | |||
| } | |||
| } | |||
| .btn { | |||
| padding: 8rpx 24rpx; | |||
| font-size: 28rpx; | |||
| font-weight: 500; | |||
| line-height: 1.4; | |||
| color: #FFFFFF; | |||
| background: linear-gradient(to right, #21FEEC, #019AF9); | |||
| border-radius: 28rpx; | |||
| } | |||
| } | |||
| .btn-apply { | |||
| margin-top: 32rpx; | |||
| width: 100%; | |||
| height: auto; | |||
| padding: 0; | |||
| background: none; | |||
| font-size: 0; | |||
| .bg { | |||
| width: 100%; | |||
| height: auto; | |||
| } | |||
| } | |||
| .bar { | |||
| margin-top: 24rpx; | |||
| flex-wrap: nowrap; | |||
| padding: 16rpx 24rpx; | |||
| .col { | |||
| flex: none; | |||
| } | |||
| .divider { | |||
| flex: 1; | |||
| .line { | |||
| width: 2rpx; | |||
| height: 44rpx; | |||
| background: #00A9FF; | |||
| } | |||
| } | |||
| .btn { | |||
| column-gap: 8rpx; | |||
| font-size: 24rpx; | |||
| color: #181818; | |||
| .icon { | |||
| width: 64rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| .list { | |||
| margin-top: 32rpx; | |||
| background: #FFFFFF; | |||
| border: 2rpx solid #F0F0F0; | |||
| border-radius: 24rpx; | |||
| overflow: hidden; | |||
| &-item { | |||
| margin-top: 16rpx; | |||
| padding: 16rpx 32rpx; | |||
| font-size: 28rpx; | |||
| color: #333333; | |||
| background: #FFFFFF; | |||
| border-bottom: 2rpx solid #F1F1F1; | |||
| &:last-child { | |||
| border: none; | |||
| } | |||
| .col { | |||
| flex: 1; | |||
| text-align: center; | |||
| } | |||
| .info { | |||
| justify-content: flex-start; | |||
| column-gap: 24rpx; | |||
| .avatar { | |||
| width: 72rpx; | |||
| height: 72rpx; | |||
| border-radius: 50%; | |||
| overflow: hidden; | |||
| .img { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| } | |||
| .desc { | |||
| font-size: 26rpx; | |||
| color: #A3A3A3; | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,252 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar leftClick @leftClick="$utils.navigateBack"> | |||
| <image class="icon-nav" src="@/static/image/partner/icon-nav.png" mode="widthFix"></image> | |||
| </navbar> | |||
| <view class="main"> | |||
| <view class="advantage"> | |||
| <view class="flex advantage-content"> | |||
| <view class="flex advantage-item" v-for="(item, aIdx) in advantages" :key="aIdx"> | |||
| <image class="icon" src="@/static/image/icon-checkmark-circle-fill.png" mode="widthFix"></image> | |||
| <view>{{ item }}</view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="card"> | |||
| <view class="card-header">申请合伙人</view> | |||
| <view class="form"> | |||
| <uv-form | |||
| ref="form" | |||
| :model="form" | |||
| :rules="rules" | |||
| errorType="toast" | |||
| > | |||
| <view class="form-item"> | |||
| <uv-form-item prop="name" :customStyle="formItemStyle"> | |||
| <view class="form-item-label"> | |||
| <image class="icon" src="@/static/image/icon-require.png" mode="widthFix"></image> | |||
| 姓名 | |||
| </view> | |||
| <view class="form-item-content"> | |||
| <formInput v-model="form.name"></formInput> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item"> | |||
| <uv-form-item prop="phone" :customStyle="formItemStyle"> | |||
| <view class="form-item-label"> | |||
| <image class="icon" src="@/static/image/icon-require.png" mode="widthFix"></image> | |||
| 电话 | |||
| </view> | |||
| <view class="form-item-content"> | |||
| <formInput v-model="form.phone"></formInput> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item"> | |||
| <uv-form-item prop="recommend" :customStyle="formItemStyle"> | |||
| <view class="form-item-label">推荐人</view> | |||
| <view class="form-item-content"> | |||
| <formInput v-model="form.recommend"></formInput> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| </uv-form> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="bottom"> | |||
| <view class="flex btn" @click="onSubmit">提交</view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import formInput from '@/pages_order/components/formInput.vue' | |||
| export default { | |||
| components: { | |||
| formInput, | |||
| }, | |||
| data() { | |||
| return { | |||
| advantages: ['收益高', '品类全', '到账快', '城市多'], | |||
| form: { | |||
| name: null, | |||
| phone: null, | |||
| recommend: null, | |||
| }, | |||
| rules: { | |||
| 'name': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请输入姓名', | |||
| }, | |||
| 'phone': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请输入电话', | |||
| }, | |||
| }, | |||
| formItemStyle: { padding: 0 }, | |||
| } | |||
| }, | |||
| methods: { | |||
| async onSubmit() { | |||
| try { | |||
| await this.$refs.form.validate() | |||
| const { | |||
| } = this.form | |||
| const params = { | |||
| } | |||
| // todo: fetch | |||
| // await this.$fetch('updateAddress', params) | |||
| uni.showToast({ | |||
| icon: 'success', | |||
| title: '提交成功', | |||
| }); | |||
| setTimeout(() => { | |||
| this.$utils.navigateBack() | |||
| }, 800) | |||
| } catch (err) { | |||
| console.log('onSave err', err) | |||
| } | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| min-height: 100vh; | |||
| background: linear-gradient(to right, #21FEEC, #019AF9); | |||
| /deep/ .nav-bar__view { | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| } | |||
| .icon-nav { | |||
| width: 168rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| .main { | |||
| // min-height: 100vh; | |||
| // padding: calc(var(--status-bar-height) + 130rpx) 0 calc(120rpx + env(safe-area-inset-bottom)) 0; | |||
| padding-top: calc(var(--status-bar-height) + 130rpx); | |||
| box-sizing: border-box; | |||
| } | |||
| .advantage { | |||
| padding: 0 40rpx 32rpx 40rpx; | |||
| &-content { | |||
| justify-content: space-between; | |||
| padding: 16rpx; | |||
| background: #1FB2FD99; | |||
| border: 2rpx solid #FFFFFF4D; | |||
| border-radius: 16rpx; | |||
| } | |||
| &-item { | |||
| column-gap: 8rpx; | |||
| padding-right: 16rpx; | |||
| font-size: 26rpx; | |||
| color: #FFFFFF; | |||
| .icon { | |||
| width: 40rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| } | |||
| .card { | |||
| width: 100%; | |||
| // height: 100%; | |||
| $advantage-height: 54px; | |||
| // min-height: calc(100vh - #{$advantage-height} - (var(--status-bar-height) + 130rpx) - (120rpx + env(safe-area-inset-bottom))); | |||
| min-height: calc(100vh - #{$advantage-height} - (var(--status-bar-height) + 130rpx)); | |||
| padding: 40rpx; | |||
| box-sizing: border-box; | |||
| font-family: PingFang SC; | |||
| font-weight: 400; | |||
| line-height: 1.4; | |||
| background: linear-gradient(#DAF3FF, #FBFEFF 400rpx, #FBFEFF); | |||
| border: 2rpx solid #FFFFFF; | |||
| border-top-left-radius: 48rpx; | |||
| border-top-right-radius: 48rpx; | |||
| &-header { | |||
| font-family: PingFang SC; | |||
| font-weight: 500; | |||
| font-size: 36rpx; | |||
| line-height: 1.4; | |||
| color: #191919; | |||
| } | |||
| } | |||
| .form { | |||
| &-item { | |||
| margin-top: 32rpx; | |||
| border-bottom: 2rpx solid #EEEEEE; | |||
| &-label { | |||
| font-family: PingFang SC; | |||
| font-weight: 400; | |||
| font-size: 26rpx; | |||
| line-height: 1.4; | |||
| color: #181818; | |||
| .icon { | |||
| margin-right: 8rpx; | |||
| width: 16rpx; | |||
| height: auto; | |||
| } | |||
| } | |||
| &-content { | |||
| } | |||
| } | |||
| } | |||
| .bottom { | |||
| position: fixed; | |||
| left: 0; | |||
| bottom: 0; | |||
| width: 100vw; | |||
| background: #FFFFFF; | |||
| box-sizing: border-box; | |||
| padding: 32rpx 40rpx; | |||
| padding-bottom: calc(env(safe-area-inset-bottom) + 32rpx); | |||
| box-sizing: border-box; | |||
| .btn { | |||
| width: 100%; | |||
| padding: 14rpx 0; | |||
| font-family: PingFang SC; | |||
| font-weight: 500; | |||
| font-size: 36rpx; | |||
| line-height: 1; | |||
| color: #FFFFFF; | |||
| background: linear-gradient(to right, #21FEEC, #019AF9); | |||
| border: 2rpx solid #00A9FF; | |||
| border-radius: 41rpx; | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,242 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="我的团队" leftClick @leftClick="$utils.navigateBack" color="#191919" bgColor="#FFFFFF" /> | |||
| <view class="main"> | |||
| <view class="tabs"> | |||
| <uv-tabs | |||
| :list="tabs" | |||
| :current="current" | |||
| :scrollable="false" | |||
| lineColor="#00A9FF" | |||
| lineWidth="48rpx" | |||
| lineHeight="4rpx" | |||
| :activeStyle="{ | |||
| 'font-family': 'PingFang SC', | |||
| 'font-weight': 500, | |||
| 'font-size': '32rpx', | |||
| 'line-height': 1.4, | |||
| 'color': '#00A9FF', | |||
| }" | |||
| :inactiveStyle="{ | |||
| 'font-family': 'PingFang SC', | |||
| 'font-weight': 400, | |||
| 'font-size': '32rpx', | |||
| 'line-height': 1.4, | |||
| 'color': '#181818', | |||
| }" | |||
| @click="clickTabs" | |||
| ></uv-tabs> | |||
| </view> | |||
| <view class="list"> | |||
| <view class="flex list-item" v-for="item in list" :key="item.id"> | |||
| <view class="avatar"> | |||
| <image class="img" :src="item.avatar" mode="scaleToFill"></image> | |||
| </view> | |||
| <view>{{ item.name }}</view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import mixinsList from '@/mixins/list.js' | |||
| export default { | |||
| mixins: [mixinsList], | |||
| data() { | |||
| return { | |||
| tabs: [ | |||
| { name: '直推用户列表' }, | |||
| { name: '间推用户列表' }, | |||
| ], | |||
| mixinsListApi: '', | |||
| current: 0, | |||
| } | |||
| }, | |||
| onShow() { | |||
| console.log('onShow') | |||
| }, | |||
| onLoad(arg) { | |||
| this.clickTabs({ index: arg.index || 0 }) | |||
| }, | |||
| methods: { | |||
| // todo: delete | |||
| getData() { | |||
| this.list = [ | |||
| { | |||
| id: '001', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李世海', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '002', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '周静', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '003', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '周海', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '004', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '冯启彬', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '005', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李娉', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '006', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李书萍', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '007', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李世海', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '008', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '周静', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '009', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '周海', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '010', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '冯启彬', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '011', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李娉', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| { | |||
| id: '012', | |||
| avatar: '/static/image/temp-30.png', | |||
| name: '李书萍', | |||
| price: 10, | |||
| createTime: '2025-07-15', | |||
| }, | |||
| ] | |||
| }, | |||
| //点击tab栏 | |||
| clickTabs({ index }) { | |||
| console.log('clickTabs') | |||
| this.current = index | |||
| if (index == 0) { | |||
| delete this.queryParams.status | |||
| } else { | |||
| this.queryParams.status = index - 1 | |||
| } | |||
| this.getData() | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page__view { | |||
| width: 100vw; | |||
| min-height: 100vh; | |||
| background-color: $uni-bg-color; | |||
| position: relative; | |||
| /deep/ .nav-bar__view { | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| } | |||
| } | |||
| .main { | |||
| padding: calc(var(--status-bar-height) + 244rpx) 32rpx 40rpx 32rpx; | |||
| .tabs { | |||
| position: fixed; | |||
| top: calc(var(--status-bar-height) + 120rpx); | |||
| left: 0; | |||
| width: 100%; | |||
| height: 84rpx; | |||
| background: #FFFFFF; | |||
| z-index: 1; | |||
| /deep/ .uv-tabs__wrapper__nav__line { | |||
| border-radius: 2rpx; | |||
| } | |||
| } | |||
| } | |||
| .list { | |||
| background: #FFFFFF; | |||
| border-radius: 32rpx; | |||
| overflow: hidden; | |||
| &-item { | |||
| margin-top: 16rpx; | |||
| padding: 16rpx 32rpx; | |||
| font-size: 28rpx; | |||
| color: #333333; | |||
| background: #FFFFFF; | |||
| border-bottom: 2rpx solid #F1F1F1; | |||
| justify-content: flex-start; | |||
| column-gap: 24rpx; | |||
| &:last-child { | |||
| border: none; | |||
| } | |||
| .avatar { | |||
| width: 72rpx; | |||
| height: 72rpx; | |||
| border-radius: 50%; | |||
| overflow: hidden; | |||
| .img { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,233 @@ | |||
| <template> | |||
| <view class="page__view"> | |||
| <navbar title="提现" leftClick @leftClick="$utils.navigateBack" color="#191919" bgColor="#FFFFFF" /> | |||
| <view class="main"> | |||
| <view class="card"> | |||
| <view class="card-header">微信提现</view> | |||
| <view class="form"> | |||
| <uv-form | |||
| ref="form" | |||
| :model="form" | |||
| :rules="rules" | |||
| errorType="toast" | |||
| > | |||
| <view class="form-item"> | |||
| <uv-form-item prop="name" :customStyle="formItemStyle"> | |||
| <view class="form-item-label">真实姓名</view> | |||
| <view class="form-item-content"> | |||
| <formInput v-model="form.name"></formInput> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| <view class="form-item"> | |||
| <uv-form-item prop="amount" :customStyle="formItemStyle"> | |||
| <view class="form-item-label">提现金额</view> | |||
| <view class="form-item-content"> | |||
| <formInput v-model="form.amount"></formInput> | |||
| </view> | |||
| </uv-form-item> | |||
| </view> | |||
| </uv-form> | |||
| </view> | |||
| </view> | |||
| <view class="notice"> | |||
| 请仔细检查并确认相关信息,因用户个人疏忽导致的充值错误。需由用户自行承担。 | |||
| <!-- todo: 替换配置项key --> | |||
| <text class="highlight" @click="$refs.modal.open('user_ys', '提现须知')">《提现须知》</text> | |||
| </view> | |||
| <agreementModal ref="modal"></agreementModal> | |||
| </view> | |||
| <view class="bottom"> | |||
| <button class="btn" @click="onSubmit">提现</button> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import formInput from '@/pages_order/components/formInput.vue' | |||
| import agreementModal from '@/pages_order/components/agreementModal.vue' | |||
| export default { | |||
| components: { | |||
| formInput, | |||
| agreementModal, | |||
| }, | |||
| data() { | |||
| return { | |||
| form: { | |||
| name: null, | |||
| amount: null, | |||
| }, | |||
| rules: { | |||
| 'name': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请输入真实姓名', | |||
| }, | |||
| 'amount': { | |||
| type: 'string', | |||
| required: true, | |||
| message: '请输入提现金额', | |||
| }, | |||
| }, | |||
| formItemStyle: { padding: 0 }, | |||
| } | |||
| }, | |||
| methods: { | |||
| async onSubmit() { | |||
| try { | |||
| await this.$refs.form.validate() | |||
| const { | |||
| } = this.form | |||
| const params = { | |||
| } | |||
| // todo: fetch | |||
| // await this.$fetch('updateAddress', params) | |||
| uni.showToast({ | |||
| icon: 'success', | |||
| title: '提交成功', | |||
| }); | |||
| setTimeout(() => { | |||
| this.$utils.navigateBack() | |||
| }, 800) | |||
| } catch (err) { | |||
| console.log('onSave err', err) | |||
| } | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page__view { | |||
| width: 100vw; | |||
| min-height: 100vh; | |||
| background: unset; | |||
| position: relative; | |||
| /deep/ .nav-bar__view { | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| } | |||
| } | |||
| .main { | |||
| padding: calc(var(--status-bar-height) + 144rpx) 32rpx 224rpx 32rpx; | |||
| } | |||
| .card { | |||
| padding: 32rpx; | |||
| background: #FFFFFF; | |||
| border: 2rpx solid #FFFFFF; | |||
| border-radius: 32rpx; | |||
| & + & { | |||
| margin-top: 40rpx; | |||
| } | |||
| &-header { | |||
| font-family: PingFang SC; | |||
| font-weight: 500; | |||
| font-size: 36rpx; | |||
| line-height: 1.4; | |||
| color: #252545; | |||
| margin-bottom: 32rpx; | |||
| } | |||
| } | |||
| .form { | |||
| padding: 8rpx 0 0 0; | |||
| &-item { | |||
| border-bottom: 2rpx solid #EEEEEE; | |||
| &:last-child { | |||
| border: none; | |||
| } | |||
| & + & { | |||
| margin-top: 40rpx; | |||
| } | |||
| &-label { | |||
| font-family: PingFang SC; | |||
| font-weight: 400; | |||
| font-size: 26rpx; | |||
| line-height: 1.4; | |||
| color: #181818; | |||
| } | |||
| &-content { | |||
| margin-top: 14rpx; | |||
| padding: 6rpx 0; | |||
| .text { | |||
| padding: 2rpx 0; | |||
| font-family: PingFang SC; | |||
| font-weight: 400; | |||
| font-size: 32rpx; | |||
| line-height: 1.4; | |||
| &.placeholder { | |||
| color: #C6C6C6; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .notice { | |||
| margin-top: 40rpx; | |||
| font-size: 24rpx; | |||
| line-height: 1.4; | |||
| color: #BABABA; | |||
| .highlight { | |||
| color: #F79400; | |||
| } | |||
| } | |||
| .bottom { | |||
| position: fixed; | |||
| left: 0; | |||
| bottom: 0; | |||
| width: 100vw; | |||
| // height: 200rpx; | |||
| padding: 24rpx 40rpx; | |||
| padding-bottom: calc(env(safe-area-inset-bottom) + 24rpx); | |||
| background: #FFFFFF; | |||
| box-sizing: border-box; | |||
| .btn { | |||
| width: 100%; | |||
| padding: 14rpx 0; | |||
| box-sizing: border-box; | |||
| font-family: PingFang SC; | |||
| font-weight: 500; | |||
| font-size: 36rpx; | |||
| line-height: 1; | |||
| color: #FFFFFF; | |||
| background: linear-gradient(to right, #21FEEC, #019AF9); | |||
| border: 2rpx solid #00A9FF; | |||
| border-radius: 41rpx; | |||
| } | |||
| } | |||
| </style> | |||