542 lines
14 KiB
Vue
542 lines
14 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<div class="circle-change">
|
||
<h3>圈子消息</h3>
|
||
<el-form :inline="true" size="mini" class="my-form">
|
||
<el-form-item>
|
||
<el-input :value="detail.advisor.deptName" disabled />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-input :value="detail.advisor.showName" disabled />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-select
|
||
v-model="changeGroupId"
|
||
filterable
|
||
remote
|
||
reserve-keyword
|
||
placeholder="请输入关键词"
|
||
:remote-method="getCircleList"
|
||
>
|
||
<el-option
|
||
v-for="item in circleOptions"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:value="item.id"
|
||
:disabled="item.id === detail.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button
|
||
type="primary"
|
||
:disabled="changeGroupId === detail.id"
|
||
@click="changeCircle"
|
||
>切换</el-button
|
||
>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<div class="circle-main">
|
||
<div class="circle-main-header">
|
||
<div class="circle-info">
|
||
<img :src="detail.coverImage" alt="" />
|
||
<div>
|
||
<h4>{{ detail.name }}</h4>
|
||
<p>{{ detail.remark }}</p>
|
||
</div>
|
||
</div>
|
||
<div class="circle-set">
|
||
<div class="set-item-wrap">
|
||
<div class="set-item mb10">
|
||
<label>开放观众发言:</label>
|
||
<el-switch
|
||
v-model="detail.interactiveStatus"
|
||
:active-value="1"
|
||
:inactive-value="2"
|
||
@change="changeSwitch(1)"
|
||
/>
|
||
</div>
|
||
<div class="set-item">
|
||
<label>先审后发:</label>
|
||
<el-switch
|
||
v-model="detail.firstAudit"
|
||
:active-value="1"
|
||
:inactive-value="2"
|
||
@change="changeSwitch(2)"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div class="set-item-wrap">
|
||
<div class="set-item mb10">
|
||
<label>隐藏用户昵称:</label>
|
||
<el-switch
|
||
v-model="detail.showNickName"
|
||
:active-value="2"
|
||
:inactive-value="1"
|
||
@change="changeSwitch(3)"
|
||
/>
|
||
</div>
|
||
<div class="set-item">
|
||
<label>隐藏圈子人数:</label>
|
||
<el-switch
|
||
v-model="detail.showMemberCount"
|
||
:active-value="2"
|
||
:inactive-value="1"
|
||
@change="changeSwitch(4)"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<img
|
||
class="icon"
|
||
src="@/assets/images/trumpet.png"
|
||
alt=""
|
||
@click="setNotice"
|
||
/>
|
||
<img
|
||
class="icon"
|
||
src="@/assets/images/data.png"
|
||
alt=""
|
||
@click="$router.push('/circle/data')"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div class="circle-content">
|
||
<div v-show="chatType === 1" class="circle-interact">
|
||
<div class="circle-interact-header">
|
||
<ul class="tabs">
|
||
<li
|
||
v-for="(item, index) in msgTabs"
|
||
:key="item.id"
|
||
:class="[msgType === item.id ? 'active' : '']"
|
||
@click="msgType = item.id"
|
||
>
|
||
{{ item.name }}
|
||
</li>
|
||
</ul>
|
||
<el-form :inline="true" size="mini" class="my-form">
|
||
<el-form-item label="">
|
||
<el-input v-model="msgKeyWord" placeholder="请输入内容搜索" />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" @click="onSearch">搜索</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<newsList
|
||
v-for="(item, index) in msgTabs"
|
||
v-show="msgType === item.id"
|
||
:ref="`newsListRef${item.id}`"
|
||
:group-id="detail.id"
|
||
:type="item.id"
|
||
:new-msg="newMsg"
|
||
:modifyStateObj="modifyStateObj"
|
||
@setReplyMsg="setReplyMsg"
|
||
@modifyStateCallback="modifyStateCallback"
|
||
/>
|
||
</div>
|
||
<privateChat
|
||
v-show="chatType === 2"
|
||
:user-info="privateUserInfo"
|
||
:private-new-msg="privateNewMsg"
|
||
:group-id="detail.id"
|
||
@closePrivateChat="closePrivateChat"
|
||
@setReplyMsg="setReplyMsg"
|
||
/>
|
||
<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>
|
||
<li
|
||
:class="[userTabIndex === 3 ? 'active' : '']"
|
||
@click="userTabIndex = 3"
|
||
>
|
||
禁言列表
|
||
</li>
|
||
</ul>
|
||
<userLnteractList
|
||
v-show="userTabIndex === 0"
|
||
:group-id="detail.id"
|
||
:new-msg="newMsg"
|
||
:modifyStateObj="modifyStateObj"
|
||
@setReplyMsg="setReplyMsg"
|
||
@toPrivateChat="toPrivateChat"
|
||
@modifyStateCallback="modifyStateCallback"
|
||
/>
|
||
<userList
|
||
v-show="userTabIndex === 1"
|
||
:key="1"
|
||
:group-id="detail.id"
|
||
:type="1"
|
||
@toPrivateChat="toPrivateChat"
|
||
@modifyStateCallback="modifyStateCallback"
|
||
/>
|
||
<privateList
|
||
v-show="userTabIndex === 2"
|
||
:group-id="detail.id"
|
||
:private-new-msg="privateNewMsg"
|
||
@toPrivateChat="toPrivateChat"
|
||
/>
|
||
<userList
|
||
v-show="userTabIndex === 3"
|
||
:key="2"
|
||
:group-id="detail.id"
|
||
:type="2"
|
||
:modifyStateObj="modifyStateObj"
|
||
@modifyStateCallback="modifyStateCallback"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div v-if="replyMsg.id" class="quote">
|
||
<div class="quote-content">
|
||
<label>用户:{{ replyMsg.userName }}</label>
|
||
<p v-if="replyMsg.contentType === 1">{{ replyMsg.content }}</p>
|
||
<p v-else-if="replyMsg.contentType === 2">[图片]</p>
|
||
</div>
|
||
<i class="el-icon-close" @click="setReplyMsg({})"></i>
|
||
</div>
|
||
<messageSend
|
||
v-if="detail.status === 3"
|
||
:reply-id="replyMsg.id"
|
||
:interactive-type="chatType"
|
||
:private-user-info="privateUserInfo"
|
||
:group-id="detail.id"
|
||
@sendCallBack="setReplyMsg"
|
||
/>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import {
|
||
getCircleList,
|
||
getCircleDetail,
|
||
setFirstAudit,
|
||
setInteractiveStatus,
|
||
setShowMemberCount,
|
||
setShowNickName,
|
||
setNotice
|
||
} from "@/api/circle.js";
|
||
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";
|
||
import { mapGetters } from "vuex";
|
||
import webSocketConnect from "./mixins/webSocketConnect";
|
||
export default {
|
||
components: {
|
||
newsList,
|
||
userLnteractList,
|
||
userList,
|
||
privateList,
|
||
messageSend,
|
||
privateChat
|
||
},
|
||
mixins: [webSocketConnect],
|
||
data() {
|
||
return {
|
||
changeGroupId: "",
|
||
msgTabs: [
|
||
{ name: "老师", id: 2 },
|
||
{ name: "全部", id: 1 },
|
||
{ name: "精选", id: 4 }
|
||
],
|
||
msgType: 1,
|
||
userTabIndex: 0,
|
||
chatType: 1, // 1 群聊 2 私聊
|
||
detail: {
|
||
advisor: {}
|
||
},
|
||
circleOptions: [],
|
||
msgKeyWord: "",
|
||
replyMsg: {}, // 引用的消息
|
||
newMsg: {},
|
||
privateUserInfo: {}, // 私聊用户的用户信息
|
||
privateNewMsg: {}, // 私聊最新推送消息
|
||
modifyStateObj: {} // 修改了状态的对象
|
||
};
|
||
},
|
||
computed: {
|
||
...mapGetters(["user"])
|
||
},
|
||
async created() {
|
||
await this.getCircleDetail();
|
||
this.getCircleList();
|
||
},
|
||
methods: {
|
||
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;
|
||
}
|
||
},
|
||
setNotice() {
|
||
this.$prompt("", "圈子公告", {
|
||
confirmButtonText: "确定",
|
||
cancelButtonText: "取消",
|
||
inputType: "textarea",
|
||
inputPlaceholder: "请输入公告内容,500字以内",
|
||
inputValue: this.detail.notice
|
||
})
|
||
.then(async ({ value }) => {
|
||
const ret = await setNotice({
|
||
id: this.detail.id,
|
||
notice: value
|
||
});
|
||
if (ret && ret.code === 0) {
|
||
this.$message({
|
||
type: "success",
|
||
message: "公告设置成功"
|
||
});
|
||
}
|
||
})
|
||
.catch(() => {
|
||
this.$message({
|
||
type: "info",
|
||
message: "取消输入"
|
||
});
|
||
});
|
||
},
|
||
toPrivateChat(userInfo) {
|
||
this.privateUserInfo = Object.assign({
|
||
privateUserId: userInfo.userId,
|
||
privateUserName: userInfo.userName
|
||
});
|
||
this.chatType = 2;
|
||
},
|
||
closePrivateChat() {
|
||
this.chatType = 1;
|
||
this.privateUserInfo = {};
|
||
},
|
||
async getCircleDetail() {
|
||
console.log(this.$route);
|
||
const ret = await getCircleDetail({ id: this.$route.query.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
|
||
}
|
||
};
|
||
const 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);
|
||
const body = JSON.parse(msg.body);
|
||
if ([1].includes(body.type)) {
|
||
// 1 文字消息和图片消息
|
||
this.newMsg = JSON.parse(msg.body).data;
|
||
}
|
||
},
|
||
handlePrivateChatTopic(msg) {
|
||
debugger;
|
||
console.log("handlePrivateChatTopic", msg);
|
||
const body = JSON.parse(msg.body);
|
||
if ([1].includes(body.type)) {
|
||
// 1 文字消息和图片消息
|
||
this.privateNewMsg = JSON.parse(msg.body).data;
|
||
}
|
||
},
|
||
setReplyMsg(msg) {
|
||
this.replyMsg = msg;
|
||
},
|
||
changeCircle() {
|
||
this.$router.replace(`/circle/detail?id=${this.changeGroupId}`);
|
||
this.msgKeyWord = "";
|
||
this.getCircleDetail();
|
||
},
|
||
modifyStateCallback(obj) {
|
||
// modifyType: 1审核通过 2禁言操作
|
||
this.modifyStateObj = obj;
|
||
}
|
||
}
|
||
};
|
||
</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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.quote {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
background: rgba(155, 155, 155, 0.2);
|
||
padding: 10px;
|
||
.quote-content {
|
||
display: flex;
|
||
p {
|
||
margin-left: 8px;
|
||
}
|
||
}
|
||
i {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
</style>
|