添加用户数据更新接口和侧边栏部分内容

This commit is contained in:
柏码の讲师 2025-01-02 18:11:42 +08:00
parent cd54961b33
commit 0375eaad2c
8 changed files with 146 additions and 8 deletions

View File

@ -80,7 +80,7 @@
<dependency> <dependency>
<groupId>com.alibaba.fastjson2</groupId> <groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId> <artifactId>fastjson2</artifactId>
<version>2.0.25</version> <version>2.0.53</version>
</dependency> </dependency>
<!-- Jwt令牌生成校验框架 --> <!-- Jwt令牌生成校验框架 -->
<dependency> <dependency>

View File

@ -1,6 +1,5 @@
package com.example.config; package com.example.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;

View File

@ -3,12 +3,16 @@ package com.example.controller.admin;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.RestBean; import com.example.entity.RestBean;
import com.example.entity.dto.Account;
import com.example.entity.dto.AccountDetails;
import com.example.entity.dto.AccountPrivacy;
import com.example.entity.vo.response.AccountVO; import com.example.entity.vo.response.AccountVO;
import com.example.service.AccountDetailsService;
import com.example.service.AccountPrivacyService;
import com.example.service.AccountService; import com.example.service.AccountService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
@ -19,6 +23,12 @@ public class AccountAdminController {
@Resource @Resource
AccountService service; AccountService service;
@Resource
AccountDetailsService detailsService;
@Resource
AccountPrivacyService privacyService;
@GetMapping("/list") @GetMapping("/list")
public RestBean<JSONObject> accountList(int page, int size) { public RestBean<JSONObject> accountList(int page, int size) {
JSONObject object = new JSONObject(); JSONObject object = new JSONObject();
@ -31,4 +41,29 @@ public class AccountAdminController {
object.put("list", list); object.put("list", list);
return RestBean.success(object); return RestBean.success(object);
} }
@GetMapping("/detail")
public RestBean<JSONObject> accountDetail(int id) {
JSONObject object = new JSONObject();
object.put("detail", detailsService.findAccountDetailsById(id));
object.put("privacy", privacyService.accountPrivacy(id));
return RestBean.success(object);
}
@PostMapping("/save")
public RestBean<Void> saveAccount(@RequestBody JSONObject object) {
int id = object.getInteger("id");
Account account = service.findAccountById(id);
Account save = object.toJavaObject(Account.class);
BeanUtils.copyProperties(save, account, "password", "registerTime");
service.saveOrUpdate(account);
AccountDetails details = detailsService.findAccountDetailsById(id);
AccountDetails saveDetails = object.getJSONObject("detail").toJavaObject(AccountDetails.class);
BeanUtils.copyProperties(saveDetails, details);
detailsService.saveOrUpdate(details);
AccountPrivacy privacy = privacyService.accountPrivacy(id);
AccountPrivacy savePrivacy = object.getJSONObject("privacy").toJavaObject(AccountPrivacy.class);
BeanUtils.copyProperties(savePrivacy, privacy);
return RestBean.success();
}
} }

View File

@ -24,4 +24,6 @@ public class Account implements BaseData {
String role; String role;
String avatar; String avatar;
Date registerTime; Date registerTime;
boolean mute;
boolean banned;
} }

View File

@ -12,4 +12,6 @@ public class AccountVO {
String role; String role;
String avatar; String avatar;
Date registerTime; Date registerTime;
boolean mute;
boolean banned;
} }

View File

