@ -0,0 +1,335 @@ | |||
<template> | |||
<view class="center-page"> | |||
<!-- 顶部背景和个人信息 --> | |||
<view class="header" :style="{ 'background-image': 'url(/static/image/红烧肉.png)' }"> | |||
<view class="user-info"> | |||
<image class="avatar" :src="userInfo.avatarUrl" mode="aspectFill"></image> | |||
<view class="user-name-id"> | |||
<text class="user-name">{{ userInfo.nickName }}</text> | |||
<text class="user-id">ID:{{ userInfo.userId }}</text> | |||
</view> | |||
</view> | |||
<view class="role-switch-btn"> | |||
<uv-icon name="reload" size="30rpx" color="#fff" style="margin-right: 6rpx;" /> | |||
<text>切换为{{ userInfo.role }}</text> | |||
</view> | |||
</view> | |||
<!-- 我的订单区域 --> | |||
<view class="orders-section"> | |||
<view class="section-header"> | |||
<text class="section-title">我的订单</text> | |||
<view class="view-all" @tap="navigateTo('/pages/index/order?status=all')"> | |||
<text>全部</text> | |||
<uv-icon name="arrow-right" size="30rpx" color="#999" /> | |||
</view> | |||
</view> | |||
<view class="order-types"> | |||
<view class="order-type-item" @tap="navigateTo('/pages/index/order?status=pending')"> | |||
<view class="order-icon-wrapper"> | |||
<view class="green-circle"> | |||
<uv-icon name="red-packet" size="44rpx" color="#fff" /> | |||
</view> | |||
<uv-badge max="9" absolute :offset="[-10, -12]" bgColor="#FF2A2A" | |||
:value="userInfo.waitingPayCount" style="padding: 10rpx 15rpx;" /> | |||
</view> | |||
<text class="order-type-text">待支付</text> | |||
</view> | |||
<view class="order-type-item" @tap="navigateTo('/pages/index/order?status=processing')"> | |||
<view class="order-icon-wrapper"> | |||
<view class="green-circle"> | |||
<uv-icon name="chat" size="44rpx" color="#fff" /> | |||
</view> | |||
<uv-badge max="9" absolute :offset="[-10, -12]" bgColor="#FF2A2A" | |||
:value="userInfo.waitingDiningCount" style="padding: 10rpx 15rpx;" /> | |||
</view> | |||
<text class="order-type-text">待出餐</text> | |||
</view> | |||
<view class="order-type-item" @tap="navigateTo('/pages/index/order?status=shipping')"> | |||
<view class="order-icon-wrapper"> | |||
<view class="green-circle"> | |||
<uv-icon name="chat" size="44rpx" color="#fff" /> | |||
</view> | |||
<uv-badge max="9" absolute :offset="[-10, -12]" bgColor="#FF2A2A" | |||
:value="userInfo.deliveringCount" style="padding: 10rpx 15rpx;" /> | |||
</view> | |||
<text class="order-type-text">送餐中</text> | |||
</view> | |||
<view class="order-type-item" @tap="navigateTo('/pages/index/order?status=delivered')"> | |||
<view class="order-icon-wrapper"> | |||
<view class="green-circle"> | |||
<uv-icon name="chat" size="44rpx" color="#fff" /> | |||
</view> | |||
<uv-badge max="9" absolute :offset="[-10, -12]" bgColor="#FF2A2A" :value="userInfo.pickupCount" | |||
style="padding: 10rpx 15rpx;" /> | |||
</view> | |||
<text class="order-type-text">待取餐</text> | |||
</view> | |||
<view class="order-type-item" @tap="navigateTo('/pages/index/order?status=completed')"> | |||
<view class="order-icon-wrapper"> | |||
<view class="green-circle"> | |||
<uv-icon name="chat" size="44rpx" color="#fff" /> | |||
</view> | |||
<uv-badge max="9" absolute :offset="[-10, -12]" bgColor="#FF2A2A" | |||
:value="userInfo.completedCount" style="padding: 10rpx 15rpx;" /> | |||
</view> | |||
<text class="order-type-text">已完成</text> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 团员功能区域 --> | |||
<view class="member-functions"> | |||
<view class="section-header"> | |||
<text class="section-title">团员功能</text> | |||
</view> | |||
<view class="function-grid"> | |||
<view class="function-item" @tap="navigateTo('/pages_order/mine/updateUser')"> | |||
<view class="function-icon"> | |||
<uv-icon name="chat" size="94rpx" color="#019245" /> | |||
</view> | |||
<text class="function-text">资料修改</text> | |||
</view> | |||
<view class="function-item" @tap="navigateTo('/pages_order/mine/team')"> | |||
<view class="function-icon"> | |||
<uv-icon name="chat" size="94rpx" color="#019245" /> | |||
</view> | |||
<text class="function-text">团长申请</text> | |||
</view> | |||
<view class="function-item" @tap="navigateTo('/pages_order/mine/leader')"> | |||
<view class="function-icon"> | |||
<uv-icon name="chat" size="94rpx" color="#019245" /> | |||
</view> | |||
<text class="function-text">解绑团长</text> | |||
</view> | |||
<view class="function-item" @tap="navigateTo('/pages_order/mine/share')"> | |||
<view class="function-icon"> | |||
<uv-icon name="chat" size="94rpx" color="#019245" /> | |||
</view> | |||
<text class="function-text">推广链接</text> | |||
</view> | |||
<view class="function-item" @tap="navigateTo('/pages_order/mine/coupon')"> | |||
<view class="function-icon"> | |||
<uv-icon name="chat" size="94rpx" color="#019245" /> | |||
</view> | |||
<text class="function-text">优惠券</text> | |||
</view> | |||
<view class="function-item" @tap="navigateTo('/pages_order/mine/wallet')"> | |||
<view class="function-icon"> | |||
<uv-icon name="chat" size="94rpx" color="#019245" /> | |||
</view> | |||
<text class="function-text">钱包</text> | |||
</view> | |||
</view> | |||
</view> | |||
<tabber select="center" /> | |||
</view> | |||
</template> | |||
<script> | |||
import tabber from '@/components/base/tabbar.vue' | |||
import { mockUserInfo } from '@/static/js/mockUserInfo.js' | |||
export default { | |||
components: { | |||
tabber | |||
}, | |||
data() { | |||
return { | |||
userInfo: mockUserInfo | |||
} | |||
}, | |||
methods: { | |||
navigateTo(url) { | |||
console.log(111222); | |||
this.$utils.navigateTo({ | |||
url | |||
}) | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.center-page { | |||
min-height: 100vh; | |||
background-color: #f5f5f5; | |||
padding-bottom: 120rpx; | |||
} | |||
.header { | |||
position: relative; | |||
height: 340rpx; | |||
background-size: cover; | |||
background-position: center; | |||
color: #fff; | |||
padding: 60rpx 30rpx 0; | |||
display: flex; | |||
flex-direction: column; | |||
align-items: start; | |||
position: relative; | |||
.user-info { | |||
position: absolute; | |||
display: flex; | |||
align-items: center; | |||
margin-top: 30rpx; | |||
z-index: 2; | |||
left: 30rpx; | |||
top: 120rpx; | |||
.avatar { | |||
width: 110rpx; | |||
height: 110rpx; | |||
border-radius: 50%; | |||
} | |||
.user-name-id { | |||
margin-left: 30rpx; | |||
display: flex; | |||
flex-direction: column; | |||
.user-name { | |||
font-size: 32rpx; | |||
font-weight: bold; | |||
margin-bottom: 6rpx; | |||
} | |||
.user-id { | |||
font-size: 24rpx; | |||
opacity: 0.9; | |||
} | |||
} | |||
} | |||
.role-switch-btn { | |||
position: absolute; | |||
right: 0; | |||
top: 180rpx; | |||
background-color: rgba(255, 255, 255, 0.2); | |||
border-radius: 30rpx 0 0 30rpx; | |||
padding: 10rpx 20rpx; | |||
font-size: 24rpx; | |||
z-index: 2; | |||
display: flex; | |||
align-items: center; | |||
} | |||
} | |||
.orders-section { | |||
background-color: #fff; | |||
border-radius: 20rpx 20rpx 0 0; | |||
margin: -70rpx auto 0; | |||
padding: 15rpx; | |||
position: relative; | |||
z-index: 3; | |||
width: 90%; | |||
// margin: 0 auto; | |||
} | |||
.member-functions { | |||
background-color: #fff; | |||
padding: 30rpx; | |||
margin-top: 20rpx; | |||
width: 88%; | |||
border-radius: 20rpx; | |||
margin: 30rpx auto 0; | |||
} | |||
.section-header { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
margin-bottom: 40rpx; | |||
.section-title { | |||
font-size: 32rpx; | |||
font-weight: 500; | |||
position: relative; | |||
padding-left: 15rpx; | |||
} | |||
.view-all { | |||
display: flex; | |||
align-items: center; | |||
font-size: 26rpx; | |||
color: $uni-color-third; | |||
} | |||
} | |||
.order-types { | |||
// background-color: red; | |||
display: flex; | |||
// justify-content: space-around; | |||
.order-type-item { | |||
display: flex; | |||
flex-direction: column; | |||
align-items: center; | |||
width: 20%; | |||
.order-icon-wrapper { | |||
position: relative; | |||
margin-bottom: 4rpx; | |||
.green-circle { | |||
width: 70rpx; | |||
height: 70rpx; | |||
background-color: $uni-color; | |||
border-radius: 50%; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
} | |||
} | |||
.order-type-text { | |||
font-size: 26rpx; | |||
color: #666; | |||
margin-top: 8rpx; | |||
} | |||
} | |||
} | |||
.function-grid { | |||
display: flex; | |||
flex-wrap: wrap; | |||
.function-item { | |||
width: 25%; | |||
display: flex; | |||
flex-direction: column; | |||
align-items: center; | |||
margin-bottom: 40rpx; | |||
.function-icon { | |||
width: 80rpx; | |||
height: 80rpx; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
margin-bottom: 16rpx; | |||
} | |||
.function-text { | |||
font-size: 26rpx; | |||
color: #333; | |||
} | |||
} | |||
} | |||
</style> |
@ -0,0 +1,304 @@ | |||
<template> | |||
<view class="login"> | |||
<view class="bg1"></view> | |||
<view class="title"> | |||
定制自己的形象 | |||
</view> | |||
<view v-if="back" @click="$utils.navigateBack" style="position: absolute;top: 120rpx;left: 20rpx;"> | |||
<uv-icon size="30rpx" color="#000" name="arrow-left"></uv-icon> | |||
</view> | |||
<button class="chooseAvatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> | |||
<image :src="form.headImage" mode="aspectFill"></image> | |||
</button> | |||
<input type="nickname" placeholder="给自己起一个响亮的名字" class="nickname" id="nickName" v-model="form.nickName" /> | |||
<!-- <view class="sexSelect"> | |||
<view | |||
@click="sexClick(item)" | |||
v-for="(item, index) in sexList" | |||
:key="index" | |||
:style="{color : form.sex == item.value ? item.actColor : '#333'}"> | |||
<uv-icon | |||
size="30rpx" | |||
:color="form.sex == item.value ? item.actColor : '#333'" | |||
:name="item.icon"></uv-icon> | |||
{{ item.value }} | |||
</view> | |||
</view> --> | |||
<!-- <view class="address" | |||
@click="$refs.datetimePicker.open()"> | |||
您出生于{{ $dayjs(form.yearDate).format("YYYY") }}年 | |||
</view> | |||
<view class="address" | |||
@click="$refs.picker.open()"> | |||
{{ form.address || '请选择居住地址'}} | |||
</view> --> | |||
<uv-datetime-picker ref="datetimePicker" v-model="form.yearDate" mode="year" :minDate="minDate" | |||
:maxDate="maxDate"> | |||
</uv-datetime-picker> | |||
<uv-picker ref="picker" :columns="columns" keyName="name" @confirm="confirmAddress"></uv-picker> | |||
<view class="btn" @click="submit"> | |||
确认 | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
import { mapState } from 'vuex' | |||
export default { | |||
data() { | |||
return { | |||
form: { | |||
headImage: '', | |||
nickName: '', | |||
sex: '男', | |||
yearDate: this.$dayjs().add(-18, 'y').valueOf(),//默认满18岁 | |||
address: '', | |||
}, | |||
maxDate: this.$dayjs().valueOf(), | |||
minDate: this.$dayjs().add(-100, 'y').valueOf(), | |||
sex: { | |||
男: { | |||
name: 'man', | |||
color: '#5baaff', | |||
}, | |||
女: { | |||
name: 'woman', | |||
color: '#ff50b3', | |||
}, | |||
}, | |||
sexList: [ | |||
{ | |||
value: '男', | |||
icon: 'man', | |||
actColor: '#5baaff', | |||
}, | |||
{ | |||
value: '女', | |||
icon: 'woman', | |||
actColor: '#ff50b3', | |||
}, | |||
], | |||
columns: [], | |||
back: '', | |||
}; | |||
}, | |||
computed: { | |||
...mapState(['cityList', 'userInfo']), | |||
}, | |||
onLoad({ back }) { | |||
this.back = back | |||
// this.$nextTick(() => { | |||
// this.form.headImage = this.userInfo.headImage || this.form.headImage | |||
// this.form.nickName = this.userInfo.nickName || this.form.nickName | |||
// this.form.sex = this.userInfo.sex || this.form.sex | |||
// this.form.yearDate = this.userInfo.yearDate || this.form.yearDate | |||
// this.form.address = this.userInfo.address || this.form.address | |||
// }) | |||
}, | |||
onShow() { | |||
this.getCityList() | |||
this.getUserInfo() | |||
}, | |||
computed: {}, | |||
methods: { | |||
onChooseAvatar(res) { | |||
let self = this | |||
self.$Oss.ossUpload(res.target.avatarUrl) | |||
.then(url => { | |||
self.form.headImage = url | |||
}) | |||
}, | |||
sexClick(item) { | |||
this.form.sex = item.value | |||
}, | |||
confirmAddress(e) { | |||
this.form.address = e.value[0].name | |||
}, | |||
// 获取城市 | |||
getCityList() { | |||
this.$api('getCityList', res => { | |||
if (res.code == 200) { | |||
this.columns = [ | |||
res.result | |||
] | |||
} | |||
}) | |||
}, | |||
getUserInfo() { | |||
this.$api('getInfo', res => { | |||
if (res.code == 200) { | |||
this.form.headImage = res.result.headImage || this.form.headImage | |||
this.form.nickName = res.result.nickName || this.form.nickName | |||
this.form.sex = res.result.sex || this.form.sex | |||
this.form.yearDate = res.result.yearDate && | |||
this.$dayjs(res.result.yearDate + '-01-01').valueOf() || this.form.yearDate | |||
this.form.address = res.result.address || this.form.address | |||
} | |||
}) | |||
}, | |||
submit() { | |||
let self = this | |||
uni.createSelectorQuery().in(this) | |||
.select("#nickName") | |||
.fields({ | |||
properties: ["value"], | |||
}) | |||
.exec((res) => { | |||
const nickName = res?.[0]?.value | |||
self.form.nickName = nickName | |||
if (self.$utils.verificationAll(self.form, { | |||
headImage: '请选择头像', | |||
nickName: '请填写昵称', | |||
// address: '请选择居住地址', | |||
})) { | |||
return | |||
} | |||
let data = { | |||
...self.form, | |||
// yearDate : this.$dayjs(self.form.yearDate).format("YYYY") | |||
} | |||
self.$api('updateInfo', data, res => { | |||
if (res.code == 200) { | |||
uni.reLaunch({ | |||
url: '/pages/index/index' | |||
}) | |||
} | |||
}) | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.login { | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
align-items: center; | |||
height: 100vh; | |||
background-color: #fff; | |||
overflow: hidden; | |||
.bg1 { | |||
width: 700rpx; | |||
height: 700rpx; | |||
border-radius: 50%; | |||
background-color: #ffc0b333; | |||
position: absolute; | |||
right: -300rpx; | |||
top: -300rpx; | |||
} | |||
.title { | |||
line-height: 45rpx; | |||
font-weight: 900; | |||
padding-bottom: 100rpx; | |||
font-size: 40rpx; | |||
} | |||
.chooseAvatar { | |||
width: 100%; | |||
padding: 0 !important; | |||
margin: 0 !important; | |||
border: none; | |||
background-color: #fff !important; | |||
width: 220rpx; | |||
height: 220rpx; | |||
border-radius: 50%; | |||
image { | |||
width: 200rpx; | |||
height: 200rpx; | |||
border-radius: 50%; | |||
box-shadow: 0 0 10rpx 10rpx #00000012; | |||
margin: 10rpx; | |||
} | |||
} | |||
.chooseAvatar::after { | |||
border: none; | |||
padding: 0 !important; | |||
margin: 0 !important; | |||
} | |||
.nickname { | |||
background-color: #f7f7f7; | |||
width: 600rpx; | |||
height: 80rpx; | |||
text-align: center; | |||
border-radius: 40rpx; | |||
margin-top: 30rpx; | |||
} | |||
.sexSelect { | |||
background-color: #f7f7f7; | |||
width: 600rpx; | |||
height: 80rpx; | |||
text-align: center; | |||
border-radius: 40rpx; | |||
margin-top: 30rpx; | |||
display: flex; | |||
align-items: center; | |||
font-size: 26rpx; | |||
line-height: 80rpx; | |||
overflow: hidden; | |||
&>view { | |||
flex: 1; | |||
display: flex; | |||
justify-content: center; | |||
align-content: center; | |||
height: 100%; | |||
} | |||
&>view:nth-child(1) { | |||
border-right: 1px solid #000; | |||
} | |||
} | |||
.address { | |||
background-color: #f7f7f7; | |||
width: 600rpx; | |||
height: 80rpx; | |||
text-align: center; | |||
border-radius: 40rpx; | |||
margin-top: 30rpx; | |||
line-height: 80rpx; | |||
color: #555; | |||
} | |||
.btn { | |||
// background: $uni-linear-gradient-btn-color; | |||
background: $uni-color; | |||
color: #fff; | |||
width: 80%; | |||
padding: 20rpx 0; | |||
text-align: center; | |||
border-radius: 15rpx; | |||
margin-top: 10vh; | |||
} | |||
} | |||
</style> |
@ -0,0 +1,335 @@ | |||
<template> | |||
<view class="page"> | |||
<!-- 导航栏 --> | |||
<navbar title="团长申请" leftClick @leftClick="$utils.navigateBack" bgColor="#019245" color="#fff" /> | |||
<!-- 顶部图片区域 --> | |||
<view class="banner"> | |||
<image src="/static/image/红烧肉.png" mode="aspectFill" class="banner-image"></image> | |||
</view> | |||
<view class="content-area"> | |||
<!-- 送餐点照片上传区域 --> | |||
<view class="section-title">送餐点照片</view> | |||
<view class="section-block"> | |||
<view class="upload-container"> | |||
<view class="upload-area" @click="chooseImage" v-if="!locationImage"> | |||
<view class="plus">+</view> | |||
<view class="upload-text">添加图片</view> | |||
</view> | |||
<image v-else :src="locationImage" mode="aspectFill" class="upload-area" @click="chooseImage" /> | |||
</view> | |||
</view> | |||
<!-- 送餐点信息填写区域 --> | |||
<view class="section-title">送餐点信息</view> | |||
<view class="section-block"> | |||
<view class="form-item"> | |||
<text class="label">送餐点名称</text> | |||
<input class="input" type="text" v-model="formData.name" placeholder="请输入送餐点名称" | |||
placeholder-class="placeholder" /> | |||
</view> | |||
<view class="form-item"> | |||
<text class="label">您的姓名</text> | |||
<input class="input" type="text" v-model="formData.contactName" placeholder="请输入您的姓名" | |||
placeholder-class="placeholder" /> | |||
</view> | |||
<view class="form-item"> | |||
<text class="label">联系手机号</text> | |||
<input class="input" type="number" v-model="formData.contactPhone" placeholder="请输入您的手机号" | |||
placeholder-class="placeholder" /> | |||
</view> | |||
<view class="form-item region-item" @click="showRegionPicker"> | |||
<text class="label">所在地区</text> | |||
<view class="region-value"> | |||
<text :class="{ 'placeholder': !formData.region }" style="color: #000;">{{ formData.region || '请选择' }}</text> | |||
<uv-icon name="arrow-right" color="#000" /> | |||
</view> | |||
</view> | |||
<view class="address-item"> | |||
<text class="label">详细地址</text> | |||
<view class="address-box"> | |||
<textarea class="address-input" v-model="formData.address" placeholder="请输入详细地址" | |||
placeholder-class="placeholder" /> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 提交按钮 --> | |||
<view class="submit-btn" @click="submitApplication"> | |||
提交申请 | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
import navbar from '@/components/base/navbar.vue' | |||
export default { | |||
components: { | |||
navbar | |||
}, | |||
data() { | |||
return { | |||
locationImage: '', // 上传的送餐点照片 | |||
formData: { | |||
name: '', // 送餐点名称 | |||
contactName: '', // 联系人姓名 | |||
contactPhone: '', // 联系电话 | |||
region: '', // 所在地区 | |||
address: '' // 详细地址 | |||
} | |||
} | |||
}, | |||
methods: { | |||
// 选择图片 | |||
chooseImage() { | |||
uni.chooseImage({ | |||
count: 1, | |||
sizeType: ['compressed'], | |||
sourceType: ['album', 'camera'], | |||
success: (res) => { | |||
// 这里可以添加图片上传到服务器的逻辑 | |||
// 暂时只展示选择的图片 | |||
this.locationImage = res.tempFilePaths[0] | |||
} | |||
}) | |||
}, | |||
// 显示地区选择器(当前只是一个简单的点击反应) | |||
showRegionPicker() { | |||
// 模拟选择了一个地区 | |||
this.formData.region = '长沙市雨花区' | |||
// 显示提示 | |||
uni.showToast({ | |||
title: '已选择地区', | |||
icon: 'none' | |||
}) | |||
}, | |||
// 提交申请 | |||
submitApplication() { | |||
// 表单验证 | |||
if (!this.locationImage) { | |||
return uni.showToast({ | |||
title: '请上传送餐点照片', | |||
icon: 'none' | |||
}) | |||
} | |||
if (!this.formData.name) { | |||
return uni.showToast({ | |||
title: '请输入送餐点名称', | |||
icon: 'none' | |||
}) | |||
} | |||
if (!this.formData.contactName) { | |||
return uni.showToast({ | |||
title: '请输入您的姓名', | |||
icon: 'none' | |||
}) | |||
} | |||
if (!this.formData.contactPhone) { | |||
return uni.showToast({ | |||
title: '请输入联系手机号', | |||
icon: 'none' | |||
}) | |||
} | |||
if (!this.$utils.verificationPhone(this.formData.contactPhone)) { | |||
return uni.showToast({ | |||
title: '请输入正确的手机号', | |||
icon: 'none' | |||
}) | |||
} | |||
if (!this.formData.region) { | |||
return uni.showToast({ | |||
title: '请选择所在地区', | |||
icon: 'none' | |||
}) | |||
} | |||
if (!this.formData.address) { | |||
return uni.showToast({ | |||
title: '请输入详细地址', | |||
icon: 'none' | |||
}) | |||
} | |||
// 显示提交中 | |||
uni.showLoading({ | |||
title: '提交中...' | |||
}) | |||
// 模拟提交申请的过程 | |||
setTimeout(() => { | |||
uni.hideLoading() | |||
uni.showToast({ | |||
title: '申请提交成功', | |||
icon: 'success' | |||
}) | |||
// 延迟返回上一页 | |||
setTimeout(() => { | |||
this.$utils.navigateBack() | |||
}, 1500) | |||
}, 1000) | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.page { | |||
background-color: #f5f5f5; | |||
min-height: 100vh; | |||
} | |||
.banner { | |||
width: 100%; | |||
height: 240rpx; | |||
background-color: #019245; | |||
.banner-image { | |||
width: 100%; | |||
height: 100%; | |||
display: block; | |||
} | |||
} | |||
.content-area { | |||
padding: 20rpx; | |||
} | |||
.section-block { | |||
margin-bottom: 20rpx; | |||
background-color: #fff; | |||
border-radius: 20rpx; | |||
padding: 10rpx 20rpx; | |||
overflow: hidden; | |||
} | |||
.section-title { | |||
font-size: 28rpx; | |||
color: #333; | |||
padding: 20rpx; | |||
// border-bottom: 1rpx solid #f5f5f5; | |||
} | |||
.upload-container { | |||
padding: 20rpx; | |||
min-height: 140rpx; | |||
} | |||
.upload-area { | |||
width: 150rpx; | |||
height: 150rpx; | |||
border: 3rpx dashed $uni-color; | |||
// border-radius: 8rpx; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
align-items: center; | |||
.plus { | |||
font-size: 80rpx; | |||
color: $uni-color; | |||
line-height: 1; | |||
// margin-bottom: 5rpx; | |||
font-weight: 100; | |||
} | |||
.upload-text { | |||
font-size: 24rpx; | |||
color: $uni-color-third; | |||
} | |||
} | |||
.form-item { | |||
padding: 24rpx 0; | |||
display: flex; | |||
align-items: center; | |||
border-bottom: 2rpx solid #C7C7C7; | |||
&:last-child { | |||
border-bottom: none; | |||
} | |||
} | |||
.label { | |||
flex: 3; | |||
font-size: 28rpx; | |||
color: #333; | |||
padding-left: 10rpx; | |||
} | |||
.input { | |||
flex: 2; | |||
font-size: 28rpx; | |||
// height: 60rpx; | |||
text-align: left; | |||
} | |||
.placeholder, | |||
.region-item .region-value text.placeholder { | |||
// height: 60rpx; | |||
color: #999; | |||
} | |||
.region-item { | |||
cursor: pointer; | |||
.region-value { | |||
flex: 1; | |||
text-align: right; | |||
font-size: 28rpx; | |||
display: flex; | |||
justify-content: flex-end; | |||
align-items: center; | |||
} | |||
} | |||
.address-item { | |||
padding: 24rpx 0; | |||
display: flex; | |||
flex-direction: column; | |||
gap: 20rpx; | |||
.address-box { | |||
} | |||
.address-input { | |||
padding: 20rpx; | |||
background-color: #F5F5F5; | |||
border-radius: 10rpx; | |||
width: inherit; | |||
height: 60rpx; | |||
font-size: 28rpx; | |||
} | |||
} | |||
.submit-btn { | |||
width: 80%; | |||
margin: 40rpx auto 0; | |||
height: 100rpx; | |||
background-color: $uni-color; | |||
color: #fff; | |||
font-size: 32rpx; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
border-radius: 50rpx; | |||
// margin-top: 60rpx; | |||
} | |||
</style> |
@ -1,319 +1,282 @@ | |||
<template> | |||
<view class="login"> | |||
<view class="bg1"></view> | |||
<view class="title"> | |||
定制自己的形象 | |||
</view> | |||
<view | |||
v-if="back" | |||
@click="$utils.navigateBack" | |||
style="position: absolute;top: 120rpx;left: 20rpx;"> | |||
<uv-icon | |||
size="30rpx" | |||
color="#000" | |||
name="arrow-left"></uv-icon> | |||
</view> | |||
<button class="chooseAvatar" | |||
open-type="chooseAvatar" | |||
@chooseavatar="onChooseAvatar"> | |||
<image :src="form.headImage" | |||
mode="aspectFill"></image> | |||
</button> | |||
<input type="nickname" | |||
placeholder="给自己起一个响亮的名字" | |||
class="nickname" id="nickName" | |||
v-model="form.nickName" /> | |||
<!-- <view class="sexSelect"> | |||
<view | |||
@click="sexClick(item)" | |||
v-for="(item, index) in sexList" | |||
:key="index" | |||
:style="{color : form.sex == item.value ? item.actColor : '#333'}"> | |||
<uv-icon | |||
size="30rpx" | |||
:color="form.sex == item.value ? item.actColor : '#333'" | |||
:name="item.icon"></uv-icon> | |||
{{ item.value }} | |||
<view class="profile-page"> | |||
<!-- 头部导航栏 --> | |||
<navbar title="资料修改" bgColor="#019245" color="#fff" leftClick @leftClick="$utils.navigateBack" /> | |||
<!-- 基本资料区域 --> | |||
<view class="main-content"> | |||
<view class="section-title"> | |||
<view class="title-indicator"></view> | |||
<text>基本资料</text> | |||
</view> | |||
<!-- 头像选择区域 --> | |||
<view class="avatar-section"> | |||
<button class="chooseAvatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> | |||
<image class="avatar-img" :src="form.headImage" mode="aspectFill"></image> | |||
</button> | |||
<text class="avatar-hint">点击更换头像</text> | |||
</view> | |||
<!-- 表单区域 --> | |||
<view class="form-section"> | |||
<view class="form-item"> | |||
<text class="label">昵称</text> | |||
<input class="input" type="nickname" placeholder="请输入" v-model="form.nickName" id="nickName" | |||
placeholderStyle="color: #999; text-align: right;" /> | |||
</view> | |||
<view class="form-item"> | |||
<text class="label">手机号</text> | |||
<input class="input" type="tel" placeholder="请输入" v-model="form.phone" | |||
placeholderStyle="color: #999; text-align: right;" /> | |||
</view> | |||
</view> | |||
<!-- 保存按钮 --> | |||
<view class="save-button" @tap="submit"> | |||
<text>保存</text> | |||
</view> | |||
</view> --> | |||
<!-- <view class="address" | |||
@click="$refs.datetimePicker.open()"> | |||
您出生于{{ $dayjs(form.yearDate).format("YYYY") }}年 | |||
</view> | |||
<view class="address" | |||
@click="$refs.picker.open()"> | |||
{{ form.address || '请选择居住地址'}} | |||
</view> --> | |||
<uv-datetime-picker | |||
ref="datetimePicker" | |||
v-model="form.yearDate" | |||
mode="year" | |||
:minDate="minDate" | |||
:maxDate="maxDate"> | |||
</uv-datetime-picker> | |||
<uv-picker ref="picker" | |||
:columns="columns" | |||
keyName="name" | |||
@confirm="confirmAddress"></uv-picker> | |||
<view class="btn" @click="submit"> | |||
确认 | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
import { mapState } from 'vuex' | |||
export default { | |||
data() { | |||
return { | |||
form: { | |||
headImage: '', | |||
nickName: '', | |||
sex : '男', | |||
yearDate : this.$dayjs().add(-18, 'y').valueOf(),//默认满18岁 | |||
address : '', | |||
}, | |||
maxDate : this.$dayjs().valueOf(), | |||
minDate : this.$dayjs().add(-100, 'y').valueOf(), | |||
sex : { | |||
男 : { | |||
name : 'man', | |||
color : '#5baaff', | |||
}, | |||
女 : { | |||
name : 'woman', | |||
color : '#ff50b3', | |||
}, | |||
}, | |||
sexList : [ | |||
{ | |||
value : '男', | |||
icon : 'man', | |||
actColor : '#5baaff', | |||
}, | |||
{ | |||
value : '女', | |||
icon : 'woman', | |||
actColor : '#ff50b3', | |||
}, | |||
], | |||
columns : [], | |||
back : '', | |||
}; | |||
}, | |||
computed: { | |||
...mapState(['cityList', 'userInfo']), | |||
}, | |||
onLoad({back}) { | |||
this.back = back | |||
// this.$nextTick(() => { | |||
// this.form.headImage = this.userInfo.headImage || this.form.headImage | |||
// this.form.nickName = this.userInfo.nickName || this.form.nickName | |||
// this.form.sex = this.userInfo.sex || this.form.sex | |||
// this.form.yearDate = this.userInfo.yearDate || this.form.yearDate | |||
// this.form.address = this.userInfo.address || this.form.address | |||
// }) | |||
}, | |||
onShow() { | |||
this.getCityList() | |||
this.getUserInfo() | |||
}, | |||
computed: {}, | |||
methods: { | |||
onChooseAvatar(res) { | |||
let self = this | |||
self.$Oss.ossUpload(res.target.avatarUrl) | |||
import { mapState } from 'vuex' | |||
import { mockUserInfo } from '@/static/js/mockUserInfo.js' | |||
import navbar from '@/components/base/navbar.vue' | |||
export default { | |||
components: { | |||
navbar | |||
}, | |||
data() { | |||
return { | |||
form: { | |||
headImage: '', | |||
nickName: '', | |||
phone: '' | |||
}, | |||
back: '', | |||
} | |||
}, | |||
computed: { | |||
...mapState(['userInfo']), | |||
}, | |||
onLoad({ back }) { | |||
this.back = back | |||
}, | |||
onShow() { | |||
this.getUserInfo() | |||
}, | |||
methods: { | |||
onChooseAvatar(res) { | |||
let self = this | |||
self.$Oss.ossUpload(res.detail.avatarUrl) | |||
.then(url => { | |||
self.form.headImage = url | |||
}) | |||
}, | |||
sexClick(item){ | |||
this.form.sex = item.value | |||
}, | |||
confirmAddress(e){ | |||
this.form.address = e.value[0].name | |||
}, | |||
// 获取城市 | |||
getCityList(){ | |||
this.$api('getCityList', res => { | |||
if(res.code == 200){ | |||
this.columns = [ | |||
res.result | |||
] | |||
} | |||
}, | |||
getUserInfo() { | |||
// 使用mock数据 | |||
this.form.headImage = mockUserInfo.avatarUrl || this.form.headImage | |||
this.form.nickName = mockUserInfo.nickName || this.form.nickName | |||
this.form.phone = '13800138000' // 模拟手机号 | |||
}, | |||
submit() { | |||
let self = this | |||
// 之所以手动获取dom的input值 而不是v-model 是为了保证跨平台安全生效 | |||
uni.createSelectorQuery().in(this) | |||
.select("#nickName") | |||
.fields({ | |||
properties: ["value"], | |||
}) | |||
}, | |||
getUserInfo(){ | |||
this.$api('getInfo', res => { | |||
if(res.code == 200){ | |||
this.form.headImage = res.result.headImage || this.form.headImage | |||
this.form.nickName = res.result.nickName || this.form.nickName | |||
this.form.sex = res.result.sex || this.form.sex | |||
this.form.yearDate = res.result.yearDate && | |||
this.$dayjs(res.result.yearDate + '-01-01').valueOf() || this.form.yearDate | |||
this.form.address = res.result.address || this.form.address | |||
.exec((res) => { | |||
const nickName = res?.[0]?.value | |||
self.form.nickName = nickName | |||
if (self.$utils.verificationAll(self.form, { | |||
headImage: '请选择头像', | |||
nickName: '请填写昵称', | |||
phone: '请填写手机号' | |||
})) { | |||
return | |||
} | |||
}) | |||
}, | |||
submit() { | |||
let self = this | |||
uni.createSelectorQuery().in(this) | |||
.select("#nickName") | |||
.fields({ | |||
properties: ["value"], | |||
}) | |||
.exec((res) => { | |||
const nickName = res?.[0]?.value | |||
self.form.nickName = nickName | |||
if (self.$utils.verificationAll(self.form, { | |||
headImage: '请选择头像', | |||
nickName: '请填写昵称', | |||
// address: '请选择居住地址', | |||
})) { | |||
return | |||
} | |||
let data = { | |||
...self.form, | |||
// yearDate : this.$dayjs(self.form.yearDate).format("YYYY") | |||
} | |||
self.$api('updateInfo', data, res => { | |||
if (res.code == 200) { | |||
uni.reLaunch({ | |||
url:'/pages/index/index' | |||
}) | |||
} | |||
if (!self.$utils.verificationPhone(self.form.phone)) { | |||
uni.showToast({ | |||
icon: 'none', | |||
title: '请填写正确的手机号' | |||
}) | |||
return | |||
} | |||
uni.showLoading({ | |||
title: '保存中...' | |||
}) | |||
}, | |||
setTimeout(() => { | |||
uni.hideLoading() | |||
uni.showToast({ | |||
title: '保存成功', | |||
icon: 'success' | |||
}) | |||
// 返回上一页 | |||
setTimeout(() => { | |||
this.$utils.navigateBack() | |||
}, 1500) | |||
}, 1000) | |||
}) | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.login { | |||
.profile-page { | |||
min-height: 100vh; | |||
background-color: #f5f5f5; | |||
} | |||
.nav-bar { | |||
height: 180rpx; | |||
background-color: #019245; | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
padding: 0 30rpx; | |||
padding-top: 60rpx; | |||
box-sizing: border-box; | |||
color: #fff; | |||
.back-btn { | |||
width: 60rpx; | |||
height: 60rpx; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
align-items: center; | |||
height: 100vh; | |||
background-color: #fff; | |||
overflow: hidden; | |||
.bg1{ | |||
width: 700rpx; | |||
height: 700rpx; | |||
border-radius: 50%; | |||
background-color: #ffc0b333; | |||
position: absolute; | |||
right: -300rpx; | |||
top: -300rpx; | |||
} | |||
.nav-title { | |||
font-size: 36rpx; | |||
font-weight: 500; | |||
} | |||
.right-actions { | |||
display: flex; | |||
align-items: center; | |||
.icon-divider { | |||
width: 2rpx; | |||
height: 30rpx; | |||
background-color: rgba(255, 255, 255, 0.5); | |||
margin: 0 20rpx; | |||
} | |||
} | |||
} | |||
.main-content { | |||
padding: 30rpx; | |||
} | |||
.section-title { | |||
display: flex; | |||
align-items: center; | |||
margin-bottom: 30rpx; | |||
.title-indicator { | |||
width: 8rpx; | |||
height: 32rpx; | |||
background-color: $uni-color; | |||
margin-right: 15rpx; | |||
border-radius: 4rpx; | |||
} | |||
text { | |||
font-size: 32rpx; | |||
font-weight: 500; | |||
color: #333; | |||
} | |||
} | |||
.title { | |||
line-height: 45rpx; | |||
font-weight: 900; | |||
padding-bottom: 100rpx; | |||
font-size: 40rpx; | |||
.avatar-section { | |||
display: flex; | |||
flex-direction: column; | |||
align-items: center; | |||
margin: 50rpx 0; | |||
.chooseAvatar { | |||
width: 180rpx; | |||
height: 180rpx; | |||
border-radius: 50%; | |||
overflow: hidden; | |||
padding: 0; | |||
margin: 0; | |||
background: none; | |||
&::after { | |||
border: none; | |||
} | |||
.chooseAvatar { | |||
.avatar-img { | |||
width: 100%; | |||
padding: 0 !important; | |||
margin: 0 !important; | |||
border: none; | |||
background-color: #fff !important; | |||
width: 220rpx; | |||
height: 220rpx; | |||
height: 100%; | |||
border-radius: 50%; | |||
image{ | |||
width: 200rpx; | |||
height: 200rpx; | |||
border-radius: 50%; | |||
box-shadow: 0 0 10rpx 10rpx #00000012; | |||
margin: 10rpx; | |||
} | |||
} | |||
.chooseAvatar::after{ | |||
border: none; | |||
padding: 0 !important; | |||
margin: 0 !important; | |||
} | |||
.nickname{ | |||
background-color: #f7f7f7; | |||
width: 600rpx; | |||
height: 80rpx; | |||
text-align: center; | |||
border-radius: 40rpx; | |||
margin-top: 30rpx; | |||
} | |||
.sexSelect{ | |||
background-color: #f7f7f7; | |||
width: 600rpx; | |||
height: 80rpx; | |||
text-align: center; | |||
border-radius: 40rpx; | |||
margin-top: 30rpx; | |||
display: flex; | |||
align-items: center; | |||
font-size: 26rpx; | |||
line-height: 80rpx; | |||
overflow: hidden; | |||
&>view{ | |||
flex: 1; | |||
display: flex; | |||
justify-content: center; | |||
align-content: center; | |||
height: 100%; | |||
} | |||
&>view:nth-child(1){ | |||
border-right: 1px solid #000; | |||
} | |||
} | |||
.avatar-hint { | |||
font-size: 26rpx; | |||
color: $uni-color-third; | |||
margin-top: 20rpx; | |||
} | |||
} | |||
.form-section { | |||
background-color: #fff; | |||
border-radius: 30rpx; | |||
overflow: hidden; | |||
margin-bottom: 60rpx; | |||
.form-item { | |||
display: flex; | |||
height: 100rpx; | |||
align-items: center; | |||
padding: 0 30rpx; | |||
border-bottom: 1rpx solid #f5f5f5; | |||
&:last-child { | |||
border-bottom: none; | |||
} | |||
.address{ | |||
background-color: #f7f7f7; | |||
width: 600rpx; | |||
height: 80rpx; | |||
text-align: center; | |||
border-radius: 40rpx; | |||
margin-top: 30rpx; | |||
line-height: 80rpx; | |||
color: #555; | |||
.label { | |||
width: 150rpx; | |||
font-size: 30rpx; | |||
color: $uni-color-third; | |||
} | |||
.btn { | |||
// background: $uni-linear-gradient-btn-color; | |||
background: $uni-color; | |||
color: #fff; | |||
width: 80%; | |||
padding: 20rpx 0; | |||
text-align: center; | |||
border-radius: 15rpx; | |||
margin-top: 10vh; | |||
.input { | |||
flex: 1; | |||
height: 100%; | |||
font-size: 30rpx; | |||
color: #666; | |||
} | |||
} | |||
} | |||
.save-button { | |||
width: 90%; | |||
margin: 160rpx auto 0; | |||
height: 100rpx; | |||
background-color: $uni-color; | |||
border-radius: 45rpx; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
color: #fff; | |||
font-size: 32rpx; | |||
box-shadow: 0 6rpx 20rpx rgba(1, 146, 69, 0.3); | |||
} | |||
</style> |
@ -0,0 +1,11 @@ | |||
export const mockUserInfo = { | |||
avatarUrl: "/static/image/中森明菜.webp", | |||
nickName: "李向西", | |||
userId: "123456", | |||
role: "团长", | |||
waitingPayCount: 2, | |||
waitingDiningCount: 0, | |||
deliveringCount: 3, | |||
pickupCount: 0, | |||
completedCount: 0 | |||
} |