feat:添加个人中心
11
Yi.BBS.Vue3/package-lock.json
generated
@@ -17,6 +17,7 @@
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.32",
|
||||
"vue": "^3.2.47",
|
||||
"vue-cropper": "1.0.3",
|
||||
"vue-router": "^4.1.6",
|
||||
"yarm": "^0.4.0"
|
||||
},
|
||||
@@ -3645,6 +3646,11 @@
|
||||
"@vue/shared": "3.2.47"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-cropper": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/vue-cropper/-/vue-cropper-1.0.3.tgz",
|
||||
"integrity": "sha512-yDrZkE4H5vOiMA9WQHE+6rmXrZ1S9TMZasEPAZPKg/2I/nySHL4ECD1lNxt7+ofTPKT+9+2sQkCwagPqEqiqJg=="
|
||||
},
|
||||
"node_modules/vue-router": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.1.6.tgz",
|
||||
@@ -6615,6 +6621,11 @@
|
||||
"@vue/shared": "3.2.47"
|
||||
}
|
||||
},
|
||||
"vue-cropper": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/vue-cropper/-/vue-cropper-1.0.3.tgz",
|
||||
"integrity": "sha512-yDrZkE4H5vOiMA9WQHE+6rmXrZ1S9TMZasEPAZPKg/2I/nySHL4ECD1lNxt7+ofTPKT+9+2sQkCwagPqEqiqJg=="
|
||||
},
|
||||
"vue-router": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.1.6.tgz",
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.32",
|
||||
"vue": "^3.2.47",
|
||||
"vue-cropper": "1.0.3",
|
||||
"vue-router": "^4.1.6",
|
||||
"yarm": "^0.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"sass": "1.52.1",
|
||||
"unplugin-auto-import": "^0.15.0",
|
||||
"unplugin-vue-components": "^0.24.0",
|
||||
"vite": "^4.1.3",
|
||||
"sass": "1.52.1"
|
||||
"vite": "^4.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
9
Yi.BBS.Vue3/src/apis/fileApi.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import myaxios from '@/utils/request'
|
||||
export function upload(data){
|
||||
return myaxios({
|
||||
url: '/file',
|
||||
method: 'post',
|
||||
data:data,
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
})
|
||||
};
|
||||
139
Yi.BBS.Vue3/src/apis/userApi.js
Normal file
@@ -0,0 +1,139 @@
|
||||
import myaxios from '@/utils/request'
|
||||
|
||||
// 查询用户列表
|
||||
export function listUser(query) {
|
||||
return myaxios({
|
||||
url: '/user',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询用户详细
|
||||
export function getUser(userId) {
|
||||
return myaxios({
|
||||
url: '/user/' + parseStrEmpty(userId),
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增用户
|
||||
export function addUser(data) {
|
||||
return myaxios({
|
||||
url: '/user',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改用户
|
||||
export function updateUser(id, data) {
|
||||
return myaxios({
|
||||
url: `/user/${id}`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
export function delUser(userId) {
|
||||
return myaxios({
|
||||
url: `/user/${userId}`,
|
||||
method: 'delete',
|
||||
})
|
||||
}
|
||||
|
||||
// 用户密码重置
|
||||
export function resetUserPwd(id, password) {
|
||||
const data = {
|
||||
password
|
||||
}
|
||||
|
||||
|
||||
return myaxios({
|
||||
url: `/account/rest-password/${id}`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户状态修改
|
||||
export function changeUserStatus(userId, isDel) {
|
||||
return myaxios({
|
||||
url: `/user/${userId}/${isDel}`,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询用户个人信息
|
||||
export function getUserProfile() {
|
||||
return myaxios({
|
||||
url: '/account',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 修改用户个人信息
|
||||
export function updateUserProfile(data) {
|
||||
return myaxios({
|
||||
url: `/user/profile`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 只修改用户头像
|
||||
export function updateUserIcon(data) {
|
||||
return myaxios({
|
||||
url: `/account/icon`,
|
||||
method: 'put',
|
||||
data:{icon:data}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 用户密码重置
|
||||
export function updateUserPwd(oldPassword, newPassword) {
|
||||
const data = {
|
||||
oldPassword,
|
||||
newPassword
|
||||
}
|
||||
return myaxios({
|
||||
url: '/account/password',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户头像上传
|
||||
export function uploadAvatar(data) {
|
||||
return request({
|
||||
url: '/system/user/profile/avatar',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询授权角色
|
||||
export function getAuthRole(userId) {
|
||||
return request({
|
||||
url: '/system/user/authRole/' + userId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存授权角色
|
||||
export function updateAuthRole(data) {
|
||||
return request({
|
||||
url: '/system/user/authRole',
|
||||
method: 'put',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
// // 查询部门下拉树结构
|
||||
// export function deptTreeSelect() {
|
||||
// return request({
|
||||
// url: '/system/user/deptTree',
|
||||
// method: 'get'
|
||||
// })
|
||||
// }
|
||||
190
Yi.BBS.Vue3/src/assets/styles/index.scss
Normal file
@@ -0,0 +1,190 @@
|
||||
// @import './variables.module.scss';
|
||||
// @import './mixin.scss';
|
||||
// @import './transition.scss';
|
||||
// @import './element-ui.scss';
|
||||
// @import './sidebar.scss';
|
||||
// @import './btn.scss';
|
||||
// @import './ruoyi.scss';
|
||||
|
||||
// body {
|
||||
// height: 100%;
|
||||
// margin: 0;
|
||||
// -moz-osx-font-smoothing: grayscale;
|
||||
// -webkit-font-smoothing: antialiased;
|
||||
// text-rendering: optimizeLegibility;
|
||||
// font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
||||
// }
|
||||
|
||||
// label {
|
||||
// font-weight: 700;
|
||||
// }
|
||||
|
||||
// html {
|
||||
// height: 100%;
|
||||
// box-sizing: border-box;
|
||||
// }
|
||||
|
||||
// #app {
|
||||
// height: 100%;
|
||||
// }
|
||||
|
||||
// *,
|
||||
// *:before,
|
||||
// *:after {
|
||||
// box-sizing: inherit;
|
||||
// }
|
||||
|
||||
// .no-padding {
|
||||
// padding: 0px !important;
|
||||
// }
|
||||
|
||||
// .padding-content {
|
||||
// padding: 4px 0;
|
||||
// }
|
||||
|
||||
// a:focus,
|
||||
// a:active {
|
||||
// outline: none;
|
||||
// }
|
||||
|
||||
// a,
|
||||
// a:focus,
|
||||
// a:hover {
|
||||
// cursor: pointer;
|
||||
// color: inherit;
|
||||
// text-decoration: none;
|
||||
// }
|
||||
|
||||
// div:focus {
|
||||
// outline: none;
|
||||
// }
|
||||
|
||||
// .fr {
|
||||
// float: right;
|
||||
// }
|
||||
|
||||
// .fl {
|
||||
// float: left;
|
||||
// }
|
||||
|
||||
// .pr-5 {
|
||||
// padding-right: 5px;
|
||||
// }
|
||||
|
||||
// .pl-5 {
|
||||
// padding-left: 5px;
|
||||
// }
|
||||
|
||||
// .block {
|
||||
// display: block;
|
||||
// }
|
||||
|
||||
// .pointer {
|
||||
// cursor: pointer;
|
||||
// }
|
||||
|
||||
// .inlineBlock {
|
||||
// display: block;
|
||||
// }
|
||||
|
||||
// .clearfix {
|
||||
// &:after {
|
||||
// visibility: hidden;
|
||||
// display: block;
|
||||
// font-size: 0;
|
||||
// content: " ";
|
||||
// clear: both;
|
||||
// height: 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// aside {
|
||||
// background: #eef1f6;
|
||||
// padding: 8px 24px;
|
||||
// margin-bottom: 20px;
|
||||
// border-radius: 2px;
|
||||
// display: block;
|
||||
// line-height: 32px;
|
||||
// font-size: 16px;
|
||||
// font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
// color: #2c3e50;
|
||||
// -webkit-font-smoothing: antialiased;
|
||||
// -moz-osx-font-smoothing: grayscale;
|
||||
|
||||
// a {
|
||||
// color: #337ab7;
|
||||
// cursor: pointer;
|
||||
|
||||
// &:hover {
|
||||
// color: rgb(32, 160, 255);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// .components-container {
|
||||
// margin: 30px 50px;
|
||||
// position: relative;
|
||||
// }
|
||||
|
||||
// .pagination-container {
|
||||
// margin-top: 30px;
|
||||
// }
|
||||
|
||||
.text-center {
|
||||
text-align: center
|
||||
}
|
||||
|
||||
// .sub-navbar {
|
||||
// height: 50px;
|
||||
// line-height: 50px;
|
||||
// position: relative;
|
||||
// width: 100%;
|
||||
// text-align: right;
|
||||
// padding-right: 20px;
|
||||
// transition: 600ms ease position;
|
||||
// background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
|
||||
|
||||
// .subtitle {
|
||||
// font-size: 20px;
|
||||
// color: #fff;
|
||||
// }
|
||||
|
||||
// &.draft {
|
||||
// background: #d0d0d0;
|
||||
// }
|
||||
|
||||
// &.deleted {
|
||||
// background: #d0d0d0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .link-type,
|
||||
// .link-type:focus {
|
||||
// color: #337ab7;
|
||||
// cursor: pointer;
|
||||
|
||||
// &:hover {
|
||||
// color: rgb(32, 160, 255);
|
||||
// }
|
||||
// }
|
||||
|
||||
// .filter-container {
|
||||
// padding-bottom: 10px;
|
||||
|
||||
// .filter-item {
|
||||
// display: inline-block;
|
||||
// vertical-align: middle;
|
||||
// margin-bottom: 10px;
|
||||
// }
|
||||
// }
|
||||
|
||||
// //refine vue-multiselect plugin
|
||||
// .multiselect {
|
||||
// line-height: 16px;
|
||||
// }
|
||||
|
||||
// .multiselect--active {
|
||||
// z-index: 1000 !important;
|
||||
// }
|
||||
271
Yi.BBS.Vue3/src/assets/styles/ruoyi.scss
Normal file
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
* 通用css样式布局处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
/** 基础通用 **/
|
||||
.pt5 {
|
||||
padding-top: 5px;
|
||||
}
|
||||
.pr5 {
|
||||
padding-right: 5px;
|
||||
}
|
||||
.pb5 {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.mr5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.mb5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.ml5 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.mr10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.mr20 {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.ml20 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
margin-top: 6vh !important;
|
||||
}
|
||||
|
||||
.el-dialog.scrollbar .el-dialog__body {
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: 70vh;
|
||||
padding: 10px 20px 0;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
||||
th {
|
||||
word-break: break-word;
|
||||
background-color: #f8f8f9 !important;
|
||||
color: #515a6e;
|
||||
height: 40px !important;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
.el-table__body-wrapper {
|
||||
.el-button [class*="el-icon-"] + span {
|
||||
margin-left: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 表单布局 **/
|
||||
.form-header {
|
||||
font-size:15px;
|
||||
color:#6379bb;
|
||||
border-bottom:1px solid #ddd;
|
||||
margin:8px 10px 25px 10px;
|
||||
padding-bottom:5px
|
||||
}
|
||||
|
||||
/** 表格布局 **/
|
||||
.pagination-container {
|
||||
// position: relative;
|
||||
height: 25px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 15px;
|
||||
padding: 10px 20px !important;
|
||||
}
|
||||
|
||||
/* tree border */
|
||||
.tree-border {
|
||||
margin-top: 5px;
|
||||
border: 1px solid #e5e6e7;
|
||||
background: #FFFFFF none;
|
||||
border-radius:4px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagination-container .el-pagination {
|
||||
right: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@media ( max-width : 768px) {
|
||||
.pagination-container .el-pagination > .el-pagination__jump {
|
||||
display: none !important;
|
||||
}
|
||||
.pagination-container .el-pagination > .el-pagination__sizes {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table .fixed-width .el-button--small {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
/** 表格更多操作下拉样式 */
|
||||
.el-table .el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409EFF;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-table .el-dropdown, .el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-tree-node__content > .el-checkbox {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.list-group-striped > .list-group-item {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
padding-left: 0px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
border-top: 1px solid #e7eaec;
|
||||
margin-bottom: -1px;
|
||||
padding: 11px 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
|
||||
// .el-card__header {
|
||||
// padding: 14px 15px 7px !important;
|
||||
// min-height: 40px;
|
||||
// }
|
||||
|
||||
// .el-card__body {
|
||||
// padding: 15px 20px 20px 20px !important;
|
||||
// }
|
||||
|
||||
.card-box {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* button color */
|
||||
.el-button--cyan.is-active,
|
||||
.el-button--cyan:active {
|
||||
background: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan:focus,
|
||||
.el-button--cyan:hover {
|
||||
background: #48D1CC;
|
||||
border-color: #48D1CC;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan {
|
||||
background-color: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* text color */
|
||||
.text-navy {
|
||||
color: #1ab394;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: #1c84c6;
|
||||
}
|
||||
|
||||
.text-info {
|
||||
color: #23c6c8;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: #f8ac59;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #ed5565;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
/* image */
|
||||
.img-circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.img-lg {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.avatar-upload-preview {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(50%, -50%);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 拖拽列样式 */
|
||||
.sortable-ghost{
|
||||
opacity: .8;
|
||||
color: #fff!important;
|
||||
background: #42b983!important;
|
||||
}
|
||||
|
||||
/* 表格右侧工具栏样式 */
|
||||
.top-right-btn {
|
||||
margin-left: auto;
|
||||
}
|
||||
@@ -6,12 +6,15 @@
|
||||
|
||||
<script setup>
|
||||
import { marked } from 'marked';
|
||||
|
||||
import hljs from "highlight.js";
|
||||
//可以设置加载样式切换主题
|
||||
import 'highlight.js/styles/atom-one-dark.css'
|
||||
import '@/assets/github-markdown.css'
|
||||
import { ref,watch } from 'vue';
|
||||
|
||||
|
||||
|
||||
const outputHtml=ref("")
|
||||
const props = defineProps(['code'])
|
||||
watch(props,(n,o)=>{
|
||||
|
||||
@@ -44,6 +44,7 @@ const enterDiscuss = (id) => {
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
.item-bottom .el-icon {
|
||||
margin-right: 0.4rem;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,61 @@
|
||||
<template>
|
||||
<mavon-editor
|
||||
:v-model="text"
|
||||
:subfield="subfield"
|
||||
:codeStyle="props.codeStyle"
|
||||
:ishljs="true"
|
||||
:style="{minHeight:props.height,maxHeight:'100%'}"
|
||||
class="edit"
|
||||
@change="change"
|
||||
></mavon-editor>
|
||||
</template>
|
||||
<script setup>
|
||||
// Local Registration
|
||||
<mavon-editor ref='md' v-model="text" :subfield="true" :codeStyle="props.codeStyle" :ishljs="true"
|
||||
:style="{ minHeight: props.height, maxHeight: '100%' }" class="edit" @imgAdd="imgAdd">
|
||||
<!-- 引用视频链接的自定义按钮 -->
|
||||
<template v-slot:left-toolbar-after>
|
||||
<!--点击按钮触发的事件是打开表单对话框-->
|
||||
|
||||
<el-dropdown :hide-on-click='false'>
|
||||
<el-button aria-hidden="true" class="op-icon fa" title="表情包">
|
||||
😊
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu >
|
||||
<el-dropdown-item>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<td @click="text+='😊'">😊</td>
|
||||
<td>😊</td>
|
||||
<td>😊</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>😊</td>
|
||||
<td>😊</td>
|
||||
<td>😊</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>😊</td>
|
||||
<td>😊</td>
|
||||
<td>😊</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</el-dropdown-item>
|
||||
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
</mavon-editor>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import { mavonEditor } from 'mavon-editor'
|
||||
import 'mavon-editor/dist/css/index.css'
|
||||
import { ref,computed,watch } from 'vue';
|
||||
const props = defineProps(['height','modelValue',"codeStyle"])
|
||||
const emit=defineEmits(['update:modelValue'])
|
||||
const subfield = true;
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import { upload } from '@/apis/fileApi'
|
||||
const md = ref(null);
|
||||
const props = defineProps(['height', 'modelValue', "codeStyle"])
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
//v-model传值出去
|
||||
// //v-model传值出去
|
||||
const text = computed({
|
||||
get() {
|
||||
return props.modelValue
|
||||
@@ -29,17 +65,20 @@ const text = computed({
|
||||
}
|
||||
})
|
||||
|
||||
const change=(value ,render)=>
|
||||
{
|
||||
console.log(value,"value");
|
||||
//不用给解析后htm的值,给value即可
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
//图片上传
|
||||
const imgAdd = async (pos, $file) => {
|
||||
// 第一步.将图片上传到服务器.
|
||||
var formdata = new FormData();
|
||||
formdata.append('file', $file);
|
||||
const response = await upload(formdata)
|
||||
const url = `${import.meta.env.VITE_APP_BASEAPI}/file/${response[0].id}`;
|
||||
console.log(url)
|
||||
md.value.$img2Url(pos, url);
|
||||
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.edit
|
||||
{
|
||||
.edit {
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
<span>{{data.name}}</span>
|
||||
<span>
|
||||
|
||||
<a style="color: #409EFF; margin-left: 8px" @click="$emit('create',node, data)"
|
||||
<a style="color: #409EFF; margin-left: 8px" @click="$emit('create',node, data)" v-hasPer="['bbs:article:add']"
|
||||
|
||||
> + </a>
|
||||
<a style="color: #409EFF; margin-left: 8px" @click="$emit('update',node, data)"
|
||||
<a style="color: #409EFF; margin-left: 8px" @click="$emit('update',node, data)" v-hasPer="['bbs:article:edit']"
|
||||
|
||||
> 编辑 </a>
|
||||
<a style="color: #f56c6c; margin-left: 8px" @click="$emit('remove',node, data)"
|
||||
<a style="color: #f56c6c; margin-left: 8px" @click="$emit('remove',node, data)" v-hasPer="['bbs:article:remove']"
|
||||
|
||||
> 删除 </a>
|
||||
</span>
|
||||
|
||||
@@ -32,10 +32,13 @@
|
||||
<div class="flex-grow" />
|
||||
|
||||
<el-menu-item index="5">
|
||||
<el-input placeholder="请输入关键字" clearable />
|
||||
<div style="width: 350px;">
|
||||
<el-input style="width: 300px;" placeholder="全站搜索" clearable prefix-icon="Search" />
|
||||
<el-button type="primary" plain>搜索</el-button>
|
||||
</div>
|
||||
</el-menu-item>
|
||||
|
||||
搜索</el-menu-item>
|
||||
<el-menu-item index="6">
|
||||
<el-menu-item index="6" @click="enterProfile" >
|
||||
<AvatarInfo :size='30' :isSelf="true" />
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="6">
|
||||
@@ -66,6 +69,8 @@ const logout=async ()=>{
|
||||
const enterIndex=()=>{
|
||||
router.push("/index");
|
||||
};
|
||||
const enterProfile=()=>{
|
||||
router.push("/profile");}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
import './assets/main.css'
|
||||
import '@/assets/styles/index.scss' // global css
|
||||
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
import directive from './directive' // directive
|
||||
|
||||
|
||||
@@ -9,7 +9,13 @@ const router = createRouter({
|
||||
return { top: 0 }
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
{
|
||||
name:'test',
|
||||
path: '/test',
|
||||
component: () => import('../views/Test.vue')
|
||||
},
|
||||
{
|
||||
|
||||
path: '/loginLayout',
|
||||
name: 'loginLayout',
|
||||
component: LoginLayout,
|
||||
@@ -27,7 +33,6 @@ const router = createRouter({
|
||||
// },
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: '/',
|
||||
name: 'layout',
|
||||
@@ -55,6 +60,12 @@ const router = createRouter({
|
||||
name:'editArt',
|
||||
path:'/editArt',
|
||||
component:()=>import('../views/EditArticle.vue')
|
||||
},
|
||||
{
|
||||
name:'profile',
|
||||
path:'/profile',
|
||||
component:()=>import('../views/profile/Index.vue')
|
||||
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -6,10 +6,10 @@ const useUserStore = defineStore('user',
|
||||
state: () => ({
|
||||
id:'',
|
||||
token: getToken(),
|
||||
name: '登录用户',
|
||||
name: '游客',
|
||||
icon: null,
|
||||
roles: [],
|
||||
permissions: ['*:*:*']
|
||||
permissions: []
|
||||
}),
|
||||
getters: {
|
||||
},
|
||||
@@ -49,7 +49,7 @@ const useUserStore = defineStore('user',
|
||||
}
|
||||
// this.roles = ["admin"];
|
||||
// this.permissions=["*:*:*"]
|
||||
this.name = user.name
|
||||
this.name = user.nick
|
||||
this.avatar = avatar;
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
|
||||
@@ -66,8 +66,10 @@
|
||||
|
||||
<li>
|
||||
<el-button type="primary" size="default"
|
||||
v-hasPer="['bbs:discuss:edit']"
|
||||
@click="updateHander(route.params.discussId)">编辑</el-button>
|
||||
<el-button style="margin-left: 1rem" type="danger"
|
||||
v-hasPer="['bbs:discuss:remove']"
|
||||
@click="delHander(route.params.discussId)">删除</el-button>
|
||||
</li>
|
||||
<li>分类: <span>文章</span></li>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<el-button>重置</el-button>
|
||||
<el-button type="primary" @click="async()=>{ await loadDiscussList();}">查询</el-button>
|
||||
<el-button @click="enterEditArticle" type="primary">分享</el-button>
|
||||
<el-button @click="enterEditArticle" type="primary" v-hasPer="['bbs:discuss:add']">分享</el-button>
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
展开
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
<el-input placeholder="请输入" v-model="editForm.introduction" />
|
||||
</el-form-item>
|
||||
<el-form-item label="内容:" prop="content">
|
||||
{{ editForm.content + "*" }}
|
||||
<MavonEdit
|
||||
height="30rem"
|
||||
v-model="editForm.content"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<h2> 登录-欢迎</h2>
|
||||
<el-input v-model="loginForm.userName" placeholder="用户名" />
|
||||
<el-input v-model="loginForm.password" placeholder="密码" />
|
||||
<el-button class="login-btn" type="primary" @click="login">登录</el-button>
|
||||
<el-input v-model="loginForm.password" placeholder="密码" show-password />
|
||||
<el-button class="login-btn" type="primary" @click="login" >登录</el-button>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
|
||||
1
Yi.BBS.Vue3/src/views/Test.vue
Normal file
@@ -0,0 +1 @@
|
||||
<template></template>
|
||||
123
Yi.BBS.Vue3/src/views/profile/Index.vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<div class="app-container" style="width: 1400px;">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<template v-slot:header>
|
||||
<div class="clearfix">
|
||||
<span>个人信息</span>
|
||||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<div class="text-center">
|
||||
<userAvatar :user="state.user" />
|
||||
</div>
|
||||
<ul class="list-group list-group-striped">
|
||||
<li class="list-group-item">
|
||||
<el-icon><User /></el-icon> 用户名称
|
||||
<div class="pull-right">{{ state.user.userName }}</div>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<el-icon><Phone /></el-icon> 手机号码
|
||||
<div class="pull-right">{{ state.user.phone }}</div>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<el-icon><Message /></el-icon> 用户邮箱
|
||||
<div class="pull-right">{{ state.user.email }}</div>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<el-icon><HelpFilled /></el-icon> 所属部门
|
||||
<div class="pull-right" v-if="state.dept">{{ state.dept.deptName }}</div>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<el-icon><Avatar /></el-icon> 所属角色
|
||||
<div class="pull-right"><span v-for="role in state.roles" :key="role.id">{{ role.roleName }} /</span></div>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<el-icon><Stopwatch /></el-icon> 创建日期
|
||||
<div class="pull-right">{{ state.user.creationTime }}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="18" :xs="24">
|
||||
<el-card>
|
||||
<template v-slot:header>
|
||||
<div class="clearfix">
|
||||
<span>基本资料</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tab-pane label="基本资料" name="userinfo">
|
||||
<userInfo :user="state.user" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="修改密码" name="resetPwd">
|
||||
<resetPwd />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Profile">
|
||||
import userAvatar from "./UserAvatar.vue";
|
||||
import userInfo from "./UserInfo.vue";
|
||||
import resetPwd from "./ResetPwd.vue";
|
||||
import { getUserProfile } from "@/apis/userApi.js";
|
||||
import { onMounted ,ref,reactive} from "vue";
|
||||
|
||||
const activeTab = ref("userinfo");
|
||||
const state = reactive({
|
||||
user: {},
|
||||
dept: {},
|
||||
roles: [],
|
||||
roleGroup: {},
|
||||
postGroup: {}
|
||||
});
|
||||
|
||||
function getUser() {
|
||||
getUserProfile().then(response => {
|
||||
state.user = response.user;
|
||||
state.dept=response.dept;
|
||||
state.roles=response.roles;
|
||||
state.roleGroup = response.roleGroup;
|
||||
state.postGroup = response.postGroup;
|
||||
});
|
||||
};
|
||||
onMounted(()=>{
|
||||
getUser();
|
||||
})
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.pull-right {
|
||||
float: right !important;
|
||||
}
|
||||
.list-group-striped > .list-group-item {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
padding-left: 0px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
border-top: 1px solid #e7eaec;
|
||||
margin-bottom: -1px;
|
||||
padding: 11px 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
59
Yi.BBS.Vue3/src/views/profile/ResetPwd.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<el-form ref="pwdRef" :model="user" :rules="rules" label-width="80px">
|
||||
<el-form-item label="旧密码" prop="oldPassword">
|
||||
<el-input v-model="user.oldPassword" placeholder="请输入旧密码" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword">
|
||||
<el-input v-model="user.confirmPassword" placeholder="请确认新密码" type="password" show-password/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submit">保存</el-button>
|
||||
<el-button type="danger" @click="close">关闭</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { updateUserPwd } from "@/apis/userApi";
|
||||
import { ref,reactive } from "vue";
|
||||
|
||||
const pwdRef=ref(null);
|
||||
|
||||
const user = reactive({
|
||||
oldPassword: undefined,
|
||||
newPassword: undefined,
|
||||
confirmPassword: undefined
|
||||
});
|
||||
|
||||
const equalToPassword = (rule, value, callback) => {
|
||||
if (user.newPassword !== value) {
|
||||
callback(new Error("两次输入的密码不一致"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
const rules = ref({
|
||||
oldPassword: [{ required: true, message: "旧密码不能为空", trigger: "blur" }],
|
||||
newPassword: [{ required: true, message: "新密码不能为空", trigger: "blur" }, { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }],
|
||||
confirmPassword: [{ required: true, message: "确认密码不能为空", trigger: "blur" }, { required: true, validator: equalToPassword, trigger: "blur" }]
|
||||
});
|
||||
|
||||
/** 提交按钮 */
|
||||
function submit() {
|
||||
pwdRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
updateUserPwd(user.oldPassword, user.newPassword).then(response => {
|
||||
alert("修改成功");
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
/** 关闭按钮 */
|
||||
function close() {
|
||||
alert("关闭")
|
||||
// proxy.$tab.closePage();
|
||||
};
|
||||
</script>
|
||||
174
Yi.BBS.Vue3/src/views/profile/UserAvatar.vue
Normal file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<div class="user-info-head" @click="editCropper()"><img :src="options.img" title="点击上传头像" class="img-circle img-lg" /></div>
|
||||
<el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
|
||||
<el-row>
|
||||
<el-col :xs="24" :md="12" :style="{height: '350px'}">
|
||||
<vue-cropper
|
||||
ref="cropper"
|
||||
:img="options.img"
|
||||
:info="true"
|
||||
:autoCrop="options.autoCrop"
|
||||
:autoCropWidth="options.autoCropWidth"
|
||||
:autoCropHeight="options.autoCropHeight"
|
||||
:fixedBox="options.fixedBox"
|
||||
@realTime="realTime"
|
||||
v-if="visible"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :xs="24" :md="12" :style="{height: '350px'}">
|
||||
<div class="avatar-upload-preview">
|
||||
<img :src="options.previews.url" :style="options.previews.img"/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<br/>
|
||||
<el-row>
|
||||
<el-col :lg="2" :md="2">
|
||||
<el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
|
||||
<el-button>
|
||||
选择
|
||||
<el-icon class="el-icon--right"><Upload /></el-icon>
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-col>
|
||||
<el-col :lg="{span: 1, offset: 2}" :md="2">
|
||||
<el-button icon="Plus" @click="changeScale(1)"></el-button>
|
||||
</el-col>
|
||||
<el-col :lg="{span: 1, offset: 1}" :md="2">
|
||||
<el-button icon="Minus" @click="changeScale(-1)"></el-button>
|
||||
</el-col>
|
||||
<el-col :lg="{span: 1, offset: 1}" :md="2">
|
||||
<el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
|
||||
</el-col>
|
||||
<el-col :lg="{span: 1, offset: 1}" :md="2">
|
||||
<el-button icon="RefreshRight" @click="rotateRight()"></el-button>
|
||||
</el-col>
|
||||
<el-col :lg="{span: 2, offset: 6}" :md="2">
|
||||
<el-button type="primary" @click="uploadImg()">上传</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import "vue-cropper/dist/index.css";
|
||||
import { VueCropper } from "vue-cropper";
|
||||
import { upload } from "@/apis/fileApi";
|
||||
import { updateUserIcon } from "@/apis/userApi";
|
||||
import useUserStore from '@/stores/user'
|
||||
import { ref ,reactive } from "vue";
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
const cropper=ref(null);
|
||||
|
||||
const open = ref(false);
|
||||
const visible = ref(false);
|
||||
const title = ref("修改头像");
|
||||
|
||||
//图片裁剪数据
|
||||
const options = reactive({
|
||||
img: userStore.icon, // 裁剪图片的地址
|
||||
autoCrop: true, // 是否默认生成截图框
|
||||
autoCropWidth: 200, // 默认生成截图框宽度
|
||||
autoCropHeight: 200, // 默认生成截图框高度
|
||||
fixedBox: true, // 固定截图框大小 不允许改变
|
||||
previews: {} //预览数据
|
||||
});
|
||||
|
||||
/** 编辑头像 */
|
||||
function editCropper() {
|
||||
open.value = true;
|
||||
};
|
||||
/** 打开弹出层结束时的回调 */
|
||||
function modalOpened() {
|
||||
visible.value = true;
|
||||
};
|
||||
/** 覆盖默认上传行为 */
|
||||
function requestUpload() {
|
||||
};
|
||||
/** 向左旋转 */
|
||||
function rotateLeft() {
|
||||
cropper.value.rotateLeft();
|
||||
};
|
||||
/** 向右旋转 */
|
||||
function rotateRight() {
|
||||
cropper.value.rotateRight();
|
||||
};
|
||||
/** 图片缩放 */
|
||||
function changeScale(num) {
|
||||
num = num || 1;
|
||||
cropper.value.changeScale(num);
|
||||
};
|
||||
/** 上传预处理 */
|
||||
function beforeUpload(file) {
|
||||
if (file.type.indexOf("image/") == -1) {
|
||||
alert("文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件。");
|
||||
} else {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
options.img = reader.result;
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
/** 上传图片 */
|
||||
function uploadImg() {
|
||||
cropper.value.getCropBlob(data => {
|
||||
let formData = new FormData();
|
||||
formData.append("file", data);
|
||||
upload(formData).then(response => {
|
||||
open.value = false;
|
||||
options.img = import.meta.env.VITE_APP_BASE_API +"/file/"+response[0].id;
|
||||
userStore.icon = options.img;
|
||||
updateUserIcon(response[0].id).then(response2=>{
|
||||
alert("修改成功");
|
||||
visible.value = false;
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
};
|
||||
/** 实时预览 */
|
||||
function realTime(data) {
|
||||
options.previews = data;
|
||||
};
|
||||
/** 关闭窗口 */
|
||||
function closeDialog() {
|
||||
options.img = userStore.iocn;
|
||||
options.visible = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.user-info-head {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.user-info-head:hover:after {
|
||||
content: "+";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
color: #eee;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
cursor: pointer;
|
||||
line-height: 110px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
58
Yi.BBS.Vue3/src/views/profile/UserInfo.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<el-form ref="userRef" :model="user" :rules="rules" label-width="80px">
|
||||
<el-form-item label="用户昵称" prop="nickName">
|
||||
<el-input v-model="user.nick" maxlength="30" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码" prop="phone">
|
||||
<el-input v-model="user.phone" maxlength="11" />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="user.email" maxlength="50" />
|
||||
</el-form-item>
|
||||
<el-form-item label="性别">
|
||||
<el-radio-group v-model="user.sex">
|
||||
<el-radio :label="0">男</el-radio>
|
||||
<el-radio :label="1">女</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submit">保存</el-button>
|
||||
<el-button type="danger" @click="close">关闭</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { updateUserProfile } from "@/apis/userApi";
|
||||
import { ref } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object
|
||||
}
|
||||
});
|
||||
|
||||
const userRef=ref(null);
|
||||
|
||||
const rules = ref({
|
||||
nick: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
|
||||
email: [{ required: true, message: "邮箱地址不能为空", trigger: "blur" }, { type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }],
|
||||
phone: [{ required: true, message: "手机号码不能为空", trigger: "blur" }, { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }],
|
||||
});
|
||||
|
||||
/** 提交按钮 */
|
||||
function submit() {
|
||||
userRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
updateUserProfile(props.user).then(response => {
|
||||
alert("修改成功");
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
/** 关闭按钮 */
|
||||
function close() {
|
||||
alert("关闭")
|
||||
proxy.$tab.closePage();
|
||||
};
|
||||
</script>
|
||||
@@ -9,7 +9,7 @@ namespace Yi.Framework.Data.DataSeeds
|
||||
{
|
||||
public abstract class AbstractDataSeed<TEntity> : IDataSeed<TEntity>
|
||||
{
|
||||
private readonly IRepository<TEntity> _repository;
|
||||
protected readonly IRepository<TEntity> _repository;
|
||||
public AbstractDataSeed(IRepository<TEntity> repository)
|
||||
{
|
||||
_repository = repository;
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Data.DataSeeds;
|
||||
using Yi.Framework.Ddd.Repositories;
|
||||
using Yi.RBAC.Domain.Identity.Entities;
|
||||
using Yi.RBAC.Domain.Shared.Identity.EnumClasses;
|
||||
|
||||
namespace Yi.BBS.Domain.DataSeed
|
||||
{
|
||||
[AppService(typeof(IDataSeed))]
|
||||
public class BbsMenuDataSeed : AbstractDataSeed<MenuEntity>
|
||||
{
|
||||
public BbsMenuDataSeed(IRepository<MenuEntity> repository) : base(repository)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<bool> IsInvoker()
|
||||
{
|
||||
return !await _repository.IsAnyAsync(x => x.MenuName == "BBS");
|
||||
}
|
||||
public override List<MenuEntity> GetSeedData()
|
||||
{
|
||||
List<MenuEntity> entities = new List<MenuEntity>();
|
||||
//BBS
|
||||
MenuEntity bbs = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "BBS",
|
||||
MenuType = MenuTypeEnum.Catalogue,
|
||||
Router = "/bbs",
|
||||
IsShow = true,
|
||||
IsLink = false,
|
||||
MenuIcon = "international",
|
||||
OrderNum = 97,
|
||||
ParentId = 0,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(bbs);
|
||||
//文章管理
|
||||
MenuEntity article = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章管理",
|
||||
PermissionCode = "bbs:article:list",
|
||||
MenuType = MenuTypeEnum.Menu,
|
||||
Router = "article",
|
||||
IsShow = true,
|
||||
IsLink = false,
|
||||
IsCache = true,
|
||||
Component = "bbs/article/index",
|
||||
MenuIcon = "education",
|
||||
OrderNum = 100,
|
||||
ParentId = bbs.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(article);
|
||||
|
||||
MenuEntity articleQuery = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章查询",
|
||||
PermissionCode = "bbs:article:query",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = article.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(articleQuery);
|
||||
|
||||
MenuEntity articleAdd = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章新增",
|
||||
PermissionCode = "bbs:article:add",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = article.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(articleAdd);
|
||||
|
||||
MenuEntity articleEdit = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章修改",
|
||||
PermissionCode = "bbs:article:edit",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = article.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(articleEdit);
|
||||
|
||||
MenuEntity articleRemove = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章删除",
|
||||
PermissionCode = "bbs:article:remove",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = article.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(articleRemove);
|
||||
|
||||
|
||||
//主题管理
|
||||
MenuEntity discuss = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "主题管理",
|
||||
PermissionCode = "bbs:discuss:list",
|
||||
MenuType = MenuTypeEnum.Menu,
|
||||
Router = "discuss",
|
||||
IsShow = true,
|
||||
IsLink = false,
|
||||
IsCache = true,
|
||||
Component = "bbs/discuss/index",
|
||||
MenuIcon = "education",
|
||||
OrderNum = 100,
|
||||
ParentId = bbs.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(discuss);
|
||||
|
||||
MenuEntity discussQuery = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "主题查询",
|
||||
PermissionCode = "bbs:discuss:query",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = discuss.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(discussQuery);
|
||||
|
||||
MenuEntity discussAdd = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "主题新增",
|
||||
PermissionCode = "bbs:discuss:add",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = discuss.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(discussAdd);
|
||||
|
||||
MenuEntity discussEdit = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "主题修改",
|
||||
PermissionCode = "bbs:discuss:edit",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = discuss.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(discussEdit);
|
||||
|
||||
MenuEntity discussRemove = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "主题删除",
|
||||
PermissionCode = "bbs:discuss:remove",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = discuss.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(discussRemove);
|
||||
|
||||
|
||||
|
||||
//板块管理
|
||||
MenuEntity plate = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "板块管理",
|
||||
PermissionCode = "bbs:plate:list",
|
||||
MenuType = MenuTypeEnum.Menu,
|
||||
Router = "plate",
|
||||
IsShow = true,
|
||||
IsLink = false,
|
||||
IsCache = true,
|
||||
Component = "bbs/plate/index",
|
||||
MenuIcon = "education",
|
||||
OrderNum = 100,
|
||||
ParentId = bbs.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(plate);
|
||||
|
||||
MenuEntity plateQuery = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "板块查询",
|
||||
PermissionCode = "bbs:plate:query",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = plate.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(plateQuery);
|
||||
|
||||
MenuEntity plateAdd = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "板块新增",
|
||||
PermissionCode = "bbs:plate:add",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = plate.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(plateAdd);
|
||||
|
||||
MenuEntity plateEdit = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "板块修改",
|
||||
PermissionCode = "bbs:plate:edit",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = plate.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(plateEdit);
|
||||
|
||||
MenuEntity plateRemove = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "板块删除",
|
||||
PermissionCode = "bbs:plate:remove",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = plate.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(plateRemove);
|
||||
|
||||
//默认值
|
||||
entities.ForEach(m =>
|
||||
{
|
||||
m.IsDeleted = false;
|
||||
m.State = true;
|
||||
});
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\framework\Yi.Framework.Data\Yi.Framework.Data.csproj" />
|
||||
<ProjectReference Include="..\..\rbac\Yi.RBAC.Domain\Yi.RBAC.Domain.csproj" />
|
||||
<ProjectReference Include="..\Yi.BBS.Domain.Shared\Yi.BBS.Domain.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -22,12 +22,18 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="ip2region.db">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="key.pem">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="public.pem">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="yi-sqlsugar-dev.db">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
BIN
Yi.Framework.Net6/src/project/BBS/Yi.BBS.Web/ip2region.db
Normal file
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
@@ -12,6 +12,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\framework\Yi.Framework.Data\Yi.Framework.Data.csproj" />
|
||||
<ProjectReference Include="..\..\rbac\Yi.RBAC.Domain\Yi.RBAC.Domain.csproj" />
|
||||
<ProjectReference Include="..\Yi.BBS.Domain.Shared\Yi.BBS.Domain.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -22,12 +22,18 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="ip2region.db">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="key.pem">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="public.pem">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="yi-sqlsugar-dev.db">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Yi.RBAC.Application.Identity
|
||||
|
||||
var entities = await _DbQueryable.WhereIF(!string.IsNullOrEmpty(input.MenuName), x => x.MenuName.Contains(input.MenuName!))
|
||||
.WhereIF(input.State is not null, x => x.State == input.State)
|
||||
.OrderByDescending(x=>x.OrderNum)
|
||||
.ToPageListAsync(input.PageNum, input.PageSize, total);
|
||||
return new PagedResultDto<MenuGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ namespace Yi.RBAC.Domain.DataSeeds
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<bool> IsInvoker()
|
||||
{
|
||||
return !await _repository.IsAnyAsync(x => x.MenuName == "系统管理");
|
||||
}
|
||||
public override List<MenuEntity> GetSeedData()
|
||||
{
|
||||
List<MenuEntity> entities = new List<MenuEntity>();
|
||||
@@ -107,88 +111,6 @@ namespace Yi.RBAC.Domain.DataSeeds
|
||||
entities.Add(swagger);
|
||||
|
||||
|
||||
//BBS
|
||||
MenuEntity bbs = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "BBS",
|
||||
MenuType = MenuTypeEnum.Catalogue,
|
||||
Router = "/bbs",
|
||||
IsShow = true,
|
||||
IsLink = false,
|
||||
MenuIcon = "international",
|
||||
OrderNum = 97,
|
||||
ParentId = 0,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(bbs);
|
||||
//文章管理
|
||||
MenuEntity article = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章管理",
|
||||
PermissionCode = "bbs:article:list",
|
||||
MenuType = MenuTypeEnum.Menu,
|
||||
Router = "article",
|
||||
IsShow = true,
|
||||
IsLink = false,
|
||||
IsCache = true,
|
||||
Component = "bbs/article/index",
|
||||
MenuIcon = "education",
|
||||
OrderNum = 100,
|
||||
ParentId = bbs.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(article);
|
||||
|
||||
MenuEntity articleQuery = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章查询",
|
||||
PermissionCode = "bbs:article:query",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = article.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(articleQuery);
|
||||
|
||||
MenuEntity articleAdd = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章新增",
|
||||
PermissionCode = "bbs:article:add",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = article.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(articleAdd);
|
||||
|
||||
MenuEntity articleEdit = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章修改",
|
||||
PermissionCode = "bbs:article:edit",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = article.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(articleEdit);
|
||||
|
||||
MenuEntity articleRemove = new MenuEntity()
|
||||
{
|
||||
Id = SnowflakeHelper.NextId,
|
||||
MenuName = "文章删除",
|
||||
PermissionCode = "bbs:article:remove",
|
||||
MenuType = MenuTypeEnum.Component,
|
||||
OrderNum = 100,
|
||||
ParentId = article.Id,
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(articleRemove);
|
||||
|
||||
//ERP
|
||||
MenuEntity erp = new MenuEntity()
|
||||
{
|
||||
@@ -1143,6 +1065,13 @@ namespace Yi.RBAC.Domain.DataSeeds
|
||||
IsDeleted = false
|
||||
};
|
||||
entities.Add(loginLogRemove);
|
||||
|
||||
//默认值
|
||||
entities.ForEach(m =>
|
||||
{
|
||||
m.IsDeleted = false;
|
||||
m.State = true;
|
||||
});
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@ VITE_APP_BASE_API = '/dev-api'
|
||||
# ws/开发环境
|
||||
VITE_APP_BASE_WS = '/dev-ws'
|
||||
|
||||
#BBS
|
||||
VITE_APP_BASE_URL='http://localhost:19003/api'
|
||||
|
||||
VITE_APP_BASE_URL='http://localhost:19001/api'
|
||||
#RBAC
|
||||
# VITE_APP_BASE_URL='http://localhost:19001/api'
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -219,7 +219,8 @@ const dataScopeOptions = ref([
|
||||
]);
|
||||
|
||||
const data = reactive({
|
||||
form: {},
|
||||
form: {
|
||||
},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
@@ -368,7 +369,7 @@ function reset() {
|
||||
roleName: undefined,
|
||||
roleCode: undefined,
|
||||
orderNum: 0,
|
||||
state: false,
|
||||
state: true,
|
||||
menuCheckStrictly: false,
|
||||
deptCheckStrictly: false,
|
||||
remark: undefined,
|
||||
|
||||