设置页面更新,修改用户名,用户信息获取
This commit is contained in:
parent
86752408b8
commit
985a261c6f
3
acdr-ui/.vscode/settings.json
vendored
3
acdr-ui/.vscode/settings.json
vendored
@ -61,5 +61,6 @@
|
||||
".eslintrc.cjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,.stylelintrc.*,.eslintrc-auto-import.json,.editorconfig,.commitlint.cjs",
|
||||
"vite.config.ts": "tsconfig.*.json,uno.config.ts,tsconfig.json,uni-pages.d.ts",
|
||||
"manifest.config.ts": "manifest.config.ts,pages.config.ts"
|
||||
}
|
||||
},
|
||||
"vue3snippets.enable-compile-vue-file-on-did-save-code": true
|
||||
}
|
||||
|
36
acdr-ui/src/components/AddressCell.vue
Normal file
36
acdr-ui/src/components/AddressCell.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<view
|
||||
class="pos-fixed z-999 left-[20px] top-[10px] flex gap-[10px] items-center content-center justify-center"
|
||||
>
|
||||
<image src="/static/addresscell/location.png" class="w-[30px]" mode="widthFix" />
|
||||
<view>
|
||||
{{
|
||||
!addressDetail.addressComponent
|
||||
? '正在加载...'
|
||||
: `${addressDetail.addressComponent.city} ${addressDetail.addressComponent.district}`
|
||||
}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="js" setup>
|
||||
import { getLocation, getMapDetailAddress } from '@/service/mapService'
|
||||
|
||||
const addressDetail = ref({})
|
||||
// 获取地址详细信息
|
||||
const getLocationDetail = async () => {
|
||||
try {
|
||||
const loction = await getLocation()
|
||||
const res = await getMapDetailAddress(loction.longitude, loction.latitude)
|
||||
addressDetail.value = res
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(async () => {
|
||||
await getLocationDetail()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -299,10 +299,7 @@
|
||||
{
|
||||
"path": "pages/settings/index",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationBarTitleText": "设置页面"
|
||||
},
|
||||
"needLogin": true
|
||||
"style": {}
|
||||
},
|
||||
{
|
||||
"path": "pages/space/index",
|
||||
|
@ -10,6 +10,7 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<Banner />
|
||||
<AddressCell />
|
||||
<loading-animation v-model="isLoading" />
|
||||
<view class="index">
|
||||
<view
|
||||
@ -75,37 +76,35 @@ import QuickServiceCarousel from './components/quickServiceCarousel.vue'
|
||||
import RecommendedServices from './components/recommendedServices.vue'
|
||||
import Banner from './components/banner.vue'
|
||||
import LoadingAnimation from '@/components/LoadingAnimation.vue'
|
||||
import { imgUrl } from '@/utils/commUtils'
|
||||
import { imgUrl, toast } from '@/utils/commUtils'
|
||||
import { httpGet } from '@/utils/http'
|
||||
import Tabbar from '@/components/Tabbar.vue'
|
||||
import AddressCell from '@/components/AddressCell.vue'
|
||||
|
||||
const isLoading = ref(false)
|
||||
const petInfo = ref({})
|
||||
|
||||
// // 暂停两秒
|
||||
// setTimeout(() => {
|
||||
// isLoading.value = false
|
||||
// }, 2000)
|
||||
|
||||
const toExtended = () => {
|
||||
// 跳转到extended 页面
|
||||
uni.navigateTo({
|
||||
url: '/pages/extended/index',
|
||||
})
|
||||
}
|
||||
|
||||
// 获取当前页面的宠物信息
|
||||
const getPetInfo = async () => {
|
||||
try {
|
||||
const res = await httpGet('/petInfo/index')
|
||||
if (res.code === 200) {
|
||||
petInfo.value = res.data
|
||||
} else {
|
||||
toast(res.message)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
const toExtended = () => {
|
||||
// 跳转到extended 页面
|
||||
uni.navigateTo({
|
||||
url: '/pages/extended/index',
|
||||
})
|
||||
}
|
||||
|
||||
const toPath = (path) => {
|
||||
uni.navigateTo({
|
||||
url: path,
|
||||
@ -113,7 +112,9 @@ const toPath = (path) => {
|
||||
}
|
||||
|
||||
onLoad(async () => {
|
||||
isLoading.value = true
|
||||
await getPetInfo()
|
||||
isLoading.value = false
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -1,12 +1,3 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
style: {
|
||||
navigationBarTitleText: '设置页面',
|
||||
},
|
||||
needLogin: true,
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="setting-root bg-[#F5F5F5] h-full p-5">
|
||||
<!-- 国际化设置 -->
|
||||
@ -22,37 +13,64 @@
|
||||
|
||||
<!-- 账户设置 -->
|
||||
<view class="card mb-4 p-4 bg-white rounded-lg shadow">
|
||||
<view class="text-gray-800 text-lg mb-2">账户设置</view>
|
||||
<view class="wd-cell" @click="showUserNamePopup = true">
|
||||
<text class="text-gray-800">账户名称</text>
|
||||
<text class="text-gray-400 ml-auto">{{ sinfo.userName }}</text>
|
||||
<wd-icon name="right" size="16" class="ml-2"></wd-icon>
|
||||
</view>
|
||||
<view class="wd-cell" @click="goToBindPhone">
|
||||
<text class="text-gray-800">手机号绑定</text>
|
||||
<text class="text-gray-400 ml-auto">191****0915</text>
|
||||
<text class="text-gray-400 ml-auto">{{ sinfo.phone }}</text>
|
||||
<wd-icon name="right" size="16" class="ml-2"></wd-icon>
|
||||
</view>
|
||||
<view class="wd-cell" @click="goToRealNameAuth">
|
||||
<view class="wd-cell" @click="!sinfo.isAuth ? goToRealNameAuth() : toast('你已经实名了')">
|
||||
<text class="text-gray-800">实名认证</text>
|
||||
<text class="text-gray-400 ml-auto">已实名</text>
|
||||
<text v-if="sinfo.isAuth" class="text-gray-400 ml-auto">已实名</text>
|
||||
<text v-else class="text-gray-400 ml-auto">未实名</text>
|
||||
<wd-icon name="right" size="16" class="ml-2"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 修改用户名的弹窗 -->
|
||||
<wd-popup v-model="showUserNamePopup" position="center" custom-style="padding: 20px;">
|
||||
<view class="flex flex-col gap-3">
|
||||
<view class="text-gray-800 mb-4">修改用户名</view>
|
||||
<input v-model="newUserName" type="text" placeholder="请输入新的用户名" />
|
||||
<view class="btn-group mt-4">
|
||||
<button class="confirm-btn" @click="updateUserName">确认</button>
|
||||
<button class="cancel-btn" @click="showUserNamePopup = false">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
|
||||
<!-- 退出登录按钮 -->
|
||||
<view class="card mb-4 p-4 bg-white rounded-lg shadow">
|
||||
<button class="logout-button" @click="logout">退出登录</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<LoadingAnimation v-model="loading" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup lang="js">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useConfigStore } from '../../store/config'
|
||||
import { useConfigStore } from '@/store/config'
|
||||
import { useUserStore } from '@/store'
|
||||
import { httpGet } from '@/utils/http'
|
||||
import { httpPost, httpGet } from '@/utils/http'
|
||||
import LoadingAnimation from '@/components/LoadingAnimation.vue'
|
||||
import { toast } from '@/utils/commUtils'
|
||||
|
||||
const configStore = useConfigStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const languages = configStore.languages
|
||||
const selectedLanguage = ref<string>(languages['zh-Hans'])
|
||||
const selectedLanguage = ref(languages['zh-Hans'])
|
||||
|
||||
const sinfo = ref({})
|
||||
const showUserNamePopup = ref(false)
|
||||
const newUserName = ref('')
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
const languageOptions = computed(() =>
|
||||
Object.entries(languages).map(([key, value]) => ({
|
||||
@ -77,21 +95,54 @@ const goToBindPhone = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 获取页面信息
|
||||
const getSettingInfo = async () => {
|
||||
const settingInfo = await httpGet('/setting/info')
|
||||
try {
|
||||
if (settingInfo.code === 200) {
|
||||
sinfo.value = settingInfo.data
|
||||
} else {
|
||||
toast(settingInfo.message)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
// 修改用户名的请求
|
||||
const updateUserName = async () => {
|
||||
if (!newUserName.value) {
|
||||
toast('用户名不能为空')
|
||||
return
|
||||
}
|
||||
const response = await httpPost('/setting/updateUserName', {}, { userName: newUserName.value })
|
||||
if (response.code === 200) {
|
||||
sinfo.value.userName = newUserName.value
|
||||
toast('用户名修改成功')
|
||||
showUserNamePopup.value = false
|
||||
} else {
|
||||
toast(response.message)
|
||||
}
|
||||
}
|
||||
|
||||
const logout = async () => {
|
||||
// 发送后台请求
|
||||
const logRes = await httpGet('/user/logout')
|
||||
if (logRes.code == 200) {
|
||||
uni.showToast({ title: '退出成功', icon: 'none' })
|
||||
} else {
|
||||
uni.showToast({ title: logRes.msg, icon: 'none' })
|
||||
}
|
||||
// 清除用户信息
|
||||
userStore.clearUserInfo()
|
||||
// 跳转到登录页面
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/index',
|
||||
})
|
||||
}
|
||||
|
||||
onLoad(async () => {
|
||||
loading.value = true
|
||||
await getSettingInfo()
|
||||
loading.value = false
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -123,4 +174,23 @@ const logout = async () => {
|
||||
.logout-button {
|
||||
@apply w-full py-3 bg-red-500 text-white text-lg rounded;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
background-color: #4caf50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background-color: #f44336;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
BIN
acdr-ui/src/static/addresscell/location.png
Normal file
BIN
acdr-ui/src/static/addresscell/location.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1,62 @@
|
||||
package com.yskj.acdr.common.verify;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Getter
|
||||
@Component
|
||||
public class UserNameValidator {
|
||||
|
||||
private String errorString = "用户名不合法";
|
||||
|
||||
// 非法词语列表
|
||||
private final String[] ILLEGAL_WORDS = {"admin", "root", "illegal"};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return errorString;
|
||||
}
|
||||
|
||||
public boolean valid(String userName) {
|
||||
// 用户名不能为空
|
||||
if (StrUtil.isBlank(userName)) {
|
||||
errorString = "用户名不能为空";
|
||||
System.out.println(errorString);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 用户名长度不能大于6
|
||||
if (userName.length() > 6) {
|
||||
errorString = "用户名长度大于6";
|
||||
System.out.println(errorString);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 用户名不能以特殊字符开头(仅允许字母或数字开头)
|
||||
if (!Character.isLetterOrDigit(userName.charAt(0))) {
|
||||
errorString = "用户名不能以特殊字符开头";
|
||||
System.out.println(errorString);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 用户名不能全是数字
|
||||
if (userName.matches("\\d+")) {
|
||||
errorString = "用户名不能全是数字";
|
||||
System.out.println(errorString);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 用户名不能包含违法词语
|
||||
for (String word : ILLEGAL_WORDS) {
|
||||
if (userName.toLowerCase().contains(word)) {
|
||||
errorString = "用户名包含违法词语: " + word;
|
||||
System.out.println(errorString);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 所有条件都符合,验证通过
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.yskj.acdr.master.setting.controller;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yskj.acdr.common.cache.GlobalRedisCache;
|
||||
import com.yskj.acdr.common.response.GlobalResponse;
|
||||
import com.yskj.acdr.common.verify.UserNameValidator;
|
||||
import com.yskj.acdr.master.setting.entity.AccountInfo;
|
||||
import com.yskj.acdr.master.user.entity.Users;
|
||||
import com.yskj.acdr.master.user.service.AuthenticationService;
|
||||
import com.yskj.acdr.master.user.service.UsersService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RequestMapping("/setting")
|
||||
@RestController
|
||||
public class SettingController {
|
||||
|
||||
@Resource
|
||||
private UsersService usersService;
|
||||
|
||||
@Resource
|
||||
private AuthenticationService authService;
|
||||
|
||||
@Resource
|
||||
private GlobalRedisCache<String> redisCache;
|
||||
|
||||
@Resource
|
||||
private UserNameValidator userValid;
|
||||
|
||||
/**
|
||||
* 获取账户信息
|
||||
* @return 账户信息类
|
||||
*/
|
||||
@GetMapping("/info")
|
||||
public GlobalResponse<AccountInfo> info() {
|
||||
Users users = usersService.getById(StpUtil.getLoginIdAsLong());
|
||||
return GlobalResponse.success(
|
||||
new AccountInfo().setIsAuth(authService.isRealName())
|
||||
.setPhone(users.getPhone())
|
||||
.setUserName(users.getNickname())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改手机号
|
||||
*/
|
||||
@PostMapping("/updatePhone")
|
||||
@Transactional
|
||||
public GlobalResponse<Boolean> updatePhone(String code,String newPhone) {
|
||||
// 验证验证码
|
||||
String cachedCode = redisCache.get(newPhone);
|
||||
if (cachedCode == null || !cachedCode.equals(code)) {
|
||||
return GlobalResponse.failure("验证码错误或已过期");
|
||||
}
|
||||
// 更新用户手机号
|
||||
Users users = usersService.getById(StpUtil.getLoginIdAsLong());
|
||||
users.setPhone(newPhone);
|
||||
return GlobalResponse.success(usersService.updateById(users));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户名称
|
||||
*/
|
||||
@PostMapping("/updateUserName")
|
||||
@Transactional
|
||||
public GlobalResponse<Boolean> updateUserName(String userName) {
|
||||
// 这里添加验证信息
|
||||
if (!userValid.valid(userName)) {
|
||||
return GlobalResponse.failure("用户名不合理,%s,请重新输入!".formatted(userValid.getErrorString()));
|
||||
}
|
||||
// 更新用户手机号
|
||||
Users users = usersService.getById(StpUtil.getLoginIdAsLong());
|
||||
users.setNickname(userName);
|
||||
return GlobalResponse.success(usersService.updateById(users));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.yskj.acdr.master.setting.entity;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@ApiModel(value = "AccountInfo", description = "账户信息类")
|
||||
public class AccountInfo {
|
||||
|
||||
// 手机号信息
|
||||
private String phone;
|
||||
|
||||
// 用户名信息
|
||||
private String userName;
|
||||
|
||||
// 是否实名认证
|
||||
private Boolean isAuth;
|
||||
|
||||
}
|
@ -17,6 +17,7 @@ import com.yskj.acdr.master.user.service.UsersService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yskj.acdr.utils.MutualHttpUtil;
|
||||
import com.yskj.acdr.utils.ProfileUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -56,7 +57,7 @@ public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements
|
||||
@Value("${profiles:active}")
|
||||
private String debug;
|
||||
|
||||
@Autowired
|
||||
@Resource
|
||||
private GlobalRedisCache<String> redisCache;
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user