feat:完善discuss主题相关功能及界面
This commit is contained in:
@@ -36,8 +36,9 @@
|
||||
<el-col :span="14">
|
||||
<el-row class="left-div">
|
||||
<el-col :span="24">
|
||||
<AvatarInfo :size="50" :showWatching="true" :time="'2023-03-08 21:09:02'"></AvatarInfo>
|
||||
|
||||
<!-- {{ discuss.user }} -->
|
||||
<AvatarInfo :size="50" :showWatching="true" :time="discuss.creationTime" :userInfo="discuss.user"></AvatarInfo>
|
||||
<!-- :userInfo="{nick:'qwe'} -->
|
||||
<el-divider />
|
||||
<h2>{{ discuss.title }}</h2>
|
||||
<ArticleContentInfo :code="discuss.content??''"></ArticleContentInfo>
|
||||
@@ -137,6 +138,8 @@ const items = [{ user: "用户1" }, { user: "用户2" }, { user: "用户3" }];
|
||||
const articleData = ref([]);
|
||||
//主题内容
|
||||
const discuss = ref({});
|
||||
|
||||
|
||||
//当前默认选择的子文章
|
||||
const currentNodeKey=route.params.articleId;
|
||||
//目录数据
|
||||
|
||||
@@ -42,13 +42,30 @@
|
||||
</div>
|
||||
|
||||
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="推荐" name="first"> </el-tab-pane>
|
||||
<el-tab-pane label="最新" name="second"> </el-tab-pane>
|
||||
<el-tab-pane label="最热" name="third"> </el-tab-pane>
|
||||
<el-tabs v-model="activeName" @tab-change="handleClick">
|
||||
<el-tab-pane label="最新" name="new"> </el-tab-pane>
|
||||
<el-tab-pane label="推荐" name="suggest"> </el-tab-pane>
|
||||
<el-tab-pane label="最热" name="host"> </el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-collapse >
|
||||
<el-collapse-item >
|
||||
<template #title>
|
||||
<div class="collapse-top">
|
||||
已置顶主题<el-icon class="header-icon">
|
||||
<info-filled />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<div class="div-item" v-for="i in topDiscussList" >
|
||||
<DisscussCard :title="i.title" :introduction="i.introduction" :creationTime="i.creationTime" :id="i.id" :user="i.user" :color="i.color" :seeNum="i.seeNum" badge="置顶"/>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
<el-divider v-show="topDiscussList.length>0" />
|
||||
|
||||
<div class="div-item" v-for="i in discussList" >
|
||||
<DisscussCard :title="i.title" :introduction="i.introduction" :createTime="i.createTime" :id="i.id"/>
|
||||
<DisscussCard :title="i.title" :introduction="i.introduction" :creationTime="i.creationTime" :id="i.id" :color="i.color" :seeNum="i.seeNum" :user="i.user"/>
|
||||
</div>
|
||||
<div>
|
||||
<el-pagination
|
||||
@@ -70,25 +87,30 @@
|
||||
|
||||
<script setup>
|
||||
import DisscussCard from '@/components/DisscussCard.vue'
|
||||
import {getList} from '@/apis/discussApi.js'
|
||||
import {getList,getTopList} from '@/apis/discussApi.js'
|
||||
import { onMounted, ref,reactive } from 'vue'
|
||||
import { useRoute,useRouter } from 'vue-router'
|
||||
|
||||
//数据定义
|
||||
const route=useRoute()
|
||||
const router=useRouter()
|
||||
const activeName = ref('first')
|
||||
const activeName = ref('new')
|
||||
//主题内容
|
||||
const discussList=ref([]);
|
||||
//置顶主题内容
|
||||
const topDiscussList = ref([]);
|
||||
const total=ref(100)
|
||||
const query=reactive({
|
||||
pageNum:1,
|
||||
pageSize:10,
|
||||
title:'',
|
||||
plateId:route.params.plateId
|
||||
plateId:route.params.plateId,
|
||||
type:activeName.value
|
||||
})
|
||||
|
||||
const handleClick = (tab, event) => {
|
||||
console.log(tab, event)
|
||||
const handleClick =async (tab, event) => {
|
||||
query.type=activeName.value ;
|
||||
await loadDiscussList();
|
||||
}
|
||||
|
||||
onMounted(async()=>{
|
||||
@@ -100,6 +122,10 @@ const loadDiscussList=async()=>{
|
||||
const response= await getList(query);
|
||||
discussList.value=response.items;
|
||||
total.value=Number( response.total);
|
||||
|
||||
//全查,无需参数
|
||||
const topResponse=await getTopList();
|
||||
topDiscussList.value=topResponse.items;
|
||||
}
|
||||
|
||||
//进入添加主题页面
|
||||
@@ -130,6 +156,10 @@ background-color: #FFFFFF;
|
||||
padding: 1rem;
|
||||
margin: 1rem 0rem ;
|
||||
}
|
||||
.collapse-top
|
||||
{
|
||||
padding-left: 2rem;
|
||||
}
|
||||
.header .el-input
|
||||
{
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="route.query.artType == 'article'"
|
||||
label="名称:"
|
||||
label="子文章名称:"
|
||||
prop="name"
|
||||
>
|
||||
<el-input placeholder="请输入" v-model="editForm.name" />
|
||||
@@ -100,7 +100,10 @@ const ruleFormRef = ref(null);
|
||||
const rules = reactive({
|
||||
title: [
|
||||
{ required: true, message: "请输入标题", trigger: "blur" },
|
||||
{ min: 3, max: 20, message: "长度 3 到 20", trigger: "blur" },
|
||||
{ min: 3, max: 40, message: "长度 3 到 20", trigger: "blur" },
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: "请输入子文章名称", trigger: "blur" },
|
||||
],
|
||||
content: [
|
||||
{ required: true, message: "请输入内容", trigger: "blur" },
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" v-for="i in discussList">
|
||||
<DisscussCard :title="i.title" :introduction="i.introduction" :createTime="i.createTime" :id="i.id"/>
|
||||
<DisscussCard :title="i.title" :introduction="i.introduction" :creationTime="i.creationTime" :id="i.id" :user="i.user" :seeNum="i.seeNum"/>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
<el-input v-model="loginForm.userName" placeholder="用户名" />
|
||||
<el-input v-model="loginForm.password" placeholder="密码" show-password />
|
||||
<el-button class="login-btn" type="primary" @click="login" >登录</el-button>
|
||||
<br>
|
||||
<el-button class="login-btn" type="primary" @click="guestlogin" >游客临时登录</el-button>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
@@ -16,7 +18,12 @@ const loginForm=reactive({
|
||||
uuid:"",
|
||||
code:""
|
||||
})
|
||||
|
||||
const guestlogin=async ()=>{
|
||||
loginForm.userName="guest";
|
||||
loginForm.password="123456"
|
||||
await userStore.login(loginForm);
|
||||
router.push("/index")
|
||||
}
|
||||
const login=async ()=>{
|
||||
const response= await userStore.login(loginForm);
|
||||
if( response.code==undefined)
|
||||
@@ -38,5 +45,6 @@ margin:0rem 0 0.5rem 0;
|
||||
.login-btn
|
||||
{
|
||||
width: 100%;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
@@ -1,49 +1,44 @@
|
||||
<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">
|
||||
<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 :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'}">
|
||||
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
||||
<div class="avatar-upload-preview">
|
||||
<img :src="options.previews.url" :style="options.previews.img"/>
|
||||
<img :src="options.previews.url" :style="options.previews.img" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<br/>
|
||||
<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-icon class="el-icon--right">
|
||||
<Upload />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-col>
|
||||
<el-col :lg="{span: 1, offset: 2}" :md="2">
|
||||
<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-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-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-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-col :lg="{ span: 2, offset: 6 }" :md="2">
|
||||
<el-button type="primary" @click="uploadImg()">上传</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -56,11 +51,11 @@ 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";
|
||||
import { ref, reactive } from "vue";
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
const cropper=ref(null);
|
||||
const cropper = ref(null);
|
||||
|
||||
const open = ref(false);
|
||||
const visible = ref(false);
|
||||
@@ -89,7 +84,7 @@ function requestUpload() {
|
||||
};
|
||||
/** 向左旋转 */
|
||||
function rotateLeft() {
|
||||
cropper.value.rotateLeft();
|
||||
cropper.value.rotateLeft();
|
||||
};
|
||||
/** 向右旋转 */
|
||||
function rotateRight() {
|
||||
@@ -110,30 +105,20 @@ function beforeUpload(file) {
|
||||
reader.onload = () => {
|
||||
options.img = reader.result;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
/** 上传图片 */
|
||||
function uploadImg() {
|
||||
cropper.value.getCropBlob(data => {
|
||||
async function uploadImg() {
|
||||
await cropper.value.getCropBlob(async 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;
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
const response = await upload(formData)
|
||||
open.value = false;
|
||||
options.img = import.meta.env.VITE_APP_BASEAPI + "/file/" + response[0].id;
|
||||
userStore.icon = options.img;
|
||||
await updateUserIcon(response[0].id);
|
||||
alert("上传成功")
|
||||
});
|
||||
};
|
||||
/** 实时预览 */
|
||||
@@ -142,11 +127,12 @@ function realTime(data) {
|
||||
};
|
||||
/** 关闭窗口 */
|
||||
function closeDialog() {
|
||||
options.img = userStore.iocn;
|
||||
options.img = userStore.icon;
|
||||
options.visible = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.user-info-head {
|
||||
position: relative;
|
||||
@@ -171,4 +157,24 @@ function closeDialog() {
|
||||
line-height: 110px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<el-form ref="userRef" :model="user" :rules="rules" label-width="80px">
|
||||
<el-form-item label="用户昵称" prop="nickName">
|
||||
<el-form-item label="账号" prop="userName">
|
||||
<el-input v-model="user.userName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户昵称" prop="nick">
|
||||
<el-input v-model="user.nick" maxlength="30" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码" prop="phone">
|
||||
@@ -24,8 +27,9 @@
|
||||
|
||||
<script setup>
|
||||
import { updateUserProfile } from "@/apis/userApi";
|
||||
import useUserStore from "@/stores/user"
|
||||
import { ref } from "vue";
|
||||
|
||||
const userStore=useUserStore();
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object
|
||||
@@ -45,6 +49,10 @@ function submit() {
|
||||
userRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
updateUserProfile(props.user).then(response => {
|
||||
console.log(props.user.nick,"props.user.nick")
|
||||
console.log(userStore,"userStore.nick")
|
||||
userStore.name=props.user.nick
|
||||
console.log(userStore.name,"userStore.name");
|
||||
alert("修改成功");
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user