feat:完成权限相关、全局配置、优化细节
This commit is contained in:
@@ -7,10 +7,21 @@
|
||||
</el-config-provider>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ElConfigProvider } from 'element-plus'
|
||||
import useConfigStore from "@/stores/config";
|
||||
import { ElConfigProvider } from 'element-plus'
|
||||
import {onMounted } from "vue";
|
||||
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
const locale= zhCn;
|
||||
|
||||
const configStore = useConfigStore();
|
||||
|
||||
//加载全局信息
|
||||
onMounted(async()=>{
|
||||
|
||||
await configStore.getConfig();
|
||||
})
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
|
||||
9
Yi.BBS.Vue3/src/apis/configApi.js
Normal file
9
Yi.BBS.Vue3/src/apis/configApi.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import myaxios from '@/utils/request'
|
||||
|
||||
//获取配置
|
||||
export function getAll(){
|
||||
return myaxios({
|
||||
url: '/config',
|
||||
method: 'get'
|
||||
})
|
||||
};
|
||||
55
Yi.BBS.Vue3/src/components/AgreeInfo.vue
Normal file
55
Yi.BBS.Vue3/src/components/AgreeInfo.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<el-button text @click="agree">
|
||||
<el-icon v-if="data.isAgree" color="#409EFF">
|
||||
<CircleCheckFilled />
|
||||
</el-icon>
|
||||
<el-icon v-else color="#1E1E1E">
|
||||
<Pointer />
|
||||
</el-icon> 点赞:{{ data.agreeNum ?? 0 }}</el-button>
|
||||
</template>
|
||||
<script setup>
|
||||
import {onMounted,reactive,watch} from 'vue'
|
||||
import { operate } from '@/apis/agreeApi'
|
||||
|
||||
|
||||
//'isAgree','agreeNum','id'
|
||||
const props = defineProps([ 'data'])
|
||||
|
||||
watch(()=>props,(n)=>{
|
||||
data.id=n.data.id;
|
||||
data.isAgree=n.data.isAgree;
|
||||
data.agreeNum=n.data.agreeNum;
|
||||
},{deep:true})
|
||||
|
||||
|
||||
const data=reactive({
|
||||
id:'',
|
||||
isAgree:false,
|
||||
agreeNum:0
|
||||
})
|
||||
// onMounted(()=>{
|
||||
|
||||
// })
|
||||
//点赞操作
|
||||
const agree = async () => {
|
||||
const response = await operate(data.id)
|
||||
const res = response.data;
|
||||
//提示框,颜色区分
|
||||
if (res.isAgree) {
|
||||
data.isAgree = true;
|
||||
data.agreeNum += 1;
|
||||
ElMessage({
|
||||
message: res.message,
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
else {
|
||||
data.isAgree = false;
|
||||
data.agreeNum-= 1;
|
||||
ElMessage({
|
||||
message: res.message,
|
||||
type: 'warning',
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,14 +1,16 @@
|
||||
<template>
|
||||
<div class="botton-div">
|
||||
<a><el-icon><UserFilled /></el-icon>站长:橙子</a>
|
||||
<a><el-icon><Search /></el-icon>YiFramework意框架</a>
|
||||
<a><el-icon><UserFilled /></el-icon>站长:{{configStore.author}}</a>
|
||||
<a><el-icon><Search /></el-icon>{{configStore.bottom}}</a>
|
||||
<a><el-icon><View /></el-icon>关于本站</a>
|
||||
<a><el-icon><Message /></el-icon>建议反馈</a>
|
||||
<p></p>
|
||||
<a><el-icon><Position /></el-icon>2023 <span style="color: #40a9ff ;">意社区</span> | 赣ICP备xxxxxx号-4</a>
|
||||
<a ><el-icon><Position /></el-icon>{{configStore.icp}}</a>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import useConfigStore from "@/stores/config";
|
||||
const configStore= useConfigStore();
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-icon
|
||||
@@ -31,6 +33,6 @@ a:hover {
|
||||
height: auto;
|
||||
width: auto;
|
||||
justify-content: center;
|
||||
margin: 1rem auto;
|
||||
margin: 0.5rem auto;
|
||||
}
|
||||
</style>
|
||||
@@ -41,8 +41,8 @@
|
||||
<div class="item-description">
|
||||
{{ discuss.creationTime }}
|
||||
</div>
|
||||
|
||||
|
||||
<AgreeInfo :data="discuss"/>
|
||||
<!--
|
||||
<el-button text @click="agree">
|
||||
<el-icon v-if="discuss.isAgree" color="#409EFF">
|
||||
<CircleCheckFilled />
|
||||
@@ -51,7 +51,7 @@
|
||||
<Pointer />
|
||||
</el-icon> 点赞:{{ discuss.agreeNum ?? 0 }}</el-button>
|
||||
<el-button icon="Star" text>
|
||||
收藏</el-button>
|
||||
收藏</el-button> -->
|
||||
|
||||
<el-button icon="View" text>
|
||||
浏览数:{{ discuss.seeNum ?? 0 }}</el-button>
|
||||
@@ -69,6 +69,7 @@
|
||||
import { h, ref, toRef, onMounted ,reactive} from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import AvatarInfo from './AvatarInfo.vue';
|
||||
import AgreeInfo from './AgreeInfo.vue'
|
||||
import { operate } from '@/apis/agreeApi'
|
||||
|
||||
const props = defineProps(['discuss','badge'])
|
||||
|
||||
129
Yi.BBS.Vue3/src/components/UserSelectInfo.vue
Normal file
129
Yi.BBS.Vue3/src/components/UserSelectInfo.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<el-select
|
||||
style="width: 600px;"
|
||||
v-model="value"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
placeholder="请输入用户账号(可多选)"
|
||||
remote-show-suffix
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref,computed } from 'vue'
|
||||
import {listUser} from '@/apis/userApi'
|
||||
const props = defineProps(['modelValue'])
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
|
||||
//这个为可选择的列表,{value,label},value为用户id,label为账号名称(不可重复)
|
||||
const options = ref([])
|
||||
|
||||
const value = computed({
|
||||
get() {
|
||||
return props.modelValue
|
||||
},
|
||||
set(value) {
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
onMounted( async()=>{
|
||||
|
||||
const response= await listUser({ids:value.value.join()});
|
||||
const res=response.data.items;
|
||||
//下拉列表
|
||||
options.value = res
|
||||
.map((item) => {
|
||||
return { value: `${item.id}`, label: `用户:${item.userName}` }
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
const loadUser=async(query)=>{
|
||||
const response= await listUser({userName:query});
|
||||
const res=response.data.items;
|
||||
//下拉列表
|
||||
options.value = res
|
||||
.map((item) => {
|
||||
return { value: `${item.id}`, label: `用户:${item.userName}` }
|
||||
})
|
||||
}
|
||||
|
||||
const remoteMethod =async (query) => {
|
||||
if (query) {
|
||||
loading.value = true
|
||||
await loadUser(query);
|
||||
loading.value = false
|
||||
} else {
|
||||
options.value = []
|
||||
}
|
||||
}
|
||||
|
||||
const states = [
|
||||
'Alabama',
|
||||
'Alaska',
|
||||
'Arizona',
|
||||
'Arkansas',
|
||||
'California',
|
||||
'Colorado',
|
||||
'Connecticut',
|
||||
'Delaware',
|
||||
'Florida',
|
||||
'Georgia',
|
||||
'Hawaii',
|
||||
'Idaho',
|
||||
'Illinois',
|
||||
'Indiana',
|
||||
'Iowa',
|
||||
'Kansas',
|
||||
'Kentucky',
|
||||
'Louisiana',
|
||||
'Maine',
|
||||
'Maryland',
|
||||
'Massachusetts',
|
||||
'Michigan',
|
||||
'Minnesota',
|
||||
'Mississippi',
|
||||
'Missouri',
|
||||
'Montana',
|
||||
'Nebraska',
|
||||
'Nevada',
|
||||
'New Hampshire',
|
||||
'New Jersey',
|
||||
'New Mexico',
|
||||
'New York',
|
||||
'North Carolina',
|
||||
'North Dakota',
|
||||
'Ohio',
|
||||
'Oklahoma',
|
||||
'Oregon',
|
||||
'Pennsylvania',
|
||||
'Rhode Island',
|
||||
'South Carolina',
|
||||
'South Dakota',
|
||||
'Tennessee',
|
||||
'Texas',
|
||||
'Utah',
|
||||
'Vermont',
|
||||
'Virginia',
|
||||
'Washington',
|
||||
'West Virginia',
|
||||
'Wisconsin',
|
||||
'Wyoming',
|
||||
]
|
||||
</script>
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
>
|
||||
<el-menu-item class="logo" index="" @click="enterIndex" >
|
||||
<img class="img-icon" style="width: 35px; height: 35px" src="@/assets/logo.ico" />Yi意社区</el-menu-item>
|
||||
<img class="img-icon" style="width: 35px; height: 35px" src="@/assets/logo.ico" />{{configStore.name}}</el-menu-item>
|
||||
<el-menu-item index="1" @click="enterIndex">主页</el-menu-item>
|
||||
<el-sub-menu index="2">
|
||||
<template #title>学习</template>
|
||||
@@ -56,6 +56,8 @@ import AvatarInfo from '@/components/AvatarInfo.vue'
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import useUserStore from '@/stores/user.js'
|
||||
import useConfigStore from "@/stores/config";
|
||||
const configStore= useConfigStore();
|
||||
const router = useRouter()
|
||||
const userStore =useUserStore();
|
||||
const activeIndex = ref('1')
|
||||
|
||||
22
Yi.BBS.Vue3/src/stores/config.js
Normal file
22
Yi.BBS.Vue3/src/stores/config.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import {getAll} from '@/apis/configApi'
|
||||
import { defineStore } from 'pinia'
|
||||
const useConfigStore = defineStore('config',
|
||||
{
|
||||
state: () => ({
|
||||
data: []
|
||||
}),
|
||||
getters: {
|
||||
name:(state)=>state.data.filter(s=> s.configKey=='bbs.site.name').map(x=>x.configValue)[0],
|
||||
author:(state)=>state.data.filter(s=> s.configKey=='bbs.site.author').map(x=>x.configValue)[0],
|
||||
icp:(state)=>state.data.filter(s=> s.configKey=='bbs.site.icp').map(x=>x.configValue)[0],
|
||||
bottom:(state)=>state.data.filter(s=>s.configKey=='bbs.site.bottom').map(x=>x.configValue)[0]
|
||||
},
|
||||
actions: {
|
||||
// 登录
|
||||
async getConfig() {
|
||||
const response = await getAll();
|
||||
this.data = response.data.items;
|
||||
},
|
||||
},
|
||||
})
|
||||
export default useConfigStore;
|
||||
@@ -20,11 +20,15 @@ const myaxios = axios.create({
|
||||
// }
|
||||
// }],
|
||||
})
|
||||
|
||||
|
||||
|
||||
// 请求拦截器
|
||||
myaxios.interceptors.request.use(function (config) {
|
||||
if (getToken()) {
|
||||
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
|
||||
return config;
|
||||
}, function (error) {
|
||||
return Promise.reject(error);
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<el-divider class="tab-divider" />
|
||||
|
||||
<el-space :size="10" :spacer="spacer">
|
||||
<el-button icon="Pointer" text> 4</el-button>
|
||||
<AgreeInfo :data="discuss"/>
|
||||
<el-button icon="Star" text> 0</el-button>
|
||||
<el-button icon="Share" text> 分享</el-button>
|
||||
<el-button icon="Operation" text> 操作</el-button>
|
||||
@@ -134,7 +134,7 @@ import CommentInfo from "@/components/CommentInfo.vue";
|
||||
import BottomInfo from '@/components/BottomInfo.vue'
|
||||
import TreeArticleInfo from "@/components/TreeArticleInfo.vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
import AgreeInfo from '@/components/AgreeInfo.vue'
|
||||
import { get as discussGet, del as discussDel } from "@/apis/discussApi.js";
|
||||
import { all as articleall, del as articleDel, get as articleGet } from "@/apis/articleApi.js";
|
||||
//数据定义
|
||||
|
||||
@@ -213,4 +213,9 @@ display: flex;
|
||||
.collapse-list >>> .el-collapse-item__header {
|
||||
border-bottom-color: #F0F2F5 !important;
|
||||
}
|
||||
|
||||
.el-divider
|
||||
{
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
</style>
|
||||
@@ -18,6 +18,10 @@
|
||||
<el-radio-button label="User">部分用户可见</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="可见用户:" v-if="route.query.artType == 'discuss' && perRadio=='User'">
|
||||
<UserSelectInfo v-model="editForm.permissionUserIds"/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
|
||||
<el-form-item v-if="route.query.artType == 'article'" label="子文章名称:" prop="name">
|
||||
@@ -59,6 +63,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import MavonEdit from "@/components/MavonEdit.vue";
|
||||
import UserSelectInfo from '@/components/UserSelectInfo.vue'
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
@@ -103,6 +108,7 @@ const editForm = reactive({
|
||||
introduction: "",
|
||||
content: "",
|
||||
name: "",
|
||||
permissionUserIds:[]
|
||||
});
|
||||
|
||||
//组装主题内容: 需要更新主题信息
|
||||
@@ -145,6 +151,8 @@ const submit = async (formEl) => {
|
||||
discuss.plateId = discuss.plateId ?? route.query.plateId
|
||||
discuss.cover=dialogImageUrl.value;
|
||||
discuss.permissionType=perRadio.value;
|
||||
|
||||
discuss.permissionUserIds=editForm.permissionUserIds;
|
||||
//主题创建
|
||||
if (route.query.operType == "create") {
|
||||
const response = await discussAdd(discuss);
|
||||
@@ -231,6 +239,7 @@ const loadDiscuss = async () => {
|
||||
discuss.plateId = res.plateId;
|
||||
dialogImageUrl.value= res.cover;
|
||||
perRadio.value=res.permissionType;
|
||||
editForm.permissionUserIds=res.permissionUserIds;
|
||||
};
|
||||
//加载文章
|
||||
const loadArticle = async () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="login-wrapper">
|
||||
<h1>意社区-登录</h1>
|
||||
<h1>{{configStore.name}}-登录</h1>
|
||||
<div class="login-form">
|
||||
<div class="username form-item">
|
||||
<span>使用邮箱或者手机号</span>
|
||||
@@ -38,6 +38,8 @@
|
||||
import { reactive } from 'vue';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import useUserStore from '@/stores/user.js'
|
||||
import useConfigStore from "@/stores/config";
|
||||
const configStore= useConfigStore();
|
||||
const userStore = useUserStore();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
</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 :label="'Male'">男</el-radio>
|
||||
<el-radio :label="'Woman'">女</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
|
||||
Reference in New Issue
Block a user