From 8e38cc8536cfda9b6bda8548d63778cbf5f4d634 Mon Sep 17 00:00:00 2001 From: web <candymxq888@outlook.com> Date: 星期六, 26 四月 2025 17:27:57 +0800 Subject: [PATCH] fix:添加个人中心和重置密码 --- src/views/system/user/index.vue | 678 ++++++++++++++++++++------------------- src/api/login.js | 18 + src/api/system/user.js | 7 src/views/screen/flow/report/index.vue | 23 - src/views/userCenter.vue | 248 ++++++++++++++ src/views/screen/temperature/report/index.vue | 23 - src/router/index.js | 12 7 files changed, 636 insertions(+), 373 deletions(-) diff --git a/src/api/login.js b/src/api/login.js index a0cafe1..1f2a52c 100644 --- a/src/api/login.js +++ b/src/api/login.js @@ -25,3 +25,21 @@ method: 'get', }); } + +export function userDetail() { + return { + get: (id) => { + return publicRequest({ + url: `/admin/user/detail/${id}`, + method: 'get', + }); + }, + setPsw: (data) => { + return publicRequest({ + url: '/admin/user/changePassword', + method: 'post', + data + }); + }, + } +} \ No newline at end of file diff --git a/src/api/system/user.js b/src/api/system/user.js index 962e862..1099169 100644 --- a/src/api/system/user.js +++ b/src/api/system/user.js @@ -65,5 +65,12 @@ method: 'get', }) }, + //获取已绑定管理员的角色列表 + resetPwd:(id) =>{ + return publicRequest({ + url: `/admin/user/resetPassword/${id}`, + method: 'post', + }) + }, } } diff --git a/src/router/index.js b/src/router/index.js index de49203..c6d4a29 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -8,6 +8,7 @@ */ import { createWebHashHistory, createRouter } from 'vue-router' /* Layout */ +import Layout from '@/layout' import Screen from '@/screen' import Flow from '@/screen/flow.vue' import Temp from '@/screen/temp.vue' @@ -36,7 +37,16 @@ { path: '/', hidden: true, - redirect: '/flow' + component: Layout, + redirect: '/screen', + children: [ + { + path: 'userCenter', + component: () => import('@/views/userCenter.vue'), + name: 'userCenter', + meta: { title: '个人中心', icon: 'PhUserCircleFill', affix: true } + }, + ] }, { path: '/login', diff --git a/src/views/screen/flow/report/index.vue b/src/views/screen/flow/report/index.vue index dfdaeb0..23d967a 100644 --- a/src/views/screen/flow/report/index.vue +++ b/src/views/screen/flow/report/index.vue @@ -7,17 +7,9 @@ const cascaderOption = { label: 'pointName', value: 'id', children: 'childrenList', checkStrictly: true, expandTrigger: 'hover', emitPath: false }; //级联选择器配置 const typeOption = ref([]) -const timeOption = ref([ - { label: '小时', value: 1 }, - { label: '日', value: 2 }, - { label: '月', value: 4 }, - { label: '季度', value: 5 }, - { label: '年', value: 6 }, -]) const timeVal = ref([]) const searchData = reactive({ pointId: '', - dateType: 2, createTimeRange: '' }) const tableRef = ref(null); //表格实例 @@ -72,21 +64,6 @@ <div class="report"> <div class="report-tool"> <el-cascader size="large" v-model="searchData.pointId" :options="typeOption" :show-all-levels="false" :props="cascaderOption" clearable /> - <el-select - v-model="searchData.dateType" - class="tool-select" - size="large" - placeholder="请选择" - clearable - style="width: 15rem" - > - <el-option - v-for="item in timeOption" - :key="item.value" - :label="item.label" - :value="item.value" - /> - </el-select> <el-date-picker v-model="timeVal" type="datetimerange" diff --git a/src/views/screen/temperature/report/index.vue b/src/views/screen/temperature/report/index.vue index 9543303..b99a73d 100644 --- a/src/views/screen/temperature/report/index.vue +++ b/src/views/screen/temperature/report/index.vue @@ -7,17 +7,9 @@ const cascaderOption = { label: 'pointName', value: 'id', children: 'childrenList', checkStrictly: true, expandTrigger: 'hover', emitPath: false }; //级联选择器配置 const typeOption = ref([]) -const timeOption = ref([ - { label: '小时', value: 1 }, - { label: '日', value: 2 }, - { label: '月', value: 3 }, - { label: '季度', value: 4 }, - { label: '年', value: 5 }, -]) const timeVal = ref([]) const searchData = reactive({ pointId: '', - dateType: 2, createTimeRange: '' }) const tableRef = ref(null); //表格实例 @@ -71,21 +63,6 @@ <div class="report"> <div class="report-tool"> <el-cascader size="large" v-model="searchData.pointId" :options="typeOption" :show-all-levels="false" :props="cascaderOption" clearable /> - <el-select - v-model="searchData.dateType" - class="tool-select" - size="large" - placeholder="请选择" - clearable - style="width: 15rem" - > - <el-option - v-for="item in timeOption" - :key="item.value" - :label="item.label" - :value="item.value" - /> - </el-select> <el-date-picker v-model="timeVal" type="datetimerange" diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index 99c400e..4f87b0e 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -1,15 +1,15 @@ - <!-- - * @Author: Liuyi candymxq888@outlook.com - * @Date: 2024-08-06 16:17:39 - * @LastEditors: Liuyi candymxq888@outlook.com - * @LastEditTime: 2024-10-23 15:51:47 - * @FilePath: \water-qinghe-web\src\views\system\user\index.vue - * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE - --> - <template> - <div class="app-container"> - <el-form :model="queryParams" ref="queryRef" :inline="true"> - <el-form-item label="用户名称" prop="name"> +<!-- +* @Author: Liuyi candymxq888@outlook.com +* @Date: 2024-08-06 16:17:39 +* @LastEditors: Liuyi candymxq888@outlook.com +* @LastEditTime: 2024-10-23 15:51:47 +* @FilePath: \water-qinghe-web\src\views\system\user\index.vue +* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE +--> +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryRef" :inline="true"> + <el-form-item label="用户名称" prop="name"> <el-input v-model="queryParams.name" placeholder="请输入用户名称" @@ -17,366 +17,392 @@ style="width: 200px" @keyup.enter="handleQuery" /> - </el-form-item> - <el-form-item> + </el-form-item> + <el-form-item> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button> - </el-form-item> - </el-form> - <el-row :gutter="10" class="mb8"> - <el-col :span="1.5"> + </el-form-item> + </el-form> + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> <el-button type="primary" plain icon="Plus" @click="handleAdd" - >新增</el-button> - </el-col> - </el-row> - <!--表格及分页--> - <el-table v-loading="loading" :data="tableData"> - <el-table-column + >新增 + </el-button> + </el-col> + </el-row> + <!--表格及分页--> + <el-table v-loading="loading" :data="tableData"> + <el-table-column v-for="(item, key, index) of tableHeader" :prop="key.toString()" :label="item" :key="index" align="center" - > + > <template #default="scope"> <div v-if="key === 'userType'"> - {{userTypeList?.filter(fil => fil.dictValue == scope.row.userType.toString())[0].dictLabel}} + {{ userTypeList?.filter(fil => fil.dictValue == scope.row.userType.toString())[0].dictLabel }} </div> </template> </el-table-column> - <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template #default="scope"> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button> - <el-button v-if="scope.row.userType == 3" link type="primary" icon="Edit" @click="handleRole(scope.row)">绑定角色</el-button> + <el-button v-if="scope.row.userType == 3" link type="primary" icon="Edit" + @click="handleRole(scope.row)">绑定角色 + </el-button> + <el-button link type="primary" icon="reset" @click="handeReset(scope.row)">重置密码</el-button> <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button> </template> - </el-table-column> - </el-table> - <pagination - :total="pageParam.total" - v-model:page="pageParam.page" - v-model:limit="pageParam.limit" - :page-sizes="[10,20,30]" - @pagination="getList" - /> - <!-- 添加或修改对话框 --> - <el-dialog :title="title" v-model="open" append-to-body center> - <el-form class="form-box" ref="userRef" :model="form" :rules="rules"> - <el-form-item label="用户名" prop="userName"> - <el-input :disabled ="!!form.id" v-model="form.userName" placeholder="请输入用户名称"/> - </el-form-item> - <el-form-item v-if="!form.id" label="密码" prop="password"> - <el-input v-model="form.password" placeholder="请输入密码" /> - </el-form-item> - <el-form-item label="昵称" prop="nickName"> - <el-input v-model="form.nickName" placeholder="请输入昵称" /> - </el-form-item> - <el-form-item label="用户类型" prop="userType"> - <el-select v-model="form.userType" placeholder="请选择用户类型"> - <el-option - v-for="(item,index) in userTypeList" - :label="item.dictLabel" - :value="item.dictValue" - :key="index" - ></el-option> - </el-select> - </el-form-item> - <el-form-item label="联系邮箱" prop="email"> - <el-input v-model="form.email" placeholder="请输入邮箱地址" /> - </el-form-item> - <el-form-item label="联系方式" prop="contact"> - <el-input v-model="form.contact" placeholder="请输入联系方式" /> - </el-form-item> - <el-form-item v-if="!form.id"> - <br> - </el-form-item> - <el-form-item label="上传头像" prop=""> - <upload-icons @uploadData="uploadData" :imageList="form.headImg" :limit="1"></upload-icons> - </el-form-item> - <el-form-item></el-form-item> - </el-form> - <template #footer> + </el-table-column> + </el-table> + <pagination + :total="pageParam.total" + v-model:page="pageParam.page" + v-model:limit="pageParam.limit" + :page-sizes="[10,20,30]" + @pagination="getList" + /> + <!-- 添加或修改对话框 --> + <el-dialog :title="title" v-model="open" append-to-body center> + <el-form class="form-box" ref="userRef" :model="form" :rules="rules"> + <el-form-item label="用户名" prop="userName"> + <el-input :disabled="!!form.id" v-model="form.userName" placeholder="请输入用户名称"/> + </el-form-item> + <el-form-item v-if="!form.id" label="密码" prop="password"> + <el-input v-model="form.password" placeholder="请输入密码"/> + </el-form-item> + <el-form-item label="昵称" prop="nickName"> + <el-input v-model="form.nickName" placeholder="请输入昵称"/> + </el-form-item> + <el-form-item label="用户类型" prop="userType"> + <el-select v-model="form.userType" placeholder="请选择用户类型"> + <el-option + v-for="(item,index) in userTypeList" + :label="item.dictLabel" + :value="item.dictValue" + :key="index" + ></el-option> + </el-select> + </el-form-item> + <el-form-item label="联系邮箱" prop="email"> + <el-input v-model="form.email" placeholder="请输入邮箱地址"/> + </el-form-item> + <el-form-item label="联系方式" prop="contact"> + <el-input v-model="form.contact" placeholder="请输入联系方式"/> + </el-form-item> + <el-form-item /> + <el-form-item label="上传头像" prop=""> + <upload-icons @uploadData="uploadData" :imageList="form.headImg" :limit="1"></upload-icons> + </el-form-item> + <el-form-item></el-form-item> + </el-form> + <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="submitForm">确 定</el-button> <el-button @click="cancel">取 消</el-button> </div> - </template> - </el-dialog> - - <!-- 角色设置弹窗 --> - <el-dialog - v-model="open1" - title="角色绑定" - align-center - center - width="300" - > - <div class="bandCheck"> - <el-checkbox-group v-model="roleCheckedList"> - <el-checkbox v-for="(item,index) in roleSelectList" :key="index" :label="item.name" :value="item.id" size ="large" /> - </el-checkbox-group> - </div> - <div class="handleBtn"> - <el-button @click="open1 = false">取消</el-button> - <el-button type="primary" @click="bandListConfirm">确认</el-button> - </div> - </el-dialog> - </div> - </template> - - <script setup> - import user from "@/api/system/user"; - import role from "@/api/system/role"; - import { sysDictData } from "@/api/system/dict"; - import setPostParams from "@/utils/searchParams.js"; - const { proxy } = getCurrentInstance(); - const imgBaseUrl = import.meta.env.VITE_APP_IMG_BASEURL //图片前缀 - - /** - * 搜索相关 - */ - /** 搜索按钮操作 */ - function handleQuery() { - getList({keywords:queryParams.value.name,page:1}) - } - - /** 重置按钮操作 */ - function resetQuery() { - proxy.resetForm("queryRef"); - handleQuery(); - } + </template> + </el-dialog> - /** - * Table表格权限数据列表相关 - */ - const pageParam = ref({ - total:0, - limit:0, - page:0, + <!-- 角色设置弹窗 --> + <el-dialog + v-model="open1" + title="角色绑定" + align-center + center + width="300" + > + <div class="bandCheck"> + <el-checkbox-group v-model="roleCheckedList"> + <el-checkbox v-for="(item,index) in roleSelectList" :key="index" :label="item.name" :value="item.id" + size="large"/> + </el-checkbox-group> + </div> + <div class="handleBtn"> + <el-button @click="open1 = false">取消</el-button> + <el-button type="primary" @click="bandListConfirm">确认</el-button> + </div> + </el-dialog> + </div> +</template> + +<script setup> +import user from "@/api/system/user"; +import role from "@/api/system/role"; +import {sysDictData} from "@/api/system/dict"; +import setPostParams from "@/utils/searchParams.js"; + +const {proxy} = getCurrentInstance(); +const imgBaseUrl = import.meta.env.VITE_APP_IMG_BASEURL //图片前缀 + +/** + * 搜索相关 + */ +/** 搜索按钮操作 */ +function handleQuery() { + getList({keywords: queryParams.value.name, page: 1}) +} + +/** 重置按钮操作 */ +function resetQuery() { + proxy.resetForm("queryRef"); + handleQuery(); +} + +/** + * Table表格权限数据列表相关 + */ +const pageParam = ref({ + total: 0, + limit: 0, + page: 0, +}) +const tableData = ref([]); +let tableHeader = ref({ + userName: '用户名称', + nickName: '昵称', + userType: '用户类型', + contact: '联系方式', + email: '邮箱地址', + createTimeView: '创建时间' +}) + +/** 获取列表 */ +async function getList(val) { + loading.value = true; + + let postParam = setPostParams(val) + await user().search(postParam).then((res) => { + tableData.value = res.data.list + pageParam.value.total = res.data.total + pageParam.value.limit = res.data.limit + pageParam.value.page = res.data.page }) - const tableData = ref([]); - let tableHeader = ref({ - userName: '用户名称', - nickName: '昵称', - userType:'用户类型', - contact:'联系方式', - email:'邮箱地址', - createTimeView:'创建时间' - }) - /** 获取列表 */ - async function getList(val) { - loading.value = true; + loading.value = false; +} - let postParam = setPostParams(val) - await user().search(postParam).then((res) =>{ - tableData.value = res.data.list - pageParam.value.total = res.data.total - pageParam.value.limit = res.data.limit - pageParam.value.page = res.data.page +/** 新增按钮操作 */ +async function handleAdd() { + reset(); + open.value = true; + title.value = "新增用户"; +} + +/** 修改按钮操作 */ +async function handleUpdate(row) { + reset(); + form.value = Object.assign({}, row) + open.value = true; + title.value = "修改用户"; +} + +/** 重置密码 */ +function handeReset(row) { + proxy.$modal.confirm('是否确认重置"' + row.nickName + '"的密码?').then(function () { + return user().resetPwd(row.id).then(res => { + proxy.$modal.confirm(`重置密码成功,新密码为:${res.data}`); }) - loading.value = false; - } - - /** 新增按钮操作 */ - async function handleAdd() { - reset(); - open.value = true; - title.value = "新增用户"; - } - - /** 修改按钮操作 */ - async function handleUpdate(row) { - reset(); - form.value = Object.assign({},row) - open.value = true; - title.value = "修改用户"; - } + }) +} - /** 删除按钮操作 */ - function handleDelete(row) { - proxy.$modal.confirm('是否确认删除名称为"' + row.nickName + '"的数据项?').then(function() { +/** 删除按钮操作 */ +function handleDelete(row) { + proxy.$modal.confirm('是否确认删除名称为"' + row.nickName + '"的数据项?').then(function () { return user().remove(row.id); - }).then(() => { + }).then(() => { getList(); proxy.$modal.msgSuccess("删除成功"); - }).catch(() => {}); - } + }).catch(() => { + }); +} - /** - * 新增/修改弹窗Form表单相关 - */ - const open = ref(false); - const loading = ref(false); - const title = ref(""); +/** + * 新增/修改弹窗Form表单相关 + */ +const open = ref(false); +const loading = ref(false); +const title = ref(""); - const data = reactive({ - form:{}, +const data = reactive({ + form: {}, queryParams: { name: undefined, }, rules: { - userName: [{ required: true, message: "请输入用户名称", trigger: "blur" }], - password: [{ required: true, message: "请输入密码", trigger: "blur" }], - nickName: [{ required: true, message: "请输入昵称", trigger: "blur" }], - userType: [{ required: true, message: "请选择用户类型", trigger: "blur" }], - contact: [{ required: true, message: "请输入联系方式", trigger: "blur" }], - email: [{ required: true, message: "请输入邮箱地址", trigger: "blur" }], - headImg: [{ required: true, message: "请上传用户头像", trigger: "blur" }], + userName: [{required: true, message: "请输入用户名称", trigger: "blur"}], + password: [{required: true, message: "请输入密码", trigger: "blur"}], + nickName: [{required: true, message: "请输入昵称", trigger: "blur"}], + userType: [{required: true, message: "请选择用户类型", trigger: "blur"}], + contact: [{required: true, message: "请输入联系方式", trigger: "blur"}], + email: [{required: true, message: "请输入邮箱地址", trigger: "blur"}], + headImg: [{required: true, message: "请上传用户头像", trigger: "blur"}], }, - }); - const { queryParams, form, rules } = toRefs(data); +}); +const {queryParams, form, rules} = toRefs(data); - //上传文件,添加图片地址信息 - const uploadData = (img) => { - form.value.headImg = imgBaseUrl + img.toString() - } +//上传文件,添加图片地址信息 +const uploadData = (img) => { + form.value.headImg = imgBaseUrl + img.toString() +} - //获取用户分类列表 - const userTypeList = ref() - const getUserType = async() =>{ - await sysDictData().searchType('user_type').then((res) =>{ - userTypeList.value = res.data - }) - } - /** 提交按钮 */ - function submitForm() { - proxy.$refs["userRef"].validate(valid => { +//获取用户分类列表 +const userTypeList = ref() +const getUserType = async () => { + await sysDictData().searchType('user_type').then((res) => { + userTypeList.value = res.data + }) +} + +/** 提交按钮 */ +function submitForm() { + proxy.$refs["userRef"].validate(valid => { if (valid) { - if (form.value.id != undefined) { - user().modify(form.value).then(res => { - proxy.$modal.msgSuccess("修改成功"); - open.value = false; - getList(); - }).catch(() =>{ - open.value = false; - proxy.$modal.msgError("修改失败"); - }); - } else { - user().create(form.value).then(res => { - proxy.$modal.msgSuccess("新增成功"); - open.value = false; - getList(); - }).catch(() =>{ - open.value = false; - proxy.$modal.msgError("新增失败"); - }); - } - } - }); - } - - /** 取消按钮 */ - function cancel() { - open.value = false; - reset(); - } - - /** 表单重置 */ - function reset() { - form.value = { - userName: '', - nickName: '', - headImg:undefined, - userType:undefined, - contact:'', - email:'', - }; - proxy.resetForm("userRef"); - } - - /** - * 设置角色相关 - */ - - //获取用户角色列表 - const open1 = ref(false) - const roleCheckedList = ref([]) - const roleSelectList = ref() - - //获取用户角色列表 - const getUserRole = async() =>{ - await role().search({limit:100,page:1}).then((res) =>{ - roleSelectList.value = res.data.list - }) - } - //绑定按钮 - const userId = ref() - async function handleRole(row){ - open1.value = true - userId.value = row.id - await getUserRole() - await getBandedRoleList(userId.value) - } - //获取已绑定角色列表 - async function getBandedRoleList(id){ - await user().getListRoleAdmin(id).then((res) =>{ - if(res.code == 200){ - let list = [] - res.data.forEach((item) =>{ - list.push(item.id) - }) - roleCheckedList.value = list - console.log(123,res) - } - }) - } - //绑定请求 - async function bandListConfirm(){ - let postParam = { - id:userId.value, - listRole:roleCheckedList.value - } - // console.log('roleCheckedList',roleCheckedList.value,id) - await user().setListRoleAdmin(postParam).then((res) =>{ - if(res.code == 200){ - proxy.$modal.msgSuccess("绑定成功"); - open1.value = false; - } - }) - } - getUserType() - getList(); - </script> - <style lang="scss" scoped> - .table-headImg{ - max-width: 100px; - height: 50px; - } - .el-dialog{ - width:50vw; - .user-form{ - display: flex; - flex-wrap: wrap; - justify-content:flex-start; - align-items: center; - margin: 20px auto; - width: 90%; - .el-form-item{ - width: 45%; + if (form.value.id != undefined) { + user().modify(form.value).then(res => { + proxy.$modal.msgSuccess("修改成功"); + open.value = false; + getList(); + }).catch(() => { + open.value = false; + proxy.$modal.msgError("修改失败"); + }); + } else { + user().create(form.value).then(res => { + proxy.$modal.msgSuccess("新增成功"); + open.value = false; + getList(); + }).catch(() => { + open.value = false; + proxy.$modal.msgError("新增失败"); + }); } } + }); +} + +/** 取消按钮 */ +function cancel() { + open.value = false; + reset(); +} + +/** 表单重置 */ +function reset() { + form.value = { + userName: '', + nickName: '', + headImg: undefined, + userType: undefined, + contact: '', + email: '', + }; + proxy.resetForm("userRef"); +} + +/** + * 设置角色相关 + */ + + //获取用户角色列表 +const open1 = ref(false) +const roleCheckedList = ref([]) +const roleSelectList = ref() + +//获取用户角色列表 +const getUserRole = async () => { + await role().search({limit: 100, page: 1}).then((res) => { + roleSelectList.value = res.data.list + }) +} +//绑定按钮 +const userId = ref() + +async function handleRole(row) { + open1.value = true + userId.value = row.id + await getUserRole() + await getBandedRoleList(userId.value) +} + +//获取已绑定角色列表 +async function getBandedRoleList(id) { + await user().getListRoleAdmin(id).then((res) => { + if (res.code == 200) { + let list = [] + res.data.forEach((item) => { + list.push(item.id) + }) + roleCheckedList.value = list + console.log(123, res) + } + }) +} + +//绑定请求 +async function bandListConfirm() { + let postParam = { + id: userId.value, + listRole: roleCheckedList.value } - .bandCheck{ - width:100%; - /* background-color: beige; */ - display: flex; - justify-content: center; - align-items: center; - margin-bottom:100px; + // console.log('roleCheckedList',roleCheckedList.value,id) + await user().setListRoleAdmin(postParam).then((res) => { + if (res.code == 200) { + proxy.$modal.msgSuccess("绑定成功"); + open1.value = false; + } + }) +} + +getUserType() +getList(); +</script> +<style lang="scss" scoped> +.table-headImg { + max-width: 100px; + height: 50px; +} + +.el-dialog { + width: 50vw; + + .user-form { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + align-items: center; + margin: 20px auto; + width: 90%; + + .el-form-item { + width: 45%; + } } - .handleBtn{ - width:100%; - /* background-color: beige; */ - display: flex; - justify-content: center; - align-items: center; - .el-button{ - width:100px; - } +} + +.bandCheck { + width: 100%; + /* background-color: beige; */ + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 100px; +} + +.handleBtn { + width: 100%; + /* background-color: beige; */ + display: flex; + justify-content: center; + align-items: center; + + .el-button { + width: 100px; } - </style> +} +</style> \ No newline at end of file diff --git a/src/views/userCenter.vue b/src/views/userCenter.vue new file mode 100644 index 0000000..5d02ad8 --- /dev/null +++ b/src/views/userCenter.vue @@ -0,0 +1,248 @@ +<template> + <div class="user-container"> + <div class="user-content"> + <div class="title">个人信息</div> + <div class="user-form"> + <div class="item"> + <div class="name">头像:</div> + <div class="image"> + <img :src="preUrl + form.headImg" class="userImage"/> + </div> + </div> + <div class="item"> + <div class="name">用户名:</div> + <div class="info">{{ form.userName }}</div> + </div> + <div class="item"> + <div class="name">昵称:</div> + <div class="info">{{ form.nickName }}</div> + </div> + <div class="item"> + <div class="name">联系方式:</div> + <div class="info">{{ form.contact }}</div> + </div> + <div class="item"> + <div class="name">邮箱:</div> + <div class="info">{{ form.email }}</div> + </div> + <div class="item"> + <div class="name">密码:</div> + <div class="info pwd"> + ******** + <el-button type="plain" @click="isShow = true">修改密码</el-button> + </div> + </div> + </div> + <div class="bottom"> + <el-button type="primary" @click="loginOut">退出登录</el-button> + </div> + <div class="footer"></div> + </div> + <el-dialog v-model="isShow"> + <div class="title">修改密码</div> + <el-form :model="pwdForm" ref="formRef" :rules="rules"> + <el-form-item prop="oldPassword" label="旧密码"> + <el-input v-model="pwdForm.oldPassword" placeholder="请输入旧密码"></el-input> + </el-form-item> + <el-form-item prop="newPassword" label="新密码"> + <el-input v-model="pwdForm.newPassword" placeholder="请输入新密码"></el-input> + </el-form-item> + <el-form-item prop="confirmPassword" label="确认密码"> + <el-input v-model="pwdForm.confirmPassword" placeholder="再次输入新密码"></el-input> + </el-form-item> + <el-form-item class="handel-btn"> + <el-button @click="cancel()">取消</el-button> + <el-button type="primary" @click="modifyPwd()">提交</el-button> + </el-form-item> + </el-form> + </el-dialog> + </div> +</template> + +<script setup> +import {userDetail} from '@/api/login' +const { proxy } = getCurrentInstance(); +const form = ref({}) +const preUrl = ref(import.meta.env.VITE_APP_IMG_BASEURL) +const getUserInfo = async () =>{ + let id = JSON.parse(localStorage.getItem('id')) + await userDetail().get(id).then(res => { + form.value = res.data + }) +} + +const confirmPass = (rule, value, callback) => { + if (value === '') { + callback(new Error('请再次输入密码')); + } else if (value !== pwdForm.value.newPassword) { + callback(new Error('两次输入密码不一致!')); + } else { + callback(); + } +} + +//修改密码 +const rules = { + oldPassword: [ + { required: true, message: "密码不能为空", trigger: "blur" }, + ], + newPassword: [ + {required: true, pattern: /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\W_]).{8,}$/, message: "密码必须是8位以上的英文数字字符组合", trigger: "blur" } + ], + confirmPassword: [ + { required: true, validator: confirmPass, message: "两次密码不一致", trigger: "blur" } + ] +} +const formRef = ref() +const isShow = ref(false) +const pwdForm = ref({ + oldPassword:'', + newPassword:'', + confirmPassword:'', +}) +const modifyPwd = () =>{ + formRef.value.validate(async (valid) => { + if(valid){ + const data = { + oldPassword: pwdForm.value.oldPassword, + newPassword: pwdForm.value.newPassword + } + await userDetail().setPsw(data).then(res => { + if(res.code == 200){ + proxy.$modal.msgSuccess("修改成功"); + } + }) + } + }) +} +const cancel = () =>{ + isShow.value = false + pwdForm.value = {} +} +onMounted(() =>{ + getUserInfo() +}) + +</script> + +<style lang="scss" scoped> +.user-container{ + width: 100%; + padding: 1% 12%; + .user-content{ + width: 100%; + background: rgba(242, 246, 248, 0.4); + border-radius: 20px; + .title{ + width: 100%; + height:80px; + background: rgba(112, 184, 225, 0.13); + display: flex; + align-items: center; + justify-content: center; + font-size: 30px; + color: #262627; + border-top-left-radius: 20px; + border-top-right-radius: 20px; + } + .user-form{ + width: 100%; + height:550px; + padding: 10px 80px; + .item{ + width: 100%; + height: 16%; + display: flex; + justify-content:flex-start; + align-items:center; + margin-left: 10%; + .name{ + width:90px; + font-size: 20px; + color: #626268; + font-weight: bold; + margin-right: 20px; + } + .info{ + width: 70%; + height: 35%; + display: flex; + align-items:center; + border-bottom: 1px solid rgba(29, 33, 41, 0.27); + font-size: 18px; + color: rgba(66, 66, 67, 0.98); + font-weight: bold; + } + .pwd{ + display: flex; + justify-content: space-between; + align-items: center; + .el-button{ + margin-bottom: 10px; + } + } + } + } + .bottom{ + width: 100%; + height:80px; + //background: rgba(112, 184, 225, 0.13); + display: flex; + align-items: center; + justify-content: center; + font-size: 30px; + color: #262627; + } + .footer{ + width: 100%; + height:100px; + background: rgba(112, 184, 225, 0.13); + border-bottom-left-radius: 20px; + border-bottom-right-radius: 20px; + } + } + :deep(.el-dialog){ + width: 40%; + height:40vh; + padding: 10px 200px; + .title{ + width: 100%; + height: 50px; + display: flex; + justify-content:center; + align-items: center; + font-weight: bold; + font-size: 20px; + margin-bottom: 50px; + } + .el-form{ + .el-form-item{ + margin-bottom: 30px; + } + .handel-btn{ + width: 50%; + margin: 0 auto; + .el-button{ + width: 40%; + height: 35px; + display: flex; + justify-content:center; + align-items: center; + font-size: 18px; + margin: 20px auto; + letter-spacing: 6px; + } + } + } + } +} +.image{ + border:1px solid rgba(112, 184, 225, 0.32); + border-radius: 10px; + padding: 5px; +} +.userImage{ + width: 100px; + max-height:100px; +} +</style> \ No newline at end of file -- Gitblit v1.9.3