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