| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- <template>
- <view class="settings-root">
- <erp-nav-bar title="个人资料设置" />
- <!-- 资料列表 -->
- <view class="settings-list" :style="{ marginTop: '10px' }">
- <view class="item-row avatar-row" @click="doChooseImage">
- <text class="item-label">头像</text>
- <view class="item-right">
- <view class="avatar-wrapper">
- <image class="avatar-img" :src="myInfo.avatarUrl || 'https://img.icons8.com/color/144/user.png'"
- mode="aspectFill"></image>
- <view class="avatar-uploading" v-if="uploading">
- <text class="uploading-text">上传中...</text>
- </view>
- </view>
- <text class="icon-more"></text>
- </view>
- </view>
- <view class="item-row" @click="doEditName">
- <text class="item-label">用户昵称</text>
- <view class="item-right">
- <text class="item-value">{{ myInfo.userName }}</text>
- <text class="icon-more"></text>
- </view>
- </view>
- </view>
- <view class="settings-list mt-30">
- <view class="item-row no-tap">
- <text class="item-label">手机号码</text>
- <view class="item-right">
- <text class="item-value readonly">{{ myInfo.phone }}</text>
- </view>
- </view>
- <view class="item-row no-tap">
- <text class="item-label">授权客户</text>
- <view class="item-right">
- <text class="item-value readonly">{{ myInfo.authClientName || myInfo.authClientFRowID || '无' }}</text>
- </view>
- </view>
- </view>
- <view class="footer-bar">
- <button class="btn-confirm" @click="saveProfile" :disabled="uploading">确认保存</button>
- </view>
- </view>
- </template>
- <script>
- import ErpNavBar from '@/components/erp-nav-bar.vue';
- import { getMyInfo, updateMyInfo } from '@/api/system/customer.js';
- import { uploadFile } from '@/api/resource/oss.js';
- export default {
- components: { ErpNavBar },
- data() {
- return {
- uploading: false,
- pendingAvatarOssId: null,
- myInfo: {
- avatarUrl: '',
- userName: '',
- phone: '',
- avatar: null,
- authClientFRowID: '',
- authClientName: ''
- }
- }
- },
- async onLoad() {
- await this.loadInfo();
- },
- methods: {
- async loadInfo() {
- try {
- uni.showLoading({ title: '加载中' });
- const res = await getMyInfo();
- uni.hideLoading();
- const d = res.data;
- this.myInfo = {
- avatarUrl: d.avatarUrl || '',
- userName: d.userName || '',
- phone: d.phone || '',
- avatar: d.avatar || null,
- authClientFRowID: d.authClientFRowID || '',
- authClientName: d.authClientName || ''
- };
- this.pendingAvatarOssId = null;
- } catch (e) {
- uni.hideLoading();
- uni.showToast({ title: '加载失败', icon: 'none' });
- }
- },
- doChooseImage() {
- uni.chooseImage({
- count: 1,
- sizeType: ['compressed'],
- sourceType: ['album', 'camera'],
- success: async (res) => {
- const tempPath = res.tempFilePaths[0];
- this.myInfo.avatarUrl = tempPath;
- this.uploading = true;
- try {
- const uploadRes = await uploadFile(tempPath);
- this.pendingAvatarOssId = uploadRes.ossId;
- uni.showToast({ title: '头像上传成功', icon: 'success' });
- } catch (e) {
- uni.showToast({ title: '头像上传失败', icon: 'none' });
- this.myInfo.avatarUrl = '';
- } finally {
- this.uploading = false;
- }
- }
- });
- },
- doEditName() {
- uni.showModal({
- title: '设置昵称',
- content: this.myInfo.userName,
- editable: true,
- confirmColor: '#C1001C',
- success: (res) => {
- if (res.confirm) {
- this.myInfo.userName = res.content || this.myInfo.userName;
- }
- }
- });
- },
- saveProfile() {
- if (this.uploading) return;
- uni.showModal({
- title: '确认保存',
- content: `昵称:${this.myInfo.userName}\n手机:${this.myInfo.phone}\n请确认以上信息是否填写正确?`,
- confirmText: '确认',
- cancelText: '取消',
- confirmColor: '#C1001C',
- success: async (res) => {
- if (!res.confirm) return;
- try {
- uni.showLoading({ title: '保存中' });
- const payload = { userName: this.myInfo.userName };
- if (this.pendingAvatarOssId !== null) {
- payload.avatar = this.pendingAvatarOssId;
- }
- await updateMyInfo(payload);
- uni.hideLoading();
- uni.showToast({ title: '保存成功', icon: 'success' });
- setTimeout(() => { uni.navigateBack(); }, 1200);
- } catch (e) {
- uni.hideLoading();
- uni.showToast({ title: e.message || '保存失败', icon: 'none' });
- }
- }
- });
- }
- }
- }
- </script>
- <style scoped>
- .settings-root {
- width: 100vw;
- height: 100vh;
- background: #f8fafb;
- display: flex;
- flex-direction: column;
- }
- .settings-list {
- background: #fff;
- padding: 0 40rpx;
- }
- .mt-30 {
- margin-top: 30rpx;
- }
- .item-row {
- display: flex;
- justify-content: space-between;
- align-items: center;
- min-height: 110rpx;
- border-bottom: 2rpx solid #f9f9f9;
- }
- .item-row:last-child {
- border-bottom: none;
- }
- .avatar-row {
- height: 180rpx;
- }
- .item-label {
- font-size: 32rpx;
- color: #333;
- }
- .item-right {
- display: flex;
- align-items: center;
- }
- .avatar-wrapper {
- position: relative;
- width: 110rpx;
- height: 110rpx;
- margin-right: 20rpx;
- }
- .avatar-img {
- width: 110rpx;
- height: 110rpx;
- border-radius: 50%;
- background: #eee;
- }
- .avatar-uploading {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- border-radius: 50%;
- background: rgba(0, 0, 0, 0.45);
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .uploading-text {
- font-size: 20rpx;
- color: #fff;
- }
- .item-value {
- font-size: 30rpx;
- color: #666;
- margin-right: 15rpx;
- }
- .item-value.readonly {
- color: #aaa;
- margin-right: 0;
- }
- .icon-more {
- width: 14rpx;
- height: 14rpx;
- border-top: 3rpx solid #ccc;
- border-right: 3rpx solid #ccc;
- transform: rotate(45deg);
- }
- .footer-bar {
- padding: 40rpx;
- margin-top: auto;
- padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
- }
- .btn-confirm {
- width: 100%;
- height: 90rpx;
- background: #C1001C;
- color: #fff;
- border-radius: 45rpx;
- font-size: 32rpx;
- font-weight: bold;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- </style>
|