Compare commits
23 Commits
59d1ba9a7e
..
uniapp
| Author | SHA1 | Date | |
|---|---|---|---|
| 271ec4b9c2 | |||
| abd279e7a7 | |||
| 7c6656d1fc | |||
| 6720c15e30 | |||
| 2860c46ec1 | |||
| 47d10945a6 | |||
| 560b214af4 | |||
| 1f4a588d3b | |||
| 35a41d8358 | |||
| 37b53b54ff | |||
| db99bebcb4 | |||
| dd16348558 | |||
| e39c06526d | |||
| 2a0677014a | |||
| c38846f13b | |||
| 941464c330 | |||
| 825ac3457d | |||
| 7913a63a39 | |||
| 78386d4cc1 | |||
| 09c7889525 | |||
| 974d149d25 | |||
| f289f79813 | |||
| f49f1f1ad1 |
@@ -44,3 +44,5 @@ OpenIM_*
|
||||
|
||||
# plugin
|
||||
/nativeplugins
|
||||
android-keeplive
|
||||
sl-notify
|
||||
|
||||
@@ -1,36 +1,41 @@
|
||||
<script>
|
||||
import {mapGetters,mapActions} from "vuex";
|
||||
// #ifdef APP
|
||||
import IMSDK, {IMMethods,MessageType,SessionType,} from "openim-uniapp-polyfill";
|
||||
import config from "./common/config";
|
||||
// #endif
|
||||
import config from "@/common/config";
|
||||
import {getDbDir,toastWithCallback} from "@/util/common.js";
|
||||
import {conversationSort} from "@/util/imCommon";
|
||||
import {checkUpgrade} from "@/api/login.js"
|
||||
import {getConversationContent,conversationSort,prepareConversationState,updateTabbar} from "@/util/imCommon";
|
||||
import {PageEvents,UpdateMessageTypes} from "@/constant";
|
||||
|
||||
import checkUpgrade from "@/util/app_update.js"
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
console.log("App Launch");
|
||||
this.$store.dispatch("system/getConfig");
|
||||
// #ifdef APP
|
||||
plus.screen.lockOrientation("portrait-primary");
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
//screen.orientation.type = "";
|
||||
screen.orientation.lock('portrait');
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
console.error(
|
||||
`暂时不支持运行到 Web,如果需要移动端的 Web 项目,参考 [H5 demo](https://github.com/openimsdk/openim-h5-demo)`
|
||||
`暂时不支持运行到小程序端`
|
||||
);
|
||||
return ;
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
console.error(`暂时不支持运行到小程序端`);
|
||||
// #endif
|
||||
this.checkUpdate();
|
||||
this.setGlobalIMlistener();
|
||||
this.tryLogin();
|
||||
this.init();
|
||||
},
|
||||
onShow: function() {
|
||||
console.log("App Show");
|
||||
//console.log("App Show");
|
||||
// #ifdef APP
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), false);
|
||||
// #endif
|
||||
this.handleArguments();
|
||||
//console.log(this.$store.state.contact);
|
||||
},
|
||||
onHide: function() {
|
||||
console.log("App Hide");
|
||||
//console.log("App Hide");
|
||||
// #ifdef APP
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), true);
|
||||
// #endif
|
||||
@@ -46,8 +51,27 @@
|
||||
"storeHistoryMessageList",
|
||||
"storeIsSyncing",
|
||||
"storeGroupList",
|
||||
"config",
|
||||
'storeUnHandleFriendApplicationNum',
|
||||
'storeUnHandleGroupApplicationNum',
|
||||
'storeUnReadCount',
|
||||
'storeCircleUnreadCount'
|
||||
]),
|
||||
},
|
||||
watch:{
|
||||
storeUnReadCount(){
|
||||
updateTabbar(0);
|
||||
},
|
||||
storeUnHandleFriendApplicationNum(){
|
||||
updateTabbar(1);
|
||||
},
|
||||
storeUnHandleGroupApplicationNum(){
|
||||
updateTabbar(1);
|
||||
},
|
||||
storeCircleUnreadCount(){
|
||||
updateTabbar(2);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions("message", ["pushNewMessage", "updateOneMessage"]),
|
||||
...mapActions("conversation", ["updateCurrentMemberInGroup"]),
|
||||
@@ -68,9 +92,23 @@
|
||||
"pushNewSentGroupApplition",
|
||||
"updateSentGroupApplition",
|
||||
]),
|
||||
init(){
|
||||
//uni.setStorageSync('BusinessToken','eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3ZWJtYW4udGlueXdhbi5jbiIsImF1ZCI6IndlYm1hbi50aW55d2FuLmNuIiwiaWF0IjoxNzcwMTAyMjc2LCJuYmYiOjE3NzAxMDIyNzYsImV4cCI6MTc3MDcwNzA3NiwiZXh0ZW5kIjp7ImlkIjoxMDA3MDMsInVzZXJuYW1lIjoiMTg2MTE4ODI2MjMiLCJjbGllbnQiOiJXRUIifX0.yZ2u4cCZq2hLRAIpCKUs8GZkut7CObmfApIZGP_L2ro');
|
||||
//uni.setStorageSync('IMToken','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOiJKTTZHMEVWMjVSIiwiUGxhdGZvcm1JRCI6MiwiZXhwIjoxNzc3ODc4Mjc2LCJpYXQiOjE3NzAxMDIyNzF9.rKWz00yCB36CexCahW-HhsFZfKIFcfkuOYLKApQWQT0 ');
|
||||
//uni.setStorageSync('IMUserID','JM6G0EV25R');
|
||||
const IMToken = uni.getStorageSync("IMToken");
|
||||
const IMUserID = uni.getStorageSync("IMUserID")+'';
|
||||
if (IMToken && IMUserID) {
|
||||
// #ifdef APP
|
||||
this.tryLogin();
|
||||
// #endif
|
||||
}else{
|
||||
plus.navigator.closeSplashscreen();
|
||||
//uni.$u.route("/pages/common/login/index");
|
||||
}
|
||||
},
|
||||
setGlobalIMlistener() {
|
||||
this.$store.dispatch("system/getConfig");
|
||||
console.log("setGlobalIMlistener");
|
||||
//console.log("setGlobalIMlistener");
|
||||
// init
|
||||
const kickHander = (message) => {
|
||||
toastWithCallback(message, () => {
|
||||
@@ -80,27 +118,32 @@
|
||||
uni.removeStorage({
|
||||
key: "BusinessToken",
|
||||
});
|
||||
uni.$u.route("/pages/login/index");
|
||||
uni.$u.route("/pages/common/login/index");
|
||||
});
|
||||
};
|
||||
//由于 APP 管理员强制用户下线,或由于登录策略导致用户被踢下线
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnKickedOffline, (data) => {
|
||||
kickHander("您的账号在其他设备登录,请重新登陆!");
|
||||
});
|
||||
//token无效回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnUserTokenExpired, (data) => {
|
||||
kickHander("您的登录已过期,请重新登陆!");
|
||||
});
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnUserTokenInvalid, (data) => {
|
||||
kickHander("您的登录已无效,请重新登陆!");
|
||||
});
|
||||
|
||||
|
||||
// sync
|
||||
//向服务器同步会话开始时的回调。
|
||||
const syncStartHandler = ({data}) => {
|
||||
this.$store.commit("user/SET_IS_SYNCING", true);
|
||||
this.$store.commit("user/SET_REINSTALL", data);
|
||||
};
|
||||
//同步中
|
||||
const syncProgressHandler = ({data}) => {
|
||||
this.$store.commit("user/SET_PROGRESS", data);
|
||||
};
|
||||
//向服务器同步会话成功时的回调。
|
||||
const syncFinishHandler = () => {
|
||||
uni.hideLoading();
|
||||
this.$store.dispatch("conversation/getConversationList");
|
||||
@@ -109,6 +152,7 @@
|
||||
this.$store.dispatch("conversation/getUnReadCount");
|
||||
this.$store.commit("user/SET_IS_SYNCING", false);
|
||||
};
|
||||
//向服务器同步会话失败时的回调。
|
||||
const syncFailedHandler = () => {
|
||||
uni.hideLoading();
|
||||
uni.$u.toast("同步消息失败");
|
||||
@@ -116,65 +160,67 @@
|
||||
this.$store.dispatch("conversation/getUnReadCount");
|
||||
this.$store.commit("user/SET_IS_SYNCING", false);
|
||||
};
|
||||
//向服务器同步会话开始时的回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerStart, syncStartHandler);
|
||||
//向服务器同步会话成功时的回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerFinish, syncFinishHandler);
|
||||
//向服务器同步会话失败时的回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerFailed, syncFailedHandler);
|
||||
//同步中
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerProgress, syncProgressHandler);
|
||||
|
||||
// self
|
||||
const selfInfoUpdateHandler = ({data}) => {
|
||||
|
||||
// 当前登录用户个人信息改变时会收到此回调。
|
||||
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnSelfInfoUpdated, ({data}) => {
|
||||
this.$store.commit("user/SET_SELF_INFO", {
|
||||
...this.storeSelfInfo,
|
||||
...data,
|
||||
});
|
||||
};
|
||||
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnSelfInfoUpdated, selfInfoUpdateHandler);
|
||||
|
||||
});
|
||||
|
||||
// message
|
||||
const newMessagesHandler = ({data}) => {
|
||||
//接收到新消息时会收到此回调,回调中只会携带一条消息。
|
||||
//设置了批量消息监听setBatchMsgListener时,此回调不会触发。
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnRecvNewMessage, ({data}) =>{});
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnRecvNewMessages, ({data}) => {
|
||||
if (this.storeIsSyncing) {
|
||||
return;
|
||||
}
|
||||
console.log(data);
|
||||
data.forEach(this.handleNewMessage);
|
||||
};
|
||||
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnRecvNewMessages, newMessagesHandler);
|
||||
|
||||
// friend
|
||||
const friendInfoChangeHandler = ({data}) => {
|
||||
console.log('friendInfoChangeHandler',data);
|
||||
});
|
||||
|
||||
//好友个人信息(包括备注)改变时会收到此回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnFriendInfoChanged,({data}) => {
|
||||
//console.log('friendInfoChangeHandler',data);
|
||||
uni.$emit(IMSDK.IMEvents.OnFriendInfoChanged, {data});
|
||||
this.updateFriendInfo({friendInfo: data,});
|
||||
};
|
||||
const friendAddedHandler = ({data}) => {
|
||||
});
|
||||
//两个用户成功建立好友关系后双方都会收到该回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnFriendAdded, ({data}) => {
|
||||
this.pushNewFriend(data);
|
||||
};
|
||||
const friendDeletedHander = ({data}) => {
|
||||
});
|
||||
//某个用户的好友列表减少时会收到该回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnFriendDeleted, ({data}) => {
|
||||
this.updateFriendInfo({
|
||||
friendInfo: data,
|
||||
isRemove: true,
|
||||
});
|
||||
};
|
||||
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnFriendInfoChanged,friendInfoChangeHandler);
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnFriendAdded, friendAddedHandler);
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnFriendDeleted, friendDeletedHander);
|
||||
|
||||
});
|
||||
|
||||
// blacklist
|
||||
const blackAddedHandler = ({data}) => {
|
||||
//某个用户的黑名单列表增加时会收到该回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnBlackAdded, ({data}) => {
|
||||
this.pushNewBlack(data);
|
||||
};
|
||||
const blackDeletedHandler = ({data}) => {
|
||||
});
|
||||
//某个用户的黑名单列表减少时会收到该回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnBlackDeleted, ({data}) => {
|
||||
this.updateBlackInfo({
|
||||
blackInfo: data,
|
||||
isRemove: true,
|
||||
});
|
||||
};
|
||||
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnBlackAdded, blackAddedHandler);
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnBlackDeleted, blackDeletedHandler);
|
||||
|
||||
});
|
||||
|
||||
// group
|
||||
const joinedGroupAddedHandler = ({data}) => {
|
||||
this.pushNewGroup(data);
|
||||
@@ -196,12 +242,15 @@
|
||||
this.updateCurrentMemberInGroup(data);
|
||||
}
|
||||
};
|
||||
|
||||
//用户所在群组的数量增加时(被邀请入群、入群申请被同意等),会收到此回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnJoinedGroupAdded,joinedGroupAddedHandler);
|
||||
//用户所在群组的数量减少时(主动退群、群被解散等),会收到此回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnJoinedGroupDeleted,joinedGroupDeletedHandler);
|
||||
//群组信息(头像、群名称等,也包括群主变化)改变时,该群所有群成员会收到此回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnGroupInfoChanged,groupInfoChangedHandler);
|
||||
//群成员信息改变(群昵称、头像等)后回调,该群所有群成员会收到此回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnGroupMemberInfoChanged,groupMemberInfoChangedHandler);
|
||||
|
||||
|
||||
// application
|
||||
const friendApplicationNumHandler = ({data}) => {
|
||||
const isRecv = data.toUserID === this.storeCurrentUserID;
|
||||
@@ -212,6 +261,7 @@
|
||||
}
|
||||
};
|
||||
const friendApplicationAccessHandler = ({data}) => {
|
||||
console.log(data);
|
||||
const isRecv = data.toUserID === this.storeCurrentUserID;
|
||||
if (isRecv) {
|
||||
this.updateRecvFriendApplition({
|
||||
@@ -243,14 +293,61 @@
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//用户发起好友申请后,申请发起者和接收者都会收到此回调,接收者可以选择同意或拒绝好友申请。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnFriendApplicationAdded,friendApplicationNumHandler);
|
||||
//好友申请被同意时,申请发起方和接收方都会收到该回调,双方成功建立好友关系。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnFriendApplicationAccepted,friendApplicationAccessHandler);
|
||||
//好友申请被拒绝时,申请发起方和接收方都会收到该回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnFriendApplicationRejected,friendApplicationAccessHandler);
|
||||
//用户发起好友申请后,申请发起者和接收者都会收到此回调,接收者可以选择同意或拒绝好友申请。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnGroupApplicationAdded,groupApplicationNumHandler);
|
||||
//好友申请被同意时,申请发起方和接收方都会收到该回调,双方成功建立好友关系。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnGroupApplicationAccepted,groupApplicationAccessHandler);
|
||||
//好友申请被拒绝时,申请发起方和接收方都会收到该回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnGroupApplicationRejected,groupApplicationAccessHandler);
|
||||
|
||||
//群组被解散时,该群所有群成员会收到此回调。
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnGroupDismissed,({ data })=>{});
|
||||
//群成员增加(如用户被邀请进群),其他群成员会收到此回调。
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnGroupMemberAdded,({ data })=>{});
|
||||
//群成员增加(如用户被邀请进群),群成员减少(如群成员退群), 其他群成员会收到此回调。。
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnGroupMemberDeleted,({ data })=>{});
|
||||
const deleteLocalMsg = (clientMsgID)=>{
|
||||
let list = this.storeHistoryMessageList;
|
||||
//console.log(data);
|
||||
list = list.filter((item)=>{
|
||||
return item.clientMsgID != clientMsgID;
|
||||
})
|
||||
this.$store.commit('message/SET_HISTORY_MESSAGE_LIST',list);
|
||||
}
|
||||
//收到的消息被撤回或自己发出的消息被撤回时,会收到此回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnNewRecvMessageRevoked,({data})=>{
|
||||
//console.log('onNewRecvMessageRevoked',res);
|
||||
deleteLocalMsg(data.clientMsgID);
|
||||
});
|
||||
//自己发出的单聊消息被对方标记为已读后,消息发送者会收到此回调。
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnRecvC2CReadReceipt,({ data })=>{});
|
||||
//自己发出的群聊消息被群成员标记为已读后,消息发送者和标记者均会收到此回调。
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnRecvGroupReadReceipt,({ data })=>{});
|
||||
//当应用在后台运行,接收到新消息时,会收到该回调,回调中只会携带一条消息。
|
||||
//设置了批量消息监听setBatchMsgListener时,此回调不会触发。
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnRecvOfflineNewMessage,({ data })=>{});
|
||||
//当应用在后台运行,接收到新消息时,会收到该回调,回调中可能会携带多条消息。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnRecvOfflineNewMessages,({data})=>{
|
||||
data.forEach(this.handleOfflineNewMessages);
|
||||
});
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnMsgDeleted,({data})=>{
|
||||
deleteLocalMsg(data.clientMsgID)
|
||||
});
|
||||
//已订阅用户的在线状态发生变化时,会触发此回调。
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnUserStatusChanged,({ data })=>{});
|
||||
//建立WebSocket连接失败返回后,触发此回调
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnConnectFailed,({ data })=>{});
|
||||
//建立WebSocket连接成功返回后,触发此回调
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnConnectSuccess,({ data })=>{});
|
||||
//建立WebSocket连接中,触发此回调
|
||||
//IMSDK.subscribe(IMSDK.IMEvents.OnConnecting,({ data })=>{});
|
||||
//正在输入状态回调。
|
||||
//IMSDK.subscribe('onInputStatusChanged',({ data })=>{});
|
||||
// conversation
|
||||
const totalUnreadCountChangedHandler = ({data}) => {
|
||||
if (this.storeIsSyncing) {
|
||||
@@ -284,79 +381,106 @@
|
||||
const result = [...data, ...filterArr];
|
||||
this.$store.commit("conversation/SET_CONVERSATION_LIST",conversationSort(result));
|
||||
};
|
||||
|
||||
//会话总未读发生变化时的回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnTotalUnreadMessageCountChanged,totalUnreadCountChangedHandler);
|
||||
//有新会话产生时,会收到此回调。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnNewConversation, newConversationHandler);
|
||||
//某些会话的关键信息发生变化时,会触发该回调,例如会话的未读数发生变化,会话的最后一条消息发生变化等。
|
||||
IMSDK.subscribe(IMSDK.IMEvents.OnConversationChanged,conversationChangedHandler);
|
||||
|
||||
},
|
||||
|
||||
tryLogin() {
|
||||
const initStore = () => {
|
||||
this.$store.dispatch("user/getSelfInfo");
|
||||
this.$store.dispatch("conversation/getConversationList");
|
||||
this.$store.dispatch("conversation/getUnReadCount");
|
||||
this.$store.dispatch("contact/getBlacklist");
|
||||
this.$store.dispatch("contact/getRecvFriendApplications");
|
||||
this.$store.dispatch("contact/getSentFriendApplications");
|
||||
this.$store.dispatch("contact/getRecvGroupApplications");
|
||||
this.$store.dispatch("contact/getSentGroupApplications");
|
||||
this.$store.dispatch("contact/getFriendList");
|
||||
this.$store.dispatch("circle/getFriendCircleInfo");
|
||||
uni.switchTab({
|
||||
url: "/pages/conversation/conversationList/index?isRedirect=true"
|
||||
});
|
||||
|
||||
async tryLogin() {
|
||||
const _this = this;
|
||||
const IMToken = uni.getStorageSync("IMToken");
|
||||
const IMUserID = uni.getStorageSync("IMUserID")+'';
|
||||
//console.log('IMToken:',IMToken);
|
||||
//console.log('IMUserID:',IMUserID);
|
||||
const path = await getDbDir();
|
||||
//console.log('path:',path);
|
||||
const IMConfig = {
|
||||
systemType: "uni-app",
|
||||
apiAddr: config.getApiUrl(), // SDK的API接口地址。如:http://xxx:10002
|
||||
wsAddr: config.getWsUrl(), // SDK的websocket地址。如: ws://xxx:10001
|
||||
dataDir: path, // 数据存储路径
|
||||
logLevel: 6,
|
||||
logFilePath: path,
|
||||
isLogStandardOutput: true,
|
||||
isExternalExtensions: false,
|
||||
};
|
||||
getDbDir()
|
||||
.then(async (path) => {
|
||||
const flag = await IMSDK.asyncApi(IMMethods.InitSDK, IMSDK.uuid(), {
|
||||
systemType: "uni-app",
|
||||
apiAddr: config.getApiUrl(), // SDK的API接口地址。如:http://xxx:10002
|
||||
wsAddr: config.getWsUrl(), // SDK的websocket地址。如: ws://xxx:10001
|
||||
dataDir: path, // 数据存储路径
|
||||
logLevel: 6,
|
||||
logFilePath: path,
|
||||
isLogStandardOutput: true,
|
||||
isExternalExtensions: false,
|
||||
//console.log('IMConfig:',IMConfig);
|
||||
const flag = await IMSDK.asyncApi(IMMethods.InitSDK, IMSDK.uuid(), IMConfig);
|
||||
//console.log('flag:',flag);
|
||||
if (!flag) {
|
||||
plus.navigator.closeSplashscreen();
|
||||
console.log('初始化IMSDK失败!');
|
||||
uni.$u.toast("初始化IMSDK失败!");
|
||||
return;
|
||||
}
|
||||
|
||||
_this.setGlobalIMlistener();
|
||||
// setTimeout(()=>{
|
||||
|
||||
// },1000);
|
||||
let status;
|
||||
do{
|
||||
status = await IMSDK.asyncApi(IMSDK.IMMethods.GetLoginStatus,IMSDK.uuid());
|
||||
//console.log(status);
|
||||
}while(status == -1001);
|
||||
if (status === 3) {
|
||||
console.log('初始化,已经登录!');
|
||||
_this.initStore();
|
||||
return;
|
||||
}
|
||||
if (status === 1) {
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.Login, IMSDK.uuid(), {
|
||||
userID: IMUserID,
|
||||
token: IMToken,
|
||||
})
|
||||
.then(_this.initStore)
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
uni.removeStorage({
|
||||
key: "IMToken",
|
||||
});
|
||||
uni.removeStorage({
|
||||
key: "BusinessToken",
|
||||
});
|
||||
plus.navigator.closeSplashscreen();
|
||||
});
|
||||
if (!flag) {
|
||||
plus.navigator.closeSplashscreen();
|
||||
uni.$u.toast("初始化IMSDK失败!");
|
||||
return;
|
||||
}
|
||||
const status = await IMSDK.asyncApi(IMSDK.IMMethods.GetLoginStatus,IMSDK.uuid());
|
||||
if (status === 3) {
|
||||
initStore();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const IMToken = uni.getStorageSync("IMToken");
|
||||
const IMUserID = uni.getStorageSync("IMUserID")+'';
|
||||
if (IMToken && IMUserID) {
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.Login, IMSDK.uuid(), {
|
||||
userID: IMUserID,
|
||||
token: IMToken,
|
||||
})
|
||||
.then(initStore)
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
uni.removeStorage({
|
||||
key: "IMToken",
|
||||
});
|
||||
uni.removeStorage({
|
||||
key: "BusinessToken",
|
||||
});
|
||||
plus.navigator.closeSplashscreen();
|
||||
});
|
||||
} else {
|
||||
plus.navigator.closeSplashscreen();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("get dir failed");
|
||||
console.log(err);
|
||||
plus.navigator.closeSplashscreen();
|
||||
});
|
||||
},
|
||||
|
||||
handleOfflineNewMessages(newServerMsg) {
|
||||
console.log(newServerMsg);
|
||||
console.log( getConversationContent(newServerMsg));
|
||||
uni.createPushMessage({
|
||||
title:"您的朋友发来新的消息",
|
||||
content:getConversationContent(newServerMsg),
|
||||
payload:{
|
||||
type:"msg",
|
||||
data:newServerMsg
|
||||
},
|
||||
//icon:'',
|
||||
//sound:'',
|
||||
//cover:'false',
|
||||
//delay:0,
|
||||
//when:0,//消息上显示的提示时间
|
||||
//channelId:"",
|
||||
//category:"",
|
||||
success(res){
|
||||
//console.log(res);
|
||||
},
|
||||
fail(res){
|
||||
//console.log(res);
|
||||
},
|
||||
complete(res){
|
||||
//console.log(res);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handleNewMessage(newServerMsg) {
|
||||
if (this.inCurrentConversation(newServerMsg)) {
|
||||
if (
|
||||
@@ -368,8 +492,11 @@
|
||||
setTimeout(() => uni.$emit(PageEvents.ScrollToBottom, true));
|
||||
uni.$u.debounce(this.markConversationAsRead, 2000);
|
||||
}
|
||||
}else{
|
||||
this.handleOfflineNewMessages(newServerMsg);
|
||||
}
|
||||
},
|
||||
|
||||
inCurrentConversation(newServerMsg) {
|
||||
switch (newServerMsg.sessionType) {
|
||||
case SessionType.Single:
|
||||
@@ -386,6 +513,7 @@
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
markConversationAsRead() {
|
||||
IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.MarkConversationMessageAsRead,
|
||||
@@ -393,26 +521,93 @@
|
||||
this.storeCurrentConversation.conversationID
|
||||
);
|
||||
},
|
||||
|
||||
initStore() {
|
||||
const _this = this;
|
||||
this.$store.dispatch("user/getSelfInfo");
|
||||
this.$store.dispatch("conversation/getConversationList");
|
||||
this.$store.dispatch("conversation/getUnReadCount");
|
||||
this.$store.dispatch("contact/getBlacklist");
|
||||
this.$store.dispatch("contact/getRecvFriendApplications");
|
||||
this.$store.dispatch("contact/getSentFriendApplications");
|
||||
this.$store.dispatch("contact/getRecvGroupApplications");
|
||||
this.$store.dispatch("contact/getSentGroupApplications");
|
||||
this.$store.dispatch("contact/getFriendList");
|
||||
this.$store.dispatch("circle/getFriendCircleInfo");
|
||||
|
||||
if(true !== this.handleArguments()){
|
||||
uni.switchTab({
|
||||
url: "/pages/conversation/conversationList/index?isRedirect=true",
|
||||
complete() {
|
||||
_this.keppAlive();
|
||||
_this.checkUpdate();
|
||||
},
|
||||
fail(e){
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 验证是否升级
|
||||
checkUpdate() {
|
||||
let system = uni.getSystemInfoSync()
|
||||
plus.runtime.getProperty(plus.runtime.appid, function(inf) {
|
||||
checkUpgrade({version:system.appVersion,platform:system.platform,version_wgt:inf.versionCode}).then(res=>{
|
||||
let skip_version = uni.getStorageSync('skip_version')
|
||||
if(res && res.version!=skip_version){
|
||||
uni.$emit('closeWebview')
|
||||
this.setShow(this.current, false)
|
||||
router('/pages/common/upgrade?model=' + JSON.stringify(res), '', 'fade-in')
|
||||
}
|
||||
})
|
||||
})
|
||||
const _this = this;
|
||||
checkUpgrade();
|
||||
},
|
||||
},
|
||||
|
||||
keppAlive(){
|
||||
// #ifdef APP-NVUE
|
||||
uni.requestPermissions(['android.permission.RECEIVE_BOOT_COMPLETED'], (result) => {
|
||||
if (result.granted) {
|
||||
console.log('权限已获得');
|
||||
} else {
|
||||
console.log('权限被拒绝');
|
||||
uni.showModal({
|
||||
title: '权限申请',
|
||||
content: '您需要授权后台运行权限才能正常使用该功能',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
|
||||
handleArguments(){
|
||||
var args= plus.runtime.arguments;
|
||||
if(args){
|
||||
if(args.startsWith('shunliao://')){
|
||||
console.log(args);
|
||||
return ;
|
||||
}
|
||||
if(args.startsWith('{')){
|
||||
const json = JSON.parse(args);
|
||||
if(json.type == 'msg'){
|
||||
if(this.inCurrentConversation(json.data)){
|
||||
}else{
|
||||
let conversation = this.storeConversationList.find((item) => item === json.data);
|
||||
if(conversation){
|
||||
plus.navigator.closeSplashscreen();
|
||||
prepareConversationState(conversation);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
// 处理args参数,如直达到某新页面等
|
||||
console.log(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/static/imfont/iconfont.css";
|
||||
/*每个页面公共css */
|
||||
text,view{
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
}
|
||||
@import "@/uni_modules/uview-ui/index.scss";
|
||||
@import "@/styles/login.scss";
|
||||
@import "@/styles/global.scss";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
```
|
||||
安卓App Key:7105a186f961b5d418914c5d1b12f6af
|
||||
n1e5a6s6m7
|
||||
```
|
||||
```
|
||||
|
||||
Binary file not shown.
+65
-9
@@ -4,8 +4,41 @@ import config from "@/common/config";
|
||||
export const businessConfig = (params) =>
|
||||
uni.$u?.http.post("/common/init", JSON.stringify(params));
|
||||
// 验证是否升级
|
||||
export const checkUpgrade = (params) =>
|
||||
uni.$u?.http.post("/common/checkUpgrade", JSON.stringify(params));
|
||||
export const checkUpgrade = (params) =>{
|
||||
const _this = this;
|
||||
return new Promise((resolve,reject)=>{
|
||||
let system = uni.getSystemInfoSync()
|
||||
plus.runtime.getProperty(plus.runtime.appid, function(inf) {
|
||||
uni.$u?.http.post("/common/checkUpgrade", JSON.stringify({
|
||||
version:system.appVersion,
|
||||
platform:system.platform,
|
||||
version_wgt:inf.versionCode,
|
||||
})).then(res=>{
|
||||
console.log(res);
|
||||
if(!res || !res.version){
|
||||
return reject(true);
|
||||
}
|
||||
let skip_version = uni.getStorageSync('skip_version')
|
||||
//console.log(res.version,skip_version);
|
||||
if(res && res.version!=skip_version){
|
||||
uni.$emit('closeWebview')
|
||||
uni.setStorageSync('upgrade_model',res)
|
||||
uni.navigateTo({
|
||||
url: '/pages/common/upgrade',
|
||||
animationType:"fade-in",
|
||||
complete(res1) {
|
||||
//console.log(res1);
|
||||
return resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
reject();
|
||||
}).catch(e=>{
|
||||
reject(e);
|
||||
})
|
||||
});
|
||||
});
|
||||
};
|
||||
export const businessLogin = (params) =>
|
||||
uni.$u?.http.post("/common/login", JSON.stringify(params));
|
||||
export const businessSendSms = (params) =>
|
||||
@@ -32,7 +65,7 @@ export const businessModify = (params) =>
|
||||
// 用户信息
|
||||
export const businessInfoUpdate = (params) =>
|
||||
uni.$u?.http.post(
|
||||
"/user/info",
|
||||
"/user/profile",
|
||||
JSON.stringify({...params}),
|
||||
{
|
||||
header: {
|
||||
@@ -80,9 +113,10 @@ export const businessSearchUser = (keyword,searchtype) =>
|
||||
},
|
||||
}
|
||||
);
|
||||
export const getArticle = (id,type) => uni.$u?.http.post("/article/detail",JSON.stringify({id,type:(type? type : 'id')}));
|
||||
export const getSpage = (name) => uni.$u?.http.get(`/article/singpage?name=${name}`);
|
||||
export const getArticle = (id) => uni.$u?.http.get(`/article/detail?id=${id}`);
|
||||
export const getFriendCircle = (page=1,limit=10) =>{
|
||||
return uni.$u?.http.get("/friendcircle/list",JSON.stringify({limit:limit,page:page}));
|
||||
return uni.$u?.http.get(`/friendcircle/list?limit=${limit}&page=${page}`);
|
||||
}
|
||||
export const getFriendCircleNewcount = () =>{
|
||||
return uni.$u?.http.get("/friendcircle/newcount");
|
||||
@@ -95,17 +129,39 @@ export const upload = (files,data,onProgress) =>{
|
||||
onProgress = data;
|
||||
data = {};
|
||||
}
|
||||
data.data = data.data ? data.data : {};
|
||||
let headers = {};
|
||||
if(data.token){
|
||||
headers = data.headers;
|
||||
delete data.headers;
|
||||
}
|
||||
headers = {
|
||||
...headers,
|
||||
client:uni.getSystemInfoSync().osName,
|
||||
token:uni.getStorageSync("BusinessToken"),
|
||||
operationID: (Math.random() * 36).toString(36).slice(2) + new Date().getTime().toString(),
|
||||
// #ifdef APP-PLUS
|
||||
ClientVersion:plus.runtime.versionCode,
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
ClientVersion:350,
|
||||
// #endif
|
||||
}
|
||||
console.log(typeof files);
|
||||
let url = "/user/upload";
|
||||
if(data.url){
|
||||
url = data.url;
|
||||
delete data.url;
|
||||
}
|
||||
url= config.getRegisterUrl()+url;
|
||||
return new Promise((resolve,reject)=>{
|
||||
var u = uni.uploadFile({
|
||||
url: config.getRegisterUrl()+"/user/upload", // 仅为示例,非真实的接口地址
|
||||
url: url,
|
||||
filePath: files,
|
||||
//files:files.length > 1 ? files : files[0],
|
||||
name: "file",
|
||||
formData:data,
|
||||
header:{
|
||||
token:uni.getStorageSync("BusinessToken"),
|
||||
},
|
||||
header:headers,
|
||||
success({data,errMsg}){
|
||||
console.log(data);
|
||||
data = JSON.parse(data);
|
||||
|
||||
+6
-8
@@ -3,13 +3,10 @@
|
||||
// const API_URL = `http://${BASE_HOST}:10002`
|
||||
// const WS_URL = `ws://${BASE_HOST}:10001`
|
||||
|
||||
const BASE_DOMAIN = 'www.axzc.xyz'
|
||||
// const CHAT_URL = `https://${BASE_DOMAIN}/chat`
|
||||
// const API_URL = `https://${BASE_DOMAIN}/api`
|
||||
// const WS_URL = `wss://${BASE_DOMAIN}/msg_gateway`
|
||||
const CHAT_URL = `http://${BASE_DOMAIN}/api`
|
||||
const API_URL = `http://${BASE_DOMAIN}/imapi`
|
||||
const WS_URL = `ws://${BASE_DOMAIN}/ws`
|
||||
const BASE_DOMAIN = 'www.shun777.com'
|
||||
const CHAT_URL = `https://${BASE_DOMAIN}/api`
|
||||
const API_URL = `https://${BASE_DOMAIN}/imapi`
|
||||
const WS_URL = `wss://${BASE_DOMAIN}/msg_gateway`
|
||||
|
||||
const version = '2.0.6'
|
||||
|
||||
@@ -18,7 +15,8 @@ const getApiUrl = () => uni.getStorageSync("IMApiUrl") || API_URL;
|
||||
const getWsUrl = () => uni.getStorageSync("IMWsUrl") || WS_URL;
|
||||
|
||||
module.exports = {
|
||||
cdnUrl:"http://"+BASE_DOMAIN,
|
||||
//cdnUrl:"http://"+BASE_DOMAIN,
|
||||
cdnUrl:"https://shunliao.oss-accelerate.aliyuncs.com",
|
||||
version,
|
||||
getRegisterUrl,
|
||||
getApiUrl,
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<view @longpress="longpress" >
|
||||
<u-image
|
||||
@click="click"
|
||||
:width="width"
|
||||
:height="height"
|
||||
:mode="mode"
|
||||
@error="errorHandle"
|
||||
:src="cachesrc"></u-image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from "@/util";
|
||||
export default {
|
||||
name: "CacheImage",
|
||||
props: {
|
||||
src: String,
|
||||
type: {
|
||||
type: String,
|
||||
default: "images",
|
||||
},
|
||||
mode:{
|
||||
type: String,
|
||||
default: "aspectFill",
|
||||
},
|
||||
width: {
|
||||
type: Number|String,
|
||||
default: "100",
|
||||
},
|
||||
height: {
|
||||
type: Number|String,
|
||||
default: "",
|
||||
},
|
||||
shape:{
|
||||
type: String,
|
||||
default: "square",
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cachesrc:"",
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.init(this.src);
|
||||
},
|
||||
watch: {
|
||||
src(newVal) {
|
||||
this.init(newVal);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
init(nv){
|
||||
const _this = this;
|
||||
if (nv) {
|
||||
util.cacheFile(util.cdn(nv),this.type).then(res=>{
|
||||
_this.cachesrc = res;
|
||||
//console.log(_this.cachesrc);
|
||||
});
|
||||
return ;
|
||||
}
|
||||
},
|
||||
errorHandle() {
|
||||
this.cachesrc="/static/images/default_image.png";
|
||||
},
|
||||
click() {
|
||||
this.$emit("click");
|
||||
},
|
||||
longpress() {
|
||||
this.$emit("longpress");
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,92 +1,80 @@
|
||||
<template>
|
||||
<u-navbar :title="title" placeholder class="custom_nav_bar">
|
||||
<template slot="left">
|
||||
<slot name="left">
|
||||
<view class="u-nav-slot">
|
||||
<img
|
||||
@click="leftClick"
|
||||
class="back_icon"
|
||||
width="12"
|
||||
height="20"
|
||||
src="static/images/common_left_arrow.png"
|
||||
alt=""
|
||||
srcset=""
|
||||
/>
|
||||
</view>
|
||||
</slot>
|
||||
</template>
|
||||
<u-navbar :title="title" placeholder class="custom_nav_bar">
|
||||
<template slot="left">
|
||||
<slot name="left">
|
||||
<view class="u-nav-slot">
|
||||
<img @click="leftClick" class="back_icon" width="12" height="20"
|
||||
src="static/images/common_left_arrow.png" alt="" srcset="" />
|
||||
</view>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<template slot="center">
|
||||
<slot name="center"></slot>
|
||||
</template>
|
||||
<template slot="center">
|
||||
<slot name="center"></slot>
|
||||
</template>
|
||||
|
||||
<template slot="right">
|
||||
<slot name="more">
|
||||
<view @click="rightClick" v-if="more" class="u-nav-slot">
|
||||
<u-icon
|
||||
class="more_dot"
|
||||
name="more-dot-fill"
|
||||
size="23"
|
||||
color="#0C1C33"
|
||||
></u-icon>
|
||||
</view>
|
||||
</slot>
|
||||
</template>
|
||||
</u-navbar>
|
||||
<template slot="right">
|
||||
<slot name="more">
|
||||
<view @click="rightClick" v-if="more" class="u-nav-slot">
|
||||
<u-icon class="more_dot" name="more-dot-fill" size="23" color="#0C1C33"></u-icon>
|
||||
</view>
|
||||
</slot>
|
||||
</template>
|
||||
</u-navbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "",
|
||||
components: {},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
more: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
route: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
leftClick() {
|
||||
if (this.route) {
|
||||
uni.navigateBack();
|
||||
}
|
||||
this.$emit("leftClick");
|
||||
},
|
||||
rightClick() {
|
||||
this.$emit("rightClick");
|
||||
},
|
||||
},
|
||||
};
|
||||
export default {
|
||||
name: "",
|
||||
components: {},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
more: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
route: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
leftClick() {
|
||||
if (this.route) {
|
||||
uni.navigateBack();
|
||||
}
|
||||
this.$emit("leftClick");
|
||||
},
|
||||
rightClick() {
|
||||
this.$emit("rightClick");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.custom_nav_bar {
|
||||
::v-deep .u-navbar__content__left {
|
||||
padding: 0;
|
||||
}
|
||||
.custom_nav_bar {
|
||||
::v-deep .u-navbar__content__left {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::v-deep .u-navbar__content__right {
|
||||
padding: 0;
|
||||
}
|
||||
::v-deep .u-navbar__content__right {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.back_icon {
|
||||
padding: 24rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.back_icon {
|
||||
padding: 24rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.more_dot {
|
||||
padding: 24rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
.more_dot {
|
||||
padding: 24rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,13 +1,15 @@
|
||||
<template>
|
||||
<u-avatar @longpress="longpress" @click="click" @onError="errorHandle" :src="getAvatarUrl" :text="avatarText"
|
||||
bg-color="#cdcdcd" :defaultUrl="getDdefaultUrl" :shape="shape" :size="size" mode="aspectFill" font-size="14">
|
||||
<u-avatar @longpress="longpress" @click="click" @onError="errorHandle" :src="cachesrc" :text="avatarText"
|
||||
bg-color="#cdcdcd" :defaultUrl="getDefaultUrl" :shape="shape" :size="size" mode="aspectFill" font-size="14">
|
||||
</u-avatar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import defaultGroupIcon from "@/static/images/contact_my_group.png";
|
||||
import defaultUserIcon from "@/static/images/user/avatar.png";
|
||||
import defaultNotifyIcon from "@/static/images/default_notify_icon.png";
|
||||
import util from "@/util";
|
||||
import md5 from "md5";
|
||||
export default {
|
||||
name: "MyAvatar",
|
||||
props: {
|
||||
@@ -34,34 +36,48 @@
|
||||
data() {
|
||||
return {
|
||||
avatarText: undefined,
|
||||
cachesrc:"",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getAvatarUrl() {
|
||||
if (this.src) {
|
||||
return util.cdn(this.src);
|
||||
}
|
||||
if (this.isGroup) {
|
||||
return defaultGroupIcon;
|
||||
}
|
||||
if (this.isNotify) {
|
||||
return defaultNotifyIcon;
|
||||
}
|
||||
this.avatarText = this.desc ? this.desc.slice(0, 1) : "未知";
|
||||
return "";
|
||||
},
|
||||
getDdefaultUrl() {
|
||||
return this.isGroup ? defaultGroupIcon : undefined;
|
||||
getDefaultUrl() {
|
||||
return this.isGroup ? defaultGroupIcon : defaultUserIcon;
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
src(nv,ov){
|
||||
this.init(nv);
|
||||
},
|
||||
desc() {
|
||||
//this.redirectShow();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init(this.src);
|
||||
},
|
||||
methods: {
|
||||
errorHandle() {
|
||||
init(nv){
|
||||
const _this = this;
|
||||
if (nv) {
|
||||
util.cacheFile(util.cdn(nv),'avatar').then(res=>{
|
||||
_this.avatarText=""
|
||||
_this.cachesrc = res;
|
||||
//console.log(_this.cachesrc);
|
||||
});
|
||||
return ;
|
||||
}
|
||||
if (this.isGroup) {
|
||||
_this.cachesrc = defaultGroupIcon;
|
||||
return ;
|
||||
}
|
||||
if (this.isNotify) {
|
||||
_this.cachesrc = defaultNotifyIcon;
|
||||
return ;
|
||||
}
|
||||
this.avatarText = this.desc ? this.desc.slice(0, 1) : "未知";
|
||||
},
|
||||
redirectShow() {
|
||||
if (this.avatarText) {
|
||||
this.avatarText = undefined;
|
||||
}
|
||||
errorHandle() {
|
||||
this.avatarText = this.desc ? this.desc.slice(0, 1) : "未知";
|
||||
},
|
||||
click() {
|
||||
this.$emit("click");
|
||||
@@ -69,15 +85,7 @@
|
||||
longpress() {
|
||||
this.$emit("longpress");
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
src() {
|
||||
this.redirectShow();
|
||||
},
|
||||
desc() {
|
||||
this.redirectShow();
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
const token = uni.getStorageSync('IMToken');
|
||||
if (!token) {
|
||||
uni.redirectTo({
|
||||
url: "/pages/login/index"
|
||||
url: "/pages/common/login/index"
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view @click="clickItem" class="user_item">
|
||||
<view @longtap.stop.prevent="longtap" @tap="clickItem" class="user_item">
|
||||
<view v-if="checkVisible" class="check_wrap"
|
||||
:class="{ check_wrap_active: checked, check_wrap_disabled: disabled }">
|
||||
<u-icon v-show="checked" name="checkbox-mark" size="12" color="#fff" />
|
||||
@@ -8,10 +8,11 @@
|
||||
<my-avatar :src="item.faceURL" :desc="item.remark || item.nickname || item.showName"
|
||||
:isGroup="item.groupName !== undefined || isGroupConversation" size="42" />
|
||||
<view class="user_item_details">
|
||||
<text class="user_name">{{item.remark || item.nickname || item.groupName || item.showName}}</text>
|
||||
<text v-if="item.roleLevel === 100" class="user_role">群主</text>
|
||||
<text v-if="item.roleLevel === 60" class="user_role admin_role">管理员</text>
|
||||
<!-- <view class="bottom_line" /> -->
|
||||
<view class="user_name">{{item.remark || item.nickname || item.groupName || item.showName}}</view>
|
||||
<view v-if="item.roleLevel === 100" class="user_role">群主</view>
|
||||
<view v-else-if="item.roleLevel === 60" class="user_role admin_role">管理员<u-icon v-if="item.muteEndTime>0" size="24" name="volume-off"></u-icon></view>
|
||||
<view v-else class="user_role"><u-icon v-if="item.muteEndTime>0" size="24" name="volume-off"></u-icon></view>
|
||||
<view class="bottom_line" />
|
||||
</view>
|
||||
|
||||
<slot name="action"></slot>
|
||||
@@ -55,6 +56,12 @@
|
||||
this.$emit(this.checkVisible ? "updateCheck" : "itemClick", this.item);
|
||||
}
|
||||
},
|
||||
longtap(){
|
||||
if(this.checkVisible){
|
||||
return ;
|
||||
}
|
||||
this.$emit("longtapEvent", this.item);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -119,6 +126,8 @@
|
||||
padding: 8rpx 24rpx;
|
||||
border-radius: 24rpx;
|
||||
margin-left: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $u-tips-color;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,678 @@
|
||||
<template>
|
||||
<div class="cut-avatar-page" v-if="tempFilePath">
|
||||
<div class="main-content" v-if="1==2">
|
||||
<div class="preview-section">
|
||||
<div v-if="resultPath" class="result-box">
|
||||
<image :src="resultPath" mode="widthFix" class="result-image" @click="previewResult"></image>
|
||||
<div class="action-row">
|
||||
<button class="btn btn-outline" @click="reSelect">重新选择</button>
|
||||
<button class="btn btn-primary" @click="uploadImage">确认上传</button>
|
||||
</div>
|
||||
<text class="tip-text">点击图片可预览大图</text>
|
||||
</div>
|
||||
|
||||
<div v-else class="upload-box" @click="onSelect">
|
||||
<div class="placeholder-icon">+</div>
|
||||
<text class="upload-text">点击上传图片</text>
|
||||
<text class="upload-sub-text">支持 JPG/PNG,自动裁剪 1:1</text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="isShowEditor" class="editor-modal" :class="{ 'dark-mode': isDarkMode }">
|
||||
<div class="cropper-wrapper">
|
||||
<movable-area class="crop-area" :style="{ height: screenHeight + 'px' }">
|
||||
<movable-view
|
||||
class="crop-view"
|
||||
direction="all"
|
||||
:out-of-bounds="true"
|
||||
:x="imgX"
|
||||
:y="imgY"
|
||||
:scale="scale+''"
|
||||
:scale-min="0.5"
|
||||
:scale-max="4"
|
||||
:animation="false"
|
||||
@change="onMoveChange"
|
||||
@scale="onScaleChange"
|
||||
:style="{ width: imgDisplayWidth + 'px', height: imgDisplayHeight + 'px' }"
|
||||
>
|
||||
<image :src="tempFilePath" class="target-image" :style="{ transform: 'rotate(' + rotation + 'deg)' }"></image>
|
||||
</movable-view>
|
||||
</movable-area>
|
||||
|
||||
<div class="mask-layer" :style="{ height: screenHeight + 'px' }">
|
||||
<div class="mask-top" :style="{ height: (screenHeight - cropSize) / 2 + 'px' }"></div>
|
||||
<div class="mask-middle" :style="{ height: cropSize + 'px' }">
|
||||
<div class="mask-left" :style="{ width: (screenWidth - cropSize) / 2 + 'px' }"></div>
|
||||
<div class="crop-box" :style="{ width: cropSize + 'px', height: cropSize + 'px' }">
|
||||
<div class="corner c-tl"></div>
|
||||
<div class="corner c-tr"></div>
|
||||
<div class="corner c-bl"></div>
|
||||
<div class="corner c-br"></div>
|
||||
</div>
|
||||
<div class="mask-right" :style="{ width: (screenWidth - cropSize) / 2 + 'px' }"></div>
|
||||
</div>
|
||||
<div class="mask-bottom" :style="{ height: (screenHeight - cropSize) / 2 + 'px' }"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="editor-toolbar">
|
||||
<div class="tool-btn" @click="onCancel">取消</div>
|
||||
<div class="tool-btn" @click="onReset"> <text class="icon-reset">↻</text> 重置 </div>
|
||||
<div class="tool-btn" @click="onRotate"> <text class="icon-rotate">↻</text> 旋转 </div>
|
||||
<div class="tool-btn btn-confirm" @click="onConfirm">确定</div>
|
||||
</div>
|
||||
|
||||
<canvas canvas-id="cropCanvas" class="crop-canvas" :style="{ width: cropSize + 'px', height: cropSize + 'px' }"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 核心逻辑说明:
|
||||
* 1. 使用 movable-view 实现用户手势交互(拖拽、缩放)。
|
||||
* 2. 使用 image 的 css transform 实现视觉上的旋转。
|
||||
* 3. 最终生成时,通过计算偏移量,使用 CanvasContext 绘制图像。
|
||||
* 4. 旋转后的 Canvas 绘图坐标系需要特殊处理 (translate + rotate)。
|
||||
*/
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// --- 系统/环境参数 ---
|
||||
screenWidth: 375,
|
||||
screenHeight: 600,
|
||||
isDarkMode: false,
|
||||
|
||||
// --- 业务数据 ---
|
||||
resultPath: '', // 最终生成的图片路径
|
||||
|
||||
// --- 编辑器状态 ---
|
||||
isShowEditor: false,
|
||||
tempFilePath: '', // 选中的原始图片路径
|
||||
|
||||
// --- 图片原始信息 ---
|
||||
realImgWidth: 0,
|
||||
realImgHeight: 0,
|
||||
|
||||
// --- 交互状态数据 ---
|
||||
cropSize: 280, // 裁剪框大小 (正方形)
|
||||
imgDisplayWidth: 0, // 图片在屏幕上的初始显示宽度
|
||||
imgDisplayHeight: 0, // 图片在屏幕上的初始显示高度
|
||||
|
||||
// movable-view 的属性
|
||||
imgX: 0,
|
||||
imgY: 0,
|
||||
scale: 1,
|
||||
rotation: 0, // 0, 90, 180, 270
|
||||
|
||||
// 记录移动过程中的临时数据 (用于计算)
|
||||
currentX: 0,
|
||||
currentY: 0,
|
||||
currentScale: 1,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.initSystemInfo();
|
||||
},
|
||||
methods: {
|
||||
// -----------------------------------------------------------
|
||||
// 初始化与系统适配
|
||||
// -----------------------------------------------------------
|
||||
initSystemInfo() {
|
||||
const sys = uni.getSystemInfoSync();
|
||||
this.screenWidth = sys.windowWidth;
|
||||
this.screenHeight = sys.windowHeight;
|
||||
|
||||
// 适配暗黑模式
|
||||
if (sys.theme === 'dark') {
|
||||
this.isDarkMode = true;
|
||||
}
|
||||
|
||||
// 动态计算裁剪框大小 (屏幕宽度的 80%,最大 400px 用于适配 Pad)
|
||||
let size = this.screenWidth * 0.8;
|
||||
if (size > 400) size = 400;
|
||||
this.cropSize = Math.floor(size);
|
||||
},
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 交互逻辑
|
||||
// -----------------------------------------------------------
|
||||
onSelect() {
|
||||
console.log('[Debug] 点击选择图片');
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['original', 'compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: (res) => {
|
||||
const src = res.tempFilePaths[0];
|
||||
this.enterEditor(src);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('[Error] 选择图片失败', err);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
reSelect() {
|
||||
this.onSelect();
|
||||
},
|
||||
|
||||
previewResult() {
|
||||
if (this.resultPath) {
|
||||
uni.previewImage({
|
||||
urls: [this.resultPath],
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
uploadImage() {
|
||||
console.log('[Debug] 触发上传逻辑, 路径:', this.resultPath);
|
||||
// 这里预留上传 API 调用
|
||||
uni.showLoading({ title: '正在上传...' });
|
||||
setTimeout(() => {
|
||||
uni.hideLoading();
|
||||
uni.showToast({ title: '模拟上传成功', icon: 'success' });
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 编辑器逻辑
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// 进入编辑模式,初始化图片位置
|
||||
enterEditor(src) {
|
||||
uni.showLoading({ title: '加载中...' });
|
||||
|
||||
uni.getImageInfo({
|
||||
src: src,
|
||||
success: (res) => {
|
||||
this.tempFilePath = src;
|
||||
this.realImgWidth = res.width;
|
||||
this.realImgHeight = res.height;
|
||||
|
||||
// 重置状态
|
||||
this.rotation = 0;
|
||||
this.scale = 1;
|
||||
this.currentScale = 1;
|
||||
|
||||
// 计算图片初始显示尺寸(使其适应屏幕宽度,类似 width: 100%)
|
||||
// 这里我们让图片的短边至少填满裁剪框,方便用户操作
|
||||
const ratio = this.realImgWidth / this.realImgHeight;
|
||||
|
||||
if (ratio > 1) {
|
||||
// 横图:高度定为裁剪框大小 + 一点冗余,宽度自适应
|
||||
this.imgDisplayHeight = this.cropSize;
|
||||
this.imgDisplayWidth = this.imgDisplayHeight * ratio;
|
||||
} else {
|
||||
// 竖图
|
||||
this.imgDisplayWidth = this.cropSize;
|
||||
this.imgDisplayHeight = this.imgDisplayWidth / ratio;
|
||||
}
|
||||
|
||||
// 居中计算
|
||||
// 屏幕中心
|
||||
const centerX = this.screenWidth / 2;
|
||||
const centerY = this.screenHeight / 2;
|
||||
|
||||
// 计算 movable-view 的初始 x, y 使其居中
|
||||
// movable-view 的 x,y 是相对于 movable-area (全屏) 的左上角
|
||||
this.imgX = centerX - this.imgDisplayWidth / 2;
|
||||
this.imgY = centerY - this.imgDisplayHeight / 2;
|
||||
|
||||
// 同步 current 值
|
||||
this.currentX = this.imgX;
|
||||
this.currentY = this.imgY;
|
||||
|
||||
this.isShowEditor = true;
|
||||
uni.hideLoading();
|
||||
},
|
||||
fail: () => {
|
||||
uni.hideLoading();
|
||||
uni.showToast({ title: '图片加载失败', icon: 'none' });
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
onMoveChange(e) {
|
||||
// 记录移动位置,用于最终裁剪计算
|
||||
// detail: {x, y, source}
|
||||
this.currentX = e.detail.x;
|
||||
this.currentY = e.detail.y;
|
||||
},
|
||||
onReset(){
|
||||
this.rotation = 0;
|
||||
this.currentScale = 1;
|
||||
},
|
||||
onScaleChange(e) {
|
||||
// detail: {scale}
|
||||
this.currentScale = e.detail.scale;
|
||||
},
|
||||
|
||||
onRotate() {
|
||||
console.log('[Debug] 点击旋转');
|
||||
// 顺时针旋转 90 度
|
||||
this.rotation = (this.rotation + 90) % 360;
|
||||
// 旋转后,可能需要重置一下缩放或位置逻辑?
|
||||
// 本方案中,为了简化体验,仅做视觉旋转,
|
||||
// 最终 Canvas 裁剪时根据 rotation 参数处理坐标系。
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
this.isShowEditor = false;
|
||||
this.tempFilePath = '';
|
||||
},
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 核心裁剪生成逻辑 (Canvas)
|
||||
// -----------------------------------------------------------
|
||||
// -----------------------------------------------------------
|
||||
onConfirm() {
|
||||
console.log('[Debug] 开始生成图片');
|
||||
uni.showLoading({ title: '处理中...' });
|
||||
|
||||
const ctx = uni.createCanvasContext('cropCanvas', this);
|
||||
|
||||
// 1. 基础参数
|
||||
const destSize = this.cropSize; // 画布大小 (正方形)
|
||||
const halfDest = destSize / 2;
|
||||
|
||||
// 清空画布
|
||||
ctx.setFillStyle('#FFFFFF');
|
||||
ctx.fillRect(0, 0, destSize, destSize);
|
||||
|
||||
// 2. 计算【屏幕坐标系】下的中心点偏移
|
||||
// 这里的逻辑是:找出"图片中心"相对于"裁剪框中心"在屏幕上的距离
|
||||
|
||||
// A. 裁剪框中心在屏幕上的坐标
|
||||
const cropCenterX = (this.screenWidth - this.cropSize) / 2 + this.cropSize / 2;
|
||||
const cropCenterY = (this.screenHeight - this.cropSize) / 2 + this.cropSize / 2;
|
||||
|
||||
// B. 图片中心在屏幕上的坐标
|
||||
// 注意:movable-view 的 x,y 是左上角坐标,且 movable-view 的缩放是以中心为原点的
|
||||
// 实际上 uni-app 的 movable-view 在缩放/移动后,x/y 会自动更新为当前的左上角位置
|
||||
// 所以图片中心 = 当前x + (显示宽度 * 缩放 / 2)
|
||||
const currentRealWidth = this.imgDisplayWidth * this.currentScale;
|
||||
const currentRealHeight = this.imgDisplayHeight * this.currentScale;
|
||||
|
||||
const imgCenterX = this.currentX + currentRealWidth / 2;
|
||||
const imgCenterY = this.currentY + currentRealHeight / 2;
|
||||
|
||||
// C. 算出屏幕偏移向量 (Screen Diff)
|
||||
// 含义:图片中心在裁剪框中心的 右侧 diffX 像素,下方 diffY 像素
|
||||
const diffX = imgCenterX - cropCenterX;
|
||||
const diffY = imgCenterY - cropCenterY;
|
||||
|
||||
// 3. 将屏幕偏移向量【映射】到旋转后的 Canvas 坐标系
|
||||
// 我们需要算出:在旋转后的坐标系里,图片中心应该在哪里 (drawX, drawY)
|
||||
let drawX = 0;
|
||||
let drawY = 0;
|
||||
|
||||
// 规范化旋转角度 (0, 90, 180, 270)
|
||||
const angle = this.rotation % 360;
|
||||
|
||||
// 坐标系映射逻辑:
|
||||
// 屏幕 X+ (向右),屏幕 Y+ (向下)
|
||||
// 假设 Canvas 原点已移至中心并旋转:
|
||||
switch (angle) {
|
||||
case 0:
|
||||
// 0度:坐标系一致
|
||||
drawX = diffX;
|
||||
drawY = diffY;
|
||||
break;
|
||||
case 90:
|
||||
// 90度 (顺时针):Canvas X轴指向屏幕下,Canvas Y轴指向屏幕左
|
||||
// 屏幕的 X+ (向右) 对应 Canvas 的 Y- (向左的相反) -> drawY = -diffX
|
||||
// 屏幕的 Y+ (向下) 对应 Canvas 的 X+ (向下) -> drawX = diffY
|
||||
drawX = diffY;
|
||||
drawY = -diffX;
|
||||
break;
|
||||
case 180:
|
||||
// 180度:Canvas X轴向左,Canvas Y轴向上 (完全相反)
|
||||
drawX = -diffX;
|
||||
drawY = -diffY;
|
||||
break;
|
||||
case 270: // 相当于 -90度
|
||||
// 270度:Canvas X轴向上,Canvas Y轴向右
|
||||
// 屏幕 X+ (向右) 对应 Canvas Y+ -> drawY = diffX
|
||||
// 屏幕 Y+ (向下) 对应 Canvas X- -> drawX = -diffY
|
||||
drawX = -diffY;
|
||||
drawY = diffX;
|
||||
break;
|
||||
}
|
||||
|
||||
// 4. 执行绘制
|
||||
ctx.save();
|
||||
|
||||
// a. 将原点移到画布中心
|
||||
ctx.translate(halfDest, halfDest);
|
||||
// b. 旋转坐标系
|
||||
ctx.rotate((angle * Math.PI) / 180);
|
||||
|
||||
// c. 绘制图片
|
||||
// drawImage 的 x,y 是图片的左上角坐标
|
||||
// 我们算出的 drawX, drawY 是图片中心相对于画布中心的坐标
|
||||
// 所以要减去宽高的一半
|
||||
ctx.drawImage(this.tempFilePath, drawX - currentRealWidth / 2, drawY - currentRealHeight / 2, currentRealWidth, currentRealHeight);
|
||||
|
||||
ctx.restore();
|
||||
|
||||
// 5. 导出图片
|
||||
ctx.draw(false, () => {
|
||||
setTimeout(() => {
|
||||
uni.canvasToTempFilePath(
|
||||
{
|
||||
canvasId: 'cropCanvas',
|
||||
width: destSize,
|
||||
height: destSize,
|
||||
fileType: 'jpg',
|
||||
quality: 1,
|
||||
success: (res) => {
|
||||
this.resultPath = res.tempFilePath;
|
||||
this.tempFilePath = "";
|
||||
this.isShowEditor = false;
|
||||
uni.hideLoading();
|
||||
this.$emit('save', {path:this.resultPath});
|
||||
},
|
||||
fail: () => {
|
||||
uni.hideLoading();
|
||||
uni.showToast({ title: '生成失败', icon: 'none' });
|
||||
},
|
||||
},
|
||||
this,
|
||||
);
|
||||
}, 200);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* ========================
|
||||
CSS 变量定义
|
||||
======================== */
|
||||
.cut-avatar-page {
|
||||
--primary-color: #ef3912;
|
||||
--bg-color: #f8f9fa;
|
||||
--text-color: #333333;
|
||||
--modal-bg: #000000;
|
||||
|
||||
min-height: 100vh;
|
||||
background-color: var(--bg-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 适配暗黑模式 */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.page-container {
|
||||
--bg-color: #1a1a1a;
|
||||
--text-color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================
|
||||
主界面样式
|
||||
======================== */
|
||||
.nav-bar {
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--bg-color);
|
||||
/* 简单的顶部阴影 */
|
||||
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.preview-section {
|
||||
width: 100%;
|
||||
max-width: 600px; /* Pad 适配限制 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
/* 上传占位框 */
|
||||
.upload-box {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
border: 2px dashed #cccccc;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.upload-box:active {
|
||||
background-color: rgba(239, 57, 18, 0.05);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 40px;
|
||||
color: #999;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.upload-text {
|
||||
font-size: 16px;
|
||||
color: var(--text-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.upload-sub-text {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/* 结果展示区 */
|
||||
.result-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.result-image {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
background-color: #eee;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.action-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: 14px;
|
||||
padding: 8px 24px;
|
||||
border-radius: 20px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--primary-color);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-outline {
|
||||
background-color: transparent;
|
||||
border: 1px solid #ccc;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
/* ========================
|
||||
编辑器弹窗样式 (全屏)
|
||||
======================== */
|
||||
.editor-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 999;
|
||||
background-color: #000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cropper-wrapper {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.crop-area {
|
||||
width: 100%;
|
||||
/* height 由 JS 动态控制 */
|
||||
}
|
||||
|
||||
.crop-view {
|
||||
/* 初始不可见,加载图片后显示 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.target-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* 优化图片渲染 */
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
/* 遮罩层布局 */
|
||||
.mask-layer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
pointer-events: none; /* 让事件穿透到底下的 movable-area */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.mask-top,
|
||||
.mask-bottom,
|
||||
.mask-left,
|
||||
.mask-right {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.mask-middle {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
/* 裁剪框样式 */
|
||||
.crop-box {
|
||||
position: relative;
|
||||
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 四个角的装饰 */
|
||||
.corner {
|
||||
position: absolute;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 3px solid #fff;
|
||||
}
|
||||
|
||||
.c-tl {
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
.c-tr {
|
||||
top: -2px;
|
||||
right: -2px;
|
||||
border-left: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
.c-bl {
|
||||
bottom: -2px;
|
||||
left: -2px;
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
}
|
||||
.c-br {
|
||||
bottom: -2px;
|
||||
right: -2px;
|
||||
border-left: none;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
/* 底部工具栏 */
|
||||
.editor-toolbar {
|
||||
height: 80px; /* 留足安全距离 */
|
||||
background-color: #1a1a1a;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 30px;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.tool-btn {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn-confirm {
|
||||
color: var(--primary-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icon-rotate {
|
||||
font-size: 18px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* Canvas 隐藏处理 */
|
||||
.crop-canvas {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
top: -9999px;
|
||||
pointer-events: none;
|
||||
visibility: hidden; /* 这里用 hidden, 有些环境 display:none 会导致不渲染 */
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,155 +0,0 @@
|
||||
<template>
|
||||
<view class="map_container"></view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
map: null,
|
||||
centerMarker: null,
|
||||
currentPoint: null,
|
||||
currentAddress: '',
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.createMap();
|
||||
this.initializeMap();
|
||||
},
|
||||
methods: {
|
||||
createMap() {
|
||||
const mapId = "map_" + Math.random();
|
||||
const map = plus.maps.create(mapId, {
|
||||
zoom: 13,
|
||||
MapType: plus.maps.MapType.MAPTYPE_NORMAL,
|
||||
traffic: true,
|
||||
zoomControls: true,
|
||||
top: "0",
|
||||
left: "0",
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: "static",
|
||||
});
|
||||
|
||||
plus.webview.currentWebview().append(map);
|
||||
this.map = map;
|
||||
},
|
||||
|
||||
initializeMap() {
|
||||
const _this = this;
|
||||
|
||||
// 获取当前位置
|
||||
uni.getLocation({
|
||||
type: 'gcj02',
|
||||
success(res) {
|
||||
const point = new plus.maps.Point(res.longitude, res.latitude);
|
||||
_this.map.setCenter(point);
|
||||
_this.currentPoint = point;
|
||||
_this.addCenterMarker(point);
|
||||
_this.getAddressByPoint(point);
|
||||
_this.setupMapMoveListener();
|
||||
_this.map.show();
|
||||
},
|
||||
fail() {
|
||||
// 如果获取位置失败,使用默认位置
|
||||
const defaultPoint = new plus.maps.Point(116.4074, 39.9042);
|
||||
_this.map.setCenter(defaultPoint);
|
||||
_this.currentPoint = defaultPoint;
|
||||
_this.addCenterMarker(defaultPoint);
|
||||
_this.getAddressByPoint(defaultPoint);
|
||||
_this.setupMapMoveListener();
|
||||
_this.map.show();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addCenterMarker(point) {
|
||||
// 移除旧的marker
|
||||
if (this.centerMarker) {
|
||||
this.map.removeOverlay(this.centerMarker);
|
||||
}
|
||||
|
||||
// 添加中心点marker
|
||||
this.centerMarker = new plus.maps.Marker(point);
|
||||
this.centerMarker.setIcon("/static/images/chat/marker.png");
|
||||
this.map.addOverlay(this.centerMarker);
|
||||
},
|
||||
|
||||
setupMapMoveListener() {
|
||||
const _this = this;
|
||||
|
||||
// 使用定时器轮询来检测地图位置变化
|
||||
// plus.maps 的 H5 版本可能不支持事件监听,通过定时器实现
|
||||
let lastCenter = this.map.getCenter ? this.map.getCenter() : null;
|
||||
|
||||
setInterval(() => {
|
||||
_this.map.getCurrentCenter((state, point) => {
|
||||
if (state !== 0 || !point) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 简单的位置变化检测
|
||||
if (!lastCenter ||
|
||||
lastCenter.getLng() !== point.getLng() ||
|
||||
lastCenter.getLat() !== point.getLat()) {
|
||||
|
||||
lastCenter = point;
|
||||
_this.updateCenterMarker();
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
},
|
||||
|
||||
updateCenterMarker() {
|
||||
const _this = this;
|
||||
|
||||
this.map.getCurrentCenter((state, point) => {
|
||||
if (state !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
_this.currentPoint = point;
|
||||
_this.addCenterMarker(point);
|
||||
_this.getAddressByPoint(point);
|
||||
});
|
||||
},
|
||||
|
||||
getAddressByPoint(point) {
|
||||
const _this = this;
|
||||
|
||||
// 简化处理:直接显示"位置已选择",不调用外部 API
|
||||
// 如果需要真实地址,可以在确认时调用服务端 API
|
||||
_this.currentAddress = '位置已选择';
|
||||
},
|
||||
|
||||
getCurrentCenter(callback) {
|
||||
const _this = this;
|
||||
|
||||
this.map.getCurrentCenter((state, point) => {
|
||||
if (state !== 0) {
|
||||
callback(state, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// 直接返回当前数据,地址会异步更新
|
||||
callback(state, {
|
||||
point: point,
|
||||
lng: point.getLng(),
|
||||
lat: point.getLat(),
|
||||
address: _this.currentAddress || '位置已选择'
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.map_container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -4,7 +4,7 @@
|
||||
:show="previewVideoFlag"
|
||||
opacity="1"
|
||||
:custom-style="customMaskStyle">
|
||||
<view @tap.stop
|
||||
<view @tap.stop="quitPlay"
|
||||
class="playBox"
|
||||
style="height:100vh;width:100vw;">
|
||||
<video
|
||||
@@ -18,7 +18,7 @@
|
||||
</video>
|
||||
<view class="quitBox" @click="quitPlay">
|
||||
<u-icon name="close-circle" color="#FFF" size="32"></u-icon>
|
||||
<cover-view class="icon"></cover-view>
|
||||
<!-- <cover-view class="icon"></cover-view> -->
|
||||
</view>
|
||||
</view>
|
||||
</u-overlay>
|
||||
@@ -99,7 +99,7 @@
|
||||
right: 5%;
|
||||
top: 10%;
|
||||
.icon{
|
||||
color: #fff;
|
||||
color: #f00;
|
||||
font-size: 32px;
|
||||
font-family: uicon-iconfont;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ export const GroupMemberListTypes = {
|
||||
Preview: "Preview",
|
||||
Transfer: "Transfer",
|
||||
Kickout: "Kickout",
|
||||
setAdmin: "setAdmin",
|
||||
Mute: "Mute",
|
||||
};
|
||||
|
||||
export const ContactChooseTypes = {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<!-- <script src="/static/wangeditor/index.js"></script>
|
||||
<link rel="stylesheet" href="/static/wangeditor/style.css" /> -->
|
||||
<script>
|
||||
var coverSupport =
|
||||
"CSS" in window &&
|
||||
|
||||
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
com.shun777.app
|
||||
密码123
|
||||
@@ -0,0 +1,272 @@
|
||||
/**
|
||||
* 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
|
||||
*/
|
||||
|
||||
var isIos
|
||||
// #ifdef APP-PLUS
|
||||
isIos = (plus.os.name == "iOS")
|
||||
// #endif
|
||||
|
||||
// 判断推送权限是否开启
|
||||
function judgeIosPermissionPush() {
|
||||
var result = false;
|
||||
var UIApplication = plus.ios.import("UIApplication");
|
||||
var app = UIApplication.sharedApplication();
|
||||
var enabledTypes = 0;
|
||||
if (app.currentUserNotificationSettings) {
|
||||
var settings = app.currentUserNotificationSettings();
|
||||
enabledTypes = settings.plusGetAttribute("types");
|
||||
console.log("enabledTypes1:" + enabledTypes);
|
||||
if (enabledTypes == 0) {
|
||||
console.log("推送权限没有开启");
|
||||
} else {
|
||||
result = true;
|
||||
console.log("已经开启推送功能!")
|
||||
}
|
||||
plus.ios.deleteObject(settings);
|
||||
} else {
|
||||
enabledTypes = app.enabledRemoteNotificationTypes();
|
||||
if (enabledTypes == 0) {
|
||||
console.log("推送权限没有开启!");
|
||||
} else {
|
||||
result = true;
|
||||
console.log("已经开启推送功能!")
|
||||
}
|
||||
console.log("enabledTypes2:" + enabledTypes);
|
||||
}
|
||||
plus.ios.deleteObject(app);
|
||||
plus.ios.deleteObject(UIApplication);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断定位权限是否开启
|
||||
function judgeIosPermissionLocation() {
|
||||
var result = false;
|
||||
var cllocationManger = plus.ios.import("CLLocationManager");
|
||||
var status = cllocationManger.authorizationStatus();
|
||||
result = (status != 2)
|
||||
console.log("定位权限开启:" + result);
|
||||
// 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
|
||||
/* var enable = cllocationManger.locationServicesEnabled();
|
||||
var status = cllocationManger.authorizationStatus();
|
||||
console.log("enable:" + enable);
|
||||
console.log("status:" + status);
|
||||
if (enable && status != 2) {
|
||||
result = true;
|
||||
console.log("手机定位服务已开启且已授予定位权限");
|
||||
} else {
|
||||
console.log("手机系统的定位没有打开或未给予定位权限");
|
||||
} */
|
||||
plus.ios.deleteObject(cllocationManger);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断麦克风权限是否开启
|
||||
function judgeIosPermissionRecord() {
|
||||
var result = false;
|
||||
var avaudiosession = plus.ios.import("AVAudioSession");
|
||||
var avaudio = avaudiosession.sharedInstance();
|
||||
var permissionStatus = avaudio.recordPermission();
|
||||
console.log("permissionStatus:" + permissionStatus);
|
||||
if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
|
||||
console.log("麦克风权限没有开启");
|
||||
} else {
|
||||
result = true;
|
||||
console.log("麦克风权限已经开启");
|
||||
}
|
||||
plus.ios.deleteObject(avaudiosession);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断相机权限是否开启
|
||||
function judgeIosPermissionCamera() {
|
||||
var result = false;
|
||||
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
|
||||
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
|
||||
console.log("authStatus:" + authStatus);
|
||||
if (authStatus == 3) {
|
||||
result = true;
|
||||
console.log("相机权限已经开启");
|
||||
} else {
|
||||
console.log("相机权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(AVCaptureDevice);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断相册权限是否开启
|
||||
function judgeIosPermissionPhotoLibrary() {
|
||||
var result = false;
|
||||
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
|
||||
var authStatus = PHPhotoLibrary.authorizationStatus();
|
||||
console.log("authStatus:" + authStatus);
|
||||
if (authStatus == 3) {
|
||||
result = true;
|
||||
console.log("相册权限已经开启");
|
||||
} else {
|
||||
console.log("相册权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(PHPhotoLibrary);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断通讯录权限是否开启
|
||||
function judgeIosPermissionContact() {
|
||||
var result = false;
|
||||
var CNContactStore = plus.ios.import("CNContactStore");
|
||||
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
|
||||
if (cnAuthStatus == 3) {
|
||||
result = true;
|
||||
console.log("通讯录权限已经开启");
|
||||
} else {
|
||||
console.log("通讯录权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(CNContactStore);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断日历权限是否开启
|
||||
function judgeIosPermissionCalendar() {
|
||||
var result = false;
|
||||
var EKEventStore = plus.ios.import("EKEventStore");
|
||||
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
|
||||
if (ekAuthStatus == 3) {
|
||||
result = true;
|
||||
console.log("日历权限已经开启");
|
||||
} else {
|
||||
console.log("日历权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(EKEventStore);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 判断备忘录权限是否开启
|
||||
function judgeIosPermissionMemo() {
|
||||
var result = false;
|
||||
var EKEventStore = plus.ios.import("EKEventStore");
|
||||
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
|
||||
if (ekAuthStatus == 3) {
|
||||
result = true;
|
||||
console.log("备忘录权限已经开启");
|
||||
} else {
|
||||
console.log("备忘录权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(EKEventStore);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Android权限查询
|
||||
function requestAndroidPermission(permissionID) {
|
||||
return new Promise((resolve, reject) => {
|
||||
plus.android.requestPermissions(
|
||||
[permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
|
||||
function(resultObj) {
|
||||
var result = 0;
|
||||
for (var i = 0; i < resultObj.granted.length; i++) {
|
||||
var grantedPermission = resultObj.granted[i];
|
||||
console.log('已获取的权限:' + grantedPermission);
|
||||
result = 1
|
||||
}
|
||||
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
|
||||
var deniedPresentPermission = resultObj.deniedPresent[i];
|
||||
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
|
||||
result = 0
|
||||
}
|
||||
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
|
||||
var deniedAlwaysPermission = resultObj.deniedAlways[i];
|
||||
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
|
||||
result = -1
|
||||
}
|
||||
resolve(result);
|
||||
// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
|
||||
// if (result != 1) {
|
||||
// gotoAppPermissionSetting()
|
||||
// }
|
||||
},
|
||||
function(error) {
|
||||
console.log('申请权限错误:' + error.code + " = " + error.message);
|
||||
resolve({
|
||||
code: error.code,
|
||||
message: error.message
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// 使用一个方法,根据参数判断权限
|
||||
function judgeIosPermission(permissionID) {
|
||||
if (permissionID == "location") {
|
||||
return judgeIosPermissionLocation()
|
||||
} else if (permissionID == "camera") {
|
||||
return judgeIosPermissionCamera()
|
||||
} else if (permissionID == "photoLibrary") {
|
||||
return judgeIosPermissionPhotoLibrary()
|
||||
} else if (permissionID == "record") {
|
||||
return judgeIosPermissionRecord()
|
||||
} else if (permissionID == "push") {
|
||||
return judgeIosPermissionPush()
|
||||
} else if (permissionID == "contact") {
|
||||
return judgeIosPermissionContact()
|
||||
} else if (permissionID == "calendar") {
|
||||
return judgeIosPermissionCalendar()
|
||||
} else if (permissionID == "memo") {
|
||||
return judgeIosPermissionMemo()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 跳转到**应用**的权限页面
|
||||
function gotoAppPermissionSetting() {
|
||||
if (isIos) {
|
||||
var UIApplication = plus.ios.import("UIApplication");
|
||||
var application2 = UIApplication.sharedApplication();
|
||||
var NSURL2 = plus.ios.import("NSURL");
|
||||
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
|
||||
var setting2 = NSURL2.URLWithString("app-settings:");
|
||||
application2.openURL(setting2);
|
||||
|
||||
plus.ios.deleteObject(setting2);
|
||||
plus.ios.deleteObject(NSURL2);
|
||||
plus.ios.deleteObject(application2);
|
||||
} else {
|
||||
// console.log(plus.device.vendor);
|
||||
var Intent = plus.android.importClass("android.content.Intent");
|
||||
var Settings = plus.android.importClass("android.provider.Settings");
|
||||
var Uri = plus.android.importClass("android.net.Uri");
|
||||
var mainActivity = plus.android.runtimeMainActivity();
|
||||
var intent = new Intent();
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
|
||||
intent.setData(uri);
|
||||
mainActivity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查系统的设备服务是否开启
|
||||
// var checkSystemEnableLocation = async function () {
|
||||
function checkSystemEnableLocation() {
|
||||
if (isIos) {
|
||||
var result = false;
|
||||
var cllocationManger = plus.ios.import("CLLocationManager");
|
||||
var result = cllocationManger.locationServicesEnabled();
|
||||
console.log("系统定位开启:" + result);
|
||||
plus.ios.deleteObject(cllocationManger);
|
||||
return result;
|
||||
} else {
|
||||
var context = plus.android.importClass("android.content.Context");
|
||||
var locationManager = plus.android.importClass("android.location.LocationManager");
|
||||
var main = plus.android.runtimeMainActivity();
|
||||
var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
|
||||
var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
|
||||
console.log("系统定位开启:" + result);
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
judgeIosPermission: judgeIosPermission,
|
||||
requestAndroidPermission: requestAndroidPermission,
|
||||
checkSystemEnableLocation: checkSystemEnableLocation,
|
||||
gotoAppPermissionSetting: gotoAppPermissionSetting
|
||||
}
|
||||
@@ -58,6 +58,5 @@ app.REQUEST_TRACE = false;
|
||||
// 引入请求封装
|
||||
import request from "./util/request/index";
|
||||
request(app)
|
||||
//require("./util/request/index")(app);
|
||||
|
||||
app.$mount();
|
||||
+43
-16
@@ -1,17 +1,18 @@
|
||||
{
|
||||
"name" : "回声",
|
||||
"appid" : "__UNI__CA458BA",
|
||||
"description" : "",
|
||||
"versionName" : "3.3.4",
|
||||
"versionCode" : 334,
|
||||
"name" : "瞬聊",
|
||||
"appid" : "__UNI__E41111F",
|
||||
"description" : "一款即时聊天软件",
|
||||
"versionName" : "3.5.1",
|
||||
"versionCode" : 351,
|
||||
"transformPx" : false,
|
||||
"app-plus" : {
|
||||
"bounce" : "none",
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"orientation" : [ "portrait-primary" ],
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : false,
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : false,
|
||||
"delay" : 0
|
||||
@@ -23,7 +24,8 @@
|
||||
"Geolocation" : {},
|
||||
"Fingerprint" : {},
|
||||
"Contacts" : {},
|
||||
"Barcode" : {}
|
||||
"Barcode" : {},
|
||||
"Push" : {}
|
||||
},
|
||||
"distribute" : {
|
||||
"android" : {
|
||||
@@ -48,12 +50,16 @@
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_MEDIA_IMAGES\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_MEDIA_VIDEO\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_MEDIA_VISUAL_USER_SELECTED\"/>"
|
||||
],
|
||||
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
|
||||
"minSdkVersion" : 21,
|
||||
"targetSdkVersion" : 26,
|
||||
"schemes" : "huisheng"
|
||||
"targetSdkVersion" : 36,
|
||||
"schemes" : "shunliao"
|
||||
},
|
||||
"ios" : {
|
||||
"dSYMs" : false,
|
||||
@@ -69,11 +75,11 @@
|
||||
},
|
||||
"capabilities" : {
|
||||
"entitlements" : {
|
||||
"com.apple.developer.associated-domains" : [ "huisheng", "applinks:url.huisheng.hk" ]
|
||||
"com.apple.developer.associated-domains" : [ "shunliao", "applinks:www.shun777.com", "applinks:url.shun777.com" ]
|
||||
}
|
||||
},
|
||||
"idfa" : false,
|
||||
"urltypes" : "huisheng"
|
||||
"urltypes" : "shunliao"
|
||||
},
|
||||
"sdkConfigs" : {
|
||||
"ad" : {},
|
||||
@@ -91,10 +97,25 @@
|
||||
},
|
||||
"share" : {},
|
||||
"statics" : {},
|
||||
"speech" : {}
|
||||
"speech" : {},
|
||||
"push" : {
|
||||
"unipush" : {
|
||||
"version" : "2",
|
||||
"offline" : false,
|
||||
"icons" : {
|
||||
"small" : {
|
||||
"ldpi" : "static/images/about_logo.png",
|
||||
"mdpi" : "static/images/about_logo.png",
|
||||
"hdpi" : "static/images/about_logo.png",
|
||||
"xhdpi" : "static/images/about_logo.png",
|
||||
"xxhdpi" : "static/images/about_logo.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"splashscreen" : {
|
||||
"androidStyle" : "default",
|
||||
"androidStyle" : "common",
|
||||
"iosStyle" : "common",
|
||||
"android" : {
|
||||
"hdpi" : "unpackage/res/cover/480_762.9.png",
|
||||
@@ -143,7 +164,7 @@
|
||||
"platforms" : "Android,iOS",
|
||||
"url" : "https://ext.dcloud.net.cn/plugin?id=6577",
|
||||
"android_package_name" : "",
|
||||
"ios_bundle_id" : "com.tuoyun.uni",
|
||||
"ios_bundle_id" : "com.shun777.app",
|
||||
"isCloud" : true,
|
||||
"bought" : 1,
|
||||
"pid" : "6577",
|
||||
@@ -163,7 +184,10 @@
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
"usingComponents" : true,
|
||||
"unipush" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
@@ -199,6 +223,9 @@
|
||||
"treeShaking" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"unipush" : {
|
||||
"enable" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-11
@@ -1,12 +1,17 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@openim/client-sdk": "^0.0.11-ahpha.1",
|
||||
"date-fns": "^2.30.0",
|
||||
"dayjs": "^1.11.6",
|
||||
"grapheme-splitter": "^1.0.4",
|
||||
"image-tools": "^1.4.0",
|
||||
"md5": "^2.3.0",
|
||||
"openim-uniapp-polyfill": "^1.4.1",
|
||||
"uuid": "^9.0.0"
|
||||
}
|
||||
}
|
||||
"dependencies": {
|
||||
"@openim/client-sdk": "^0.0.11-ahpha.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"dayjs": "^1.11.6",
|
||||
"grapheme-splitter": "^1.0.4",
|
||||
"image-tools": "^1.4.0",
|
||||
"md5": "^2.3.0",
|
||||
"openim-uniapp-polyfill": "^1.4.4",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"worker-loader": "^3.0.8",
|
||||
"worker-plugin": "^5.0.1"
|
||||
}
|
||||
}
|
||||
+214
-31
@@ -2,32 +2,40 @@
|
||||
"pages": [
|
||||
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/login/index"
|
||||
"path": "pages/common/login/index"
|
||||
},
|
||||
{
|
||||
"path": "pages/login/registerOrForget/index"
|
||||
"path": "pages/index/launch",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/setSelfInfo/index"
|
||||
"path": "pages/index/guide",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/setPassword/index"
|
||||
"path": "pages/common/registerOrForget/index"
|
||||
},
|
||||
{
|
||||
"path": "pages/login/verifyCode/index"
|
||||
"path": "pages/common/setSelfInfo/index"
|
||||
},
|
||||
{
|
||||
"path": "pages/profile/index/index"
|
||||
"path": "pages/common/setPassword/index"
|
||||
},
|
||||
{
|
||||
"path": "pages/common/verifyCode/index"
|
||||
},
|
||||
{
|
||||
"path": "pages/user/index/index"
|
||||
},
|
||||
{
|
||||
"path": "pages/conversation/conversationList/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"disableScroll": true,
|
||||
"app-plus": {
|
||||
"bounce": "none"
|
||||
}
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -135,6 +143,14 @@
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/common/contactChoose/chooseGroupMember",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/common/createGroup/index",
|
||||
"style": {
|
||||
@@ -199,21 +215,21 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/profile/selfInfo/index",
|
||||
"path": "pages/user/selfInfo/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/profile/accountSetting/index",
|
||||
"path": "pages/user/accountSetting/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/profile/blockList/index",
|
||||
"path": "pages/user/blockList/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
@@ -241,14 +257,14 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/profile/about/index",
|
||||
"path": "pages/user/about/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/workbench/index/index",
|
||||
"path": "pages/find/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
@@ -257,7 +273,11 @@
|
||||
{
|
||||
"path": "pages/common/upgrade",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
"navigationStyle": "custom",
|
||||
"backgroundColor": "transparent",
|
||||
"navigationBarTextStyle": "white",
|
||||
"navigationBarTitleText": "系统更新",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -274,31 +294,32 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/workbench/friend-circle/friend-circle",
|
||||
"path": "pages/find/friend-circle/friend-circle",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/friend-circle/releaseFriendCircle",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/workbench/friend-circle/releaseFriendCircle",
|
||||
"path": "pages/find/friend-circle/chooseLocation",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/workbench/friend-circle/chooseLocation",
|
||||
"path": "pages/find/friend-circle/chooseCircleBgImg",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/workbench/friend-circle/chooseCircleBgImg",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/workbench/friend-circle/builtinBgImg",
|
||||
"path": "pages/find/friend-circle/builtinBgImg",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
@@ -346,7 +367,163 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/workbench/near/near",
|
||||
"path": "pages/find/near/near",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/vip/vip",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/conversation/groupAlbum/groupAlbum",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/selfInfo/change_bio",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/shake/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/shake/linked_list",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/shake/set",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/shake/user_detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/shake/friend_home",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/shake/agree_apply_friend",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/shake/chatting/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/shake/chatting/zhuanfa_pop",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/music/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/find/music/song_list",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/bill/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/bill/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/bill/question",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/bill/statistics",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/set",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/wallet",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/wallet_option",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/wallet_pay",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/wallet_sub_page/bind_bank",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/wallet_sub_page/lin_qian_tong",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/wallet_sub_page/qin_shu_ka",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/service/wallet_sub_page/fenfu-page",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
@@ -372,13 +549,13 @@
|
||||
"text": "通讯录"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/workbench/index/index",
|
||||
"pagePath": "pages/find/index/index",
|
||||
"iconPath": "./static/images/tabbar/workbench.png",
|
||||
"selectedIconPath": "static/images/tabbar/workbench_active.png",
|
||||
"text": "发现"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/profile/index/index",
|
||||
"pagePath": "pages/user/index/index",
|
||||
"iconPath": "./static/images/tabbar/profile.png",
|
||||
"selectedIconPath": "static/images/tabbar/profile_active.png",
|
||||
"text": "我"
|
||||
@@ -391,5 +568,11 @@
|
||||
"app-plus": {
|
||||
"bounce": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
"easycom": {
|
||||
"autoscan": true,
|
||||
"custom": {
|
||||
"^c-(.*)": "@/components/$1/index.vue"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
<template>
|
||||
<view class="contact_choose_container">
|
||||
<custom-nav-bar title="联系人">
|
||||
<view slot="more" style="margin-right: 10rpx;">
|
||||
<u-button type="primary" @click="confirm" :disabled="!isConfirmEnable">确定</u-button>
|
||||
</view>
|
||||
</custom-nav-bar>
|
||||
|
||||
<uni-nav-bar
|
||||
left-icon="back"
|
||||
@clickLeft="uni.$u.route({type:'back'})"
|
||||
statusBar
|
||||
title="联系人">
|
||||
<template v-slot:right>
|
||||
<u-button type="primary" size="mini" @click="confirm" :disabled="!isConfirmEnable">确定</u-button>
|
||||
</template>
|
||||
</uni-nav-bar>
|
||||
<view class="search_bar_wrap">
|
||||
<u-search shape="square" placeholder="搜索" :showAction="false" v-model="keyword" />
|
||||
</view>
|
||||
|
||||
<view class="tab_container">
|
||||
<template v-if="activeTab === 0">
|
||||
<setting-item @click="tabChange(tabs[0].idx)" :title="tabs[0].title" :border="false" />
|
||||
<div @click="tabChange(tabs[0].idx)" style="display: flex; align-items: center;justify-content: space-between;padding: 20rpx 40rpx;">
|
||||
{{ tabs[0].title }}
|
||||
<u-icon name="arrow-right" />
|
||||
</div>
|
||||
<view class="tab_pane">
|
||||
<template v-for="cell in conversationList">
|
||||
<template v-if="cell.groupID">
|
||||
<template v-if="cell.groupID && type!='Invite'">
|
||||
<user-item
|
||||
v-if="allowGroup"
|
||||
@itemClick="updateCheckedUserOrGroup"
|
||||
@@ -25,7 +31,7 @@
|
||||
:checkVisible="muitple"
|
||||
:item="cell" :key="cell.groupID" />
|
||||
</template>
|
||||
<template v-if="cell.userID">
|
||||
<template v-if="cell.userID && !cell.userID.startsWith('system')">
|
||||
<user-item
|
||||
@itemClick="updateCheckedUserOrGroup"
|
||||
@updateCheck="updateCheckedUserOrGroup"
|
||||
@@ -54,23 +60,19 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import { mapGetters } from "vuex";
|
||||
import {ContactChooseTypes} from "@/constant";
|
||||
import {formatChooseData,toastWithCallback} from "@/util/common";
|
||||
import IMSDK from "openim-uniapp-polyfill";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import IMSDK from "openim-uniapp-polyfill"
|
||||
import UserItem from "@/components/UserItem/index.vue";
|
||||
import ChooseIndexList from "@/components/ChooseIndexList/index.vue";
|
||||
import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue";
|
||||
import SettingItem from "@/components/SettingItem/index.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
UserItem,
|
||||
ChooseIndexList,
|
||||
ChooseIndexFooter,
|
||||
SettingItem,
|
||||
ChooseIndexFooter
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -94,18 +96,23 @@
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
"storeFriendList",
|
||||
"storeCurrentConversation",
|
||||
"storeCurrentUserID",
|
||||
"storeConversationList",
|
||||
]),
|
||||
...mapGetters(["storeCurrentUserID","storeFriendList","storeConversationList",'storeCurrentConversation']),
|
||||
getChooseData() {
|
||||
const _this = this;
|
||||
let list = [...this.storeFriendList];
|
||||
list = list.filter((item)=>{
|
||||
return !item.userID.startsWith('system') && !item.userID.startsWith('official_team') && item.userID !== this.storeCurrentUserID
|
||||
});
|
||||
if(!this.allowGroup){
|
||||
list = list.filter((item)=>{
|
||||
return !item.groupID
|
||||
});
|
||||
}
|
||||
if (this.keyword) {
|
||||
return {
|
||||
indexList: ["#"],
|
||||
dataList: [
|
||||
this.storeFriendList.filter(
|
||||
list.filter(
|
||||
(friend) =>
|
||||
friend.nickname.includes(this.keyword) ||
|
||||
friend.remark.includes(this.keyword)
|
||||
@@ -113,14 +120,22 @@
|
||||
],
|
||||
};
|
||||
}
|
||||
return formatChooseData(this.storeFriendList);
|
||||
return formatChooseData(list);
|
||||
},
|
||||
|
||||
conversationList(){
|
||||
const _this = this;
|
||||
let list = [...this.storeConversationList];
|
||||
list = list.filter((item)=>{
|
||||
return !item.userID.startsWith('system') && !item.userID.startsWith('official_team') && item.userID !== this.storeCurrentUserID
|
||||
});
|
||||
if(!this.allowGroup){
|
||||
list = list.filter((item)=>{
|
||||
return !item.groupID
|
||||
});
|
||||
}
|
||||
if(this.keyword){
|
||||
list = list.filter((item)=>{77
|
||||
list = list.filter((item)=>{
|
||||
return item.showName.indexOf(_this.kw)>-1 || item.userID.indexOf(_this.kw)>-1 || item.groupID.indexOf(_this.kw)>-1
|
||||
})
|
||||
}
|
||||
@@ -165,18 +180,16 @@
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
const {groupID,type,checkedUserIDList,muitple} = options;
|
||||
const {groupID,type,checkedUserIDList,muitple,allowType} = options;
|
||||
this.type = type;
|
||||
if(allowType){
|
||||
this.allowGroup = allowType === 'All';
|
||||
}
|
||||
this.groupID = groupID;
|
||||
if(muitple){
|
||||
this.muitple = muitple;
|
||||
}
|
||||
//this.muitple = true;
|
||||
this.checkedUserIDList = checkedUserIDList ? JSON.parse(checkedUserIDList) : [];
|
||||
//console.log(this.checkedUserIDList);
|
||||
//console.log(this.groupID);
|
||||
//console.log(this.muitple);
|
||||
//console.log(this.type);
|
||||
if (this.type === ContactChooseTypes.Invite) {
|
||||
this.allowGroup = false;
|
||||
this.checkDisabledUser();
|
||||
@@ -235,6 +248,7 @@
|
||||
}
|
||||
},
|
||||
confirm() {
|
||||
const _this = this;
|
||||
//console.log(this.checkedUserIDList,this.checkedGroupIDList);
|
||||
//return false;
|
||||
// if (this.activeTab) {
|
||||
@@ -262,16 +276,20 @@
|
||||
return;
|
||||
}
|
||||
if (this.type === ContactChooseTypes.Invite) {
|
||||
console.log(_this.getCheckedUserInfo,_this.groupID);
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.InviteUserToGroup, IMSDK.uuid(), {
|
||||
groupID: this.groupID,
|
||||
groupID: _this.groupID,
|
||||
reason: "",
|
||||
userIDList: this.getCheckedUserInfo.map((user) => user.userID),
|
||||
userIDList: _this.getCheckedUserInfo.map((user) => user.userID),
|
||||
})
|
||||
.then(() => {
|
||||
toastWithCallback("操作成功", () => uni.navigateBack());
|
||||
this.comfirmLoading = false;
|
||||
_this.comfirmLoading = false;
|
||||
})
|
||||
.catch(() => toastWithCallback("操作失败"));
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
toastWithCallback("操作失败")
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -294,7 +312,7 @@
|
||||
}
|
||||
|
||||
.contact_choose_container {
|
||||
height: 100vh;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -306,7 +324,6 @@
|
||||
.tab_container {
|
||||
@include colBox(false);
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.setting_item {
|
||||
padding: 32rpx 36rpx;
|
||||
@@ -343,6 +360,7 @@
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
overflow-y: scroll;
|
||||
|
||||
.member_list {
|
||||
flex: 1;
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<view class="contact_choose_container">
|
||||
<uni-nav-bar
|
||||
left-icon="back"
|
||||
@clickLeft="uni.$u.route({type:'back'})"
|
||||
statusBar
|
||||
title="群成员">
|
||||
<template v-slot:right>
|
||||
<u-button type="primary" size="mini" @click="confirm" :disabled="!isConfirmEnable">确定</u-button>
|
||||
</template>
|
||||
</uni-nav-bar>
|
||||
|
||||
<view class="search_bar_wrap">
|
||||
<u-search shape="square" placeholder="搜索" :showAction="false" v-model="keyword" />
|
||||
</view>
|
||||
|
||||
<view class="tab_container">
|
||||
<view class="tab_pane">
|
||||
<choose-index-list
|
||||
@updateCheck="updateCheckedUser"
|
||||
:indexList="getChooseData.indexList"
|
||||
:itemArr="getChooseData.dataList"
|
||||
:checkedIDList="checkedUserIDList"
|
||||
:disabledIDList="disabledUserIDList"
|
||||
:showCheck="muitple" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {formatChooseData,toastWithCallback} from "@/util/common";
|
||||
import IMSDK from "openim-uniapp-polyfill"
|
||||
import UserItem from "@/components/UserItem/index.vue";
|
||||
import ChooseIndexList from "@/components/ChooseIndexList/index.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
UserItem,
|
||||
ChooseIndexList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyword: "",
|
||||
groupID: "",
|
||||
groupMemberList:[],
|
||||
hideUserIDList: [],
|
||||
checkedUserIDList: [],
|
||||
disabledUserIDList: [],
|
||||
comfirmLoading: false,
|
||||
muitple:true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getChooseData() {
|
||||
const list = [...this.groupMemberList];
|
||||
if (this.keyword) {
|
||||
return {
|
||||
indexList: ["#"],
|
||||
dataList: [
|
||||
list.filter(
|
||||
(friend) =>{
|
||||
if(friend.nickname && friend.nickname.indexOf(this.keyword) !==-1){
|
||||
return true;
|
||||
}
|
||||
if(friend.remark && friend.remark.includes(this.keyword)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
),
|
||||
],
|
||||
};
|
||||
}
|
||||
return formatChooseData(list);
|
||||
},
|
||||
getCheckedUserInfo() {
|
||||
const tmpUserIDList = [...this.checkedUserIDList];
|
||||
const checkedFriends = this.groupMemberList.filter((friend) => {
|
||||
const idx = tmpUserIDList.findIndex(
|
||||
(userID) => userID === friend.userID
|
||||
);
|
||||
if (idx > -1) {
|
||||
tmpUserIDList.splice(idx, 1);
|
||||
}
|
||||
return idx > -1;
|
||||
});
|
||||
return [...checkedFriends];
|
||||
},
|
||||
isConfirmEnable(){
|
||||
if(this.checkedUserIDList.length){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
async onLoad(options) {
|
||||
const {groupID,checkedUserIDList,hideUserIDList,muitple} = options;
|
||||
this.groupID = groupID;
|
||||
if(muitple){
|
||||
this.muitple = muitple;
|
||||
}
|
||||
this.checkedUserIDList = checkedUserIDList ? JSON.parse(checkedUserIDList) : [];
|
||||
this.hideUserIDList = hideUserIDList ? JSON.parse(hideUserIDList) : [];
|
||||
const list = await this.getGroupMemberList();
|
||||
|
||||
this.groupMemberList = list.filter(
|
||||
(friend) =>{
|
||||
return false == this.hideUserIDList.includes(friend.userID);
|
||||
}
|
||||
);
|
||||
if (this.checkedUserIDList.length > 0) {
|
||||
this.checkDisabledUser();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getGroupMemberList() {
|
||||
const _this = this;
|
||||
return new Promise((resolve,reject)=>{
|
||||
if (!_this.groupID) {
|
||||
return reject('groupid is null');
|
||||
}
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.GetGroupMemberList, IMSDK.uuid(), {
|
||||
groupID: _this.groupID,
|
||||
filter: 0,
|
||||
offset: 0,
|
||||
count: 6,
|
||||
}).then(({ data }) => {
|
||||
return resolve(data)
|
||||
}).catch(e=>{
|
||||
return reject(e);
|
||||
})
|
||||
});
|
||||
},
|
||||
checkDisabledUser() {
|
||||
const friendIDList = this.groupMemberList.map((friend) => friend.userID);
|
||||
IMSDK.asyncApi("getUsersInGroup", IMSDK.uuid(), {
|
||||
groupID: this.groupID,
|
||||
userIDList: friendIDList,
|
||||
}).then(({data}) => {
|
||||
this.disabledUserIDList = data;
|
||||
});
|
||||
},
|
||||
tabChange(idx) {
|
||||
this.keyword = "";
|
||||
this.activeTab = idx;
|
||||
},
|
||||
updateCheckedUser({userID}) {
|
||||
if(!this.muitple){
|
||||
this.checkedUserIDList = [userID];
|
||||
this.confirm();
|
||||
}else{
|
||||
if (this.checkedUserIDList.includes(userID)) {
|
||||
const idx = this.checkedUserIDList.findIndex((item) => item === userID);
|
||||
const tmpArr = [...this.checkedUserIDList];
|
||||
tmpArr.splice(idx, 1);
|
||||
this.checkedUserIDList = [...tmpArr];
|
||||
} else {
|
||||
this.checkedUserIDList = [...this.checkedUserIDList, userID];
|
||||
}
|
||||
}
|
||||
},
|
||||
confirm() {
|
||||
this.comfirmLoading = true;
|
||||
try{
|
||||
const eventChannel = this.getOpenerEventChannel();
|
||||
eventChannel.emit('onSelectedConfirm', this.getCheckedUserInfo);
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
this.comfirmLoading = false;
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
this.comfirmLoading = false;
|
||||
},
|
||||
},
|
||||
onBackPress() {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.u-popup {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.contact_choose_container {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.search_bar_wrap {
|
||||
height: 34px;
|
||||
padding: 12px 22px;
|
||||
}
|
||||
|
||||
.tab_container {
|
||||
@include colBox(false);
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.setting_item {
|
||||
padding: 32rpx 36rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
// padding: 16rpx 8rpx;
|
||||
background: #f8f9fa;
|
||||
color: #8e9ab0;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.tabs_bar {
|
||||
@include vCenterBox();
|
||||
justify-content: space-evenly;
|
||||
|
||||
.tab_item {
|
||||
@include colBox(false);
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab_pane {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.member_list {
|
||||
flex: 1;
|
||||
height: 80% !important;
|
||||
|
||||
::v-deepuni-scroll-view {
|
||||
max-height: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.user_list {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.member_anchor {
|
||||
background-color: #f8f8f8 !important;
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<view class="contact_choose_container">
|
||||
<custom-nav-bar title="联系人" />
|
||||
<uni-nav-bar
|
||||
left-icon="back"
|
||||
@clickLeft="uni.$u.route({type:'back'})"
|
||||
statusBar
|
||||
title="联系人">
|
||||
</uni-nav-bar>
|
||||
|
||||
<view class="search_bar_wrap">
|
||||
<u-search shape="square" placeholder="搜索" :showAction="false" v-model="keyword" />
|
||||
@@ -8,14 +13,17 @@
|
||||
|
||||
<view class="tab_container">
|
||||
<template v-if="activeTab === 0">
|
||||
<setting-item @click="tabChange(tabs[0].idx)" :title="tabs[0].title" :border="false" />
|
||||
<div @click="tabChange(tabs[0].idx)" style="display: flex; align-items: center;justify-content: space-between;padding: 20rpx 40rpx;">
|
||||
{{ tabs[0].title }}
|
||||
<u-icon name="arrow-right" />
|
||||
</div>
|
||||
<view class="tab_pane">
|
||||
<user-item
|
||||
@updateCheck="updateCheckedUser"
|
||||
:checked="checkedUserIDList.includes(cell.userID)"
|
||||
:disabled="disabledUserIDList.includes(cell.userID)"
|
||||
:checkVisible="true"
|
||||
v-for="cell in storeConversationList" :item="cell" :key="cell.userID" />
|
||||
v-for="cell in conversationList" :item="cell" :key="cell.userID" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -33,23 +41,19 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import { mapGetters } from "vuex";
|
||||
import {ContactChooseTypes} from "@/constant";
|
||||
import {formatChooseData,toastWithCallback} from "@/util/common";
|
||||
import IMSDK from "openim-uniapp-polyfill";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import IMSDK from "openim-uniapp-polyfill"
|
||||
import UserItem from "@/components/UserItem/index.vue";
|
||||
import ChooseIndexList from "@/components/ChooseIndexList/index.vue";
|
||||
import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue";
|
||||
import SettingItem from "@/components/SettingItem/index.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
UserItem,
|
||||
ChooseIndexList,
|
||||
ChooseIndexFooter,
|
||||
SettingItem,
|
||||
ChooseIndexFooter
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -70,18 +74,42 @@
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
"storeFriendList",
|
||||
"storeCurrentConversation",
|
||||
"storeCurrentUserID",
|
||||
"storeConversationList",
|
||||
]),
|
||||
...mapGetters(["storeFriendList","storeConversationList",'storeCurrentConversation',"storeCurrentUserID"]),
|
||||
|
||||
conversationList(){
|
||||
const _this = this;
|
||||
let list = [...this.storeConversationList];
|
||||
list = list.filter((item)=>{
|
||||
return !item.userID.startsWith('system') && !item.userID.startsWith('official_team') && item.userID !== this.storeCurrentUserID
|
||||
});
|
||||
if(!this.allowGroup){
|
||||
list = list.filter((item)=>{
|
||||
return !item.groupID
|
||||
});
|
||||
}
|
||||
if(this.keyword){
|
||||
list = list.filter((item)=>{
|
||||
return item.showName.indexOf(_this.kw)>-1 || item.userID.indexOf(_this.kw)>-1 || item.groupID.indexOf(_this.kw)>-1
|
||||
})
|
||||
}
|
||||
return list;
|
||||
},
|
||||
getChooseData() {
|
||||
const _this = this;
|
||||
let list = [...this.storeFriendList];
|
||||
list = list.filter((item)=>{
|
||||
return !item.userID.startsWith('system') && !item.userID.startsWith('official_team') && item.userID !== this.storeCurrentUserID
|
||||
});
|
||||
if(!this.allowGroup){
|
||||
list = list.filter((item)=>{
|
||||
return !item.groupID
|
||||
});
|
||||
}
|
||||
if (this.keyword) {
|
||||
return {
|
||||
indexList: ["#"],
|
||||
dataList: [
|
||||
this.storeFriendList.filter(
|
||||
list.filter(
|
||||
(friend) =>
|
||||
friend.nickname.includes(this.keyword) ||
|
||||
friend.remark.includes(this.keyword)
|
||||
@@ -89,7 +117,7 @@
|
||||
],
|
||||
};
|
||||
}
|
||||
return formatChooseData(this.storeFriendList);
|
||||
return formatChooseData(list);
|
||||
},
|
||||
getCheckedInfo() {
|
||||
const tmpUserIDList = [...this.checkedUserIDList];
|
||||
@@ -106,10 +134,16 @@
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const {groupID,type,checkedUserIDList,limit} = options;
|
||||
//console.log(this.storeFriendList);
|
||||
//cardInfo
|
||||
const {groupID,type,checkedUserIDList,muitple,allowType,limit} = options;
|
||||
this.type = type;
|
||||
if(allowType){
|
||||
this.allowGroup = allowType === 'All';
|
||||
}
|
||||
this.groupID = groupID;
|
||||
if(muitple){
|
||||
this.muitple = muitple;
|
||||
}
|
||||
this.checkedUserIDList = checkedUserIDList ? JSON.parse(checkedUserIDList) : [];
|
||||
if (this.type === ContactChooseTypes.Invite) {
|
||||
this.checkDisabledUser();
|
||||
|
||||
@@ -48,11 +48,7 @@
|
||||
|
||||
<script>
|
||||
import { ContactChooseTypes } from "@/constant";
|
||||
import IMSDK, {
|
||||
GroupType,
|
||||
IMMethods,
|
||||
SessionType,
|
||||
} from "openim-uniapp-polyfill";
|
||||
import IMSDK, {GroupType,IMMethods,SessionType,} from "openim-uniapp-polyfill";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import { navigateToDesignatedConversation } from "@/util/imCommon";
|
||||
@@ -88,7 +84,7 @@ export default {
|
||||
(member) => member.userID,
|
||||
);
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.GetList}&checkedUserIDList=${JSON.stringify(checkedIDList)}`,
|
||||
url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.GetList}&checkedUserIDList=${JSON.stringify(checkedIDList)}&allowType=User`,
|
||||
});
|
||||
},
|
||||
complateCreate() {
|
||||
|
||||
@@ -1,94 +1,93 @@
|
||||
<template>
|
||||
<view class="details_container">
|
||||
<custom-nav-bar title="个人资料" />
|
||||
<view class="details_container">
|
||||
<custom-nav-bar title="个人资料" />
|
||||
|
||||
<view class="info_list">
|
||||
<user-info-row-item class="info_item" lable="头像" arrow>
|
||||
<my-avatar
|
||||
:src="sourceInfo.faceURL"
|
||||
:desc="sourceInfo.nickname"
|
||||
size="26"
|
||||
/>
|
||||
</user-info-row-item>
|
||||
<user-info-row-item class="info_item" lable="昵称" arrow>
|
||||
<text class="right_content">{{ sourceInfo.nickname }}</text>
|
||||
</user-info-row-item>
|
||||
<user-info-row-item class="info_item" lable="性别" arrow>
|
||||
<text class="right_content">{{ getGender }}</text>
|
||||
</user-info-row-item>
|
||||
<user-info-row-item class="info_item" lable="生日" arrow>
|
||||
<text class="right_content">{{ getBirthStr }}</text>
|
||||
</user-info-row-item>
|
||||
</view>
|
||||
<view class="info_list">
|
||||
<user-info-row-item class="info_item" lable="头像" arrow>
|
||||
<my-avatar :src="sourceInfo.faceURL" :desc="sourceInfo.nickname" size="26" />
|
||||
</user-info-row-item>
|
||||
<user-info-row-item class="info_item" lable="昵称" arrow>
|
||||
<text class="right_content">{{ sourceInfo.nickname }}</text>
|
||||
</user-info-row-item>
|
||||
<user-info-row-item class="info_item" lable="性别" arrow>
|
||||
<text class="right_content">{{ getGender }}</text>
|
||||
</user-info-row-item>
|
||||
<user-info-row-item class="info_item" lable="生日" arrow>
|
||||
<text class="right_content">{{ getBirthStr }}</text>
|
||||
</user-info-row-item>
|
||||
</view>
|
||||
|
||||
<view class="info_list">
|
||||
<user-info-row-item class="info_item" lable="手机号码" arrow>
|
||||
<text class="right_content">{{ sourceInfo.phoneNumber || "-" }}</text>
|
||||
</user-info-row-item>
|
||||
<user-info-row-item class="info_item" lable="邮箱" arrow>
|
||||
<text class="right_content">{{ sourceInfo.email || "-" }}</text>
|
||||
</user-info-row-item>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info_list">
|
||||
<user-info-row-item class="info_item" lable="手机号码" arrow>
|
||||
<text class="right_content">{{ sourceInfo.phoneNumber || "-" }}</text>
|
||||
</user-info-row-item>
|
||||
<user-info-row-item class="info_item" lable="邮箱" arrow>
|
||||
<text class="right_content">{{ sourceInfo.email || "-" }}</text>
|
||||
</user-info-row-item>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from "dayjs";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue";
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
MyAvatar,
|
||||
UserInfoRowItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sourceInfo: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getGender() {
|
||||
if (this.sourceInfo.gender === 1) {
|
||||
return "男";
|
||||
}
|
||||
if (this.sourceInfo.gender === 2) {
|
||||
return "女";
|
||||
}
|
||||
return "保密";
|
||||
},
|
||||
getBirthStr() {
|
||||
const birth = this.sourceInfo.birth ?? 0;
|
||||
return dayjs(birth).format("YYYY-MM-DD");
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const { sourceInfo } = options;
|
||||
this.sourceInfo = JSON.parse(sourceInfo);
|
||||
},
|
||||
};
|
||||
import dayjs from "dayjs";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
MyAvatar,
|
||||
UserInfoRowItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sourceInfo: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getGender() {
|
||||
if (this.sourceInfo.gender === 1) {
|
||||
return "男";
|
||||
}
|
||||
if (this.sourceInfo.gender === 2) {
|
||||
return "女";
|
||||
}
|
||||
return "保密";
|
||||
},
|
||||
getBirthStr() {
|
||||
const birth = this.sourceInfo.birth ?? 0;
|
||||
return dayjs(birth).format("YYYY-MM-DD");
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const {
|
||||
sourceInfo
|
||||
} = options;
|
||||
this.sourceInfo = util.aesdecode(sourceInfo);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.details_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
background-color: #f6f6f6;
|
||||
.details_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
background-color: #f6f6f6;
|
||||
|
||||
.info_list {
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
margin: 24rpx;
|
||||
.info_list {
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
margin: 24rpx;
|
||||
|
||||
.info_item {
|
||||
background-color: #fff;
|
||||
// border-bottom: 1px solid rgba(153, 153, 153, 0.3);
|
||||
.info_item {
|
||||
background-color: #fff;
|
||||
// border-bottom: 1px solid rgba(153, 153, 153, 0.3);
|
||||
|
||||
.right_content {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
.right_content {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+250
-276
@@ -1,309 +1,283 @@
|
||||
<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 util from "@/util/index.js"
|
||||
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 = util.aesdecode(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>
|
||||
@@ -2,7 +2,7 @@
|
||||
<view class="page_container">
|
||||
<view class="login">
|
||||
<view class="logo">
|
||||
<img src="static/images/logo.png" alt="" />
|
||||
<img :src="cdn(config.app_logo)" alt="" />
|
||||
<view class="title">欢迎使用{{ config.name }}</view>
|
||||
</view>
|
||||
<u-tabs v-if="1 == 2" :list="list" :current="active" @click="click"></u-tabs>
|
||||
@@ -32,8 +32,7 @@
|
||||
</u-form-item>
|
||||
<u-form-item v-if="active <= 1 && !isPwdLogin" label="" prop="verificationCode">
|
||||
<u-input v-model="loginInfo.verificationCode" border="surround" placeholder="请输入验证码">
|
||||
<view class="code_btn" slot="suffix" @click="getCode">
|
||||
{{ count !== 0 ? `${count} s` : "获取验证码" }}
|
||||
<view class="code_btn" slot="suffix" @click="getCode">{{ count !== 0 ? `${count} s` : "获取验证码" }}
|
||||
</view>
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
@@ -67,6 +66,9 @@ import AreaPicker from "@/components/AreaPicker";
|
||||
import { checkLoginError } from "@/util/common";
|
||||
import { SmsUserFor } from "@/constant";
|
||||
import IMSDK from "openim-uniapp-polyfill";
|
||||
import util from "@/util/index.js"
|
||||
import config from "@/common/config";
|
||||
import {getDbDir,toastWithCallback} from "@/util/common.js";
|
||||
|
||||
let timer;
|
||||
|
||||
@@ -119,6 +121,7 @@ export default {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
...util,
|
||||
click({ index }) {
|
||||
this.active = index;
|
||||
},
|
||||
@@ -143,59 +146,46 @@ export default {
|
||||
this.loginInfo.email = "commiu@outlook.com";
|
||||
this.loginInfo.password = "qwe123";
|
||||
}
|
||||
//plus.navigator.closeSplashscreen();
|
||||
},
|
||||
updateEye() {
|
||||
this.eying = !this.eying;
|
||||
},
|
||||
toRegisterOrForget(isRegister) {
|
||||
uni.$u.route("/pages/login/registerOrForget/index", {
|
||||
uni.$u.route("/pages/common/registerOrForget/index", {
|
||||
isRegister,
|
||||
});
|
||||
},
|
||||
async startLogin() {
|
||||
// this.$refs.loginForm.validate().then(async (valid) => {
|
||||
this.loading = true;
|
||||
this.saveLoginInfo();
|
||||
let data = {};
|
||||
try {
|
||||
data = await businessLogin({
|
||||
mobile: this.loginInfo.phoneNumber,
|
||||
email: this.loginInfo.email,
|
||||
region: `+${this.loginInfo.region}`,
|
||||
password: this.isPwdLogin ? md5(this.loginInfo.password) : "",
|
||||
platform: uni.$u.os(),
|
||||
type: this.active === 0 ? 'mobile' : 'email',
|
||||
code: this.loginInfo.verificationCode,
|
||||
});
|
||||
const { imToken, userID } = data;
|
||||
this.loading = true;
|
||||
this.saveLoginInfo();
|
||||
let data = {};
|
||||
try {
|
||||
data = await businessLogin({
|
||||
mobile: this.loginInfo.phoneNumber,
|
||||
email: this.loginInfo.email,
|
||||
region: `+${this.loginInfo.region}`,
|
||||
password: this.isPwdLogin ? md5(this.loginInfo.password) : "",
|
||||
platform: uni.$u.os(),
|
||||
type: this.active === 0 ? 'mobile' : 'email',
|
||||
code: this.loginInfo.verificationCode,
|
||||
});
|
||||
const { imToken, userID } = data;
|
||||
this.saveLoginProfile(data);
|
||||
this.$store.commit("user/SET_AUTH_DATA", data);
|
||||
this.loginInfo.password = "";
|
||||
// #ifdef APP
|
||||
await IMSDK.asyncApi(IMSDK.IMMethods.Login, uuidv4(), {
|
||||
userID,
|
||||
token: imToken,
|
||||
});
|
||||
// await IMSDK.asyncApi(IMSDK.IMMethods.Login, uuidv4(), {
|
||||
// userID,
|
||||
// token: imToken,
|
||||
// });
|
||||
plus.runtime.restart();
|
||||
// #endif
|
||||
this.saveLoginProfile(data);
|
||||
this.$store.commit("user/SET_AUTH_DATA", data);
|
||||
this.$store.dispatch("user/getSelfInfo");
|
||||
this.$store.dispatch("conversation/getConversationList");
|
||||
this.$store.dispatch("conversation/getUnReadCount");
|
||||
// this.$store.dispatch("contact/getFriendList");
|
||||
// this.$store.dispatch("contact/getGrouplist");
|
||||
this.$store.dispatch("contact/getBlacklist");
|
||||
this.$store.dispatch("contact/getRecvFriendApplications");
|
||||
this.$store.dispatch("contact/getSentFriendApplications");
|
||||
this.$store.dispatch("contact/getRecvGroupApplications");
|
||||
this.$store.dispatch("contact/getSentGroupApplications");
|
||||
uni.switchTab({
|
||||
url: "/pages/conversation/conversationList/index",
|
||||
});
|
||||
this.loginInfo.password = "";
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
uni.$u.toast(checkLoginError(err));
|
||||
}
|
||||
this.loading = false;
|
||||
// });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
uni.$u.toast(checkLoginError(err));
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
saveLoginProfile(data) {
|
||||
const { imToken, token, userID } = data;
|
||||
@@ -227,12 +217,13 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const options = {
|
||||
phoneNumber: this.loginInfo.phoneNumber,
|
||||
region: `+${this.loginInfo.region}`,
|
||||
usedFor: SmsUserFor.Login,
|
||||
operationID: Date.now() + "",
|
||||
};
|
||||
const options = {
|
||||
mobile: this.loginInfo.phoneNumber,
|
||||
email: this.loginInfo.email,
|
||||
region: `+${this.loginInfo.region}`,
|
||||
event: "login",
|
||||
type:"mobile"
|
||||
};
|
||||
businessSendSms(options)
|
||||
.then(() => {
|
||||
uni.$u.toast("验证码已发送!");
|
||||
@@ -279,9 +270,10 @@ export default {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
border-radius: 32rpx;
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
}
|
||||
+60
-24
@@ -1,33 +1,39 @@
|
||||
<template>
|
||||
<view class="map_page">
|
||||
<u-navbar left-icon="arrow-left" @leftClick="back" placeholder bgColor="transparent">
|
||||
<template slot="right">
|
||||
<u-button type="primary" class="confirm_btn" size="mini" @click="confirm">确定</u-button>
|
||||
</template>
|
||||
</u-navbar>
|
||||
<view style="display: flex; flex-direction: column; height: 100%;">
|
||||
<!-- 使用web-view嵌入天地图 -->
|
||||
<ly-map class="ly-map"
|
||||
v-if="lng && lat"
|
||||
@onUserEvent="onUserEvent"
|
||||
ref="map"
|
||||
:type="type"
|
||||
:lonlat=[lng,lat]
|
||||
:map-key="apikey" />
|
||||
<view class="search_container" v-if="1==2">
|
||||
<u-search placeholder="日照香炉生紫烟" v-model="keyword"></u-search>
|
||||
<u-cell-group :customStyle="{backgroundColor:'#FFF'}">
|
||||
<u-cell title="摇一摇" icon="/static/images/workbench/05.png" :size="cellSize"></u-cell>
|
||||
<u-cell title="看一看" icon="/static/images/workbench/06.png" :size="cellSize"></u-cell>
|
||||
<u-cell title="听一听" icon="/static/images/workbench/06.png" :size="cellSize"></u-cell>
|
||||
<u-cell title="附近" icon="/static/images/workbench/08.png" :size="cellSize"></u-cell>
|
||||
<u-cell title="购物" icon="/static/images/workbench/09.png" :size="cellSize"></u-cell>
|
||||
<u-cell title="摇一摇" icon="/static/images/find/05.png" :size="cellSize"></u-cell>
|
||||
<u-cell title="看一看" icon="/static/images/find/06.png" :size="cellSize"></u-cell>
|
||||
<u-cell title="听一听" icon="/static/images/find/06.png" :size="cellSize"></u-cell>
|
||||
<u-cell title="附近" icon="/static/images/find/08.png" :size="cellSize"></u-cell>
|
||||
<u-cell title="购物" icon="/static/images/find/09.png" :size="cellSize"></u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="map_info" v-if="type == 'viewlocation'">
|
||||
<view class="left">
|
||||
<u-text wordWrap="anywhere" size="16" :text="address"></u-text>
|
||||
</view>
|
||||
<u-button @click="gotoMap" class="right">
|
||||
<uni-icons size="36" color="#07c160" type="paperplane-filled"></uni-icons>
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -53,6 +59,7 @@
|
||||
if(opt.address){
|
||||
this.address = opt.address;
|
||||
}
|
||||
console.log(this.type)
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
@@ -72,10 +79,12 @@
|
||||
})
|
||||
}
|
||||
},
|
||||
gotoMap(){
|
||||
util.toMapAPP(this.lng,this.lat,this.address);
|
||||
},
|
||||
onUserEvent(e) {
|
||||
//console.log(e)
|
||||
if(this.type=='chooselocation'){
|
||||
if(e.type == "move"){
|
||||
if(e.type == "move"){
|
||||
if(this.type=='chooselocation'){
|
||||
this.lng = e.lng;
|
||||
this.lat = e.lat;
|
||||
this.$refs.map.setMarkers([
|
||||
@@ -84,10 +93,22 @@
|
||||
lat: Number(e.lat)
|
||||
}
|
||||
]);
|
||||
return ;
|
||||
}
|
||||
if(this.type=='viewlocation'){
|
||||
return ;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
if(this.type=='viewlocation'){
|
||||
if(e.type=='back'){
|
||||
uni.navigateBack();
|
||||
return ;
|
||||
}
|
||||
if(e.type=='confirm'){
|
||||
this.confirm();
|
||||
return ;
|
||||
}
|
||||
//console.log(e)
|
||||
},
|
||||
/**
|
||||
* 确定位置按钮点击
|
||||
@@ -107,14 +128,14 @@
|
||||
uni.request({
|
||||
url:url,
|
||||
success(res){
|
||||
//console.log(res.data);
|
||||
console.log(res.data);
|
||||
const result = res.data.result;
|
||||
_this.address = result.formatted_address;
|
||||
console.log( {
|
||||
lng: result.location.lon,
|
||||
lat: result.location.lat,
|
||||
address: result.formatted_address
|
||||
});
|
||||
// console.log( {
|
||||
// lng: result.location.lon,
|
||||
// lat: result.location.lat,
|
||||
// address: result.formatted_address
|
||||
// });
|
||||
//return 1;
|
||||
// 通过事件通道返回数据给父页面
|
||||
const eventChannel = _this.getOpenerEventChannel();
|
||||
@@ -122,7 +143,9 @@
|
||||
eventChannel.emit('onConfirm', {
|
||||
lng: result.location.lon,
|
||||
lat: result.location.lat,
|
||||
address: result.formatted_address
|
||||
name: result.addressComponent.town,
|
||||
address: result.formatted_address,
|
||||
addressComponent:result.addressComponent
|
||||
});
|
||||
uni.navigateBack();
|
||||
},
|
||||
@@ -153,8 +176,21 @@
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.confirm_btn{
|
||||
padding: 30rpx 10rpx;
|
||||
.map_info{
|
||||
height: 100rpx;
|
||||
padding: 50rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.left{
|
||||
flex:1;
|
||||
}
|
||||
.right{
|
||||
width: 100rpx;
|
||||
.u-button{
|
||||
background-color: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
<script>
|
||||
import IMSDK from "openim-uniapp-polyfill";
|
||||
import util from "@/util/index.js"
|
||||
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import {
|
||||
@@ -56,7 +57,7 @@
|
||||
isSelfNickname,
|
||||
sourceInfo
|
||||
} = options;
|
||||
this.sourceInfo = JSON.parse(sourceInfo);
|
||||
this.sourceInfo = util.aesdecode(sourceInfo);
|
||||
console.log(sourceInfo);
|
||||
console.log(this.sourceInfo);
|
||||
this.isRemark = !!isRemark;
|
||||
|
||||
@@ -34,15 +34,10 @@
|
||||
|
||||
<script>
|
||||
import AreaPicker from "@/components/AreaPicker";
|
||||
import {
|
||||
businessSendSms
|
||||
} from "@/api/login";
|
||||
import {
|
||||
SmsUserFor
|
||||
} from "@/constant";
|
||||
import {
|
||||
checkLoginError
|
||||
} from "@/util/common";
|
||||
import {businessSendSms} from "@/api/login";
|
||||
import {SmsUserFor} from "@/constant";
|
||||
import {checkLoginError} from "@/util/common";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
components: {
|
||||
AreaPicker,
|
||||
@@ -98,8 +93,8 @@
|
||||
uni.$u.toast("验证码已发送!");
|
||||
setTimeout(
|
||||
() =>
|
||||
uni.$u.route("/pages/login/verifyCode/index", {
|
||||
userInfo: JSON.stringify(this.userInfo),
|
||||
uni.$u.route("/pages/common/verifyCode/index", {
|
||||
userInfo: util.aesencode(this.userInfo),
|
||||
isRegister: this.isRegister,
|
||||
}),
|
||||
1000,
|
||||
@@ -112,7 +107,7 @@
|
||||
});
|
||||
},
|
||||
back() {
|
||||
uni.$u.route("/pages/login/index");
|
||||
uni.$u.route("/pages/common/login/index");
|
||||
},
|
||||
showPicker() {
|
||||
this.$refs.AreaPicker.init();
|
||||
+17
-31
@@ -1,24 +1,9 @@
|
||||
<template>
|
||||
<view class="scan_page" :style="{height:windowHeight+'px'}">
|
||||
<uni-nav-bar
|
||||
left-icon="back"
|
||||
@clickLeft="back"
|
||||
fixed
|
||||
backgroundColor="#FFF"
|
||||
statusBar
|
||||
>
|
||||
<uni-nav-bar left-icon="back" @clickLeft="back" fixed backgroundColor="#FFF" statusBar>
|
||||
</uni-nav-bar>
|
||||
<barcode id='1'
|
||||
class="barcode"
|
||||
ref="barcode"
|
||||
:autostart="true"
|
||||
background="rgb(0,0,0)"
|
||||
frameColor="#07c160"
|
||||
scanbarColor="#07c160"
|
||||
:style="{height:windowHeight+'px'}"
|
||||
:filters="fil"
|
||||
@marked="success"
|
||||
@error="fail">
|
||||
<barcode id='1' class="barcode" ref="barcode" :autostart="true" background="rgb(0,0,0)" frameColor="#07c160"
|
||||
scanbarColor="#07c160" :style="{height:windowHeight+'px'}" :filters="fil" @marked="success" @error="fail">
|
||||
</barcode>
|
||||
<view class="overlay">
|
||||
<button class="btn" @click="toStart">开始扫码识别</button>
|
||||
@@ -33,8 +18,8 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
fil: [0, 2, 1,3,4,12],
|
||||
windowHeight:500,
|
||||
fil: [0, 2, 1, 3, 4, 12],
|
||||
windowHeight: 500,
|
||||
}
|
||||
},
|
||||
|
||||
@@ -52,10 +37,10 @@
|
||||
},
|
||||
methods: {
|
||||
success(e) {
|
||||
console.log("success1:" + JSON.stringify(e));
|
||||
//console.log("success1:" + JSO1N.stringify(e));
|
||||
},
|
||||
fail(e) {
|
||||
console.log("fail1:" + JSON.stringify(e));
|
||||
//console.log("fail1:" + JSON1.stringify(e));
|
||||
},
|
||||
toStart: function() {
|
||||
this.$refs.barcode.start({
|
||||
@@ -63,7 +48,7 @@
|
||||
filename: '_doc/barcode/'
|
||||
});
|
||||
},
|
||||
tocancel:function(){
|
||||
tocancel: function() {
|
||||
this.$refs.barcode.cancel();
|
||||
},
|
||||
toFlash: function() {
|
||||
@@ -73,12 +58,11 @@
|
||||
toscan: function() {
|
||||
console.log("scan:");
|
||||
const barcodeModule = uni.requireNativePlugin('barcodeScan');
|
||||
barcodeModule.scan("/static/barcode1.png"
|
||||
,(e)=>{
|
||||
console.log("scan_error:"+JSON.stringify(e));
|
||||
barcodeModule.scan("/static/barcode1.png", (e) => {
|
||||
console.log("scan_error:", e);
|
||||
});
|
||||
},
|
||||
back(){
|
||||
back() {
|
||||
uni.navigateBack();
|
||||
}
|
||||
}
|
||||
@@ -86,14 +70,15 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.scan_page{
|
||||
.scan_page {
|
||||
width: 750rpx;
|
||||
position: relative;
|
||||
|
||||
.barcode {
|
||||
width: 750rpx;
|
||||
background-color: #808080;
|
||||
}
|
||||
|
||||
|
||||
.btn {
|
||||
top: 20rpx;
|
||||
width: 730rpx;
|
||||
@@ -102,7 +87,8 @@
|
||||
background-color: #458B00;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.overlay{
|
||||
|
||||
.overlay {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
position: absolute;
|
||||
bottom: 100rpx;
|
||||
@@ -111,4 +97,4 @@
|
||||
height: 200rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -32,9 +32,8 @@
|
||||
|
||||
import searchGroup from "static/images/contact_add_join_group_fill.png";
|
||||
import searchUser from "static/images/contact_add_search_user_fill.png";
|
||||
import {
|
||||
businessSearchUserInfo
|
||||
} from "@/api/login";
|
||||
import {businessSearchUserInfo} from "@/api/login";
|
||||
import util from "@/util/index.js"
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -86,10 +85,10 @@
|
||||
);
|
||||
info = data[0];
|
||||
}
|
||||
console.log(info)
|
||||
if (info) {
|
||||
const s = util.aesencode(info);
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/groupCard/index?sourceInfo=${JSON.stringify(info,)}`,
|
||||
url: `/pages/common/groupCard/index?sourceInfo=${s}`,
|
||||
});
|
||||
} else {
|
||||
this.empty = true;
|
||||
@@ -117,7 +116,7 @@
|
||||
console.log(info)
|
||||
if (info) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/userCard/index?sourceInfo=${JSON.stringify(info,)}`,
|
||||
url: `/pages/common/userCard/index?sourceID=${info.userID}`,
|
||||
});
|
||||
} else {
|
||||
this.empty = true;
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<view class="set_password_container content_with_back">
|
||||
<view class="title">重置密码</view>
|
||||
<u-form class="loginForm commonPage-form" labelPosition="top" :model="formData" :rules="rules" :labelStyle="{
|
||||
fontSize: '14px',
|
||||
marginTop: '20rpx',
|
||||
minWidth: '200rpx',
|
||||
}" ref="loginForm">
|
||||
fontSize: '14px',
|
||||
marginTop: '20rpx',
|
||||
minWidth: '200rpx',
|
||||
}" ref="loginForm">
|
||||
<u-form-item label="密码" prop="password">
|
||||
<u-input v-model="formData.password" border="surround" placeholder="请输入密码" :password="!passwordEying">
|
||||
<u-icon @click="updateEye('passwordEying')" slot="suffix"
|
||||
@@ -30,9 +30,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
businessReset
|
||||
} from "@/api/login";
|
||||
import {businessReset} from "@/api/login";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -61,7 +60,7 @@
|
||||
validator: (rule, value, callback) => {
|
||||
return value.length >= 6;
|
||||
},
|
||||
message: "密码太短",
|
||||
message: "密码太过于简单",
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
@@ -89,8 +88,8 @@
|
||||
isRegister,
|
||||
codeValue
|
||||
} = options;
|
||||
this.userInfo = JSON.parse(userInfo);
|
||||
this.isRegister = JSON.parse(isRegister);
|
||||
this.userInfo = util.aesdecode(userInfo);
|
||||
this.isRegister = util.parse(isRegister);
|
||||
this.codeValue = codeValue;
|
||||
},
|
||||
onBackPress() {
|
||||
@@ -112,7 +111,7 @@
|
||||
businessReset(options)
|
||||
.then(() => {
|
||||
uni.$u.toast("密码重置成功,请前往登录!");
|
||||
setTimeout(() => uni.$u.route("/pages/login/index"), 1000);
|
||||
setTimeout(() => uni.$u.route("/pages/common/login/index"), 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('err', err)
|
||||
@@ -2,10 +2,10 @@
|
||||
<view class="set_info_container content_with_back">
|
||||
<view class="title">设置信息</view>
|
||||
<u-form class="loginForm commonPage-form" labelPosition="top" :model="userInfo" :rules="rules" :labelStyle="{
|
||||
fontSize: '14px',
|
||||
marginTop: '20rpx',
|
||||
minWidth: '200rpx',
|
||||
}" ref="loginForm">
|
||||
fontSize: '14px',
|
||||
marginTop: '20rpx',
|
||||
minWidth: '200rpx',
|
||||
}" ref="loginForm">
|
||||
<u-form-item label="昵称" prop="nickname">
|
||||
<u-input v-model="userInfo.nickname" border="surround" placeholder="请输入您的昵称" clearable>
|
||||
</u-input>
|
||||
@@ -37,8 +37,9 @@
|
||||
import md5 from "md5";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import { mapGetters } from "vuex";
|
||||
import { businessRegister } from "@/api/login";
|
||||
import { checkLoginError } from "@/util/common";
|
||||
import {businessRegister} from "@/api/login";
|
||||
import {checkLoginError } from "@/util/common";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
components: {
|
||||
MyAvatar,
|
||||
@@ -61,10 +62,11 @@
|
||||
nickname: [{
|
||||
type: "string",
|
||||
required: true,
|
||||
message: "请填写真实姓名",
|
||||
message: "请填写您的昵称",
|
||||
trigger: ["blur", "change"],
|
||||
}, ],
|
||||
password: [{
|
||||
password: [
|
||||
{
|
||||
type: "string",
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
@@ -75,20 +77,20 @@
|
||||
validator: (rule, value, callback) => {
|
||||
return value.length >= 6;
|
||||
},
|
||||
message: "密码太短",
|
||||
message: "密码太过于简单",
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
confirmPassword: [{
|
||||
type: "string",
|
||||
required: true,
|
||||
message: "请输入确认密码",
|
||||
message: "请再次输入密码",
|
||||
trigger: ["blur", "change"],
|
||||
pattern: /^(?=.*\d)(?=.*[a-zA-Z]).{6,}$/,
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
return value === this.formData.password;
|
||||
return value === this.userInfo.password;
|
||||
},
|
||||
message: "两次密码不一致",
|
||||
trigger: ["change", "blur"],
|
||||
@@ -102,15 +104,17 @@
|
||||
},
|
||||
onLoad(options) {
|
||||
const {userInfo,codeValue} = options;
|
||||
this.userInfo = {
|
||||
...this.userInfo,
|
||||
...JSON.parse(userInfo),
|
||||
};
|
||||
if(userInfo){
|
||||
this.userInfo = {
|
||||
...this.userInfo,
|
||||
...util.aesdecode(userInfo),
|
||||
};
|
||||
}
|
||||
this.codeValue = codeValue;
|
||||
if(process.env.NODE_ENV == 'development'){
|
||||
//this.userInfo.email = "commiu@outlook.com";
|
||||
this.userInfo.nickname = "";
|
||||
this.userInfo.password = "qwe123";
|
||||
this.userInfo.password = "qwe1231";
|
||||
this.userInfo.confirmPassword = "qwe123";
|
||||
}
|
||||
},
|
||||
@@ -128,36 +132,46 @@
|
||||
}
|
||||
});
|
||||
},
|
||||
async doRegister() {
|
||||
this.loading = true;
|
||||
const options = {
|
||||
code: this.codeValue,
|
||||
platform: uni.$u.os(),
|
||||
autoLogin: true,
|
||||
...this.userInfo,
|
||||
region: `+${this.userInfo.region}`,
|
||||
password: md5(this.userInfo.password),
|
||||
mobile: this.userInfo.mobile
|
||||
};
|
||||
try {
|
||||
await businessRegister(options);
|
||||
this.saveLoginInfo();
|
||||
uni.$u.toast('注册成功')
|
||||
uni.$u.route("/pages/login/index")
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
if(err.msg=="验证码过期" || err.msg=="验证码错误"){
|
||||
uni.$u.route("/pages/login/verifyCode/index", {
|
||||
userInfo: JSON.stringify(this.userInfo),
|
||||
isRegister: true,
|
||||
resend: 1,
|
||||
})
|
||||
return ;
|
||||
doRegister() {
|
||||
const _this = this;
|
||||
this.$refs.loginForm.validate().then(async (res) => {
|
||||
_this.loading = true;
|
||||
console.log(res);
|
||||
const options = {
|
||||
code: _this.codeValue,
|
||||
platform: uni.$u.os(),
|
||||
autoLogin: true,
|
||||
..._this.userInfo,
|
||||
region: `+${_this.userInfo.region}`,
|
||||
password: md5(_this.userInfo.password),
|
||||
mobile: _this.userInfo.mobile
|
||||
};
|
||||
try {
|
||||
await businessRegister(options);
|
||||
_this.saveLoginInfo();
|
||||
uni.$u.toast('注册成功')
|
||||
uni.$u.route("/pages/common/login/index")
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
if(err.msg=="验证码过期" || err.msg=="验证码错误"){
|
||||
const s = util.aesencode(_this.userInfo);
|
||||
uni.$u.route("/pages/common/verifyCode/index", {
|
||||
userInfo: s,
|
||||
isRegister: true,
|
||||
resend: 1,
|
||||
})
|
||||
return ;
|
||||
}
|
||||
// uni.$u.toast('注册失败')
|
||||
} finally {
|
||||
_this.loading = false;
|
||||
}
|
||||
// uni.$u.toast('注册失败')
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
uni.$u.toast('校验通过')
|
||||
}).catch(errors => {
|
||||
console.log(errors);
|
||||
uni.$u.toast('校验失败')
|
||||
});
|
||||
return ;
|
||||
},
|
||||
saveLoginInfo() {
|
||||
uni.setStorage({
|
||||
@@ -174,7 +188,6 @@
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.set_info_container {
|
||||
margin-top: var(--status-bar-height);
|
||||
background: linear-gradient(180deg,
|
||||
rgba(0, 137, 255, 0.1) 0%,
|
||||
rgba(255, 255, 255, 0) 100%);
|
||||
+100
-30
@@ -1,24 +1,32 @@
|
||||
<template>
|
||||
<view class="m-shade n-flex-1 n-align-center n-justify-center">
|
||||
<view :style="{width:'580rpx'}">
|
||||
<image src="/static/image/upgrade.png" mode="widthFix"></image>
|
||||
<view class="n-ps-all-ll n-ms-top-ll n-position-absolute">
|
||||
<text class="n-size-mm n-weight-7 n-color-inverse">发现新版本</text>
|
||||
<text class="n-size-base n-ms-top-ss n-color-inverse">V{{model.version}}</text>
|
||||
</view>
|
||||
<view class="n-ps-all-l n-radius-lb-base" :style="{backgroundColor:'#f3f3f3',borderRadius:'0 0 16rpx 16rpx'}">
|
||||
<view :style="{height:'300rpx'}">
|
||||
<scroll-view class="n-flex-1" :show-scrollbar="false" scroll-y>
|
||||
<rich-text class="n-size-s" :nodes="model.content" :style="{lineHeight:'26rpx'}"></rich-text>
|
||||
</scroll-view>
|
||||
<view class="upgrade_page">
|
||||
<uni-nav-bar left-icon="back"
|
||||
@clickLeft="back"
|
||||
title="系统更新"
|
||||
backgroundColor="#FFF"
|
||||
fixed
|
||||
statusBar>
|
||||
</uni-nav-bar>
|
||||
|
||||
<view style="flex:1;display: flex;align-items: center;justify-content: center;">
|
||||
<view :style="{width:'580rpx',position:'relative'}">
|
||||
<image src="/static/images/upgrade.png" :style="{width:'580rpx'}" mode="widthFix"></image>
|
||||
<view class="version_info">
|
||||
<text class="title">发现新版本</text>
|
||||
<text class="code">V{{model.version}}</text>
|
||||
</view>
|
||||
<view class="n-height-base n-justify-center">
|
||||
<view v-if="progress">
|
||||
<uv-line-progress :percentage="value" activeColor="#fc3463"></uv-line-progress>
|
||||
</view>
|
||||
<view class="n-flex-row" v-else>
|
||||
<uv-button class="n-flex-1 n-ms-right-ll" v-if="model.force==0" @click="cancel" :customStyle="{backgroundColor:'#f3f3f3'}" text="暂不更新" color="#fc3463" shape="circle" throttleTime="1000" plain></uv-button>
|
||||
<uv-button class="n-flex-1" @click="upgrade" text="立即更新" color="#fc3463" shape="circle" throttleTime="1000"></uv-button>
|
||||
<view class="detail">
|
||||
<scroll-view :show-scrollbar="false" scroll-y>
|
||||
<rich-text :nodes="model.content"></rich-text>
|
||||
</scroll-view>
|
||||
<view class="footer">
|
||||
<view v-if="progress">
|
||||
<u-line-progress :percentage="value" activeColor="#fc3463"></u-line-progress>
|
||||
</view>
|
||||
<view class="buttons" v-else>
|
||||
<u-button v-if="model.force==0" @click="cancel" :customStyle="{backgroundColor:'#f3f3f3'}" text="暂不更新" color="#fc3463" shape="circle" throttleTime="1000" plain></u-button>
|
||||
<u-button @click="upgrade" text="立即更新" color="#fc3463" shape="circle" throttleTime="1000"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -27,7 +35,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -42,9 +50,23 @@
|
||||
}
|
||||
},
|
||||
onLoad(evt) {
|
||||
if(evt.model){
|
||||
this.model = {...this.model, ...JSON.parse(evt.model)}
|
||||
// if(evt.model){
|
||||
// this.model = {...this.model, ...JSON.parse(evt.model)}
|
||||
// }
|
||||
var model = uni.getStorageSync('upgrade_model');
|
||||
console.log(model);
|
||||
if(model){
|
||||
this.model = {...this.model, ...model};
|
||||
}
|
||||
// this.model = {
|
||||
// "id": 1,
|
||||
// "type": 1,
|
||||
// "force": 1,
|
||||
// "source": "https://shunliao.oss-accelerate.aliyuncs.com/files/150016c51d8672fde3d1cc6945a95089_695d97b6c0162.wgt",
|
||||
// "version": "3.3.6",
|
||||
// "content": "修复了一些bug",
|
||||
// "source_text": null
|
||||
// };
|
||||
},
|
||||
onBackPress() {
|
||||
if(this.model.force==1){
|
||||
@@ -52,6 +74,11 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back(){
|
||||
if(this.model.force!=1){
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
// 取消更新
|
||||
cancel() {
|
||||
uni.navigateBack()
|
||||
@@ -80,17 +107,14 @@
|
||||
// 防止强制更新无法关闭界面
|
||||
this.model.force = 0
|
||||
if(this.model.type==1){
|
||||
uni.showToast({
|
||||
title:'更新成功,软件重启'
|
||||
})
|
||||
util.showToast('更新成功,软件重启')
|
||||
setTimeout(()=>{ plus.runtime.restart() }, 1500)
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: error=>{
|
||||
uni.showToast({
|
||||
title:'下载失败,请检查您的网络情况'
|
||||
})
|
||||
util.showToast('下载失败,请检查您的网络情况')
|
||||
this.model.force = 0;
|
||||
}
|
||||
})
|
||||
// 监听下载进度
|
||||
@@ -103,8 +127,54 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.m-shade{
|
||||
<style lang="scss" scoped>
|
||||
.upgrade_page{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
.version_info{
|
||||
position: absolute;
|
||||
top:120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin-left: 20rpx;
|
||||
width: 100%;
|
||||
.title{
|
||||
color: #fff;
|
||||
}
|
||||
.code{
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.detail{
|
||||
margin-top: -10rpx;
|
||||
background-color:#f3f3f3;
|
||||
border-radius:0 0 16rpx 16rpx;
|
||||
padding: 10rpx 20rpx 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
scroll-view{
|
||||
flex: 1;
|
||||
min-height: 300rpx;
|
||||
rich-text{
|
||||
font-size:32rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
.footer{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 20rpx;
|
||||
.buttons{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,51 +1,55 @@
|
||||
<template>
|
||||
<view @click="click" class="row_item" :class="{ arrow_right: arrow }">
|
||||
<view class="title">
|
||||
<text>{{ lable }}</text>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>{{ content }}</text>
|
||||
</view>
|
||||
<slot>
|
||||
<u-icon v-if="arrow" name="arrow-right" color="#999" size="20"></u-icon>
|
||||
</slot>
|
||||
</view>
|
||||
<view @click="click" class="row_item" :class="{ arrow_right: arrow }">
|
||||
<view class="title">
|
||||
<text>{{ lable }}</text>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>{{ content }}</text>
|
||||
</view>
|
||||
<slot>
|
||||
<u-icon v-if="arrow" name="arrow-right" color="#999" size="20"></u-icon>
|
||||
</slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "",
|
||||
components: {},
|
||||
props: {
|
||||
lable: String,
|
||||
content: String,
|
||||
arrow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
click() {
|
||||
this.$emit("click");
|
||||
},
|
||||
},
|
||||
};
|
||||
export default {
|
||||
name: "",
|
||||
components: {},
|
||||
props: {
|
||||
lable: String,
|
||||
content: String,
|
||||
arrow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
click() {
|
||||
this.$emit("click");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.row_item {
|
||||
@include vCenterBox();
|
||||
padding: 24rpx 44rpx;
|
||||
}
|
||||
.row_item {
|
||||
@include vCenterBox();
|
||||
padding: 24rpx 44rpx;
|
||||
.content{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
.title {
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.arrow_right {
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
.arrow_right {
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<view class="user_card_container">
|
||||
<u-loading-page :loading="isLoading" loading-text="loading..."></u-loading-page>
|
||||
<custom-nav-bar title="" />
|
||||
<custom-nav-bar title="" @rightClick="toMoreInfo" more v-if="isFriend" />
|
||||
<custom-nav-bar title="" v-else />
|
||||
|
||||
<view v-if="!isLoading" style="flex: 1;display: flex;flex-direction: column;">
|
||||
<view class="base_info">
|
||||
@@ -9,26 +10,23 @@
|
||||
size="46" />
|
||||
<view class="user_name">
|
||||
<text class="text">{{ getShowName }}</text>
|
||||
<text class="id" @click="copy(sourceUserInfo.userID)">{{sourceUserInfo.userID}}</text>
|
||||
</view>
|
||||
<view class="add_btn" @click="toAddFriend" v-if="trySendRequest">
|
||||
<u-button type="primary" icon="man-add" text="添加"></u-button>
|
||||
<text class="id" @click="copy(sourceUserInfo.userID || sourceUserInfo.id)">{{sourceUserInfo.userID || sourceUserInfo.id}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info_row">
|
||||
<user-info-row-item lable="性别" :content="getGender" />
|
||||
<user-info-row-item lable="生日" :content="getBirth" />
|
||||
<user-info-row-item lable="个性签名" :content="sourceUserInfo.bio" />
|
||||
</view>
|
||||
<view v-if="isFriend" class="info_row">
|
||||
<user-info-row-item @click="toMoreInfo" lable="个人资料" arrow />
|
||||
</view>
|
||||
|
||||
<uni-list class="info_row">
|
||||
<uni-list-item title="性别" :rightText="getGender"></uni-list-item>
|
||||
<uni-list-item title="生日" :rightText="getBirth"></uni-list-item>
|
||||
<uni-list-item title="个性签名">
|
||||
<u--text slot="footer" color="#999" :text="sourceUserInfo.bio" :lines="2" wordWrap="anywhere"></u--text>
|
||||
</uni-list-item>
|
||||
</uni-list>
|
||||
<uni-list class="info_row" v-if="isFriend">
|
||||
<uni-list-item v-if="isFriend" title="性别" @click="toMoreInfo" clickable showArrow></uni-list-item>
|
||||
<uni-list-item v-if="1==2" title="朋友圈" @click="gotoCircle" clickable showArrow></uni-list-item>
|
||||
</uni-list>
|
||||
<view class="action_row" v-if="!isSelf">
|
||||
<view @click="toDesignatedConversation" class="action_item">
|
||||
<img src="static/images/user_card_message.png" alt="" />
|
||||
<text>发消息</text>
|
||||
</view>
|
||||
<u-button type="primary" icon="chat" text="发消息" @click="toDesignatedConversation" v-if="isFriend"></u-button>
|
||||
<u-button type="primary" icon="man-add" text="添加" @click="toAddFriend" v-else></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -43,6 +41,7 @@
|
||||
import UserInfoRowItem from "./components/UserInfoRowItem.vue";
|
||||
import {businessSearchUserInfo} from "@/api/login";
|
||||
import dayjs from "dayjs";
|
||||
import util from "@/util/index.js"
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -106,10 +105,9 @@
|
||||
if (sourceID) {
|
||||
this.sourceID = sourceID;
|
||||
} else {
|
||||
const info = JSON.parse(sourceInfo);
|
||||
const info = util.aesdecode(sourceInfo);
|
||||
this.sourceID = info.userID;
|
||||
}
|
||||
//console.log(this.storeSelfInfo);
|
||||
this.getSourceUserInfo();
|
||||
},
|
||||
methods: {
|
||||
@@ -132,6 +130,7 @@
|
||||
info = {
|
||||
...friendInfo
|
||||
};
|
||||
//console.log(info);
|
||||
} else {
|
||||
const {
|
||||
data
|
||||
@@ -143,21 +142,14 @@
|
||||
info = {
|
||||
...(data[0] ?? {})
|
||||
};
|
||||
//console.log(info);
|
||||
}
|
||||
this.isLoading = true
|
||||
try {
|
||||
const res = await businessSearchUserInfo(this.sourceID);
|
||||
const res = await businessSearchUserInfo(this.sourceID);console.log(res);
|
||||
if (res.total > 0) {
|
||||
const {
|
||||
data
|
||||
} = await IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.GetUsersInfo,
|
||||
IMSDK.uuid(),
|
||||
[this.sourceID+''],
|
||||
);
|
||||
const imData = data[0]?.friendInfo ?? data[0]?.publicInfo ?? {};
|
||||
info = {
|
||||
...imData,
|
||||
...info,
|
||||
...res.data[0],
|
||||
};
|
||||
}
|
||||
@@ -165,6 +157,7 @@
|
||||
info = {};
|
||||
}
|
||||
this.isLoading = false
|
||||
//console.log(info);
|
||||
this.sourceUserInfo = {
|
||||
...info,
|
||||
};
|
||||
@@ -177,6 +170,13 @@
|
||||
notNeedVerification: false,
|
||||
});
|
||||
},
|
||||
gotoCircle(){
|
||||
console.log('gotoCircle');
|
||||
return ;
|
||||
uni.navigateTo({
|
||||
url:"/pages/find/friend-circle/friend-circle?userId="+this.sourceID
|
||||
})
|
||||
},
|
||||
toDesignatedConversation() {
|
||||
navigateToDesignatedConversation(
|
||||
this.sourceID,
|
||||
@@ -185,8 +185,9 @@
|
||||
).catch(() => uni.$u.toast("获取会话信息失败"));
|
||||
},
|
||||
toMoreInfo() {
|
||||
const s = util.aesencode(this.sourceUserInfo);
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/userCardMore/index?sourceInfo=${JSON.stringify(this.sourceUserInfo,)}`,
|
||||
url: `/pages/common/userCardMore/index?sourceInfo=${s}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -207,16 +208,6 @@
|
||||
padding: 44rpx;
|
||||
margin-bottom: 18rpx;
|
||||
|
||||
.add_btn {
|
||||
width: 140rpx;
|
||||
height: 60rpx;
|
||||
margin-left: auto;
|
||||
|
||||
.u-button {
|
||||
width: 140rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.u-avatar {
|
||||
margin-right: 24rpx;
|
||||
@@ -226,7 +217,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12rpx;
|
||||
height: 46px;
|
||||
|
||||
.text {
|
||||
@@ -271,23 +261,6 @@
|
||||
margin: 44rpx;
|
||||
flex: 1;
|
||||
|
||||
.action_item {
|
||||
width: 100%;
|
||||
@include colBox(true);
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 22rpx 0;
|
||||
background: $u-primary;
|
||||
color: #fff;
|
||||
border-radius: 12rpx;
|
||||
|
||||
img {
|
||||
margin-right: 16rpx;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.id {
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
import IMSDK from "openim-uniapp-polyfill";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue";
|
||||
import {
|
||||
ContactChooseTypes
|
||||
} from "@/constant";
|
||||
import {ContactChooseTypes} from "@/constant";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
@@ -59,7 +58,7 @@
|
||||
},
|
||||
onLoad(options) {
|
||||
const {sourceInfo} = options;
|
||||
this.sourceInfo = JSON.parse(sourceInfo);
|
||||
this.sourceInfo = util.aesdecode(sourceInfo);
|
||||
},
|
||||
methods: {
|
||||
change(isBlack) {
|
||||
@@ -76,23 +75,31 @@
|
||||
},
|
||||
confirmRemove() {
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.DeleteFriend,IMSDK.uuid(),this.sourceInfo.userID,)
|
||||
.then(() => this.showToast("操作成功"))
|
||||
.then(() => {
|
||||
this.showToast("操作成功");
|
||||
uni.navigateBack({
|
||||
delta: 2,
|
||||
})
|
||||
})
|
||||
.catch(() => this.showToast("操作失败"))
|
||||
.finally(() => (this.showConfirm = false));
|
||||
},
|
||||
toMore() {
|
||||
const s = util.aesencode(this.sourceInfo);
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/detailsFileds/index?sourceInfo=${JSON.stringify(this.sourceInfo,)}`,
|
||||
url: `/pages/common/detailsFileds/index?sourceInfo=${s}`,
|
||||
});
|
||||
},
|
||||
toMark() {
|
||||
const s = util.aesencode(this.sourceInfo);
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/markOrIDPage/index?isRemark=true&sourceInfo=${JSON.stringify(this.sourceInfo,)}`,
|
||||
url: `/pages/common/markOrIDPage/index?isRemark=true&sourceInfo=${s}`,
|
||||
});
|
||||
},
|
||||
toShare() {
|
||||
const s = util.aesencode(this.sourceInfo);
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.ShareCard}&cardInfo=${JSON.stringify(this.sourceInfo)}`,
|
||||
url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.ShareCard}&cardInfo=${s}`,
|
||||
});
|
||||
},
|
||||
showToast(message) {
|
||||
|
||||
@@ -14,22 +14,25 @@
|
||||
</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>
|
||||
</view>
|
||||
<canvas canvas-id="qrcode_canvas" id="qrcode_canvas" style="width: 600rpx; height: 600rpx"></canvas>
|
||||
<view id="qrcode_canvas_container" style="width: 600rpx; height: 600rpx">
|
||||
<canvas canvas-id="qrcode_canvas" id="qrcode_canvas" style="width: 600rpx; height: 600rpx"></canvas>
|
||||
</view>
|
||||
<u-gap></u-gap>
|
||||
<view style="color: #b4b4b4;">扫一扫上面的二维码图案,加我为朋友</view>
|
||||
</view>
|
||||
<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="scan" type="default" plain :hairline="false" color="#506388" iconColor="#9aa2b2">扫一扫</u-button>
|
||||
<u-button @click="createQrcode" type="default" plain :hairline="false" color="#506388" iconColor="#9aa2b2">换个样式</u-button>
|
||||
<u-button @click="save" type="default" plain :hairline="false" color="#506388" iconColor="#9aa2b2">保存图片</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -39,6 +42,7 @@
|
||||
import QRCode from "@/components/qrcode.js";
|
||||
import UserBase from '@/components/User.vue';
|
||||
import util from "@/util";
|
||||
import { mapGetters } from "vuex";
|
||||
export default {
|
||||
mixins:[UserBase],
|
||||
components: {
|
||||
@@ -46,37 +50,128 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
qrcodeUrl:"",
|
||||
qrcode_src:"",
|
||||
source:{
|
||||
type:"user",
|
||||
showName:"",
|
||||
faceURL:"",
|
||||
code:"",
|
||||
},
|
||||
qrcodeSize:"360",
|
||||
qrcodeStyle:[]
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
console.log(this.userInfo)
|
||||
this.createQrcode();
|
||||
computed:{
|
||||
...mapGetters(["storeFriendList","storeGroupList","config"]),
|
||||
},
|
||||
watch:{
|
||||
qrcodeSize(nv,ov){
|
||||
if(nv && this.qrcodeUrl){
|
||||
this.createQrcode();
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(opt) {
|
||||
if(opt.sourceInfo){
|
||||
this.source = util.aesdecode(opt.sourceInfo);
|
||||
}else{
|
||||
this.source = {
|
||||
type:"user",
|
||||
showName:"",
|
||||
faceURL:"",
|
||||
code:"",
|
||||
};
|
||||
}
|
||||
if(this.source.type == "user"){
|
||||
this.qrcodeUrl = `${this.config.website}/u/${this.source.code}`;
|
||||
}else{
|
||||
this.qrcodeUrl = `${this.config.website}/g/${this.source.code}`;
|
||||
}
|
||||
this.qrcodeStyle.push({
|
||||
background: "#fff", // 背景色
|
||||
foreground: '#000000', // 前景色
|
||||
pdground: '#000000', // 定位角点颜色
|
||||
correctLevel: 3, // 容错级别
|
||||
image: this.config.app_logo, // 二维码图标
|
||||
imageSize: 40, // 二维码图标大小
|
||||
});
|
||||
this.qrcodeStyle.push({
|
||||
background: "#fff", // 背景色
|
||||
foreground: '#000000', // 前景色
|
||||
pdground: '#000000', // 定位角点颜色
|
||||
correctLevel: 3, // 容错级别
|
||||
image: this.source.faceURL, // 二维码图标
|
||||
imageSize: 40, // 二维码图标大小
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
const _this = this;
|
||||
uni.createSelectorQuery().in(this).select("#qrcode_canvas_container")
|
||||
.boundingClientRect((data) => {
|
||||
_this.qrcodeSize = data.width
|
||||
|
||||
})
|
||||
.exec();
|
||||
},
|
||||
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;
|
||||
const style = this.qrcodeStyle[Math.floor(Math.random() * this.qrcodeStyle.length)];
|
||||
style.imageSize = parseInt(this.qrcodeSize * 0.2);
|
||||
return new Promise((resolve, reject) => {
|
||||
new QRCode({
|
||||
context: _this, // 上下文环境
|
||||
canvasId: 'qrcode_canvas', // canvas-id
|
||||
usingComponents: true, // 是否是自定义组件
|
||||
showLoading: false, // 是否显示loading
|
||||
loadingText: "", // loading文字
|
||||
text: "/pages/common/invite_register?code=", // 生成内容
|
||||
size: 320, // 二维码大小
|
||||
background: "#fff", // 背景色
|
||||
foreground: '#000000', // 前景色
|
||||
pdground: '#000000', // 定位角点颜色
|
||||
correctLevel: 3, // 容错级别
|
||||
image: "", // 二维码图标
|
||||
imageSize: 40, // 二维码图标大小
|
||||
cbResult: function(res) { // 生成二维码的回调
|
||||
//_this.qrcode_src = (res)
|
||||
//resolve(res);
|
||||
},
|
||||
});
|
||||
var createFn = (icon)=>{
|
||||
console.log(icon)
|
||||
new QRCode({
|
||||
context: _this, // 上下文环境
|
||||
canvasId: 'qrcode_canvas', // canvas-id
|
||||
usingComponents: true, // 是否是自定义组件
|
||||
showLoading: false, // 是否显示loading
|
||||
loadingText: "", // loading文字
|
||||
text: `${_this.qrcodeUrl}`, // 生成内容
|
||||
size: _this.qrcodeSize, // 二维码大小
|
||||
background: style.background, // 背景色
|
||||
foreground: style.foreground, // 前景色
|
||||
pdground: style.pdground, // 定位角点颜色
|
||||
correctLevel: 3, // 容错级别
|
||||
image: icon || "", // 二维码图标
|
||||
imageSize: style.imageSize || 40, // 二维码图标大小
|
||||
cbResult: function(res) { // 生成二维码的回调
|
||||
_this.qrcode_src = (res)
|
||||
//resolve(res);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if(!style.image){
|
||||
createFn();
|
||||
return ;
|
||||
}
|
||||
if(style.image.startsWith("/static/images")){
|
||||
createFn(style.image);
|
||||
return ;
|
||||
}
|
||||
if(!style.image.startsWith("http")){
|
||||
style.image = util.cdn(style.image);
|
||||
}
|
||||
util.cacheFile(style.image,'avatar').then(fn=>{
|
||||
createFn(fn);
|
||||
});
|
||||
return ;
|
||||
});
|
||||
},
|
||||
}
|
||||
@@ -84,48 +179,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>
|
||||
@@ -22,10 +22,11 @@
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import user from "../../../store/modules/user";
|
||||
import { businessSendSms, businessVerifyCode } from "@/api/login";
|
||||
import { SmsUserFor } from "@/constant";
|
||||
import { checkLoginError } from "@/util/common";
|
||||
import user from "@/store/modules/user";
|
||||
import {businessSendSms,businessVerifyCode} from "@/api/login";
|
||||
import {SmsUserFor} from "@/constant";
|
||||
import {checkLoginError } from "@/util/common";
|
||||
import util from "@/util/index.js"
|
||||
let timer;
|
||||
export default {
|
||||
data() {
|
||||
@@ -49,7 +50,7 @@
|
||||
resend
|
||||
} = options;
|
||||
console.log(userInfo,isRegister)
|
||||
this.userInfo = JSON.parse(userInfo);
|
||||
this.userInfo = util.aesdecode(userInfo);
|
||||
this.isRegister = JSON.parse(isRegister);
|
||||
if(resend == 1){
|
||||
this.count = 0;
|
||||
@@ -61,7 +62,7 @@
|
||||
onReady() {},
|
||||
methods: {
|
||||
back() {
|
||||
uni.$u.route("/pages/login/registerOrForget/index", {
|
||||
uni.$u.route("/pages/common/registerOrForget/index", {
|
||||
isRegister: this.isRegister,
|
||||
});
|
||||
},
|
||||
@@ -76,15 +77,16 @@
|
||||
};
|
||||
businessVerifyCode(options)
|
||||
.then(() => {
|
||||
const s = util.aesencode(this.userInfo);
|
||||
if (this.isRegister) {
|
||||
uni.$u.route("/pages/login/setSelfInfo/index", {
|
||||
userInfo: JSON.stringify(this.userInfo),
|
||||
uni.$u.route("/pages/common/setSelfInfo/index", {
|
||||
userInfo: s,
|
||||
isRegister: this.isRegister,
|
||||
codeValue: this.codeValue,
|
||||
});
|
||||
} else {
|
||||
uni.$u.route("/pages/login/setPassword/index", {
|
||||
userInfo: JSON.stringify(this.userInfo),
|
||||
uni.$u.route("/pages/common/setPassword/index", {
|
||||
userInfo: s,
|
||||
isRegister: !this.isRegister,
|
||||
codeValue: this.codeValue,
|
||||
});
|
||||
@@ -1,256 +1,245 @@
|
||||
<template>
|
||||
<view class="page_container">
|
||||
<custom-nav-bar :title="isGroupApplication ? '群通知' : '好友请求'" />
|
||||
<view class="page_container">
|
||||
<custom-nav-bar :title="isGroupApplication ? '群通知' : '好友请求'" />
|
||||
|
||||
<view class="application_item">
|
||||
<view class="base_info_row">
|
||||
<view class="base_info_left" @click="toSourceDetails">
|
||||
<my-avatar :src="getSourceFaceURL" :desc="getSourceName" />
|
||||
<view class="base_info_details">
|
||||
<text class="nickname">{{ getSourceName }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="application_item">
|
||||
<view class="base_info_row">
|
||||
<view class="base_info_left" @click="toSourceDetails">
|
||||
<my-avatar :src="getSourceFaceURL" :desc="getSourceName" />
|
||||
<view class="base_info_details">
|
||||
<text class="nickname">{{ getSourceName }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-icon name="arrow-right" size="18" color="#999"></u-icon>
|
||||
</view>
|
||||
<u-icon name="arrow-right" size="18" color="#999"></u-icon>
|
||||
</view>
|
||||
|
||||
<view class="request_message">
|
||||
<view v-if="isGroupApplication" class="title">
|
||||
<text>申请加入 </text>
|
||||
<text class="group_name">{{ currentApplication.groupName }}</text>
|
||||
</view>
|
||||
<text v-else>{{ `${getSourceName}:` }}</text>
|
||||
<text>{{ currentApplication.reqMsg }}</text>
|
||||
</view>
|
||||
<view class="request_message">
|
||||
<view v-if="isGroupApplication" class="title">
|
||||
<text>申请加入 </text>
|
||||
<text class="group_name">{{ currentApplication.groupName }}</text>
|
||||
</view>
|
||||
<text v-else>{{ `${getSourceName}:` }}</text>
|
||||
<text>{{ currentApplication.reqMsg }}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="action_row">
|
||||
<u-button
|
||||
:loading="loadingState.accept"
|
||||
@click="acceptAplication"
|
||||
type="primary"
|
||||
:plain="true"
|
||||
:text="`通过${isGroupApplication ? '入群' : '好友'}申请`"
|
||||
></u-button>
|
||||
</view>
|
||||
<view class="action_row">
|
||||
<u-button :loading="loadingState.accept" @click="acceptAplication" type="primary" :plain="true"
|
||||
:text="`通过${isGroupApplication ? '入群' : '好友'}申请`"></u-button>
|
||||
</view>
|
||||
|
||||
<view class="action_row">
|
||||
<u-button
|
||||
:loading="loadingState.refuse"
|
||||
@click="refuseAplication"
|
||||
type="primary"
|
||||
:plain="true"
|
||||
:text="`拒绝${isGroupApplication ? '入群' : '好友'}申请`"
|
||||
></u-button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="action_row">
|
||||
<u-button :loading="loadingState.refuse" @click="refuseAplication" type="primary" :plain="true"
|
||||
:text="`拒绝${isGroupApplication ? '入群' : '好友'}申请`"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import IMSDK, { GroupJoinSource } from "openim-uniapp-polyfill";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
MyAvatar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentApplication: {},
|
||||
isOnline: false,
|
||||
loadingState: {
|
||||
accept: false,
|
||||
refuse: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["storeSelfInfo"]),
|
||||
isGroupApplication() {
|
||||
return this.currentApplication.groupID !== undefined;
|
||||
},
|
||||
getSourceID() {
|
||||
return (
|
||||
this.currentApplication.fromUserID ?? this.currentApplication.userID
|
||||
);
|
||||
},
|
||||
getSourceName() {
|
||||
return (
|
||||
this.currentApplication.fromNickname ?? this.currentApplication.nickname
|
||||
);
|
||||
},
|
||||
getSourceFaceURL() {
|
||||
return (
|
||||
this.currentApplication.fromFaceURL ?? this.currentApplication.faceURL
|
||||
);
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const { application } = options;
|
||||
this.currentApplication = JSON.parse(application);
|
||||
},
|
||||
methods: {
|
||||
toSourceDetails() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/userCard/index?sourceID=${this.getSourceID}`,
|
||||
});
|
||||
},
|
||||
acceptAplication() {
|
||||
this.loadingState.accept = true;
|
||||
let func;
|
||||
if (this.isGroupApplication) {
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.AcceptGroupApplication,
|
||||
IMSDK.uuid(),
|
||||
{
|
||||
groupID: this.currentApplication.groupID,
|
||||
fromUserID: this.currentApplication.userID,
|
||||
handleMsg: "",
|
||||
},
|
||||
);
|
||||
} else {
|
||||
console.log(this.currentApplication);
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.AcceptFriendApplication,
|
||||
IMSDK.uuid(),
|
||||
{
|
||||
toUserID: this.currentApplication.fromUserID,
|
||||
handleMsg: "",
|
||||
},
|
||||
);
|
||||
}
|
||||
func
|
||||
.then(() => {
|
||||
uni.$u.toast("操作成功");
|
||||
setTimeout(() => uni.navigateBack(), 500);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
uni.$u.toast("操作失败");
|
||||
})
|
||||
.finally(() => (this.loadingState.accept = false));
|
||||
},
|
||||
refuseAplication() {
|
||||
this.loadingState.refuse = true;
|
||||
let func;
|
||||
if (this.isGroupApplication) {
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.RefuseGroupApplication,
|
||||
IMSDK.uuid(),
|
||||
{
|
||||
groupID: this.currentApplication.groupID,
|
||||
fromUserID: this.currentApplication.userID,
|
||||
handleMsg: "",
|
||||
},
|
||||
);
|
||||
} else {
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.RefuseFriendApplication,
|
||||
IMSDK.uuid(),
|
||||
{
|
||||
toUserID: this.currentApplication.fromUserID,
|
||||
handleMsg: "",
|
||||
},
|
||||
);
|
||||
}
|
||||
func
|
||||
.then(() => {
|
||||
uni.$u.toast("操作成功");
|
||||
setTimeout(() => uni.navigateBack(), 250);
|
||||
})
|
||||
.catch(() => uni.$u.toast("操作失败"))
|
||||
.finally(() => (this.loadingState.refuse = false));
|
||||
},
|
||||
},
|
||||
};
|
||||
import {mapGetters} from "vuex";
|
||||
import IMSDK, {GroupJoinSource} from "openim-uniapp-polyfill";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
MyAvatar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentApplication: {},
|
||||
isOnline: false,
|
||||
loadingState: {
|
||||
accept: false,
|
||||
refuse: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["storeSelfInfo"]),
|
||||
isGroupApplication() {
|
||||
return this.currentApplication.groupID !== undefined;
|
||||
},
|
||||
getSourceID() {
|
||||
return (
|
||||
this.currentApplication.fromUserID ?? this.currentApplication.userID
|
||||
);
|
||||
},
|
||||
getSourceName() {
|
||||
return (
|
||||
this.currentApplication.fromNickname ?? this.currentApplication.nickname
|
||||
);
|
||||
},
|
||||
getSourceFaceURL() {
|
||||
return (
|
||||
this.currentApplication.fromFaceURL ?? this.currentApplication.faceURL
|
||||
);
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const {
|
||||
application
|
||||
} = options;
|
||||
this.currentApplication = util.aesdecode(application);
|
||||
},
|
||||
methods: {
|
||||
toSourceDetails() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/userCard/index?sourceID=${this.getSourceID}`,
|
||||
});
|
||||
},
|
||||
acceptAplication() {
|
||||
this.loadingState.accept = true;
|
||||
let func;
|
||||
if (this.isGroupApplication) {
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.AcceptGroupApplication,
|
||||
IMSDK.uuid(), {
|
||||
groupID: this.currentApplication.groupID,
|
||||
fromUserID: this.currentApplication.userID,
|
||||
handleMsg: "",
|
||||
},
|
||||
);
|
||||
} else {
|
||||
console.log(this.currentApplication);
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.AcceptFriendApplication,
|
||||
IMSDK.uuid(), {
|
||||
toUserID: this.currentApplication.fromUserID,
|
||||
handleMsg: "",
|
||||
},
|
||||
);
|
||||
}
|
||||
func
|
||||
.then(() => {
|
||||
uni.$u.toast("操作成功");
|
||||
setTimeout(() => uni.navigateBack(), 500);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
uni.$u.toast("操作失败");
|
||||
})
|
||||
.finally(() => (this.loadingState.accept = false));
|
||||
},
|
||||
refuseAplication() {
|
||||
this.loadingState.refuse = true;
|
||||
let func;
|
||||
if (this.isGroupApplication) {
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.RefuseGroupApplication,
|
||||
IMSDK.uuid(), {
|
||||
groupID: this.currentApplication.groupID,
|
||||
fromUserID: this.currentApplication.userID,
|
||||
handleMsg: "",
|
||||
},
|
||||
);
|
||||
} else {
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.RefuseFriendApplication,
|
||||
IMSDK.uuid(), {
|
||||
toUserID: this.currentApplication.fromUserID,
|
||||
handleMsg: "",
|
||||
},
|
||||
);
|
||||
}
|
||||
func
|
||||
.then(() => {
|
||||
uni.$u.toast("操作成功");
|
||||
setTimeout(() => uni.navigateBack(), 250);
|
||||
})
|
||||
.catch(() => uni.$u.toast("操作失败"))
|
||||
.finally(() => (this.loadingState.refuse = false));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page_container {
|
||||
background-color: #f8f8f8;
|
||||
.page_container {
|
||||
background-color: #f8f8f8;
|
||||
|
||||
.application_item {
|
||||
padding: 72rpx 44rpx 24rpx;
|
||||
background-color: #fff;
|
||||
.application_item {
|
||||
padding: 72rpx 44rpx 24rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.base_info_row {
|
||||
@include btwBox();
|
||||
.base_info_row {
|
||||
@include btwBox();
|
||||
|
||||
.base_info_left {
|
||||
@include vCenterBox();
|
||||
}
|
||||
.base_info_left {
|
||||
@include vCenterBox();
|
||||
}
|
||||
|
||||
.base_info_details {
|
||||
margin-left: 24rpx;
|
||||
.base_info_details {
|
||||
margin-left: 24rpx;
|
||||
|
||||
.nickname {
|
||||
@include nomalEllipsis();
|
||||
max-width: 600rpx;
|
||||
}
|
||||
.nickname {
|
||||
@include nomalEllipsis();
|
||||
max-width: 600rpx;
|
||||
}
|
||||
|
||||
.online_state {
|
||||
@include vCenterBox();
|
||||
flex-direction: row;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 6rpx;
|
||||
.online_state {
|
||||
@include vCenterBox();
|
||||
flex-direction: row;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 6rpx;
|
||||
|
||||
.dot {
|
||||
background-color: #10cc64;
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.dot {
|
||||
background-color: #10cc64;
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.request_message {
|
||||
background-color: #eee;
|
||||
margin-top: 48rpx;
|
||||
padding: 24rpx 36rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
min-height: 240rpx;
|
||||
.request_message {
|
||||
background-color: #eee;
|
||||
margin-top: 48rpx;
|
||||
padding: 24rpx 36rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
min-height: 240rpx;
|
||||
|
||||
.title {
|
||||
margin-bottom: 12rpx;
|
||||
color: $uni-text-color;
|
||||
.title {
|
||||
margin-bottom: 12rpx;
|
||||
color: $uni-text-color;
|
||||
|
||||
.group_name {
|
||||
@nomalEllipsis();
|
||||
max-width: 400rpx;
|
||||
color: $uni-color-primary;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.group_name {
|
||||
@nomalEllipsis();
|
||||
max-width: 400rpx;
|
||||
color: $uni-color-primary;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.join_source {
|
||||
margin-top: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.join_source {
|
||||
margin-top: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.action_row {
|
||||
margin-top: 24rpx;
|
||||
.action_row {
|
||||
margin-top: 24rpx;
|
||||
|
||||
.u-button {
|
||||
border: none;
|
||||
}
|
||||
.u-button {
|
||||
border: none;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.u-button {
|
||||
color: #999 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
&:last-child {
|
||||
.u-button {
|
||||
color: #999 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -28,13 +28,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
navigateToDesignatedConversation
|
||||
} from "@/util/imCommon";
|
||||
import IMSDK, {
|
||||
SessionType
|
||||
} from "openim-uniapp-polyfill";
|
||||
import {navigateToDesignatedConversation} from "@/util/imCommon";
|
||||
import IMSDK, {SessionType} from "openim-uniapp-polyfill";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
name: "ApplicationItem",
|
||||
components: {
|
||||
@@ -97,17 +94,12 @@
|
||||
methods: {
|
||||
clickItem() {
|
||||
if (this.showAccept) {
|
||||
const s = util.aesencode(this.application);
|
||||
uni.navigateTo({
|
||||
url: `/pages/contact/applicationDetails/index?application=${JSON.stringify(
|
||||
this.application,
|
||||
)}`,
|
||||
url: `/pages/contact/applicationDetails/index?application=${s}`,
|
||||
});
|
||||
} else {
|
||||
let sourceID =
|
||||
this.application.groupID ??
|
||||
(this.isRecv ?
|
||||
this.application.fromUserID :
|
||||
this.application.toUserID);
|
||||
let sourceID = this.application.groupID ?? (this.isRecv ? this.application.fromUserID : this.application.toUserID);
|
||||
let cardType = this.isGroupApplication ? "groupCard" : "userCard";
|
||||
const url = `/pages/common/${cardType}/index?sourceID=${sourceID}`;
|
||||
uni.navigateTo({
|
||||
|
||||
@@ -1,173 +1,185 @@
|
||||
<template>
|
||||
<view class="application_list_container">
|
||||
<custom-nav-bar :title="isGroupApplication ? '新的群聊' : '新的好友'" />
|
||||
<view
|
||||
class="pane_row"
|
||||
:style="{ transform: `translateX(${isRecv ? '0' : '-100%'})` }"
|
||||
>
|
||||
<view class="pane_content">
|
||||
<u-list v-if="getRecvRenderData.length > 0" class="application_list">
|
||||
<u-list-item
|
||||
v-for="application in getRecvRenderData"
|
||||
:key="
|
||||
application[!isGroupApplication ? 'fromUserID' : 'userID'] +
|
||||
application.groupID
|
||||
"
|
||||
>
|
||||
<application-item :isRecv="true" :application="application" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<u-list
|
||||
v-else-if="getSendRenderData.length > 0"
|
||||
class="application_list"
|
||||
>
|
||||
<u-list-item
|
||||
v-for="application in getSendRenderData"
|
||||
:key="application[!isGroupApplication ? 'toUserID' : 'groupID']"
|
||||
>
|
||||
<application-item :application="application" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<view v-else class="empty">
|
||||
<image src="@/static/images/block_empty.png"></image>
|
||||
<text class="empty_text">暂无数据</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="application_list_container">
|
||||
<custom-nav-bar :title="isGroupApplication ? '新的群聊' : '新的好友'" />
|
||||
<view class="pane_row" :style="{ transform: `translateX(${isRecv ? '0' : '-100%'})` }">
|
||||
<view class="pane_content">
|
||||
<u-list v-if="getRecvRenderData.length > 0" class="application_list">
|
||||
<u-list-item v-for="(application,index) in getRecvRenderData" :key="index">
|
||||
<application-item :isRecv="true" :application="application" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<u-list v-else-if="getSendRenderData.length > 0" class="application_list">
|
||||
<u-list-item v-for="(application,index1) in getSendRenderData"
|
||||
:key="index1">
|
||||
<application-item :application="application" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<view v-else class="empty">
|
||||
<image src="@/static/images/block_empty.png"></image>
|
||||
<text class="empty_text">暂无数据</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import { ContactMenuTypes } from "@/constant";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import ApplicationItem from "./ApplicationItem.vue";
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
ApplicationItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyword: "",
|
||||
isRecv: true,
|
||||
isGroupApplication: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
"storeRecvFriendApplications",
|
||||
"storeSentFriendApplications",
|
||||
"storeRecvGroupApplications",
|
||||
"storeSentGroupApplications",
|
||||
]),
|
||||
getRecvRenderData() {
|
||||
const tmpList = this.isGroupApplication
|
||||
? this.storeRecvGroupApplications
|
||||
: this.storeRecvFriendApplications;
|
||||
tmpList.sort((a, b) => (a.handleResult === 0 ? -1 : 1));
|
||||
return tmpList.slice(0, 4);
|
||||
},
|
||||
getSendRenderData() {
|
||||
const tmpList = this.isGroupApplication
|
||||
? this.storeSentGroupApplications
|
||||
: this.storeSentFriendApplications;
|
||||
tmpList.sort((a, b) => (a.handleResult === 0 ? -1 : 1));
|
||||
return tmpList.slice(0, 4);
|
||||
},
|
||||
tabList() {
|
||||
return [
|
||||
{
|
||||
name: this.isGroupApplication ? "入群申请" : "好友请求",
|
||||
},
|
||||
{
|
||||
name: "我的请求",
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
onLoad(params) {
|
||||
const { applicationType } = params;
|
||||
this.isGroupApplication = applicationType === ContactMenuTypes.NewGroup;
|
||||
},
|
||||
methods: {
|
||||
clickTab({ index }) {
|
||||
this.isRecv = index === 0;
|
||||
},
|
||||
previewAll() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/contact/applicationListDetails/index?isGroupApplication=${this.isGroupApplication}&isRecv=${this.isRecv}`,
|
||||
});
|
||||
},
|
||||
toSearch() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/searchUserOrGroup/index?isSearchGroup=${this.isGroupApplication}`,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
import {
|
||||
ContactMenuTypes
|
||||
} from "@/constant";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import ApplicationItem from "./ApplicationItem.vue";
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
ApplicationItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyword: "",
|
||||
isRecv: true,
|
||||
isGroupApplication: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
"storeRecvFriendApplications",
|
||||
"storeSentFriendApplications",
|
||||
"storeRecvGroupApplications",
|
||||
"storeSentGroupApplications",
|
||||
]),
|
||||
getRecvRenderData() {
|
||||
const tmpList = this.isGroupApplication ?
|
||||
this.storeRecvGroupApplications :
|
||||
this.storeRecvFriendApplications;
|
||||
tmpList.sort((a, b) => (a.handleResult === 0 ? -1 : 1));
|
||||
return tmpList.slice(0, 4);
|
||||
},
|
||||
getSendRenderData() {
|
||||
const tmpList = this.isGroupApplication ?
|
||||
this.storeSentGroupApplications :
|
||||
this.storeSentFriendApplications;
|
||||
tmpList.sort((a, b) => (a.handleResult === 0 ? -1 : 1));
|
||||
return tmpList.slice(0, 4);
|
||||
},
|
||||
tabList() {
|
||||
return [{
|
||||
name: this.isGroupApplication ? "入群申请" : "好友请求",
|
||||
},
|
||||
{
|
||||
name: "我的请求",
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
// watch:{
|
||||
// getRecvRenderData:{
|
||||
// handler(v){
|
||||
// console.log(v)
|
||||
// },
|
||||
// immediate: true, // 立即执行一次
|
||||
// deep: true // 开启深度监听
|
||||
// },
|
||||
// getSendRenderData:{
|
||||
// handler(v){
|
||||
// console.log(v)
|
||||
// },
|
||||
// immediate: true, // 立即执行一次
|
||||
// deep: true // 开启深度监听
|
||||
// }
|
||||
// },
|
||||
onLoad(params) {
|
||||
const {
|
||||
applicationType
|
||||
} = params;
|
||||
this.isGroupApplication = applicationType === ContactMenuTypes.NewGroup;
|
||||
},
|
||||
methods: {
|
||||
clickTab({
|
||||
index
|
||||
}) {
|
||||
this.isRecv = index === 0;
|
||||
},
|
||||
previewAll() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/contact/applicationListDetails/index?isGroupApplication=${this.isGroupApplication}&isRecv=${this.isRecv}`,
|
||||
});
|
||||
},
|
||||
toSearch() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/searchUserOrGroup/index?isSearchGroup=${this.isGroupApplication}`,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.empty {
|
||||
@include centerBox();
|
||||
flex-direction: column;
|
||||
margin-top: 25vh !important;
|
||||
.empty {
|
||||
@include centerBox();
|
||||
flex-direction: column;
|
||||
margin-top: 25vh !important;
|
||||
|
||||
&_text {
|
||||
margin-top: 26rpx;
|
||||
color: #8e9ab0;
|
||||
}
|
||||
image {
|
||||
width: 237rpx;
|
||||
height: 244rpx;
|
||||
}
|
||||
}
|
||||
.application_list_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
background-color: #f8f9fa;
|
||||
overflow-x: hidden;
|
||||
&_text {
|
||||
margin-top: 26rpx;
|
||||
color: #8e9ab0;
|
||||
}
|
||||
|
||||
.search_bar_wrap {
|
||||
height: 34px;
|
||||
padding: 12px 22px;
|
||||
background-color: #fff;
|
||||
}
|
||||
image {
|
||||
width: 237rpx;
|
||||
height: 244rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.u-tabs {
|
||||
background-color: #fff;
|
||||
}
|
||||
.application_list_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
background-color: #f8f9fa;
|
||||
overflow-x: hidden;
|
||||
|
||||
.pane_row {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
transition: all 0.3s ease 0s !important;
|
||||
background-color: #fff;
|
||||
margin-top: 20rpx;
|
||||
.search_bar_wrap {
|
||||
height: 34px;
|
||||
padding: 12px 22px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.pane_content {
|
||||
@include colBox(false);
|
||||
height: 100%;
|
||||
flex: 0 0 100%;
|
||||
.u-tabs {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.pane_title {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
padding: 12rpx 44rpx;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.pane_row {
|
||||
display: flex;
|
||||
//flex: 1;
|
||||
transition: all 0.3s ease 0s !important;
|
||||
background-color: #fff;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.application_list {
|
||||
flex: 1;
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.pane_content {
|
||||
@include colBox(false);
|
||||
width: 100%;
|
||||
//height: 100%;
|
||||
//flex: 0 0 100%;
|
||||
|
||||
.view_all {
|
||||
background-color: #fff;
|
||||
padding: 44rpx 44rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
.pane_title {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
padding: 12rpx 44rpx;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.application_list {
|
||||
flex: 1;
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.view_all {
|
||||
background-color: #fff;
|
||||
padding: 44rpx 44rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,81 +1,81 @@
|
||||
<template>
|
||||
<view class="application_list_container">
|
||||
<custom-nav-bar :title="getTitle" />
|
||||
<view class="application_list_container">
|
||||
<custom-nav-bar :title="getTitle" />
|
||||
|
||||
<u-list class="application_list">
|
||||
<u-list-item
|
||||
v-for="application in getRenderData"
|
||||
:key="getKey(application)"
|
||||
>
|
||||
<application-item :isRecv="isRecv" :application="application" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
</view>
|
||||
<u-list class="application_list">
|
||||
<u-list-item v-for="application in getRenderData" :key="getKey(application)">
|
||||
<application-item :isRecv="isRecv" :application="application" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import ApplicationItem from "../applicationList/ApplicationItem.vue";
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
ApplicationItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isGroupApplication: false,
|
||||
isRecv: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getRenderData() {
|
||||
let getterKey = this.isRecv
|
||||
? "storeRecvFriendApplications"
|
||||
: "storeSentFriendApplications";
|
||||
if (this.isGroupApplication) {
|
||||
getterKey = this.isRecv
|
||||
? "storeRecvGroupApplications"
|
||||
: "storeSentGroupApplications";
|
||||
}
|
||||
return [...this.$store.getters[getterKey]].sort((a, b) =>
|
||||
a.handleResult === 0 ? -1 : 1,
|
||||
);
|
||||
},
|
||||
getKey() {
|
||||
return (application) => {
|
||||
if (this.isGroupApplication) {
|
||||
return this.isRecv
|
||||
? application.userID + application.groupID
|
||||
: application.groupID;
|
||||
}
|
||||
return application[this.isRecv ? "fromUserID" : "toUserID"];
|
||||
};
|
||||
},
|
||||
getTitle() {
|
||||
if (!this.isRecv) {
|
||||
return "我的申请";
|
||||
}
|
||||
return this.isGroupApplication ? "群通知" : "好友请求";
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const { isGroupApplication, isRecv } = options;
|
||||
this.isGroupApplication = JSON.parse(isGroupApplication);
|
||||
this.isRecv = JSON.parse(isRecv);
|
||||
},
|
||||
methods: {},
|
||||
};
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import ApplicationItem from "../applicationList/ApplicationItem.vue";
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
ApplicationItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isGroupApplication: false,
|
||||
isRecv: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getRenderData() {
|
||||
let getterKey = this.isRecv ?
|
||||
"storeRecvFriendApplications" :
|
||||
"storeSentFriendApplications";
|
||||
if (this.isGroupApplication) {
|
||||
getterKey = this.isRecv ?
|
||||
"storeRecvGroupApplications" :
|
||||
"storeSentGroupApplications";
|
||||
}
|
||||
return [...this.$store.getters[getterKey]].sort((a, b) =>
|
||||
a.handleResult === 0 ? -1 : 1,
|
||||
);
|
||||
},
|
||||
getKey() {
|
||||
return (application) => {
|
||||
if (this.isGroupApplication) {
|
||||
return this.isRecv ?
|
||||
application.userID + application.groupID :
|
||||
application.groupID;
|
||||
}
|
||||
return application[this.isRecv ? "fromUserID" : "toUserID"];
|
||||
};
|
||||
},
|
||||
getTitle() {
|
||||
if (!this.isRecv) {
|
||||
return "我的申请";
|
||||
}
|
||||
return this.isGroupApplication ? "群通知" : "好友请求";
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const {
|
||||
isGroupApplication,
|
||||
isRecv
|
||||
} = options;
|
||||
this.isGroupApplication = JSON.parse(isGroupApplication);
|
||||
this.isRecv = JSON.parse(isRecv);
|
||||
},
|
||||
methods: {},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.application_list_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
background-color: #f8f8f8;
|
||||
.application_list_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
background-color: #f8f8f8;
|
||||
|
||||
.application_list {
|
||||
margin-top: 24rpx;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
.application_list {
|
||||
margin-top: 24rpx;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -26,15 +26,15 @@
|
||||
{
|
||||
idx: 0,
|
||||
title: "创建群聊",
|
||||
desc: "创建群聊,全面使用OpenIM",
|
||||
desc: "创建群聊",
|
||||
icon: contact_add_create_group_img,
|
||||
},
|
||||
{
|
||||
idx: 1,
|
||||
title: "添加群聊",
|
||||
desc: "向管理员或团队成员询问ID",
|
||||
icon: rcontact_add_join_group_img,
|
||||
},
|
||||
// {
|
||||
// idx: 1,
|
||||
// title: "添加群聊",
|
||||
// desc: "向管理员或团队成员询问ID",
|
||||
// icon: contact_add_join_group_img,
|
||||
// },
|
||||
],
|
||||
friendActionMenus: [
|
||||
{
|
||||
|
||||
@@ -14,9 +14,27 @@
|
||||
<SearchbarPlace @click="toSearch">搜索</SearchbarPlace>
|
||||
</view>
|
||||
<uni-list class="contact_menus">
|
||||
<uni-list-item title="新的好友" :showBadge="storeUnHandleFriendApplicationNum>0" :badgeText="storeUnHandleFriendApplicationNum+''" badgeType="error" thumbSize="lg" to="/pages/contact/applicationList/index?applicationType=NewFriend" thumb="/static/images/contact_new_friend.png"></uni-list-item>
|
||||
<uni-list-item title="新的群组" thumbSize="lg" to="/pages/contact/applicationList/index?applicationType=NewGroup" thumb="/static/images/contact_new_group.png"></uni-list-item>
|
||||
<uni-list-item title="群聊" thumbSize="lg" to="/pages/contact/groupList/index" thumb="/static/images/contact_my_group.png"></uni-list-item>
|
||||
<uni-list-item title="新的好友"
|
||||
:showBadge="storeUnHandleFriendApplicationNum>0"
|
||||
:badgeText="storeUnHandleFriendApplicationNum+''"
|
||||
badgeType="error"
|
||||
thumbSize="lg"
|
||||
to="/pages/contact/applicationList/index?applicationType=NewFriend"
|
||||
thumb="/static/images/contact_new_friend.png"></uni-list-item>
|
||||
<uni-list-item
|
||||
title="新的群组"
|
||||
:showBadge="storeUnHandleGroupApplicationNum>0"
|
||||
:badgeText="storeUnHandleGroupApplicationNum+''"
|
||||
badgeType="error"
|
||||
thumbSize="lg"
|
||||
to="/pages/contact/applicationList/index?applicationType=NewGroup"
|
||||
thumb="/static/images/contact_new_group.png"></uni-list-item>
|
||||
<uni-list-item
|
||||
v-if="1==2"
|
||||
title="群聊"
|
||||
thumbSize="lg"
|
||||
to="/pages/contact/groupList/index"
|
||||
thumb="/static/images/contact_my_group.png"></uni-list-item>
|
||||
</uni-list>
|
||||
|
||||
<choose-index-list v-if="getIndexData.dataList.length > 0" @itemClick="userClick" :height="`${listHeight}px`"
|
||||
@@ -46,7 +64,11 @@
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["storeFriendList",'storeUnHandleFriendApplicationNum']),
|
||||
...mapGetters([
|
||||
"storeFriendList",
|
||||
'storeUnHandleFriendApplicationNum',
|
||||
'storeUnHandleGroupApplicationNum'
|
||||
]),
|
||||
getIndexData() {
|
||||
return formatChooseData(this.storeFriendList);
|
||||
},
|
||||
@@ -54,9 +76,6 @@
|
||||
mounted() {
|
||||
this.getListHeight();
|
||||
},
|
||||
async onShow() {
|
||||
//await this.getFriendList();
|
||||
},
|
||||
methods: {
|
||||
...mapActions('contact',['getFriendList']),
|
||||
toSearch(){
|
||||
|
||||
+120
-142
@@ -1,157 +1,135 @@
|
||||
<template>
|
||||
<view class="group_list_container">
|
||||
<custom-nav-bar title="我的群组">
|
||||
<view class="group_list_container">
|
||||
<custom-nav-bar title="我的群组"></custom-nav-bar>
|
||||
<view class="search_bar_wrap">
|
||||
<u-search class="search_bar" shape="square" placeholder="搜索" disabled :showAction="false" />
|
||||
</view>
|
||||
|
||||
</custom-nav-bar>
|
||||
<view class="search_bar_wrap">
|
||||
<u-search
|
||||
class="search_bar"
|
||||
shape="square"
|
||||
placeholder="搜索"
|
||||
disabled
|
||||
:showAction="false"
|
||||
/>
|
||||
</view>
|
||||
<u-tabs :scrollable="false" :list="tabList" @click="clickTab"></u-tabs>
|
||||
|
||||
<u-tabs :scrollable="false" :list="tabList" @click="clickTab"></u-tabs>
|
||||
<view class="pane_row" :style="{ transform: `translateX(${isMyCreate ? '0' : '-100%'})` }">
|
||||
<view class="pane_content">
|
||||
<u-list v-if="getMyCreateGroupList.length > 0" class="group_list" :height="`${getListHeight}px`">
|
||||
<u-list-item v-for="group in getMyCreateGroupList" :key="group.groupID">
|
||||
<group-item :groupInfo="group" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<u-empty v-else mode="list" />
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="pane_row"
|
||||
:style="{ transform: `translateX(${isMyCreate ? '0' : '-100%'})` }"
|
||||
>
|
||||
<view class="pane_content">
|
||||
<u-list
|
||||
v-if="getMyCreateGroupList.length > 0"
|
||||
class="group_list"
|
||||
:height="`${getListHeight}px`"
|
||||
>
|
||||
<u-list-item
|
||||
v-for="group in getMyCreateGroupList"
|
||||
:key="group.groupID"
|
||||
>
|
||||
<group-item :groupInfo="group" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<u-empty v-else mode="list" />
|
||||
</view>
|
||||
|
||||
<view class="pane_content">
|
||||
<u-list
|
||||
v-if="getMyJoinedGroupList.length > 0"
|
||||
class="group_list"
|
||||
:height="`${getListHeight}px`"
|
||||
>
|
||||
<u-list-item
|
||||
v-for="group in getMyJoinedGroupList"
|
||||
:key="group.groupID"
|
||||
>
|
||||
<group-item :groupInfo="group" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<u-empty v-else mode="list" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pane_content">
|
||||
<u-list v-if="getMyJoinedGroupList.length > 0" class="group_list" :height="`${getListHeight}px`">
|
||||
<u-list-item v-for="group in getMyJoinedGroupList" :key="group.groupID">
|
||||
<group-item :groupInfo="group" />
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<u-empty v-else mode="list" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import GroupItem from "./GroupItem.vue";
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
GroupItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyword: "",
|
||||
tabList: [
|
||||
{
|
||||
name: "我创建的",
|
||||
},
|
||||
{
|
||||
name: "我加入的",
|
||||
},
|
||||
],
|
||||
isMyCreate: true,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["storeGroupList", "storeCurrentUserID"]),
|
||||
getMyCreateGroupList() {
|
||||
return this.storeGroupList.filter(
|
||||
(group) => group.ownerUserID === this.storeCurrentUserID,
|
||||
);
|
||||
},
|
||||
getListHeight() {
|
||||
const statusBar = uni.getWindowInfo().statusBarHeight;
|
||||
const searchBar = 58;
|
||||
const tabAndNavBar = 44 * 2;
|
||||
const titleBar = 32;
|
||||
return (
|
||||
uni.getWindowInfo().safeArea.height -
|
||||
statusBar -
|
||||
searchBar -
|
||||
tabAndNavBar -
|
||||
titleBar
|
||||
);
|
||||
},
|
||||
getMyJoinedGroupList() {
|
||||
// console.log(this.storeGroupList.filter(group => group.ownerUserID !== this.storeCurrentUserID));
|
||||
return this.storeGroupList.filter(
|
||||
(group) => group.ownerUserID !== this.storeCurrentUserID,
|
||||
);
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
clickTab({ index }) {
|
||||
this.isMyCreate = index === 0;
|
||||
},
|
||||
toCreateGroup() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/createGroup/index`,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import GroupItem from "./GroupItem.vue";
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
GroupItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyword: "",
|
||||
tabList: [{
|
||||
name: "我创建的",
|
||||
},
|
||||
{
|
||||
name: "我加入的",
|
||||
},
|
||||
],
|
||||
isMyCreate: true,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["storeGroupList", "storeCurrentUserID"]),
|
||||
getMyCreateGroupList() {
|
||||
return this.storeGroupList.filter(
|
||||
(group) => group.ownerUserID === this.storeCurrentUserID,
|
||||
);
|
||||
},
|
||||
getListHeight() {
|
||||
const statusBar = uni.getWindowInfo().statusBarHeight;
|
||||
const searchBar = 58;
|
||||
const tabAndNavBar = 44 * 2;
|
||||
const titleBar = 32;
|
||||
return (
|
||||
uni.getWindowInfo().safeArea.height -
|
||||
statusBar -
|
||||
searchBar -
|
||||
tabAndNavBar -
|
||||
titleBar
|
||||
);
|
||||
},
|
||||
getMyJoinedGroupList() {
|
||||
//console.log(this.storeGroupList);
|
||||
return this.storeGroupList.filter(
|
||||
(group) => group.ownerUserID !== this.storeCurrentUserID,
|
||||
);
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
clickTab({
|
||||
index
|
||||
}) {
|
||||
this.isMyCreate = index === 0;
|
||||
},
|
||||
toCreateGroup() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/createGroup/index`,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.group_list_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
.group_list_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
|
||||
.nav_right_action {
|
||||
padding-right: 44rpx;
|
||||
}
|
||||
.nav_right_action {
|
||||
padding-right: 44rpx;
|
||||
}
|
||||
|
||||
.search_bar_wrap {
|
||||
height: 34px;
|
||||
padding: 12px 22px;
|
||||
}
|
||||
.search_bar_wrap {
|
||||
height: 34px;
|
||||
padding: 12px 22px;
|
||||
}
|
||||
|
||||
.pane_row {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
transition: all 0.3s ease 0s !important;
|
||||
border-top: 2rpx solid #e8eaef;
|
||||
// overflow-x: hidden;
|
||||
.pane_row {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
transition: all 0.3s ease 0s !important;
|
||||
border-top: 2rpx solid #e8eaef;
|
||||
// overflow-x: hidden;
|
||||
|
||||
.pane_content {
|
||||
@include colBox(false);
|
||||
height: 100%;
|
||||
flex: 0 0 100%;
|
||||
.pane_content {
|
||||
@include colBox(false);
|
||||
height: 100%;
|
||||
flex: 0 0 100%;
|
||||
|
||||
.pane_title {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
padding: 6px 22px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
.pane_title {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
padding: 6px 22px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,193 +1,284 @@
|
||||
<template>
|
||||
<view class="editor_wrap">
|
||||
<editor
|
||||
:placeholder="placeholder"
|
||||
id="editor2"
|
||||
@ready="editorReady"
|
||||
@focus="editorFocus"
|
||||
@blur="editorBlur"
|
||||
@input="editorInput" />
|
||||
</view>
|
||||
<div id="editor-container" :call="option" :change:call="editorModule.call"><!-- 编辑器 --></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { forIn } from "lodash";
|
||||
import {html2Text} from "@/util/common";
|
||||
export default {
|
||||
props: {
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editorCtx: null,
|
||||
lastStr: "",
|
||||
isInsertingEmoji: false, // 标记是否正在插入表情
|
||||
hasFocus: false, // 记录编辑器是否有焦点
|
||||
};
|
||||
timer:null,
|
||||
option:null,
|
||||
events:[],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editorReady() {
|
||||
uni
|
||||
.createSelectorQuery()
|
||||
.select("#editor2")
|
||||
.context((res) => {
|
||||
//this.$emit("ready", res);
|
||||
this.editorCtx = res.context;
|
||||
})
|
||||
.exec();
|
||||
insertText(text,successFn,errorFn){
|
||||
this.addEvent('insertText',text);
|
||||
},
|
||||
editorFocus() {
|
||||
this.hasFocus = true;
|
||||
// 如果正在插入表情,不触发 focus 事件,并立即隐藏键盘
|
||||
if (this.isInsertingEmoji) {
|
||||
// #ifdef APP-PLUS || H5
|
||||
uni.hideKeyboard();
|
||||
// #endif
|
||||
return;
|
||||
}
|
||||
this.$emit("focus");
|
||||
insertImgEmoji(src,successFn,errorFn){
|
||||
this.addEvent('insertImgEmoji',src);
|
||||
},
|
||||
editorBlur() {
|
||||
this.hasFocus = false;
|
||||
this.$emit("blur");
|
||||
insertMention(username,userid){
|
||||
this.addEvent('insertMention',{
|
||||
username,
|
||||
userid
|
||||
});
|
||||
},
|
||||
clear(){
|
||||
this.editorCtx.clear()
|
||||
this.addEvent('clear');
|
||||
},
|
||||
insertText(text,successFn,errFn){
|
||||
// 标记正在插入表情,阻止 focus 事件触发
|
||||
this.isInsertingEmoji = true;
|
||||
|
||||
// 先隐藏键盘,避免插入时键盘弹出
|
||||
// #ifdef APP-PLUS || H5
|
||||
uni.hideKeyboard();
|
||||
// #endif
|
||||
|
||||
// 如果编辑器当前有焦点,先让它失焦(通过点击外部区域)
|
||||
// 但这种方式可能不太可靠,所以我们主要依赖 isInsertingEmoji 标志
|
||||
|
||||
// 使用 insertText 插入文本(这是最可靠的方法)
|
||||
// 虽然会触发焦点,但我们已经通过 isInsertingEmoji 标志阻止了 focus 事件
|
||||
this.editorCtx.insertText({
|
||||
text: text,
|
||||
success: (res) => {
|
||||
successFn && successFn.call(this, [res]);
|
||||
console.log("插入文字成功");
|
||||
|
||||
// 插入后立即隐藏键盘,防止键盘弹出
|
||||
// #ifdef APP-PLUS || H5
|
||||
// 使用多个延迟确保键盘被隐藏
|
||||
setTimeout(() => {
|
||||
uni.hideKeyboard();
|
||||
}, 10);
|
||||
setTimeout(() => {
|
||||
uni.hideKeyboard();
|
||||
}, 50);
|
||||
setTimeout(() => {
|
||||
uni.hideKeyboard();
|
||||
}, 100);
|
||||
// #endif
|
||||
|
||||
// 延迟重置标志,确保 focus 事件被完全忽略
|
||||
setTimeout(() => {
|
||||
this.isInsertingEmoji = false;
|
||||
}, 300);
|
||||
},
|
||||
fail: (err) => {
|
||||
errFn && errFn.call(this, [err]);
|
||||
console.log("插入文字失败", err);
|
||||
this.isInsertingEmoji = false;
|
||||
}
|
||||
});
|
||||
blur(){
|
||||
this.addEvent('blur');
|
||||
},
|
||||
delete(){
|
||||
this.editorCtx.getContents({
|
||||
success({html,text,delta}){
|
||||
console.log(html,text,delta);
|
||||
}
|
||||
})
|
||||
return ;
|
||||
//setContents(OBJECT)
|
||||
let emojiStr = this.editorCtx.getContents();
|
||||
let emojiArr = [];
|
||||
emojiStr = emojiStr.replace(/\[([^(\]|\[)]*)\]/g, function(item, index) {
|
||||
emojiArr.unshift(item);
|
||||
});
|
||||
let sendStr ="";
|
||||
if (emojiArr.length > 0) {
|
||||
if (this.sendStr.endsWith(emojiArr[0])) {
|
||||
this.sendStr = this.sendStr.replace(emojiArr[0], "");
|
||||
focus(){
|
||||
this.addEvent('focus');
|
||||
},
|
||||
setHtml(html){
|
||||
this.addEvent('setHtml',html);
|
||||
},
|
||||
getText(){
|
||||
this.addEvent('getText');
|
||||
},
|
||||
getHtml(){
|
||||
console.log(this);
|
||||
return 1;
|
||||
this.addEvent('getHtml');
|
||||
},
|
||||
getSelectionPosition(){
|
||||
this.addEvent('getSelectionPosition');
|
||||
},
|
||||
getParentNode(){
|
||||
this.addEvent('getParentNode');
|
||||
},
|
||||
// 调用
|
||||
call() {
|
||||
if (this.timer) return;
|
||||
// 消费事件队列(生产者/消费者机制)
|
||||
this.timer = setInterval(() => {
|
||||
if (this.events.length) {
|
||||
this.option = this.events.shift();
|
||||
console.log(this.option);
|
||||
} else {
|
||||
this.sendStr = this.sendStr.slice(0, this.sendStr.length - 1);
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
} else {
|
||||
this.sendStr = this.sendStr.slice(0, this.sendStr.length - 1);
|
||||
}, 10);
|
||||
},
|
||||
// 添加事件队列
|
||||
addEvent(name, data) {
|
||||
// #ifdef APP-PLUS
|
||||
// tips:由于采用监听option改变来调用方法,
|
||||
// 如果连续变化两次option,渲染层只会则监听到最后一次
|
||||
// 导致调用丢失,所以采用事件队列形式解决,稍微延时10ms
|
||||
// 等待渲染进程监听到option变化,在进行更改option
|
||||
// 从性能上,几乎无感可以放心使用
|
||||
const option = {
|
||||
id: this.genId(),
|
||||
name: `_${name}`,
|
||||
data
|
||||
};
|
||||
this.events.push(option);
|
||||
this.call();
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
this[`_${name}`] && this[`_${name}`](data);
|
||||
// #endif
|
||||
},
|
||||
genId() {
|
||||
let result = '';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
const charactersLength = characters.length;
|
||||
for (let i = 0; i < 30; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
this.editorCtx.setContents({
|
||||
html:sendStr
|
||||
})
|
||||
console.log('delete')
|
||||
},
|
||||
editorInput(e) {
|
||||
let str = e.detail.html;
|
||||
const oldArr = (this.lastStr ?? '').split("");
|
||||
let contentStr = str;
|
||||
oldArr.forEach((str) => {
|
||||
contentStr = contentStr.replace(str, "");
|
||||
});
|
||||
contentStr = html2Text(contentStr);
|
||||
this.$emit("input", e);
|
||||
this.lastStr = e.detail.html;
|
||||
return Date.now() + result;
|
||||
},
|
||||
// 开始拖拽地图
|
||||
UserEvent(data) {
|
||||
//console.log(data);
|
||||
this.$emit('onUserEvent',data);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script module="editorModule" lang="renderjs">
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
_editorIns:null
|
||||
}
|
||||
},
|
||||
};
|
||||
mounted() {
|
||||
this._initEditor();
|
||||
},
|
||||
methods: {
|
||||
_initEditor() {
|
||||
if (typeof window.wangEditor === 'function') {
|
||||
this._initialize();
|
||||
} else {
|
||||
const script = document.createElement('script');
|
||||
script.onload = this._initialize;
|
||||
script.src = "static/wangeditor/index.js";
|
||||
document.head.appendChild(script);
|
||||
|
||||
const link = document.createElement('link');
|
||||
link.href = "static/wangeditor/style.css";
|
||||
link.rel = "stylesheet";
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
},
|
||||
// 创建地图
|
||||
_initialize() {
|
||||
const _this = this;
|
||||
// 创建地图实例
|
||||
const {createEditor} = window.wangEditor
|
||||
|
||||
const editor = createEditor({
|
||||
selector: '#editor-container',
|
||||
html: '',
|
||||
config: {
|
||||
placeholder: '',
|
||||
maxLength:100,
|
||||
hoverbarKeys:{
|
||||
divider: {menuKeys: [],},
|
||||
link: {menuKeys: [],},
|
||||
image: {menuKeys: [],},
|
||||
pre: {menuKeys: [],},
|
||||
table: {menuKeys: [],},
|
||||
text: {menuKeys: [],},
|
||||
video: {menuKeys: [],},
|
||||
},
|
||||
onCreated(){
|
||||
_this.$ownerInstance.callMethod('UserEvent',{
|
||||
type:'ready'
|
||||
});
|
||||
},
|
||||
//onDestroyed(){},
|
||||
onFocus(){
|
||||
_this.$ownerInstance.callMethod('UserEvent',{
|
||||
type:'focus'
|
||||
});
|
||||
},
|
||||
onBlur(){
|
||||
_this.$ownerInstance.callMethod('UserEvent',{
|
||||
type:'blur'
|
||||
});
|
||||
},
|
||||
//onDestroyed(){},
|
||||
onChange(editor) {
|
||||
const html = editor.getHtml()
|
||||
const text = editor.getText()
|
||||
//console.log('editor content', html)
|
||||
// 也可以同步到 <textarea>
|
||||
_this.$ownerInstance.callMethod('UserEvent',{
|
||||
type:'onChange',
|
||||
html,
|
||||
text,
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
editor.on('atevent',()=>{
|
||||
_this.$ownerInstance.callMethod('UserEvent',{
|
||||
type:'atevent'
|
||||
});
|
||||
})
|
||||
this._editorIns = editor;
|
||||
console.log(editor.insertText);
|
||||
this._editorIns.insertText("text");
|
||||
},
|
||||
|
||||
_insertText(text){
|
||||
console.log('_insertText',text);
|
||||
this._editorIns.insertText(text);
|
||||
},
|
||||
_insertNode(node){
|
||||
this._editorIns.insertNode(node);
|
||||
},
|
||||
_insertImgEmoji(src){
|
||||
this._insertNode({
|
||||
type: 'image',
|
||||
style:{width:'30px',height:'30px'},
|
||||
src: src,
|
||||
children: [{text: ''}],
|
||||
});
|
||||
},
|
||||
_insertMention(data){
|
||||
this._insertNode({
|
||||
type: 'mention',
|
||||
username: data.username,
|
||||
userid: data.userid,
|
||||
children: [{
|
||||
text: ''
|
||||
}],
|
||||
});
|
||||
},
|
||||
_clear(){
|
||||
this._editorIns.clear();
|
||||
},
|
||||
_delete(){
|
||||
this._editorIns.deleteBackward();
|
||||
},
|
||||
_blur(){
|
||||
this._editorIns.blur();
|
||||
},
|
||||
_focus(){
|
||||
this._editorIns.focus();
|
||||
},
|
||||
_setHtml(html){
|
||||
this._editorIns.setHtml(html);
|
||||
},
|
||||
_getText(){
|
||||
return this._editorIns.getText();
|
||||
},
|
||||
_getHtml(){
|
||||
return this._editorIns.getHtml();
|
||||
},
|
||||
_getSelectionPosition(){
|
||||
return this._editorIns.getSelectionPosition();
|
||||
},
|
||||
_getParentNode(){
|
||||
return this._editorIns.getParentNode();
|
||||
},
|
||||
// 通过监听call来调用渲染层方法
|
||||
call(newValue, oldValue, ownerInstance, instance) {
|
||||
if(!newValue){
|
||||
return false;
|
||||
}
|
||||
if (this[newValue.name] && typeof this[newValue.name] === "function") {
|
||||
this[newValue.name](newValue.data);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.editor_wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#editor2 {
|
||||
background-color: #fff;
|
||||
min-height: 30px;
|
||||
max-height: 120px;
|
||||
height: auto;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
::v-deep.ql-editor {
|
||||
img {
|
||||
vertical-align: sub !important;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.canvas_container {
|
||||
position: fixed;
|
||||
bottom: -99px;
|
||||
z-index: -100;
|
||||
|
||||
&_name {
|
||||
max-width: 480rpx;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#atCanvas {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.convas_container_name {
|
||||
font-size: 16px !important;
|
||||
.custom_editor {
|
||||
::v-deep.w-e-text-container{
|
||||
background: transparent;
|
||||
|
||||
[data-slate-editor]{
|
||||
padding: 0;
|
||||
}
|
||||
p,
|
||||
span{
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
}
|
||||
p{
|
||||
white-space: pre-wrap; /* 保留空格 */
|
||||
margin: 0;
|
||||
}
|
||||
img{
|
||||
}
|
||||
span{
|
||||
}
|
||||
span[data-w-e-type="mention"]{
|
||||
background-color: #ccc;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -150,7 +150,7 @@
|
||||
};
|
||||
if (this.voiceCanSend) {
|
||||
//console.log("=====上传语音文件,并发送语音信息====");
|
||||
this.$emit('RecodeEvent',{type:"sendVoiceMessage",audio:voiceFile})
|
||||
this.$emit('RecodEvent',{type:"sendVoiceMessage",audio:voiceFile})
|
||||
return;
|
||||
} else {
|
||||
console.log("=====已经取消发送语音信息====")
|
||||
|
||||
@@ -59,21 +59,22 @@
|
||||
this.textValue = e.detail.value;
|
||||
// 更新光标位置
|
||||
this.cursorPos = e.detail.cursor || this.textValue.length;
|
||||
this.$emit("input", {
|
||||
detail: {
|
||||
value: this.textValue,
|
||||
text: this.textValue,
|
||||
html: this.textValue // 简单编辑器,HTML 就是文本
|
||||
}
|
||||
this.$emit("onUserEvent", {
|
||||
"type":"input",
|
||||
text: this.textValue,
|
||||
html: this.textValue // 简单编辑器,HTML 就是文本
|
||||
});
|
||||
},
|
||||
onFocus(e) {
|
||||
this.$emit("focus", e);
|
||||
this.$emit("onUserEvent",{
|
||||
type:"focus",
|
||||
e
|
||||
});
|
||||
},
|
||||
onBlur(e) {
|
||||
// 保存光标位置
|
||||
this.cursorPos = e.detail.cursor || this.textValue.length;
|
||||
this.$emit("blur", e);
|
||||
this.$emit("onUserEvent",{type:"blur", e});
|
||||
},
|
||||
// 插入文本(表情或普通文本)
|
||||
insertText(text, successFn, errFn) {
|
||||
@@ -93,12 +94,10 @@
|
||||
this.cursorPos = newCursorPos;
|
||||
|
||||
// 触发 input 事件
|
||||
this.$emit("input", {
|
||||
detail: {
|
||||
value: newText,
|
||||
text: newText,
|
||||
html: newText
|
||||
}
|
||||
this.$emit("onUserEvent", {
|
||||
type:"input",
|
||||
html: newText,
|
||||
text: newText,
|
||||
});
|
||||
|
||||
// 使用 $nextTick 确保 DOM 更新后再设置光标
|
||||
@@ -139,12 +138,10 @@
|
||||
clear() {
|
||||
this.textValue = "";
|
||||
this.cursorPos = 0;
|
||||
this.$emit("input", {
|
||||
detail: {
|
||||
value: "",
|
||||
text: "",
|
||||
html: ""
|
||||
}
|
||||
this.$emit("onUserEvent", {
|
||||
type:"input",
|
||||
text: "",
|
||||
html: ""
|
||||
});
|
||||
},
|
||||
// 删除(退格)
|
||||
@@ -180,12 +177,10 @@
|
||||
this.cursorPos = currentPos - deletedLength;
|
||||
|
||||
// 触发 input 事件
|
||||
this.$emit("input", {
|
||||
detail: {
|
||||
value: this.textValue,
|
||||
text: this.textValue,
|
||||
html: this.textValue
|
||||
}
|
||||
this.$emit("onUserEvent", {
|
||||
type:"input",
|
||||
text: this.textValue,
|
||||
html: this.textValue
|
||||
});
|
||||
|
||||
// 使用 $nextTick 确保 DOM 更新后再设置光标
|
||||
@@ -220,12 +215,12 @@
|
||||
|
||||
.simple_editor_textarea {
|
||||
width: 100%;
|
||||
min-height: 30px;
|
||||
min-height: 60rpx;
|
||||
max-height: 120px;
|
||||
line-height: 60rpx;
|
||||
background-color: #fff;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
padding: 4px;
|
||||
font-size: 30rpx;
|
||||
padding: 0 6rpx;
|
||||
word-break: break-all;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-if="isMute">
|
||||
<view class="forbidden_footer">
|
||||
<view class="mute_tip" v-if="storeCurrentGroup.status === 3">全群禁言中</view>
|
||||
<view class="mute_tip" v-else>您被禁言至{{date(storeCurrentMemberInGroup.muteEndTime)}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else-if="!isSingle && !storeCurrentMemberInGroup.userID">
|
||||
<view class="forbidden_footer">
|
||||
<view class="mute_tip">您不是群成员</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="chat_footer">
|
||||
<!-- 语音信息 -->
|
||||
<image class="action_btn" v-show="inputType == 'keyboard'" @click.prevent="swtichInputType('record')" mode="heightFix" src="@/static/images/chating_footer_audio.png" alt="" srcset="" />
|
||||
<image class="action_btn" v-show="inputType == 'record'" @click.prevent="swtichInputType('keyboard')" mode="heightFix" src="@/static/images/chating_footer_audio_recording.png" alt="" srcset="" />
|
||||
<view class="input_content">
|
||||
<Recoder v-if="inputType == 'record'" @RecodeEvent="onRecodeEvent"></Recoder>
|
||||
<Recoder v-if="inputType == 'record'" @RecodEvent="onRecodEvent"></Recoder>
|
||||
<SimpleEditor
|
||||
v-if="inputType == 'keyboard'"
|
||||
class="custom_editor"
|
||||
ref="customEditor"
|
||||
:value="inputHtml"
|
||||
@focus="editorFocus"
|
||||
@blur="editorBlur"
|
||||
@input="editorInput" />
|
||||
@onUserEvent="onEditorEvent"
|
||||
:value="inputHtml"/>
|
||||
</view>
|
||||
|
||||
<view class="footer_action_area" v-show="inputType == 'keyboard'">
|
||||
@@ -45,18 +54,22 @@
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters,mapActions} from "vuex";
|
||||
import {getPurePath,html2Text,getVideoCover,getVideoInfo} from "@/util/common";
|
||||
import {offlinePushInfo} from "@/util/imCommon";
|
||||
import {offlinePushInfo,date} from "@/util/imCommon";
|
||||
import {ChatingFooterActionTypes,UpdateMessageTypes,} from "@/constant";
|
||||
import IMSDK, {IMMethods,MessageStatus,MessageType,} from "openim-uniapp-polyfill";
|
||||
import IMSDK, {IMMethods,MessageStatus,MessageType,SessionType} from "openim-uniapp-polyfill";
|
||||
import CustomEditor from "./CustomEditor";
|
||||
import SimpleEditor from "./SimpleEditor";
|
||||
import ChatingActionBar from "./ChatingActionBar";
|
||||
import Recoder from "./Recoder";
|
||||
|
||||
import {upload} from "@/api/login.js"
|
||||
import IM from "@/util/im.js";
|
||||
import permision from "@/js_sdk/wa-permission/permission.js"
|
||||
const needClearTypes = [MessageType.TextMessage];
|
||||
|
||||
const rtcChoose = [
|
||||
@@ -74,7 +87,7 @@
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SimpleEditor,
|
||||
CustomEditor,SimpleEditor,
|
||||
ChatingActionBar,
|
||||
Recoder,
|
||||
},
|
||||
@@ -87,7 +100,7 @@
|
||||
voiceIconText : "正在录音...",
|
||||
inputType:"keyboard",
|
||||
isEmoji:false,
|
||||
inputHtml: '<span>@cansnow</span><span>@baidu</span><span>@jingds</span>',
|
||||
inputHtml: '',
|
||||
actionBarVisible: false,
|
||||
isInputFocus: false,
|
||||
actionSheetMenu: [],
|
||||
@@ -102,10 +115,32 @@
|
||||
"storeCurrentConversation",
|
||||
"storeCurrentGroup",
|
||||
"storeBlackList",
|
||||
"storeCurrentUserID",
|
||||
"storeCurrentMemberInGroup"
|
||||
]),
|
||||
isSingle() {
|
||||
return (
|
||||
this.storeCurrentConversation.conversationType === SessionType.Single
|
||||
);
|
||||
},
|
||||
hasContent() {
|
||||
return html2Text(this.inputHtml) !== "";
|
||||
},
|
||||
isAdminOrOwner(){
|
||||
return this.storeCurrentMemberInGroup && this.storeCurrentMemberInGroup?.roleLevel>20;
|
||||
},
|
||||
isMute(){
|
||||
if(this.isSingle){
|
||||
return false;
|
||||
}
|
||||
if(this.storeCurrentGroup && this.storeCurrentGroup.status === 3 && !this.isAdminOrOwner){
|
||||
return true;
|
||||
}
|
||||
if (this.storeCurrentMemberInGroup && this.storeCurrentMemberInGroup?.muteEndTime>0){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
footerOutsideFlag(newVal) {
|
||||
@@ -113,6 +148,8 @@
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
//console.log(this.storeCurrentGroup)
|
||||
//console.log(this.storeCurrentMemberInGroup)
|
||||
this.setKeyboardListener();
|
||||
},
|
||||
beforeDestroy() {
|
||||
@@ -120,6 +157,7 @@
|
||||
},
|
||||
methods: {
|
||||
...mapActions("message", ["pushNewMessage", "updateOneMessage"]),
|
||||
date,
|
||||
async createTextMessage() {
|
||||
let message = "";
|
||||
const text = html2Text(this.inputHtml);
|
||||
@@ -128,7 +166,7 @@
|
||||
IMSDK.uuid(),
|
||||
text
|
||||
);
|
||||
console.log(message);
|
||||
//console.log(message);
|
||||
return message;
|
||||
},
|
||||
async sendTextMessage() {
|
||||
@@ -141,22 +179,26 @@
|
||||
if (needClearTypes.includes(message.contentType)) {
|
||||
this.$refs.customEditor.clear();
|
||||
}
|
||||
let method = IMMethods.SendMessage;
|
||||
// if([MessageType.PictureMessage,MessageType.VoiceMessage,MessageType.VideoMessage,MessageType.FileMessage].includes(message.contentType)){
|
||||
// method = IMMethods.SendMessageNotOss;
|
||||
// }
|
||||
this.$emit("scrollToBottom");
|
||||
IMSDK.asyncApi(IMMethods.SendMessage, IMSDK.uuid(), {
|
||||
IMSDK.asyncApi(method, IMSDK.uuid(), {
|
||||
recvID: user_id,
|
||||
groupID: group_id,
|
||||
message,
|
||||
offlinePushInfo,
|
||||
})
|
||||
.then(({data}) => {
|
||||
console.log(data);
|
||||
//console.log(data);
|
||||
this.updateOneMessage({
|
||||
message: data,
|
||||
isSuccess: true,
|
||||
});
|
||||
})
|
||||
.catch(({data,errCode,errMsg}) => {
|
||||
console.log(errCode,errMsg);
|
||||
console.log(errCode,errMsg,data);
|
||||
uni.$u.toast(errMsg);
|
||||
this.updateOneMessage({
|
||||
message: data,
|
||||
@@ -175,7 +217,6 @@
|
||||
});
|
||||
},
|
||||
recordAudioMsg(){
|
||||
|
||||
if (uni.getSystemInfoSync().platform == "android") {
|
||||
permission.requestAndroid("android.permission.RECORD_AUDIO"); //Android请求录音权限
|
||||
} else {
|
||||
@@ -212,17 +253,7 @@
|
||||
this.isEmoji = false;
|
||||
}
|
||||
},
|
||||
editorFocus() {
|
||||
this.isInputFocus = true;
|
||||
this.$emit("scrollToBottom");
|
||||
},
|
||||
editorBlur() {
|
||||
this.isInputFocus = false;
|
||||
},
|
||||
editorInput(e) {
|
||||
// SimpleEditor 返回的是纯文本,直接使用
|
||||
this.inputHtml = e.detail.value || e.detail.text || e.detail.html || "";
|
||||
},
|
||||
|
||||
async sendLocationMessage(res){
|
||||
console.log(res);
|
||||
const _this = this;
|
||||
@@ -240,46 +271,22 @@
|
||||
},
|
||||
async sendVoiceMessage(audio){
|
||||
const _this = this;
|
||||
const message = await IMSDK.asyncApi(
|
||||
IMMethods.CreateSoundMessageFromFullPath,
|
||||
IMSDK.uuid(),
|
||||
{
|
||||
soundPath:getPurePath(audio.tempFilePath),
|
||||
duration:audio.contentDuration
|
||||
}
|
||||
);
|
||||
const message = await IM.createVoiceMessage(audio.tempFilePath,audio.contentDuration);
|
||||
_this.sendMessage(message,_this.storeCurrentConversation.userID,_this.storeCurrentConversation.groupID);
|
||||
|
||||
},
|
||||
// from comp
|
||||
sendMediaMesage(paths) {
|
||||
const _this = this;
|
||||
paths.forEach(async (item) => {
|
||||
console.log(item);
|
||||
try {
|
||||
let message = null;
|
||||
if(item.search('.mp4')>0){
|
||||
const realVideoPath = await getPurePath(item);
|
||||
console.log('处理后的可用路径', realVideoPath);
|
||||
const info = await getVideoInfo(realVideoPath);
|
||||
const cover = await getVideoCover(item);
|
||||
const videoParams = {
|
||||
videoPath: realVideoPath,
|
||||
videoType: "mp4",
|
||||
duration: info.duration,
|
||||
snapshotPath: getPurePath(cover),
|
||||
};
|
||||
console.log('videoParams', videoParams);
|
||||
message = await IMSDK.asyncApi(
|
||||
IMMethods.CreateVideoMessageFromFullPath,
|
||||
IMSDK.uuid(),
|
||||
videoParams
|
||||
);
|
||||
console.log('1');
|
||||
message = await IM.createVideoMessage(item);
|
||||
}else{
|
||||
message = await IMSDK.asyncApi(
|
||||
IMMethods.CreateImageMessageFromFullPath,
|
||||
IMSDK.uuid(),
|
||||
getPurePath(item)
|
||||
);
|
||||
console.log('2');
|
||||
message = await IM.createImageMessage(item);
|
||||
}
|
||||
console.log(message);
|
||||
if(message){
|
||||
@@ -318,8 +325,45 @@
|
||||
disposeKeyboardListener() {
|
||||
uni.offKeyboardHeightChange(this.keyboardChangeHander);
|
||||
},
|
||||
|
||||
onRecodeEvent(e){
|
||||
onEditorEvent(e){
|
||||
const _this = this;
|
||||
if(e.type=="atevent" && this.storeCurrentConversation.groupID){
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/contactChoose/chooseGroupMember?groupID=${this.storeCurrentConversation.groupID}&checkedUserIDList=[]&hideUserIDList=[${this.storeCurrentUserID}]&allowType=User`,
|
||||
events: {
|
||||
onSelectedConfirm(userList) {
|
||||
userList.forEach((user)=>{
|
||||
_this.$refs.customEditor.insertMention(user.remark || user.nickname || user.showName,user.userID);
|
||||
_this.$refs.customEditor.focus();
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
return ;
|
||||
}
|
||||
if(e.type=="ready"){
|
||||
return ;
|
||||
}
|
||||
if(e.type=="focus"){
|
||||
this.isInputFocus = true;
|
||||
this.$emit("scrollToBottom");
|
||||
return ;
|
||||
}
|
||||
if(e.type=="blur"){
|
||||
this.isInputFocus = false;
|
||||
return ;
|
||||
}
|
||||
if(e.type=="onChange"){
|
||||
return ;
|
||||
}
|
||||
if(e.type=="input"){
|
||||
// SimpleEditor 返回的是纯文本,直接使用
|
||||
this.inputHtml = e.html || e.text || "";
|
||||
return ;
|
||||
}
|
||||
console.log(e);
|
||||
},
|
||||
onRecodEvent(e){
|
||||
const _this = this;
|
||||
switch(e.type){
|
||||
case "voiceIconTextChange":
|
||||
@@ -335,6 +379,30 @@
|
||||
break;
|
||||
}
|
||||
},
|
||||
pickMedia(){
|
||||
const _this = this;
|
||||
plus.gallery.pick(({files})=>{
|
||||
console.log(files);
|
||||
_this.sendMediaMesage(files);
|
||||
}, (error )=>{
|
||||
console.log(error);
|
||||
}, {
|
||||
animation:true,
|
||||
confirmText:"确定",
|
||||
//crop:null,
|
||||
editable:true,
|
||||
filename:"_doc/",
|
||||
filter:"none",//image,none,video
|
||||
maximum:9,
|
||||
multiple:true,
|
||||
permissionAlert:true,
|
||||
//popover:{},
|
||||
//selected:[""],
|
||||
onmaxed(){
|
||||
console.log("超出最大选择数");
|
||||
},
|
||||
});
|
||||
},
|
||||
onUserEvent(e){
|
||||
const _this = this;
|
||||
switch(e.type){
|
||||
@@ -366,13 +434,13 @@
|
||||
|
||||
// 直接插入文本,不等待 nextTick,减少延迟
|
||||
this.$refs.customEditor.insertText(e.emoji,() =>{
|
||||
console.log("插入文字成功");
|
||||
//console.log("插入文字成功");
|
||||
// 延迟重置标志,确保其他事件不会隐藏表情栏
|
||||
setTimeout(() => {
|
||||
this.isInsertingEmoji = false;
|
||||
}, 300);
|
||||
},(err) => {
|
||||
console.log("插入文字失败", err);
|
||||
//console.log("插入文字失败", err);
|
||||
this.isInsertingEmoji = false;
|
||||
});
|
||||
break;
|
||||
@@ -389,27 +457,8 @@
|
||||
return ;
|
||||
}
|
||||
if(e.source == "album"){
|
||||
plus.gallery.pick(({files})=>{
|
||||
_this.sendMediaMesage(files);
|
||||
}, (error )=>{
|
||||
reject(error);
|
||||
}, {
|
||||
animation:true,
|
||||
confirmText:"确定",
|
||||
//crop:null,
|
||||
editable:true,
|
||||
filename:"_doc/",
|
||||
filter:"none",
|
||||
maximum:9,
|
||||
multiple:true,
|
||||
permissionAlert:true,
|
||||
//popover:{},
|
||||
//selected:[""],
|
||||
onmaxed(){
|
||||
console.log("超出最大选择数");
|
||||
},
|
||||
});
|
||||
}
|
||||
_this.pickMedia();
|
||||
}
|
||||
break;
|
||||
case "prepend_call_message":
|
||||
this.actionSheetMenu = [...rtcChoose];
|
||||
@@ -450,11 +499,10 @@
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.custom_editor {
|
||||
img {
|
||||
vertical-align: sub;
|
||||
}
|
||||
min-height: 60rpx;
|
||||
max-height: 240rpx;
|
||||
}
|
||||
|
||||
|
||||
.forbidden_footer {
|
||||
width: 100%;
|
||||
height: 112rpx;
|
||||
@@ -465,7 +513,7 @@
|
||||
align-items: center;
|
||||
background: #f0f2f6;
|
||||
}
|
||||
|
||||
|
||||
.chat_footer {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
@@ -473,16 +521,17 @@
|
||||
background: #f6f6f6;
|
||||
// height: 50px;
|
||||
max-height: 120px;
|
||||
padding: 0 20rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
gap: 20rpx;
|
||||
|
||||
.mute_tip{
|
||||
|
||||
}
|
||||
|
||||
.input_content {
|
||||
flex: 1;
|
||||
min-height: 80rpx;
|
||||
max-height: 240rpx;
|
||||
border-radius: 8rpx;
|
||||
position: relative;
|
||||
|
||||
|
||||
.record_btn {
|
||||
// background-color: #3c9cff;
|
||||
background: #fff;
|
||||
@@ -491,37 +540,21 @@
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.quote_message {
|
||||
@include vCenterBox();
|
||||
justify-content: space-between;
|
||||
margin-top: 12rpx;
|
||||
padding: 8rpx;
|
||||
// padding-top: 20rpx;
|
||||
border-radius: 6rpx;
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
|
||||
.content {
|
||||
::v-deep uni-view {
|
||||
@include ellipsisWithLine(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action_btn{
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
margin: 24rpx auto;
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
.footer_action_area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
|
||||
.send_btn {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
background-color: $uni-color-success;
|
||||
padding: 0 8px;
|
||||
border-radius: 4px;
|
||||
|
||||
@@ -23,12 +23,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex";
|
||||
import {
|
||||
SessionType
|
||||
} from "openim-uniapp-polyfill";
|
||||
import {mapGetters} from "vuex";
|
||||
import {SessionType} from "openim-uniapp-polyfill";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
|
||||
export default {
|
||||
|
||||
@@ -6,13 +6,11 @@
|
||||
<view id="scroll_wrap">
|
||||
<u-loadmore nomoreText="" :status="loadMoreStatus" />
|
||||
<view class="msg_item" v-for="item in storeHistoryMessageList" :key="item.clientMsgID" @click="onUserMessageEvent({type:'selected'},item)">
|
||||
<template v-if="selectFlag">
|
||||
<uni-icons class="selectedIcon" size="30" color="#07c160" type="checkbox-filled" v-if="selectClientMsgIDItems.indexOf(item.clientMsgID)>-1"></uni-icons>
|
||||
<uni-icons class="selectedIcon" size="30" color="#ccc" type="circle" v-else></uni-icons>
|
||||
</template>
|
||||
<MessageItemRender
|
||||
@userEvent="onUserMessageEvent"
|
||||
:source="item"
|
||||
:selectItems="selectItems"
|
||||
:selectFlag="selectFlag"
|
||||
:conversationID="storeCurrentConversation.conversationID"
|
||||
:isSender="item.sendID === storeCurrentUserID"
|
||||
/>
|
||||
@@ -74,13 +72,6 @@
|
||||
return "nomore";
|
||||
}
|
||||
return this.messageLoadState.loading ? "loading" : "loadmore";
|
||||
},
|
||||
selectClientMsgIDItems(){
|
||||
let arr = [];
|
||||
this.selectItems.forEach((v,k)=>{
|
||||
arr.push(v.clientMsgID);
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -8,9 +8,16 @@
|
||||
export default {
|
||||
name: "ErrorMessagegRender",
|
||||
components: {},
|
||||
props: {
|
||||
message: Object,
|
||||
conversationID:String,
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created(){
|
||||
console.log(this.message);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -31,11 +31,7 @@
|
||||
return {
|
||||
loadingWidth: "120px",
|
||||
maxHeight:'120px',
|
||||
src:"",
|
||||
coverCachePath:"",
|
||||
coverDownloading:false,
|
||||
coverExists:false,
|
||||
coverDownloadProgress:"",
|
||||
src:""
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -52,40 +48,11 @@
|
||||
methods: {
|
||||
async init(){
|
||||
const self = this;
|
||||
let url = "";
|
||||
// 如果有远程 snapshotUrl,则下载到 coverCachePath
|
||||
const snapshotUrl = this.message.FaceElem.data;
|
||||
const key = md5(snapshotUrl || '');
|
||||
this.coverCachePath = `_doc/${this.conversationID}/face_${key}.jpg`;
|
||||
if (typeof plus === 'undefined' || !this.coverCachePath) return;
|
||||
try {
|
||||
// 检查封面是否存在
|
||||
const coverExists = await util.fileExsit(self.coverCachePath);
|
||||
this.coverExists = !!coverExists;
|
||||
if (this.coverExists) {
|
||||
this.src = this.coverCachePath;
|
||||
return;
|
||||
}
|
||||
if (!snapshotUrl) {
|
||||
this.src="/static/images/sync_error.png";
|
||||
return;
|
||||
}
|
||||
this.coverDownloading = true;
|
||||
await new Promise((resolve, reject) => {
|
||||
util.downloadFile(snapshotUrl, self.coverCachePath, function(localPath) {
|
||||
self.coverDownloading = false;
|
||||
self.coverExists = true;
|
||||
resolve(localPath);
|
||||
}, function(err) {
|
||||
self.coverDownloading = false;
|
||||
reject(err);
|
||||
}, function(progress) {
|
||||
self.coverDownloadProgress = progress;
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
this.coverDownloading = false;
|
||||
}
|
||||
// 检查封面是否存在
|
||||
util.cacheFile(snapshotUrl,'face').then((fn)=>{
|
||||
self.src = fn;
|
||||
});
|
||||
},
|
||||
onLoaded() {
|
||||
this.loadingWidth = "auto";
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
src="/static/images/sync_error.png">
|
||||
</u--image>
|
||||
<u--text class="address" :style="{
|
||||
width:selfWidth+'px'
|
||||
}" :lines="1" :size="20" :text="desc"></u--text>
|
||||
width:selfWidth+'px',
|
||||
paddingTop:'5px'
|
||||
}" :lines="1" :size="16" :text="desc"></u--text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from "@/util"
|
||||
import md5 from "md5";
|
||||
export default {
|
||||
name: "LocationMessageRender",
|
||||
components: {},
|
||||
@@ -39,7 +39,6 @@
|
||||
data() {
|
||||
return {
|
||||
selfWidth:200,
|
||||
loadingWidth: "200px",
|
||||
src:"",
|
||||
coverDownloading:false,
|
||||
coverDownloadProgress:"",
|
||||
@@ -49,12 +48,13 @@
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.selfWidth = uni.$u.getPx('400rpx');
|
||||
let loc = this.message.locationElem;
|
||||
this.desc = loc.description;
|
||||
this.apisrc = "http://api.tianditu.gov.cn/staticimage?"
|
||||
+"center="+loc.longitude+","+loc.latitude
|
||||
+"&width=400"
|
||||
+"&height=300"
|
||||
+"&height=250"
|
||||
+"&zoom=10"
|
||||
+"&markers="+loc.longitude+","+loc.latitude
|
||||
+"&tk=5255a4be64441ba9fa2ebe605ca472bf";
|
||||
@@ -72,30 +72,20 @@
|
||||
const imageWidth = res.width;
|
||||
const aspectRatio = imageHeight / imageWidth;
|
||||
_this.maxHeight = (_this.selfWidth * aspectRatio);
|
||||
console.log(res)
|
||||
_this.src = src;
|
||||
}
|
||||
})
|
||||
},
|
||||
async init(){
|
||||
const self = this;
|
||||
let url = "";
|
||||
// 如果有远程 snapshotUrl,则下载到 coverCachePath
|
||||
const snapshotUrl = this.apisrc ;
|
||||
const key = md5(snapshotUrl || '');
|
||||
const dir_name = `${this.conversationID}`;
|
||||
const save_file_name = `loc_${key}.png`;
|
||||
const coverCachePath = `${dir_name}/${save_file_name}`;
|
||||
if (typeof plus === 'undefined' || !coverCachePath) return;
|
||||
self.coverDownloading = true;
|
||||
util.cacheFile(snapshotUrl,coverCachePath,(fn)=>{
|
||||
util.cacheFile(snapshotUrl,dir_name).then((fn)=>{
|
||||
self.coverDownloading = false;
|
||||
self.getImageInfo(fn);
|
||||
console.log(fn);
|
||||
},(e)=>{
|
||||
console.log(e);
|
||||
},(e)=>{
|
||||
console.log(e);
|
||||
//console.log(fn);
|
||||
});
|
||||
},
|
||||
clickMediaItem() {
|
||||
@@ -105,7 +95,6 @@
|
||||
})
|
||||
},
|
||||
onLoaded() {
|
||||
this.loadingWidth = "auto";
|
||||
},
|
||||
|
||||
},
|
||||
@@ -115,7 +104,6 @@
|
||||
<style lang="scss" scoped>
|
||||
.location_message_container{
|
||||
.address{
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<view class="text_message_container bg_container" v-if="notification.contentType == 101">
|
||||
<u-parse :content="getContent" :previewImg="false" :showImgMenu="false" selectable></u-parse>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {parseBr} from "@/util/common";
|
||||
|
||||
export default {
|
||||
name: "NotificationRender",
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
message: Object,
|
||||
conversationID:String,
|
||||
isSender:Boolean
|
||||
},
|
||||
computed:{
|
||||
notification(){
|
||||
const body = JSON.parse(this.message.notificationElem.detail);
|
||||
body.data = JSON.parse(body.data);
|
||||
return body.data;
|
||||
},
|
||||
getContent() {
|
||||
return parseBr(this.notification.textElem?.content);
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content:"",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
onMessageEvent(e){
|
||||
this.$emit('onMessageEvent',e);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -49,7 +49,7 @@
|
||||
const imageWidth = this.message.pictureElem.sourcePicture.width;
|
||||
const aspectRatio = imageHeight / imageWidth;
|
||||
return 120 * aspectRatio;
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
@@ -58,25 +58,45 @@
|
||||
async init(){
|
||||
const self = this;
|
||||
let url = "";
|
||||
const pictureElem = this.message.pictureElem;
|
||||
// 如果有远程 snapshotUrl,则下载到 coverCachePath
|
||||
const snapshotUrl = (this.message.pictureElem.snapshotPicture?.url ?? this.message.pictureElem.sourcePath );
|
||||
const key = md5(snapshotUrl || '');
|
||||
this.coverCachePath = `${this.conversationID}/img_${key}.jpg`;
|
||||
util.cacheFile(snapshotUrl,this.coverCachePath,(e)=>{
|
||||
let snapshotUrl = pictureElem?.sourcePath;
|
||||
if(snapshotUrl && await util.fileExsit(snapshotUrl)){
|
||||
self.src = snapshotUrl;
|
||||
return ;
|
||||
}
|
||||
|
||||
snapshotUrl = (pictureElem?.sourcePicture.url ?? pictureElem.bigPicture?.url);
|
||||
if(!snapshotUrl){
|
||||
console.log(this.message);
|
||||
return;
|
||||
}
|
||||
console.log(snapshotUrl);
|
||||
util.cacheFile(snapshotUrl,`${this.conversationID}`).then((fn)=>{
|
||||
self.coverDownloading = false;
|
||||
self.src = coverCachePath;
|
||||
console.log(e);
|
||||
},(e)=>{
|
||||
console.log(e);
|
||||
},(e)=>{
|
||||
console.log(e);
|
||||
self.src = fn;
|
||||
console.log(fn);
|
||||
});
|
||||
},
|
||||
getShowPath(url){
|
||||
return new Promise((resolve,reject)=>{
|
||||
if(url.startsWith('file')||url.startsWith('_')||url.startsWith('http')||url.startsWith('blob')){
|
||||
return resolve(url);
|
||||
}
|
||||
plus.io.resolveLocalFileSystemURL(url, function(entry) {
|
||||
return resolve(entry.toLocalURL());
|
||||
}, function(e) {
|
||||
console.log(e);
|
||||
resolve(url);
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
clickMediaItem() {
|
||||
uni.previewImage({
|
||||
current: 0,
|
||||
//urls: [this.message.pictureElem.sourcePicture.url],
|
||||
urls: ["_doc/"+this.coverCachePath],
|
||||
urls: [this.src],
|
||||
indicator: "none",
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="text_message_container bg_container">
|
||||
<u-parse :content="getContent" :previewImg="false" :showImgMenu="false" selectable></u-parse>
|
||||
<u-parse :content="getContent" :previewImg="false" :showImgMenu="false"></u-parse>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="video_message_container" @click="clickMediaItem">
|
||||
<view class="video_message_container">
|
||||
<u--image
|
||||
:showLoading="true"
|
||||
:src="src"
|
||||
:width="imgWidth"
|
||||
:height="maxHeight"
|
||||
mode="widthFix"
|
||||
@load="onLoaded"
|
||||
@click="clickMediaItem">
|
||||
@load="onLoaded" >
|
||||
<template v-slot:loading>
|
||||
<u-loading-icon color="red"></u-loading-icon>
|
||||
</template>
|
||||
@@ -21,8 +20,8 @@
|
||||
</view>
|
||||
<text class="progress-text">{{ videoDownloadProgress }}%</text>
|
||||
</view>
|
||||
<u-icon v-else-if="videoExists" class="play_icon" name="play-circle" size="48" color="#fff"></u-icon>
|
||||
<uni-icons v-else class="play_icon" type="cloud-download" size="48" color="#fff"></uni-icons>
|
||||
<u-icon v-else-if="videoExists" class="play_icon" name="play-circle" size="48" color="#ccc"></u-icon>
|
||||
<uni-icons v-else class="play_icon" type="cloud-download" size="48" color="#ccc"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 视频播放器组件 -->
|
||||
@@ -54,7 +53,7 @@
|
||||
"videoType": "mp4",
|
||||
"videoSize": 3751005,
|
||||
"duration": 44,
|
||||
"snapshotPath": "/storage/emulated/0/Android/data/hk.huisheng.im/apps/__UNI__CA458BA/doc/video_cover_2ea1c8ec.jpg",
|
||||
"snapshotPath": "/storage/emulated/0/Android/data/hk.huisheng.im/apps/__UNI__E41111F/doc/video_cover_2ea1c8ec.jpg",
|
||||
"snapshotSize": 36974,
|
||||
"snapshotUrl": "http://www.axzc.xyz/object/100003/msg_videoSnapshot_d9a596f3e665e84559821a8aa5fb9f16.jpg",
|
||||
"snapshotWidth": 1087,
|
||||
@@ -116,55 +115,38 @@
|
||||
},
|
||||
methods: {
|
||||
async init(){
|
||||
// 如果有远程 snapshotUrl,则下载到 coverCachePath
|
||||
const _this = this;
|
||||
console.log(this.message?.videoElem,this.conversationID);
|
||||
const snapshotUrl = this.message?.videoElem?.snapshotUrl;
|
||||
const key = md5(this.message?.videoElem?.videoUrl || '');
|
||||
const coverCachePath = `${this.conversationID}/cover_${key}.jpg`;
|
||||
this.videoCachePath = `${this.conversationID}/${key}.mp4`;
|
||||
this.videoExists = await util.fileExists(this.videoCachePath);
|
||||
self.coverDownloading = true;
|
||||
util.cacheFile(snapshotUrl,coverCachePath,(e)=>{
|
||||
self.coverDownloading = false;
|
||||
self.src = coverCachePath;
|
||||
console.log(e);
|
||||
},(e)=>{
|
||||
console.log(e);
|
||||
},(e)=>{
|
||||
console.log(e);
|
||||
});
|
||||
},
|
||||
clickMediaItem() {
|
||||
uni.previewImage({
|
||||
current: 0,
|
||||
urls: [this.message.videoElem?.snapshotUrl],
|
||||
indicator: "none",
|
||||
_this.coverDownloading = true;
|
||||
//console.log(snapshotUrl);
|
||||
util.cacheFile(snapshotUrl,`${this.conversationID}`).then((fn)=>{
|
||||
_this.coverDownloading = false;
|
||||
_this.src = fn;
|
||||
//console.log(fn);
|
||||
});
|
||||
_this.videoExists = util.fileExsit(util.getCachePath(_this.message?.videoElem?.videoUrl,`${_this.conversationID}`));
|
||||
},
|
||||
async onLoaded() {
|
||||
this.loadingWidth = "auto";
|
||||
},
|
||||
onOverlayClick() {
|
||||
const _this = this;
|
||||
// 点击覆盖层:如果视频已缓存则直接播放,否则开始下载
|
||||
if (this.videoExists) {
|
||||
this.playVideo("_doc/"+this.videoCachePath);
|
||||
return;
|
||||
}
|
||||
const url = this.message?.videoElem?.videoUrl || this.message?.videoElem?.videoPath;
|
||||
const url = _this.message?.videoElem?.videoUrl;
|
||||
if (!url) {
|
||||
uni.showToast({ title: '无可下载的视频' });
|
||||
return;
|
||||
}
|
||||
this.videoDownloading = true;
|
||||
this.videoDownloadProgress = 0;
|
||||
util.downloadFile(url, this.videoCachePath, (localPath) => {
|
||||
this.videoDownloading = false;
|
||||
this.videoExists = true;
|
||||
this.playVideo("_doc/"+localPath);
|
||||
}, (err) => {
|
||||
this.videoDownloading = false;
|
||||
uni.showToast({ title: '下载失败' });
|
||||
}, (prog) => {
|
||||
_this.videoDownloading = true;
|
||||
_this.videoDownloadProgress = 0;
|
||||
util.cacheFile(url, `${_this.conversationID}`, (prog) => {
|
||||
//console.log(prog);
|
||||
this.videoDownloadProgress = prog;
|
||||
}).then((fn) => {
|
||||
_this.videoDownloading = false;
|
||||
_this.videoExists = true;
|
||||
_this.playVideo(fn);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
conversationID:String,
|
||||
},
|
||||
data() {
|
||||
console.log(this.message);
|
||||
return {
|
||||
src:"",
|
||||
};
|
||||
@@ -45,23 +44,13 @@
|
||||
},
|
||||
methods: {
|
||||
async init(){
|
||||
console.log(this.message);
|
||||
//console.log(this.message);
|
||||
const self = this;
|
||||
let audio = this.message.soundElem;
|
||||
//soundPath
|
||||
// 如果有远程 snapshotUrl,则下载到 cachePath
|
||||
const snapshotUrl = audio.sourceUrl;
|
||||
const key = md5(snapshotUrl || '');
|
||||
const save_file_name = `audio_${key}.${audio.soundType}`;
|
||||
const cachePath = `${this.conversationID}/${save_file_name}`;
|
||||
if (typeof plus === 'undefined' || !cachePath) return;
|
||||
util.cacheFile(snapshotUrl,cachePath,(fn)=>{
|
||||
util.cacheFile(snapshotUrl,`${this.conversationID}`).then((fn)=>{
|
||||
self.src = fn;
|
||||
console.log(fn);
|
||||
},(e)=>{
|
||||
console.log(e);
|
||||
},(e)=>{
|
||||
console.log(e);
|
||||
//console.log(fn);
|
||||
});
|
||||
},
|
||||
handleAudio(){
|
||||
|
||||
@@ -1,35 +1,43 @@
|
||||
<template>
|
||||
<view v-if="!getNoticeContent" :id="`auchor${source.clientMsgID}`" class="message_item"
|
||||
:class="{ message_item_self: isSender, message_item_active: isActive }">
|
||||
<my-avatar size="42" :desc="source.senderNickname" :src="source.senderFaceUrl" @click="viewDetail" />
|
||||
<view class="message_container">
|
||||
<view class="message_sender" :style="{ 'flex-direction': !isSender ? 'row-reverse' : 'row' }">
|
||||
<text>{{ formattedMessageTime }}</text>
|
||||
<text style="margin-left: 2rpx; margin-right: 2rpx">{{ "" }}</text>
|
||||
<text v-if="!isSingle">{{ source.senderNickname }}</text>
|
||||
</view>
|
||||
<view class="message_send_state_box">
|
||||
<view style="height: 100%;display: flex;justify-items: center;align-items: center;">
|
||||
<view class="message_send_state">
|
||||
<u-loading-icon v-if="showSending && !isPreview" />
|
||||
<image v-if="isFailedMessage && !isPreview" class="state_img" src="@/static/images/chating_message_failed.png" />
|
||||
</view>
|
||||
<view v-if="isNoticeMessage" class="notice_message_container" :id="`auchor${source.clientMsgID}`">
|
||||
<text>{{ getNoticeContent }}</text>
|
||||
</view>
|
||||
<view v-else-if="source.contentType == 1519" class="notice_message_container" :id="`auchor${source.clientMsgID}`">
|
||||
<text @click="toAnnouncement">{{ announcementElem.opUser.nickname }}更新了群公告</text>
|
||||
</view>
|
||||
<view v-else class="message_wrapper">
|
||||
<template v-if="selectFlag">
|
||||
<uni-icons class="selectedIcon" size="30" color="#07c160" type="checkbox-filled" v-if="selectClientMsgIDItems.indexOf(source.clientMsgID)>-1"></uni-icons>
|
||||
<uni-icons class="selectedIcon" size="30" color="#ccc" type="circle" v-else></uni-icons>
|
||||
</template>
|
||||
<view :id="`auchor${source.clientMsgID}`" class="message_item"
|
||||
:class="{ message_item_self: isSender, message_item_active: isActive }">
|
||||
<my-avatar size="42" :desc="source.senderNickname" :src="source.senderFaceUrl" @click="viewDetail" />
|
||||
<view class="message_container">
|
||||
<view class="message_sender" :style="{ 'flex-direction': !isSender ? 'row-reverse' : 'row' }">
|
||||
<text>{{ formattedMessageTime }}</text>
|
||||
<text style="margin-left: 2rpx; margin-right: 2rpx">{{ "" }}</text>
|
||||
<text v-if="!isSingle">{{ source.senderNickname }}</text>
|
||||
</view>
|
||||
<view class="message_content_wrap message_content_wrap_shadow" :id="`message_content_wrap_${source.clientMsgID}`" @longtap.stop.prevent="longtapEvent($event)">
|
||||
<component :is="component"
|
||||
@messageEvent="onMessageEvent"
|
||||
:isSender="isSender"
|
||||
:message="source"
|
||||
:conversationID="conversationID"
|
||||
></component>
|
||||
<view class="message_send_state_box">
|
||||
<view style="height: 100%;display: flex;justify-items: center;align-items: center;">
|
||||
<view class="message_send_state">
|
||||
<u-loading-icon v-if="showSending && !isPreview" />
|
||||
<image v-if="isFailedMessage && !isPreview" class="state_img" src="@/static/images/chating_message_failed.png" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="message_content_wrap message_content_wrap_shadow" :id="`message_content_wrap_${source.clientMsgID}`" @longtap.stop.prevent="longtapEvent($event)">
|
||||
<component v-if="component" :is="component"
|
||||
@messageEvent="onMessageEvent"
|
||||
:isSender="isSender"
|
||||
:message="source"
|
||||
:conversationID="conversationID"
|
||||
></component>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<view v-else class="notice_message_container" style="margin: 0 auto;" :id="`auchor${source.clientMsgID}`">
|
||||
<text>{{ getNoticeContent }}</text>
|
||||
<view class="selected_overlay" v-if="selectFlag"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -53,6 +61,7 @@
|
||||
import MarkdownMessageRender from "./MarkdownMessageRender";
|
||||
import StreamMessageRender from "./StreamMessageRender";
|
||||
import OANotificationRender from "./OANotificationRender";
|
||||
import NotificationRender from "./NotificationRender";
|
||||
|
||||
import ErrorMessageRender from "./ErrorMessageRender";
|
||||
import {noticeMessageTypes} from "@/constant";
|
||||
@@ -78,6 +87,7 @@
|
||||
MarkdownMessageRender,
|
||||
StreamMessageRender,
|
||||
OANotificationRender,
|
||||
NotificationRender,
|
||||
ErrorMessageRender
|
||||
},
|
||||
props: {
|
||||
@@ -89,6 +99,16 @@
|
||||
conversationID:String,
|
||||
isPreview: Boolean,
|
||||
isActive: Boolean,
|
||||
selectFlag:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
selectItems:{
|
||||
type:Array,
|
||||
default(){
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -97,7 +117,8 @@
|
||||
toolTipFlag: false,
|
||||
popPostion:"default",
|
||||
toolTipData: [],
|
||||
component:"ErrorMessageRender",
|
||||
component:"",
|
||||
announcementElem:{opUser:{nickname:""}}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -113,16 +134,17 @@
|
||||
formattedMessageTime() {
|
||||
return formatMessageTime(this.source.sendTime);
|
||||
},
|
||||
isNoticeMessage(){
|
||||
return noticeMessageTypes.includes(this.source.contentType);
|
||||
},
|
||||
getNoticeContent() {
|
||||
const isNoticeMessage = noticeMessageTypes.includes(
|
||||
this.source.contentType
|
||||
);
|
||||
return !isNoticeMessage ?
|
||||
"" :
|
||||
tipMessaggeFormat(
|
||||
if(this.isNoticeMessage){
|
||||
return tipMessaggeFormat(
|
||||
this.source,
|
||||
this.$store.getters.storeCurrentUserID
|
||||
);
|
||||
}
|
||||
return "";
|
||||
},
|
||||
isSuccessMessage() {
|
||||
return this.source.status === MessageStatus.Succeed;
|
||||
@@ -133,38 +155,50 @@
|
||||
showSending() {
|
||||
return this.source.status === MessageStatus.Sending && !this.sendingDelay;
|
||||
},
|
||||
selectClientMsgIDItems(){
|
||||
let arr = [];
|
||||
this.selectItems.forEach((v,k)=>{
|
||||
arr.push(v.clientMsgID);
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const MsgType2Components = {
|
||||
['type_'+MessageType.TextMessage] : "TextMessageRender",
|
||||
['type_'+MessageType.PictureMessage] : "PictureMessageRender",
|
||||
['type_'+MessageType.VoiceMessage] : "VoiceMessageRender",
|
||||
['type_'+MessageType.VideoMessage] : "VideoMessageRender",
|
||||
['type_'+MessageType.FileMessage] : "FileMessageRender",
|
||||
['type_'+MessageType.AtTextMessage] : "AtTextMessageRender",
|
||||
['type_'+MessageType.MergeMessage] : "MergeMessageRender",
|
||||
['type_'+MessageType.CardMessage] : "CardMessageRender",
|
||||
['type_'+MessageType.LocationMessage] : "LocationMessageRender",
|
||||
['type_'+MessageType.CustomMessage] : "CustomMessageRender",
|
||||
['type_'+MessageType.TypingMessage] : "TypingMessageRender",
|
||||
['type_'+MessageType.QuoteMessage] : "QuoteMessageRender",
|
||||
['type_'+MessageType.FaceMessage] : "FaceMessageRender",
|
||||
['type_'+MessageType.MarkdownMessage] : "MarkdownMessageRender",
|
||||
['type_'+MessageType.StreamMessage] : "StreamMessageRender",
|
||||
['type_'+MessageType.OANotification] : "OANotificationRender"
|
||||
};
|
||||
this.component = MsgType2Components['type_'+this.source.contentType] || "ErrorMessageRender";
|
||||
if(this.source.contentType == MessageType.GroupAnnouncementUpdated){
|
||||
this.announcementElem = JSON.parse(this.source.notificationElem.detail)
|
||||
}else{
|
||||
const MsgType2Components = {
|
||||
['type_'+MessageType.TextMessage] : "TextMessageRender",
|
||||
['type_'+MessageType.PictureMessage] : "PictureMessageRender",
|
||||
['type_'+MessageType.VoiceMessage] : "VoiceMessageRender",
|
||||
['type_'+MessageType.VideoMessage] : "VideoMessageRender",
|
||||
['type_'+MessageType.FileMessage] : "FileMessageRender",
|
||||
['type_'+MessageType.AtTextMessage] : "AtTextMessageRender",
|
||||
['type_'+MessageType.MergeMessage] : "MergeMessageRender",
|
||||
['type_'+MessageType.CardMessage] : "CardMessageRender",
|
||||
['type_'+MessageType.LocationMessage] : "LocationMessageRender",
|
||||
['type_'+MessageType.CustomMessage] : "CustomMessageRender",
|
||||
['type_'+MessageType.TypingMessage] : "TypingMessageRender",
|
||||
['type_'+MessageType.QuoteMessage] : "QuoteMessageRender",
|
||||
['type_'+MessageType.FaceMessage] : "FaceMessageRender",
|
||||
['type_'+MessageType.MarkdownMessage] : "MarkdownMessageRender",
|
||||
['type_'+MessageType.StreamMessage] : "StreamMessageRender",
|
||||
['type_'+MessageType.OANotification] : "OANotificationRender",
|
||||
'type_2001' : "NotificationRender"
|
||||
};
|
||||
this.component = MsgType2Components['type_'+this.source.contentType] || "ErrorMessageRender";
|
||||
}
|
||||
this.$emit('userEvent',{type:"messageItemRender"},this.source.clientMsgID);
|
||||
this.setSendingDelay();
|
||||
},
|
||||
methods: {
|
||||
viewDetail(){
|
||||
if(this.isSender){
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url:"/pages/common/userCard/index?sourceID="+this.source.sendID
|
||||
})
|
||||
}
|
||||
this.$emit('userEvent',{type:"avatarClick"},this.source);
|
||||
},
|
||||
toAnnouncement(){
|
||||
uni.navigateTo({
|
||||
url:"/pages/conversation/groupSettings/announcement"
|
||||
})
|
||||
},
|
||||
setSendingDelay() {
|
||||
if (this.source.status === MessageStatus.Sending) {
|
||||
@@ -174,20 +208,35 @@
|
||||
}
|
||||
},
|
||||
longtapEvent(e){
|
||||
console.log('longtapEvent');
|
||||
this.$emit('userEvent',{type:"longtapMsgContent"},this.source);
|
||||
},
|
||||
onMessageEvent(e){
|
||||
this.$emit('userEvent',e);
|
||||
onMessageEvent(e,data){
|
||||
this.$emit('userEvent',e,data);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.message_wrapper{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
.selected_overlay{
|
||||
position: absolute;
|
||||
left:0;
|
||||
top:0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
.message_item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex:1;
|
||||
padding: 16rpx 44rpx;
|
||||
// padding-top: 48rpx;
|
||||
position: relative;
|
||||
@@ -233,7 +282,7 @@
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
.message_content_wrap_shadow {
|
||||
box-shadow: 0px 0px 2px rgba(0,0,0,0.1);
|
||||
box-shadow: 0px 0px 0px rgba(0,0,0,0.1);
|
||||
}
|
||||
.message_content_wrap {
|
||||
@include vCenterBox();
|
||||
@@ -296,7 +345,7 @@
|
||||
// text-align: end;
|
||||
align-items: flex-end;
|
||||
.message_content_wrap_shadow {
|
||||
box-shadow: 0px 0px 2px #95e261;
|
||||
box-shadow: 0px 0px 0px #95e261;
|
||||
}
|
||||
.message_content_wrap {
|
||||
flex-direction: row-reverse;
|
||||
@@ -326,10 +375,14 @@
|
||||
.notice_message_container {
|
||||
@include ellipsisWithLine(2);
|
||||
text-align: center;
|
||||
margin: 24rpx 48rpx;
|
||||
padding: 24rpx 48rpx;
|
||||
word-break: break-word;
|
||||
// font-size: 24rpx;
|
||||
font-size: 0.85rem;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,14 +19,15 @@
|
||||
<script>
|
||||
import {mapActions,mapGetters} from "vuex";
|
||||
import {offlinePushInfo} from "@/util/imCommon";
|
||||
import {PageEvents,ContactChooseTypes } from "@/constant";
|
||||
import {PageEvents,ContactChooseTypes,noticeMessageTypes} from "@/constant";
|
||||
import ChatingHeader from "./components/ChatingHeader";
|
||||
import ChatingFooter from "./components/ChatingFooter/index";
|
||||
import ChatingList from "./components/ChatingList";
|
||||
import SelectHeader from "./components/SelectHeader";
|
||||
import SelectFooter from "./components/SelectFooter";
|
||||
import {markConversationAsRead} from "@/util/imCommon";
|
||||
import IMSDK, {MessageType} from "openim-uniapp-polyfill";
|
||||
import IMSDK, {MessageType,GroupMemberRole,SessionType} from "openim-uniapp-polyfill";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
components: {
|
||||
ChatingHeader,
|
||||
@@ -50,8 +51,25 @@
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
"storeCurrentConversation","storeCurrentMsg",'storeCurrentMsgID'
|
||||
"storeHistoryMessageList",
|
||||
"storeCurrentUserID",
|
||||
"storeCurrentConversation",
|
||||
"storeCurrentMsg",
|
||||
'storeCurrentMsgID',
|
||||
"storeCurrentGroup",
|
||||
"storeCurrentMemberInGroup"
|
||||
]),
|
||||
isSingle() {
|
||||
return (
|
||||
this.storeCurrentConversation.conversationType === SessionType.Single
|
||||
);
|
||||
},
|
||||
isOwner() {
|
||||
return this.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Owner;
|
||||
},
|
||||
isAdmin() {
|
||||
return this.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Admin;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.Audio = uni.createInnerAudioContext(); //音频
|
||||
@@ -71,6 +89,16 @@
|
||||
console.log(r);
|
||||
this.updateCurrentMsg({});
|
||||
})
|
||||
//console.log(this.storeCurrentConversation)
|
||||
if(process.env.NODE_ENV == 'development'){
|
||||
// if(this.storeCurrentConversation.groupID){
|
||||
// setTimeout(()=>{
|
||||
// uni.navigateTo({
|
||||
// url:"/pages/conversation/groupAlbum/groupAlbum?groupID="+this.storeCurrentConversation.groupID
|
||||
// });
|
||||
// },1000)
|
||||
// }
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
storeCurrentMsgID(nv,ov){
|
||||
@@ -86,13 +114,22 @@
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
//console.log("onload");
|
||||
//console.log("onload",this.storeCurrentConversation);
|
||||
this.setPageListener();
|
||||
if (options?.back2Tab) {
|
||||
this.back2Tab = JSON.parse(options.back2Tab);
|
||||
}
|
||||
// IMSDK.subscribe(IMSDK.IMEvents.OnMsgDeleted,({data})=>{
|
||||
// let list = this.storeHistoryMessageList;
|
||||
// //console.log(data);
|
||||
// list = list.filter((item)=>{
|
||||
// return item.serverMsgID != data.serverMsgID;
|
||||
// })
|
||||
// this.$store.commit('message/SET_HISTORY_MESSAGE_LIST',list);
|
||||
// });
|
||||
},
|
||||
onUnload() {
|
||||
//IMSDK.unsubscribe(IMSDK.IMEvents.OnMsgDeleted);
|
||||
//console.log("unload");
|
||||
this.disposePageListener();
|
||||
markConversationAsRead({...this.$store.getters.storeCurrentConversation,},true);
|
||||
@@ -102,6 +139,7 @@
|
||||
if (this.Audio) {
|
||||
this.Audio.stop();
|
||||
this.Audio.destroy();
|
||||
this.Audio = null;
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
@@ -173,9 +211,6 @@
|
||||
}
|
||||
},
|
||||
sendMessage(message, user_id, group_id) {
|
||||
//this.scrollToBottom();
|
||||
//console.log(message);
|
||||
//console.log(user_id,group_id);
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.SendMessage, IMSDK.uuid(), {
|
||||
recvID: user_id,
|
||||
groupID: group_id,
|
||||
@@ -183,15 +218,23 @@
|
||||
offlinePushInfo,
|
||||
})
|
||||
.then(({data}) => {
|
||||
console.log(data);
|
||||
this.pushNewMessage(message);
|
||||
if(user_id && this.storeCurrentConversation.userID == user_id){
|
||||
this.pushNewMessage(message);
|
||||
this.scrollToBottom();
|
||||
return ;
|
||||
}
|
||||
if(group_id && this.storeCurrentConversation.groupID == group_id){
|
||||
this.pushNewMessage(message);
|
||||
this.scrollToBottom();
|
||||
return ;
|
||||
}
|
||||
})
|
||||
.catch((res = {data,errCode,errMsg}) => {
|
||||
console.log(res);
|
||||
uni.$u.toast(errMsg);
|
||||
});
|
||||
},
|
||||
onUserMessageEvent(e, data) {
|
||||
async onUserMessageEvent(e, data) {
|
||||
const _this = this;
|
||||
if (e.type == 'select') {
|
||||
this.selectFlag = true;
|
||||
@@ -206,24 +249,23 @@
|
||||
}
|
||||
if (e.type == 'selected') {
|
||||
if (this.selectFlag == true) {
|
||||
let founded = false;
|
||||
let arr = [];
|
||||
for (var index = 0; index < this.selectItems.length; index++) {
|
||||
var v = this.selectItems[index];
|
||||
if (v.clientMsgID == data.clientMsgID) {
|
||||
founded = true;
|
||||
} else {
|
||||
arr.push(v);
|
||||
}
|
||||
if(noticeMessageTypes.includes(data.contentType)){
|
||||
return ;
|
||||
}
|
||||
if (!founded) {
|
||||
arr.push(data);
|
||||
let arr = this.selectItems.filter((item)=>item.clientMsgID != data.clientMsgID);
|
||||
if(arr.length === this.selectItems.length){
|
||||
arr.push(data)
|
||||
}
|
||||
this.selectItems = [...arr];
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (e.type == 'deleteMsg') {
|
||||
if (e.type == 'deleteMsg' || e.type == 'deleteServerMsg') {
|
||||
let method = IMSDK.IMMethods.DeleteMessageFromLocalStorage;
|
||||
if(e.type == 'deleteServerMsg'){
|
||||
method = IMSDK.IMMethods.RevokeMessage
|
||||
}
|
||||
//console.log(method);
|
||||
let deleteMsgs = [];
|
||||
if (!data) {
|
||||
deleteMsgs = [...this.selectItems];
|
||||
@@ -232,19 +274,13 @@
|
||||
}
|
||||
for (let i = 0; i < deleteMsgs.length; i++) {
|
||||
let element = deleteMsgs[i];
|
||||
IMSDK.asyncApi('deleteMessageFromLocalStorage', IMSDK.uuid(), {
|
||||
let a = await IMSDK.asyncApi(method, IMSDK.uuid(), {
|
||||
conversationID: _this.storeCurrentConversation.conversationID,
|
||||
clientMsgID: element.clientMsgID
|
||||
}).then(res => {
|
||||
//console.log(res);
|
||||
}).catch(res => {
|
||||
//console.log(res);
|
||||
}).finally(() => {
|
||||
//console.log(arguments);
|
||||
})
|
||||
});
|
||||
//console.log(a);
|
||||
}
|
||||
this.selectItems = [];
|
||||
this.$refs.chatingListRef.loadMessageList();
|
||||
return;
|
||||
}
|
||||
if (e.type == 'forward') {
|
||||
@@ -291,7 +327,11 @@
|
||||
conversationID: _this.storeCurrentConversation.conversationID,
|
||||
clientMsgID: data.clientMsgID
|
||||
}).then(res => {
|
||||
console.log(res);
|
||||
let list = _this.storeHistoryMessageList;
|
||||
list = list.filter((item)=>{
|
||||
return item.clientMsgID != data.clientMsgID;
|
||||
});
|
||||
_this.$store.commit('message/SET_HISTORY_MESSAGE_LIST',list);
|
||||
}).catch(res => {
|
||||
console.log(res);
|
||||
}).finally(() => {
|
||||
@@ -299,7 +339,7 @@
|
||||
})
|
||||
return;
|
||||
}
|
||||
if(e.type == 'audio_msg_click'){
|
||||
if (e.type == 'audio_msg_click'){
|
||||
if(_this.storeCurrentMsgID){
|
||||
_this.updateCurrentMsg({clientMsgID:""});
|
||||
}else{
|
||||
@@ -318,9 +358,12 @@
|
||||
let nowTime = new Date().getTime();
|
||||
let msgTime = data.createTime;
|
||||
let diff = nowTime - msgTime;
|
||||
if (this.isSender && diff < 120000) {
|
||||
if (_this.storeCurrentUserID == data.sendID && diff < 120000) {
|
||||
menu.push('撤回')
|
||||
}
|
||||
if(_this.isAdmin || _this.isOwner){
|
||||
menu.push('撤回(管理员功能)')
|
||||
}
|
||||
uni.showActionSheet({
|
||||
itemList: menu,
|
||||
success({tapIndex}) {
|
||||
@@ -360,6 +403,9 @@
|
||||
case "删除":
|
||||
_this.onUserMessageEvent({type: 'deleteMsg'}, data);
|
||||
break;
|
||||
case "撤回(管理员功能)":
|
||||
_this.onUserMessageEvent({type: 'deleteServerMsg'}, data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -367,6 +413,20 @@
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (e.type == 'avatarClick'){
|
||||
if(data.sendID == this.storeCurrentUserID){
|
||||
return ;
|
||||
}
|
||||
if(!_this.isSingle){
|
||||
if(this.storeCurrentMemberInGroup.roleLevel < 60 && this.storeCurrentGroup.lookMemberInfo!=0){
|
||||
return ;
|
||||
}
|
||||
}
|
||||
uni.navigateTo({
|
||||
url:"/pages/common/userCard/index?sourceID="+data.sendID
|
||||
})
|
||||
return ;
|
||||
}
|
||||
}
|
||||
},
|
||||
onBackPress() {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<uni-icons size="24" color="#FFF" type="personadd"></uni-icons>
|
||||
<text>添加好友</text>
|
||||
</view>
|
||||
<view @click="clickMenu({name:'createGroup'})" class="menu_item">
|
||||
<view @click="clickMenu({name:'scan'})" class="menu_item">
|
||||
<uni-icons size="24" color="#FFF" type="scan"></uni-icons>
|
||||
<text>扫一扫</text>
|
||||
</view>
|
||||
@@ -191,6 +191,45 @@
|
||||
padding: 0 24rpx 10rpx;
|
||||
//margin-top: var(--status-bar-height);
|
||||
background: #f4f4f4;
|
||||
.status_notice{
|
||||
.err-tag {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 44rpx;
|
||||
background: #ffe1dd;
|
||||
border-radius: 12rpx 12rpx 12rpx 12rpx;
|
||||
margin-left: 8rpx;
|
||||
|
||||
.status {
|
||||
font-size: 24rpx;
|
||||
margin-left: 8rpx;
|
||||
font-weight: 400;
|
||||
color: #ff381f;
|
||||
}
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 44rpx;
|
||||
background: #f2f8ff;
|
||||
border-radius: 12rpx 12rpx 12rpx 12rpx;
|
||||
margin-left: 8rpx;
|
||||
|
||||
.loading {
|
||||
animation: loading 1.5s infinite;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: 24rpx;
|
||||
margin-left: 8rpx;
|
||||
font-weight: 400;
|
||||
color: #0089ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.self_info {
|
||||
@include btwBox();
|
||||
@@ -216,46 +255,6 @@
|
||||
max-width: 240rpx;
|
||||
}
|
||||
|
||||
.err-tag {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 152rpx;
|
||||
height: 44rpx;
|
||||
background: #ffe1dd;
|
||||
border-radius: 12rpx 12rpx 12rpx 12rpx;
|
||||
margin-left: 8rpx;
|
||||
|
||||
.status {
|
||||
font-size: 24rpx;
|
||||
margin-left: 8rpx;
|
||||
font-weight: 400;
|
||||
color: #ff381f;
|
||||
}
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 152rpx;
|
||||
height: 44rpx;
|
||||
background: #f2f8ff;
|
||||
border-radius: 12rpx 12rpx 12rpx 12rpx;
|
||||
margin-left: 8rpx;
|
||||
|
||||
.loading {
|
||||
animation: loading 1.5s infinite;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: 24rpx;
|
||||
margin-left: 8rpx;
|
||||
font-weight: 400;
|
||||
color: #0089ff;
|
||||
}
|
||||
}
|
||||
|
||||
.online_state {
|
||||
@include vCenterBox();
|
||||
margin-left: 24rpx;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<template>
|
||||
<view @longtap.prevent="longtapConversationItem" @tap.prevent="clickConversationItem" :class="['conversation_item',source.isPinned?'pinned' : '']">
|
||||
<view class="left_info">
|
||||
<my-avatar :isGroup="isGroup" :isNotify="isNotify" :src="source.faceURL" :desc="source.showName" size="46" />
|
||||
<view class="avatar">
|
||||
<my-avatar :isGroup="isGroup" :isNotify="isNotify" :src="source.faceURL" :desc="source.showName" size="46" />
|
||||
<u-badge v-if="source.unreadCount>0" max="99" :value="source.unreadCount"></u-badge>
|
||||
</view>
|
||||
<view class="details">
|
||||
<view class="title">
|
||||
<text class="conversation_name">
|
||||
@@ -9,11 +12,11 @@
|
||||
</text>
|
||||
<view class="right_desc">
|
||||
<text class="send_time">{{ latestMessageTime }}</text>
|
||||
<u-badge max="99" :value="source.unreadCount"></u-badge>
|
||||
</view>
|
||||
</view>
|
||||
<view class="lastest_msg_wrap">
|
||||
<text class="lastest_msg_content">{{ latestMessage }}</text>
|
||||
<uni-icons v-if="source.recvMsgOpt===2" custom-prefix="imfont" type="im-bell-off" size="16" color="#ddd"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -45,6 +48,7 @@
|
||||
parsedMessage = JSON.parse(this.source.latestMsg);
|
||||
} catch (e) {}
|
||||
if (!parsedMessage) return "";
|
||||
//console.log(parsedMessage);
|
||||
return getConversationContent(parsedMessage);
|
||||
},
|
||||
latestMessageTime() {
|
||||
@@ -101,21 +105,29 @@
|
||||
box-sizing: border-box;
|
||||
padding: 12rpx 44rpx 20rpx;
|
||||
flex:1;
|
||||
|
||||
.avatar{
|
||||
position: relative;
|
||||
.u-badge{
|
||||
position: absolute;
|
||||
right: -6rpx;
|
||||
top: -6rpx;
|
||||
}
|
||||
}
|
||||
.details {
|
||||
@include colBox(true);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
flex:1;
|
||||
margin-left: 24rpx;
|
||||
height: 46px;
|
||||
color: $uni-text-color;
|
||||
padding-bottom:20rpx;
|
||||
color: $u-main-color;
|
||||
.title{
|
||||
@include btwBox();
|
||||
.conversation_name {
|
||||
@include nomalEllipsis();
|
||||
max-width: 40vw;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.right_desc {
|
||||
@@ -138,6 +150,7 @@
|
||||
|
||||
.lastest_msg_wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
margin: 10rpx 0;
|
||||
color: #666;
|
||||
@@ -160,5 +173,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +1,17 @@
|
||||
<template>
|
||||
<view class="conversation_container">
|
||||
<chat-header ref="chatHeaderRef" />
|
||||
<scroll-view class="scroll-view" scroll-y="true" refresher-enabled="true" :refresher-triggered="triggered"
|
||||
:scroll-top="scrollTop" :scroll-with-animation="true" @scroll="scroll" @refresherrefresh="onRefresh"
|
||||
@refresherrestore="onRestore" @scrolltolower="scrolltolower">
|
||||
<uni-swipe-action ref="swipe_action">
|
||||
<uni-swipe-action-item :right-options="swipe_actions" @click="actionClick($event,item)" v-for="item in storeConversationList" :key="item.conversationID" >
|
||||
<conversation-item @longtapEvent="showExtendMenu(item)" :source="item"/>
|
||||
</uni-swipe-action-item>
|
||||
</uni-swipe-action>
|
||||
</scroll-view>
|
||||
<uni-swipe-action ref="swipe_action">
|
||||
<template v-for="item in storeConversationList" >
|
||||
<uni-swipe-action-item
|
||||
v-if="item.sendID !='system1'"
|
||||
:right-options="swipe_actions"
|
||||
@click="actionClick($event,item)"
|
||||
:key="item.conversationID" >
|
||||
<conversation-item @longtapEvent="showExtendMenu(item)" :source="item"/>
|
||||
</uni-swipe-action-item>
|
||||
</template>
|
||||
</uni-swipe-action>
|
||||
<view class="loading_wrap" v-if="storeProgress > 0 && storeProgress < 100">
|
||||
<u-loading-icon :vertical="true" :text="storeProgress + '%'"></u-loading-icon>
|
||||
</view>
|
||||
@@ -55,12 +57,16 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
triggered: false,
|
||||
refreshing: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["storeConversationList", "storeIsSyncing", "storeProgress"]),
|
||||
...mapGetters([
|
||||
"storeConversationList",
|
||||
"storeIsSyncing",
|
||||
"storeProgress",
|
||||
'storeCurrentUserID'
|
||||
]),
|
||||
},
|
||||
onReady() {
|
||||
// #ifdef APP
|
||||
@@ -69,23 +75,18 @@
|
||||
},
|
||||
onLoad() {
|
||||
//console.log(this.storeConversationList);
|
||||
this._freshing = false;
|
||||
this.triggered = true;
|
||||
setTimeout(()=>{
|
||||
// uni.navigateTo({
|
||||
// //url:'/pages/workbench/friend-circle/friend-circle',
|
||||
// url:'/pages/common/map',
|
||||
// events: {
|
||||
// onConfirm(res) {
|
||||
// console.log(res);
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// uni.switchTab({
|
||||
// url:"/pages/profile/index/index"
|
||||
// })
|
||||
prepareConversationState(this.storeConversationList[1]);
|
||||
},1000)
|
||||
this.freshing = false;
|
||||
if(process.env.NODE_ENV == 'development'){
|
||||
setTimeout(()=>{
|
||||
// uni.switchTab({
|
||||
// url:"/pages/user/index/index"
|
||||
// })
|
||||
// uni.navigateTo({
|
||||
// url:"/pages/conversation/groupAlbum/groupAlbum?groupID=1731702760"
|
||||
// });
|
||||
//prepareConversationState(this.storeConversationList[0]);
|
||||
},1000)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
test(){
|
||||
@@ -93,33 +94,33 @@
|
||||
},
|
||||
showExtendMenu(item){
|
||||
const _this = this;
|
||||
const menu = [item.recvMsgOpt===0 ? '关闭免打扰':'免打扰',item.isPrivateChat? '关闭阅后即焚':'开启阅后即焚','隐藏',item.isPinned ? '取消置顶':'置顶','删除'];
|
||||
const menu = [item.recvMsgOpt===0 ? '免打扰':'关闭免打扰',item.isPrivateChat? '关闭阅后即焚':'开启阅后即焚','隐藏',item.isPinned ? '取消置顶':'置顶','删除'];
|
||||
uni.showActionSheet({
|
||||
itemList:menu,
|
||||
success(e) {
|
||||
switch(menu[e.tapIndex]){
|
||||
case '免打扰':
|
||||
IMSDK.asyncApi('setConversation', IMSDK.uuid(), {
|
||||
conversationID: conversationId,
|
||||
_this.setConversation({
|
||||
conversationID: item.conversationID,
|
||||
recvMsgOpt: 2
|
||||
})
|
||||
break;
|
||||
case '关闭免打扰':
|
||||
IMSDK.asyncApi('setConversation', IMSDK.uuid(), {
|
||||
conversationID: conversationId,
|
||||
_this.setConversation({
|
||||
conversationID: item.conversationID,
|
||||
recvMsgOpt: 0
|
||||
})
|
||||
break;
|
||||
case '开启阅后即焚':
|
||||
IMSDK.asyncApi('setConversation', IMSDK.uuid(), {
|
||||
conversationID: conversationId,
|
||||
_this.setConversation({
|
||||
conversationID: item.conversationID,
|
||||
isPrivateChat: true,
|
||||
burnDuration:60
|
||||
})
|
||||
break;
|
||||
case '关闭阅后即焚':
|
||||
IMSDK.asyncApi('setConversation', IMSDK.uuid(), {
|
||||
conversationID: conversationId,
|
||||
_this.setConversation({
|
||||
conversationID: item.conversationID,
|
||||
isPrivateChat: false
|
||||
})
|
||||
break;
|
||||
@@ -127,10 +128,16 @@
|
||||
IMSDK.asyncApi('hideConversation', IMSDK.uuid(), item.conversationID)
|
||||
break;
|
||||
case '置顶':
|
||||
_this.setPinConversation(item.conversationID,true);
|
||||
_this.setConversation({
|
||||
conversationID: item.conversationID,
|
||||
isPinned: true
|
||||
});
|
||||
break;
|
||||
case '取消置顶':
|
||||
_this.setPinConversation(item.conversationID,false);
|
||||
_this.setConversation({
|
||||
conversationID: item.conversationID,
|
||||
isPinned: false
|
||||
})
|
||||
break;
|
||||
case '删除':
|
||||
_this.deleteConversation(item.conversationID);
|
||||
@@ -155,43 +162,44 @@
|
||||
},
|
||||
|
||||
deleteConversation(conversationID){
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.DeleteConversationAndDeleteAllMsg, IMSDK.uuid(), conversationID).then(res=>{
|
||||
this.$store.dispatch('conversation/deleteConversation',conversationID).then(res=>{
|
||||
console.log('删除成功');
|
||||
}).catch(e=>{
|
||||
|
||||
})
|
||||
},
|
||||
setPinConversation(conversationId,status){
|
||||
IMSDK.asyncApi('setConversation', IMSDK.uuid(), {
|
||||
conversationID: conversationId,
|
||||
isPinned: status
|
||||
})
|
||||
|
||||
async setConversation(data){
|
||||
await IMSDK.asyncApi('setConversation', IMSDK.uuid(), data);
|
||||
},
|
||||
|
||||
scroll(e) {
|
||||
this.old.scrollTop = e.detail.scrollTop;
|
||||
},
|
||||
onRefresh() {
|
||||
if (this._freshing) return;
|
||||
this._freshing = true;
|
||||
if (this.refreshing) return;
|
||||
console.log('onRefresh');
|
||||
this.refreshing = true;
|
||||
this.queryList(true);
|
||||
},
|
||||
onRestore() {
|
||||
this.triggered = "restore";
|
||||
console.log("onRestore");
|
||||
},
|
||||
scrolltolower() {
|
||||
this.queryList();
|
||||
},
|
||||
async queryList(isFirstPage = false) {
|
||||
await this.$store.dispatch("conversation/getConversationList",isFirstPage);
|
||||
this.triggered = false;
|
||||
this._freshing = false;
|
||||
uni.stopPullDownRefresh();
|
||||
this.refreshing = false;
|
||||
},
|
||||
closeAllSwipe() {
|
||||
this.$refs.swipeWrapperRef.closeAll();
|
||||
},
|
||||
},
|
||||
onReachBottom() {
|
||||
this.scrolltolower();
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.queryList(true);
|
||||
},
|
||||
onPageScroll(res) {
|
||||
this.old.scrollTop = res.scrollTop;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -199,7 +207,6 @@
|
||||
.conversation_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.conversation_search {
|
||||
@@ -217,11 +224,6 @@
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scroll-view {
|
||||
height: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.loading_wrap {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
<template>
|
||||
<view class="group_album_page">
|
||||
<uni-nav-bar left-icon="back" @clickLeft="back" @clickRight="manage" title="群相册" statusBar fixed>
|
||||
<view slot="left">
|
||||
<uni-icons type="back"></uni-icons>
|
||||
</view>
|
||||
<view slot="right" v-if="isAdmin">
|
||||
<text v-if="manageStatus">取消</text>
|
||||
<text v-else>管理</text>
|
||||
</view>
|
||||
</uni-nav-bar>
|
||||
<view class="list">
|
||||
<view class="item" v-if="isAdmin">
|
||||
<view class="pickfile" @click="pickMedia">
|
||||
<u-icon
|
||||
color="#D3d3d3"
|
||||
size="40"
|
||||
name="plus"
|
||||
></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<template v-for="(item,index) in fileList">
|
||||
<view v-if="item.status!=1" :key="'fileList'+index" class="item">
|
||||
<c-CacheImage :src="item.url" width="234rpx" height="234rpx"></c-CacheImage>
|
||||
<view class="overlay"></view>
|
||||
<u-line-progress :percentage="item.progress" showText></u-line-progress>
|
||||
</view>
|
||||
</template>
|
||||
<view v-for="(item,index) in list" :key="index" class="item" @click="itemClick(item,index)" :class="{cancheck:manageStatus,checked:selectedItemIds.includes(item.id)}">
|
||||
<c-CacheImage :src="item.url" width="234rpx" height="234rpx" @click="itemClick(item,index)" ></c-CacheImage>
|
||||
</view>
|
||||
</view>
|
||||
<u-loadmore :status="load_status" />
|
||||
<view class="footer" v-if="manageStatus">
|
||||
<button @click="selectAll" size="mini">全选</button>
|
||||
<button @click="deleteItem" type="warn" size="mini">删除({{selectedItemIds.length}})</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import util from "@/util/index.js"
|
||||
import {upload} from "@/api/login.js"
|
||||
import {mapGetters} from "vuex";
|
||||
import {GroupMemberRole} from "openim-uniapp-polyfill";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
albumWidth: 0,
|
||||
fileList: [],
|
||||
list: [
|
||||
{
|
||||
id:1,
|
||||
url: "https://cdn.uviewui.com/uview/album/1.jpg",
|
||||
},
|
||||
{
|
||||
id:2,
|
||||
url: "https://cdn.uviewui.com/uview/album/2.jpg",
|
||||
},
|
||||
{
|
||||
id:3,
|
||||
url: "https://cdn.uviewui.com/uview/album/3.jpg",
|
||||
},
|
||||
{
|
||||
id:4,
|
||||
url: "https://cdn.uviewui.com/uview/album/4.jpg",
|
||||
},
|
||||
{
|
||||
id:5,
|
||||
url: "https://cdn.uviewui.com/uview/album/5.jpg",
|
||||
},
|
||||
{
|
||||
id:6,
|
||||
url: "https://cdn.uviewui.com/uview/album/6.jpg",
|
||||
},
|
||||
{
|
||||
id:7,
|
||||
url: "https://cdn.uviewui.com/uview/album/7.jpg",
|
||||
},
|
||||
{
|
||||
id:8,
|
||||
url: "https://cdn.uviewui.com/uview/album/8.jpg",
|
||||
},
|
||||
{
|
||||
id:9,
|
||||
url: "https://cdn.uviewui.com/uview/album/9.jpg",
|
||||
},
|
||||
],
|
||||
manageStatus: false,
|
||||
selectedItemIds:[],
|
||||
uploadButtonWidth:0,
|
||||
load_status:"loadmore",
|
||||
param: {
|
||||
groupID: "",
|
||||
offset: 999999999999,
|
||||
limit: 10,
|
||||
trace: 1,
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
"storeCurrentConversation",
|
||||
"storeCurrentMemberInGroup",
|
||||
"storeCurrentGroup",
|
||||
]),
|
||||
isAdmin() {
|
||||
return this.storeCurrentMemberInGroup.roleLevel > GroupMemberRole.Normal;
|
||||
},
|
||||
},
|
||||
onLoad(opt) {
|
||||
this.param.groupID = opt.groupID
|
||||
//this.param.groupID = opt.storeCurrentConversation.groupID;
|
||||
this.init();
|
||||
this.uploadButtonWidth = uni.$u.getPx('234rpx');
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.getList(true);
|
||||
},
|
||||
getList(isFirstPage = false) {
|
||||
this.param.offset = 21;
|
||||
if (isFirstPage === true) {
|
||||
this.list = [];
|
||||
this.param.offset = 20;
|
||||
this.param.offset = 999999999999;
|
||||
}
|
||||
this.load_status = 'loading';
|
||||
uni.$u.http.post('/group/album_list', this.param).then(res => {
|
||||
if(res.length>0){
|
||||
this.param.offset = res[0].id;
|
||||
this.list = this.list.concat(res);
|
||||
this.load_status = 'loadmore';
|
||||
if(res.length < this.param.limit){
|
||||
this.load_status = 'nomore';
|
||||
}
|
||||
return ;
|
||||
}
|
||||
this.load_status = 'nomore';
|
||||
}).catch(e => {
|
||||
this.load_status = 'loadmore';
|
||||
})
|
||||
},
|
||||
itemClick(item,index) {
|
||||
if(this.manageStatus && this.isAdmin){
|
||||
if(this.selectedItemIds.includes(item.id)){
|
||||
this.selectedItemIds = this.selectedItemIds.filter(id=>item.id!=id)
|
||||
}else{
|
||||
this.selectedItemIds.push(item.id);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
const urls = this.list.map(item=>util.cdn(item.url));
|
||||
uni.previewImage({
|
||||
urls:urls,
|
||||
current:index,
|
||||
})
|
||||
},
|
||||
deleteItem(){
|
||||
if(!this.isAdmin || this.selectedItemIds.length == 0){
|
||||
return ;
|
||||
}
|
||||
const _this = this;
|
||||
uni.showModal({
|
||||
content:"确定删除吗?一旦删除不能恢复",
|
||||
success(res) {
|
||||
if(res.confirm){
|
||||
_this.doDelete();
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
selectAll(){
|
||||
if(!this.isAdmin){
|
||||
return ;
|
||||
}
|
||||
const arr = [];
|
||||
this.list.forEach(item=>{
|
||||
arr.push(item.id);
|
||||
})
|
||||
this.selectedItemIds = [...arr];
|
||||
},
|
||||
doDelete(){
|
||||
if(!this.isAdmin || this.selectedItemIds.length == 0){
|
||||
return ;
|
||||
}
|
||||
uni.$u.http.post('/group/album_delete', {ids:this.selectedItemIds}).then(res => {
|
||||
this.list = this.list.filter(item=>!this.selectedItemIds.includes(item.id));
|
||||
this.selectedItemIds = [];
|
||||
this.manageStatus = false;
|
||||
}).catch(e => {
|
||||
uni.$u.toast(e?.msg || e);
|
||||
})
|
||||
},
|
||||
back() {
|
||||
if (this.manageStatus) {
|
||||
this.manageStatus = false;
|
||||
return;
|
||||
}
|
||||
util.goto(1);
|
||||
},
|
||||
manage() {
|
||||
if(!this.isAdmin){
|
||||
return ;
|
||||
}
|
||||
this.manageStatus = !this.manageStatus;
|
||||
},
|
||||
pickMedia(){
|
||||
if(!this.isAdmin){
|
||||
return ;
|
||||
}
|
||||
const _this = this;
|
||||
uni.chooseImage({
|
||||
success(res) {
|
||||
//res.tempFilePaths[0]
|
||||
//res.tempFiles[0].path
|
||||
//res.tempFiles[0].size
|
||||
let i = 0;
|
||||
_this.fileList = res.tempFilePaths.map(path=>{
|
||||
i++;
|
||||
return {
|
||||
"id": 'temp_'+i,
|
||||
"group_id": 0,
|
||||
"user_id": 0,
|
||||
"url": path,
|
||||
"title": path,
|
||||
"progress": 0,
|
||||
"status": 0,
|
||||
};
|
||||
});
|
||||
_this.batchUpload();
|
||||
}
|
||||
});
|
||||
// uni.chooseMedia({
|
||||
// count: 9,
|
||||
// mediaType: ['image'],
|
||||
// sourceType: ['album', 'camera'],
|
||||
// success(res) {
|
||||
// console.log(res.tempFiles[0].tempFilePath)
|
||||
// }
|
||||
// })
|
||||
},
|
||||
async batchUpload(){
|
||||
if(!this.isAdmin){
|
||||
return ;
|
||||
}
|
||||
const _this = this;
|
||||
const lists = [].concat(this.fileList);
|
||||
let result = {};
|
||||
for (let i = 0; i < lists.length; i++) {
|
||||
result = await upload(lists[i].url,{
|
||||
savePath: "album" ,
|
||||
url:"/group/album_create",
|
||||
groupID:_this.param.groupID
|
||||
},(res)=>{
|
||||
try{
|
||||
_this.fileList[i].progress = res.progress;
|
||||
}catch(e){
|
||||
|
||||
}
|
||||
});
|
||||
console.log(result);
|
||||
if(result.code == 0){
|
||||
_this.fileList[i].status = 1;
|
||||
_this.list.unshift(result.data);
|
||||
}else{
|
||||
uni.$u.toast(data.msg);
|
||||
}
|
||||
}
|
||||
_this.fileList = [];
|
||||
}
|
||||
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.getList(true);
|
||||
},
|
||||
onReachBottom() {
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.group_album_page{
|
||||
.footer{
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 44px;
|
||||
background-color: #fff;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 20rpx;
|
||||
uni-button{
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 12rpx;
|
||||
padding-right: 12rpx;
|
||||
.item{
|
||||
position: relative;
|
||||
margin-bottom: 12rpx;
|
||||
margin-left: 12rpx;
|
||||
::v-deep .u-upload__button{
|
||||
margin: 0;
|
||||
}
|
||||
&.cancheck::after{
|
||||
content: " ";
|
||||
font-family: uicon-iconfont;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
background-color: rgb(255, 255, 255);
|
||||
border-color: rgb(200, 201, 204);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
&.cancheck.checked::after{
|
||||
content: "";
|
||||
background-color: rgb(41, 121, 255);
|
||||
border-color: rgb(41, 121, 255);
|
||||
color:#FFF;
|
||||
}
|
||||
.overlay{
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.u-line-progress{
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
top:50%;
|
||||
margin-top: -6px;
|
||||
width: 80%;
|
||||
left: 10%;
|
||||
}
|
||||
.pickfile{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #f6f6f6;
|
||||
width: 234rpx;
|
||||
height: 234rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -3,10 +3,12 @@
|
||||
<u-navbar :autoBack="true" bgColor="#ECECEC" title="群管理" safeAreaInsetTop placeholder fixed></u-navbar>
|
||||
<uni-list>
|
||||
<uni-list-item title="群主管理权转让" @click="toTransfer" showArrow clickable></uni-list-item>
|
||||
<uni-list-item title="设置管理员" @click="setAdmin" showArrow clickable></uni-list-item>
|
||||
<uni-list-item title="进群验证" @switchChange="updateGroupInfo('needVerification',storeCurrentGroup.needVerification==1 ? 2: 1)" showSwitch :switchChecked="!(storeCurrentGroup.needVerification != 1)"></uni-list-item>
|
||||
<uni-list-item title="允许查看成员资料" @switchChange="updateGroupInfo('lookMemberInfo',storeCurrentGroup.applyMemberFriend == 1 ? 0 : 1)" showSwitch :switchChecked="storeCurrentGroup.applyMemberFriend==0"></uni-list-item>
|
||||
<uni-list-item title="允许群内添加好友" @switchChange="updateGroupInfo('applyMemberFriend',storeCurrentGroup.applyMemberFriend == 1 ? 0 : 1)" showSwitch :switchChecked="storeCurrentGroup.applyMemberFriend==0"></uni-list-item>
|
||||
<uni-list-item :title="isMute ? '解除禁言':'全员禁言'" @switchChange="updateMute" showSwitch :switchChecked="isMute"></uni-list-item>
|
||||
<!-- <uni-list-item title="进群验证" :rightText="verifyTypeText" @click="changeVerify" clickable></uni-list-item> -->
|
||||
<uni-list-item title="允许查看成员资料" @switchChange="updateGroupInfo('lookMemberInfo',storeCurrentGroup.lookMemberInfo == 1 ? 0 : 1)" showSwitch :switchChecked="storeCurrentGroup.lookMemberInfo==0"></uni-list-item>
|
||||
<!-- <uni-list-item title="允许群内添加好友" @switchChange="updateGroupInfo('applyMemberFriend',storeCurrentGroup.applyMemberFriend == 1 ? 0 : 1)" showSwitch :switchChecked="storeCurrentGroup.applyMemberFriend==0"></uni-list-item> -->
|
||||
<uni-list-item title="全员禁言" @switchChange="updateMute" showSwitch :switchChecked="isMute"></uni-list-item>
|
||||
|
||||
</uni-list>
|
||||
</view>
|
||||
@@ -14,13 +16,7 @@
|
||||
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import IMSDK, {
|
||||
GroupMemberRole,
|
||||
GroupStatus,
|
||||
GroupVerificationType,
|
||||
IMMethods,
|
||||
MessageReceiveOptType,
|
||||
} from "openim-uniapp-polyfill";
|
||||
import IMSDK, {GroupMemberRole,GroupStatus,GroupVerificationType,IMMethods,MessageReceiveOptType,} from "openim-uniapp-polyfill";
|
||||
import {GroupMemberListTypes} from "@/constant";
|
||||
export default {
|
||||
data() {
|
||||
@@ -34,8 +30,19 @@
|
||||
"storeCurrentMemberInGroup",
|
||||
"storeCurrentGroup",
|
||||
]),
|
||||
verifyTypeText(){
|
||||
if(this.storeCurrentGroup.needVerification === 0){
|
||||
return '0'
|
||||
}
|
||||
if(this.storeCurrentGroup.needVerification === 1){
|
||||
return '1'
|
||||
}
|
||||
return '2';
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.isMute = this.storeCurrentGroup.status == 3;
|
||||
console.log(this.storeCurrentGroup);
|
||||
// IMSDK.asyncApi('getSpecifiedGroupsInfo', IMSDK.uuid(), [this.storeCurrentGroup.groupID]).then(res=>{
|
||||
// console.log(res);
|
||||
// }).catch(e=>{
|
||||
@@ -48,7 +55,13 @@
|
||||
url: `/pages/conversation/groupMemberList/index?type=${GroupMemberListTypes.Transfer}&groupID=${this.storeCurrentGroup.groupID}`,
|
||||
});
|
||||
},
|
||||
setAdmin(){
|
||||
uni.navigateTo({
|
||||
url: `/pages/conversation/groupMemberList/index?type=${GroupMemberListTypes.setAdmin}&groupID=${this.storeCurrentGroup.groupID}`,
|
||||
});
|
||||
},
|
||||
updateMute(){
|
||||
this.isMute = !this.isMute;
|
||||
IMSDK.asyncApi('changeGroupMute', IMSDK.uuid(), {
|
||||
groupID: this.storeCurrentGroup.groupID,
|
||||
isMute: this.isMute
|
||||
@@ -67,6 +80,18 @@
|
||||
console.log(e);
|
||||
})
|
||||
},
|
||||
changeVerify(){
|
||||
uni.showActionSheet({
|
||||
itemList:[
|
||||
'申请进群需要群主或管理员同意;群成员邀请可以直接进群',
|
||||
'申请进群需要群主或管理员同意;群主和管理员邀请可以直接进群;普通成员邀请进群需群主或管理员同意',
|
||||
'直接进群'
|
||||
],
|
||||
success(res){
|
||||
console.log(res);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,126 +1,128 @@
|
||||
<template>
|
||||
<custom-nav-bar @leftClick="leftClick" :title="getTitle">
|
||||
</custom-nav-bar>
|
||||
<custom-nav-bar @leftClick="leftClick" :title="getTitle">
|
||||
</custom-nav-bar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import { ContactChooseTypes } from "@/constant";
|
||||
export default {
|
||||
name: "",
|
||||
components: {
|
||||
CustomNavBar,
|
||||
},
|
||||
props: {
|
||||
checkVisible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isNomal: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isTransfer: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isAt: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isSetAdmin: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isMute: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isCall: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
groupID: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
moreMenuVisible: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getTitle() {
|
||||
if (this.isCall) {
|
||||
return "邀请成员";
|
||||
}
|
||||
if (this.isAt) {
|
||||
return "选择提醒的人";
|
||||
}
|
||||
if (this.isSetAdmin) {
|
||||
return "设置管理员";
|
||||
}
|
||||
if (this.isMute) {
|
||||
return "禁言成员";
|
||||
}
|
||||
if (this.checkVisible) {
|
||||
return "移除群成员";
|
||||
}
|
||||
return "群成员";
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
leftClick() {
|
||||
if (this.checkVisible) {
|
||||
this.$emit("update:checkVisible", false);
|
||||
}
|
||||
},
|
||||
rightClick() {
|
||||
this.moreMenuVisible = true;
|
||||
},
|
||||
checkMenu() {
|
||||
if (this.moreMenuVisible) {
|
||||
this.moreMenuVisible = false;
|
||||
}
|
||||
},
|
||||
inviteMember() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}`,
|
||||
});
|
||||
},
|
||||
removeMember() {
|
||||
this.$emit("removeMember");
|
||||
},
|
||||
},
|
||||
};
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import {
|
||||
ContactChooseTypes
|
||||
} from "@/constant";
|
||||
export default {
|
||||
name: "",
|
||||
components: {
|
||||
CustomNavBar,
|
||||
},
|
||||
props: {
|
||||
checkVisible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isNomal: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isTransfer: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isAt: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isSetAdmin: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isMute: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isCall: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
groupID: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
moreMenuVisible: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getTitle() {
|
||||
if (this.isCall) {
|
||||
return "邀请成员";
|
||||
}
|
||||
if (this.isAt) {
|
||||
return "选择提醒的人";
|
||||
}
|
||||
if (this.isSetAdmin) {
|
||||
return "设置管理员";
|
||||
}
|
||||
if (this.isMute) {
|
||||
return "禁言成员";
|
||||
}
|
||||
if (this.checkVisible) {
|
||||
return "移除群成员";
|
||||
}
|
||||
return "群成员";
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
leftClick() {
|
||||
if (this.checkVisible) {
|
||||
this.$emit("update:checkVisible", false);
|
||||
}
|
||||
},
|
||||
rightClick() {
|
||||
this.moreMenuVisible = true;
|
||||
},
|
||||
checkMenu() {
|
||||
if (this.moreMenuVisible) {
|
||||
this.moreMenuVisible = false;
|
||||
}
|
||||
},
|
||||
inviteMember() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}&allowType=User`,
|
||||
});
|
||||
},
|
||||
removeMember() {
|
||||
this.$emit("removeMember");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.more_container {
|
||||
position: relative;
|
||||
.more_container {
|
||||
position: relative;
|
||||
|
||||
.more_dot {
|
||||
padding: 24rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.more_dot {
|
||||
padding: 24rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.more_menu {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-100%, 100%);
|
||||
box-shadow: 0px 0px 6px 2px rgba(0, 0, 0, 0.16);
|
||||
width: max-content;
|
||||
border-radius: 8rpx;
|
||||
background-color: #fff;
|
||||
.more_menu {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-100%, 100%);
|
||||
box-shadow: 0px 0px 6px 2px rgba(0, 0, 0, 0.16);
|
||||
width: max-content;
|
||||
border-radius: 8rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.menu_item {
|
||||
padding: 20rpx 48rpx;
|
||||
font-size: 28rpx;
|
||||
color: $uni-text-color;
|
||||
.menu_item {
|
||||
padding: 20rpx 48rpx;
|
||||
font-size: 28rpx;
|
||||
color: $uni-text-color;
|
||||
|
||||
// &:nth-child(1) {
|
||||
// border-bottom: 1px solid #F0F0F0;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
// &:nth-child(1) {
|
||||
// border-bottom: 1px solid #F0F0F0;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,314 +1,475 @@
|
||||
<template>
|
||||
<view @click="pageClick" class="group_members_container">
|
||||
<group-member-list-header
|
||||
ref="navHeaderRef"
|
||||
:checkVisible.sync="showCheck"
|
||||
:isTransfer="isTransfer"
|
||||
:isNomal="!isOwner && !isAdmin"
|
||||
:groupID="groupID"
|
||||
@removeMember="showMemberCheck"
|
||||
/>
|
||||
<view @click="pageClick" class="group_members_container">
|
||||
<group-member-list-header
|
||||
ref="navHeaderRef"
|
||||
:checkVisible.sync="showCheck"
|
||||
:isTransfer="isTransfer"
|
||||
:isSetAdmin="isSetAdmin"
|
||||
:isNomal="!isOwner && !isAdmin"
|
||||
:groupID="groupID"
|
||||
@removeMember="showMemberCheck"
|
||||
/>
|
||||
|
||||
<view class="search_bar_wrap">
|
||||
<u-search
|
||||
disabled
|
||||
class="search_bar"
|
||||
shape="square"
|
||||
placeholder="搜索"
|
||||
:showAction="false"
|
||||
v-model="keyword"
|
||||
/>
|
||||
</view>
|
||||
<view class="search_bar_wrap">
|
||||
<u-search class="search_bar" shape="square" placeholder="搜索" :showAction="false"
|
||||
v-model="keyword" />
|
||||
</view>
|
||||
|
||||
<u-list
|
||||
class="member_list"
|
||||
@scrolltolower="loadMore"
|
||||
lowerThreshold="100"
|
||||
height="1"
|
||||
>
|
||||
<u-list-item v-for="member in groupMemberList" :key="member.userID">
|
||||
<user-item
|
||||
@itemClick="userClick"
|
||||
@updateCheck="updateCheck"
|
||||
:checked="isChecked(member.userID)"
|
||||
:checkVisible="showCheck"
|
||||
:disabled="!canCheck(member) && showCheck"
|
||||
:item="member"
|
||||
/>
|
||||
</u-list-item>
|
||||
<view
|
||||
v-show="loadState.loading"
|
||||
class="member_loading"
|
||||
>
|
||||
<u-loading-icon></u-loading-icon>
|
||||
</view>
|
||||
</u-list>
|
||||
<u-list class="member_list" @scrolltolower="loadMore" lowerThreshold="100" height="1">
|
||||
<u-list-item v-for="member in filterGroupMemberList" :key="member.userID">
|
||||
<user-item
|
||||
@itemClick="userClick"
|
||||
@updateCheck="updateCheck"
|
||||
@longtapEvent="longtap"
|
||||
:checked="isChecked(member.userID)"
|
||||
:checkVisible="showCheck"
|
||||
:disabled="!canCheck(member) && showCheck" :item="member"
|
||||
/>
|
||||
</u-list-item>
|
||||
<view v-show="loadState.loading" class="member_loading">
|
||||
<u-loading-icon></u-loading-icon>
|
||||
</view>
|
||||
</u-list>
|
||||
<template v-if="showCheck" >
|
||||
<choose-index-footer
|
||||
:comfirmLoading="comfirmLoading"
|
||||
@removeItem="updateCheck"
|
||||
@confirm="confirm"
|
||||
:choosedData="getChoosedData"
|
||||
:isRemove="isRemove"
|
||||
:maxLength="groupMemberLength" />
|
||||
</template>
|
||||
|
||||
<choose-index-footer
|
||||
v-if="showCheck"
|
||||
:comfirmLoading="comfirmLoading"
|
||||
@removeItem="updateCheck"
|
||||
@confirm="confirm"
|
||||
:choosedData="getChoosedData"
|
||||
:isRemove="isRemove"
|
||||
:maxLength="groupMemberLength"
|
||||
/>
|
||||
|
||||
<u-modal
|
||||
:show="showConfirmModal"
|
||||
asyncClose
|
||||
showCancelButton
|
||||
@confirm="modalConfirm"
|
||||
@cancel="() => (showConfirmModal = false)"
|
||||
:content="
|
||||
isRemove
|
||||
? '确定移除已选群成员?'
|
||||
: `确定要把群主转移给${choosedTransferMember.nickname}吗?`
|
||||
"
|
||||
/>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
<u-modal
|
||||
:show="showConfirmModal"
|
||||
asyncClose
|
||||
showCancelButton
|
||||
@confirm="modalConfirm"
|
||||
@cancel="() => (showConfirmModal = false)" :content="isRemove? '确定移除已选群成员?': `确定要把群主转移给${choosedTransferMember.nickname}吗?`
|
||||
" />
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let moreActionArea;
|
||||
import { GroupMemberListTypes } from "@/constant";
|
||||
import IMSDK, { GroupMemberRole } from "openim-uniapp-polyfill";
|
||||
import UserItem from "@/components/UserItem/index.vue";
|
||||
import GroupMemberListHeader from "./components/GroupMemberListHeader.vue";
|
||||
import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue";
|
||||
export default {
|
||||
components: {
|
||||
GroupMemberListHeader,
|
||||
ChooseIndexFooter,
|
||||
UserItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showCheck: false,
|
||||
groupID: "",
|
||||
keyword: "",
|
||||
showConfirmModal: false,
|
||||
comfirmLoading: false,
|
||||
groupMemberList: [],
|
||||
choosedMemberIDList: [],
|
||||
choosedTransferMember: {},
|
||||
type: GroupMemberListTypes.Preview,
|
||||
isRightKick: true,
|
||||
loadState: {
|
||||
hasMore: true,
|
||||
loading: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getChoosedData() {
|
||||
const tmpList = [...this.choosedMemberIDList];
|
||||
return this.groupMemberList.filter(
|
||||
(member) => {
|
||||
const idx = tmpList.findIndex((item) => item === member.userID);
|
||||
if (idx > -1) {
|
||||
tmpList.splice(idx, 1);
|
||||
}
|
||||
return idx > -1;
|
||||
},
|
||||
);
|
||||
},
|
||||
isRemove() {
|
||||
return this.type === GroupMemberListTypes.Kickout;
|
||||
},
|
||||
isTransfer() {
|
||||
return this.type === GroupMemberListTypes.Transfer;
|
||||
},
|
||||
isChecked() {
|
||||
return (userID) => this.choosedMemberIDList.includes(userID);
|
||||
},
|
||||
isOwner() {
|
||||
return (
|
||||
this.$store.getters.storeCurrentMemberInGroup.roleLevel ===
|
||||
GroupMemberRole.Owner
|
||||
);
|
||||
},
|
||||
isAdmin() {
|
||||
return (
|
||||
this.$store.getters.storeCurrentMemberInGroup.roleLevel ===
|
||||
GroupMemberRole.Admin
|
||||
);
|
||||
},
|
||||
canCheck() {
|
||||
return ({ roleLevel, userID }) => {
|
||||
if (this.type === GroupMemberListTypes.Kickout) {
|
||||
return (
|
||||
(this.isOwner ||
|
||||
(this.isAdmin && roleLevel !== GroupMemberRole.Owner)) &&
|
||||
userID !== this.$store.getters.storeCurrentUserID
|
||||
);
|
||||
}
|
||||
let moreActionArea;
|
||||
import {mapActions,mapGetters} from "vuex";
|
||||
import {GroupMemberListTypes} from "@/constant";
|
||||
import IMSDK, {GroupMemberRole} from "openim-uniapp-polyfill";
|
||||
import UserItem from "@/components/UserItem/index.vue";
|
||||
import GroupMemberListHeader from "./components/GroupMemberListHeader.vue";
|
||||
import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
components: {
|
||||
GroupMemberListHeader,
|
||||
ChooseIndexFooter,
|
||||
UserItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showCheck: false,
|
||||
groupID: "",
|
||||
keyword: "",
|
||||
showConfirmModal: false,
|
||||
comfirmLoading: false,
|
||||
groupMemberList: [],
|
||||
filterGroupMemberList:[],
|
||||
choosedMemberIDList: [],
|
||||
choosedTransferMember: {},
|
||||
type: GroupMemberListTypes.Preview,
|
||||
isRightKick: true,
|
||||
loadState: {
|
||||
hasMore: true,
|
||||
loading: false,
|
||||
},
|
||||
adminUserIdList:[]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'storeCurrentUserID',
|
||||
'storeCurrentGroup',
|
||||
"storeCurrentMemberInGroup"
|
||||
]),
|
||||
getChoosedData() {
|
||||
const tmpList = [...this.choosedMemberIDList];
|
||||
return this.groupMemberList.filter(
|
||||
(member) => {
|
||||
const idx = tmpList.findIndex((item) => item === member.userID);
|
||||
if (idx > -1) {
|
||||
tmpList.splice(idx, 1);
|
||||
}
|
||||
return idx > -1;
|
||||
},
|
||||
);
|
||||
},
|
||||
isRemove() {
|
||||
return this.type === GroupMemberListTypes.Kickout;
|
||||
},
|
||||
isTransfer() {
|
||||
return this.type === GroupMemberListTypes.Transfer;
|
||||
},
|
||||
isSetAdmin() {
|
||||
return this.type === GroupMemberListTypes.setAdmin;
|
||||
},
|
||||
isChecked() {
|
||||
return (userID) => this.choosedMemberIDList.includes(userID);
|
||||
},
|
||||
isOwner() {
|
||||
return (
|
||||
this.storeCurrentMemberInGroup.roleLevel ===
|
||||
GroupMemberRole.Owner
|
||||
);
|
||||
},
|
||||
isAdmin() {
|
||||
return (
|
||||
this.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Admin
|
||||
);
|
||||
},
|
||||
canCheck() {
|
||||
return ({
|
||||
roleLevel,
|
||||
userID
|
||||
}) => {
|
||||
if (this.type === GroupMemberListTypes.Kickout) {
|
||||
return (
|
||||
(this.isOwner || (this.isAdmin && roleLevel !== GroupMemberRole.Owner)) &&
|
||||
userID !== this.$store.storeCurrentUserID
|
||||
);
|
||||
}
|
||||
|
||||
return userID !== this.$store.getters.storeCurrentUserID;
|
||||
};
|
||||
},
|
||||
groupMemberLength() {
|
||||
return this.$store.getters.storeCurrentGroup?.memberCount ?? 0;
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const { groupID, type } = options;
|
||||
this.loadMemberList(groupID);
|
||||
this.type = type;
|
||||
this.groupID = groupID;
|
||||
this.isRightKick = type === GroupMemberListTypes.Kickout;
|
||||
if (
|
||||
this.isRightKick
|
||||
) {
|
||||
this.showCheck = true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async pageClick(e) {
|
||||
if (!moreActionArea) {
|
||||
moreActionArea = await this.getEl(".more_container");
|
||||
}
|
||||
if (!moreActionArea) return;
|
||||
if (
|
||||
e.target.y < moreActionArea.top ||
|
||||
e.target.y > moreActionArea.bottom ||
|
||||
e.target.x < moreActionArea.left
|
||||
) {
|
||||
this.$refs.navHeaderRef.checkMenu();
|
||||
}
|
||||
},
|
||||
confirm() {
|
||||
this.showConfirmModal = true;
|
||||
},
|
||||
modalConfirm() {
|
||||
let func = () => {};
|
||||
if (this.type === GroupMemberListTypes.Kickout) {
|
||||
func = IMSDK.asyncApi(IMSDK.IMMethods.KickGroupMember, IMSDK.uuid(), {
|
||||
groupID: this.getChoosedData[0].groupID,
|
||||
reason: "",
|
||||
userIDList: this.getChoosedData.map((member) => member.userID),
|
||||
});
|
||||
} else {
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.TransferGroupOwner,
|
||||
IMSDK.uuid(),
|
||||
{
|
||||
groupID: this.choosedTransferMember.groupID,
|
||||
newOwnerUserID: this.choosedTransferMember.userID,
|
||||
},
|
||||
);
|
||||
}
|
||||
func
|
||||
.then(() => this.showToast("操作成功", () => uni.navigateBack()))
|
||||
.catch(() => this.showToast("操作失败"))
|
||||
.finally(() => (this.showConfirmModal = false));
|
||||
},
|
||||
updateChoosedData(userID) {
|
||||
if (this.choosedMemberIDList.includes(userID)) {
|
||||
const idx = this.choosedMemberIDList.findIndex(
|
||||
(item) => item === userID,
|
||||
);
|
||||
const tmpArr = [...this.choosedMemberIDList];
|
||||
tmpArr.splice(idx, 1);
|
||||
this.choosedMemberIDList = tmpArr;
|
||||
} else {
|
||||
this.choosedMemberIDList = [...this.choosedMemberIDList, userID];
|
||||
}
|
||||
console.log(this.choosedMemberIDList);
|
||||
},
|
||||
userClick(member) {
|
||||
if (this.type === GroupMemberListTypes.Transfer) {
|
||||
if (member.userID === this.$store.getters.storeCurrentUserID) return;
|
||||
this.choosedTransferMember = member;
|
||||
this.showConfirmModal = true;
|
||||
} else {
|
||||
uni.$u.route("/pages/common/userCard/index", {
|
||||
sourceID: member.userID,
|
||||
memberInfo: JSON.stringify(member),
|
||||
});
|
||||
}
|
||||
},
|
||||
updateCheck(member) {
|
||||
this.updateChoosedData(member.userID);
|
||||
},
|
||||
showMemberCheck() {
|
||||
this.type = GroupMemberListTypes.Kickout;
|
||||
this.showCheck = true;
|
||||
},
|
||||
loadMore() {
|
||||
const stateKey = "loadState";
|
||||
const methodKey = "loadMemberList";
|
||||
if (this[stateKey].hasMore && !this[stateKey].loading) {
|
||||
this[methodKey]();
|
||||
}
|
||||
},
|
||||
loadMemberList(groupID) {
|
||||
this.loadState.loading = true;
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.GetGroupMemberList, IMSDK.uuid(), {
|
||||
groupID: groupID ?? this.groupID,
|
||||
filter: 0,
|
||||
offset: this.groupMemberList.length,
|
||||
count: 500,
|
||||
})
|
||||
.then(({ data }) => {
|
||||
this.groupMemberList = [...this.groupMemberList, ...data];
|
||||
this.loadState.hasMore = data.length === 500;
|
||||
})
|
||||
.finally(() => (this.loadState.loading = false));
|
||||
},
|
||||
showToast(message, complete = null) {
|
||||
this.$refs.uToast.show({
|
||||
message,
|
||||
complete,
|
||||
});
|
||||
},
|
||||
getEl(el) {
|
||||
return new Promise((resolve) => {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query
|
||||
.select(el)
|
||||
.boundingClientRect((data) => {
|
||||
// 存在data,且存在宽和高,视为渲染完毕
|
||||
resolve(data);
|
||||
})
|
||||
.exec();
|
||||
});
|
||||
},
|
||||
},
|
||||
onBackPress(options) {
|
||||
if (this.showCheck && this.isRightKick) {
|
||||
this.showCheck = false;
|
||||
this.type = GroupMemberListTypes.Preview;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
};
|
||||
return userID !== this.$store.storeCurrentUserID;
|
||||
};
|
||||
},
|
||||
groupMemberLength() {
|
||||
return this.storeCurrentGroup?.memberCount ?? 0;
|
||||
},
|
||||
|
||||
},
|
||||
watch:{
|
||||
keyword(v){
|
||||
this.filterGroupMemberList = this.getFilterGroupMemberList();
|
||||
},
|
||||
groupMemberList(v){
|
||||
this.filterGroupMemberList = this.getFilterGroupMemberList();
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const {
|
||||
groupID,
|
||||
type
|
||||
} = options;
|
||||
this.loadMemberList(groupID);
|
||||
this.type = type;
|
||||
this.groupID = groupID;
|
||||
this.isRightKick = (type == GroupMemberListTypes.setAdmin|| type === GroupMemberListTypes.Kickout);
|
||||
if (this.isRightKick) {
|
||||
this.showCheck = true;
|
||||
}
|
||||
if(type == GroupMemberListTypes.setAdmin){
|
||||
IMSDK.asyncApi('getGroupMemberOwnerAndAdmin', IMSDK.uuid(), this.groupID).then(({data}) => {
|
||||
let arr = [];
|
||||
data.forEach((item)=>{
|
||||
if(item.roleLevel == GroupMemberRole.Admin){
|
||||
arr.push(item.userID);
|
||||
}
|
||||
});
|
||||
this.adminUserIdList = arr;
|
||||
this.choosedMemberIDList = arr;
|
||||
console.log(arr);
|
||||
// 调用成功
|
||||
})
|
||||
.catch(({ errCode, errMsg }) => {
|
||||
console.log(errCode, errMsg );
|
||||
// 调用失败
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
getFilterGroupMemberList(){
|
||||
if(this.keyword){
|
||||
return this.groupMemberList.filter((item)=>{
|
||||
const kw = this.keyword.toLowerCase();
|
||||
if(item.nickname && item.nickname.toLowerCase().includes(kw)){
|
||||
return true;
|
||||
}
|
||||
if(item.showName && item.showName.toLowerCase().includes(kw)){
|
||||
return true;
|
||||
}
|
||||
if(item.remark && item.remark.toLowerCase().includes(kw)){
|
||||
return true;
|
||||
}
|
||||
if(item.groupName && item.groupName.toLowerCase().includes(kw)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return this.groupMemberList;
|
||||
},
|
||||
async pageClick(e) {
|
||||
if (!moreActionArea) {
|
||||
moreActionArea = await this.getEl(".more_container");
|
||||
}
|
||||
if (!moreActionArea) return;
|
||||
if (
|
||||
e.target.y < moreActionArea.top ||
|
||||
e.target.y > moreActionArea.bottom ||
|
||||
e.target.x < moreActionArea.left
|
||||
) {
|
||||
this.$refs.navHeaderRef.checkMenu();
|
||||
}
|
||||
},
|
||||
async confirm() {
|
||||
if(this.isSetAdmin){
|
||||
uni.showLoading({mask:true})
|
||||
const remveUserIds = this.adminUserIdList.filter(userID=>{
|
||||
return !this.choosedMemberIDList.includes(userID);
|
||||
});
|
||||
const addUserIds = this.choosedMemberIDList.filter(userID=>{
|
||||
return !this.adminUserIdList.includes(userID);
|
||||
});
|
||||
remveUserIds.forEach(async (userID)=>{
|
||||
await IMSDK.asyncApi(IMSDK.IMMethods.SetGroupMemberInfo,IMSDK.uuid(),{
|
||||
roleLevel:GroupMemberRole.Normal,
|
||||
groupID:this.groupID,
|
||||
userID:userID
|
||||
});
|
||||
})
|
||||
addUserIds.forEach(async (userID)=>{
|
||||
await IMSDK.asyncApi(IMSDK.IMMethods.SetGroupMemberInfo,IMSDK.uuid(),{
|
||||
roleLevel:GroupMemberRole.Admin,
|
||||
groupID:this.groupID,
|
||||
userID:userID
|
||||
});
|
||||
})
|
||||
uni.hideLoading();
|
||||
this.groupMemberList = [];
|
||||
this.loadMemberList(this.groupID);
|
||||
uni.navigateBack();
|
||||
}else{
|
||||
this.showConfirmModal = true;
|
||||
}
|
||||
},
|
||||
modalConfirm() {
|
||||
let func = () => {};
|
||||
if (this.type === GroupMemberListTypes.Kickout) {
|
||||
func = IMSDK.asyncApi(IMSDK.IMMethods.KickGroupMember, IMSDK.uuid(), {
|
||||
groupID: this.getChoosedData[0].groupID,
|
||||
reason: "",
|
||||
userIDList: this.getChoosedData.map((member) => member.userID),
|
||||
});
|
||||
} else {
|
||||
func = IMSDK.asyncApi(
|
||||
IMSDK.IMMethods.TransferGroupOwner,
|
||||
IMSDK.uuid(), {
|
||||
groupID: this.choosedTransferMember.groupID,
|
||||
newOwnerUserID: this.choosedTransferMember.userID,
|
||||
},
|
||||
);
|
||||
}
|
||||
func
|
||||
.then(() => this.showToast("操作成功", () => uni.navigateBack()))
|
||||
.catch(() => this.showToast("操作失败"))
|
||||
.finally(() => (this.showConfirmModal = false));
|
||||
},
|
||||
updateChoosedData(userID) {
|
||||
if (this.choosedMemberIDList.includes(userID)) {
|
||||
const idx = this.choosedMemberIDList.findIndex(
|
||||
(item) => item === userID,
|
||||
);
|
||||
const tmpArr = [...this.choosedMemberIDList];
|
||||
tmpArr.splice(idx, 1);
|
||||
this.choosedMemberIDList = tmpArr;
|
||||
} else {
|
||||
this.choosedMemberIDList = [...this.choosedMemberIDList, userID];
|
||||
}
|
||||
},
|
||||
userClick(member) {
|
||||
if (this.type === GroupMemberListTypes.Transfer) {
|
||||
if (member.userID === this.storeCurrentUserID) return;
|
||||
this.choosedTransferMember = member;
|
||||
this.showConfirmModal = true;
|
||||
} else {
|
||||
if(member.userID == this.storeCurrentUserID){
|
||||
return ;
|
||||
}
|
||||
if(this.storeCurrentMemberInGroup.roleLevel < 60 && this.storeCurrentGroup.lookMemberInfo!=0){
|
||||
return ;
|
||||
}
|
||||
const s = util.aesencode(member);
|
||||
uni.$u.route("/pages/common/userCard/index", {
|
||||
sourceID: member.userID,
|
||||
memberInfo: s,
|
||||
});
|
||||
}
|
||||
},
|
||||
updateCheck(member) {
|
||||
this.updateChoosedData(member.userID);
|
||||
},
|
||||
showMemberCheck() {
|
||||
this.type = GroupMemberListTypes.Kickout;
|
||||
this.showCheck = true;
|
||||
},
|
||||
loadMore() {
|
||||
const stateKey = "loadState";
|
||||
const methodKey = "loadMemberList";
|
||||
if (this[stateKey].hasMore && !this[stateKey].loading) {
|
||||
this[methodKey]();
|
||||
}
|
||||
},
|
||||
loadMemberList(groupID) {
|
||||
this.loadState.loading = true;
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.GetGroupMemberList, IMSDK.uuid(), {
|
||||
groupID: groupID ?? this.groupID,
|
||||
filter: 0,
|
||||
offset: this.groupMemberList.length,
|
||||
count: 500,
|
||||
})
|
||||
.then(({
|
||||
data
|
||||
}) => {
|
||||
this.groupMemberList = [...this.groupMemberList, ...data];
|
||||
this.filterGroupMemberList = this.getFilterGroupMemberList();
|
||||
this.loadState.hasMore = data.length === 500;
|
||||
})
|
||||
.finally(() => (this.loadState.loading = false));
|
||||
},
|
||||
longtap(member){
|
||||
const _this = this;
|
||||
if(this.isRightKick){
|
||||
return ;
|
||||
}
|
||||
if(!this.isOwner&&!this.isAdmin){
|
||||
return ;
|
||||
}
|
||||
if(this.storeCurrentMemberInGroup.roleLevel <= member.roleLevel ){
|
||||
return ;
|
||||
}
|
||||
let itemList = [];
|
||||
if(this.isOwner){
|
||||
itemList.push(member.roleLevel == GroupMemberRole.Admin ? '取消管理员' : '设为管理员');
|
||||
}
|
||||
if(this.isOwner || this.isAdmin){
|
||||
itemList.push(member.muteEndTime > 0 ? '取消禁言':'设置禁言');
|
||||
itemList.push('踢出群聊');
|
||||
}
|
||||
uni.showActionSheet({
|
||||
itemList:itemList,
|
||||
async success({tapIndex}) {
|
||||
const label = itemList[tapIndex];
|
||||
if(['设为管理员','取消管理员'].includes(label)){
|
||||
let roleId = label=='设为管理员' ? GroupMemberRole.Admin : GroupMemberRole.Normal;
|
||||
|
||||
await IMSDK.asyncApi(IMSDK.IMMethods.SetGroupMemberInfo,IMSDK.uuid(),{
|
||||
roleLevel:roleId,
|
||||
groupID:_this.groupID,
|
||||
userID:member.userID
|
||||
});
|
||||
_this.groupMemberList = _this.groupMemberList.map((item)=>{
|
||||
if(item.userID == member.userID){
|
||||
item.roleLevel = roleId
|
||||
}
|
||||
return item;
|
||||
});
|
||||
return ;
|
||||
}
|
||||
if(['取消禁言','设置禁言'].includes(label)){
|
||||
if(label == '取消禁言'){
|
||||
_this.setMute(member.userID,0)
|
||||
return ;
|
||||
}
|
||||
uni.showActionSheet({
|
||||
itemList:['2小时','8小时','1天','3天','7天','15天','30天','1年'],
|
||||
success(res){
|
||||
const secs = [3600*2,3600*8,3600*24,3600*72,3600*24*7,3600*24*15,3600*24*30,3600*24*365];
|
||||
_this.setMute(member.userID,secs[res.tapIndex])
|
||||
}
|
||||
});
|
||||
return ;
|
||||
}
|
||||
if(label=="踢出群聊"){
|
||||
await IMSDK.asyncApi(IMSDK.IMMethods.KickGroupMember,IMSDK.uuid(),{
|
||||
groupID:_this.groupID,
|
||||
reason:"",
|
||||
userIDList:[member.userID]
|
||||
});
|
||||
_this.groupMemberList = _this.groupMemberList.filter((item)=>{
|
||||
return item.userID != member.userID;
|
||||
});
|
||||
return ;
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
async setMute(userID,mutedSeconds){
|
||||
const _this = this;
|
||||
await IMSDK.asyncApi(IMSDK.IMMethods.ChangeGroupMemberMute,IMSDK.uuid(),{
|
||||
mutedSeconds:mutedSeconds,
|
||||
groupID:_this.groupID,
|
||||
userID:userID
|
||||
});
|
||||
this.groupMemberList = this.groupMemberList.map((item)=>{
|
||||
if(item.userID == userID){
|
||||
item.muteEndTime = mutedSeconds===0 ? 0 : (new Date().getTime())+mutedSeconds*1000
|
||||
}
|
||||
return item;
|
||||
});
|
||||
},
|
||||
showToast(message, complete = null) {
|
||||
this.$refs.uToast.show({
|
||||
message,
|
||||
complete,
|
||||
});
|
||||
},
|
||||
getEl(el) {
|
||||
return new Promise((resolve) => {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query
|
||||
.select(el)
|
||||
.boundingClientRect((data) => {
|
||||
// 存在data,且存在宽和高,视为渲染完毕
|
||||
resolve(data);
|
||||
})
|
||||
.exec();
|
||||
});
|
||||
},
|
||||
},
|
||||
onBackPress(options) {
|
||||
if (this.showCheck && this.isRightKick) {
|
||||
this.showCheck = false;
|
||||
this.type = GroupMemberListTypes.Preview;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.group_members_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
.group_members_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
|
||||
.search_bar_wrap {
|
||||
height: 34px;
|
||||
padding: 12px 22px;
|
||||
}
|
||||
.search_bar_wrap {
|
||||
height: 34px;
|
||||
padding: 12px 22px;
|
||||
}
|
||||
|
||||
.at_all_btn {
|
||||
font-weight: 500;
|
||||
padding: 24rpx 44rpx;
|
||||
}
|
||||
.at_all_btn {
|
||||
font-weight: 500;
|
||||
padding: 24rpx 44rpx;
|
||||
}
|
||||
|
||||
::v-deep.u-popup {
|
||||
flex: none;
|
||||
}
|
||||
::v-deep.u-popup {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.member_list {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
.member_list {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,17 +1,29 @@
|
||||
<template>
|
||||
<view style="display: flex;flex-direction: column;width: 100vw;height: 100vh;">
|
||||
<view>
|
||||
<u-navbar
|
||||
:autoBack="true"
|
||||
title="群公告"
|
||||
safeAreaInsetTop
|
||||
placeholder
|
||||
fixed
|
||||
:autoBack="true"
|
||||
>
|
||||
<view class="u-nav-slot" slot="right" v-if="isOwner || isAdmin">
|
||||
<u-button type="primary" size="mini" @click="save">确定</u-button>
|
||||
<u-button type="primary" @click="save">保存</u-button>
|
||||
</view>
|
||||
</u-navbar>
|
||||
<u--textarea :disabled="!isOwner && !isAdmin" count confirmType="done" focus autoHeight maxlength="-1" border="none" v-model="announcement"></u--textarea >
|
||||
<u-parse v-if="!isOwner && !isAdmin" :content="announcement"></u-parse>
|
||||
<u--textarea v-else
|
||||
count
|
||||
confirmType="done"
|
||||
focus
|
||||
autoHeight
|
||||
height="500"
|
||||
maxlength="1500"
|
||||
border="none"
|
||||
:adjustPosition="false"
|
||||
class="textarea"
|
||||
placeholder="暂无公告"
|
||||
v-model="announcement"
|
||||
>
|
||||
</u--textarea>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -38,14 +50,14 @@
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.announcement = this.storeCurrentGroup.notification;
|
||||
this.announcement = this.storeCurrentGroup.notification;
|
||||
},
|
||||
methods: {
|
||||
back(){
|
||||
uni.navigateBack();
|
||||
},
|
||||
save(){
|
||||
if(!isOwner && !isAdmin){
|
||||
if(!this.isOwner && !this.isAdmin){
|
||||
return ;
|
||||
}
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.SetGroupInfo, IMSDK.uuid(), {
|
||||
@@ -62,6 +74,12 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.textarea{
|
||||
}
|
||||
.u-nav-slot{
|
||||
.u-button{
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -11,6 +11,7 @@
|
||||
<view class="member_item" v-for="(member, index) in groupMemberList" :key="member.userID">
|
||||
<my-avatar :src="member.faceURL" :desc="member.nickname" :key="member.userID" size="48" />
|
||||
<view class="ower" v-if="member.roleLevel === 100">群主</view>
|
||||
<view class="ower" v-if="member.roleLevel === 60">管理员</view>
|
||||
<text class="member_item_name">{{ member.nickname }}</text>
|
||||
</view>
|
||||
<view class="member_item">
|
||||
@@ -75,7 +76,7 @@
|
||||
},
|
||||
inviteMember() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/common/contactChoose/choose?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}`,
|
||||
url: `/pages/common/contactChoose/choose?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}&allowType=User`,
|
||||
});
|
||||
},
|
||||
kickMember() {
|
||||
|
||||
@@ -3,35 +3,26 @@
|
||||
<u-navbar :autoBack="true" bgColor="#ECECEC" :title="'群聊设置('+storeCurrentGroup.memberCount+')'" safeAreaInsetTop placeholder fixed></u-navbar>
|
||||
|
||||
<view class="group_settings_content">
|
||||
<view class="setting_row info_row" v-if="1==2">
|
||||
<view class="group_avatar" @click="updateGroupAvatar">
|
||||
<my-avatar :src="storeCurrentConversation.faceURL" :isGroup="true" size="46" />
|
||||
<image v-if="isOwner" class="edit_icon" src="@/static/images/group_setting_edit.png" alt="" />
|
||||
</view>
|
||||
<view class="group_info">
|
||||
<view class="group_info_name">
|
||||
<text class="group_name">{{ storeCurrentConversation.showName }}({{storeCurrentGroup.memberCount}})</text>
|
||||
<image v-if="isOwner || isAdmin" @click="toUpdateGroupName" style="width: 24rpx; height: 24rpx" src="@/static/images/group_edit.png" alt="" />
|
||||
</view>
|
||||
|
||||
<text @click="copyGroupID" class="sub_title">{{storeCurrentConversation.groupID}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<group-member-row v-if="isJoinGroup" :isNomal="!isAdmin && !isOwner"
|
||||
:groupID="storeCurrentConversation.groupID" :memberCount="storeCurrentGroup.memberCount"
|
||||
:groupMemberList="groupMemberList" />
|
||||
|
||||
<uni-list>
|
||||
<uni-list-item title="群聊名称" :rightText="storeCurrentConversation.showName" @click="editGroupName" :clickable="isOwner || isAdmin" :showArrow="isOwner || isAdmin"></uni-list-item>
|
||||
<uni-list-item title="群图标" @click="updateGroupAvatar" clickable showArrow>
|
||||
<template v-slot:footer>
|
||||
<my-avatar :src="storeCurrentConversation.faceURL" :isGroup="true" size="46" />
|
||||
</template>
|
||||
</uni-list-item>
|
||||
<uni-list-item title="群名称" :rightText="storeCurrentConversation.showName" @click="editGroupName" :clickable="isOwner || isAdmin" :showArrow="isOwner || isAdmin"></uni-list-item>
|
||||
<uni-list-item title="群公告" to="/pages/conversation/groupSettings/announcement" clickable showArrow></uni-list-item>
|
||||
<uni-list-item title="群二维码" :to="'/pages/common/userOrGroupQrCode?groupID='+storeCurrentConversation.groupID" clickable showArrow></uni-list-item>
|
||||
<uni-list-item title="群二维码" :to="getGroupQrcdeUrl" clickable showArrow></uni-list-item>
|
||||
<uni-list-item v-if="isOwner || isAdmin" title="群管理" to="/pages/conversation/groupManage/index" clickable showArrow></uni-list-item>
|
||||
<uni-list-item v-if="1==2" title="备注" :rightText="storeCurrentConversation.showName" @click="editGroupName" :clickable="isOwner || isAdmin" :showArrow="isOwner || isAdmin"></uni-list-item>
|
||||
</uni-list>
|
||||
<u-gap></u-gap>
|
||||
<uni-list>
|
||||
<uni-list-item title="查找聊天内容" to=""></uni-list-item>
|
||||
<uni-list-item title="群相册" :to="'/pages/conversation/groupAlbum/groupAlbum?groupID='+storeCurrentConversation.groupID" showArrow></uni-list-item>
|
||||
<uni-list-item title="查找聊天内容" :to="'/pages/common/search/index?type=conversation&conversationID='+storeCurrentConversation.conversationID" showArrow></uni-list-item>
|
||||
</uni-list>
|
||||
<u-gap></u-gap>
|
||||
<uni-list>
|
||||
@@ -56,24 +47,21 @@
|
||||
</view>
|
||||
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
<c-cut-avatar ref="cutAvatar" @save="saveAvatar" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import {GroupMemberListTypes} from "@/constant";
|
||||
import IMSDK, {
|
||||
GroupMemberRole,
|
||||
GroupStatus,
|
||||
GroupVerificationType,
|
||||
IMMethods,
|
||||
MessageReceiveOptType,
|
||||
} from "openim-uniapp-polyfill";
|
||||
import IMSDK, {GroupMemberRole,GroupStatus,GroupVerificationType,IMMethods,MessageReceiveOptType,} from "openim-uniapp-polyfill";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import SettingItem from "@/components/SettingItem/index.vue";
|
||||
import GroupMemberRow from "./components/GroupMemberRow.vue";
|
||||
import {getPurePath} from "@/util/common";
|
||||
import util from "@/util/index.js"
|
||||
import {upload} from "@/api/login.js";
|
||||
|
||||
const ConfirmTypes = {
|
||||
Dismiss: "Dismiss",
|
||||
@@ -100,7 +88,7 @@
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
console.log(this.storeCurrentConversation);
|
||||
//console.log(this.storeCurrentConversation);
|
||||
/*
|
||||
this.$store.commit("conversation/SET_CURRENT_CONVERSATION", {
|
||||
"conversationID": "sg_1793688611",
|
||||
@@ -192,6 +180,15 @@
|
||||
isAdmin() {
|
||||
return this.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Admin;
|
||||
},
|
||||
getGroupQrcdeUrl(){
|
||||
const info = util.aesencode({
|
||||
code : this.storeCurrentConversation.groupID,
|
||||
showName: `${this.storeCurrentConversation.showName}(${this.storeCurrentGroup.memberCount})`,
|
||||
faceURL : this.storeCurrentConversation.faceURL,
|
||||
type : "group",
|
||||
});
|
||||
return `/pages/common/userOrGroupQrCode?sourceInfo=${info}`;
|
||||
},
|
||||
getGroupVerStr() {
|
||||
if (
|
||||
this.storeCurrentGroup.needVerification ===
|
||||
@@ -210,6 +207,8 @@
|
||||
return this.storeCurrentGroup.status === GroupStatus.Muted;
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
},
|
||||
methods: {
|
||||
editGroupName(){
|
||||
if(this.isOwner || this.isAdmin){
|
||||
@@ -242,9 +241,9 @@
|
||||
if (!this.isAdmin && !this.isOwner) {
|
||||
return;
|
||||
}
|
||||
|
||||
const s = util.aesencode(this.storeCurrentGroup);
|
||||
uni.navigateTo({
|
||||
url: `/pages/conversation/updateGroupOrNickname/index?sourceInfo=${JSON.stringify(this.storeCurrentGroup,)}`,
|
||||
url: `/pages/conversation/updateGroupOrNickname/index?sourceInfo=${s}`,
|
||||
});
|
||||
},
|
||||
copyGroupID() {
|
||||
@@ -276,6 +275,22 @@
|
||||
console.log(e);
|
||||
})
|
||||
},
|
||||
saveAvatar(e){
|
||||
if (!this.isAdmin && !this.isOwner) {
|
||||
return;
|
||||
}
|
||||
this.tempFilePath = e.path;
|
||||
upload(e.path,{
|
||||
'url':"/group/avatar",
|
||||
savePath: "groupavatar",
|
||||
groupID: this.storeCurrentConversation.groupID,
|
||||
}).then((res) => {
|
||||
console.log("上传成功",res);
|
||||
//userStore.selfInfo.faceURL = res.data.faceURL;
|
||||
}).catch((res1) => {
|
||||
console.log("上传失败",res1);
|
||||
});
|
||||
},
|
||||
updateGroupAvatar() {
|
||||
if (!this.isAdmin && !this.isOwner) {
|
||||
return;
|
||||
@@ -288,6 +303,8 @@
|
||||
tempFilePaths
|
||||
}) => {
|
||||
const path = tempFilePaths[0];
|
||||
this.$refs.cutAvatar.enterEditor(path);
|
||||
return ;
|
||||
const nameIdx = path.lastIndexOf("/") + 1;
|
||||
const typeIdx = path.lastIndexOf(".") + 1;
|
||||
const fileName = path.slice(nameIdx);
|
||||
|
||||
@@ -1,92 +1,89 @@
|
||||
<template>
|
||||
<view class="page_container">
|
||||
<custom-nav-bar :title="getTitle">
|
||||
<view class="nav_right_action" slot="more">
|
||||
<u-button type="primary" v-show="!updateLoading" @click="comfirmUpdate">保存</u-button>
|
||||
<u-loading-icon v-show="updateLoading" />
|
||||
</view>
|
||||
</custom-nav-bar>
|
||||
<view class="page_container">
|
||||
<custom-nav-bar :title="getTitle">
|
||||
<view class="nav_right_action" slot="more">
|
||||
<u-button type="primary" v-show="!updateLoading" @click="comfirmUpdate">保存</u-button>
|
||||
<u-loading-icon v-show="updateLoading" />
|
||||
</view>
|
||||
</custom-nav-bar>
|
||||
|
||||
<view class="content_row">
|
||||
<u-input
|
||||
v-model="content"
|
||||
disabledColor="transparent"
|
||||
maxlength="16"
|
||||
placeholder="请输入内容"
|
||||
clearable
|
||||
>
|
||||
</u-input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content_row">
|
||||
<u-input v-model="content" disabledColor="transparent" maxlength="16" placeholder="请输入内容" clearable>
|
||||
</u-input>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import IMSDK from "openim-uniapp-polyfill";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
MyAvatar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sourceInfo: {},
|
||||
content: "",
|
||||
updateLoading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getTitle() {
|
||||
return "修改群聊名称";
|
||||
},
|
||||
getSubTitle() {
|
||||
return "修改群名称后,将在群内通知其他成员";
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const { sourceInfo } = options;
|
||||
this.sourceInfo = JSON.parse(sourceInfo);
|
||||
this.content = this.sourceInfo.groupName;
|
||||
},
|
||||
methods: {
|
||||
comfirmUpdate() {
|
||||
this.updateLoading = true;
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.SetGroupInfo, IMSDK.uuid(), {
|
||||
groupID: this.sourceInfo.groupID,
|
||||
groupName: this.content,
|
||||
})
|
||||
.then(() => {
|
||||
uni.$u.toast("修改成功");
|
||||
setTimeout(() => uni.navigateBack(), 250);
|
||||
})
|
||||
.catch(() => uni.$u.toast("修改失败"))
|
||||
.finally(() => (this.updateLoading = false));
|
||||
},
|
||||
},
|
||||
};
|
||||
import IMSDK from "openim-uniapp-polyfill";
|
||||
import CustomNavBar from "@/components/CustomNavBar/index.vue";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import util from "@/util/index.js"
|
||||
export default {
|
||||
components: {
|
||||
CustomNavBar,
|
||||
MyAvatar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sourceInfo: {},
|
||||
content: "",
|
||||
updateLoading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getTitle() {
|
||||
return "修改群聊名称";
|
||||
},
|
||||
getSubTitle() {
|
||||
return "修改群名称后,将在群内通知其他成员";
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
const {
|
||||
sourceInfo
|
||||
} = options;
|
||||
this.sourceInfo = util.aesdecode(sourceInfo);
|
||||
this.content = this.sourceInfo.groupName;
|
||||
},
|
||||
methods: {
|
||||
comfirmUpdate() {
|
||||
this.updateLoading = true;
|
||||
IMSDK.asyncApi(IMSDK.IMMethods.SetGroupInfo, IMSDK.uuid(), {
|
||||
groupID: this.sourceInfo.groupID,
|
||||
groupName: this.content,
|
||||
})
|
||||
.then(() => {
|
||||
uni.$u.toast("修改成功");
|
||||
setTimeout(() => uni.navigateBack(), 250);
|
||||
})
|
||||
.catch(() => uni.$u.toast("修改失败"))
|
||||
.finally(() => (this.updateLoading = false));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
.page_container {
|
||||
@include colBox(false);
|
||||
height: 100vh;
|
||||
|
||||
.nav_right_action {
|
||||
margin-right: 36rpx;
|
||||
}
|
||||
.nav_right_action {
|
||||
margin-right: 36rpx;
|
||||
}
|
||||
|
||||
.content_row {
|
||||
margin-top: 96rpx;
|
||||
margin: 72rpx 44rpx 0;
|
||||
.content_row {
|
||||
margin-top: 96rpx;
|
||||
margin: 72rpx 44rpx 0;
|
||||
|
||||
.u-input {
|
||||
background-color: #e8eaef;
|
||||
}
|
||||
.u-input {
|
||||
background-color: #e8eaef;
|
||||
}
|
||||
|
||||
.u-button {
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
.u-button {
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+14
-6
@@ -1,12 +1,17 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<u-navbar title="选择背景图" :background="{ background: '#ffffff'}"
|
||||
:border-bottom="false">
|
||||
<view class="slot-wrap" slot="right">
|
||||
<uni-nav-bar
|
||||
left-icon="back"
|
||||
@clickLeft="uni.$u.route({type:'back'})"
|
||||
statusBar
|
||||
backgroundColor="#ffffff"
|
||||
:border="false"
|
||||
title="选择背景图">
|
||||
<template v-slot:footer>
|
||||
<u-button :custom-style="customBtnStyle" size="mini" :disabled="submitFlag"
|
||||
:type="submitFlag?'info ':'success'" @click="handleLink()">设置</u-button>
|
||||
</view>
|
||||
</u-navbar>
|
||||
</template>
|
||||
</uni-nav-bar>
|
||||
<u-grid @click="clickGrid">
|
||||
<u-grid-item v-for="(item, index) in bgList" :key="index" :index="index" :custom-style="item.isCheck?girdItemCustomStyle:{}">
|
||||
<u-image :src="item.src" width="200rpx" height="200rpx" mode="aspectFill"></u-image>
|
||||
@@ -46,7 +51,10 @@ export default {
|
||||
handleLink(){
|
||||
const item = this.bgList.find(it=>it.isCheck);
|
||||
if(item){
|
||||
this.$u.vuex('circleBgImg', item.src);
|
||||
this.$store.commit('circle/SET_SETTINGS',{
|
||||
...this.$store.storeCircleSettings,
|
||||
bg:item.src
|
||||
});
|
||||
uni.navigateBack({
|
||||
delta:2
|
||||
})
|
||||
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<view>
|
||||
<uni-nav-bar
|
||||
left-icon="back"
|
||||
@clickLeft="uni.$u.route({type:'back'})"
|
||||
statusBar
|
||||
backgroundColor="#ffffff"
|
||||
title="选择背景图">
|
||||
</uni-nav-bar>
|
||||
<uni-list>
|
||||
<uni-list-item disabled="true" title="选择内置背景图" @click="linkToBuiltinBgImg" clickable showArrow></uni-list-item>
|
||||
<uni-list-item title="通过手机选择" @click="chooseImg" clickable showArrow></uni-list-item>
|
||||
</uni-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {upload} from "@/api/login"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
titleStyle:{
|
||||
marginLeft:"20rpx",
|
||||
fontSize:"32rpx",
|
||||
color:"#000000"
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
chooseImg() {
|
||||
let that=this;
|
||||
uni.chooseImage({
|
||||
count: 1, //默认9
|
||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['camera','album'], //从相册选择
|
||||
success: function(res) {
|
||||
console.log("res",res);
|
||||
let tempFilePaths = res.tempFilePaths;
|
||||
that.myUpload(tempFilePaths[0]);
|
||||
return;
|
||||
}
|
||||
});
|
||||
return;
|
||||
},
|
||||
|
||||
//上传返回图片
|
||||
myUpload(filePath) {
|
||||
let _this=this;
|
||||
let obj = {
|
||||
filePath:filePath,
|
||||
'url':"/friendcircle/upload_bg",
|
||||
savePath: "circle" //文件存放目录
|
||||
}
|
||||
console.log("通过手机选择",obj);
|
||||
upload(filePath,obj).then((res1) => {
|
||||
_this.$store.commit('circle/SET_SETTINGS',{
|
||||
..._this.$store.storeCircleSettings,
|
||||
bg:res1.data.url
|
||||
});
|
||||
uni.navigateBack();
|
||||
}).catch((res1) => {
|
||||
console.log("上传失败",res1);
|
||||
});
|
||||
},
|
||||
|
||||
linkToBuiltinBgImg() {
|
||||
this.$u.route('/pages/tabbar/find/friend-circle/builtinBgImg');
|
||||
},
|
||||
},
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
+53
-29
@@ -6,7 +6,8 @@
|
||||
<view class="content">
|
||||
<view class="content-name" @tap="linkToBusinessCard(item.user_id)">{{ item.user.nickname || item.user.remark }}</view>
|
||||
<view class="content-desc">
|
||||
<u--text :lines="5" :text="item.body" />
|
||||
<text class="u-line-5" selectable user-select>{{item.body}}</text>
|
||||
<!-- <u-text :lines="5" :text="item.body" selectable /> -->
|
||||
</view>
|
||||
<!-- 图片,视频 -->
|
||||
<view class="content-img" v-if="item.files!=null&&item.files.length>0">
|
||||
@@ -14,12 +15,12 @@
|
||||
<view v-if="item.files.length==1&&item.releaseType==1"
|
||||
class="u-flex u-row-left u-col-center"
|
||||
style="width:100%;min-height: 200rpx;">
|
||||
<u-image width="280rpx" :src="cdn(item.files[0])" mode="widthFix" @tap="previewImg(0)">
|
||||
<u-image width="280rpx" :src="cdn(item.files[0])" mode="aspectFill" @tap="previewImg(0)">
|
||||
<u-loading-icon slot="loading"></u-loading-icon>
|
||||
<view slot="error"
|
||||
class="u-flex u-row-left u-col-center"
|
||||
style="font-size: 24rpx;width: 200rpx;height: 100rpx;margin-top: -50rpx;">
|
||||
<u-icon name="photo" size="100" label="加载失败" label-pos="bottom"></u-icon>
|
||||
<u-icon name="photo" size="100" label="加载失败" label-pos="bottom"></u-icon>
|
||||
</view>
|
||||
</u-image>
|
||||
</view>
|
||||
@@ -38,14 +39,9 @@
|
||||
|
||||
|
||||
<!-- 视频 -->
|
||||
<view class="u-m-b-30 u-m-t-30 u-flex u-row-left u-col-center"
|
||||
<view class="u-m-b-30 u-m-t-30 u-flex u-row-left u-col-center"
|
||||
v-if="item.files.length > 0&&item.releaseType==2" @tap="previewImg(0, item)">
|
||||
<view v-if="vuex_OSPlat=='ios'">
|
||||
<u-image width="280rpx" :src="getVideoPoster(item.files[0])" mode="widthFix">
|
||||
<u-loading-icon slot="loading"></u-loading-icon>
|
||||
</u-image>
|
||||
</view>
|
||||
<view v-else class="u-flex u-row-center u-col-center"
|
||||
<view class="u-flex u-row-center u-col-center"
|
||||
style="border: 1rpx solid #36648b;width:280rpx;height:120rpx;border-radius: 16rpx;">
|
||||
<u-icon name="play-circle" size="48" color="#36648b"
|
||||
label="点击查看视频" label-pos="bottom"></u-icon>
|
||||
@@ -54,16 +50,16 @@
|
||||
</view>
|
||||
|
||||
<!-- 地点 -->
|
||||
<view v-if="(item.address&&item.address.chooseFlag)==true" class="u-line-2 u-m-t-10 u-m-b-10" style="font-size: 30rpx;color: #36648b;">
|
||||
<u-icon name="map" color="#36648b" size="30" :custom-style="{marginLeft:'-4rpx'}"></u-icon>
|
||||
<text> {{ item.address.name}}</text>
|
||||
<view v-if="(item.address&&item.address.chooseFlag)==true" @click="gotomap(item)" class="content-address">
|
||||
<u-icon name="map" color="#36648b"></u-icon>
|
||||
<u-text class="name" :lines="1" :text="item.address.name"></u-text>
|
||||
</view>
|
||||
|
||||
<!-- 相对时间 点赞按钮等 -->
|
||||
<view class="relavivetime" :id="`comment-${'null'}-${index}`">
|
||||
<view class="time">
|
||||
<view>{{ item.created_at }}</view>
|
||||
<view @click="deleteCircle(item,index)" style="color:#36648b;margin-left: 20rpx;" v-if="item.user_id==selfInfo.userID">删除</view>
|
||||
<view @click="deleteCircle(item,index)" style="color:#36648b;margin-left: 20rpx;" v-if="item.user_id==storeSelfInfo.userID">删除</view>
|
||||
</view>
|
||||
|
||||
<view class="icon-box u-flex u-row-between u-col-center">
|
||||
@@ -80,22 +76,29 @@
|
||||
<!-- 点赞人 评论 -->
|
||||
<view class="msg-box">
|
||||
<view class="thumbinfo u-border-bottom" v-if="item.likes!=null&&item.likes.length">
|
||||
<uni-icons size="30" type="heart" color="#36648b" class="u-m-r-10"></uni-icons>
|
||||
<text class="thumbinfo-name" v-for="(userInfo, pindex) in item.likes" :index="pindex"
|
||||
:key="pindex" @tap="linkToBusinessCard(userInfo.userId)">
|
||||
{{ userInfo.nickame }}{{ pindex != item.likes.length - 1 ? ',' : '' }}
|
||||
<uni-icons size="24" type="heart" color="#36648b" class="u-m-r-10"></uni-icons>
|
||||
<text class="thumbinfo-name" v-for="(ui, pindex) in item.likes" :index="pindex"
|
||||
:key="pindex" @tap="linkToBusinessCard(ui.user_id)">
|
||||
{{ ui.nickname }}{{ pindex != item.likes.length - 1 ? ',' : '' }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="comment" v-if="item.comments!=null&&item.comments.length">
|
||||
<view class="comment-box" v-for="(comment, commentIndex) in item.comments" :index="comment.id"
|
||||
:key="comment.id" hover-class="comment-hover-class"
|
||||
<view
|
||||
class="comment-box"
|
||||
v-for="(comment, commentIndex) in item.comments"
|
||||
:index="comment.id"
|
||||
:key="comment.id"
|
||||
hover-class="comment-hover-class"
|
||||
:id="`comment-${item.id}-${comment.id}`"
|
||||
@tap="handleComment(comment, index)">
|
||||
<text class="comment-box-name">
|
||||
{{ comment.user.nickname }}
|
||||
<text class="callback u-m-l-4 u-m-r-4">回复</text>
|
||||
</text>
|
||||
<text v-if="comment.reply_user_id" class="comment-box-name">{{ comment.user.nickname }}:</text>
|
||||
<text class="callback u-m-l-4 u-m-r-4" v-if="comment.reply_user_id">回复</text>
|
||||
<text v-if="comment.reply_user_id" class="comment-box-name">
|
||||
{{ comment.user.nickname }}
|
||||
</text>
|
||||
<text>:</text>
|
||||
<text class="comment-box-content">{{ comment.body }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -106,10 +109,10 @@
|
||||
|
||||
<script>
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import videoPlayer from '@/components/videoPlayer.vue';
|
||||
import util from "@/util/index.js";
|
||||
import { mapGetters } from "vuex";
|
||||
export default{
|
||||
components:{videoPlayer ,MyAvatar},
|
||||
components:{MyAvatar},
|
||||
props:{
|
||||
index:{
|
||||
type:Number,
|
||||
@@ -123,9 +126,7 @@
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
selfInfo() {
|
||||
return this.$store.getters.storeSelfInfo;
|
||||
},
|
||||
...mapGetters(["storeSelfInfo"]),
|
||||
},
|
||||
data(){
|
||||
//console.log(this.item);
|
||||
@@ -138,6 +139,9 @@
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
log(v){
|
||||
console.log(v)
|
||||
},
|
||||
clickThumb(item,index){
|
||||
this.$emit('userEvent',{type:'clickThumb',item,index});
|
||||
},
|
||||
@@ -173,6 +177,12 @@
|
||||
return "http://192.168.31.125:9090/we-chat/images/friendCircle/1715421601709.mp4";
|
||||
//return videoSrc;
|
||||
},
|
||||
gotomap(item){
|
||||
const addr = item.address;
|
||||
uni.navigateTo({
|
||||
url:`/pages/common/map?type=viewlocation&lng=${addr.longitude}&lat=${addr.latitude}&address=${addr.address}`
|
||||
})
|
||||
},
|
||||
cdn:util.cdn
|
||||
}
|
||||
}
|
||||
@@ -215,6 +225,9 @@
|
||||
padding-top: 4rpx;
|
||||
//line-height: 36rpx;
|
||||
font-size: 32rpx;
|
||||
uni-text{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
&-img {
|
||||
@@ -242,7 +255,18 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-address{
|
||||
font-size: 26rpx;
|
||||
color: #36648b;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10rpx;
|
||||
.u-icon{
|
||||
|
||||
}
|
||||
.name{
|
||||
}
|
||||
}
|
||||
.msg-box {
|
||||
width: 100%;
|
||||
background-color: #FFF;
|
||||
@@ -290,8 +314,8 @@
|
||||
|
||||
&-content {
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+110
-142
@@ -2,72 +2,71 @@
|
||||
<view class="content" id="content">
|
||||
<u-navbar
|
||||
@leftClick="leftClick"
|
||||
bgColor="transparent"
|
||||
:bgColor="scrollTop>bannarHeight?'#f4f4f4':'transparent'"
|
||||
title="朋友圈"
|
||||
title-size="36"
|
||||
leftIconColor="#fff"
|
||||
:titleStyle ="{color:'#fff'}"
|
||||
:leftIconColor="scrollTop>bannarHeight?'#333':'#fff'"
|
||||
:titleStyle ="{color:scrollTop>bannarHeight?'#333':'#fff'}"
|
||||
:title-bold="true"
|
||||
:border-bottom="false">
|
||||
<view slot="right" class="u-margin-right-20" @click="showTypeSheet"
|
||||
@longpress="linkToRelease({releaseType:0})">
|
||||
<u-icon name="camera" color="#fff" size="32"></u-icon>
|
||||
<u-icon name="camera" :color="scrollTop>bannarHeight?'#333':'#fff'" size="32"></u-icon>
|
||||
</view>
|
||||
</u-navbar>
|
||||
<scroll-view :scroll-x="false" :scroll-y="true" class="scrollView"
|
||||
:scroll-with-animation="scrollWithAnimation" :scroll-top="scrollTop" @scroll="scrolling"
|
||||
@scrolltolower="loadMore"
|
||||
:style="'height:'+scrollViewHeight+'px'">
|
||||
<!-- 我的朋友圈基本信息 -->
|
||||
<view class="content-imgbox">
|
||||
<image class="bgimg" v-if="settings.bg" :src="settings.bg" mode="scaleToFill" @tap="showSheet"></image>
|
||||
<view class="bgimg" v-else @tap="showSheet"></view>
|
||||
|
||||
<MyAvatar class="headimg" :src="selfInfo.faceURL" :desc="selfInfo.nickname || selfInfo.remark"
|
||||
:isGroup="Boolean(selfInfo.groupID)" size="66" @tap="linkToBusinessCard(selfInfo.userID)" />
|
||||
<text class="nickname">{{ selfInfo.nickname || selfInfo.remark }}</text>
|
||||
</view>
|
||||
<!-- 个性签名 -->
|
||||
<view class="signature">
|
||||
<view class="">{{ selfInfo.bio }}</view>
|
||||
</view>
|
||||
<!-- 我的朋友圈基本信息 -->
|
||||
<view class="content-imgbox" :class="{top:scrollTop>bannarHeight}">
|
||||
<image class="bgimg" v-if="storeCircleSettings.bg" :src="cdn(storeCircleSettings.bg)" mode="scaleToFill" @tap="showSheet"></image>
|
||||
<view class="bgimg" v-else @tap="showSheet"></view>
|
||||
|
||||
<view v-if="unreadCount>0" style="display: flex;justify-content: center;">
|
||||
<view @click="clearUnReadCount()"
|
||||
style="width: 300rpx;height:70rpx;line-height:70rpx;background-color: #333333;color: #ffffff;border-radius:10rpx;display: flex;align-items: center;">
|
||||
<view style="width:80rpx;padding:0 10rpx;">
|
||||
<MyAvatar :src="selfInfo.faceURL" class="headimg" desc=" " size="24"/>
|
||||
</view>
|
||||
<view style="flex:1;">
|
||||
{{unreadCount}}条新信息
|
||||
</view>
|
||||
<MyAvatar class="headimg" :src="storeSelfInfo.faceURL" :desc="storeSelfInfo.nickname || storeSelfInfo.remark"
|
||||
:isGroup="Boolean(storeSelfInfo.groupID)" size="66" @tap="linkToBusinessCard(storeSelfInfo.userID)" />
|
||||
<text class="nickname">{{ storeSelfInfo.nickname || storeSelfInfo.remark }}</text>
|
||||
</view>
|
||||
<!-- 个性签名 -->
|
||||
<view class="signature">
|
||||
<u--text :text="storeSelfInfo.bio" :lines="4" size="13" color="#999"></u--text>
|
||||
</view>
|
||||
|
||||
<view v-if="storeCircleUnreadCount>0" style="display: flex;justify-content: center;">
|
||||
<view @click="clearUnReadCount()"
|
||||
style="width: 300rpx;height:70rpx;line-height:70rpx;background-color: #333333;color: #ffffff;border-radius:10rpx;display: flex;align-items: center;">
|
||||
<view style="width:80rpx;padding:0 10rpx;">
|
||||
<MyAvatar :src="storeSelfInfo.faceURL" class="headimg" desc=" " size="24"/>
|
||||
</view>
|
||||
<view style="flex:1;">
|
||||
{{storeCircleUnreadCount}}条新信息
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 朋友圈列表 -->
|
||||
<view class="content-circle">
|
||||
<!-- circleData是vuex变量,不在本页面定义 -->
|
||||
<template v-if="circleData!=null&&circleData.length>0">
|
||||
<template v-for="(item, index) in circleData" >
|
||||
<CircleItem :key="index" :index="index" :item="item" @userEvent="onUserEvent"></CircleItem>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 朋友圈列表 -->
|
||||
<view class="content-circle">
|
||||
<!-- storeCircleData是vuex变量,不在本页面定义 -->
|
||||
<template v-if="storeCircleData!=null&&storeCircleData.length>0">
|
||||
<template v-for="(item, index) in storeCircleData" >
|
||||
<CircleItem :key="index" :index="index" :item="item" @userEvent="onUserEvent"></CircleItem>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view style="margin-top: 30%;">
|
||||
<u-empty text="暂无动态,发一条试试吧~"></u-empty>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view style="margin-top: 30%;">
|
||||
<u-empty text="暂无动态,发一条试试吧~"></u-empty>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<u-overlay :show="showInput" @click="showInput = false">
|
||||
<view class="input-box" style="height: 100rpx;" @tap.stop>
|
||||
<view class="input-box" :style="{
|
||||
height: '100rpx',
|
||||
bottom:keyboardHeight+'px'
|
||||
}" @tap.stop>
|
||||
<view class="input-box-flex">
|
||||
<view class="input-box-flex-grow">
|
||||
<input :adjust-position="false" type="text" class="content" id="input" v-model="content"
|
||||
:confirm-type="'send'" :confirm-hold="true" placeholder-style="color:#DDD;" :cursor-spacing="6"
|
||||
:placeholder="placeholder" :focus="true" @confirm="sendMsg" />
|
||||
:placeholder="placeholder" :focus="true" @confirm="commitComment" />
|
||||
</view>
|
||||
<u-button class="btn" type="primary" size="mini" @tap.prevent.stop="sendMsg">发送</u-button>
|
||||
<u-button class="btn" type="primary" size="mini" @tap.prevent.stop="commitComment">发送</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-overlay>
|
||||
@@ -77,14 +76,12 @@
|
||||
<videoPlayer :previewVideoFlag="previewVideoFlag" :previewVideoSrc="previewVideoSrc" @quitPlay="previewVideoFlag=false"></videoPlayer>
|
||||
</view>
|
||||
<!-- 删除朋友圈确认框 -->
|
||||
<view v-if="delCircleObj.delCircleModelFlag==true">
|
||||
<u-modal v-model="delCircleObj.delCircleModelFlag" :show-title="false"
|
||||
:show-confirm-button="true" confirm-text="删除" confirm-color="#fa3534"
|
||||
:show-cancel-button="true" cancel-text="取消" cancel-color="#000000"
|
||||
content="删除该朋友圈?" :content-style="{color:'#000000',fontSize:'32rpx',fontWeight:'bold'}"
|
||||
<u-modal :show="delCircleObj.delCircleModelFlag"
|
||||
:showConfirmButton="true" confirmText="删除" confirmColor="#fa3534"
|
||||
:showCancelButton="true" cancelText="取消" cancelColor="#000000"
|
||||
content="删除该朋友圈?"
|
||||
@confirm="confirmDelCircle()" @cancel="cancelDelCircle()">
|
||||
</u-modal>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -93,53 +90,31 @@
|
||||
import {getFriendCircle} from "@/api/login.js"
|
||||
import UserBase from "@/components/User.vue"
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import util from "@/util/index.js";
|
||||
import CircleItem from "./components/circleItem.vue"
|
||||
import { mapGetters } from "vuex";
|
||||
import util from "@/util";
|
||||
export default {
|
||||
name: 'firendCircle',
|
||||
mixins:[UserBase],
|
||||
components:{videoPlayer ,MyAvatar,CircleItem},
|
||||
computed: {
|
||||
selfInfo() {
|
||||
return this.$store.getters.storeSelfInfo;
|
||||
},
|
||||
circleData() {
|
||||
return this.$store.getters.storeCircleData;
|
||||
},
|
||||
unreadCount() {
|
||||
return this.$store.getters.storeCircleUnreadCount;
|
||||
},
|
||||
last_unread_item() {
|
||||
return this.$store.getters.storeCircleLastUnreadItem;
|
||||
},
|
||||
settings() {
|
||||
return this.$store.getters.storeCircleSettings;
|
||||
},
|
||||
computed:{
|
||||
...mapGetters(["storeSelfInfo",'storeCircleData','storeCircleUnreadCount','storeCircleTopUnreadItems','storeCircleSettings']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loadMoreFlag:true,//可以分页加载吗
|
||||
platFrom:'',
|
||||
girdItemCustomStyle:{
|
||||
padding: '0',
|
||||
margin:'0',
|
||||
border:'1rpx solid #f2f6fc'
|
||||
},
|
||||
scrollViewHeight: 0,
|
||||
bannarHeight:202,
|
||||
scrollTop: 0,
|
||||
currentTop: 0,
|
||||
currentScroll: 0,
|
||||
scrollWithAnimation: false,
|
||||
content: '',
|
||||
placeholder: '',
|
||||
showInput: false,
|
||||
keyboardHeight:0,
|
||||
focus: false,
|
||||
id: '', //某一条朋友圈id
|
||||
commentInfo: {},
|
||||
currentItem: {},
|
||||
previewVideoFlag:false,
|
||||
previewVideoSrc:'',
|
||||
videoContext:null,
|
||||
page:1,
|
||||
limit:5,
|
||||
//删除对象参数
|
||||
@@ -152,37 +127,28 @@
|
||||
},
|
||||
//vuex变量
|
||||
watch:{
|
||||
circleData:function(val){
|
||||
console.log("监听到朋友圈内容有变动",val.length);
|
||||
storeCircleData:function(val){
|
||||
//console.log("监听到朋友圈内容有变动",val.length);
|
||||
}
|
||||
},
|
||||
|
||||
onReady() {
|
||||
console.log(this.selfInfo);
|
||||
let that = this;
|
||||
uni.onKeyboardHeightChange(res => {
|
||||
that.keyboardHeight = res.height;
|
||||
if (res.height == 0) {
|
||||
let windowHeight = this.$u.sys().windowHeight;
|
||||
this.scrollViewHeight = windowHeight - 90;
|
||||
this.showInput = false;
|
||||
this.currentTop = 0;
|
||||
that.showInput = false;
|
||||
return;
|
||||
} else {
|
||||
this.currentTop = 999;
|
||||
let windowHeight = this.$u.sys().windowHeight;
|
||||
this.scrollViewHeight = (windowHeight - res.height) - 120;
|
||||
}
|
||||
});
|
||||
},
|
||||
onShow: function(option) {
|
||||
let windowHeight = this.$u.sys().windowHeight;
|
||||
this.scrollViewHeight = windowHeight - 90;
|
||||
console.log("onshow",this.page);
|
||||
//let windowHeight = this.$u.sys().windowHeight;
|
||||
//this.scrollViewHeight = windowHeight - 90;
|
||||
//console.log("onshow",this.page);
|
||||
},
|
||||
onLoad:function(){
|
||||
let that=this;
|
||||
this.platFrom= this.$u.os();
|
||||
console.log("onload",this.platFrom);
|
||||
let param={
|
||||
page:1,
|
||||
limit:this.limit,
|
||||
@@ -192,11 +158,11 @@
|
||||
this.getCircleDataList(param);
|
||||
uni.$on("handleFriendCircle", function(friendCircleMessage) {
|
||||
console.log("监听到朋友圈动态有更新",friendCircleMessage);
|
||||
let id= friendCircleMessage.content.id;
|
||||
let newPraise= friendCircleMessage.content.likes;
|
||||
const index = that.circleData.findIndex(i => i.id ==id);
|
||||
that.circleData[index].likes=JSON.parse(newPraise);
|
||||
if(friendCircleMessage.content.is_liked&&friendCircleMessage.userId!=that.selfInfo.userID){
|
||||
//let id= friendCircleMessage.content.id;
|
||||
//let newPraise= friendCircleMessage.content.likes;
|
||||
//const index = that.storeCircleData.findIndex(i => i.id ==id);
|
||||
//that.storeCircleData[index].likes=JSON.parse(newPraise);
|
||||
if(friendCircleMessage.content.is_liked&&friendCircleMessage.userId!=that.storeSelfInfo.userID){
|
||||
that.$store.dispatch('circle/updateUnreadCount',1);
|
||||
}
|
||||
})
|
||||
@@ -219,6 +185,7 @@
|
||||
|
||||
methods: {
|
||||
goto:util.goto,
|
||||
cdn:util.cdn,
|
||||
clearUnReadCount(){
|
||||
this.$store.dispatch('circle/updateUnreadCount',0-this.unreadCount);
|
||||
},
|
||||
@@ -229,16 +196,16 @@
|
||||
},
|
||||
|
||||
//滚动事件
|
||||
scrolling: function(event) {
|
||||
scrolling: function(scrollTop) {
|
||||
//console.log("event",event);
|
||||
let that = this;
|
||||
if (that.showInput == true) {
|
||||
return;
|
||||
}
|
||||
let scrollTop = event.detail.scrollTop;
|
||||
setTimeout(function() {
|
||||
that.currentScroll = scrollTop;
|
||||
}, 300);
|
||||
//let scrollTop = event.detail.scrollTop;
|
||||
// setTimeout(function() {
|
||||
// that.currentScroll = scrollTop;
|
||||
// }, 300);
|
||||
},
|
||||
//加载更多
|
||||
loadMore:function(){
|
||||
@@ -267,7 +234,7 @@
|
||||
itemList:['更换相册封面'],
|
||||
success: function (res) {
|
||||
if(res.tapIndex == 0){
|
||||
_this.goto('/pages/workbench/friend-circle/chooseCircleBgImg');
|
||||
_this.goto('/pages/find/friend-circle/chooseCircleBgImg');
|
||||
}
|
||||
},
|
||||
fail: function (res) {
|
||||
@@ -278,11 +245,13 @@
|
||||
showTypeSheet() {
|
||||
const _this = this;
|
||||
uni.showActionSheet({
|
||||
itemList:['选择照片','选择视频'],
|
||||
itemList:['文字','照片','视频'],
|
||||
success: function (res) {
|
||||
//toChooseRelease
|
||||
if(res.tapIndex<2){
|
||||
if([1,2].includes(res.tapIndex)){
|
||||
_this.toChooseRelease(res.tapIndex);
|
||||
}else{
|
||||
_this.linkToRelease({releaseType:0})
|
||||
}
|
||||
},
|
||||
fail: function (res) {
|
||||
@@ -295,28 +264,20 @@
|
||||
clickThumb(item,index) {
|
||||
let that=this;
|
||||
let flag=true;
|
||||
item.is_liked = !item.is_liked;
|
||||
if (item.is_liked) {
|
||||
item.likes.push({
|
||||
userId: this.selfInfo.userID,
|
||||
userName: this.selfInfo.nickname
|
||||
});
|
||||
} else {
|
||||
const index = item.likes.findIndex(i => i.userId == this.selfInfo.userID);
|
||||
item.likes.splice(index, 1);
|
||||
flag=false;
|
||||
}
|
||||
console.log("当前动态下标",index);
|
||||
console.log("点赞列表",item);
|
||||
let param={
|
||||
id:item.id,
|
||||
likes:JSON.stringify(item.likes),
|
||||
user_id: this.storeSelfInfo.userID,
|
||||
nickname: this.storeSelfInfo.nickname,
|
||||
avatar: this.storeSelfInfo.avatar,
|
||||
is_liked:flag
|
||||
};
|
||||
this.$store.dispatch('circle/like',param).then(res=>{
|
||||
console.log("点赞更新成功",res.data);
|
||||
item.likes=JSON.parse(res.data.likes);
|
||||
that.circleData[index]=item;
|
||||
}).catch(e=>{
|
||||
item.is_liked = !item.is_liked;
|
||||
console.log("评论失败",e);
|
||||
@@ -324,7 +285,7 @@
|
||||
},
|
||||
//跳转到名片
|
||||
linkToBusinessCard(userId) {
|
||||
if(userId==this.selfInfo.userID){
|
||||
if(userId==this.storeSelfInfo.userID){
|
||||
return;
|
||||
}
|
||||
this.goto('/pages/common/userCard?sourceID='+userId);
|
||||
@@ -343,16 +304,9 @@
|
||||
let param={
|
||||
id:delCircleId
|
||||
};
|
||||
deleteCircle(param).then(res => {
|
||||
if(res.code==200){
|
||||
that.delCircleObj.delCircleModelFlag=false;
|
||||
that.delCircleObj.tempDelCircleId="";
|
||||
that.delCircleObj.tempDelIndex="";
|
||||
let tempData=that.circleData;
|
||||
tempData.splice(delIndex,1);
|
||||
this.$u.vuex('circleData', tempData);
|
||||
}
|
||||
});
|
||||
that.delCircleObj.delCircleModelFlag=false;
|
||||
this.$store.dispatch('circle/deleteFriendCircleList',param);
|
||||
|
||||
},
|
||||
cancelDelCircle:function(){
|
||||
let that=this;
|
||||
@@ -365,14 +319,13 @@
|
||||
handleComment(comment, index) {
|
||||
let that = this;
|
||||
this.content = '';
|
||||
that.currentItem = that.circleData[index];
|
||||
that.currentTop = 0;
|
||||
that.currentItem = that.storeCircleData[index];
|
||||
this.id = that.currentItem.id;
|
||||
this.commentInfo = comment || {};
|
||||
this.placeholder = '评论:';
|
||||
if (comment) {
|
||||
//console.log("评论内容",comment);
|
||||
if (comment.comment.user_id == this.selfInfo.userID) {
|
||||
if (comment.comment.user_id == this.storeSelfInfo.userID) {
|
||||
//如果是回复自己
|
||||
this.placeholder = `评论:`;
|
||||
} else {
|
||||
@@ -383,7 +336,7 @@
|
||||
this.showInput = true;
|
||||
},
|
||||
//提交评论消息
|
||||
sendMsg() {
|
||||
commitComment() {
|
||||
let that=this;
|
||||
if (!that.$u.trim(that.content)) {
|
||||
return;
|
||||
@@ -420,7 +373,6 @@
|
||||
//关闭键盘 关闭输入框
|
||||
closeInputModel() {
|
||||
this.showInput = false;
|
||||
this.currentTop = 0;
|
||||
this.content = '';
|
||||
this.id = '';
|
||||
this.commentInfo = {};
|
||||
@@ -432,7 +384,7 @@
|
||||
let that = this;
|
||||
let tempFilePaths = [];
|
||||
//拍照
|
||||
if (index == 0) {
|
||||
if (index == 1) {
|
||||
uni.chooseImage({
|
||||
count: 9, //默认9
|
||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
||||
@@ -447,9 +399,10 @@
|
||||
return;
|
||||
}
|
||||
});
|
||||
return ;
|
||||
}
|
||||
//选择视频
|
||||
if (index == 1) {
|
||||
if (index == 2) {
|
||||
uni.chooseVideo({
|
||||
sourceType: ['camera', 'album'],
|
||||
maxDuration: 60,
|
||||
@@ -465,13 +418,14 @@
|
||||
return;
|
||||
}
|
||||
});
|
||||
return ;
|
||||
}
|
||||
|
||||
},
|
||||
//点击自定义组件相机按钮
|
||||
linkToRelease(params) {
|
||||
console.log(params);
|
||||
let url = "/pages/workbench/friend-circle/releaseFriendCircle?";
|
||||
let url = "/pages/find/friend-circle/releaseFriendCircle?";
|
||||
for(let key in params){
|
||||
if(key!="tempFilePaths"){
|
||||
url+=key+"="+params[key]+"&";
|
||||
@@ -490,7 +444,7 @@
|
||||
//return videoSrc;
|
||||
},
|
||||
leftClick(e){
|
||||
this.goto('/pages/workbench/index/index',"2");
|
||||
this.goto('/pages/find/index/index',"2");
|
||||
},
|
||||
onUserEvent(e){
|
||||
switch(e.type){
|
||||
@@ -500,6 +454,9 @@
|
||||
case 'handleComment':
|
||||
this.handleComment(e.comment,e.index);
|
||||
break;
|
||||
case 'deleteCircle':
|
||||
this.deleteCircle(e.item,e.index);
|
||||
break;
|
||||
case 'linkToBusinessCard':
|
||||
this.linkToBusinessCard(e.userID);
|
||||
break;
|
||||
@@ -507,6 +464,14 @@
|
||||
},
|
||||
cdn:util.cdn
|
||||
},
|
||||
onReachBottom() {
|
||||
this.loadMore();
|
||||
},
|
||||
onPageScroll({scrollTop}) {
|
||||
this.scrollTop = scrollTop;
|
||||
//console.log(scrollTop)
|
||||
//this.scrolling(scrollTop);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -533,6 +498,9 @@
|
||||
}
|
||||
&-imgbox {
|
||||
position: relative;
|
||||
&.top{
|
||||
background: #f4f4f4;
|
||||
}
|
||||
|
||||
.bgimg {
|
||||
width: 100%;
|
||||
+54
-60
@@ -22,7 +22,7 @@
|
||||
:adjust-position="true" :auto-blur="true" @linechange="inputLineChange" @input="inputing"
|
||||
:confirm-hold="true" :show-confirm-bar="false"
|
||||
:focus="inputFocusFlag" :disable-default-padding="true"
|
||||
v-model="content" :cursor="content.length" :maxlength="-1" />
|
||||
v-model="content" :cursor="content.length" :maxlength="1500" />
|
||||
</scroll-view>
|
||||
<!-- 文件选择区 -->
|
||||
<view v-if="releaseType!=0" class="uploadBox">
|
||||
@@ -49,29 +49,33 @@
|
||||
</view>
|
||||
<!-- 选项 -->
|
||||
<view class="tips">
|
||||
<u-cell-group>
|
||||
<!-- :value="address.name" :value-style="customValueStyle" :label="address.address" -->
|
||||
<u-cell bg-color="#ffffff"
|
||||
:title="address.chooseFlag?(address.name):'所在位置'" :title-style="customTitleStyle"
|
||||
:value="address.chooseFlag?(address.address):'请选择'" isLink
|
||||
@click="toChooseLocation()">
|
||||
<view slot="icon" class="u-flex u-row-center u-col-center">
|
||||
<u-icon name="map" size="32" :color="address.chooseFlag?'#19be6b':'#606266'"></u-icon>
|
||||
</view>
|
||||
</u-cell>
|
||||
<u-cell bg-color="#ffffff" title="提醒谁看" :title-style="customTitleStyle" @click="toRemind">
|
||||
<view slot="icon" class="u-flex u-row-center u-col-center">
|
||||
<u-icon name="/static/images/friendCircle/at.png" width="24" height="24" color="#606266"></u-icon>
|
||||
</view>
|
||||
</u-cell>
|
||||
<u-cell bg-color="#ffffff" @click="toSetPromission()"
|
||||
title="谁可以看" :title-style="customTitleStyle"
|
||||
:value="'公开'" :value-style="customValueStyle">
|
||||
<view slot="icon" class="u-flex u-row-center u-col-center">
|
||||
<u-icon name="account" size="32" color="#606266"></u-icon>
|
||||
</view>
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
<uni-list>
|
||||
<uni-list-item
|
||||
title="所在位置"
|
||||
:rightText="address.chooseFlag?(address.name):'请选择'"
|
||||
:show-extra-icon="true"
|
||||
:extra-icon="{color: '#666',size: '22',type: 'location-filled'}"
|
||||
clickable
|
||||
showArrow
|
||||
@click="toChooseLocation">
|
||||
</uni-list-item>
|
||||
<uni-list-item v-if="1==2"
|
||||
title="提醒谁看"
|
||||
:rightText="address.chooseFlag?(address.address):'请选择'"
|
||||
clickable
|
||||
showArrow
|
||||
@click="toRemind">
|
||||
</uni-list-item>
|
||||
<uni-list-item
|
||||
title="谁可以看"
|
||||
rightText="公开"
|
||||
:show-extra-icon="true"
|
||||
:extra-icon="{color: '#666',size: '22',type: 'notification-filled'}"
|
||||
clickable
|
||||
showArrow
|
||||
@click="toSetPromission">
|
||||
</uni-list-item>
|
||||
</uni-list>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -273,21 +277,23 @@
|
||||
//去选择所在位置
|
||||
toChooseLocation:function(){
|
||||
let that=this;
|
||||
uni.chooseLocation({
|
||||
success: function (res) {
|
||||
// console.log('位置名称:' + res.name);
|
||||
// console.log('详细地址:' + res.address);
|
||||
// console.log('纬度:' + res.latitude);
|
||||
//console.log('经度:' + res.longitude);
|
||||
that.address=res;
|
||||
that.address.chooseFlag=true;
|
||||
//console.log("that.address",that.address);
|
||||
},
|
||||
fail:function(){
|
||||
that.address={};
|
||||
that.address.chooseFlag=false;
|
||||
uni.navigateTo({
|
||||
url:"/pages/common/map",
|
||||
events:{
|
||||
onConfirm(res) {
|
||||
//_this.sendLocationMessage(res);
|
||||
that.address={
|
||||
address:res.address,
|
||||
name:`${res.addressComponent.city}•${res.addressComponent.town}`,
|
||||
latitude:res.lat,
|
||||
longitude:res.lng,
|
||||
};
|
||||
that.address.chooseFlag=true;
|
||||
console.log(res);
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
return ;
|
||||
},
|
||||
//设置发布朋友圈的查看权限
|
||||
toSetPromission:function(){
|
||||
@@ -422,28 +428,16 @@
|
||||
let that=this;
|
||||
console.error('submitPublish');
|
||||
uni.$u.http.post('/friendcircle/create',param).then(res => {
|
||||
let newCircle=res;
|
||||
if(newCircle.address!=null&&newCircle.address.length>0){
|
||||
newCircle.address=JSON.parse(newCircle.address);
|
||||
}else{
|
||||
newCircle.address={"chooseFlag":false};
|
||||
}
|
||||
if(newCircle.fileList!=null&&newCircle.fileList.length>0){
|
||||
newCircle.fileList=JSON.parse(newCircle.fileList);
|
||||
}else{
|
||||
newCircle.fileList=[];
|
||||
}
|
||||
if(newCircle.praise!=null){
|
||||
newCircle.praise=JSON.parse(newCircle.praise);
|
||||
}else{
|
||||
newCircle.praise=[];
|
||||
}
|
||||
if(newCircle.comment!=null){
|
||||
newCircle.comment=JSON.parse(newCircle.comment);
|
||||
}
|
||||
else{
|
||||
newCircle.comment=[];
|
||||
}
|
||||
console.log("发布成功",res);
|
||||
let newCircle=res.data;
|
||||
newCircle['user'] = {
|
||||
"id": this.$store.getters.storeSelfInfo.userID,
|
||||
"nickname": this.$store.getters.storeSelfInfo.nickname,
|
||||
"avatar": this.$store.getters.storeSelfInfo.faceURL,
|
||||
};
|
||||
newCircle['likes'] = [];
|
||||
newCircle['comments'] = [];
|
||||
newCircle['is_liked'] = false;
|
||||
let circleDataList=[...this.circleData];
|
||||
circleDataList.unshift(newCircle);
|
||||
that.$store.commit('circle/SET_LIST',circleDataList);
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<view class="workbench_page">
|
||||
<uni-nav-bar
|
||||
title="发现"
|
||||
statusBar
|
||||
fixed
|
||||
background-color="transparent"></uni-nav-bar>
|
||||
<uni-list>
|
||||
<uni-list-item title="朋友圈"
|
||||
thumb="/static/images/find/01.png"
|
||||
:thumbSize="thumbSize"
|
||||
showArrow
|
||||
to="/pages/find/friend-circle/friend-circle">
|
||||
<view slot="footer" v-if="storeCircleTopUnreadItems.length>0">
|
||||
<view class="avatargroup">
|
||||
<MyAvatar :src="item.user.avatar" shape="circle" size="32" v-for="(item,index) in storeCircleTopUnreadItems" :key="index"></MyAvatar>
|
||||
<u-avatar :text="'+'+storeCircleUnreadCount" size="32" bg-color="#353432" shape="circle"></u-avatar>
|
||||
</view>
|
||||
</view>
|
||||
</uni-list-item>
|
||||
</uni-list>
|
||||
<u-gap :height="10"></u-gap>
|
||||
<uni-list>
|
||||
<uni-list-item title="扫一扫" thumb="/static/images/find/03.png" :thumbSize="thumbSize" @click="scan" clickable showArrow></uni-list-item>
|
||||
<uni-list-item v-if="1==2" title="摇一摇" thumb="/static/images/find/05.png" :thumbSize="thumbSize" to="/pages/find/shake/index" showArrow></uni-list-item>
|
||||
<uni-list-item v-if="1==2" title="看一看" thumb="/static/images/find/06.png" :thumbSize="thumbSize" to="/pages/find/friend-circle/friend-circle" showArrow></uni-list-item>
|
||||
<uni-list-item v-if="1==2" title="听一听" thumb="/static/images/find/06.png" :thumbSize="thumbSize" to="/pages/find/music/index" showArrow></uni-list-item>
|
||||
<uni-list-item v-if="config.near_user_open == '1'" title="附近" thumb="/static/images/find/08.png" :thumbSize="thumbSize" to="/pages/find/near/near" showArrow></uni-list-item>
|
||||
<uni-list-item v-if="1===2" title="购物" thumb="/static/images/find/09.png" :thumbSize="thumbSize" :to="'/pages/common/webview?url='+encodeURI('http://pinduoduo.com')" showArrow></uni-list-item>
|
||||
</uni-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import MyAvatar from "@/components/MyAvatar/index.vue";
|
||||
import util from "@/util";
|
||||
export default {
|
||||
components:{MyAvatar},
|
||||
data() {
|
||||
return {
|
||||
thumbSize:"base"
|
||||
};
|
||||
},
|
||||
computed:{
|
||||
...mapGetters(["config",'storeCircleUnreadCount','storeCircleTopUnreadItems']),
|
||||
},
|
||||
onShow: function() {
|
||||
let unreadCount= 1;
|
||||
this.$store.dispatch('circle/getFriendCircleInfo');
|
||||
},
|
||||
methods: {
|
||||
scan:util.scan
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.workbench_page {
|
||||
background-color: #ececec !important;
|
||||
}
|
||||
.avatargroup{
|
||||
display: flex;
|
||||
.u-avatar {
|
||||
position: relative;
|
||||
margin-left: -16px;
|
||||
//border: 1px solid #333;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<view v-if="currentPlaySong != null" class="play-bar flex-v-center" @click="bindOnShowPlayViewPopup">
|
||||
<view class="music-cover flex-v-h-center" :class="currentPlayer.playState ? 'spin-start':'spin-stop'">
|
||||
<u-avatar :src="currentPlaySong.pic" mode="circle" size='70'></u-avatar>
|
||||
</view>
|
||||
<view style="width: 64%;">
|
||||
<view class="music-info flex-v-center text-line-1">
|
||||
<view class="music-name text-line-1">{{currentPlaySong.songName}}</view>
|
||||
<view class="line">-</view>
|
||||
<view class="music-singer text-line-1">{{currentPlaySong.artist}}</view>
|
||||
</view>
|
||||
<view class="u-p-l-20 u-p-r-20 u-flex u-row-between u-col-center">
|
||||
<view style="width: 80%;">
|
||||
<u-line-progress active-color="#19be6b"
|
||||
:striped="true"
|
||||
:height="8"
|
||||
:striped-active="true"
|
||||
:show-percent="false"
|
||||
:percent="currentPlayer.progress"></u-line-progress>
|
||||
</view>
|
||||
<view class="u-font-24 u-tips-color">
|
||||
<text> {{currentPlaySong.songTimeMinutes}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bars flex-v-center flex-space-between">
|
||||
<view style="width: 64rpx;">
|
||||
<view class="u-progress-content flex-v-h-center btn-active" @tap.stop="bindOnControllerPlay">
|
||||
<u-icon :class="currentPlayer.playState ? 'play' : 'pause'"
|
||||
:name="currentPlayer.playState ? 'pause-circle' : 'play-circle'" size="54"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tools-item btn-active" style="display: inline-block;" @tap.stop="bindOnShowPlayListPopup">
|
||||
<u-icon name="music-list" custom-prefix="custom-icon" size="54"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="play-bar flex-v-center test-border u-tips-color">
|
||||
<view style="text-align: center;width: 100%;">
|
||||
<text>当前暂无播放歌曲记录</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
bindOnControllerPlay(){
|
||||
this.$emit("changePlayStatus");
|
||||
},
|
||||
bindOnShowPlayListPopup(){
|
||||
this.$emit("showPlayList")
|
||||
},
|
||||
bindOnShowPlayViewPopup(){
|
||||
this.$emit("showPlayView")
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@import "@/static/music/music.css";
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.play-bar{
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 120rpx;
|
||||
background-color: #ffffff;
|
||||
padding: 0 40rpx;
|
||||
z-index: 1000;
|
||||
.music-cover{
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
background-image: url('@/static/music/disc-plus.png');
|
||||
background-size: 100% 100%;
|
||||
flex-shrink:0;
|
||||
-webkit-transform: rotate(360deg);
|
||||
animation: rotation 10s linear infinite;
|
||||
-moz-animation: rotation 10s linear infinite;
|
||||
-webkit-animation: rotation 10s linear infinite;
|
||||
-o-animation: rotation 10s linear infinite;
|
||||
}
|
||||
@-webkit-keyframes rotation{
|
||||
from {-webkit-transform: rotate(0deg);}
|
||||
to {-webkit-transform: rotate(360deg);}
|
||||
}
|
||||
.spin-stop{
|
||||
-webkit-animation-play-state:paused
|
||||
}
|
||||
.spin-start{
|
||||
-webkit-animation-play-state:running
|
||||
}
|
||||
.music-info{
|
||||
display: flex;
|
||||
padding: 0 20rpx;
|
||||
flex: 1;
|
||||
.music-name{
|
||||
max-width: 65%;
|
||||
flex-shrink:0;
|
||||
}
|
||||
.line{
|
||||
padding: 0 10rpx;
|
||||
color: $uni-text-color-disable;
|
||||
font-size: $uni-font-size-sm;
|
||||
}
|
||||
.music-singer{
|
||||
max-width: 35%;
|
||||
color: $uni-text-color-disable;
|
||||
font-size: $uni-font-size-sm;
|
||||
}
|
||||
}
|
||||
.bars{
|
||||
width: 160rpx;
|
||||
text-align: right;
|
||||
height: 100%;
|
||||
.u-progress-content{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar :is-back="true" title="" :background="{ background: '#ffffff' }"
|
||||
:border-bottom="false" z-index="1001">
|
||||
<view class="slot-wrap u-font-32">
|
||||
<view class="u-font-32" style="width: 100%;">
|
||||
<u-tabs :list="tabList" active-color="#2ebe4b"
|
||||
:is-scroll="false" :show-bar="true" :font-size="34"
|
||||
:current="currentTab" :active-item-style="activeItemStyle"
|
||||
@change="tabChange"></u-tabs>
|
||||
</view>
|
||||
</view>
|
||||
</u-navbar>
|
||||
<view>
|
||||
|
||||
<view class="u-p-l-40 u-p-r-40">
|
||||
<view class="u-m-t-20 u-m-b-20">
|
||||
<u-search placeholder="支持搜索歌手,歌名,专辑"
|
||||
border-color="#eeeeee"
|
||||
bg-color="#ffffff"
|
||||
shape="square"
|
||||
:clearabled="true"
|
||||
:show-action="true"
|
||||
:action-style="actionStyle"
|
||||
:animation="false"
|
||||
height="80"
|
||||
@search="search"
|
||||
@custom="search"
|
||||
v-model="searchWord">
|
||||
</u-search>
|
||||
</view>
|
||||
<scroll-view
|
||||
:scroll-x="false" :scroll-y="true" :style="'height:'+(pageHeight)+'px'">
|
||||
<u-row>
|
||||
<u-col :span="12">
|
||||
<view class="u-p-30 u-font-36" style="font-weight: bold;">
|
||||
<text>热门男歌手</text>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col :span="4" v-for="(item,index) in singerManList" :key="index">
|
||||
<view class="u-m-b-30" @click="toSongList(item)">
|
||||
<view class="u-flex u-row-center u-col-center">
|
||||
<view>
|
||||
<u-image width="100%" height="130rpx"
|
||||
border-radius="16rpx"
|
||||
mode="heightFix"
|
||||
:src="item.avatar"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view style="text-align: center;margin-top:4rpx;font-size: 26rpx;color: #000000;">
|
||||
<text>{{item.singerName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
|
||||
<u-row>
|
||||
<u-col :span="12">
|
||||
<view class="u-p-30 u-font-36" style="font-weight: bold;">
|
||||
<text>热门女歌手</text>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col :span="4" v-for="(item,index) in singerWomenList" :key="index">
|
||||
<view class="u-m-b-30" @click="toSongList(item)">
|
||||
<view class="u-flex u-row-center u-col-center">
|
||||
<view>
|
||||
<u-image width="100%" height="130rpx"
|
||||
border-radius="16rpx"
|
||||
mode="heightFix"
|
||||
:src="item.avatar"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view style="text-align: center;margin-top:4rpx;font-size: 26rpx;color: #000000;">
|
||||
<text>{{item.singerName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pageHeight:0,
|
||||
tabList:[
|
||||
{
|
||||
name: '在线听'
|
||||
},
|
||||
{
|
||||
name: '本地听'
|
||||
},
|
||||
],
|
||||
currentTab:0,
|
||||
activeItemStyle:{
|
||||
fontSize:'36rpx',
|
||||
},
|
||||
actionStyle:{
|
||||
backgroundColor:'#46be72',
|
||||
color:'#ffffff',
|
||||
height:'80rpx',
|
||||
lineHeight:'80rpx',
|
||||
position:'relative',
|
||||
left:'0rpx',
|
||||
textAlign:'center',
|
||||
width:'140rpx',
|
||||
borderRadius:'10rpx',
|
||||
borderTopRightRadius:'10rpx',
|
||||
borderBottomRightRadius:'10rpx'
|
||||
},
|
||||
searchWord:'',
|
||||
singerManList:[
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M0000025NhlN2yWrP4.jpg?max_age=2592000',
|
||||
singerName:'周杰伦'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001BLpXF2DyJe2.jpg?max_age=2592000',
|
||||
singerName:'林俊杰'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000002J4UUk29y8BY.jpg?max_age=2592000',
|
||||
singerName:'薛之谦'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000003Nz2So3XXYek.jpg?max_age=2592000',
|
||||
singerName:'陈奕迅'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000002azErJ0UcDN6.jpg?max_age=2592000',
|
||||
singerName:'张杰'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000003aQYLo2x8izP_4.jpg?max_age=2592000',
|
||||
singerName:'刘德华'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000004NMZuf2BLjg8_2.jpg?max_age=2592000',
|
||||
singerName:'周传雄'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000000aHmbL2aPXWH.jpg?max_age=2592000',
|
||||
singerName:'李荣浩'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000003fA5G40k6hKc.jpg?max_age=2592000',
|
||||
singerName:'周深'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001IoTZp19YMDG.jpg?max_age=2592000',
|
||||
singerName:'易烊千玺'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001z2JmX09LLgL.jpg?max_age=2592000',
|
||||
singerName:'汪苏泷'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000000CK5xN3yZDJt.jpg?max_age=2592000',
|
||||
singerName:'许嵩'
|
||||
}
|
||||
],
|
||||
singerWomenList:[
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001fNHEf1SFEFN.jpg?max_age=2592000',
|
||||
singerName:'G.E.M.邓紫棋'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M0000003ZpE43ypssl.jpg?max_age=2592000',
|
||||
singerName:'张碧晨'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000000oCQfT3kdonw.jpg?max_age=2592000',
|
||||
singerName:'黄霄雲'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000002lKaDq2lLLtk.jpg?max_age=2592000',
|
||||
singerName:'蔡健雅'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000002azErJ0UcDN6.jpg?max_age=2592000',
|
||||
singerName:'苏星婕'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000003iPzNg35cWzp.jpg?max_age=2592000',
|
||||
singerName:'程响'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000000aw4WC2EQYTv_5.jpg?max_age=2592000',
|
||||
singerName:'张靓颖'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000000GGDys0yA0Nk_2.jpg?max_age=2592000',
|
||||
singerName:'梁静茹'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000001pWERg3vFgg8.jpg?max_age=2592000',
|
||||
singerName:'孙燕姿'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R500x500M000000GDDuQ3sGQiT.jpg?max_age=2592000',
|
||||
singerName:'王菲'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000003jJGvv3C82KZ_5.jpg?max_age=2592000',
|
||||
singerName:'刘若英'
|
||||
},
|
||||
{
|
||||
avatar:'https://y.qq.com/music/photo_new/T001R300x300M000002raUWw3PXdkT_5.jpg?max_age=2592000',
|
||||
singerName:'张韶涵'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
created:function(){
|
||||
let pageHeight= this.$u.sys().windowHeight*0.82;
|
||||
this.pageHeight=pageHeight;
|
||||
},
|
||||
methods: {
|
||||
tabChange:function(index){
|
||||
this.currentTab = index;
|
||||
},
|
||||
search:function(value){
|
||||
console.log("搜索关键字",value);
|
||||
let that=this;
|
||||
if(value.length>0){
|
||||
this.$u.route({
|
||||
url:'pages/tabbar/find/music/song-list',
|
||||
params:{
|
||||
keyWords:value
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
toSongList:function(singer){
|
||||
let that=this;
|
||||
this.$u.route({
|
||||
url:'pages/tabbar/find/music/song-list',
|
||||
params:{
|
||||
keyWords:singer.singerName
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.slot-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* 如果您想让slot内容占满整个导航栏的宽度 */
|
||||
flex: 1;
|
||||
/* 如果您想让slot内容与导航栏左右有空隙 */
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
.status_bar {
|
||||
height: var(--status-bar-height);
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar :is-back="true" :title="navbarTitle" :background="{ background: '#ffffff' }"
|
||||
:title-bold="true" title-size="34"
|
||||
:border-bottom="true" z-index="1001">
|
||||
</u-navbar>
|
||||
<view>
|
||||
<view class="u-p-30 u-flex u-row-between u-col-center">
|
||||
<view style="font-size: 36rpx;font-weight: bold;">
|
||||
<text>列表</text>
|
||||
<text>({{songList.length}})</text>
|
||||
</view>
|
||||
<view class="u-flex u-row-left u-col-center">
|
||||
<view class="u-m-r-30">
|
||||
<u-icon name="play-circle-fill" size="42" color="#2979ff" @click="playAll()"
|
||||
label="播放全部" label-size="32"></u-icon>
|
||||
</view>
|
||||
<view class="u-m-l-30">
|
||||
<u-icon name="heart-fill" size="42" color="#fa3534" @click="addToLocal()"
|
||||
label="添加本地" label-size="32"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view :scroll-x="false" :scroll-y="true" :style="'height:'+(pageHeight-50)+'px'" @scrolltolower="loadMore">
|
||||
<view class="u-flex u-row-between u-col-center u-p-30 u-border-bottom"
|
||||
v-for="(song,index) in songList" :key="index">
|
||||
<view class="u-flex u-row-left u-col-center">
|
||||
<view class="u-m-r-30">
|
||||
<u-image :src="song.pic" width="100rpx" height="100rpx" border-radius="12rpx"></u-image>
|
||||
</view>
|
||||
<view>
|
||||
<view class="u-font-34 u-m-b-10 u-line-1" style="color: #000000;width: 400rpx;">{{escape2Html(song.name)}}</view>
|
||||
<view class="u-font-28 u-m-t-10 u-flex u-row-left u-col-center u-line-3" style="color: #808288;width: 400rpx;">
|
||||
{{escape2Html(song.artist)}}-{{escape2Html(song.album)}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-around u-col-center">
|
||||
<view>
|
||||
<u-icon v-if="currentPlaySong&¤tPlaySong.id==song.rid&¤tPlayer.playState" name="pause-circle" size="50" color="#797979"></u-icon>
|
||||
<u-icon v-else @click="toPlaySong(song)" name="play-circle" size="50" color="#797979"></u-icon>
|
||||
</view>
|
||||
<view class="u-m-l-30">
|
||||
<u-icon @click="download(song)" name="download" size="50" color="#797979"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view>
|
||||
<play-bar @changePlayStatus="changePlayStatus" @showPlayView='bindOnPlayBarChange' @showPlayList='bindOnShowPlayListPopup'></play-bar>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import playBar from './components/play-bar.vue';
|
||||
import playerUtil from '@/util/music/music-player.js';
|
||||
export default {
|
||||
components:{
|
||||
playBar
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
navbarTitle:"歌曲列表",
|
||||
pageHeight:0,
|
||||
pageNum:1,
|
||||
pageSize:30,
|
||||
searchWord:"",
|
||||
total:0,
|
||||
songList:[],
|
||||
loadMoreFlag:false
|
||||
};
|
||||
},
|
||||
watch:{
|
||||
currentPlaySong:function(newSong){
|
||||
let that=this;
|
||||
console.log("====监听到播放歌曲发生变化======");
|
||||
if(newSong!=null&&newSong.id){
|
||||
playerUtil.initPlayer(that);
|
||||
}
|
||||
}
|
||||
},
|
||||
created:function(){
|
||||
let pageHeight= this.$u.sys().windowHeight*0.79;
|
||||
this.pageHeight=pageHeight;
|
||||
},
|
||||
onLoad:function(option){
|
||||
let that=this;
|
||||
console.log("搜索词",option);
|
||||
let keyWords= option.keyWords;
|
||||
if(keyWords){
|
||||
this.navbarTitle=keyWords;
|
||||
this.searchWord=keyWords;
|
||||
};
|
||||
this.getSongList();
|
||||
that.$u.vuex("currentPlayer.canPlay",false);
|
||||
//当前是是否暂停或停止状态,true 表示暂停或停止,false 表示正在播放
|
||||
if(playerUtil.bgAudioManager.paused==true){
|
||||
playerUtil.initPlayer(that);
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getSongList:function(){
|
||||
let that=this;
|
||||
let param={
|
||||
pageNum:that.pageNum,
|
||||
pageSize:that.pageSize,
|
||||
keyWords:encodeURI(this.searchWord)
|
||||
};
|
||||
console.log("搜索歌曲列表",param);
|
||||
this.$u.api.music.searchMusicList(param).then(res => {
|
||||
//console.log("获取歌曲列表结果",res);
|
||||
if(res.code==200){
|
||||
let result= res.data;
|
||||
if(result!=null&&result!=undefined){
|
||||
let reqData= result.data;
|
||||
this.total= reqData.total;
|
||||
let list=reqData.list;
|
||||
if(that.loadMoreFlag==true){
|
||||
this.songList=this.songList.concat(list);
|
||||
return;
|
||||
}else{
|
||||
this.songList=list;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
loadMore:function(){
|
||||
let that=this;
|
||||
if(that.songList.length>=that.total){
|
||||
that.globalUtil.utilAlert("暂无更多");
|
||||
that.loadMoreFlag=false;
|
||||
return;
|
||||
}
|
||||
that.pageNum++;
|
||||
that.loadMoreFlag=true;
|
||||
console.log("加载更多");
|
||||
that.getSongList();
|
||||
},
|
||||
|
||||
toPlaySong:function(song){
|
||||
//console.log("当前选中播放歌曲",song);
|
||||
//this.$u.vuex("currentPlaySong",song);
|
||||
let param={
|
||||
musicId:song.rid
|
||||
};
|
||||
this.$u.api.music.getSongInfoAndLrc(param).then(res => {
|
||||
if(res.code==200){
|
||||
let baseInfoResult= res.data;
|
||||
let lrclist= baseInfoResult.data.lrclist;
|
||||
let songInfo= baseInfoResult.data.songinfo;
|
||||
songInfo.lrclist=lrclist;
|
||||
this.$u.api.music.getSongSrc(param).then(res => {
|
||||
if(res.code==200){
|
||||
let songSrcResult= res.data;
|
||||
let songSrc=songSrcResult.data.url;
|
||||
songInfo.playSrc=songSrc;
|
||||
console.log("获取歌曲详细信息结果",songInfo);
|
||||
this.$u.vuex("currentPlaySong",songInfo);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
//this.$forceUpdate();
|
||||
},
|
||||
|
||||
changePlayStatus:function(){
|
||||
let that=this;
|
||||
console.log("改变状态")
|
||||
playerUtil.bindOnControllerPlay(that);
|
||||
},
|
||||
|
||||
bindOnPlayBarChange(){
|
||||
//this.$refs.playViewPopup.show();
|
||||
},
|
||||
bindOnShowPlayListPopup(){
|
||||
//this.$refs.playListPopup.show();
|
||||
},
|
||||
playAll:function(){
|
||||
|
||||
},
|
||||
addToLocal:function(){
|
||||
let that=this;
|
||||
},
|
||||
download:function(song){
|
||||
let that=this;
|
||||
let param={
|
||||
musicId:song.rid,
|
||||
songName:that.escape2Html(song.name),
|
||||
saveDir:that.escape2Html(song.artist),
|
||||
};
|
||||
console.log("下载参数",param);
|
||||
this.$u.api.music.downLoadSong(param).then(res => {
|
||||
console.log("下载结果",res);
|
||||
if(res.code==200){
|
||||
that.globalUtil.utilAlert("下载成功");
|
||||
let playSrc= res.data.url;
|
||||
}else{
|
||||
that.globalUtil.utilAlert("下载失败");
|
||||
}
|
||||
})
|
||||
},
|
||||
escape2Html:function(str) {
|
||||
var arrEntities={'lt':'<','gt':'>','nbsp':' ','amp':'&','quot':'"','$':','};
|
||||
return str.replace(/&(lt|gt|nbsp|amp|quot);/ig,function(all,t){
|
||||
return arrEntities[t];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,249 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar :is-back="true" back-icon-color="#333333"
|
||||
title="通过朋友验证" :title-bold="true" :title-size="34"
|
||||
:background="{ background: '#ffffff' }"
|
||||
title-color="#404133" :border-bottom="false">
|
||||
</u-navbar>
|
||||
<view class="">
|
||||
<scroll-view :scroll-x="false" :scroll-y="true" class="u-p-t-10 u-p-b-30"
|
||||
:style="'width:100%;height:'+scrollviewHeight+'px'">
|
||||
<view class="u-p-l-40 u-p-r-40">
|
||||
<view class="u-p-l-20 u-title-color u-font-28">
|
||||
<text>设置备注</text>
|
||||
</view>
|
||||
<view class="inputBox">
|
||||
<u-input :custom-style="customInputStyle"
|
||||
v-model="form.nickName" type="text"
|
||||
:border="false" :height="60" :clearable="false"/>
|
||||
</view>
|
||||
<view class="u-title-color u-p-l-30 u-m-t-10">
|
||||
<text>
|
||||
<text style="font-size: 28rpx;">"{{form.userRemark}}"</text>
|
||||
<text style="color: #36648b;margin-left: 20rpx;">选词填入</text>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
<view class="u-m-t-30 u-p-l-40 u-p-r-40">
|
||||
<view class="u-p-l-20 u-title-color u-font-28">
|
||||
<text>添加标签与描述</text>
|
||||
</view>
|
||||
<view style="background-color: #f0f0f0;border-radius: 16rpx;margin-top: 20rpx;font-size: 32rpx;">
|
||||
<view class="u-flex u-row-between u-col-center" style="padding:16rpx 26rpx;">
|
||||
<view class="u-p-20 label-font">
|
||||
<text>标签</text>
|
||||
</view>
|
||||
<view class="u-p-20">
|
||||
<u-icon name="arrow-right" color="#909399" :size="32"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<u-gap :height="1" bg-color="#e5e8ec"></u-gap>
|
||||
<view class="u-flex u-row-between u-col-center" style="padding:16rpx 26rpx;">
|
||||
<view class="u-p-20 label-font">
|
||||
<text>描述</text>
|
||||
</view>
|
||||
<view class="u-p-20">
|
||||
<u-icon name="arrow-right" color="#909399" :size="32"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="u-m-t-30 u-p-l-40 u-p-r-40">
|
||||
<view class="u-p-l-20 u-title-color u-font-28">
|
||||
<text>设置朋友权限</text>
|
||||
</view>
|
||||
<view style="background-color: #f0f0f0;border-radius: 16rpx;margin-top: 20rpx;font-size: 32rpx;">
|
||||
<view class="u-flex u-row-between u-col-center"
|
||||
@click="changePower(0)"
|
||||
style="padding:16rpx 26rpx;">
|
||||
<view class="u-p-20 label-font">
|
||||
<text>聊天、朋友圈、微信运动等</text>
|
||||
</view>
|
||||
<view class="u-p-20" v-show="form.friendPower==0">
|
||||
<u-icon name="checkbox-mark" color="#19be6b" :size="32"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<u-gap :height="1" bg-color="#e5e8ec"></u-gap>
|
||||
<view class="u-flex u-row-between u-col-center"
|
||||
@click="changePower(1)"
|
||||
style="padding:16rpx 26rpx;">
|
||||
<view class="u-p-20 label-font">
|
||||
<text>仅聊天</text>
|
||||
</view>
|
||||
<view class="u-p-20" v-show="form.friendPower==1">
|
||||
<u-icon name="checkbox-mark" color="#19be6b" :size="32"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="u-m-t-30 u-p-l-40 u-p-r-40" v-if="form.friendPower==0">
|
||||
<view class="u-p-l-20 u-title-color u-font-28">
|
||||
<text>朋友圈和状态</text>
|
||||
</view>
|
||||
<view style="background-color: #f0f0f0;border-radius: 16rpx;margin-top: 20rpx;font-size: 32rpx;">
|
||||
<view class="u-flex u-row-between u-col-center" style="padding:16rpx 26rpx;">
|
||||
<view class="u-p-20 label-font">
|
||||
<text>不让他(她)看</text>
|
||||
</view>
|
||||
<view class="u-p-20">
|
||||
<u-switch v-model="form.forbidSelf" :size="40" active-color="#19be6b" inactive-color="#eee"></u-switch>
|
||||
</view>
|
||||
</view>
|
||||
<u-gap :height="1" bg-color="#e5e8ec"></u-gap>
|
||||
<view class="u-flex u-row-between u-col-center" style="padding:16rpx 26rpx;">
|
||||
<view class="u-p-20 label-font">
|
||||
<text>不看他(她)</text>
|
||||
</view>
|
||||
<view class="u-p-20">
|
||||
<u-switch v-model="form.forbidHis" :size="40" active-color="#19be6b" inactive-color="#eee"></u-switch>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view :style="'height:'+footerHeight+'px'"
|
||||
class="u-flex u-row-center u-col-top footerbox">
|
||||
<u-button type="success" :custom-style="customBtnStyle" @click="submitApply">完成</u-button>
|
||||
</view>
|
||||
|
||||
<u-popup v-model="loadingShow"
|
||||
:mask-close-able="false" :mask="false"
|
||||
mode="center" border-radius="20" width="250rpx" height="250rpx">
|
||||
<view class="u-flex u-row-center u-col-center"
|
||||
style="flex-direction: column; text-align: center;
|
||||
background-color: #000000;color: #ffffff;height: 250rpx;width: 250rpx;">
|
||||
<view v-if="loadingStep==1">
|
||||
<view>
|
||||
<!-- <u-circle-progress :percent="100" bg-color="none"
|
||||
inactive-color="#909399"
|
||||
active-color="#ffffff"
|
||||
:border-width="6"
|
||||
:duration="1000" :width="100">
|
||||
</u-circle-progress> -->
|
||||
<u-loading mode="circle" :size="80" color="#909399"></u-loading>
|
||||
</view>
|
||||
<view class="u-m-t-20 u-font-32" style="font-weight: 420rpx;">正在处理...</view>
|
||||
</view>
|
||||
<view v-if="loadingStep==2">
|
||||
<view>
|
||||
<u-icon name="checkmark" color="#ffffff" :size="80"></u-icon>
|
||||
</view>
|
||||
<view class="u-m-t-20 u-font-32" style="font-weight: 420rpx;">已通过验证</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
scrollviewHeight:0,
|
||||
footerHeight:0,
|
||||
customInputStyle:{
|
||||
fontSize:'32rpx',
|
||||
color:'#909399',
|
||||
paddingLeft:'10rpx'
|
||||
},
|
||||
form:{
|
||||
id:'3',
|
||||
avatar:'/static/image/default/default-user/3.jpg',
|
||||
nickName:'王工',
|
||||
signature:'',
|
||||
userRemark:'你好,美女',
|
||||
address:'浙江 杭州',
|
||||
sex:0,
|
||||
friendPower:0,
|
||||
forbidSelf:false,
|
||||
forbidHis:false,
|
||||
},
|
||||
customBtnStyle:{
|
||||
padding:'20rpx 40rpx',
|
||||
width:'300rpx'
|
||||
},
|
||||
loadingShow:false,
|
||||
loadingStep:1,
|
||||
};
|
||||
},
|
||||
created:function(){
|
||||
let pageHeight= this.$u.sys().windowHeight;
|
||||
this.scrollviewHeight=pageHeight*0.783;
|
||||
this.footerHeight=pageHeight*0.09;
|
||||
},
|
||||
onLoad:function(option){
|
||||
let that=this;
|
||||
/* let param=JSON.parse(decodeURIComponent(option.personInfo));
|
||||
this.form=param; */
|
||||
this.form=this.yyy_current_user;
|
||||
},
|
||||
methods:{
|
||||
friendNameFocus:function(){
|
||||
let that=this;
|
||||
},
|
||||
changePower:function(status){
|
||||
let that=this;
|
||||
},
|
||||
submitApply:function(){
|
||||
let that=this;
|
||||
that.loadingStep=1;
|
||||
that.loadingShow=true;
|
||||
setTimeout(function(){
|
||||
that.loadingStep=2;
|
||||
setTimeout(function(){
|
||||
that.loadingShow=false;
|
||||
uni.navigateTo({
|
||||
animationType:'slide-in-left',
|
||||
url:'/pages/find/shake/friend_home?personInfo='+encodeURIComponent(JSON.stringify(that.form))
|
||||
});
|
||||
/* that.$u.route({
|
||||
url:'/pages/find/shake/friend_home',
|
||||
animationType:'slide-in-left',
|
||||
params:{
|
||||
personInfo:encodeURIComponent(JSON.stringify(that.form))
|
||||
},
|
||||
}) */
|
||||
},400)
|
||||
},800);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.inputBox{
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 16rpx;
|
||||
margin-top: 20rpx;
|
||||
padding:16rpx 26rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.footerbox{
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
//opacity: 0.7;
|
||||
}
|
||||
.label-font{
|
||||
font-size: 34rpx;
|
||||
color: #000000;
|
||||
font-weight: 420;
|
||||
}
|
||||
.u-title-color{
|
||||
color: #606266 !important;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
page{
|
||||
background-color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,554 @@
|
||||
<template>
|
||||
<view class="message-item-container"
|
||||
:class="checkBoxFlag?'u-flex u-row-left u-col-center':''">
|
||||
<view v-if="checkBoxFlag">
|
||||
<template v-if="item.messageType!=0">
|
||||
<u-checkbox :size="46" v-model="item.checked"
|
||||
shape="circle" active-color="#19be6b" @click.native="checkChange(item)"></u-checkbox>
|
||||
</template>
|
||||
</view>
|
||||
<view class="u-p-b-20 u-p-t-20" style="width: 100%;">
|
||||
<!-- 系统信息-->
|
||||
<view v-if="item.messageType==0">
|
||||
<view v-if="item.showTimeFlag" style="text-align: center;color:#aaaaaa;font-size: 28rpx;margin-top: 20rpx;">
|
||||
<text v-if="item.formatTimeStr&&item.formatTimeStr.length>0">
|
||||
{{item.formatTimeStr}}
|
||||
</text>
|
||||
<text v-else>
|
||||
{{item.createTime.substring(10,16)}}
|
||||
</text>
|
||||
</view>
|
||||
<view style="text-align: center;color:#aaaaaa;font-size: 30rpx;margin-top: 20rpx;">
|
||||
{{parseSYSContent(item)}}
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="chat-time">
|
||||
<text v-if="item.showTimeFlag">
|
||||
<text v-if="item.formatTimeStr&&item.formatTimeStr.length>0">
|
||||
{{item.formatTimeStr}}
|
||||
</text>
|
||||
<text v-else>
|
||||
{{item.createTime.length>10?item.createTime.substring(10,16):item.createTime}}
|
||||
</text>
|
||||
</text>
|
||||
</view>
|
||||
<view :class="{'chat-container':true,'chat-location-me':item.meFlag}">
|
||||
<view class="chat-icon-container u-flex u-row-center u-col-center"
|
||||
@click="toYYYPerson(item)">
|
||||
<view hover-class="my-hover-class"
|
||||
class="u-flex u-row-center u-col-center">
|
||||
<u-image :class="{'chat-icon':true,'chat-icon-me':item.meFlag}"
|
||||
:src="item.userAvatar" width="80rpx" height="80rpx"
|
||||
mode="aspectFill">
|
||||
<view slot="error"
|
||||
class="u-flex u-row-center u-col-center u-p-t-10"
|
||||
style="width: 80rpx;height: 80rpx;border-radius: 12rpx;">
|
||||
<view>
|
||||
<image src="/static/image/default/default-user/default-user.png"
|
||||
style="width: 50rpx;height:50rpx;"></image>
|
||||
</view>
|
||||
</view>
|
||||
</u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="chat-content-container u-p-t-10">
|
||||
<!-- 文本信息 -->
|
||||
<view v-if="item.contentType == messageApi.CONTENT_TYPE.TEXT_CONTENT_TYPE">
|
||||
<zb-tooltip placement="top" :visible.sync="toolTipFlag" color="#4c4c4c">
|
||||
<view slot="content" style="width: 550rpx;"
|
||||
class="u-flex u-flex-wrap u-row-left u-col-center">
|
||||
<view v-for="(item,index) in toolTipData" :key="index"
|
||||
style="text-align: center;padding: 20rpx 30rpx;">
|
||||
<view class="u-flex u-row-center u-col-center" @click="handleMessage(item)">
|
||||
<view>
|
||||
<u-image :src="item.icon" :width="36" :height="36"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view style="font-size:26rpx;margin-top: 6rpx;">
|
||||
<text>{{item.title}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view @longpress="toolTipFlag=!toolTipFlag"
|
||||
:class="{'chat-text-container':true,'chat-text-container-me u-text-reserve':item.meFlag}">
|
||||
<u-parse :html="parseTextContent(item)"
|
||||
:tag-style="tagStyle">
|
||||
</u-parse>
|
||||
</view>
|
||||
</zb-tooltip>
|
||||
</view>
|
||||
<!-- 图片信息 -->
|
||||
<view v-if="item.contentType == messageApi.CONTENT_TYPE.IMG_CONTENT_TYPE">
|
||||
<view class="content contentType3" @tap="showPic(item)">
|
||||
<u-image :width="item.content.width*2" :height="item.content.height*2"
|
||||
:lazy-load="true" mode="widthFix" :src="parseImageSrc(item)">
|
||||
<u-loading slot="loading"></u-loading>
|
||||
</u-image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
var previewSrcArr = [];
|
||||
export default {
|
||||
name: "message-item",
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
"id": "",
|
||||
"chatGroupId": "",
|
||||
"userId": 0,
|
||||
"meFlag": true,
|
||||
"userName": '',
|
||||
"userAvatar": "",
|
||||
'messageType': "",
|
||||
"contentType": "",
|
||||
"content": {},
|
||||
"timestamp": "",
|
||||
"createTime": "",
|
||||
"platFrom": this.messageApi.msgPlat,
|
||||
}
|
||||
}
|
||||
},
|
||||
checkBoxFlag:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
toolTipFlag: false,
|
||||
toolTipData: [{
|
||||
id: 1,
|
||||
icon: '/static/image/wx/handle-msg/copy.jpg',
|
||||
title: '复制',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
icon: '/static/image/wx/handle-msg/zhuanfa.jpg',
|
||||
title: '转发', //转发
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
icon: '/static/image/wx/handle-msg/shoucang.jpg',
|
||||
title: '收藏',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
icon: '/static/image/wx/handle-msg/shanchu.jpg',
|
||||
title: '删除',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
icon: '/static/image/wx/handle-msg/duoxuan.jpg',
|
||||
title: '多选',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
icon: '/static/image/wx/handle-msg/yinyong.jpg',
|
||||
title: '引用',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
icon: '/static/image/wx/handle-msg/tixing.jpg',
|
||||
title: '提醒',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
icon: '/static/image/wx/handle-msg/souyisou.jpg',
|
||||
title: '搜一搜',
|
||||
disabled: false
|
||||
},
|
||||
],
|
||||
tagStyle:{
|
||||
img:'width:22px;height:22px;position:relative;top:10rpx;',
|
||||
span:'margin:0px;padding:0px;font-size:30rpx',
|
||||
},
|
||||
previewVideoFlag:false, //播放视频控制器
|
||||
previewVideoSrc:'',
|
||||
redbagPopFlag:false,
|
||||
maskCustomStyle:{
|
||||
background: 'rgba(255, 255, 255, 0.7)'
|
||||
},
|
||||
currentRedBagInfo:null,
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
parseSYSContent:function(item){
|
||||
let that=this;
|
||||
let contentType = item.contentType;
|
||||
let contentObj=item.content;
|
||||
if (contentType == 1) {
|
||||
let msgStr = contentObj.text;
|
||||
console.log("transText",msgStr);
|
||||
return msgStr;
|
||||
}
|
||||
},
|
||||
//内容格式化
|
||||
parseTextContent: function(item) {
|
||||
let that=this;
|
||||
let contentType = item.contentType;
|
||||
let contentObj=item.content;
|
||||
let msgStr = contentObj.text;
|
||||
let sysType = contentObj.contentType; //内容类型
|
||||
let optionType = contentObj.optionType;
|
||||
let transText = this.transform(msgStr,'','',contentObj.linkName);
|
||||
return transText;
|
||||
},
|
||||
|
||||
//预览图片
|
||||
showPic:function(item){
|
||||
let url= item.content.fullPath;
|
||||
let target= item.content.fileSaveTarget;
|
||||
if(target=="local"){
|
||||
url= this.$u.api.multipartAddress.getFileByPath+url;
|
||||
}
|
||||
uni.previewImage({
|
||||
urls: previewSrcArr.length > 0 ? previewSrcArr : [url],
|
||||
current: url,
|
||||
loop: false,
|
||||
});
|
||||
},
|
||||
|
||||
parseImageSrc:function(item){
|
||||
let that=this;
|
||||
let msgId= item.id;
|
||||
let localSrc= uni.getStorageSync("image"+msgId);
|
||||
if(localSrc){
|
||||
return localSrc;
|
||||
}
|
||||
let contentObj=item.content;
|
||||
let url= contentObj.fullPath;
|
||||
let target= contentObj.fileSaveTarget;
|
||||
if(target=="local"){
|
||||
let fileName= contentObj.fileName;
|
||||
url=this.$u.api.multipartAddress.showFile+fileName;
|
||||
}
|
||||
that.setImageLocalSrc(url,msgId);
|
||||
return url;
|
||||
},
|
||||
parseImgSize: function(item, type) {
|
||||
let contentObj=item.content;
|
||||
let height = contentObj.height;
|
||||
let width = contentObj.width;
|
||||
if (type == "h") {
|
||||
if (height == null || height == undefined) {
|
||||
return "auto";
|
||||
} else {
|
||||
return height * 2;
|
||||
}
|
||||
} else {
|
||||
if (width == null || width == undefined) {
|
||||
return 300;
|
||||
} else {
|
||||
return width * 2;
|
||||
}
|
||||
}
|
||||
},
|
||||
setImageLocalSrc(url,msgId){
|
||||
let that=this;
|
||||
that.messageApi.setImageLocalSrc(url,msgId);
|
||||
},
|
||||
toYYYPerson:function(item){
|
||||
let that=this;
|
||||
if(item.meFlag==false){
|
||||
that.$emit("toYYYPerson",item);
|
||||
}
|
||||
},
|
||||
checkChange:function(msg){
|
||||
let that=this;
|
||||
that.$emit("checkChange",msg);
|
||||
},
|
||||
handleMessage:function(menuItem){
|
||||
this.toolTipFlag=false;
|
||||
this.$emit("handleMessage",menuItem,this.item);
|
||||
},
|
||||
transform (content, fileSize, fileSuffix,linkName) {
|
||||
if (fileSize === undefined) {
|
||||
fileSize = '';
|
||||
}
|
||||
if (fileSuffix === undefined) {
|
||||
fileSuffix = '';
|
||||
}
|
||||
let html = function(end) {
|
||||
return new RegExp('\\n*\\[' + (end || '') +
|
||||
'(code|pre|div|span|p|table|thead|th|tbody|tr|td|ul|li|ol|li|dl|dt|dd|h2|h3|h4|h5)([\\s\\S]*?)]\\n*',
|
||||
'g');
|
||||
};
|
||||
if (content)
|
||||
{
|
||||
content = content.replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/"/g, '"') // XSS
|
||||
.replace(html(), '<$1 $2>')
|
||||
.replace(html('/'), '</$1>') // 转移HTML代码
|
||||
.replace(/\n/g, '<br>'); // 转义换行
|
||||
content=getUrl(content);
|
||||
content=content.replace(/face\[([^\s\[\]]+?)]/g, function(face) {
|
||||
let alt = face.replace(/^face/g, '');
|
||||
let fa =faceUtil.emojiMap;
|
||||
let srcPrefix=faceUtil.emojiUrl;
|
||||
let imageSrc=srcPrefix+ fa[alt];
|
||||
//console.log("表情",imageSrc);
|
||||
let imgContent= '<img class="emoji" src="' +imageSrc+ '"/>';
|
||||
return imgContent;
|
||||
})
|
||||
// 转义图片
|
||||
.replace(/img\[([^\s]+?)]/g, function(img) {
|
||||
let href = img.replace(/(^img\[)|(]$)/g, '');
|
||||
return '<img class="message-img" src="' + href + '" alt="消息图片不能加载">';
|
||||
})
|
||||
// 转义文件
|
||||
.replace(/file\([\s\S]+?\)\[[\s\S]*?]/g, function(str) {
|
||||
let href = (str.match(/file\(([\s\S]+?)\)\[/) || [])[1];
|
||||
let text = (str.match(/\)\[([\s\S]*?)]/) || [])[1];
|
||||
if (!href) return str;
|
||||
return '<div class="flex"><i class="iconfont icon-xiazai-yun"></i><a class="message-file" href="' +
|
||||
href + '">' + (text || href) + '</a><span>' + fileSize + '</span></div>'
|
||||
})
|
||||
// 转义音频
|
||||
.replace(/audio\[([^\s]+?)]/g, function(audio) {
|
||||
return '<div class="message-audio" data-src="' + audio.replace(/(^audio\[)|(]$)/g, '') +
|
||||
'"><i class="layui-icon"></i><p>音频消息</p></div>';
|
||||
})
|
||||
// 转义视频
|
||||
.replace(/video\[([^\s]+?)]/g, function(video) {
|
||||
return '<div class="message-video" data-src="' + video.replace(/(^video\[)|(]$)/g, '') +
|
||||
'"><i class="layui-icon"></i></div>';
|
||||
})
|
||||
// 转义链接
|
||||
.replace(/a\([\s\S]+?\)\[[\s\S]*?]/g, function(str) {
|
||||
let href = (str.match(/a\(([\s\S]+?)\)\[/) || [])[1];
|
||||
let text = (str.match(/\)\[([\s\S]*?)]/) || [])[1];
|
||||
if (!href) return str;
|
||||
if(linkName&&linkName.length>0){
|
||||
return '<a href="' + href + '" target="_blank">' + linkName + '</a>';
|
||||
};
|
||||
return '<a href="' + href + '" target="_blank">' + (text || href) + '</a>';
|
||||
})
|
||||
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.message-item-container {
|
||||
padding:0rpx 20rpx;
|
||||
}
|
||||
|
||||
.chat-time {
|
||||
padding: 4rpx 0rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
justify-items: flex-start;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.chat-location-me {
|
||||
flex-direction: row-reverse;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.chat-icon-me {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.chat-icon-container {
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
.chat-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.chat-content-container {
|
||||
margin: 0rpx 15rpx;
|
||||
max-width: 70%;
|
||||
}
|
||||
|
||||
.chat-user-name {
|
||||
font-size: 26rpx;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.chat-text-container {
|
||||
//word-break: break-all;
|
||||
word-wrap:break-word;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
padding: 20rpx 20rpx;
|
||||
margin-top: 5rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.chat-text-container-me {
|
||||
background-color: #95ec69;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
width: 40rpx !important;
|
||||
height: 40rpx !important;
|
||||
position: relative;
|
||||
top: 10rpx;
|
||||
}
|
||||
|
||||
//语音信息样式
|
||||
.content-audio-container {
|
||||
background-color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
padding: 25rpx 20rpx;
|
||||
margin-top: 5rpx;
|
||||
/* #ifndef APP-NVUE */
|
||||
max-width: 500rpx;
|
||||
/* #endif */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.voice_icon {
|
||||
height: 34rpx;
|
||||
width: 34rpx;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
.voice_icon_right {
|
||||
background-image: url('@/static/images/chat/voice/voice-left-3.png');
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.voice_icon_left {
|
||||
background-image: url('@/static/images/chat/voice/voice-right-3.png');
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.voice_icon_right_an {
|
||||
animation: voiceAn_right 1s linear alternate infinite;
|
||||
}
|
||||
|
||||
.voice_icon_left_an {
|
||||
animation: voiceAn_left 1s linear alternate infinite;
|
||||
}
|
||||
|
||||
@keyframes voiceAn_right {
|
||||
0% {
|
||||
background-image: url('@/static/images/chat/voice/voice-left-1.png');
|
||||
}
|
||||
|
||||
50% {
|
||||
background-image: url('@/static/images/chat/voice/voice-left-2.png');
|
||||
}
|
||||
|
||||
100% {
|
||||
background-image: url('@/static/images/chat/voice/voice-left-3.png');
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes voiceAn_left {
|
||||
0% {
|
||||
background-image: url('@/static/images/chat/voice/voice-right-1.png');
|
||||
}
|
||||
|
||||
50% {
|
||||
background-image: url('@/static/images/chat/voice/voice-right-2.png');
|
||||
}
|
||||
|
||||
100% {
|
||||
background-image: url('@/static/images/chat/voice/voice-right-3.png');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//我的语音信息样式
|
||||
.chat-audio-container-me {
|
||||
background-color: #95ec69;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
//文件信息样式
|
||||
.contentType-file {
|
||||
width: 450rpx;
|
||||
padding: 0;
|
||||
border-radius: 10rpx;
|
||||
border: 1rpx solid #e4e7ed;
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
//红包
|
||||
.contentType-redbag {
|
||||
padding: 20rpx 30rpx;
|
||||
padding-bottom: 6rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #f29100;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
//位置
|
||||
.contentType-location {
|
||||
width: 500rpx;
|
||||
padding: 0rpx 10rpx;
|
||||
border-radius: 10rpx;
|
||||
border: 1rpx solid #e4e7ed;
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
//组合信息
|
||||
.contentType-fixed {
|
||||
border-radius: 10rpx;
|
||||
font-size: 32rpx;
|
||||
word-break: break-word;
|
||||
padding: 20rpx;
|
||||
background-color: #95ec69 !important;
|
||||
border: 1rpx solid #e4e7ed;
|
||||
max-width: 400rpx;
|
||||
|
||||
.img {
|
||||
width: 200rpx;
|
||||
height: auto;
|
||||
max-width: 300rpx;
|
||||
max-height: 400rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.u-flex-reserve {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.u-text-reserve {
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,441 @@
|
||||
<template>
|
||||
<view class="zhuanfa-container">
|
||||
<template v-if="moreFlag==false">
|
||||
<view>
|
||||
<u-navbar :is-back="false"
|
||||
back-icon-color="#333333"
|
||||
title=""
|
||||
:border-bottom="false"
|
||||
:background="{ background: '#f0f0f0'}"
|
||||
z-index="1001">
|
||||
<view class="slot-wrap u-flex u-row-between u-col-center u-font-32">
|
||||
<view @click="goback()">
|
||||
<text>关闭</text>
|
||||
</view>
|
||||
<view style="font-weight: bold;font-size: 34rpx;color: #000000;">
|
||||
<text>选择一个聊天</text>
|
||||
</view>
|
||||
<view @click="changeMoreFlag(1)">
|
||||
<text>多选</text>
|
||||
</view>
|
||||
</view>
|
||||
</u-navbar>
|
||||
<view>
|
||||
<view style="background-color: #f0f0f0;" class="u-p-30">
|
||||
<view class="u-flex u-row-center u-col-center"
|
||||
style="background-color: #ffffff;height:70rpx;border-radius: 10rpx;color: #c0c0c0;">
|
||||
<view class="u-m-r-20">
|
||||
<u-icon class="u-clear-icon" top="6rpx" :size="40" name="search" color="#c0c0c0"></u-icon>
|
||||
</view>
|
||||
<view style="color: #c0c0c0;font-size: 34rpx;">搜索</view>
|
||||
</view>
|
||||
<view class="u-m-t-40 u-p-b-20" v-if="latestZhuanFa.length>0">
|
||||
<view style="font-size: 30rpx;font-weight: bold;">
|
||||
<text>最近转发</text>
|
||||
</view>
|
||||
<view class="u-flex u-row-left u-col-center u-m-t-20" style="text-align: center;">
|
||||
<view class="u-m-r-40" v-for="(lastestItem,index) in latestZhuanFa" :key="index">
|
||||
<view class="u-flex u-row-center u-col-center">
|
||||
<view style="height: 100rpx;width: 100rpx;">
|
||||
<u-image :src="lastestItem.avatar"
|
||||
:width="100" :height="100" :border-radius="12"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-line-2 u-tips-color"
|
||||
style="width: 100rpx;height: 64rpx;line-height: 30rpx;font-size: 26rpx;padding:8rpx;">
|
||||
<text>{{lastestItem.nickName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="u-p-30" style="background-color: #ffffff;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;">
|
||||
<view class="u-flex u-row-between u-col-center u-font-30">
|
||||
<view style="color: #000000;font-weight: bold;">
|
||||
<text>最近聊天</text>
|
||||
</view>
|
||||
<view style="color:#36648b;">
|
||||
<text>创建聊天</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="lastestChatUsers.length>0" class="u-m-t-30">
|
||||
<view v-for="(user,uIndex) in lastestChatUsers" :key="uIndex"
|
||||
class="u-flex u-row-left u-col-center u-p-t-16 u-p-b-16">
|
||||
<view style="width:90rpx;" class="u-flex u-row-left u-col-center">
|
||||
<view>
|
||||
<u-image :src="user.avatar" :width="76" :height="76" border-radius="8rpx"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view style="width: 600rpx;"
|
||||
class="u-flex u-row-between u-col-center u-p-20 u-border-bottom">
|
||||
<view style="text-align: left;">
|
||||
<view class="u-line-1" style="font-size: 32rpx;color: #000000;">
|
||||
<text>{{user.nickName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="moreFlag==true">
|
||||
<view>
|
||||
<u-navbar :is-back="false"
|
||||
back-icon-color="#333333"
|
||||
title=""
|
||||
:border-bottom="false"
|
||||
:background="{ background: '#f0f0f0'}"
|
||||
z-index="1001">
|
||||
<view class="slot-wrap u-flex u-row-between u-col-center u-font-32">
|
||||
<view @click="changeMoreFlag(0)">
|
||||
<text>取消</text>
|
||||
</view>
|
||||
<view style="font-weight: bold;font-size: 34rpx;color: #000000;">
|
||||
<text>选择多个聊天</text>
|
||||
</view>
|
||||
<view>
|
||||
<view v-if="checkedUsers.length<1" style="border-radius: 10rpx;background-color: #dddddd;color: #909399;padding: 10rpx 20rpx;">
|
||||
<text>完成</text>
|
||||
</view>
|
||||
<view v-if="checkedUsers.length>0"
|
||||
@click="openZhuanFa()"
|
||||
style="border-radius: 10rpx;background-color: #19be6b;color: #ffffff;padding: 10rpx 20rpx;">
|
||||
<text>完成({{checkedUsers.length}})</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-navbar>
|
||||
|
||||
<view style="background-color: #f0f0f0;">
|
||||
<view v-if="checkedUsers.length<1" class="u-p-30">
|
||||
<view class="u-flex u-row-center u-col-center"
|
||||
style="background-color: #ffffff;height:70rpx;border-radius: 10rpx;color: #c0c0c0;">
|
||||
<view class="u-m-r-20">
|
||||
<u-icon class="u-clear-icon" top="6rpx" :size="40" name="search" color="#c0c0c0"></u-icon>
|
||||
</view>
|
||||
<view style="color: #c0c0c0;font-size: 34rpx;">搜索</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="u-p-30">
|
||||
<view class="u-flex u-row-left u-col-center"
|
||||
style="background-color: #ffffff;border-radius: 10rpx;color: #c0c0c0;">
|
||||
<view class="u-p-20" style="width: 400rpx;">
|
||||
<scroll-view class="hidden-scroll-bar"
|
||||
:scroll-into-view="scrollIntoViewId"
|
||||
:scroll-with-animation="true"
|
||||
:scroll-y="false" :scroll-x="true" style="width:400rpx;">
|
||||
<view class="u-flex u-row-left u-col-center">
|
||||
<view class="u-m-l-20"
|
||||
v-for="(checkeItem,index) in checkedUsers"
|
||||
:key="index">
|
||||
<view :id="'u-'+checkeItem.chatNumber"
|
||||
class="u-flex u-row-center u-col-center">
|
||||
<view>
|
||||
<u-image :src="checkeItem.avatar"
|
||||
:width="80" :height="80" :border-radius="12"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-p-l-30" v-if="checkedUsers.length<4" style="color: #909399;font-size: 34rpx;">
|
||||
<text>搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view v-if="checkedUsers.length>=4" class="u-p-l-30" style="color: #909399;font-size: 34rpx;" >
|
||||
<text>搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="u-p-30" v-if="latestZhuanFa.length>0">
|
||||
<view style="font-size: 30rpx;font-weight: bold;">
|
||||
<text>最近转发</text>
|
||||
</view>
|
||||
<view class="u-flex u-row-left u-col-center u-m-t-20" style="text-align: center;">
|
||||
<view class="u-m-r-40" v-for="(lastestItem,index) in latestZhuanFa" :key="index">
|
||||
<view class="u-flex u-row-center u-col-center">
|
||||
<view>
|
||||
<u-image :src="lastestItem.avatar"
|
||||
:width="100" :height="100" :border-radius="12"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-line-2 u-tips-color"
|
||||
style="width: 100rpx;height: 64rpx;line-height: 30rpx;font-size: 26rpx;padding: 8rpx;">
|
||||
<text>{{lastestItem.nickName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="u-p-30"
|
||||
style="background-color: #ffffff;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;">
|
||||
<view class="u-flex u-row-between u-col-center u-font-30">
|
||||
<view style="color: #000000;font-weight: bold;">
|
||||
<text>最近聊天</text>
|
||||
</view>
|
||||
<view style="color:#36648b;">
|
||||
<text>从通讯录选择</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="lastestChatUsers.length>0" class="u-m-t-30">
|
||||
<view v-for="(user,uIndex) in lastestChatUsers" :key="uIndex"
|
||||
class="u-flex u-row-left u-col-center u-m-b-20">
|
||||
<view>
|
||||
<u-checkbox :size="46" v-model="user.checked" @click.native="checkChange(user)"
|
||||
shape="circle" active-color="#19be6b"></u-checkbox>
|
||||
</view>
|
||||
<view class="u-flex u-row-left u-col-center u-p-b-20">
|
||||
<view style="width:90rpx;" class="u-flex u-row-center u-col-center">
|
||||
<view>
|
||||
<u-image :src="user.avatar" :width="76" :height="76" border-radius="8rpx"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-col-center u-p-20 u-border-bottom">
|
||||
<view style="text-align: left;">
|
||||
<view class="u-line-1" style="font-size: 32rpx;color: #000000;width: 480rpx;">
|
||||
<text>{{user.nickName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<u-popup v-model="openZhuanFaFlag" mode="center" border-radius="16"
|
||||
:mask-close-able="false"
|
||||
width="625rpx" :height="checkedUsers.length>3?'600rpx':'520rpx'">
|
||||
<view class="u-p-30">
|
||||
<view style="font-size: 34rpx;font-weight: bold;">
|
||||
<text>分别发送给:</text>
|
||||
</view>
|
||||
<view class="u-m-t-30">
|
||||
<view class="u-flex u-flex-wrap u-row-left u-col-center">
|
||||
<view v-for="(checkeItem,index) in checkedUsers" class="u-m-r-16 u-m-t-10"
|
||||
:key="index">
|
||||
<view class="u-flex u-row-center u-col-center">
|
||||
<view>
|
||||
<u-image :src="checkeItem.avatar"
|
||||
:width="80" :height="80" :border-radius="12"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-col-center u-m-t-30 u-p-t-30 u-p-b-10 u-tips-color u-border-top">
|
||||
<view>
|
||||
<text>[逐条转发]共{{selectedMessages.length>0?selectedMessages.length:2}}条信息</text>
|
||||
</view>
|
||||
<view>
|
||||
<u-icon name="arrow-right" size="32"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-20 u-p-b-20">
|
||||
<view style="background-color: #f7f7f7;width: 550rpx;padding:16rpx 20rpx;text-align: left;color: #909399;font-size: 30rpx;">
|
||||
<text>给朋友留言</text>
|
||||
</view>
|
||||
</view>
|
||||
<view style="position: absolute;width: 560rpx;bottom:30rpx;"
|
||||
class="u-flex u-row-between u-col-center u-font-34 u-p-t-30 u-border-top">
|
||||
<view style="color: #000000;text-align: center;width: 50%;">
|
||||
<view @click="cancelZhuanFa()">
|
||||
<text>取消</text>
|
||||
</view>
|
||||
</view>
|
||||
<view style="color: #36648b;text-align: center;width: 50%;">
|
||||
<view @click="confirmSend()">
|
||||
<text>发送({{checkedUsers.length}})</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<u-popup v-model="maxLengthFlag" mode="center" border-radius="16"
|
||||
:mask-close-able="false" height="300rpx"
|
||||
width="620rpx">
|
||||
<view style="text-align: center;font-weight: bold;font-size: 34rpx;">
|
||||
<view class="u-flex u-row-center u-col-center" style="width: 100%; height: 200rpx;">
|
||||
<view>
|
||||
<text>最多只能选择9个聊天</text>
|
||||
</view>
|
||||
</view>
|
||||
<view @click="maxLengthFlag=false"
|
||||
style="color: #36648b;padding-top:30rpx;padding-bottom: 30rpx; width: 100%;" class="u-border-top">
|
||||
<text>我知道了</text>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
moreFlag:false,
|
||||
scrollHidden:false,
|
||||
checkNum:0,
|
||||
latestZhuanFa:[],
|
||||
checkedUsers:[],
|
||||
scrollIntoViewId:"",
|
||||
lastestChatUsers:[],
|
||||
openZhuanFaFlag:false,
|
||||
maxLengthFlag:false,
|
||||
selectedMessages:[],
|
||||
};
|
||||
},
|
||||
onPageScroll:function(e){
|
||||
let top= e.scrollTop;
|
||||
let pageHeight= this.$u.sys().windowHeight;
|
||||
if((top/pageHeight)>0.25){
|
||||
console.log("隐藏");
|
||||
this.scrollHidden=true;
|
||||
}else{
|
||||
this.scrollHidden=false;
|
||||
}
|
||||
},
|
||||
onLoad:function(option){
|
||||
if(option.checkedMessages){
|
||||
this.selectedMessages=JSON.parse(decodeURIComponent(option.checkedMessages));
|
||||
this.selectedMessages[0].showTimeFlag=true;
|
||||
};
|
||||
this.checkedUsers=[];
|
||||
this.latestZhuanFa=this.vuex_lastestZhuanFaUsers;
|
||||
this.latestZhuanFa.map(function(item){
|
||||
item.checked=false;
|
||||
});
|
||||
this.lastestChatUsers=this.vuex_yyyFriendList.concat(this.latestZhuanFa);
|
||||
this.lastestChatUsers.map(function(item){
|
||||
item.checked=false;
|
||||
});
|
||||
},
|
||||
|
||||
methods:{
|
||||
goback:function(){
|
||||
uni.navigateBack();
|
||||
},
|
||||
changeMoreFlag:function(value){
|
||||
this.moreFlag=value;
|
||||
},
|
||||
checkChange:function(user){
|
||||
let that=this;
|
||||
let isExist = this.checkedUsers.some(item=>item.chatNumber===user.chatNumber);
|
||||
if(!isExist){
|
||||
if(that.checkedUsers.length>=9){
|
||||
this.maxLengthFlag=true;
|
||||
return;
|
||||
};
|
||||
this.checkedUsers.push(user);
|
||||
this.$nextTick(function(){
|
||||
that.scrollIntoViewId="u-"+user.chatNumber;
|
||||
})
|
||||
}else{
|
||||
this.checkedUsers = this.checkedUsers.filter(function(item) {
|
||||
return item.chatNumber!=user.chatNumber
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
openZhuanFa:function(){
|
||||
this.openZhuanFaFlag=true;
|
||||
},
|
||||
confirmSend:function(){
|
||||
let that=this;
|
||||
console.log("===选择的用户===",that.checkedUsers);
|
||||
console.log("===转发的信息===",that.selectedMessages);
|
||||
let lastMsg=that.selectedMessages[that.selectedMessages.length-1];
|
||||
let friendList=that.vuex_yyyFriendList;
|
||||
for (var i = 0; i < friendList.length; i++) {
|
||||
let friend= friendList[i];
|
||||
friend.checked=false;
|
||||
let isExist = that.checkedUsers.some(item=>item.chatNumber===friend.chatNumber);
|
||||
if(isExist){
|
||||
that.setLastMsgContent(friend,lastMsg,that.selectedMessages)
|
||||
}
|
||||
};
|
||||
that.$nextTick(function(){
|
||||
that.$u.vuex("vuex_yyyFriendList",friendList);
|
||||
that.openZhuanFaFlag=false;
|
||||
uni.navigateBack();
|
||||
});
|
||||
},
|
||||
cancelZhuanFa:function(){
|
||||
this.openZhuanFaFlag=false;
|
||||
},
|
||||
|
||||
setLastMsgContent:function(friend,message){
|
||||
let that=this;
|
||||
let formatContent="";
|
||||
let contentType=message.contentType;
|
||||
let contentObj=message.content;
|
||||
switch (contentType+""){
|
||||
case "1":
|
||||
formatContent=contentObj.text;
|
||||
formatContent=formatContent.replace(/face\[([^\s\[\]]+?)]/g, function(face) {
|
||||
return face.replace(/^face/g, '')
|
||||
});
|
||||
break;
|
||||
case "2":
|
||||
formatContent="[图片]";
|
||||
break;
|
||||
case "3":
|
||||
formatContent="[视频]";
|
||||
break;
|
||||
case "4":
|
||||
formatContent="[语音]";
|
||||
break;
|
||||
case "7":
|
||||
formatContent="[红包]";
|
||||
break;
|
||||
case "10":
|
||||
formatContent="[聊天记录]";
|
||||
break;
|
||||
case "11":
|
||||
formatContent="[图文]";
|
||||
break;
|
||||
case "12":
|
||||
formatContent="[视频文字]";
|
||||
break;
|
||||
default:
|
||||
formatContent="[其他]";
|
||||
break;
|
||||
};
|
||||
console.log("最后一条信息",formatContent);
|
||||
console.log("群号",friend.chatNumber);
|
||||
if(friend.chatNumber=="000000"){
|
||||
let obj={
|
||||
"lastMsgContent":formatContent,
|
||||
"messageList":that.selectedMessages,
|
||||
"lastMsgTime":message.createTime,
|
||||
};
|
||||
this.$u.vuex("vuex_fileAssist",obj);
|
||||
}else{
|
||||
friend.lastMsgContent=formatContent;
|
||||
friend.sendTimeStr=message.createTime;
|
||||
friend.messageList=that.selectedMessages;
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.slot-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* 如果您想让slot内容占满整个导航栏的宽度 */
|
||||
flex: 1;
|
||||
/* 如果您想让slot内容与导航栏左右有空隙 */
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<view>
|
||||
<view>
|
||||
<u-navbar :custom-back="goback" title=" " :background="{ background: '#ffffff' }" :border-bottom="false">
|
||||
<view class="slot-wrap" @click="toDetail()">
|
||||
<view>
|
||||
<u-icon name="more-dot-fill" color="#000000" :size="35"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</u-navbar>
|
||||
</view>
|
||||
<view class="friendInfo">
|
||||
<view class="img">
|
||||
<u-image :src="friendInfo.avatar"
|
||||
mode="aspectFill" width="120" height="120" border-radius="12">
|
||||
<u-loading slot="loading"></u-loading>
|
||||
<view slot="error"
|
||||
class="u-flex u-row-center u-col-center u-p-t-10"
|
||||
style="width: 90rpx;height: 90rpx;background-color: #f1f1f1;border-radius: 12rpx;">
|
||||
<view>
|
||||
<image src="/static/image/default/default-user/default-user.png"
|
||||
style="width: 64rpx;height: 64rpx;"></image>
|
||||
</view>
|
||||
</view>
|
||||
</u-image>
|
||||
</view>
|
||||
|
||||
<view class="friendInfo-desc">
|
||||
<view class="friendInfo-desc-name u-flex u-row-left u-col-center">
|
||||
<view class="u-line-2" style="font-size:42rpx;max-width: 400rpx;">
|
||||
<text>{{friendInfo.nickName}}</text>
|
||||
</view>
|
||||
<view class="u-m-l-10 u-flex u-row-center u-col-center u-p-b-10">
|
||||
<view>
|
||||
<u-image v-if="friendInfo.sex==1" src="/static/image/chat/addFriend/woman.png" width="34rpx" height="34rpx"></u-image>
|
||||
<u-image v-if="friendInfo.sex==0" src="/static/image/chat/addFriend/man.png" width="34rpx" height="34rpx"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="friendInfo-desc-gray u-line-1 u-m-b-4" style="max-width: 500rpx;">微信号:{{friendInfo.chatNumber}}</view>
|
||||
<view v-if="friendInfo.address&&friendInfo.address!=0&&friendInfo.address.length>0" class="friendInfo-desc-gray">地区:{{friendInfo.address}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-cell-group>
|
||||
<u-cell-item title="备注和标签" :title-style="titleStyle"></u-cell-item>
|
||||
<u-cell-item :border-bottom="false" title="朋友权限"
|
||||
:title-style="titleStyle" @click="setFiendPermission"></u-cell-item>
|
||||
<u-gap height="20" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
|
||||
<u-cell-item :title-style="titleStyle">
|
||||
<view slot="title" class="u-flex u-row-left u-col-center">
|
||||
<view>
|
||||
<text>朋友圈</text>
|
||||
</view>
|
||||
<view class="u-flex u-row-left u-col-center u-m-l-50"
|
||||
v-if="friendInfo.friendCircle&&friendInfo.friendCircle.length>0">
|
||||
<template v-for="(circle,index) in friendInfo.friendCircle.length">
|
||||
<view class="u-m-l-10" v-if="circle!=circle&&circle.length>0">
|
||||
<u-image :src="circle" :width="90" :height="90"></u-image>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</u-cell-item>
|
||||
<u-cell-item title="视频号" :title-style="titleStyle"></u-cell-item>
|
||||
<u-cell-item :border-bottom="false" title="更多信息" :title-style="titleStyle" @click="linkToMoreInfoMation"></u-cell-item>
|
||||
</u-cell-group>
|
||||
<u-gap height="20" bg-color="#eee" margin-top="0" margin-bottom="1"></u-gap>
|
||||
<view style="background-color: #ffffff;">
|
||||
<view class="u-flex u-row-center u-col-center u-p-30"
|
||||
style="font-size: 32rpx;color: #335f83;">
|
||||
<view class="u-m-r-20">
|
||||
<!-- width="36rpx" height="36rpx" -->
|
||||
<u-image src="/static/image/chat/sms-send.png" mode="aspectFit" width="40rpx" height="40rpx"></u-image>
|
||||
</view>
|
||||
<view style="font-weight: 450;">
|
||||
<text>发信息</text>
|
||||
</view>
|
||||
</view>
|
||||
<u-gap height="1" bg-color="#eee"></u-gap>
|
||||
<view class="u-flex u-row-center u-col-center u-p-30"
|
||||
style="font-size: 32rpx;color: #335f83;">
|
||||
<view class="u-m-r-20">
|
||||
<!-- src="/static/image/chat/yinshipin.jpg" width="40rpx" height="40rpx"-->
|
||||
<u-image src="/static/image/chat/video-call.png" mode="aspectFit" width="50rpx" height="50rpx"></u-image>
|
||||
</view>
|
||||
<view style="font-weight: 450;">
|
||||
<text>音视频通话</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-action-sheet :list="callList" v-model="callShow" @click="callClick"></u-action-sheet>
|
||||
<u-top-tips ref="uTips"></u-top-tips>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
titleStyle: {
|
||||
marginLeft: '10rpx',
|
||||
color: '#000000',
|
||||
fontSize: "34rpx",
|
||||
},
|
||||
friendInfo: {},
|
||||
callList:[
|
||||
{text: '视频通话'},
|
||||
{text: '语音通话'}
|
||||
],
|
||||
callShow:false,
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
let that=this;
|
||||
/* let param=JSON.parse(decodeURIComponent(option.personInfo));
|
||||
this.friendInfo=param; */
|
||||
this.friendInfo=this.yyy_current_user;
|
||||
//往好友里面塞
|
||||
let arr=JSON.parse(JSON.stringify(this.vuex_yyyFriendList));
|
||||
let isExist = arr.some(item=>item.chatNumber===this.friendInfo.chatNumber);
|
||||
if(!isExist){
|
||||
arr.push(this.friendInfo);
|
||||
};
|
||||
this.$u.vuex("vuex_yyyFriendList",arr);
|
||||
console.log("this.vuex_yyyFriendList=======",this.vuex_yyyFriendList);
|
||||
},
|
||||
methods: {
|
||||
goback(){
|
||||
console.log("自定义返回");
|
||||
uni.navigateBack({
|
||||
delta:3,
|
||||
animationType:"slide-out-right"
|
||||
});
|
||||
},
|
||||
//创建单聊会话
|
||||
createSingleChat:function(){
|
||||
let that=this;
|
||||
},
|
||||
//跳转聊天窗口
|
||||
linkToChatting:function(groupInfo) {
|
||||
let that=this;
|
||||
},
|
||||
//音视频弹窗
|
||||
toCall() {
|
||||
return;
|
||||
},
|
||||
//确认发起音视频
|
||||
callClick:function(index){
|
||||
this.globalUtil.utilAlert("不能进,没完事~敬请期待");
|
||||
},
|
||||
//设置标签
|
||||
setFiendTag() {
|
||||
this.globalUtil.utilAlert("不能进,没完事~敬请期待");
|
||||
return;
|
||||
},
|
||||
//设置朋友权限
|
||||
setFiendPermission() {
|
||||
this.globalUtil.utilAlert("不能进,没完事~敬请期待");
|
||||
return;
|
||||
},
|
||||
//查看朋友的朋友圈
|
||||
viewHisFiendCircle() {
|
||||
this.globalUtil.utilAlert("不能进,没完事~敬请期待");
|
||||
return;
|
||||
},
|
||||
//更多信息
|
||||
linkToMoreInfoMation() {
|
||||
this.$u.route({
|
||||
url: "/pages/tabbar/contact/friends/friend-more-info",
|
||||
params: {
|
||||
signature: this.friendInfo.signature
|
||||
}
|
||||
})
|
||||
},
|
||||
toDetail:function(){
|
||||
this.$u.route({
|
||||
url: "/pages/tabbar/contact/friends/friend-home-detail",
|
||||
params: {
|
||||
friendInfo:encodeURIComponent(JSON.stringify(this.friendInfo))
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.slot-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* 如果您想让slot内容占满整个导航栏的宽度 */
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
/* 如果您想让slot内容与导航栏左右有空隙 */
|
||||
padding: 0 30rpx;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.perch {
|
||||
height: 10rpx;
|
||||
}
|
||||
|
||||
.friendInfo {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
padding: 20rpx 30rpx 40rpx 40rpx;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
.img {
|
||||
display: block;
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
&-desc {
|
||||
padding-left: 30rpx;
|
||||
&-name {
|
||||
font-weight: bold;
|
||||
font-size: 36rpx;
|
||||
transform: translateY(-10rpx);
|
||||
color: #000000;
|
||||
}
|
||||
&-gray {
|
||||
color: #757575;
|
||||
font-size: 32rpx;
|
||||
font-weight: 420rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
page{
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar :is-back="true"
|
||||
back-icon-color="#ffffff"
|
||||
title="摇一摇"
|
||||
:background="{ background: '#101010'}"
|
||||
title-color="#ffffff"
|
||||
:title-bold="true"
|
||||
title-size="34"
|
||||
:border-bottom="false"
|
||||
z-index="1001">
|
||||
<view slot="right" class="u-p-r-30" @click="toSet()">
|
||||
<u-icon name="more-dot-fill" color="#ffffff" :size="36"></u-icon>
|
||||
</view>
|
||||
</u-navbar>
|
||||
|
||||
<view class="u-flex u-row-center u-col-center" style="padding-top: 60%;">
|
||||
<view>
|
||||
<u-image src="/static/image/wx/yaoyiyao-1.jpg" :width="200" :height="200"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="footer-box u-flex u-row-around u-col-center">
|
||||
<view @click="activeTab=0">
|
||||
<view class="u-flex u-row-center u-col-center">
|
||||
<view>
|
||||
<u-image v-if="activeTab==0" src="/static/image/wx/yaoyiyao-2.jpg" :width="48" :height="48"></u-image>
|
||||
<u-image v-if="activeTab==1" src="/static/image/wx/yaoyiyao-b.jpg" :width="48" :height="48"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-8" :style="activeTab==1?'color:#595959;':''">
|
||||
<text>人</text>
|
||||
</view>
|
||||
</view>
|
||||
<view @click="activeTab=1">
|
||||
<view class="u-flex u-row-center u-col-center">
|
||||
<view>
|
||||
<u-image v-if="activeTab==0" src="/static/image/wx/yaoyiyao-3.jpg" :width="48" :height="48"></u-image>
|
||||
<u-image v-if="activeTab==1" src="/static/image/wx/yaoyiyao-c.jpg" :width="48" :height="48"></u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-8" :style="activeTab==0?'color:#595959;':''">
|
||||
<text>歌曲和哼唱</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeTab:0,
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
toSet:function(){
|
||||
console.log("去摇一摇设置");
|
||||
uni.$u.route("/pages/find/shake/set");
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.footer-box{
|
||||
color: #ffffff;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 80rpx;
|
||||
padding: 20rpx 100rpx;
|
||||
text-align: center;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
page{
|
||||
background-color: #101010;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar :is-back="true"
|
||||
back-icon-color="#333333"
|
||||
title="打招呼的人"
|
||||
:background="{ background: '#f0f0f0'}"
|
||||
title-color="#000000"
|
||||
:title-bold="true"
|
||||
title-size="34"
|
||||
:border-bottom="false"
|
||||
z-index="1001">
|
||||
<view slot="right" class="u-p-r-30 u-font-34" @click="clear()">
|
||||
<text :style="linkedUsers.length<1?'color:#909399;':'color:#000000'">清空</text>
|
||||
</view>
|
||||
</u-navbar>
|
||||
<view class="u-p-30">
|
||||
<view v-if="linkedUsers.length>0">
|
||||
<view class="u-p-b-20">
|
||||
<text>近三天</text>
|
||||
</view>
|
||||
<view v-for="(user,uIndex) in linkedUsers" :key="uIndex"
|
||||
class="u-flex u-row-left u-col-center u-p-b-12">
|
||||
<view style="width:100rpx;" class="u-flex u-row-left u-col-center">
|
||||
<view @longpress="delUser(user,uIndex)">
|
||||
<u-image :src="user.avatar" :width="76" :height="76" border-radius="8rpx">
|
||||
<view slot="error"
|
||||
class="u-flex u-row-center u-col-center u-p-t-10 "
|
||||
style="width: 76rpx;height: 76rpx;background-color: #f0f0f0;border-radius: 12rpx;">
|
||||
<view>
|
||||
<image src="/static/image/default/default-user/default-user.png"
|
||||
style="width: 40rpx;height: 40rpx;"></image>
|
||||
</view>
|
||||
</view>
|
||||
</u-image>
|
||||
</view>
|
||||
</view>
|
||||
<view @click="toPersonInfo(user)"
|
||||
style="width: 600rpx;"
|
||||
class="u-flex u-row-between u-col-center u-p-t-6 u-p-b-12 u-border-bottom">
|
||||
<view style="text-align: left;">
|
||||
<view class="u-line-1" style="font-size: 32rpx;color: #000000;">
|
||||
<text>{{user.nickName}}</text>
|
||||
</view>
|
||||
<view class="u-tips-color u-font-28">
|
||||
<text>{{user.userRemark}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<template v-if="!idAdd(user)">
|
||||
<view style="background-color: #f0f0f0;color: #000000;padding: 10rpx 20rpx;border-radius: 6rpx;text-align: center;font-size: 30rpx;">
|
||||
<text>查看</text>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="u-font-28" style="position:relative;top: -16rpx;color: #595b5f;">
|
||||
<text>已添加</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else style="padding-top: 40%;">
|
||||
<view style="text-align: center;color: #000000;font-size: 34rpx;">
|
||||
<text>暂时没有人向你打招呼</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
linkedUsers:[],
|
||||
};
|
||||
},
|
||||
onLoad:function(){
|
||||
this.linkedUsers=JSON.parse(JSON.stringify(this.vuex_linkedUsers));
|
||||
},
|
||||
methods:{
|
||||
idAdd:function(user){
|
||||
let that=this;
|
||||
if(that.vuex_yyyFriendList.length<1){
|
||||
return false;
|
||||
}else{
|
||||
for (var i = 0; i < that.vuex_yyyFriendList.length; i++) {
|
||||
let item= that.vuex_yyyFriendList[i];
|
||||
if(item.chatNumber==user.chatNumber){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
clear:function(){
|
||||
this.$u.vuex("vuex_linkedUsers",[]);
|
||||
this.$u.vuex("vuex_yyyFriendList",[]);
|
||||
this.$u.vuex("vuex_lastestZhuanFaUsers",[]);
|
||||
this.$u.vuex("yyy_current_user",null);
|
||||
this.linkedUsers=[];
|
||||
},
|
||||
toPersonInfo:function(user){
|
||||
let that=this;
|
||||
that.$u.vuex("yyy_current_user",user);
|
||||
this.$u.route({
|
||||
url:'/pages/tabbar/find/yaoyiyao/yaoyiyao-user-detail',
|
||||
});
|
||||
},
|
||||
delUser:function(user,index){
|
||||
let that=this;
|
||||
uni.showModal({
|
||||
title: '操作',
|
||||
content: user.sendTimeStr,
|
||||
cancelText:'删除',
|
||||
confirmText:'修改时间',
|
||||
editable:true,
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
let newTime=res.content;
|
||||
if(newTime.length>0){
|
||||
that.linkedUsers[index].sendTimeStr=newTime;
|
||||
that.$u.vuex("vuex_linkedUsers",that.linkedUsers);
|
||||
}
|
||||
return;
|
||||
} else if (res.cancel) {
|
||||
that.linkedUsers.splice(index,1);
|
||||
that.$u.vuex("vuex_linkedUsers",that.linkedUsers);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,454 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-navbar :is-back="true"
|
||||
back-icon-color="#333333"
|
||||
title="摇一摇设置"
|
||||
:background="{ background: '#f0f0f0'}"
|
||||
title-color="#000000"
|
||||
:title-bold="true"
|
||||
title-size="34"
|
||||
:border-bottom="false"
|
||||
z-index="1001">
|
||||
</u-navbar>
|
||||
<view>
|
||||
<u-cell-group>
|
||||
<u-cell-item @click="showNewUserPop()" title="背景图片" :title-style="titleStyle"></u-cell-item>
|
||||
<u-cell-item title="音效" :title-style="titleStyle" :arrow="false">
|
||||
<u-switch slot="right-icon" size="48" active-color="#19BE6B" v-model="checked"></u-switch>
|
||||
</u-cell-item>
|
||||
<u-gap height="20" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
|
||||
<u-cell-item title="打招呼的人" :title-style="titleStyle" @click="toLinkedList()"></u-cell-item>
|
||||
<u-cell-item title="摇到的历史" @click="addAndUpdate()" :title-style="titleStyle"></u-cell-item>
|
||||
<u-gap height="20" bg-color="#eee" margin-top="1" margin-bottom="1"></u-gap>
|
||||
<u-cell-item title="摇一摇信息" :title-style="titleStyle" @click="toSetLatestUsers()"></u-cell-item>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
|
||||
<u-popup v-model="newLatestFlag" mode="right"
|
||||
safe-area-inset-bottom
|
||||
:mask-close-able="false"
|
||||
length="100%">
|
||||
<scroll-view class="u-p-30 u-p-t-80" scroll-y="true" style="height:85%;width: 700rpx;">
|
||||
<view>
|
||||
<u-collapse :head-style="{borderBottom:'1rpx solid #909399'}">
|
||||
<u-collapse-item :title="'第'+(index+1)+'位'"
|
||||
v-for="(newUser,index) in lastestZhuanFaUsers"
|
||||
:key="index">
|
||||
<view style="border: 1rpx solid #595b5f;padding: 10rpx 20rpx;">
|
||||
<u-form :model="newUser" :ref="'newUser-'+index"
|
||||
label-width="300rpx"
|
||||
label-position="top">
|
||||
<u-form-item label="姓名">
|
||||
<u-input v-model="newUser.nickName" />
|
||||
</u-form-item>
|
||||
<u-form-item label="微信号">
|
||||
<u-input v-model="newUser.chatNumber" />
|
||||
</u-form-item>
|
||||
<u-form-item label="头像">
|
||||
<u-input type="textarea" v-model="newUser.avatar" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
</u-collapse-item>
|
||||
</u-collapse>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="u-flex u-row-between u-col-center u-p-30">
|
||||
<u-button @click="addNewLatestUserItem()">新增</u-button>
|
||||
<u-button v-if="lastestZhuanFaUsers.length>1" @click="delNewLatestUser()">删除</u-button>
|
||||
<u-button type="success" @click="submitAddLatestUsers()">确定</u-button>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
|
||||
|
||||
<u-popup v-model="addAndUpdateFlag" mode="right"
|
||||
safe-area-inset-bottom
|
||||
:mask-close-able="false"
|
||||
length="100%">
|
||||
<scroll-view class="u-p-30 u-p-t-80" scroll-y="true" style="height:85%;width: 700rpx;">
|
||||
<view>
|
||||
<u-collapse :head-style="{borderBottom:'1rpx solid #909399'}">
|
||||
<u-collapse-item :title="'第'+(index+1)+'位'"
|
||||
v-for="(newUser,index) in newUsers"
|
||||
:key="index">
|
||||
<view style="border: 1rpx solid #595b5f;padding: 10rpx 20rpx;">
|
||||
<u-form :model="newUser" :ref="'newUser-'+index"
|
||||
label-width="300rpx"
|
||||
label-position="top">
|
||||
<u-form-item label="姓名">
|
||||
<u-input :maxlength="-1" v-model="newUser.nickName" />
|
||||
</u-form-item>
|
||||
<u-form-item label="微信号">
|
||||
<u-input :maxlength="-1" placeholder="不能与其他重复!" v-model="newUser.chatNumber" />
|
||||
</u-form-item>
|
||||
<u-form-item label="头像">
|
||||
<u-input :maxlength="-1" type="textarea" v-model="newUser.avatar" />
|
||||
</u-form-item>
|
||||
<u-form-item label="地区(注意空格)">
|
||||
<u-input :maxlength="-1" placeholder="注意格式,如: 广东 广州" v-model="newUser.address" />
|
||||
</u-form-item>
|
||||
<u-form-item label="个性签名">
|
||||
<u-input :maxlength="-1" v-model="newUser.signature" />
|
||||
</u-form-item>
|
||||
<u-form-item label="给你打招呼的内容">
|
||||
<u-input :maxlength="-1" type="textarea" v-model="newUser.userRemark" />
|
||||
</u-form-item>
|
||||
<u-form-item label="给你打招呼的时间">
|
||||
<u-input :maxlength="-1" placeholder="注意格式,如: 22:30" v-model="newUser.createTime" />
|
||||
</u-form-item>
|
||||
<u-form-item label="你通过好友时间">
|
||||
<u-input :maxlength="-1" placeholder="注意格式,如: 22:35" v-model="newUser.sendTimeStr" />
|
||||
</u-form-item>
|
||||
<u-form-item label="第一条朋友圈">
|
||||
<u-input type="textarea" :maxlength="-1" v-model="newUser.friendCircle[0]" />
|
||||
</u-form-item>
|
||||
<u-form-item label="第二条朋友圈">
|
||||
<u-input type="textarea" :maxlength="-1" v-model="newUser.friendCircle[1]" />
|
||||
</u-form-item>
|
||||
<u-form-item label="第三条朋友圈">
|
||||
<u-input type="textarea" :maxlength="-1" v-model="newUser.friendCircle[2]" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
</u-collapse-item>
|
||||
</u-collapse>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="u-flex u-row-between u-col-center u-p-30">
|
||||
<u-button @click="addNewUserItem()">新增</u-button>
|
||||
<u-button v-if="newUsers.length>1" @click="delNewUser()">删除</u-button>
|
||||
<u-button type="success" @click="submitAddUsers()">确定</u-button>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
|
||||
|
||||
<u-popup v-model="newUserPopFlag" mode="right"
|
||||
safe-area-inset-bottom
|
||||
:mask-close-able="false"
|
||||
length="100%">
|
||||
<view style="padding-top:15%;">
|
||||
<view class="u-border-top">
|
||||
<u-field v-model="count"
|
||||
type="number"
|
||||
label="本次录入数量" label-width="200rpx"
|
||||
placeholder="录入数量,建议5-10个"></u-field>
|
||||
</view>
|
||||
<view v-if="count<1" class="u-p-30 u-font-32" style="font-weight: bold;">
|
||||
<view>填入数量决定了下面录入的每项信息的数量 !!!</view>
|
||||
<view class="u-m-t-10">比如5个,那么必须填入5个人的信息,每个用%%隔开 ! </view>
|
||||
<view class="u-m-t-10">不能多! 也不能少! 没有信息的填0 !</view>
|
||||
<view>地址为例: "广东 广州,0,湖北 武汉,四川 城都,福建 厦门" </view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="count>0">
|
||||
<scroll-view class="u-p-30 u-p-t-80"
|
||||
scroll-y="true" style="height:80%;width: 700rpx;">
|
||||
<view style="padding:10rpx 20rpx;">
|
||||
<u-form :model="propArrObj" :border-bottom="false"
|
||||
label-width="300rpx"
|
||||
label-position="top">
|
||||
<u-form-item label="姓名">
|
||||
<u-input placeholder="格式: (张三%%李四%%王五)"
|
||||
type="textarea" :maxlength="-1"
|
||||
:height="300" border
|
||||
v-model="propArrObj.nickNameStr" />
|
||||
</u-form-item>
|
||||
<u-form-item label="微信号">
|
||||
<u-input placeholder="格式: (666666%%aaaaaa%%zzzzzz)"
|
||||
type="textarea" :maxlength="-1"
|
||||
:height="200" border
|
||||
v-model="propArrObj.chatNumberStr" />
|
||||
</u-form-item>
|
||||
<u-form-item label="头像">
|
||||
<u-input placeholder="格式: (xxx.jpg%%yyy.jpg%%%zzz%%jpg)"
|
||||
type="textarea" :maxlength="-1"
|
||||
:height="300" border
|
||||
v-model="propArrObj.avatarStr" />
|
||||
</u-form-item>
|
||||
<u-form-item label="个性签名">
|
||||
<u-input placeholder="格式: (哈哈哈%%嘻嘻嘻%%哇哇哇)"
|
||||
type="textarea" :maxlength="-1"
|
||||
:height="200" border
|
||||
v-model="propArrObj.signatureStr" />
|
||||
</u-form-item>
|
||||
<u-form-item label="打招呼的内容">
|
||||
<u-input placeholder="格式: (哈喽%%你好%%hello)"
|
||||
type="textarea" :maxlength="-1"
|
||||
:height="200" border
|
||||
v-model="propArrObj.userRemarkStr" />
|
||||
</u-form-item>
|
||||
<u-form-item label="地址">
|
||||
<u-input placeholder="每个值用%%隔开!没有地址的用0代替"
|
||||
type="textarea" :maxlength="-1"
|
||||
:height="100" border
|
||||
v-model="propArrObj.addressStr" />
|
||||
</u-form-item>
|
||||
<u-form-item label="打招呼时间">
|
||||
<u-input placeholder="格式: (12:01%%12:02%%12:03)"
|
||||
type="textarea" :maxlength="-1"
|
||||
:height="100" border
|
||||
v-model="propArrObj.createTimeStr" />
|
||||
</u-form-item>
|
||||
<u-form-item label="加好友时间">
|
||||
<u-input placeholder="格式: (12:01%%12:02%%12:03)"
|
||||
type="textarea" :maxlength="-1"
|
||||
:height="100" border
|
||||
v-model="propArrObj.sendTimeStr" />
|
||||
</u-form-item>
|
||||
<u-form-item label="朋友圈">
|
||||
<u-input placeholder="格式: ([xxx.jpg%%yyy.jpg,zzz.jpg]%%[111.jpg,222.jpg]%%[]%%[333.jpg])"
|
||||
type="textarea" :maxlength="-1"
|
||||
:height="300" border
|
||||
v-model="propArrObj.friendCircleStr" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="u-flex u-row-between u-col-center u-p-30">
|
||||
<u-button @click="cancelAdd()">取消</u-button>
|
||||
<u-button type="success" @click="submitAdd()">确定</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
titleStyle:{
|
||||
fontSize:"34rpx",
|
||||
color:'#000000'
|
||||
},
|
||||
linkedUsers:[], //摇一摇的人
|
||||
addAndUpdateFlag:false, //新增
|
||||
newUsers:[
|
||||
{
|
||||
id:new Date().getTime(),
|
||||
avatar:'',
|
||||
chatNumber:'',
|
||||
nickName:'',
|
||||
signature:'',
|
||||
userRemark:'',
|
||||
address:'',
|
||||
sex:0,
|
||||
friendPower:0,
|
||||
forbidSelf:false,
|
||||
forbidHis:false,
|
||||
createTime:"",
|
||||
sendTimeStr:"",
|
||||
lastMsgContent:'',
|
||||
delFlag:false,
|
||||
friendCircle:["","",""],
|
||||
messageList:[],
|
||||
},
|
||||
],
|
||||
checked:true,
|
||||
newLatestFlag:false,
|
||||
lastestZhuanFaUsers:[
|
||||
{
|
||||
id:'1',
|
||||
avatar:'/static/image/default/default-user/1.jpg',
|
||||
chatNumber:'qwe',
|
||||
nickName:'猫先生',
|
||||
}
|
||||
],
|
||||
//--------------------------------------
|
||||
newUserPopFlag:false,
|
||||
count:5,
|
||||
propArrObj:{
|
||||
nickNameStr:"",
|
||||
chatNumberStr:"",
|
||||
avatarStr:"",
|
||||
signatureStr:"",
|
||||
userRemarkStr:"",
|
||||
addressStr:"",
|
||||
createTimeStr:"",
|
||||
sendTimeStr:"",
|
||||
friendCircleStr:"",
|
||||
}
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
toSetLatestUsers:function(){
|
||||
if(this.vuex_lastestZhuanFaUsers.length>0){
|
||||
this.lastestZhuanFaUsers=JSON.parse(JSON.stringify(this.vuex_lastestZhuanFaUsers));
|
||||
}
|
||||
this.newLatestFlag=true;
|
||||
},
|
||||
addNewLatestUserItem:function(){
|
||||
let obj={
|
||||
id:new Date().getTime(),
|
||||
avatar:'',
|
||||
chatNumber:'',
|
||||
nickName:'',
|
||||
};
|
||||
this.lastestZhuanFaUsers.push(obj);
|
||||
},
|
||||
delNewLatestUser:function(){
|
||||
this.lastestZhuanFaUsers.splice(this.lastestZhuanFaUsers.length-1,1);
|
||||
},
|
||||
submitAddLatestUsers:function(){
|
||||
let that=this;
|
||||
this.$u.vuex("vuex_lastestZhuanFaUsers",this.lastestZhuanFaUsers);
|
||||
this.newLatestFlag=false;
|
||||
},
|
||||
addAndUpdate:function(){
|
||||
let that=this;
|
||||
that.addAndUpdateFlag=true
|
||||
},
|
||||
addNewUserItem:function(){
|
||||
let oldObj= this.newUsers[this.newUsers.length-1];
|
||||
let obj={
|
||||
id:new Date().getTime(),
|
||||
avatar:'',
|
||||
chatNumber:'',
|
||||
nickName:'',
|
||||
signature:'',
|
||||
userRemark:'',
|
||||
address:'',
|
||||
sex:0,
|
||||
friendPower:0,
|
||||
forbidSelf:false,
|
||||
forbidHis:false,
|
||||
createTime:oldObj.createTime,
|
||||
sendTimeStr:oldObj.sendTimeStr,
|
||||
lastMsgContent:'',
|
||||
delFlag:false,
|
||||
friendCircle:["","",""],
|
||||
messageList:[],
|
||||
};
|
||||
//this.newUsers.push(obj);
|
||||
this.newUsers.unshift(obj);
|
||||
},
|
||||
delNewUser:function(){
|
||||
this.newUsers.splice(this.newUsers.length-1,1);
|
||||
},
|
||||
submitAddUsers:function(){
|
||||
let that=this;
|
||||
uni.showModal({
|
||||
title: '确认提示',
|
||||
content: '请认真检查各项填入内容!',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
that.addAndUpdateFlag = false;
|
||||
that.linkedUsers=that.newUsers.concat(that.linkedUsers);
|
||||
that.newUsers=[
|
||||
{
|
||||
id:new Date().getTime(),
|
||||
avatar:'',
|
||||
chatNumber:'',
|
||||
nickName:'',
|
||||
signature:'',
|
||||
userRemark:'',
|
||||
address:'',
|
||||
sex:0,
|
||||
friendPower:0,
|
||||
forbidSelf:false,
|
||||
forbidHis:false,
|
||||
createTime:'',
|
||||
sendTimeStr:'',
|
||||
lastMsgContent:'',
|
||||
delFlag:false,
|
||||
friendCircle:["","",""],
|
||||
messageList:[],
|
||||
},
|
||||
]
|
||||
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
toLinkedList:function(){
|
||||
let arr=JSON.parse(JSON.stringify(this.vuex_linkedUsers));
|
||||
let newLinkedUsers=this.linkedUsers.concat(arr);
|
||||
console.log("去摇一摇设置",newLinkedUsers);
|
||||
this.$u.vuex("vuex_linkedUsers",newLinkedUsers);
|
||||
this.linkedUsers=[];
|
||||
this.$u.route("/pages/tabbar/find/yaoyiyao/yaoyiyao-linked-list");
|
||||
},
|
||||
//------------------------------------------------------------------------------------------------
|
||||
showNewUserPop:function(){
|
||||
this.newUserPopFlag=true;
|
||||
},
|
||||
|
||||
cancelAdd:function(){
|
||||
this.newUserPopFlag=false;
|
||||
},
|
||||
|
||||
submitAdd:function(){
|
||||
let that=this;
|
||||
let keys= Object.keys(that.propArrObj);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let key= keys[i];
|
||||
let keyValue= that.propArrObj[key];
|
||||
let valueArr= keyValue.split("%%");
|
||||
if(valueArr.length!=that.count){
|
||||
this.globalUtil.utilAlert("第"+(i+1)+"项录入信息有误!["+key+"]");
|
||||
return;
|
||||
}
|
||||
}
|
||||
that.muchCreateUser();
|
||||
},
|
||||
|
||||
muchCreateUser(){
|
||||
let that=this;
|
||||
let arr=[];
|
||||
for (var i = 0; i < this.count; i++) {
|
||||
let item={
|
||||
id:"u-"+i,
|
||||
avatar:that.propArrObj.avatarStr.split("%%")[i],
|
||||
chatNumber:that.propArrObj.chatNumberStr.split("%%")[i],
|
||||
nickName:that.propArrObj.nickNameStr.split("%%")[i],
|
||||
signature:that.propArrObj.signatureStr.split("%%")[i],
|
||||
userRemark:that.propArrObj.userRemarkStr.split("%%")[i],
|
||||
address:that.propArrObj.addressStr.split("%%")[i],
|
||||
createTime:that.propArrObj.createTimeStr.split("%%")[i],
|
||||
sendTimeStr:that.propArrObj.sendTimeStr.split("%%")[i],
|
||||
friendCircle:that.propArrObj.friendCircleStr.split("%%")[i],
|
||||
lastMsgContent:"",
|
||||
messageList:[],
|
||||
sex:0,
|
||||
friendPower:0,
|
||||
forbidSelf:false,
|
||||
forbidHis:false,
|
||||
delFlag:false,
|
||||
};
|
||||
arr.push(item);
|
||||
}
|
||||
console.log("====arr====",arr);
|
||||
that.linkedUsers=arr.concat(that.linkedUsers);
|
||||
this.count=0;
|
||||
this.propArrObj={
|
||||
avatarStr:"",
|
||||
chatNumberStr:"",
|
||||
nickNameStr:"",
|
||||
signatureStr:"",
|
||||
userRemarkStr:"",
|
||||
addressStr:"",
|
||||
createTimeStr:"",
|
||||
sendTimeStr:"",
|
||||
friendCircleStr:"",
|
||||
};
|
||||
that.newUserPopFlag=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
<style>
|
||||
page{
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user