@ -109,7 +109,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
if(this.existsAccountByUsername(username)) return "该用户名已被他人使用,请重新更换"; if(this.existsAccountByUsername(username)) return "该用户名已被他人使用,请重新更换";
String password = passwordEncoder.encode(info.getPassword()); String password = passwordEncoder.encode(info.getPassword());
Account account = new Account(null, info.getUsername(), Account account = new Account(null, info.getUsername(),
password, email, Const.ROLE_DEFAULT, null, new Date()); password, email, Const.ROLE_DEFAULT, null, new Date(), false, false);
if(!this.save(account)) { if(!this.save(account)) {
return "内部错误,注册失败"; return "内部错误,注册失败";
} else { } else {

View File

@ -32,3 +32,9 @@ export const apiUserDetail = (success) =>
export const apiUserList = (page, size, success) => export const apiUserList = (page, size, success) =>
get(`/api/admin/user/list?page=${page}&size=${size}`, success) get(`/api/admin/user/list?page=${page}&size=${size}`, success)
export const apiUserDetailTotal = (id, success) =>
get(`api/admin/user/detail?id=${id}`, success)
export const apiUserSave = (data, success) =>
post('/api/admin/user/save', data, success)

View File

@ -1,8 +1,9 @@
<script setup> <script setup>
import {User} from "@element-plus/icons-vue"; import {EditPen, User} from "@element-plus/icons-vue";
import {apiUserList} from "@/net/api/user"; import {apiUserDetailTotal, apiUserList, apiUserSave} from "@/net/api/user";
import {reactive, watchEffect} from "vue"; import {reactive, watchEffect} from "vue";
import {useStore} from "@/store"; import {useStore} from "@/store";
import {ElMessage} from "element-plus";
const store = useStore() const store = useStore()
@ -13,6 +14,43 @@ const userTable = reactive({
data: [] data: []
}) })
const editor = reactive({
id: 0,
display: false,
temp: {},
loading: false,
})
function loadUserEditor(user) {
editor.id = user.id
editor.display = true
editor.loading = true
apiUserDetailTotal(editor.id, data => {
editor.temp = { ...data, ...user }
editor.loading = false
})
}
function userStatus(user) {
if(user.mute && user.banned)
return '禁言中、封禁中'
else if(user.mute)
return '禁言中'
else if(user.banned)
return '封禁中'
else
return '正常'
}
function saveUserSettings() {
editor.display = false
apiUserSave(editor.temp, () => {
const user = userTable.data.find(user => user.id === editor.id)
Object.assign(user, editor.temp)
ElMessage.success('数据保存成功')
})
}
watchEffect(() => apiUserList(userTable.page, userTable.size, data => { watchEffect(() => apiUserList(userTable.page, userTable.size, data => {
userTable.total = data.total userTable.total = data.total
userTable.data = data.list userTable.data = data.list
@ -48,6 +86,18 @@ watchEffect(() => apiUserList(userTable.page, userTable.size, data => {
{{ new Date(row.registerTime).toLocaleString() }} {{ new Date(row.registerTime).toLocaleString() }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" width="100" align="center">
<template #default="{ row }">
<div>{{ userStatus(row) }}</div>
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center">
<template #default="{ row }">
<el-button size="small" type="primary" :icon="EditPen"
@click="loadUserEditor(row)"
:disabled="store.user.id === row.id">编辑</el-button>
</template>
</el-table-column>
</el-table> </el-table>
<div style="margin-top: 20px;display: flex;justify-content: right"> <div style="margin-top: 20px;display: flex;justify-content: right">
<el-pagination style="width: fit-content" <el-pagination style="width: fit-content"
@ -56,6 +106,46 @@ watchEffect(() => apiUserList(userTable.page, userTable.size, data => {
v-model:page-size="userTable.size" v-model:page-size="userTable.size"
layout="total, sizes, prev, pager, next, jumper"/> layout="total, sizes, prev, pager, next, jumper"/>
</div> </div>
<el-drawer v-model="editor.display" size="380" :close-on-click-modal="false">
<template #header>
<div>
<div style="font-weight: bold">
<el-icon><EditPen/></el-icon>
编辑用户信息
</div>
<div style="font-size: 13px">编辑完成后请点击下方保存按钮</div>
</div>
</template>
<el-form label-position="top">
<el-form-item label="用户名">
<el-input v-model="editor.temp.username"/>
</el-form-item>
<el-form-item label="电子邮件">
<el-input v-model="editor.temp.email"/>
</el-form-item>
<div style="display: flex;font-size: 14px">
<div>
<span style="margin-right: 10px">禁言</span>
<el-switch v-model="editor.temp.mute"/>
</div>
<el-divider direction="vertical" style="height: 30px;margin: 0 20px"/>
<div>
<span style="margin-right: 10px">账号封禁</span>
<el-switch v-model="editor.temp.banned"/>
</div>
</div>
<div style="margin-top: 20px;color: #606266;font-size: 14px">
注册时间: {{ new Date(editor.temp.registerTime).toLocaleString() }}
</div>
<el-divider direction="horizontal"/>
</el-form>
<template #footer>
<div style="text-align: center">
<el-button type="success" @click="saveUserSettings">保存</el-button>
<el-button type="info" @click="editor.display = false">取消</el-button>
</div>
</template>
</el-drawer>
</div> </div>
</template> </template>
@ -78,5 +168,9 @@ watchEffect(() => apiUserList(userTable.page, userTable.size, data => {
align-items: center; align-items: center;
gap: 15px; gap: 15px;
} }
:deep(.el-drawer__header) {
margin-bottom: 0;
}
} }
</style> </style>