This commit is contained in:
cansnow
2025-12-24 04:12:56 +08:00
parent f49f1f1ad1
commit f289f79813
26 changed files with 636 additions and 484 deletions
+54 -8
View File
@@ -1,20 +1,38 @@
<template>
<view class="n-ps-all-base">
<uv-parse v-if="content" :content="content"></uv-parse>
<view class="n-flex-row" v-if="showButton" :style="{marginTop:'100rpx'}">
<uv-button class="n-flex-1 n-ms-base" v-for="(item, idx) in buttonList" :key="idx" @click="switchButton(idx, item)" :text="item.title" :icon="'/static/image/' + item.value + '.png'" :plain="current==idx" :color="current==idx ? item.color:'#f8f8f8'" :customStyle="{height:'80rpx'}" :customTextStyle="{color:current==idx ? item.color:'#333333',marginLeft:'20rpx'}" shape="circle" color="#f8f8f8" throttleTime="1000"></uv-button>
<uni-nav-bar
left-icon="back"
@clickLeft="goto(1)"
fixed
statusBar
:title="title">
</uni-nav-bar>
<view class="u-content">
<u-parse
v-if="content"
:domain="config.website"
:previewImg="false"
:showImgMenu="false"
:content="content">
</u-parse>
</view>
<uv-empty :show="empty" icon="/static/image/empty.png" text="暂无数据~" width="200" marginTop="100"></uv-empty>
<view class="n-flex-row" v-if="showButton" :style="{marginTop:'100rpx'}">
<u-button class="n-flex-1 n-ms-base" v-for="(item, idx) in buttonList" :key="idx" @click="switchButton(idx, item)" :text="item.title" :icon="'/static/image/' + item.value + '.png'" :plain="current==idx" :color="current==idx ? item.color:'#f8f8f8'" :customStyle="{height:'80rpx'}" :customTextStyle="{color:current==idx ? item.color:'#333333',marginLeft:'20rpx'}" shape="circle" color="#f8f8f8" throttleTime="1000"></u-button>
</view>
<u-empty :show="empty" icon="/static/image/empty.png" text="暂无数据~" width="200" marginTop="100"></u-empty>
</view>
</template>
<script>
import {getArticle} from '@/api/login.js'
import {getSpage,getArticle} from '@/api/login.js'
import { mapGetters } from "vuex";
import util from "@/util"
export default {
data() {
return {
empty: false,
title:"",
content: '',
current: null,
questionId: 0,
@@ -28,9 +46,14 @@
onLoad(evt) {
if(evt.type=='config') this.setConfig(evt)
if(evt.type=='question') this.setQuestion(evt)
if(evt.type=='article') this.setArticle(evt)
if(evt.type=='spage') this.setSpage(evt)
this.title = evt.title;
uni.setNavigationBarTitle({title:evt.title})
},
computed:{
...mapGetters(["config"]),
},
methods: {
// 设置配置内容
setConfig(evt) {
@@ -47,15 +70,38 @@
this.questionId = evt.id
this.showButton = true
},
setArticle(evt) {
this.showButton = false;
getArticle(evt.id).then(res=>{
this.content = res.content
}).catch(e=>{
console.log(e);
})
},
setSpage(evt) {
this.showButton = false;
getSpage(evt.name).then(res=>{
this.content = res.content
}).catch(e=>{
console.log(e);
})
},
// 切换按钮
switchButton(idx, item) {
this.current = idx
getArticle({id:this.questionId,type:item.value})
}
},
goto:util.goto
}
}
</script>
<style>
<style lang="scss" scoped>
.u-content {
padding: 24rpx;
font-size: 32rpx;
color: $u-content-color;
line-height: 1.6;
}
</style>
+249 -276
View File
@@ -1,309 +1,282 @@
<template>
<view class="group_card_container">
<custom-nav-bar title="" />
<u-toast ref="uToast"></u-toast>
<view class="group_card_container">
<custom-nav-bar title="" />
<u-toast ref="uToast"></u-toast>
<view class="main">
<view class="base_info">
<my-avatar :src="sourceGroupInfo.faceURL" :isGroup="true" size="48" />
<view>
<view class="group_name">
<text>{{ sourceGroupInfo.groupName }}</text>
<text v-if="!!sourceGroupInfo.memberCount"
>{{ sourceGroupInfo.memberCount }}</text
>
</view>
<view class="create_time">
<u-icon name="clock" color="#999" size="14"></u-icon>
<text>{{ getCreateTime }}</text>
</view>
</view>
</view>
<view class="main">
<view class="base_info">
<my-avatar :src="sourceGroupInfo.faceURL" :isGroup="true" size="48" />
<view>
<view class="group_name">
<text>{{ sourceGroupInfo.groupName }}</text>
<text v-if="!!sourceGroupInfo.memberCount">{{ sourceGroupInfo.memberCount }}</text>
</view>
<view class="create_time">
<u-icon name="clock" color="#999" size="14"></u-icon>
<text>{{ getCreateTime }}</text>
</view>
</view>
</view>
<view
v-if="!!sourceGroupInfo.memberCount"
@click="toMemberList"
class="member_row info_row"
>
<view class="member_desc">
<text>群成员</text>
<text class="member_count">{{
<view v-if="!!sourceGroupInfo.memberCount" @click="toMemberList" class="member_row info_row">
<view class="member_desc">
<text>群成员</text>
<text class="member_count">{{
`${sourceGroupInfo.memberCount}`
}}</text>
<u-icon name="arrow-right" color="#999" size="18"></u-icon>
</view>
<view class="member_list">
<my-avatar
v-for="member in getRenderMemberList"
:key="member.userID"
class="member_item"
size="42"
:src="member.faceURL"
:desc="member.nickname"
></my-avatar>
<u-avatar
bgColor="#5496EB"
icon="more-dot-fill"
shape="square"
size="42"
></u-avatar>
</view>
</view>
<u-icon name="arrow-right" color="#999" size="18"></u-icon>
</view>
<view class="member_list">
<my-avatar v-for="member in getRenderMemberList" :key="member.userID" class="member_item" size="42"
:src="member.faceURL" :desc="member.nickname"></my-avatar>
<u-avatar bgColor="#5496EB" icon="more-dot-fill" shape="square" size="42"></u-avatar>
</view>
</view>
<view class="info_row">
<user-info-row-item lable="群ID号" :content="sourceGroupInfo.groupID" />
</view>
</view>
<view class="info_row">
<user-info-row-item lable="群ID号" :content="sourceGroupInfo.groupID" />
</view>
</view>
<view class="action_row">
<u-button type="primary" v-if="!isJoinedGroup" @click="joinGroup"
>申请加入该群</u-button
>
<u-button type="primary" v-else @click="chatingInGroup">发消息</u-button>
</view>
</view>
<view class="action_row">
<u-button type="primary" v-if="!isJoinedGroup" @click="joinGroup">申请加入该群</u-button>
<u-button type="primary" v-else @click="chatingInGroup">发消息</u-button>
</view>
</view>
</template>
<script>
import { GroupMemberListTypes } from "@/constant";
import { navigateToDesignatedConversation } from "@/util/imCommon";
import IMSDK, {
GroupVerificationType,
SessionType,
} from "openim-uniapp-polyfill";
import dayjs from "dayjs";
import MyAvatar from "@/components/MyAvatar/index.vue";
import CustomNavBar from "@/components/CustomNavBar/index.vue";
import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue";
import {GroupMemberListTypes} from "@/constant";
import {navigateToDesignatedConversation} from "@/util/imCommon";
import IMSDK, {GroupVerificationType,SessionType,} from "openim-uniapp-polyfill";
import dayjs from "dayjs";
import MyAvatar from "@/components/MyAvatar/index.vue";
import CustomNavBar from "@/components/CustomNavBar/index.vue";
import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue";
import userIcon from "static/images/contact_my_friend.png";
import userIcon from "static/images/contact_my_friend.png";
export default {
components: {
CustomNavBar,
MyAvatar,
UserInfoRowItem,
},
data() {
return {
sourceID: "",
isScan: false,
sourceGroupInfo: {},
groupMemberList: [],
};
},
computed: {
isJoinedGroup() {
return (
this.$store.getters.storeGroupList.findIndex(
(group) => group.groupID === this.sourceID,
) !== -1
);
},
getCreateTime() {
return dayjs(this.sourceGroupInfo.createTime).format("YYYY-MM-DD");
},
getRenderMemberList() {
if (this.isJoinedGroup) {
this.groupMemberList;
return this.groupMemberList;
}
const memberCount = this.sourceGroupInfo.memberCount ?? 0;
return new Array(memberCount >= 6 ? 6 : memberCount)
.fill(1)
.map((item, idx) => ({
userID: idx,
src: userIcon,
}));
},
},
onLoad(options) {
const { sourceID, sourceInfo, isScan } = options;
this.isScan = !!isScan;
if (sourceID) {
this.sourceID = sourceID;
this.getSourceGroupInfo();
} else {
const info = JSON.parse(sourceInfo);
this.sourceID = info.groupID;
this.sourceGroupInfo = {
...info,
};
}
this.getGroupMemberList();
},
methods: {
toMemberList() {
if (this.isJoinedGroup) {
this.$store.dispatch("conversation/getCurrentGroup", this.sourceID);
this.$store.dispatch(
"conversation/getCurrentMemberInGroup",
this.sourceID,
);
uni.navigateTo({
url: `/pages/conversation/groupMemberList/index?type=${GroupMemberListTypes.Preview}&groupID=${this.sourceID}`,
});
}
},
joinGroup() {
uni.$u.route("/pages/common/sendAddRequest/index", {
isGroup: true,
sourceID: this.sourceID,
isScan: this.isScan,
notNeedVerification:
this.sourceGroupInfo.needVerification ===
GroupVerificationType.AllNot,
sessionType: SessionType.WorkingGroup,
});
},
chatingInGroup() {
navigateToDesignatedConversation(
this.sourceID,
SessionType.WorkingGroup,
).catch(() => this.showToast("获取会话信息失败"));
},
async getSourceGroupInfo() {
let info = null;
if (this.isJoinedGroup) {
info = this.$store.getters.storeGroupList.find(
(group) => group.groupID === this.sourceID,
);
} else {
try {
const { data } = await IMSDK.asyncApi(
IMSDK.IMMethods.GetSpecifiedGroupsInfo,
IMSDK.uuid(),
[this.sourceID],
);
info = data[0] ?? {};
} catch (e) {
info = {};
}
}
this.sourceGroupInfo = {
...info,
};
},
getGroupMemberList() {
if (this.isJoinedGroup) {
IMSDK.asyncApi(IMSDK.IMMethods.GetGroupMemberList, IMSDK.uuid(), {
groupID: this.sourceID,
filter: 0,
offset: 0,
count: 6,
}).then(({ data }) => {
this.groupMemberList = [...data];
});
}
},
showToast(message) {
this.$refs.uToast.show({
message,
});
},
},
};
export default {
components: {CustomNavBar,MyAvatar,UserInfoRowItem,},
data() {
return {
sourceID: "",
isScan: false,
sourceGroupInfo: {},
groupMemberList: [],
};
},
computed: {
isJoinedGroup() {
return (this.$store.getters.storeGroupList.findIndex((group) => group.groupID === this.sourceID,) !== -1);
},
getCreateTime() {
return dayjs(this.sourceGroupInfo.createTime).format("YYYY-MM-DD");
},
getRenderMemberList() {
if (this.isJoinedGroup) {
this.groupMemberList;
return this.groupMemberList;
}
const memberCount = this.sourceGroupInfo.memberCount ?? 0;
return new Array(memberCount >= 6 ? 6 : memberCount)
.fill(1)
.map((item, idx) => ({
userID: idx,
src: userIcon,
}));
},
},
onLoad(options) {
const {sourceID,sourceInfo,isScan} = options;
this.isScan = !!isScan;
if (sourceID) {
this.sourceID = sourceID;
this.getSourceGroupInfo();
} else {
const info = JSON.parse(sourceInfo);
this.sourceID = info.groupID;
this.sourceGroupInfo = {
...info,
};
}
this.getGroupMemberList();
},
methods: {
toMemberList() {
if (this.isJoinedGroup) {
this.$store.dispatch("conversation/getCurrentGroup", this.sourceID);
this.$store.dispatch(
"conversation/getCurrentMemberInGroup",
this.sourceID,
);
uni.navigateTo({
url: `/pages/conversation/groupMemberList/index?type=${GroupMemberListTypes.Preview}&groupID=${this.sourceID}`,
});
}
},
joinGroup() {
uni.$u.route("/pages/common/sendAddRequest/index", {
isGroup: true,
sourceID: this.sourceID,
isScan: this.isScan,
notNeedVerification: this.sourceGroupInfo.needVerification ===
GroupVerificationType.AllNot,
sessionType: SessionType.WorkingGroup,
});
},
chatingInGroup() {
navigateToDesignatedConversation(
this.sourceID,
SessionType.WorkingGroup,
).catch(() => this.showToast("获取会话信息失败"));
},
async getSourceGroupInfo() {
let info = null;
if (this.isJoinedGroup) {
info = this.$store.getters.storeGroupList.find(
(group) => group.groupID === this.sourceID,
);
} else {
try {
const {
data
} = await IMSDK.asyncApi(
IMSDK.IMMethods.GetSpecifiedGroupsInfo,
IMSDK.uuid(),
[this.sourceID],
);
info = data[0] ?? {};
} catch (e) {
info = {};
}
}
this.sourceGroupInfo = {
...info,
};
},
getGroupMemberList() {
if (this.isJoinedGroup) {
IMSDK.asyncApi(IMSDK.IMMethods.GetGroupMemberList, IMSDK.uuid(), {
groupID: this.sourceID,
filter: 0,
offset: 0,
count: 6,
}).then(({
data
}) => {
this.groupMemberList = [...data];
});
}
},
showToast(message) {
this.$refs.uToast.show({
message,
});
},
},
};
</script>
<style lang="scss" scoped>
.group_card_container {
@include colBox(false);
height: 100vh;
background-color: #f6f6f6;
.group_card_container {
@include colBox(false);
height: 100vh;
background-color: #f6f6f6;
.main {
display: flex;
flex-direction: column;
flex: 1;
}
.main {
display: flex;
flex-direction: column;
flex: 1;
}
.base_info {
@include vCenterBox();
background-color: #fff;
padding: 44rpx;
margin-bottom: 18rpx;
.base_info {
@include vCenterBox();
background-color: #fff;
padding: 44rpx;
margin-bottom: 18rpx;
.u-avatar {
margin-right: 24rpx;
}
.u-avatar {
margin-right: 24rpx;
}
.group_name {
display: flex;
margin-bottom: 12rpx;
}
.group_name {
display: flex;
margin-bottom: 12rpx;
}
.create_time {
@include vCenterBox();
justify-content: center;
color: #adadad;
font-size: 26rpx;
.create_time {
@include vCenterBox();
justify-content: center;
color: #adadad;
font-size: 26rpx;
.u-icon {
margin-right: 12rpx;
}
}
}
.u-icon {
margin-right: 12rpx;
}
}
}
.member_row {
padding: 24rpx 44rpx;
.member_row {
padding: 24rpx 44rpx;
.member_desc {
margin-bottom: 24rpx;
position: relative;
.member_desc {
margin-bottom: 24rpx;
position: relative;
.member_count {
font-size: 28rpx;
color: #adadad;
margin-left: 24rpx;
}
.member_count {
font-size: 28rpx;
color: #adadad;
margin-left: 24rpx;
}
.u-icon {
position: absolute;
right: 0;
top: 0;
}
}
.u-icon {
position: absolute;
right: 0;
top: 0;
}
}
.member_list {
display: flex;
.member_list {
display: flex;
.member_item {
margin-right: 12rpx;
.member_item {
margin-right: 12rpx;
&:nth-child(7) {
margin-right: 0;
}
}
}
}
&:nth-child(7) {
margin-right: 0;
}
}
}
}
.info_row {
background-color: #fff;
margin-bottom: 24rpx;
.info_row {
background-color: #fff;
margin-bottom: 24rpx;
::v-deep .content {
color: #adadad;
}
}
::v-deep .content {
color: #adadad;
}
}
.action_row {
background-color: #fff;
padding: 44rpx 44rpx;
}
.action_row {
background-color: #fff;
padding: 44rpx 44rpx;
}
.online_state {
@include vCenterBox();
margin-left: 24rpx;
font-size: 24rpx;
color: #999;
.online_state {
@include vCenterBox();
margin-left: 24rpx;
font-size: 24rpx;
color: #999;
.dot {
background-color: #10cc64;
width: 12rpx;
height: 12rpx;
border-radius: 50%;
margin-right: 12rpx;
}
}
}
</style>
.dot {
background-color: #10cc64;
width: 12rpx;
height: 12rpx;
border-radius: 50%;
margin-right: 12rpx;
}
}
}
</style>
-1
View File
@@ -86,7 +86,6 @@
);
info = data[0];
}
console.log(info)
if (info) {
uni.navigateTo({
url: `/pages/common/groupCard/index?sourceInfo=${JSON.stringify(info,)}`,
+85 -46
View File
@@ -14,11 +14,11 @@
</uni-nav-bar>
<view style="flex:1;display: flex;flex-direction: column;align-items: center;justify-content: center;">
<view class="info_card">
<my-avatar :src="userInfo.faceURL" :desc="userInfo.nickname" size="64" />
<my-avatar :src="source.faceURL" :desc="source.showName" size="64" />
<view class="id_row">
<text class="nickname">{{ userInfo.nickname }}</text>
<view class="id_row_copy" @click="copy">
<text class="id">{{ userInfo.userID }}</text>
<text class="nickname">{{ source.showName }}</text>
<view class="id_row_copy" @click="copy(source.code)">
<text class="id">{{ source.code }}</text>
<image style="width: 32rpx; height: 32rpx" src="@/static/images/id_copy.png" mode="" />
</view>
</view>
@@ -29,7 +29,7 @@
<view style="width: 80%;display: flex;align-items: center;justify-content: center;height: 20%;">
<u-button type="default" plain :hairline="false" iconColor="#9aa2b2" @click="scan">扫一扫</u-button>
<u-button type="default" plain :hairline="false" iconColor="#9aa2b2">换个样式</u-button>
<u-button type="default" plain :hairline="false" iconColor="#9aa2b2">保存图片</u-button>
<u-button @click="save" type="default" plain :hairline="false" iconColor="#9aa2b2">保存图片</u-button>
</view>
</view>
</template>
@@ -39,6 +39,8 @@
import QRCode from "@/components/qrcode.js";
import UserBase from '@/components/User.vue';
import util from "@/util";
import { mapGetters } from "vuex";
import md5 from "md5";
export default {
mixins:[UserBase],
components: {
@@ -46,15 +48,54 @@
},
data() {
return {
qrcodeUrl:"",
qrcode_src:"",
source:{
type:"user",
showName:"",
faceURL:"",
code:"",
}
}
},
onLoad() {
console.log(this.userInfo)
computed:{
...mapGetters(["storeFriendList","storeGroupList","config"]),
},
onLoad(opt) {
if(opt.sourceInfo){
this.source = JSON.parse(opt.sourceInfo);
}else{
this.source = {
type:"user",
showName:"",
faceURL:"",
code:"",
};
}
console.log(this.config);
if(this.source.type == "user"){
this.qrcodeUrl = `${this.config.website}/u/${this.source.code}`;
}else{
this.qrcodeUrl = `${this.config.website}/g/${this.source.code}`;
}
console.log(this.qrcodeUrl);
this.createQrcode();
},
methods: {
...util,
save(){
const _this = this;
uni.saveImageToPhotosAlbum({
filePath:_this.qrcode_src,
success() {
util.success("保存成功");
},
fail(e) {
console.log(e);
util.error("保存失败");
}
})
},
createQrcode() {
const _this = this;
return new Promise((resolve, reject) => {
@@ -64,7 +105,7 @@
usingComponents: true, // 是否是自定义组件
showLoading: false, // 是否显示loading
loadingText: "", // loading文字
text: "/pages/common/invite_register?code=", // 生成内容
text: `${this.qrcodeUrl}`, // 生成内容
size: 320, // 二维码大小
background: "#fff", // 背景色
foreground: '#000000', // 前景色
@@ -73,7 +114,7 @@
image: "", // 二维码图标
imageSize: 40, // 二维码图标大小
cbResult: function(res) { // 生成二维码的回调
//_this.qrcode_src = (res)
_this.qrcode_src = (res)
//resolve(res);
},
});
@@ -84,48 +125,46 @@
</script>
<style scoped lang="scss">
.info_card {
width: 600rpx;
height: 196rpx;
border-radius: 6px;
background: #fff;
margin: 0 auto 0 auto;
padding: 0 36rpx;
color: #0c1c33;
.info_card {
width: 600rpx;
border-radius: 6px;
background: #fff;
margin: 0 auto 0 auto;
padding: 40rpx 36rpx;
color: #0c1c33;
display: flex;
align-items: center;
.id_row {
display: flex;
align-items: center;
margin-left: 16rpx;
flex-direction: column;
align-items: flex-start;
justify-content: space-around;
height: 100%;
flex: 1;
font-size: 28rpx;
.id_row {
&_copy {
@include vCenterBox();
display: flex;
//height: 46px;
margin-left: 16rpx;
flex-direction: column;
align-items: flex-start;
justify-content: space-between;
flex: 1;
font-size: 28rpx;
&_copy {
@include vCenterBox();
}
.nickname {
@include nomalEllipsis();
max-width: 400rpx;
font-weight: 500;
font-size: 34rpx;
}
.id {
color: #8e9ab0;
}
}
img {
width: 18px;
height: 18px;
.nickname {
@include nomalEllipsis();
max-width: 400rpx;
font-weight: 500;
font-size: 34rpx;
}
.id {
color: #8e9ab0;
}
}
img {
width: 18px;
height: 18px;
}
}
</style>