509 lines
13 KiB
Vue
Raw Normal View History

2025-01-26 21:07:26 +08:00
<template>
<div class="app-container">
<div class="circle-change">
<h3>圈子消息</h3>
2025-02-08 23:04:37 +08:00
<el-form :inline="true" size="mini" class="my-form">
<el-form-item>
<el-input :value="detail.advisor.deptName" disabled></el-input>
2025-01-26 21:07:26 +08:00
</el-form-item>
2025-02-08 23:04:37 +08:00
<el-form-item>
<el-input :value="detail.advisor.showName" disabled></el-input>
2025-01-26 21:07:26 +08:00
</el-form-item>
2025-02-08 23:04:37 +08:00
<el-form-item>
<el-select
v-model="changeGroupId"
filterable
remote
reserve-keyword
placeholder="请输入关键词"
:remote-method="getCircleList"
>
<el-option
:key="detail.id"
:label="detail.name"
:value="detail.id"
disabled
>
</el-option>
<el-option
v-for="item in circleOptions"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
2025-01-26 21:07:26 +08:00
</el-select>
</el-form-item>
<el-form-item>
2025-02-08 23:04:37 +08:00
<el-button type="primary" :disabled="changeGroupId === detail.id"
>切换</el-button
>
2025-01-26 21:07:26 +08:00
</el-form-item>
</el-form>
</div>
<div class="circle-main">
<div class="circle-main-header">
<div class="circle-info">
2025-02-08 23:04:37 +08:00
<img :src="detail.coverImage" alt="" />
2025-01-26 21:07:26 +08:00
<div>
2025-02-08 23:04:37 +08:00
<h4>{{ detail.name }}</h4>
<p>{{ detail.remark }}</p>
2025-01-26 21:07:26 +08:00
</div>
</div>
<div class="circle-set">
<div class="set-item-wrap">
<div class="set-item mb10">
<label>开放观众发言</label>
2025-02-08 23:04:37 +08:00
<el-switch
v-model="detail.interactiveStatus"
:active-value="1"
:inactive-value="2"
@change="changeSwitch(1)"
>
</el-switch>
2025-01-26 21:07:26 +08:00
</div>
<div class="set-item">
<label>先审后发</label>
2025-02-08 23:04:37 +08:00
<el-switch
v-model="detail.firstAudit"
:active-value="1"
:inactive-value="2"
@change="changeSwitch(2)"
>
</el-switch>
2025-01-26 21:07:26 +08:00
</div>
</div>
<div class="set-item-wrap">
<div class="set-item mb10">
<label>隐藏用户昵称</label>
2025-02-08 23:04:37 +08:00
<el-switch
v-model="detail.showNickName"
:active-value="2"
:inactive-value="1"
@change="changeSwitch(3)"
>
</el-switch>
2025-01-26 21:07:26 +08:00
</div>
<div class="set-item">
<label>隐藏圈子人数</label>
2025-02-08 23:04:37 +08:00
<el-switch
v-model="detail.showMemberCount"
:active-value="2"
:inactive-value="1"
@change="changeSwitch(4)"
>
</el-switch>
2025-01-26 21:07:26 +08:00
</div>
</div>
2025-02-08 23:04:37 +08:00
<img
class="icon"
@click="setNotice"
src="@/assets/images/trumpet.png"
alt=""
/>
2025-01-31 22:10:53 +08:00
<img
class="icon"
src="@/assets/images/data.png"
alt=""
@click="$router.push('/circle/data')"
/>
2025-01-26 21:07:26 +08:00
</div>
</div>
<div class="circle-content">
<div class="circle-interact" v-if="chatType === 1">
<div class="circle-interact-header">
<ul class="tabs">
2025-02-08 23:04:37 +08:00
<li
:class="[msgType === item.id ? 'active' : '']"
v-for="(item, index) in msgTabs"
:key="item.id"
@click="msgType = item.id"
>
{{ item.name }}
</li>
2025-01-26 21:07:26 +08:00
</ul>
2025-02-08 23:04:37 +08:00
<el-form :inline="true" size="mini" class="my-form">
2025-01-26 21:07:26 +08:00
<el-form-item label="">
2025-02-08 23:04:37 +08:00
<el-input v-model="msgKeyWord" placeholder="请输入内容搜索" />
2025-01-26 21:07:26 +08:00
</el-form-item>
<el-form-item>
2025-02-08 23:04:37 +08:00
<el-button type="primary" @click="onSearch">搜索</el-button>
2025-01-26 21:07:26 +08:00
</el-form-item>
</el-form>
</div>
2025-02-08 23:04:37 +08:00
<newsList
v-for="(item, index) in msgTabs"
:ref="`newsListRef${item.id}`"
:groupId="detail.id"
:type="item.id"
v-show="msgType === item.id"
@setReplyMsg="setReplyMsg"
:newMsg="newMsg"
/>
2025-01-26 21:07:26 +08:00
</div>
2025-02-08 23:04:37 +08:00
<privateChat
:userInfo="privateUserInfo"
:groupId="detail.id"
v-else
@closePrivateChat="() => (chatType = 1)"
/>
2025-01-26 21:07:26 +08:00
<div class="circle-user">
<ul class="tabs">
<li
:class="[userTabIndex === 0 ? 'active' : '']"
@click="userTabIndex = 0"
>
用户互动
</li>
<li
:class="[userTabIndex === 1 ? 'active' : '']"
@click="userTabIndex = 1"
>
用户列表
</li>
<li
:class="[userTabIndex === 2 ? 'active' : '']"
@click="userTabIndex = 2"
>
私聊列表
</li>
2025-02-08 23:04:37 +08:00
<li
:class="[userTabIndex === 3 ? 'active' : '']"
@click="userTabIndex = 3"
>
禁言列表
</li>
2025-01-26 21:07:26 +08:00
</ul>
2025-02-08 23:04:37 +08:00
<userLnteractList
v-show="userTabIndex === 0"
:groupId="detail.id"
:newMsg="newMsg"
@setReplyMsg="setReplyMsg"
@toPrivateChat="toPrivateChat"
/>
<userList v-if="userTabIndex === 1" type="1" />
2025-01-26 21:07:26 +08:00
<privateList
2025-02-08 23:04:37 +08:00
v-show="userTabIndex === 2"
:groupId="detail.id"
@toPrivateChat="toPrivateChat"
/>
<userList
v-if="userTabIndex === 4"
2025-01-26 21:07:26 +08:00
@toPrivateChat="toPrivateChat"
2025-02-08 23:04:37 +08:00
type="2"
2025-01-26 21:07:26 +08:00
/>
</div>
</div>
</div>
2025-02-08 23:04:37 +08:00
<div class="quote" v-if="replyMsg.id">
2025-01-31 22:10:53 +08:00
<div class="quote-content">
2025-02-08 23:04:37 +08:00
<label>用户{{ replyMsg.userName }}</label>
<p v-if="replyMsg.contentType === 1">{{ replyMsg.content }}</p>
<p v-else-if="replyMsg.contentType === 2">[图片]</p>
2025-01-31 22:10:53 +08:00
</div>
<i class="el-icon-close"></i>
</div>
2025-02-08 23:04:37 +08:00
<messageSend
v-if="detail.status === 3"
:replyId="replyMsg.id"
:interactiveType="chatType"
:groupId="detail.id"
@sendCallBack="setReplyMsg"
/>
2025-01-26 21:07:26 +08:00
</div>
</template>
<script>
2025-02-08 23:04:37 +08:00
import {
getCircleList,
getCircleDetail,
setFirstAudit,
setInteractiveStatus,
setShowMemberCount,
setShowNickName,
setNotice
} from "@/api/circle.js";
2025-01-26 21:07:26 +08:00
import newsList from "./components/newsList.vue";
import userLnteractList from "./components/userLnteractList.vue";
import userList from "./components/userList.vue";
import privateList from "./components/privateList";
import messageSend from "./components/messageSend.vue";
import privateChat from "./components/privateChat.vue";
2025-02-08 23:04:37 +08:00
import { mapGetters } from "vuex";
import webSocketConnect from "./mixins/webSocketConnect";
2025-01-26 21:07:26 +08:00
export default {
components: {
newsList,
userLnteractList,
userList,
privateList,
messageSend,
privateChat
},
data() {
return {
2025-02-08 23:04:37 +08:00
changeGroupId: "",
msgTabs: [
{ name: "老师", id: 2 },
{ name: "全部", id: 1 },
{ name: "精选", id: 4 }
],
msgType: 1,
2025-01-26 21:07:26 +08:00
userTabIndex: 0,
2025-02-08 23:04:37 +08:00
chatType: 1, // 1 群聊 2 私聊
detail: {
advisor: {}
},
circleOptions: [],
msgKeyWord: "",
replyMsg: {}, // 引用的消息
newMsg: {}
2025-01-26 21:07:26 +08:00
};
},
2025-02-08 23:04:37 +08:00
mixins: [webSocketConnect],
computed: {
...mapGetters(["user"])
},
async created() {
await this.getCircleDetail();
this.getCircleList();
},
2025-01-26 21:07:26 +08:00
methods: {
2025-02-08 23:04:37 +08:00
async getCircleList(name) {
const ret = await getCircleList({
advisorId: this.detail.advisor.id,
current: 1,
name,
size: 10,
userType: this.user.user.userType
});
if (ret && ret.code === 0) {
this.circleOptions = ret.data.list.filter(
item => item.id !== this.detail.id
);
}
},
2025-01-26 21:07:26 +08:00
setNotice() {
this.$prompt("", "圈子公告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputType: "textarea",
inputPlaceholder: "请输入公告内容500字以内"
})
2025-02-08 23:04:37 +08:00
.then(async ({ value }) => {
let ret = await setNotice({
id: this.detail.id,
notice: value
2025-01-26 21:07:26 +08:00
});
2025-02-08 23:04:37 +08:00
if (ret && ret.code === 0) {
this.$message({
type: "success",
message: "公告设置成功"
});
}
2025-01-26 21:07:26 +08:00
})
.catch(() => {
this.$message({
type: "info",
message: "取消输入"
});
});
},
2025-02-08 23:04:37 +08:00
toPrivateChat(userInfo) {
this.privateUserInfo = userInfo;
2025-01-26 21:07:26 +08:00
this.chatType = 2;
2025-02-08 23:04:37 +08:00
},
async getCircleDetail() {
console.log(this.$route);
let ret = await getCircleDetail({ id: this.$route.params.id });
if (ret && ret.code === 0) {
this.detail = ret.data;
this.changeGroupId = this.detail.id;
this.connect(this.detail.id);
}
},
async changeSwitch(type) {
const option = {
1: {
// 开放观众发言
key: "interactiveStatus",
fn: setInteractiveStatus
},
2: {
// 先审后发
key: "firstAudit",
fn: setFirstAudit
},
3: {
// 隐藏用户昵称
key: "showNickName",
fn: setShowNickName
},
4: {
// 隐藏用户昵称
key: "showMemberCount",
fn: setShowMemberCount
}
};
let ret = await option[type].fn({
groupId: this.detail.id,
status: this.detail[option[type].key]
});
if (!ret && ret.code !== 0) {
}
},
onSearch() {
this.$refs[`newsListRef${this.msgType}`][0].searchMsg(this.msgKeyWord);
},
handleGroupChatTopic(msg) {
console.log("handleGroupChatTopic", msg);
debugger;
const body = JSON.parse(msg.body);
if ([1].includes(body.type)) {
// 1 文字消息和图片消息
this.newMsg = JSON.parse(msg.body).data;
}
},
handlePrivateChatTopic(msg) {
console.log("handlePrivateChatTopic", msg);
},
setReplyMsg(msg) {
this.replyMsg = msg;
2025-01-26 21:07:26 +08:00
}
}
};
</script>
<style lang="scss" scoped>
.my-form {
::v-deep .el-form-item--mini.el-form-item {
margin-bottom: 0;
}
}
.circle-change {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
h3 {
margin: 0;
font-size: 16px;
}
}
.circle-main-header {
align-items: center;
padding: 8px 10px;
display: flex;
justify-content: space-between;
background-color: rgba(134, 134, 134, 0.1);
margin-bottom: 10px;
.circle-info {
display: flex;
align-items: center;
img {
width: 50px;
height: 50px;
border-radius: 50%;
margin-right: 10px;
}
h4 {
margin: 0 0 10px;
font-size: 14px;
}
p {
font-size: 14px;
color: #999;
margin: 0;
}
}
.circle-set {
display: flex;
align-items: center;
.set-item {
display: flex;
align-items: center;
justify-content: end;
margin-left: 5px;
&.mb10 {
margin-bottom: 6px;
}
label {
color: #666;
font-size: 14px;
}
}
.icon {
width: 30px;
height: 30px;
margin-left: 16px;
cursor: pointer;
}
}
}
.circle-content {
display: flex;
background-color: rgba(134, 134, 134, 0.1);
padding: 0 10px 10px;
.circle-interact {
display: flex;
flex-direction: column;
flex: 1;
.circle-interact-header {
display: flex;
align-items: center;
justify-content: space-between;
.tabs {
list-style: none;
display: flex;
padding: 10px;
margin: 0;
li {
padding: 4px 10px;
font-size: 14px;
color: #666;
cursor: pointer;
&.active {
color: #000;
font-weight: bold;
}
}
}
}
}
.circle-user {
width: 420px;
margin-left: 10px;
.tabs {
list-style: none;
display: flex;
padding: 10px 0;
margin: 0;
li {
flex: 1;
padding: 4px 10px;
font-size: 14px;
color: #666;
cursor: pointer;
&.active {
color: #1990ff;
font-weight: bold;
}
}
}
}
}
2025-01-31 22:10:53 +08:00
.quote {
display: flex;
justify-content: space-between;
background: rgba(155, 155, 155, 0.2);
padding: 10px;
.quote-content {
display: flex;
2025-02-08 23:04:37 +08:00
p {
margin-left: 8px;
}
2025-01-31 22:10:53 +08:00
}
i {
cursor: pointer;
}
}
2025-01-26 21:07:26 +08:00
</style>