upload project source code
This commit is contained in:
248
前端源码/uni-app/components/screens/ProfileUserInfo.vue
Normal file
248
前端源码/uni-app/components/screens/ProfileUserInfo.vue
Normal file
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<view class="userinfo-screen">
|
||||
<view class="userinfo-bg"></view>
|
||||
<view class="status-bar-placeholder"></view>
|
||||
|
||||
<view class="userinfo-header">
|
||||
<view class="userinfo-back-btn" @click="handleBack">
|
||||
<text class="userinfo-back-icon">‹</text>
|
||||
</view>
|
||||
<text class="userinfo-title">我的信息</text>
|
||||
<view class="userinfo-header-placeholder"></view>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-y class="userinfo-content">
|
||||
<view class="userinfo-inner">
|
||||
<view class="userinfo-section">
|
||||
<text class="userinfo-label">用户名</text>
|
||||
<input
|
||||
v-model="username"
|
||||
class="userinfo-input"
|
||||
type="text"
|
||||
maxlength="32"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</view>
|
||||
<view class="userinfo-section userinfo-section-mt">
|
||||
<text class="userinfo-label">手机号</text>
|
||||
<input
|
||||
v-model="mobile"
|
||||
class="userinfo-input"
|
||||
type="tel"
|
||||
maxlength="11"
|
||||
placeholder="请输入手机号"
|
||||
/>
|
||||
</view>
|
||||
<view class="userinfo-save" @click="handleSave">
|
||||
<text class="userinfo-save-text">{{ saving ? "保存中…" : "保存" }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { getUserInfo, setUserInfo } from "@/utils/auth";
|
||||
import { userApi } from "@/api";
|
||||
|
||||
declare const uni: any;
|
||||
|
||||
const emit = defineEmits<{
|
||||
back: [];
|
||||
}>();
|
||||
|
||||
const username = ref("");
|
||||
const mobile = ref("");
|
||||
const saving = ref(false);
|
||||
|
||||
const isValidPhone = (phone: string) => /^1[3-9]\d{9}$/.test(phone);
|
||||
|
||||
const loadFromStorage = () => {
|
||||
const info = getUserInfo();
|
||||
if (!info || typeof info !== "object") return;
|
||||
const u = info as Record<string, unknown>;
|
||||
username.value = String(
|
||||
u.username ?? u.name ?? ""
|
||||
).trim();
|
||||
mobile.value = String(u.mobile ?? u.phone ?? "").trim();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadFromStorage();
|
||||
});
|
||||
|
||||
const handleBack = () => {
|
||||
emit("back");
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
const name = username.value.trim();
|
||||
const tel = mobile.value.trim();
|
||||
if (!name) {
|
||||
uni.showToast({ title: "请输入用户名", icon: "none" });
|
||||
return;
|
||||
}
|
||||
if (!tel) {
|
||||
uni.showToast({ title: "请输入手机号", icon: "none" });
|
||||
return;
|
||||
}
|
||||
if (!isValidPhone(tel)) {
|
||||
uni.showToast({ title: "请输入正确的手机号", icon: "none" });
|
||||
return;
|
||||
}
|
||||
if (saving.value) return;
|
||||
saving.value = true;
|
||||
try {
|
||||
await userApi.updateCurrentUserUsernameMobile({
|
||||
username: name,
|
||||
mobile: tel,
|
||||
});
|
||||
|
||||
// 仅把表单结果合并进已有 userInfo,不把接口 data 整包写入,避免覆盖/清空头像、id 等字段
|
||||
const prev = getUserInfo();
|
||||
if (!prev || typeof prev !== "object") {
|
||||
uni.showToast({ title: "登录状态异常,请重新登录", icon: "none" });
|
||||
return;
|
||||
}
|
||||
setUserInfo({
|
||||
...prev,
|
||||
nickname: name,
|
||||
name: name,
|
||||
username: name,
|
||||
mobile: tel,
|
||||
phone: tel,
|
||||
});
|
||||
|
||||
uni.showToast({ title: "已保存", icon: "success" });
|
||||
} catch (e: any) {
|
||||
uni.showToast({
|
||||
title: e?.msg || e?.message || "保存失败,请稍后重试",
|
||||
icon: "none",
|
||||
});
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.userinfo-screen {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #f0efe9;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.status-bar-placeholder {
|
||||
height: var(--status-bar-height, 0);
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.userinfo-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
opacity: 0.3;
|
||||
background-image: url("https://www.transparenttextures.com/patterns/rice-paper.png");
|
||||
}
|
||||
|
||||
.userinfo-header {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
height: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 32rpx;
|
||||
border-bottom: 1rpx solid #dcd3c9;
|
||||
background-color: rgba(253, 251, 247, 0.8);
|
||||
backdrop-filter: blur(10rpx);
|
||||
}
|
||||
|
||||
.userinfo-back-btn {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: -16rpx;
|
||||
}
|
||||
|
||||
.userinfo-back-icon {
|
||||
font-size: 48rpx;
|
||||
color: #5a5a5a;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.userinfo-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #2c2c2c;
|
||||
letter-spacing: 0.2em;
|
||||
}
|
||||
|
||||
.userinfo-header-placeholder {
|
||||
width: 64rpx;
|
||||
}
|
||||
|
||||
.userinfo-content {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.userinfo-inner {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.userinfo-section {
|
||||
background-color: #fffdf9;
|
||||
border-radius: 24rpx;
|
||||
border: 1rpx solid #e5e5e5;
|
||||
padding: 24rpx 32rpx;
|
||||
}
|
||||
|
||||
.userinfo-section-mt {
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.userinfo-label {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #888;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.userinfo-input {
|
||||
width: 100%;
|
||||
font-size: 30rpx;
|
||||
color: #2c2c2c;
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.userinfo-save {
|
||||
margin-top: 48rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
background: linear-gradient(135deg, #8b7355, #6b5344);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.userinfo-save-text {
|
||||
font-size: 30rpx;
|
||||
color: #fffdf9;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.15em;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user