diff --git a/go/controllers/app_auth.go b/go/controllers/app_auth.go index 18520e1..4d66457 100644 --- a/go/controllers/app_auth.go +++ b/go/controllers/app_auth.go @@ -130,6 +130,67 @@ func (c *AppAuthController) GetCurrentUser() { }) } +// UpdateCurrentUserProfile 修改当前用户资料(姓名 / 邮箱)。 +// 手机号由微信验证并作为登录账号,不开放修改;同步统一身份与当前企业绑定表, +// 避免下次登录或切换企业后又读到旧的姓名。 +func (c *AppAuthController) UpdateCurrentUserProfile() { + claims, err := identity.Claims(c.Ctx.Request.Header.Get("Authorization"), identity.EndBackend, identity.EndApp) + if err != nil { + code := identity.Status(err) + c.serveJSON(map[string]interface{}{"code": code, "msg": err.Error()}) + return + } + var req struct { + Name string `json:"name"` + Email string `json:"email"` + } + body := c.Ctx.Input.RequestBody + if len(body) == 0 { + body, _ = io.ReadAll(c.Ctx.Request.Body) + } + if err := json.Unmarshal(body, &req); err != nil { + c.serveJSON(map[string]interface{}{"code": 400, "msg": "参数错误"}) + return + } + name := strings.TrimSpace(req.Name) + email := strings.TrimSpace(req.Email) + if name == "" { + c.serveJSON(map[string]interface{}{"code": 400, "msg": "请填写姓名"}) + return + } + if len([]rune(name)) > 30 { + c.serveJSON(map[string]interface{}{"code": 400, "msg": "姓名不能超过 30 个字符"}) + return + } + if email != "" && (!strings.Contains(email, "@") || len(email) > 128) { + c.serveJSON(map[string]interface{}{"code": 400, "msg": "邮箱格式不正确"}) + return + } + + uid := services.ResolveTenantUID(uint64(claims.TenantId), uint64(claims.UserID)) + num, err := models.Orm.QueryTable(new(models.SystemTenantUser)). + Filter("uid", uid). + Filter("tid", claims.TenantId). + Update(map[string]interface{}{"name": name, "email": email}) + if err != nil || num == 0 { + c.serveJSON(map[string]interface{}{"code": 400, "msg": "未找到当前企业下的用户资料"}) + return + } + _, _ = models.Orm.QueryTable(new(models.AuthIdentity)). + Filter("id", uint64(claims.UserID)). + Update(map[string]interface{}{"nickname": name, "email": email}) + _, _ = models.Orm.QueryTable(new(models.AuthTenantUser)). + Filter("identity_id", uint64(claims.UserID)). + Filter("tid", claims.TenantId). + Update(map[string]interface{}{"name": name, "email": email}) + + c.serveJSON(map[string]interface{}{ + "code": 200, + "msg": "资料已更新", + "data": map[string]interface{}{"name": name, "email": email}, + }) +} + // SendLoginCode 发送App端登录验证码 func (c *AppAuthController) SendLoginCode() { var req struct { diff --git a/go/routers/api/api.go b/go/routers/api/api.go index c165da9..d7a2ff5 100644 --- a/go/routers/api/api.go +++ b/go/routers/api/api.go @@ -54,6 +54,8 @@ func Register() { // 当前用户信息 beego.Router("/api/currentUser", &controllers.AppAuthController{}, "get:GetCurrentUser") + // 修改当前用户资料(姓名 / 邮箱;手机号由微信验证,不开放修改) + beego.Router("/api/currentUser/profile", &controllers.AppAuthController{}, "post:UpdateCurrentUserProfile") // 极验与登录验证配置 beego.Router("/api/login/getGeetest3Infos", &controllers.AppAuthController{}, "get:GetGeetest3Infos") diff --git a/uniapp/api/auth.js b/uniapp/api/auth.js index 51d85a9..01c4782 100644 --- a/uniapp/api/auth.js +++ b/uniapp/api/auth.js @@ -208,6 +208,16 @@ export function getCurrentUser() { }) } +/** 修改当前用户资料:{ name, email };手机号由微信验证,只读不传 */ +export function updateCurrentUserProfile(data) { + return request({ + url: '/api/currentUser/profile', + method: 'POST', + data, + silent: true + }) +} + /** 是否开启登录人机/验证码校验 */ export function getOpenVerify() { return request({ diff --git a/uniapp/components/AppTabbar.vue b/uniapp/components/AppTabbar.vue index 41cc026..5b29f0c 100644 --- a/uniapp/components/AppTabbar.vue +++ b/uniapp/components/AppTabbar.vue @@ -56,12 +56,19 @@ const DEFAULT_TABS = [ { name: 'home', text: '概览', icon: 'gauge' }, { name: 'functions', text: '功能', icon: 'table-cells' }, { name: 'todo', text: '待办', icon: 'circle-check' }, - { name: 'mine', text: '我的', icon: 'user' } + // 末位不再是「我的」,而是回平台(模块选择页);name 保留 mine 以兼容 current="mine" + { name: 'mine', text: '回平台', icon: 'arrow-left' } ] const list = computed(() => (props.tabs && props.tabs.length ? props.tabs : DEFAULT_TABS)) function onTap(name) { + // 「回平台」:清空页面栈回到模块选择页。必须放在 current 判重之前, + // 否则停在原「我的」页时点击会被判重拦下。 + if (name === 'mine' || name === 'platform') { + uni.reLaunch({ url: '/pages/nav/nav' }) + return + } if (name === props.current) return if (props.variant === 'switch') { emit('change', name) diff --git a/uniapp/pages/nav/nav.vue b/uniapp/pages/nav/nav.vue index f9eaff9..5cfed31 100644 --- a/uniapp/pages/nav/nav.vue +++ b/uniapp/pages/nav/nav.vue @@ -7,8 +7,8 @@ WENXIN WORKSPACE 工作台 - {{ user.account || '我的账号' }} - 游客 + {{ user.account || '我的账号' }} + 游客 @@ -471,6 +471,15 @@ async function load(force = false) { /* ==================== 交互 ==================== */ +/** 点击右上角用户名 → 进入个人中心修改资料;未授权时提示先点模块授权手机号 */ +function goProfile() { + if (guest.value) { + uni.showToast({ title: '请先点击模块授权手机号', icon: 'none' }) + return + } + uni.navigateTo({ url: '/pages/profile/profile' }) +} + function chooseTenant() { const list = tenants.value if (list.length <= 1) { uni.showToast({ title: list.length ? '当前账号仅绑定一个企业' : '暂无可切换的企业', icon: 'none' }) diff --git a/uniapp/pages/profile/profile.vue b/uniapp/pages/profile/profile.vue index 78eddb7..6392fd8 100644 --- a/uniapp/pages/profile/profile.vue +++ b/uniapp/pages/profile/profile.vue @@ -1,6 +1,12 @@