This commit is contained in:
cansnow
2026-01-01 04:15:30 +08:00
parent 09c7889525
commit 78386d4cc1
75 changed files with 1995 additions and 1715 deletions
+2
View File
@@ -44,3 +44,5 @@ OpenIM_*
# plugin # plugin
/nativeplugins /nativeplugins
android-keeplive
sl-notify
+24 -384
View File
@@ -1,417 +1,57 @@
<script> <script>
import {mapGetters,mapActions} from "vuex"; import IMSDK from "openim-uniapp-polyfill";
import IMSDK, {IMMethods,MessageType,SessionType,} from "openim-uniapp-polyfill";
import config from "./common/config";
import {getDbDir,toastWithCallback} from "@/util/common.js";
import {conversationSort} from "@/util/imCommon";
import {checkUpgrade} from "@/api/login.js"
import {PageEvents,UpdateMessageTypes} from "@/constant";
export default { export default {
onLaunch: function() { onLaunch: function() {
console.log("App Launch");
// #ifndef APP // #ifndef APP
console.error( console.error(
`暂时不支持运行到 Web或小程序端,如果需要移动端的 Web 项目,参考 [H5 demo](https://github.com/openimsdk/openim-h5-demo)` `暂时不支持运行到 Web或小程序端,如果需要移动端的 Web 项目,参考 [H5 demo](https://github.com/openimsdk/openim-h5-demo)`
); );
return ; return ;
// #endif // #endif
// #ifdef APP this.init();
this.checkUpdate();
this.setGlobalIMlistener();
this.tryLogin();
// #endif
}, },
onShow: function() { onShow: function() {
console.log("App Show"); var args= plus.runtime.arguments;
if(args){
// 处理args参数,如直达到某新页面等
console.log(args);
}
//console.log("App Show");
// #ifdef APP // #ifdef APP
IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), false); IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), false);
// #endif // #endif
//console.log(this.$store.state.contact);
}, },
onHide: function() { onHide: function() {
console.log("App Hide"); //console.log("App Hide");
// #ifdef APP // #ifdef APP
IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), true); IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), true);
// #endif // #endif
}, },
computed: {
...mapGetters([
"storeConversationList",
"storeCurrentConversation",
"storeCurrentUserID",
"storeSelfInfo",
"storeRecvFriendApplications",
"storeRecvGroupApplications",
"storeHistoryMessageList",
"storeIsSyncing",
"storeGroupList",
]),
},
methods: { methods: {
...mapActions("message", ["pushNewMessage", "updateOneMessage"]), init(){
...mapActions("conversation", ["updateCurrentMemberInGroup"]),
...mapActions("circle", ["getFriendCircleInfo"]),
...mapActions("contact", [
"updateFriendInfo",
"pushNewFriend",
"updateBlackInfo",
"pushNewBlack",
"pushNewGroup",
"updateGroupInfo",
"pushNewRecvFriendApplition",
"updateRecvFriendApplition",
"pushNewSentFriendApplition",
"updateSentFriendApplition",
"pushNewRecvGroupApplition",
"updateRecvGroupApplition",
"pushNewSentGroupApplition",
"updateSentGroupApplition",
]),
setGlobalIMlistener() {
this.$store.dispatch("system/getConfig"); this.$store.dispatch("system/getConfig");
console.log("setGlobalIMlistener"); const IMToken = uni.getStorageSync("IMToken");
// init const IMUserID = uni.getStorageSync("IMUserID")+'';
const kickHander = (message) => { if (IMToken && IMUserID) {
toastWithCallback(message, () => { uni.navigateTo({
uni.removeStorage({ url: "/pages/index/launch"
key: "IMToken",
});
uni.removeStorage({
key: "BusinessToken",
});
uni.$u.route("/pages/common/login/index");
}); });
}; }else{
IMSDK.subscribe(IMSDK.IMEvents.OnKickedOffline, (data) => { uni.navigateTo({
kickHander("您的账号在其他设备登录,请重新登陆!"); url: "/pages/common/login/index"
});
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");
this.$store.dispatch("contact/getFriendList");
this.$store.dispatch("contact/getGrouplist");
this.$store.dispatch("conversation/getUnReadCount");
this.$store.commit("user/SET_IS_SYNCING", false);
};
const syncFailedHandler = () => {
uni.hideLoading();
uni.$u.toast("同步消息失败");
this.$store.dispatch("conversation/getConversationList");
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}) => {
this.$store.commit("user/SET_SELF_INFO", {
...this.storeSelfInfo,
...data,
}); });
};
IMSDK.subscribe(IMSDK.IMEvents.OnSelfInfoUpdated, selfInfoUpdateHandler);
// message
const newMessagesHandler = ({data}) => {
if (this.storeIsSyncing) {
return;
}
data.forEach(this.handleNewMessage);
};
IMSDK.subscribe(IMSDK.IMEvents.OnRecvNewMessages, newMessagesHandler);
// friend
const friendInfoChangeHandler = ({data}) => {
console.log('friendInfoChangeHandler',data);
uni.$emit(IMSDK.IMEvents.OnFriendInfoChanged, {data});
this.updateFriendInfo({friendInfo: data,});
};
const friendAddedHandler = ({data}) => {
this.pushNewFriend(data);
};
const friendDeletedHander = ({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}) => {
this.pushNewBlack(data);
};
const blackDeletedHandler = ({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);
};
const joinedGroupDeletedHandler = ({data}) => {
this.updateGroupInfo({
groupInfo: data,
isRemove: true,
});
};
const groupInfoChangedHandler = ({data}) => {
this.updateGroupInfo({
groupInfo: data,
});
};
const groupMemberInfoChangedHandler = ({data}) => {
uni.$emit(IMSDK.IMEvents.OnGroupMemberInfoChanged, {data});
if (data.groupID === this.storeCurrentConversation?.groupID) {
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;
if (isRecv) {
this.pushNewRecvFriendApplition(data);
} else {
this.pushNewSentFriendApplition(data);
}
};
const friendApplicationAccessHandler = ({data}) => {
const isRecv = data.toUserID === this.storeCurrentUserID;
if (isRecv) {
this.updateRecvFriendApplition({
application: data,
});
} else {
this.updateSentFriendApplition({
application: data,
});
}
};
const groupApplicationNumHandler = ({data}) => {
const isRecv = data.userID !== this.storeCurrentUserID;
if (isRecv) {
this.pushNewRecvGroupApplition(data);
} else {
this.pushNewSentGroupApplition(data);
}
};
const groupApplicationAccessHandler = ({data}) => {
const isRecv = data.userID !== this.storeCurrentUserID;
if (isRecv) {
this.updateRecvGroupApplition({
application: data,
});
} else {
this.updateSentGroupApplition({
application: data,
});
}
};
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);
// conversation
const totalUnreadCountChangedHandler = ({data}) => {
if (this.storeIsSyncing) {
return;
}
this.$store.commit("conversation/SET_UNREAD_COUNT", data);
};
const newConversationHandler = ({data}) => {
if (this.storeIsSyncing) {
return;
}
const result = [...data, ...this.storeConversationList];
this.$store.commit(
"conversation/SET_CONVERSATION_LIST",
conversationSort(result)
);
};
const conversationChangedHandler = ({data}) => {
//console.log('conversationChangedHandler',data);
if (this.storeIsSyncing) {
return;
}
let filterArr = [];
//console.log(data);
const chids = data.map((ch) => ch.conversationID);
filterArr = this.storeConversationList.filter((tc) => !chids.includes(tc.conversationID));
const idx = data.findIndex((c) =>c.conversationID === this.storeCurrentConversation.conversationID);
if (idx !== -1){
this.$store.commit("conversation/SET_CURRENT_CONVERSATION",data[idx]);
}
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"
});
};
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,
});
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();
});
},
handleNewMessage(newServerMsg) {
if (this.inCurrentConversation(newServerMsg)) {
if (
newServerMsg.contentType !== MessageType.TypingMessage &&
newServerMsg.contentType !== MessageType.RevokeMessage
) {
newServerMsg.isAppend = true;
this.pushNewMessage(newServerMsg);
setTimeout(() => uni.$emit(PageEvents.ScrollToBottom, true));
uni.$u.debounce(this.markConversationAsRead, 2000);
}
} }
}, }
inCurrentConversation(newServerMsg) { }
switch (newServerMsg.sessionType) {
case SessionType.Single:
return (
newServerMsg.sendID === this.storeCurrentConversation.userID ||
(newServerMsg.sendID === this.storeCurrentUserID &&
newServerMsg.recvID === this.storeCurrentConversation.userID)
);
case SessionType.WorkingGroup:
return newServerMsg.groupID === this.storeCurrentConversation.groupID;
case SessionType.Notification:
return newServerMsg.sendID === this.storeCurrentConversation.userID;
default:
return false;
}
},
markConversationAsRead() {
IMSDK.asyncApi(
IMSDK.IMMethods.MarkConversationMessageAsRead,
IMSDK.uuid(),
this.storeCurrentConversation.conversationID
);
},
// 验证是否升级
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')
}
})
})
},
},
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
/*每个页面公共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 "@/uni_modules/uview-ui/index.scss";
@import "@/styles/login.scss"; @import "@/styles/login.scss";
@import "@/styles/global.scss"; @import "@/styles/global.scss";
+1
View File
@@ -1,4 +1,5 @@
``` ```
安卓App Key:7105a186f961b5d418914c5d1b12f6af
n1e5a6s6m7 n1e5a6s6m7
``` ```
``` ```
BIN
View File
Binary file not shown.
+68 -80
View File
@@ -1,92 +1,80 @@
<template> <template>
<u-navbar :title="title" placeholder class="custom_nav_bar"> <u-navbar :title="title" placeholder class="custom_nav_bar">
<template slot="left"> <template slot="left">
<slot name="left"> <slot name="left">
<view class="u-nav-slot"> <view class="u-nav-slot">
<img <img @click="leftClick" class="back_icon" width="12" height="20"
@click="leftClick" src="static/images/common_left_arrow.png" alt="" srcset="" />
class="back_icon" </view>
width="12" </slot>
height="20" </template>
src="static/images/common_left_arrow.png"
alt=""
srcset=""
/>
</view>
</slot>
</template>
<template slot="center"> <template slot="center">
<slot name="center"></slot> <slot name="center"></slot>
</template> </template>
<template slot="right"> <template slot="right">
<slot name="more"> <slot name="more">
<view @click="rightClick" v-if="more" class="u-nav-slot"> <view @click="rightClick" v-if="more" class="u-nav-slot">
<u-icon <u-icon class="more_dot" name="more-dot-fill" size="23" color="#0C1C33"></u-icon>
class="more_dot" </view>
name="more-dot-fill" </slot>
size="23" </template>
color="#0C1C33" </u-navbar>
></u-icon>
</view>
</slot>
</template>
</u-navbar>
</template> </template>
<script> <script>
export default { export default {
name: "", name: "",
components: {}, components: {},
props: { props: {
title: { title: {
type: String, type: String,
}, },
more: { more: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
route: { route: {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
}, },
data() { data() {
return {}; return {};
}, },
methods: { methods: {
leftClick() { leftClick() {
if (this.route) { if (this.route) {
uni.navigateBack(); uni.navigateBack();
} }
this.$emit("leftClick"); this.$emit("leftClick");
}, },
rightClick() { rightClick() {
this.$emit("rightClick"); this.$emit("rightClick");
}, },
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.custom_nav_bar { .custom_nav_bar {
::v-deep .u-navbar__content__left { ::v-deep .u-navbar__content__left {
padding: 0; padding: 0;
} }
::v-deep .u-navbar__content__right { ::v-deep .u-navbar__content__right {
padding: 0; padding: 0;
} }
.back_icon { .back_icon {
padding: 24rpx; padding: 24rpx;
margin-left: 20rpx; margin-left: 20rpx;
} }
.more_dot { .more_dot {
padding: 24rpx; padding: 24rpx;
margin-right: 20rpx; margin-right: 20rpx;
} }
} }
</style> </style>
-155
View File
@@ -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>
+1 -1
View File
@@ -53,7 +53,7 @@ const app = new Vue({
...App, ...App,
}); });
app.REQUEST_TRACE = process.env.NODE_ENV == 'development'; app.REQUEST_TRACE = process.env.NODE_ENV == 'development';
//app.REQUEST_TRACE = false; app.REQUEST_TRACE = false;
// 引入请求封装 // 引入请求封装
import request from "./util/request/index"; import request from "./util/request/index";
+33 -10
View File
@@ -1,7 +1,7 @@
{ {
"name" : "回声", "name" : "瞬聊",
"appid" : "__UNI__CA458BA", "appid" : "__UNI__E41111F",
"description" : "", "description" : "一款即时聊天软件",
"versionName" : "3.3.5", "versionName" : "3.3.5",
"versionCode" : 335, "versionCode" : 335,
"transformPx" : false, "transformPx" : false,
@@ -23,7 +23,8 @@
"Geolocation" : {}, "Geolocation" : {},
"Fingerprint" : {}, "Fingerprint" : {},
"Contacts" : {}, "Contacts" : {},
"Barcode" : {} "Barcode" : {},
"Push" : {}
}, },
"distribute" : { "distribute" : {
"android" : { "android" : {
@@ -48,12 +49,13 @@
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>", "<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\"/>"
], ],
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ], "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
"minSdkVersion" : 21, "minSdkVersion" : 21,
"targetSdkVersion" : 26, "targetSdkVersion" : 26,
"schemes" : "huisheng" "schemes" : "shunliao"
}, },
"ios" : { "ios" : {
"dSYMs" : false, "dSYMs" : false,
@@ -69,11 +71,11 @@
}, },
"capabilities" : { "capabilities" : {
"entitlements" : { "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, "idfa" : false,
"urltypes" : "huisheng" "urltypes" : "shunliao"
}, },
"sdkConfigs" : { "sdkConfigs" : {
"ad" : {}, "ad" : {},
@@ -91,7 +93,22 @@
}, },
"share" : {}, "share" : {},
"statics" : {}, "statics" : {},
"speech" : {} "speech" : {},
"push" : {
"unipush" : {
"version" : "2",
"offline" : true,
"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" : { "splashscreen" : {
"androidStyle" : "default", "androidStyle" : "default",
@@ -163,7 +180,10 @@
"setting" : { "setting" : {
"urlCheck" : false "urlCheck" : false
}, },
"usingComponents" : true "usingComponents" : true,
"unipush" : {
"enable" : true
}
}, },
"mp-alipay" : { "mp-alipay" : {
"usingComponents" : true "usingComponents" : true
@@ -199,6 +219,9 @@
"treeShaking" : { "treeShaking" : {
"enable" : true "enable" : true
} }
},
"unipush" : {
"enable" : true
} }
} }
} }
+2 -1
View File
@@ -1,12 +1,13 @@
{ {
"dependencies": { "dependencies": {
"@openim/client-sdk": "^0.0.11-ahpha.1", "@openim/client-sdk": "^0.0.11-ahpha.1",
"crypto-js": "^4.2.0",
"date-fns": "^2.30.0", "date-fns": "^2.30.0",
"dayjs": "^1.11.6", "dayjs": "^1.11.6",
"grapheme-splitter": "^1.0.4", "grapheme-splitter": "^1.0.4",
"image-tools": "^1.4.0", "image-tools": "^1.4.0",
"md5": "^2.3.0", "md5": "^2.3.0",
"openim-uniapp-polyfill": "^1.4.1", "openim-uniapp-polyfill": "^1.4.4",
"uuid": "^9.0.0" "uuid": "^9.0.0"
} }
} }
+12
View File
@@ -1,5 +1,17 @@
{ {
"pages": [ "pages": [
{
"path": "pages/index/guide",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/index/launch",
"style": {
"navigationBarTitleText": ""
}
},
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{ {
"path": "pages/common/login/index" "path": "pages/common/login/index"
+1 -5
View File
@@ -48,11 +48,7 @@
<script> <script>
import { ContactChooseTypes } from "@/constant"; import { ContactChooseTypes } from "@/constant";
import IMSDK, { import IMSDK, {GroupType,IMMethods,SessionType,} from "openim-uniapp-polyfill";
GroupType,
IMMethods,
SessionType,
} from "openim-uniapp-polyfill";
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import MyAvatar from "@/components/MyAvatar/index.vue"; import MyAvatar from "@/components/MyAvatar/index.vue";
import { navigateToDesignatedConversation } from "@/util/imCommon"; import { navigateToDesignatedConversation } from "@/util/imCommon";
+81 -82
View File
@@ -1,94 +1,93 @@
<template> <template>
<view class="details_container"> <view class="details_container">
<custom-nav-bar title="个人资料" /> <custom-nav-bar title="个人资料" />
<view class="info_list"> <view class="info_list">
<user-info-row-item class="info_item" lable="头像" arrow> <user-info-row-item class="info_item" lable="头像" arrow>
<my-avatar <my-avatar :src="sourceInfo.faceURL" :desc="sourceInfo.nickname" size="26" />
:src="sourceInfo.faceURL" </user-info-row-item>
:desc="sourceInfo.nickname" <user-info-row-item class="info_item" lable="昵称" arrow>
size="26" <text class="right_content">{{ sourceInfo.nickname }}</text>
/> </user-info-row-item>
</user-info-row-item> <user-info-row-item class="info_item" lable="性别" arrow>
<user-info-row-item class="info_item" lable="昵称" arrow> <text class="right_content">{{ getGender }}</text>
<text class="right_content">{{ sourceInfo.nickname }}</text> </user-info-row-item>
</user-info-row-item> <user-info-row-item class="info_item" lable="生日" arrow>
<user-info-row-item class="info_item" lable="性别" arrow> <text class="right_content">{{ getBirthStr }}</text>
<text class="right_content">{{ getGender }}</text> </user-info-row-item>
</user-info-row-item> </view>
<user-info-row-item class="info_item" lable="生日" arrow>
<text class="right_content">{{ getBirthStr }}</text>
</user-info-row-item>
</view>
<view class="info_list"> <view class="info_list">
<user-info-row-item class="info_item" lable="手机号码" arrow> <user-info-row-item class="info_item" lable="手机号码" arrow>
<text class="right_content">{{ sourceInfo.phoneNumber || "-" }}</text> <text class="right_content">{{ sourceInfo.phoneNumber || "-" }}</text>
</user-info-row-item> </user-info-row-item>
<user-info-row-item class="info_item" lable="邮箱" arrow> <user-info-row-item class="info_item" lable="邮箱" arrow>
<text class="right_content">{{ sourceInfo.email || "-" }}</text> <text class="right_content">{{ sourceInfo.email || "-" }}</text>
</user-info-row-item> </user-info-row-item>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import dayjs from "dayjs"; import dayjs from "dayjs";
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import MyAvatar from "@/components/MyAvatar/index.vue"; import MyAvatar from "@/components/MyAvatar/index.vue";
import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue"; import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue";
export default { import util from "@/util/index.js"
components: { export default {
CustomNavBar, components: {
MyAvatar, CustomNavBar,
UserInfoRowItem, MyAvatar,
}, UserInfoRowItem,
data() { },
return { data() {
sourceInfo: {}, return {
}; sourceInfo: {},
}, };
computed: { },
getGender() { computed: {
if (this.sourceInfo.gender === 1) { getGender() {
return "男"; if (this.sourceInfo.gender === 1) {
} return "男";
if (this.sourceInfo.gender === 2) { }
return "女"; if (this.sourceInfo.gender === 2) {
} return "女";
return "保密"; }
}, return "保密";
getBirthStr() { },
const birth = this.sourceInfo.birth ?? 0; getBirthStr() {
return dayjs(birth).format("YYYY-MM-DD"); const birth = this.sourceInfo.birth ?? 0;
}, return dayjs(birth).format("YYYY-MM-DD");
}, },
onLoad(options) { },
const { sourceInfo } = options; onLoad(options) {
this.sourceInfo = JSON.parse(sourceInfo); const {
}, sourceInfo
}; } = options;
this.sourceInfo = util.aesdecode(sourceInfo);
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.details_container { .details_container {
@include colBox(false); @include colBox(false);
height: 100vh; height: 100vh;
background-color: #f6f6f6; background-color: #f6f6f6;
.info_list { .info_list {
border-radius: 6px; border-radius: 6px;
overflow: hidden; overflow: hidden;
margin: 24rpx; margin: 24rpx;
.info_item { .info_item {
background-color: #fff; background-color: #fff;
// border-bottom: 1px solid rgba(153, 153, 153, 0.3); // border-bottom: 1px solid rgba(153, 153, 153, 0.3);
.right_content { .right_content {
color: #999; color: #999;
} }
} }
} }
} }
</style> </style>
+2 -1
View File
@@ -50,6 +50,7 @@
import {navigateToDesignatedConversation} from "@/util/imCommon"; import {navigateToDesignatedConversation} from "@/util/imCommon";
import IMSDK, {GroupVerificationType,SessionType,} from "openim-uniapp-polyfill"; import IMSDK, {GroupVerificationType,SessionType,} from "openim-uniapp-polyfill";
import dayjs from "dayjs"; import dayjs from "dayjs";
import util from "@/util/index.js"
import MyAvatar from "@/components/MyAvatar/index.vue"; import MyAvatar from "@/components/MyAvatar/index.vue";
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue"; import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue";
@@ -94,7 +95,7 @@
this.sourceID = sourceID; this.sourceID = sourceID;
this.getSourceGroupInfo(); this.getSourceGroupInfo();
} else { } else {
const info = JSON.parse(sourceInfo); const info = util.aesdecode(sourceInfo);
this.sourceID = info.groupID; this.sourceID = info.groupID;
this.sourceGroupInfo = { this.sourceGroupInfo = {
...info, ...info,
+35 -44
View File
@@ -68,6 +68,8 @@ import { checkLoginError } from "@/util/common";
import { SmsUserFor } from "@/constant"; import { SmsUserFor } from "@/constant";
import IMSDK from "openim-uniapp-polyfill"; import IMSDK from "openim-uniapp-polyfill";
import util from "@/util/index.js" import util from "@/util/index.js"
import config from "@/common/config";
import {getDbDir,toastWithCallback} from "@/util/common.js";
let timer; let timer;
@@ -145,59 +147,48 @@ export default {
this.loginInfo.email = "commiu@outlook.com"; this.loginInfo.email = "commiu@outlook.com";
this.loginInfo.password = "qwe123"; this.loginInfo.password = "qwe123";
} }
plus.navigator.closeSplashscreen();
}, },
updateEye() { updateEye() {
this.eying = !this.eying; this.eying = !this.eying;
}, },
toRegisterOrForget(isRegister) { toRegisterOrForget(isRegister) {
uni.$u.route("/pages/common/login/index", { uni.$u.route("/pages/common/registerOrForget/index", {
isRegister, isRegister,
}); });
}, },
async startLogin() { async startLogin() {
// this.$refs.loginForm.validate().then(async (valid) => { this.$refs.loginForm.validate().then(async (valid) => {
this.loading = true; this.loading = true;
this.saveLoginInfo(); this.saveLoginInfo();
let data = {}; let data = {};
try { try {
data = await businessLogin({ data = await businessLogin({
mobile: this.loginInfo.phoneNumber, mobile: this.loginInfo.phoneNumber,
email: this.loginInfo.email, email: this.loginInfo.email,
region: `+${this.loginInfo.region}`, region: `+${this.loginInfo.region}`,
password: this.isPwdLogin ? md5(this.loginInfo.password) : "", password: this.isPwdLogin ? md5(this.loginInfo.password) : "",
platform: uni.$u.os(), platform: uni.$u.os(),
type: this.active === 0 ? 'mobile' : 'email', type: this.active === 0 ? 'mobile' : 'email',
code: this.loginInfo.verificationCode, code: this.loginInfo.verificationCode,
}); });
const { imToken, userID } = data; const { imToken, userID } = data;
// #ifdef APP this.saveLoginProfile(data);
await IMSDK.asyncApi(IMSDK.IMMethods.Login, uuidv4(), { this.$store.commit("user/SET_AUTH_DATA", data);
userID, this.loginInfo.password = "";
token: imToken, // #ifdef APP
}); // await IMSDK.asyncApi(IMSDK.IMMethods.Login, uuidv4(), {
// #endif // userID,
this.saveLoginProfile(data); // token: imToken,
this.$store.commit("user/SET_AUTH_DATA", data); // });
this.$store.dispatch("user/getSelfInfo"); plus.runtime.restart();
this.$store.dispatch("conversation/getConversationList"); // #endif
this.$store.dispatch("conversation/getUnReadCount"); } catch (err) {
// this.$store.dispatch("contact/getFriendList"); console.error(err);
// this.$store.dispatch("contact/getGrouplist"); uni.$u.toast(checkLoginError(err));
this.$store.dispatch("contact/getBlacklist"); }
this.$store.dispatch("contact/getRecvFriendApplications"); this.loading = false;
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;
// });
}, },
saveLoginProfile(data) { saveLoginProfile(data) {
const { imToken, token, userID } = data; const { imToken, token, userID } = data;
+46 -12
View File
@@ -1,16 +1,12 @@
<template> <template>
<view class="map_page"> <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%;"> <view style="display: flex; flex-direction: column; height: 100%;">
<!-- 使用web-view嵌入天地图 --> <!-- 使用web-view嵌入天地图 -->
<ly-map class="ly-map" <ly-map class="ly-map"
v-if="lng && lat" v-if="lng && lat"
@onUserEvent="onUserEvent" @onUserEvent="onUserEvent"
ref="map" ref="map"
:type="type"
:lonlat=[lng,lat] :lonlat=[lng,lat]
:map-key="apikey" /> :map-key="apikey" />
<view class="search_container" v-if="1==2"> <view class="search_container" v-if="1==2">
@@ -24,10 +20,20 @@
</u-cell-group> </u-cell-group>
</view> </view>
</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> </view>
</template> </template>
<script> <script>
import util from "@/util/index.js"
export default { export default {
data() { data() {
return { return {
@@ -53,6 +59,7 @@
if(opt.address){ if(opt.address){
this.address = opt.address; this.address = opt.address;
} }
console.log(this.type)
this.init(); this.init();
}, },
methods: { methods: {
@@ -72,10 +79,12 @@
}) })
} }
}, },
gotoMap(){
util.toMapAPP(this.lng,this.lat,this.address);
},
onUserEvent(e) { onUserEvent(e) {
//console.log(e) if(e.type == "move"){
if(this.type=='chooselocation'){ if(this.type=='chooselocation'){
if(e.type == "move"){
this.lng = e.lng; this.lng = e.lng;
this.lat = e.lat; this.lat = e.lat;
this.$refs.map.setMarkers([ this.$refs.map.setMarkers([
@@ -84,10 +93,22 @@
lat: Number(e.lat) 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)
}, },
/** /**
* 确定位置按钮点击 * 确定位置按钮点击
@@ -153,8 +174,21 @@
flex: 1; flex: 1;
width: 100%; width: 100%;
} }
} .map_info{
.confirm_btn{ height: 100rpx;
padding: 30rpx 10rpx; padding: 50rpx 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
.left{
flex:1;
}
.right{
width: 100rpx;
.u-button{
background-color: #ccc;
}
}
}
} }
</style> </style>
+2 -1
View File
@@ -17,6 +17,7 @@
<script> <script>
import IMSDK from "openim-uniapp-polyfill"; import IMSDK from "openim-uniapp-polyfill";
import util from "@/util/index.js"
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import { import {
@@ -56,7 +57,7 @@
isSelfNickname, isSelfNickname,
sourceInfo sourceInfo
} = options; } = options;
this.sourceInfo = JSON.parse(sourceInfo); this.sourceInfo = util.aesdecode(sourceInfo);
console.log(sourceInfo); console.log(sourceInfo);
console.log(this.sourceInfo); console.log(this.sourceInfo);
this.isRemark = !!isRemark; this.isRemark = !!isRemark;
+5 -10
View File
@@ -34,15 +34,10 @@
<script> <script>
import AreaPicker from "@/components/AreaPicker"; import AreaPicker from "@/components/AreaPicker";
import { import {businessSendSms} from "@/api/login";
businessSendSms import {SmsUserFor} from "@/constant";
} from "@/api/login"; import {checkLoginError} from "@/util/common";
import { import util from "@/util/index.js"
SmsUserFor
} from "@/constant";
import {
checkLoginError
} from "@/util/common";
export default { export default {
components: { components: {
AreaPicker, AreaPicker,
@@ -99,7 +94,7 @@
setTimeout( setTimeout(
() => () =>
uni.$u.route("/pages/common/verifyCode/index", { uni.$u.route("/pages/common/verifyCode/index", {
userInfo: JSON.stringify(this.userInfo), userInfo: util.aesencode(this.userInfo),
isRegister: this.isRegister, isRegister: this.isRegister,
}), }),
1000, 1000,
+17 -31
View File
@@ -1,24 +1,9 @@
<template> <template>
<view class="scan_page" :style="{height:windowHeight+'px'}"> <view class="scan_page" :style="{height:windowHeight+'px'}">
<uni-nav-bar <uni-nav-bar left-icon="back" @clickLeft="back" fixed backgroundColor="#FFF" statusBar>
left-icon="back"
@clickLeft="back"
fixed
backgroundColor="#FFF"
statusBar
>
</uni-nav-bar> </uni-nav-bar>
<barcode id='1' <barcode id='1' class="barcode" ref="barcode" :autostart="true" background="rgb(0,0,0)" frameColor="#07c160"
class="barcode" scanbarColor="#07c160" :style="{height:windowHeight+'px'}" :filters="fil" @marked="success" @error="fail">
ref="barcode"
:autostart="true"
background="rgb(0,0,0)"
frameColor="#07c160"
scanbarColor="#07c160"
:style="{height:windowHeight+'px'}"
:filters="fil"
@marked="success"
@error="fail">
</barcode> </barcode>
<view class="overlay"> <view class="overlay">
<button class="btn" @click="toStart">开始扫码识别</button> <button class="btn" @click="toStart">开始扫码识别</button>
@@ -33,8 +18,8 @@
export default { export default {
data() { data() {
return { return {
fil: [0, 2, 1,3,4,12], fil: [0, 2, 1, 3, 4, 12],
windowHeight:500, windowHeight: 500,
} }
}, },
@@ -52,10 +37,10 @@
}, },
methods: { methods: {
success(e) { success(e) {
console.log("success1:" + JSON.stringify(e)); //console.log("success1:" + JSO1N.stringify(e));
}, },
fail(e) { fail(e) {
console.log("fail1:" + JSON.stringify(e)); //console.log("fail1:" + JSON1.stringify(e));
}, },
toStart: function() { toStart: function() {
this.$refs.barcode.start({ this.$refs.barcode.start({
@@ -63,7 +48,7 @@
filename: '_doc/barcode/' filename: '_doc/barcode/'
}); });
}, },
tocancel:function(){ tocancel: function() {
this.$refs.barcode.cancel(); this.$refs.barcode.cancel();
}, },
toFlash: function() { toFlash: function() {
@@ -73,12 +58,11 @@
toscan: function() { toscan: function() {
console.log("scan:"); console.log("scan:");
const barcodeModule = uni.requireNativePlugin('barcodeScan'); const barcodeModule = uni.requireNativePlugin('barcodeScan');
barcodeModule.scan("/static/barcode1.png" barcodeModule.scan("/static/barcode1.png", (e) => {
,(e)=>{ console.log("scan_error:", e);
console.log("scan_error:"+JSON.stringify(e));
}); });
}, },
back(){ back() {
uni.navigateBack(); uni.navigateBack();
} }
} }
@@ -86,14 +70,15 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.scan_page{ .scan_page {
width: 750rpx; width: 750rpx;
position: relative; position: relative;
.barcode { .barcode {
width: 750rpx; width: 750rpx;
background-color: #808080; background-color: #808080;
} }
.btn { .btn {
top: 20rpx; top: 20rpx;
width: 730rpx; width: 730rpx;
@@ -102,7 +87,8 @@
background-color: #458B00; background-color: #458B00;
border-radius: 10rpx; border-radius: 10rpx;
} }
.overlay{
.overlay {
background: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.1);
position: absolute; position: absolute;
bottom: 100rpx; bottom: 100rpx;
@@ -111,4 +97,4 @@
height: 200rpx; height: 200rpx;
} }
} }
</style> </style>
+5 -5
View File
@@ -32,9 +32,8 @@
import searchGroup from "static/images/contact_add_join_group_fill.png"; import searchGroup from "static/images/contact_add_join_group_fill.png";
import searchUser from "static/images/contact_add_search_user_fill.png"; import searchUser from "static/images/contact_add_search_user_fill.png";
import { import {businessSearchUserInfo} from "@/api/login";
businessSearchUserInfo import util from "@/util/index.js"
} from "@/api/login";
export default { export default {
components: { components: {
@@ -87,8 +86,9 @@
info = data[0]; info = data[0];
} }
if (info) { if (info) {
const s = util.aesencode(info);
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/groupCard/index?sourceInfo=${JSON.stringify(info,)}`, url: `/pages/common/groupCard/index?sourceInfo=${s}`,
}); });
} else { } else {
this.empty = true; this.empty = true;
@@ -116,7 +116,7 @@
console.log(info) console.log(info)
if (info) { if (info) {
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/userCard/index?sourceInfo=${JSON.stringify(info,)}`, url: `/pages/common/userCard/index?sourceID=${info.userID}`,
}); });
} else { } else {
this.empty = true; this.empty = true;
+5 -6
View File
@@ -30,9 +30,8 @@
</template> </template>
<script> <script>
import { import {businessReset} from "@/api/login";
businessReset import util from "@/util/index.js"
} from "@/api/login";
export default { export default {
data() { data() {
return { return {
@@ -89,8 +88,8 @@
isRegister, isRegister,
codeValue codeValue
} = options; } = options;
this.userInfo = JSON.parse(userInfo); this.userInfo = util.aesdecode(userInfo);
this.isRegister = JSON.parse(isRegister); this.isRegister = util.parse(isRegister);
this.codeValue = codeValue; this.codeValue = codeValue;
}, },
onBackPress() { onBackPress() {
@@ -112,7 +111,7 @@
businessReset(options) businessReset(options)
.then(() => { .then(() => {
uni.$u.toast("密码重置成功,请前往登录!"); uni.$u.toast("密码重置成功,请前往登录!");
setTimeout(() => uni.$u.route("/pages/login/index"), 1000); setTimeout(() => uni.$u.route("/pages/common/login/index"), 1000);
}) })
.catch((err) => { .catch((err) => {
console.log('err', err) console.log('err', err)
+5 -3
View File
@@ -39,6 +39,7 @@
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import { businessRegister } from "@/api/login"; import { businessRegister } from "@/api/login";
import { checkLoginError } from "@/util/common"; import { checkLoginError } from "@/util/common";
import util from "@/util/index.js"
export default { export default {
components: { components: {
MyAvatar, MyAvatar,
@@ -104,7 +105,7 @@
const {userInfo,codeValue} = options; const {userInfo,codeValue} = options;
this.userInfo = { this.userInfo = {
...this.userInfo, ...this.userInfo,
...JSON.parse(userInfo), ...util.aesdecode(userInfo),
}; };
this.codeValue = codeValue; this.codeValue = codeValue;
if(process.env.NODE_ENV == 'development'){ if(process.env.NODE_ENV == 'development'){
@@ -143,12 +144,13 @@
await businessRegister(options); await businessRegister(options);
this.saveLoginInfo(); this.saveLoginInfo();
uni.$u.toast('注册成功') uni.$u.toast('注册成功')
uni.$u.route("/pages/login/index") uni.$u.route("/pages/common/login/index")
} catch (err) { } catch (err) {
console.log(err); console.log(err);
if(err.msg=="验证码过期" || err.msg=="验证码错误"){ if(err.msg=="验证码过期" || err.msg=="验证码错误"){
const s = util.aesencode(this.userInfo);
uni.$u.route("/pages/common/verifyCode/index", { uni.$u.route("/pages/common/verifyCode/index", {
userInfo: JSON.stringify(this.userInfo), userInfo: s,
isRegister: true, isRegister: true,
resend: 1, resend: 1,
}) })
@@ -1,51 +1,55 @@
<template> <template>
<view @click="click" class="row_item" :class="{ arrow_right: arrow }"> <view @click="click" class="row_item" :class="{ arrow_right: arrow }">
<view class="title"> <view class="title">
<text>{{ lable }}</text> <text>{{ lable }}</text>
</view> </view>
<view class="content"> <view class="content">
<text>{{ content }}</text> <text>{{ content }}</text>
</view> </view>
<slot> <slot>
<u-icon v-if="arrow" name="arrow-right" color="#999" size="20"></u-icon> <u-icon v-if="arrow" name="arrow-right" color="#999" size="20"></u-icon>
</slot> </slot>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: "", name: "",
components: {}, components: {},
props: { props: {
lable: String, lable: String,
content: String, content: String,
arrow: { arrow: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
}, },
data() { data() {
return {}; return {};
}, },
methods: { methods: {
click() { click() {
this.$emit("click"); this.$emit("click");
}, },
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.row_item { .row_item {
@include vCenterBox(); @include vCenterBox();
padding: 24rpx 44rpx; padding: 24rpx 44rpx;
} .content{
display: flex;
align-items: center;
}
}
.title { .title {
margin-right: 24rpx; margin-right: 24rpx;
} }
.arrow_right { .arrow_right {
justify-content: space-between; justify-content: space-between;
} }
</style> </style>
+22 -51
View File
@@ -1,7 +1,8 @@
<template> <template>
<view class="user_card_container"> <view class="user_card_container">
<u-loading-page :loading="isLoading" loading-text="loading..."></u-loading-page> <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 v-if="!isLoading" style="flex: 1;display: flex;flex-direction: column;">
<view class="base_info"> <view class="base_info">
@@ -9,10 +10,7 @@
size="46" /> size="46" />
<view class="user_name"> <view class="user_name">
<text class="text">{{ getShowName }}</text> <text class="text">{{ getShowName }}</text>
<text class="id" @click="copy(sourceUserInfo.userID)">{{sourceUserInfo.userID}}</text> <text class="id" @click="copy(sourceUserInfo.userID || sourceUserInfo.id)">{{sourceUserInfo.userID || sourceUserInfo.id}}</text>
</view>
<view class="add_btn" @click="toAddFriend" v-if="trySendRequest">
<u-button type="primary" icon="man-add" text="添加"></u-button>
</view> </view>
</view> </view>
<view class="info_row"> <view class="info_row">
@@ -20,15 +18,15 @@
<user-info-row-item lable="生日" :content="getBirth" /> <user-info-row-item lable="生日" :content="getBirth" />
<user-info-row-item lable="个性签名" :content="sourceUserInfo.bio" /> <user-info-row-item lable="个性签名" :content="sourceUserInfo.bio" />
</view> </view>
<view v-if="isFriend" class="info_row">
<user-info-row-item @click="toMoreInfo" lable="个人资料" arrow /> <view class="info_row">
<user-info-row-item v-if="isFriend" @click="toMoreInfo" lable="更多信息" arrow />
<user-info-row-item v-if="1==1" @click="gotoCircle" lable="朋友圈" arrow />
</view> </view>
<view class="action_row" v-if="!isSelf"> <view class="action_row" v-if="!isSelf">
<view @click="toDesignatedConversation" class="action_item"> <u-button type="primary" icon="chat" text="发消息" @click="toDesignatedConversation" v-if="isFriend"></u-button>
<img src="static/images/user_card_message.png" alt="" /> <u-button type="primary" icon="man-add" text="添加" @click="toAddFriend" v-else></u-button>
<text>发消息</text>
</view>
</view> </view>
</view> </view>
</view> </view>
@@ -43,6 +41,7 @@
import UserInfoRowItem from "./components/UserInfoRowItem.vue"; import UserInfoRowItem from "./components/UserInfoRowItem.vue";
import {businessSearchUserInfo} from "@/api/login"; import {businessSearchUserInfo} from "@/api/login";
import dayjs from "dayjs"; import dayjs from "dayjs";
import util from "@/util/index.js"
export default { export default {
components: { components: {
@@ -106,7 +105,7 @@
if (sourceID) { if (sourceID) {
this.sourceID = sourceID; this.sourceID = sourceID;
} else { } else {
const info = JSON.parse(sourceInfo); const info = util.aesdecode(sourceInfo);
this.sourceID = info.userID; this.sourceID = info.userID;
} }
//console.log(this.storeSelfInfo); //console.log(this.storeSelfInfo);
@@ -148,16 +147,8 @@
try { try {
const res = await businessSearchUserInfo(this.sourceID); const res = await businessSearchUserInfo(this.sourceID);
if (res.total > 0) { 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 = { info = {
...imData, ...info,
...res.data[0], ...res.data[0],
}; };
} }
@@ -177,6 +168,13 @@
notNeedVerification: false, notNeedVerification: false,
}); });
}, },
gotoCircle(){
console.log('gotoCircle');
return ;
uni.navigateTo({
url:"/pages/find/friend-circle/friend-circle?userId="+this.sourceID
})
},
toDesignatedConversation() { toDesignatedConversation() {
navigateToDesignatedConversation( navigateToDesignatedConversation(
this.sourceID, this.sourceID,
@@ -185,8 +183,9 @@
).catch(() => uni.$u.toast("获取会话信息失败")); ).catch(() => uni.$u.toast("获取会话信息失败"));
}, },
toMoreInfo() { toMoreInfo() {
const s = util.aesencode(this.sourceUserInfo);
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/userCardMore/index?sourceInfo=${JSON.stringify(this.sourceUserInfo,)}`, url: `/pages/common/userCardMore/index?sourceInfo=${s}`,
}); });
} }
}, },
@@ -207,16 +206,6 @@
padding: 44rpx; padding: 44rpx;
margin-bottom: 18rpx; margin-bottom: 18rpx;
.add_btn {
width: 140rpx;
height: 60rpx;
margin-left: auto;
.u-button {
width: 140rpx;
height: 60rpx;
}
}
.u-avatar { .u-avatar {
margin-right: 24rpx; margin-right: 24rpx;
@@ -226,7 +215,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
margin-bottom: 12rpx;
height: 46px; height: 46px;
.text { .text {
@@ -271,23 +259,6 @@
margin: 44rpx; margin: 44rpx;
flex: 1; 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 { .id {
+9 -7
View File
@@ -26,9 +26,8 @@
import IMSDK from "openim-uniapp-polyfill"; import IMSDK from "openim-uniapp-polyfill";
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue"; import UserInfoRowItem from "../userCard/components/UserInfoRowItem.vue";
import { import {ContactChooseTypes} from "@/constant";
ContactChooseTypes import util from "@/util/index.js"
} from "@/constant";
export default { export default {
components: { components: {
CustomNavBar, CustomNavBar,
@@ -59,7 +58,7 @@
}, },
onLoad(options) { onLoad(options) {
const {sourceInfo} = options; const {sourceInfo} = options;
this.sourceInfo = JSON.parse(sourceInfo); this.sourceInfo = util.aesdecode(sourceInfo);
}, },
methods: { methods: {
change(isBlack) { change(isBlack) {
@@ -81,18 +80,21 @@
.finally(() => (this.showConfirm = false)); .finally(() => (this.showConfirm = false));
}, },
toMore() { toMore() {
const s = util.aesencode(this.sourceInfo);
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/detailsFileds/index?sourceInfo=${JSON.stringify(this.sourceInfo,)}`, url: `/pages/common/detailsFileds/index?sourceInfo=${s}`,
}); });
}, },
toMark() { toMark() {
const s = util.aesencode(this.sourceInfo);
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/markOrIDPage/index?isRemark=true&sourceInfo=${JSON.stringify(this.sourceInfo,)}`, url: `/pages/common/markOrIDPage/index?isRemark=true&sourceInfo=${s}`,
}); });
}, },
toShare() { toShare() {
const s = util.aesencode(this.sourceInfo);
uni.navigateTo({ 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) { showToast(message) {
+1 -1
View File
@@ -74,7 +74,7 @@
}, },
onLoad(opt) { onLoad(opt) {
if(opt.sourceInfo){ if(opt.sourceInfo){
this.source = JSON.parse(opt.sourceInfo); this.source = util.aesdecode(opt.sourceInfo);
}else{ }else{
this.source = { this.source = {
type:"user", type:"user",
+10 -8
View File
@@ -22,10 +22,11 @@
</view> </view>
</template> </template>
<script> <script>
import user from "../../../store/modules/user"; import user from "@/store/modules/user";
import { businessSendSms, businessVerifyCode } from "@/api/login"; import {businessSendSms,businessVerifyCode} from "@/api/login";
import { SmsUserFor } from "@/constant"; import {SmsUserFor} from "@/constant";
import { checkLoginError } from "@/util/common"; import {checkLoginError } from "@/util/common";
import util from "@/util/index.js"
let timer; let timer;
export default { export default {
data() { data() {
@@ -49,7 +50,7 @@
resend resend
} = options; } = options;
console.log(userInfo,isRegister) console.log(userInfo,isRegister)
this.userInfo = JSON.parse(userInfo); this.userInfo = util.aesdecode(userInfo);
this.isRegister = JSON.parse(isRegister); this.isRegister = JSON.parse(isRegister);
if(resend == 1){ if(resend == 1){
this.count = 0; this.count = 0;
@@ -61,7 +62,7 @@
onReady() {}, onReady() {},
methods: { methods: {
back() { back() {
uni.$u.route("/pages/common/login/index", { uni.$u.route("/pages/common/registerOrForget/index", {
isRegister: this.isRegister, isRegister: this.isRegister,
}); });
}, },
@@ -76,15 +77,16 @@
}; };
businessVerifyCode(options) businessVerifyCode(options)
.then(() => { .then(() => {
const s = util.aesencode(this.userInfo);
if (this.isRegister) { if (this.isRegister) {
uni.$u.route("/pages/common/setSelfInfo/index", { uni.$u.route("/pages/common/setSelfInfo/index", {
userInfo: JSON.stringify(this.userInfo), userInfo: s,
isRegister: this.isRegister, isRegister: this.isRegister,
codeValue: this.codeValue, codeValue: this.codeValue,
}); });
} else { } else {
uni.$u.route("/pages/common/setPassword/index", { uni.$u.route("/pages/common/setPassword/index", {
userInfo: JSON.stringify(this.userInfo), userInfo: s,
isRegister: !this.isRegister, isRegister: !this.isRegister,
codeValue: this.codeValue, codeValue: this.codeValue,
}); });
+218 -229
View File
@@ -1,256 +1,245 @@
<template> <template>
<view class="page_container"> <view class="page_container">
<custom-nav-bar :title="isGroupApplication ? '群通知' : '好友请求'" /> <custom-nav-bar :title="isGroupApplication ? '群通知' : '好友请求'" />
<view class="application_item"> <view class="application_item">
<view class="base_info_row"> <view class="base_info_row">
<view class="base_info_left" @click="toSourceDetails"> <view class="base_info_left" @click="toSourceDetails">
<my-avatar :src="getSourceFaceURL" :desc="getSourceName" /> <my-avatar :src="getSourceFaceURL" :desc="getSourceName" />
<view class="base_info_details"> <view class="base_info_details">
<text class="nickname">{{ getSourceName }}</text> <text class="nickname">{{ getSourceName }}</text>
</view> </view>
</view> </view>
<u-icon name="arrow-right" size="18" color="#999"></u-icon> <u-icon name="arrow-right" size="18" color="#999"></u-icon>
</view> </view>
<view class="request_message"> <view class="request_message">
<view v-if="isGroupApplication" class="title"> <view v-if="isGroupApplication" class="title">
<text>申请加入 </text> <text>申请加入 </text>
<text class="group_name">{{ currentApplication.groupName }}</text> <text class="group_name">{{ currentApplication.groupName }}</text>
</view> </view>
<text v-else>{{ `${getSourceName}` }}</text> <text v-else>{{ `${getSourceName}` }}</text>
<text>{{ currentApplication.reqMsg }}</text> <text>{{ currentApplication.reqMsg }}</text>
</view> </view>
</view> </view>
<view class="action_row"> <view class="action_row">
<u-button <u-button :loading="loadingState.accept" @click="acceptAplication" type="primary" :plain="true"
:loading="loadingState.accept" :text="`通过${isGroupApplication ? '入群' : '好友'}申请`"></u-button>
@click="acceptAplication" </view>
type="primary"
:plain="true"
:text="`通过${isGroupApplication ? '入群' : '好友'}申请`"
></u-button>
</view>
<view class="action_row"> <view class="action_row">
<u-button <u-button :loading="loadingState.refuse" @click="refuseAplication" type="primary" :plain="true"
:loading="loadingState.refuse" :text="`拒绝${isGroupApplication ? '入群' : '好友'}申请`"></u-button>
@click="refuseAplication" </view>
type="primary" </view>
:plain="true"
:text="`拒绝${isGroupApplication ? '入群' : '好友'}申请`"
></u-button>
</view>
</view>
</template> </template>
<script> <script>
import { mapGetters } from "vuex"; import {mapGetters} from "vuex";
import IMSDK, { GroupJoinSource } from "openim-uniapp-polyfill"; import IMSDK, {GroupJoinSource} from "openim-uniapp-polyfill";
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import MyAvatar from "@/components/MyAvatar/index.vue"; import MyAvatar from "@/components/MyAvatar/index.vue";
export default { import util from "@/util/index.js"
components: { export default {
CustomNavBar, components: {
MyAvatar, CustomNavBar,
}, MyAvatar,
data() { },
return { data() {
currentApplication: {}, return {
isOnline: false, currentApplication: {},
loadingState: { isOnline: false,
accept: false, loadingState: {
refuse: false, accept: false,
}, refuse: false,
}; },
}, };
computed: { },
...mapGetters(["storeSelfInfo"]), computed: {
isGroupApplication() { ...mapGetters(["storeSelfInfo"]),
return this.currentApplication.groupID !== undefined; isGroupApplication() {
}, return this.currentApplication.groupID !== undefined;
getSourceID() { },
return ( getSourceID() {
this.currentApplication.fromUserID ?? this.currentApplication.userID return (
); this.currentApplication.fromUserID ?? this.currentApplication.userID
}, );
getSourceName() { },
return ( getSourceName() {
this.currentApplication.fromNickname ?? this.currentApplication.nickname return (
); this.currentApplication.fromNickname ?? this.currentApplication.nickname
}, );
getSourceFaceURL() { },
return ( getSourceFaceURL() {
this.currentApplication.fromFaceURL ?? this.currentApplication.faceURL return (
); this.currentApplication.fromFaceURL ?? this.currentApplication.faceURL
}, );
}, },
onLoad(options) { },
const { application } = options; onLoad(options) {
this.currentApplication = JSON.parse(application); const {
}, application
methods: { } = options;
toSourceDetails() { this.currentApplication = util.aesdecode(application);
uni.navigateTo({ },
url: `/pages/common/userCard/index?sourceID=${this.getSourceID}`, methods: {
}); toSourceDetails() {
}, uni.navigateTo({
acceptAplication() { url: `/pages/common/userCard/index?sourceID=${this.getSourceID}`,
this.loadingState.accept = true; });
let func; },
if (this.isGroupApplication) { acceptAplication() {
func = IMSDK.asyncApi( this.loadingState.accept = true;
IMSDK.IMMethods.AcceptGroupApplication, let func;
IMSDK.uuid(), if (this.isGroupApplication) {
{ func = IMSDK.asyncApi(
groupID: this.currentApplication.groupID, IMSDK.IMMethods.AcceptGroupApplication,
fromUserID: this.currentApplication.userID, IMSDK.uuid(), {
handleMsg: "", groupID: this.currentApplication.groupID,
}, fromUserID: this.currentApplication.userID,
); handleMsg: "",
} else { },
console.log(this.currentApplication); );
func = IMSDK.asyncApi( } else {
IMSDK.IMMethods.AcceptFriendApplication, console.log(this.currentApplication);
IMSDK.uuid(), func = IMSDK.asyncApi(
{ IMSDK.IMMethods.AcceptFriendApplication,
toUserID: this.currentApplication.fromUserID, IMSDK.uuid(), {
handleMsg: "", toUserID: this.currentApplication.fromUserID,
}, handleMsg: "",
); },
} );
func }
.then(() => { func
uni.$u.toast("操作成功"); .then(() => {
setTimeout(() => uni.navigateBack(), 500); uni.$u.toast("操作成功");
}) setTimeout(() => uni.navigateBack(), 500);
.catch((e) => { })
console.log(e); .catch((e) => {
uni.$u.toast("操作失败"); console.log(e);
}) uni.$u.toast("操作失败");
.finally(() => (this.loadingState.accept = false)); })
}, .finally(() => (this.loadingState.accept = false));
refuseAplication() { },
this.loadingState.refuse = true; refuseAplication() {
let func; this.loadingState.refuse = true;
if (this.isGroupApplication) { let func;
func = IMSDK.asyncApi( if (this.isGroupApplication) {
IMSDK.IMMethods.RefuseGroupApplication, func = IMSDK.asyncApi(
IMSDK.uuid(), IMSDK.IMMethods.RefuseGroupApplication,
{ IMSDK.uuid(), {
groupID: this.currentApplication.groupID, groupID: this.currentApplication.groupID,
fromUserID: this.currentApplication.userID, fromUserID: this.currentApplication.userID,
handleMsg: "", handleMsg: "",
}, },
); );
} else { } else {
func = IMSDK.asyncApi( func = IMSDK.asyncApi(
IMSDK.IMMethods.RefuseFriendApplication, IMSDK.IMMethods.RefuseFriendApplication,
IMSDK.uuid(), IMSDK.uuid(), {
{ toUserID: this.currentApplication.fromUserID,
toUserID: this.currentApplication.fromUserID, handleMsg: "",
handleMsg: "", },
}, );
); }
} func
func .then(() => {
.then(() => { uni.$u.toast("操作成功");
uni.$u.toast("操作成功"); setTimeout(() => uni.navigateBack(), 250);
setTimeout(() => uni.navigateBack(), 250); })
}) .catch(() => uni.$u.toast("操作失败"))
.catch(() => uni.$u.toast("操作失败")) .finally(() => (this.loadingState.refuse = false));
.finally(() => (this.loadingState.refuse = false)); },
}, },
}, };
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.page_container { .page_container {
background-color: #f8f8f8; background-color: #f8f8f8;
.application_item { .application_item {
padding: 72rpx 44rpx 24rpx; padding: 72rpx 44rpx 24rpx;
background-color: #fff; background-color: #fff;
.base_info_row { .base_info_row {
@include btwBox(); @include btwBox();
.base_info_left { .base_info_left {
@include vCenterBox(); @include vCenterBox();
} }
.base_info_details { .base_info_details {
margin-left: 24rpx; margin-left: 24rpx;
.nickname { .nickname {
@include nomalEllipsis(); @include nomalEllipsis();
max-width: 600rpx; max-width: 600rpx;
} }
.online_state { .online_state {
@include vCenterBox(); @include vCenterBox();
flex-direction: row; flex-direction: row;
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
margin-top: 6rpx; margin-top: 6rpx;
.dot { .dot {
background-color: #10cc64; background-color: #10cc64;
width: 12rpx; width: 12rpx;
height: 12rpx; height: 12rpx;
border-radius: 50%; border-radius: 50%;
margin-right: 12rpx; margin-right: 12rpx;
} }
} }
} }
} }
.request_message { .request_message {
background-color: #eee; background-color: #eee;
margin-top: 48rpx; margin-top: 48rpx;
padding: 24rpx 36rpx; padding: 24rpx 36rpx;
border-radius: 12rpx; border-radius: 12rpx;
font-size: 28rpx; font-size: 28rpx;
color: #666; color: #666;
min-height: 240rpx; min-height: 240rpx;
.title { .title {
margin-bottom: 12rpx; margin-bottom: 12rpx;
color: $uni-text-color; color: $uni-text-color;
.group_name { .group_name {
@nomalEllipsis(); @nomalEllipsis();
max-width: 400rpx; max-width: 400rpx;
color: $uni-color-primary; color: $uni-color-primary;
margin-left: 12rpx; margin-left: 12rpx;
} }
} }
} }
.join_source { .join_source {
margin-top: 20rpx; margin-top: 20rpx;
font-size: 24rpx; font-size: 24rpx;
color: #666; color: #666;
text-align: right; text-align: right;
} }
} }
.action_row { .action_row {
margin-top: 24rpx; margin-top: 24rpx;
.u-button { .u-button {
border: none; border: none;
} }
&:last-child { &:last-child {
.u-button { .u-button {
color: #999 !important; color: #999 !important;
} }
} }
} }
} }
</style> </style>
@@ -28,13 +28,10 @@
</template> </template>
<script> <script>
import { import {navigateToDesignatedConversation} from "@/util/imCommon";
navigateToDesignatedConversation import IMSDK, {SessionType} from "openim-uniapp-polyfill";
} from "@/util/imCommon";
import IMSDK, {
SessionType
} from "openim-uniapp-polyfill";
import MyAvatar from "@/components/MyAvatar/index.vue"; import MyAvatar from "@/components/MyAvatar/index.vue";
import util from "@/util/index.js"
export default { export default {
name: "ApplicationItem", name: "ApplicationItem",
components: { components: {
@@ -97,17 +94,12 @@
methods: { methods: {
clickItem() { clickItem() {
if (this.showAccept) { if (this.showAccept) {
const s = util.aesencode(this.application);
uni.navigateTo({ uni.navigateTo({
url: `/pages/contact/applicationDetails/index?application=${JSON.stringify( url: `/pages/contact/applicationDetails/index?application=${s}`,
this.application,
)}`,
}); });
} else { } else {
let sourceID = let sourceID = this.application.groupID ?? (this.isRecv ? this.application.fromUserID : this.application.toUserID);
this.application.groupID ??
(this.isRecv ?
this.application.fromUserID :
this.application.toUserID);
let cardType = this.isGroupApplication ? "groupCard" : "userCard"; let cardType = this.isGroupApplication ? "groupCard" : "userCard";
const url = `/pages/common/${cardType}/index?sourceID=${sourceID}`; const url = `/pages/common/${cardType}/index?sourceID=${sourceID}`;
uni.navigateTo({ uni.navigateTo({
+72 -72
View File
@@ -1,81 +1,81 @@
<template> <template>
<view class="application_list_container"> <view class="application_list_container">
<custom-nav-bar :title="getTitle" /> <custom-nav-bar :title="getTitle" />
<u-list class="application_list"> <u-list class="application_list">
<u-list-item <u-list-item v-for="application in getRenderData" :key="getKey(application)">
v-for="application in getRenderData" <application-item :isRecv="isRecv" :application="application" />
:key="getKey(application)" </u-list-item>
> </u-list>
<application-item :isRecv="isRecv" :application="application" /> </view>
</u-list-item>
</u-list>
</view>
</template> </template>
<script> <script>
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import ApplicationItem from "../applicationList/ApplicationItem.vue"; import ApplicationItem from "../applicationList/ApplicationItem.vue";
export default { export default {
components: { components: {
CustomNavBar, CustomNavBar,
ApplicationItem, ApplicationItem,
}, },
data() { data() {
return { return {
isGroupApplication: false, isGroupApplication: false,
isRecv: false, isRecv: false,
}; };
}, },
computed: { computed: {
getRenderData() { getRenderData() {
let getterKey = this.isRecv let getterKey = this.isRecv ?
? "storeRecvFriendApplications" "storeRecvFriendApplications" :
: "storeSentFriendApplications"; "storeSentFriendApplications";
if (this.isGroupApplication) { if (this.isGroupApplication) {
getterKey = this.isRecv getterKey = this.isRecv ?
? "storeRecvGroupApplications" "storeRecvGroupApplications" :
: "storeSentGroupApplications"; "storeSentGroupApplications";
} }
return [...this.$store.getters[getterKey]].sort((a, b) => return [...this.$store.getters[getterKey]].sort((a, b) =>
a.handleResult === 0 ? -1 : 1, a.handleResult === 0 ? -1 : 1,
); );
}, },
getKey() { getKey() {
return (application) => { return (application) => {
if (this.isGroupApplication) { if (this.isGroupApplication) {
return this.isRecv return this.isRecv ?
? application.userID + application.groupID application.userID + application.groupID :
: application.groupID; application.groupID;
} }
return application[this.isRecv ? "fromUserID" : "toUserID"]; return application[this.isRecv ? "fromUserID" : "toUserID"];
}; };
}, },
getTitle() { getTitle() {
if (!this.isRecv) { if (!this.isRecv) {
return "我的申请"; return "我的申请";
} }
return this.isGroupApplication ? "群通知" : "好友请求"; return this.isGroupApplication ? "群通知" : "好友请求";
}, },
}, },
onLoad(options) { onLoad(options) {
const { isGroupApplication, isRecv } = options; const {
this.isGroupApplication = JSON.parse(isGroupApplication); isGroupApplication,
this.isRecv = JSON.parse(isRecv); isRecv
}, } = options;
methods: {}, this.isGroupApplication = JSON.parse(isGroupApplication);
}; this.isRecv = JSON.parse(isRecv);
},
methods: {},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.application_list_container { .application_list_container {
@include colBox(false); @include colBox(false);
height: 100vh; height: 100vh;
background-color: #f8f8f8; background-color: #f8f8f8;
.application_list { .application_list {
margin-top: 24rpx; margin-top: 24rpx;
flex: 1; flex: 1;
} }
} }
</style> </style>
+7 -7
View File
@@ -26,15 +26,15 @@
{ {
idx: 0, idx: 0,
title: "创建群聊", title: "创建群聊",
desc: "创建群聊,全面使用OpenIM", desc: "创建群聊",
icon: contact_add_create_group_img, icon: contact_add_create_group_img,
}, },
{ // {
idx: 1, // idx: 1,
title: "添加群聊", // title: "添加群聊",
desc: "向管理员或团队成员询问ID", // desc: "向管理员或团队成员询问ID",
icon: rcontact_add_join_group_img, // icon: contact_add_join_group_img,
}, // },
], ],
friendActionMenus: [ friendActionMenus: [
{ {
+1 -1
View File
@@ -15,7 +15,7 @@
</view> </view>
<uni-list class="contact_menus"> <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="新的好友" :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/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="群聊" thumbSize="lg" to="/pages/contact/groupList/index" thumb="/static/images/contact_my_group.png"></uni-list-item>
</uni-list> </uni-list>
@@ -251,12 +251,15 @@
const realVideoPath = await getPurePath(item); const realVideoPath = await getPurePath(item);
console.log('处理后的可用路径', realVideoPath); console.log('处理后的可用路径', realVideoPath);
const info = await getVideoInfo(realVideoPath); const info = await getVideoInfo(realVideoPath);
const cover = await getVideoCover(item); //const cover = await getVideoCover(item);
const res1 = await IMSDK.getVideoCover(item);
//console.log(res1.path);
const videoParams = { const videoParams = {
videoPath: realVideoPath, videoPath: realVideoPath,
videoType: "mp4", videoType: "mp4",
duration: info.duration, duration: info.duration,
snapshotPath: getPurePath(cover), snapshotPath: getPurePath(res1.path),
//snapshotPath: getPurePath(cover),
}; };
console.log('videoParams', videoParams); console.log('videoParams', videoParams);
message = await IMSDK.asyncApi( message = await IMSDK.asyncApi(
@@ -271,7 +274,7 @@
getPurePath(item) getPurePath(item)
); );
} }
console.log(message); //console.log(message);
if(message){ if(message){
_this.sendMessage(message,_this.storeCurrentConversation.userID,_this.storeCurrentConversation.groupID); _this.sendMessage(message,_this.storeCurrentConversation.userID,_this.storeCurrentConversation.groupID);
} }
@@ -416,10 +419,16 @@
return ; return ;
} }
if(e.source == "album"){ if(e.source == "album"){
// IMSDK.pickFile().then(res=>{
// console.log(res);
// }).catch(e=>{
// console.log(e);
// });
// return;
plus.gallery.pick(({files})=>{ plus.gallery.pick(({files})=>{
_this.sendMediaMesage(files); _this.sendMediaMesage(files);
}, (error )=>{ }, (error )=>{
reject(error); console.log(error);
}, { }, {
animation:true, animation:true,
confirmText:"确定", confirmText:"确定",
@@ -23,12 +23,8 @@
</template> </template>
<script> <script>
import { import {mapGetters} from "vuex";
mapGetters import {SessionType} from "openim-uniapp-polyfill";
} from "vuex";
import {
SessionType
} from "openim-uniapp-polyfill";
import MyAvatar from "@/components/MyAvatar/index.vue"; import MyAvatar from "@/components/MyAvatar/index.vue";
export default { export default {
@@ -21,8 +21,9 @@
src="/static/images/sync_error.png"> src="/static/images/sync_error.png">
</u--image> </u--image>
<u--text class="address" :style="{ <u--text class="address" :style="{
width:selfWidth+'px' width:selfWidth+'px',
}" :lines="1" :size="20" :text="desc"></u--text> paddingTop:'5px'
}" :lines="1" :size="16" :text="desc"></u--text>
</view> </view>
</template> </template>
@@ -38,7 +39,6 @@
data() { data() {
return { return {
selfWidth:200, selfWidth:200,
loadingWidth: "200px",
src:"", src:"",
coverDownloading:false, coverDownloading:false,
coverDownloadProgress:"", coverDownloadProgress:"",
@@ -48,12 +48,13 @@
}; };
}, },
created() { created() {
this.selfWidth = uni.$u.getPx('400rpx');
let loc = this.message.locationElem; let loc = this.message.locationElem;
this.desc = loc.description; this.desc = loc.description;
this.apisrc = "http://api.tianditu.gov.cn/staticimage?" this.apisrc = "http://api.tianditu.gov.cn/staticimage?"
+"center="+loc.longitude+","+loc.latitude +"center="+loc.longitude+","+loc.latitude
+"&width=400" +"&width=400"
+"&height=300" +"&height=250"
+"&zoom=10" +"&zoom=10"
+"&markers="+loc.longitude+","+loc.latitude +"&markers="+loc.longitude+","+loc.latitude
+"&tk=5255a4be64441ba9fa2ebe605ca472bf"; +"&tk=5255a4be64441ba9fa2ebe605ca472bf";
@@ -94,7 +95,6 @@
}) })
}, },
onLoaded() { onLoaded() {
this.loadingWidth = "auto";
}, },
}, },
@@ -104,7 +104,6 @@
<style lang="scss" scoped> <style lang="scss" scoped>
.location_message_container{ .location_message_container{
.address{ .address{
margin-top: 20rpx;
} }
} }
</style> </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>
@@ -54,7 +54,7 @@
"videoType": "mp4", "videoType": "mp4",
"videoSize": 3751005, "videoSize": 3751005,
"duration": 44, "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, "snapshotSize": 36974,
"snapshotUrl": "http://www.axzc.xyz/object/100003/msg_videoSnapshot_d9a596f3e665e84559821a8aa5fb9f16.jpg", "snapshotUrl": "http://www.axzc.xyz/object/100003/msg_videoSnapshot_d9a596f3e665e84559821a8aa5fb9f16.jpg",
"snapshotWidth": 1087, "snapshotWidth": 1087,
@@ -116,8 +116,11 @@
}, },
methods: { methods: {
async init(){ async init(){
const snapshotUrl = this.message?.videoElem?.snapshotUrl; const self = this;
console.log(this.message?.videoElem);
const snapshotUrl = this.message?.videoElem?.snapshotPath || this.message?.videoElem?.snapshotUrl;
self.coverDownloading = true; self.coverDownloading = true;
console.log(snapshotUrl);
util.cacheFile(snapshotUrl,`${this.conversationID}`).then((fn)=>{ util.cacheFile(snapshotUrl,`${this.conversationID}`).then((fn)=>{
self.coverDownloading = false; self.coverDownloading = false;
self.src = fn; self.src = fn;
@@ -57,6 +57,7 @@
import MarkdownMessageRender from "./MarkdownMessageRender"; import MarkdownMessageRender from "./MarkdownMessageRender";
import StreamMessageRender from "./StreamMessageRender"; import StreamMessageRender from "./StreamMessageRender";
import OANotificationRender from "./OANotificationRender"; import OANotificationRender from "./OANotificationRender";
import NotificationRender from "./NotificationRender";
import ErrorMessageRender from "./ErrorMessageRender"; import ErrorMessageRender from "./ErrorMessageRender";
import {noticeMessageTypes} from "@/constant"; import {noticeMessageTypes} from "@/constant";
@@ -82,6 +83,7 @@
MarkdownMessageRender, MarkdownMessageRender,
StreamMessageRender, StreamMessageRender,
OANotificationRender, OANotificationRender,
NotificationRender,
ErrorMessageRender ErrorMessageRender
}, },
props: { props: {
@@ -173,7 +175,8 @@
['type_'+MessageType.FaceMessage] : "FaceMessageRender", ['type_'+MessageType.FaceMessage] : "FaceMessageRender",
['type_'+MessageType.MarkdownMessage] : "MarkdownMessageRender", ['type_'+MessageType.MarkdownMessage] : "MarkdownMessageRender",
['type_'+MessageType.StreamMessage] : "StreamMessageRender", ['type_'+MessageType.StreamMessage] : "StreamMessageRender",
['type_'+MessageType.OANotification] : "OANotificationRender" ['type_'+MessageType.OANotification] : "OANotificationRender",
'type_2001' : "NotificationRender"
}; };
this.component = MsgType2Components['type_'+this.source.contentType] || "ErrorMessageRender"; this.component = MsgType2Components['type_'+this.source.contentType] || "ErrorMessageRender";
this.$emit('userEvent',{type:"messageItemRender"},this.source.clientMsgID); this.$emit('userEvent',{type:"messageItemRender"},this.source.clientMsgID);
@@ -103,19 +103,20 @@
flex:1; flex:1;
.details { .details {
@include colBox(true); display: flex;
flex-direction: column;
justify-content: space-around;
flex:1; flex:1;
margin-left: 24rpx; margin-left: 24rpx;
height: 46px; height: 46px;
color: $uni-text-color; color: $u-main-color;
padding-bottom:20rpx;
.title{ .title{
@include btwBox(); @include btwBox();
.conversation_name { .conversation_name {
@include nomalEllipsis(); @include nomalEllipsis();
max-width: 40vw; max-width: 40vw;
font-size: 32rpx; font-size: 32rpx;
font-weight: 500; font-weight: 400;
} }
.right_desc { .right_desc {
+1 -7
View File
@@ -14,13 +14,7 @@
<script> <script>
import {mapGetters} from "vuex"; import {mapGetters} from "vuex";
import IMSDK, { import IMSDK, {GroupMemberRole,GroupStatus,GroupVerificationType,IMMethods,MessageReceiveOptType,} from "openim-uniapp-polyfill";
GroupMemberRole,
GroupStatus,
GroupVerificationType,
IMMethods,
MessageReceiveOptType,
} from "openim-uniapp-polyfill";
import {GroupMemberListTypes} from "@/constant"; import {GroupMemberListTypes} from "@/constant";
export default { export default {
data() { data() {
+265 -295
View File
@@ -1,314 +1,284 @@
<template> <template>
<view @click="pageClick" class="group_members_container"> <view @click="pageClick" class="group_members_container">
<group-member-list-header <group-member-list-header ref="navHeaderRef" :checkVisible.sync="showCheck" :isTransfer="isTransfer"
ref="navHeaderRef" :isNomal="!isOwner && !isAdmin" :groupID="groupID" @removeMember="showMemberCheck" />
:checkVisible.sync="showCheck"
:isTransfer="isTransfer"
:isNomal="!isOwner && !isAdmin"
:groupID="groupID"
@removeMember="showMemberCheck"
/>
<view class="search_bar_wrap"> <view class="search_bar_wrap">
<u-search <u-search disabled class="search_bar" shape="square" placeholder="搜索" :showAction="false"
disabled v-model="keyword" />
class="search_bar" </view>
shape="square"
placeholder="搜索"
:showAction="false"
v-model="keyword"
/>
</view>
<u-list <u-list class="member_list" @scrolltolower="loadMore" lowerThreshold="100" height="1">
class="member_list" <u-list-item v-for="member in groupMemberList" :key="member.userID">
@scrolltolower="loadMore" <user-item @itemClick="userClick" @updateCheck="updateCheck" :checked="isChecked(member.userID)"
lowerThreshold="100" :checkVisible="showCheck" :disabled="!canCheck(member) && showCheck" :item="member" />
height="1" </u-list-item>
> <view v-show="loadState.loading" class="member_loading">
<u-list-item v-for="member in groupMemberList" :key="member.userID"> <u-loading-icon></u-loading-icon>
<user-item </view>
@itemClick="userClick" </u-list>
@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>
<choose-index-footer <choose-index-footer v-if="showCheck" :comfirmLoading="comfirmLoading" @removeItem="updateCheck"
v-if="showCheck" @confirm="confirm" :choosedData="getChoosedData" :isRemove="isRemove" :maxLength="groupMemberLength" />
:comfirmLoading="comfirmLoading"
@removeItem="updateCheck"
@confirm="confirm"
:choosedData="getChoosedData"
:isRemove="isRemove"
:maxLength="groupMemberLength"
/>
<u-modal <u-modal :show="showConfirmModal" asyncClose showCancelButton @confirm="modalConfirm"
:show="showConfirmModal" @cancel="() => (showConfirmModal = false)" :content="
asyncClose
showCancelButton
@confirm="modalConfirm"
@cancel="() => (showConfirmModal = false)"
:content="
isRemove isRemove
? '确定移除已选群成员?' ? '确定移除已选群成员?'
: `确定要把群主转移给${choosedTransferMember.nickname}吗?` : `确定要把群主转移给${choosedTransferMember.nickname}吗?`
" " />
/> <u-toast ref="uToast"></u-toast>
<u-toast ref="uToast"></u-toast> </view>
</view>
</template> </template>
<script> <script>
let moreActionArea; let moreActionArea;
import { GroupMemberListTypes } from "@/constant"; import {GroupMemberListTypes} from "@/constant";
import IMSDK, { GroupMemberRole } from "openim-uniapp-polyfill"; import IMSDK, {GroupMemberRole} from "openim-uniapp-polyfill";
import UserItem from "@/components/UserItem/index.vue"; import UserItem from "@/components/UserItem/index.vue";
import GroupMemberListHeader from "./components/GroupMemberListHeader.vue"; import GroupMemberListHeader from "./components/GroupMemberListHeader.vue";
import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue"; import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue";
export default { import util from "@/util/index.js"
components: { export default {
GroupMemberListHeader, components: {
ChooseIndexFooter, GroupMemberListHeader,
UserItem, ChooseIndexFooter,
}, UserItem,
data() { },
return { data() {
showCheck: false, return {
groupID: "", showCheck: false,
keyword: "", groupID: "",
showConfirmModal: false, keyword: "",
comfirmLoading: false, showConfirmModal: false,
groupMemberList: [], comfirmLoading: false,
choosedMemberIDList: [], groupMemberList: [],
choosedTransferMember: {}, choosedMemberIDList: [],
type: GroupMemberListTypes.Preview, choosedTransferMember: {},
isRightKick: true, type: GroupMemberListTypes.Preview,
loadState: { isRightKick: true,
hasMore: true, loadState: {
loading: false, hasMore: true,
}, loading: false,
}; },
}, };
computed: { },
getChoosedData() { computed: {
const tmpList = [...this.choosedMemberIDList]; getChoosedData() {
return this.groupMemberList.filter( const tmpList = [...this.choosedMemberIDList];
(member) => { return this.groupMemberList.filter(
const idx = tmpList.findIndex((item) => item === member.userID); (member) => {
if (idx > -1) { const idx = tmpList.findIndex((item) => item === member.userID);
tmpList.splice(idx, 1); if (idx > -1) {
} tmpList.splice(idx, 1);
return idx > -1; }
}, return idx > -1;
); },
}, );
isRemove() { },
return this.type === GroupMemberListTypes.Kickout; isRemove() {
}, return this.type === GroupMemberListTypes.Kickout;
isTransfer() { },
return this.type === GroupMemberListTypes.Transfer; isTransfer() {
}, return this.type === GroupMemberListTypes.Transfer;
isChecked() { },
return (userID) => this.choosedMemberIDList.includes(userID); isChecked() {
}, return (userID) => this.choosedMemberIDList.includes(userID);
isOwner() { },
return ( isOwner() {
this.$store.getters.storeCurrentMemberInGroup.roleLevel === return (
GroupMemberRole.Owner this.$store.getters.storeCurrentMemberInGroup.roleLevel ===
); GroupMemberRole.Owner
}, );
isAdmin() { },
return ( isAdmin() {
this.$store.getters.storeCurrentMemberInGroup.roleLevel === return (
GroupMemberRole.Admin this.$store.getters.storeCurrentMemberInGroup.roleLevel ===
); GroupMemberRole.Admin
}, );
canCheck() { },
return ({ roleLevel, userID }) => { canCheck() {
if (this.type === GroupMemberListTypes.Kickout) { return ({
return ( roleLevel,
(this.isOwner || userID
(this.isAdmin && roleLevel !== GroupMemberRole.Owner)) && }) => {
userID !== this.$store.getters.storeCurrentUserID if (this.type === GroupMemberListTypes.Kickout) {
); return (
} (this.isOwner ||
(this.isAdmin && roleLevel !== GroupMemberRole.Owner)) &&
userID !== this.$store.getters.storeCurrentUserID
);
}
return userID !== this.$store.getters.storeCurrentUserID; return userID !== this.$store.getters.storeCurrentUserID;
}; };
}, },
groupMemberLength() { groupMemberLength() {
return this.$store.getters.storeCurrentGroup?.memberCount ?? 0; return this.$store.getters.storeCurrentGroup?.memberCount ?? 0;
}, },
}, },
onLoad(options) { onLoad(options) {
const { groupID, type } = options; const {
this.loadMemberList(groupID); groupID,
this.type = type; type
this.groupID = groupID; } = options;
this.isRightKick = type === GroupMemberListTypes.Kickout; this.loadMemberList(groupID);
if ( this.type = type;
this.isRightKick this.groupID = groupID;
) { this.isRightKick = type === GroupMemberListTypes.Kickout;
this.showCheck = true; if (
} this.isRightKick
}, ) {
methods: { this.showCheck = true;
async pageClick(e) { }
if (!moreActionArea) { },
moreActionArea = await this.getEl(".more_container"); methods: {
} async pageClick(e) {
if (!moreActionArea) return; if (!moreActionArea) {
if ( moreActionArea = await this.getEl(".more_container");
e.target.y < moreActionArea.top || }
e.target.y > moreActionArea.bottom || if (!moreActionArea) return;
e.target.x < moreActionArea.left if (
) { e.target.y < moreActionArea.top ||
this.$refs.navHeaderRef.checkMenu(); e.target.y > moreActionArea.bottom ||
} e.target.x < moreActionArea.left
}, ) {
confirm() { this.$refs.navHeaderRef.checkMenu();
this.showConfirmModal = true; }
}, },
modalConfirm() { confirm() {
let func = () => {}; this.showConfirmModal = true;
if (this.type === GroupMemberListTypes.Kickout) { },
func = IMSDK.asyncApi(IMSDK.IMMethods.KickGroupMember, IMSDK.uuid(), { modalConfirm() {
groupID: this.getChoosedData[0].groupID, let func = () => {};
reason: "", if (this.type === GroupMemberListTypes.Kickout) {
userIDList: this.getChoosedData.map((member) => member.userID), func = IMSDK.asyncApi(IMSDK.IMMethods.KickGroupMember, IMSDK.uuid(), {
}); groupID: this.getChoosedData[0].groupID,
} else { reason: "",
func = IMSDK.asyncApi( userIDList: this.getChoosedData.map((member) => member.userID),
IMSDK.IMMethods.TransferGroupOwner, });
IMSDK.uuid(), } else {
{ func = IMSDK.asyncApi(
groupID: this.choosedTransferMember.groupID, IMSDK.IMMethods.TransferGroupOwner,
newOwnerUserID: this.choosedTransferMember.userID, IMSDK.uuid(), {
}, groupID: this.choosedTransferMember.groupID,
); newOwnerUserID: this.choosedTransferMember.userID,
} },
func );
.then(() => this.showToast("操作成功", () => uni.navigateBack())) }
.catch(() => this.showToast("操作失败")) func
.finally(() => (this.showConfirmModal = false)); .then(() => this.showToast("操作成功", () => uni.navigateBack()))
}, .catch(() => this.showToast("操作失败"))
updateChoosedData(userID) { .finally(() => (this.showConfirmModal = false));
if (this.choosedMemberIDList.includes(userID)) { },
const idx = this.choosedMemberIDList.findIndex( updateChoosedData(userID) {
(item) => item === userID, if (this.choosedMemberIDList.includes(userID)) {
); const idx = this.choosedMemberIDList.findIndex(
const tmpArr = [...this.choosedMemberIDList]; (item) => item === userID,
tmpArr.splice(idx, 1); );
this.choosedMemberIDList = tmpArr; const tmpArr = [...this.choosedMemberIDList];
} else { tmpArr.splice(idx, 1);
this.choosedMemberIDList = [...this.choosedMemberIDList, userID]; this.choosedMemberIDList = tmpArr;
} } else {
console.log(this.choosedMemberIDList); this.choosedMemberIDList = [...this.choosedMemberIDList, userID];
}, }
userClick(member) { console.log(this.choosedMemberIDList);
if (this.type === GroupMemberListTypes.Transfer) { },
if (member.userID === this.$store.getters.storeCurrentUserID) return; userClick(member) {
this.choosedTransferMember = member; if (this.type === GroupMemberListTypes.Transfer) {
this.showConfirmModal = true; if (member.userID === this.$store.getters.storeCurrentUserID) return;
} else { this.choosedTransferMember = member;
uni.$u.route("/pages/common/userCard/index", { this.showConfirmModal = true;
sourceID: member.userID, } else {
memberInfo: JSON.stringify(member), const s = util.aesencode(member);
}); uni.$u.route("/pages/common/userCard/index", {
} sourceID: member.userID,
}, memberInfo: s,
updateCheck(member) { });
this.updateChoosedData(member.userID); }
}, },
showMemberCheck() { updateCheck(member) {
this.type = GroupMemberListTypes.Kickout; this.updateChoosedData(member.userID);
this.showCheck = true; },
}, showMemberCheck() {
loadMore() { this.type = GroupMemberListTypes.Kickout;
const stateKey = "loadState"; this.showCheck = true;
const methodKey = "loadMemberList"; },
if (this[stateKey].hasMore && !this[stateKey].loading) { loadMore() {
this[methodKey](); const stateKey = "loadState";
} const methodKey = "loadMemberList";
}, if (this[stateKey].hasMore && !this[stateKey].loading) {
loadMemberList(groupID) { this[methodKey]();
this.loadState.loading = true; }
IMSDK.asyncApi(IMSDK.IMMethods.GetGroupMemberList, IMSDK.uuid(), { },
groupID: groupID ?? this.groupID, loadMemberList(groupID) {
filter: 0, this.loadState.loading = true;
offset: this.groupMemberList.length, IMSDK.asyncApi(IMSDK.IMMethods.GetGroupMemberList, IMSDK.uuid(), {
count: 500, groupID: groupID ?? this.groupID,
}) filter: 0,
.then(({ data }) => { offset: this.groupMemberList.length,
this.groupMemberList = [...this.groupMemberList, ...data]; count: 500,
this.loadState.hasMore = data.length === 500; })
}) .then(({
.finally(() => (this.loadState.loading = false)); data
}, }) => {
showToast(message, complete = null) { this.groupMemberList = [...this.groupMemberList, ...data];
this.$refs.uToast.show({ this.loadState.hasMore = data.length === 500;
message, })
complete, .finally(() => (this.loadState.loading = false));
}); },
}, showToast(message, complete = null) {
getEl(el) { this.$refs.uToast.show({
return new Promise((resolve) => { message,
const query = uni.createSelectorQuery().in(this); complete,
query });
.select(el) },
.boundingClientRect((data) => { getEl(el) {
// 存在data,且存在宽和高,视为渲染完毕 return new Promise((resolve) => {
resolve(data); const query = uni.createSelectorQuery().in(this);
}) query
.exec(); .select(el)
}); .boundingClientRect((data) => {
}, // 存在data,且存在宽和高,视为渲染完毕
}, resolve(data);
onBackPress(options) { })
if (this.showCheck && this.isRightKick) { .exec();
this.showCheck = false; });
this.type = GroupMemberListTypes.Preview; },
return true; },
} onBackPress(options) {
return false; if (this.showCheck && this.isRightKick) {
}, this.showCheck = false;
}; this.type = GroupMemberListTypes.Preview;
return true;
}
return false;
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.group_members_container { .group_members_container {
@include colBox(false); @include colBox(false);
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
.search_bar_wrap { .search_bar_wrap {
height: 34px; height: 34px;
padding: 12px 22px; padding: 12px 22px;
} }
.at_all_btn { .at_all_btn {
font-weight: 500; font-weight: 500;
padding: 24rpx 44rpx; padding: 24rpx 44rpx;
} }
::v-deep.u-popup { ::v-deep.u-popup {
flex: none; flex: none;
} }
.member_list { .member_list {
flex: 1; flex: 1;
} }
} }
</style> </style>
+7 -12
View File
@@ -62,18 +62,13 @@
<script> <script>
import {mapGetters} from "vuex"; import {mapGetters} from "vuex";
import {GroupMemberListTypes} from "@/constant"; import {GroupMemberListTypes} from "@/constant";
import IMSDK, { import IMSDK, {GroupMemberRole,GroupStatus,GroupVerificationType,IMMethods,MessageReceiveOptType,} from "openim-uniapp-polyfill";
GroupMemberRole,
GroupStatus,
GroupVerificationType,
IMMethods,
MessageReceiveOptType,
} from "openim-uniapp-polyfill";
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import MyAvatar from "@/components/MyAvatar/index.vue"; import MyAvatar from "@/components/MyAvatar/index.vue";
import SettingItem from "@/components/SettingItem/index.vue"; import SettingItem from "@/components/SettingItem/index.vue";
import GroupMemberRow from "./components/GroupMemberRow.vue"; import GroupMemberRow from "./components/GroupMemberRow.vue";
import {getPurePath} from "@/util/common"; import {getPurePath} from "@/util/common";
import util from "@/util/index.js"
const ConfirmTypes = { const ConfirmTypes = {
Dismiss: "Dismiss", Dismiss: "Dismiss",
@@ -193,13 +188,13 @@
return this.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Admin; return this.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Admin;
}, },
getGroupQrcdeUrl(){ getGroupQrcdeUrl(){
const info = { const info = util.aesencode({
code : this.storeCurrentConversation.groupID, code : this.storeCurrentConversation.groupID,
showName: `${this.storeCurrentConversation.showName}(${this.storeCurrentGroup.memberCount})`, showName: `${this.storeCurrentConversation.showName}(${this.storeCurrentGroup.memberCount})`,
faceURL : this.storeCurrentConversation.faceURL, faceURL : this.storeCurrentConversation.faceURL,
type : "group", type : "group",
}; });
return `/pages/common/userOrGroupQrCode?sourceInfo=${JSON.stringify(info,)}`; return `/pages/common/userOrGroupQrCode?sourceInfo=${s}`;
}, },
getGroupVerStr() { getGroupVerStr() {
if ( if (
@@ -251,9 +246,9 @@
if (!this.isAdmin && !this.isOwner) { if (!this.isAdmin && !this.isOwner) {
return; return;
} }
const s = util.aesencode(this.storeCurrentGroup);
uni.navigateTo({ uni.navigateTo({
url: `/pages/conversation/updateGroupOrNickname/index?sourceInfo=${JSON.stringify(this.storeCurrentGroup,)}`, url: `/pages/conversation/updateGroupOrNickname/index?sourceInfo=${s}`,
}); });
}, },
copyGroupID() { copyGroupID() {
@@ -1,92 +1,89 @@
<template> <template>
<view class="page_container"> <view class="page_container">
<custom-nav-bar :title="getTitle"> <custom-nav-bar :title="getTitle">
<view class="nav_right_action" slot="more"> <view class="nav_right_action" slot="more">
<u-button type="primary" v-show="!updateLoading" @click="comfirmUpdate">保存</u-button> <u-button type="primary" v-show="!updateLoading" @click="comfirmUpdate">保存</u-button>
<u-loading-icon v-show="updateLoading" /> <u-loading-icon v-show="updateLoading" />
</view> </view>
</custom-nav-bar> </custom-nav-bar>
<view class="content_row"> <view class="content_row">
<u-input <u-input v-model="content" disabledColor="transparent" maxlength="16" placeholder="请输入内容" clearable>
v-model="content" </u-input>
disabledColor="transparent" </view>
maxlength="16" </view>
placeholder="请输入内容"
clearable
>
</u-input>
</view>
</view>
</template> </template>
<script> <script>
import IMSDK from "openim-uniapp-polyfill"; import IMSDK from "openim-uniapp-polyfill";
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import MyAvatar from "@/components/MyAvatar/index.vue"; import MyAvatar from "@/components/MyAvatar/index.vue";
export default { import util from "@/util/index.js"
components: { export default {
CustomNavBar, components: {
MyAvatar, CustomNavBar,
}, MyAvatar,
data() { },
return { data() {
sourceInfo: {}, return {
content: "", sourceInfo: {},
updateLoading: false, content: "",
}; updateLoading: false,
}, };
computed: { },
getTitle() { computed: {
return "修改群聊名称"; getTitle() {
}, return "修改群聊名称";
getSubTitle() { },
return "修改群名称后,将在群内通知其他成员"; getSubTitle() {
}, return "修改群名称后,将在群内通知其他成员";
}, },
onLoad(options) { },
const { sourceInfo } = options; onLoad(options) {
this.sourceInfo = JSON.parse(sourceInfo); const {
this.content = this.sourceInfo.groupName; sourceInfo
}, } = options;
methods: { this.sourceInfo = util.aesdecode(sourceInfo);
comfirmUpdate() { this.content = this.sourceInfo.groupName;
this.updateLoading = true; },
IMSDK.asyncApi(IMSDK.IMMethods.SetGroupInfo, IMSDK.uuid(), { methods: {
groupID: this.sourceInfo.groupID, comfirmUpdate() {
groupName: this.content, this.updateLoading = true;
}) IMSDK.asyncApi(IMSDK.IMMethods.SetGroupInfo, IMSDK.uuid(), {
.then(() => { groupID: this.sourceInfo.groupID,
uni.$u.toast("修改成功"); groupName: this.content,
setTimeout(() => uni.navigateBack(), 250); })
}) .then(() => {
.catch(() => uni.$u.toast("修改失败")) uni.$u.toast("修改成功");
.finally(() => (this.updateLoading = false)); setTimeout(() => uni.navigateBack(), 250);
}, })
}, .catch(() => uni.$u.toast("修改失败"))
}; .finally(() => (this.updateLoading = false));
},
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.page_container { .page_container {
@include colBox(false); @include colBox(false);
height: 100vh; height: 100vh;
.nav_right_action { .nav_right_action {
margin-right: 36rpx; margin-right: 36rpx;
} }
.content_row { .content_row {
margin-top: 96rpx; margin-top: 96rpx;
margin: 72rpx 44rpx 0; margin: 72rpx 44rpx 0;
.u-input { .u-input {
background-color: #e8eaef; background-color: #e8eaef;
} }
.u-button { .u-button {
height: 60rpx; height: 60rpx;
} }
} }
} }
</style> </style>
+75
View File
@@ -0,0 +1,75 @@
<template>
<view class="page">
<view v-if="i==1">
<view>
<image src='/static/img/g1.png' style="width: 60%; margin: auto;" mode="widthFix"></image>
</view>
<view style="font-size: 56rpx; color: #333; font-weight: 700; text-align: center; margin-top: 40rpx;">
Make some <span style="color: #1D61E7; margin-left: 20rpx;">money</span></view>
<view style="width: 80%; margin: 20rpx auto; text-align: center; font-size: 32rpx; color: #333;">
Paid surveys are a handy sideline for anyone looking to make some extra moneyYou earn a commission for
each survey you complete.
</view>
</view>
<view v-if="i==2">
<view>
<image src='/static/img/g2.png' style="width: 60%; margin: auto;" mode="widthFix"></image>
</view>
<view style="font-size: 56rpx; color: #333; font-weight: 700; text-align: center; margin-top: 40rpx;">
Make money by <br><span style="color: #1D61E7;">completing surveys</span></view>
<view style="width: 80%; margin: 20rpx auto; text-align: center; font-size: 32rpx; color: #333;">
If you are looking for an easy way to make money with surveys, you can join the "MMT" community.
</view>
</view>
<view style="bottom: 0rpx; position: absolute; width:100vw; height: 200rpx; ">
<button style="width: 86%; background-color: #1D61E7; color: #fff; margin: auto;"
@click="button">{{text}}</button>
</view>
</view>
</template>
<script>
import {getUserInfo} from '@/util';
import {mapState,mapMutations} from 'vuex';
export default {
data() {
return {
i: 1,
text: "Next"
}
},
computed: {
},
//第一次加载
onLoad(e) {
},
//页面显示
onShow() {},
//方法
methods: {
button() {
if (this.i == 1) {
this.i = 2;
this.text = "Enter"
} else {
uni.navigateTo({
url: '/pages/index/index'
})
}
}
}
};
</script>
<style lang="scss" scoped>
body {
background-color: #fff;
}
.page {
min-height: 96vh;
padding-top: 200rpx;
}
</style>
+541
View File
@@ -0,0 +1,541 @@
<template>
<view>
<view class="container">
<image src="/static/images/about_logo.png" class="gif-image" style="margin-top: 40%;" mode="aspectFit"></image>
</view>
</view>
</template>
<script>
import {mapGetters,mapActions} from "vuex";
import IMSDK, {IMMethods,MessageType,SessionType,} from "openim-uniapp-polyfill";
import config from "@/common/config";
import {getDbDir,toastWithCallback} from "@/util/common.js";
import {getConversationContent,conversationSort} from "@/util/imCommon";
import {PageEvents,UpdateMessageTypes} from "@/constant";
import {checkUpgrade} from "@/api/login.js"
export default {
data() {
return {
}
},
computed: {
...mapGetters([
"storeConversationList",
"storeCurrentConversation",
"storeCurrentUserID",
"storeSelfInfo",
"storeRecvFriendApplications",
"storeRecvGroupApplications",
"storeHistoryMessageList",
"storeIsSyncing",
"storeGroupList",
"config",
]),
},
onReady() {
//console.log('onReady');
// #ifdef APP
this.checkUpdate();
this.tryLogin();
// #endif
// setTimeout(() => {
// uni.navigateTo({
// url: '/pages/index/index'
// }); // 替换为你的首页路径
// }, 4000); // 假设GIF加载完毕并显示3秒后跳转,根据GIF实际时间调整
},
created() {
//console.log('created');
},
methods: {
...mapActions("message", ["pushNewMessage", "updateOneMessage"]),
...mapActions("conversation", ["updateCurrentMemberInGroup"]),
...mapActions("circle", ["getFriendCircleInfo"]),
...mapActions("contact", [
"updateFriendInfo",
"pushNewFriend",
"updateBlackInfo",
"pushNewBlack",
"pushNewGroup",
"updateGroupInfo",
"pushNewRecvFriendApplition",
"updateRecvFriendApplition",
"pushNewSentFriendApplition",
"updateSentFriendApplition",
"pushNewRecvGroupApplition",
"updateRecvGroupApplition",
"pushNewSentGroupApplition",
"updateSentGroupApplition",
]),
setGlobalIMlistener() {
//console.log("setGlobalIMlistener");
// init
const kickHander = (message) => {
toastWithCallback(message, () => {
uni.removeStorage({
key: "IMToken",
});
uni.removeStorage({
key: "BusinessToken",
});
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");
this.$store.dispatch("contact/getFriendList");
this.$store.dispatch("contact/getGrouplist");
this.$store.dispatch("conversation/getUnReadCount");
this.$store.commit("user/SET_IS_SYNCING", false);
};
//向服务器同步会话失败时的回调。
const syncFailedHandler = () => {
uni.hideLoading();
uni.$u.toast("同步消息失败");
this.$store.dispatch("conversation/getConversationList");
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);
// 当前登录用户个人信息改变时会收到此回调。
IMSDK.subscribe(IMSDK.IMEvents.OnSelfInfoUpdated, ({data}) => {
this.$store.commit("user/SET_SELF_INFO", {
...this.storeSelfInfo,
...data,
});
});
// message
//接收到新消息时会收到此回调,回调中只会携带一条消息。
//设置了批量消息监听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.OnFriendInfoChanged,({data}) => {
console.log('friendInfoChangeHandler',data);
uni.$emit(IMSDK.IMEvents.OnFriendInfoChanged, {data});
this.updateFriendInfo({friendInfo: data,});
});
//两个用户成功建立好友关系后双方都会收到该回调。
IMSDK.subscribe(IMSDK.IMEvents.OnFriendAdded, ({data}) => {
this.pushNewFriend(data);
});
//某个用户的好友列表减少时会收到该回调。
IMSDK.subscribe(IMSDK.IMEvents.OnFriendDeleted, ({data}) => {
this.updateFriendInfo({
friendInfo: data,
isRemove: true,
});
});
// blacklist
//某个用户的黑名单列表增加时会收到该回调。
IMSDK.subscribe(IMSDK.IMEvents.OnBlackAdded, ({data}) => {
this.pushNewBlack(data);
});
//某个用户的黑名单列表减少时会收到该回调。
IMSDK.subscribe(IMSDK.IMEvents.OnBlackDeleted, ({data}) => {
this.updateBlackInfo({
blackInfo: data,
isRemove: true,
});
});
// group
const joinedGroupAddedHandler = ({data}) => {
this.pushNewGroup(data);
};
const joinedGroupDeletedHandler = ({data}) => {
this.updateGroupInfo({
groupInfo: data,
isRemove: true,
});
};
const groupInfoChangedHandler = ({data}) => {
this.updateGroupInfo({
groupInfo: data,
});
};
const groupMemberInfoChangedHandler = ({data}) => {
uni.$emit(IMSDK.IMEvents.OnGroupMemberInfoChanged, {data});
if (data.groupID === this.storeCurrentConversation?.groupID) {
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;
if (isRecv) {
this.pushNewRecvFriendApplition(data);
} else {
this.pushNewSentFriendApplition(data);
}
};
const friendApplicationAccessHandler = ({data}) => {
const isRecv = data.toUserID === this.storeCurrentUserID;
if (isRecv) {
this.updateRecvFriendApplition({
application: data,
});
} else {
this.updateSentFriendApplition({
application: data,
});
}
};
const groupApplicationNumHandler = ({data}) => {
const isRecv = data.userID !== this.storeCurrentUserID;
if (isRecv) {
this.pushNewRecvGroupApplition(data);
} else {
this.pushNewSentGroupApplition(data);
}
};
const groupApplicationAccessHandler = ({data}) => {
const isRecv = data.userID !== this.storeCurrentUserID;
if (isRecv) {
this.updateRecvGroupApplition({
application: data,
});
} else {
this.updateSentGroupApplition({
application: data,
});
}
};
//用户发起好友申请后,申请发起者和接收者都会收到此回调,接收者可以选择同意或拒绝好友申请。
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 })=>{});
//收到的消息被撤回或自己发出的消息被撤回时,会收到此回调。
//IMSDK.subscribe(IMSDK.IMEvents.onNewRecvMessageRevoked,({ data })=>{});
//自己发出的单聊消息被对方标记为已读后,消息发送者会收到此回调。
//IMSDK.subscribe(IMSDK.IMEvents.onRecvC2CReadReceipt,({ data })=>{});
//自己发出的群聊消息被群成员标记为已读后,消息发送者和标记者均会收到此回调。
//IMSDK.subscribe(IMSDK.IMEvents.onRecvGroupReadReceipt,({ data })=>{});
//当应用在后台运行,接收到新消息时,会收到该回调,回调中只会携带一条消息。
//设置了批量消息监听setBatchMsgListener时,此回调不会触发。
//IMSDK.subscribe(IMSDK.IMEvents.onRecvOfflineNewMessage,({ data })=>{});
//当应用在后台运行,接收到新消息时,会收到该回调,回调中可能会携带多条消息。
IMSDK.subscribe(IMSDK.IMEvents.OnRecvOfflineNewMessages,(res)=>{
console.log(res);
});
//已订阅用户的在线状态发生变化时,会触发此回调。
//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(IMSDK.IMEvents.onInputStatusChanged,({ data })=>{});
// conversation
const totalUnreadCountChangedHandler = ({data}) => {
if (this.storeIsSyncing) {
return;
}
this.$store.commit("conversation/SET_UNREAD_COUNT", data);
};
const newConversationHandler = ({data}) => {
if (this.storeIsSyncing) {
return;
}
const result = [...data, ...this.storeConversationList];
this.$store.commit(
"conversation/SET_CONVERSATION_LIST",
conversationSort(result)
);
};
const conversationChangedHandler = ({data}) => {
//console.log('conversationChangedHandler',data);
if (this.storeIsSyncing) {
return;
}
let filterArr = [];
//console.log(data);
const chids = data.map((ch) => ch.conversationID);
filterArr = this.storeConversationList.filter((tc) => !chids.includes(tc.conversationID));
const idx = data.findIndex((c) =>c.conversationID === this.storeCurrentConversation.conversationID);
if (idx !== -1){
this.$store.commit("conversation/SET_CURRENT_CONVERSATION",data[idx]);
}
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);
},
async tryLogin() {
const _this = this;
const IMToken = uni.getStorageSync("IMToken");
const IMUserID = uni.getStorageSync("IMUserID")+'';
//console.log('IMToken:',IMToken);
//console.log('IMUserID:',IMUserID);
if (IMToken && IMUserID) {
//un1i.create1PushMessage({content:"水水水水水水,请重新登陆!"})
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,
};
//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('初始化status === 3失败!');
_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();
});
}
}else{
plus.navigator.closeSplashscreen();
uni.$u.route("/pages/common/login/index");
}
},
handleNewMessage(newServerMsg) {
if (this.inCurrentConversation(newServerMsg)) {
if (
newServerMsg.contentType !== MessageType.TypingMessage &&
newServerMsg.contentType !== MessageType.RevokeMessage
) {
newServerMsg.isAppend = true;
this.pushNewMessage(newServerMsg);
setTimeout(() => uni.$emit(PageEvents.ScrollToBottom, true));
uni.$u.debounce(this.markConversationAsRead, 2000);
}
}else{
console.log(newServerMsg);
console.log( getConversationContent(newServerMsg));
uni.createPushMessage({
title:"您的朋友发来新的消息",
content:getConversationContent(newServerMsg),
payload: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);
}
});
}
},
inCurrentConversation(newServerMsg) {
switch (newServerMsg.sessionType) {
case SessionType.Single:
return (
newServerMsg.sendID === this.storeCurrentConversation.userID ||
(newServerMsg.sendID === this.storeCurrentUserID &&
newServerMsg.recvID === this.storeCurrentConversation.userID)
);
case SessionType.WorkingGroup:
return newServerMsg.groupID === this.storeCurrentConversation.groupID;
case SessionType.Notification:
return newServerMsg.sendID === this.storeCurrentConversation.userID;
default:
return false;
}
},
markConversationAsRead() {
IMSDK.asyncApi(
IMSDK.IMMethods.MarkConversationMessageAsRead,
IMSDK.uuid(),
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");
uni.switchTab({
url: "/pages/conversation/conversationList/index?isRedirect=true",
complete() {
_this.keppAlive();
plus.navigator.closeSplashscreen();
},
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')
}
})
})
},
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
}
}
}
</script>
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
.gif-image {
width: 50%;
}
</style>
+13 -7
View File
@@ -16,7 +16,7 @@
<view class="qr" @click="toSelfQr"> <view class="qr" @click="toSelfQr">
<img src="static/images/self_info_qr.png" alt="" /> <img src="static/images/self_info_qr.png" alt="" />
<img src="static/images/common_right.png" alt="" /> <u-icon name="arrow-right" color="#999"></u-icon>
</view> </view>
</view> </view>
</view> </view>
@@ -94,6 +94,7 @@
uni.removeStorage({ uni.removeStorage({
key: "BusinessToken", key: "BusinessToken",
}); });
IMSDK.asyncApi(IMSDK.IMMethods.UnInitSDK,IMSDK.uuid());
}).catch((err) => { }).catch((err) => {
console.log(err) console.log(err)
}).finally(() => { }).finally(() => {
@@ -116,13 +117,14 @@
}); });
}, },
toSelfQr() { toSelfQr() {
const info = { const info = util.aesencode({
code : this.selfInfo.userID, code : this.selfInfo.userID,
showName: `${this.selfInfo.nickname}`, showName: `${this.selfInfo.nickname}`,
faceURL : this.selfInfo.faceURL, faceURL : this.selfInfo.faceURL,
type : "user", type : "user"
}; });
const url = `/pages/common/userOrGroupQrCode?sourceInfo=${JSON.stringify(info,)}`;
const url = `/pages/common/userOrGroupQrCode?sourceInfo=${info}`;
uni.navigateTo({ uni.navigateTo({
url: url, url: url,
}); });
@@ -204,15 +206,19 @@
.nickname { .nickname {
@include nomalEllipsis(); @include nomalEllipsis();
max-width: 400rpx; max-width: 400rpx;
font-weight: 500; font-weight: 400;
font-size: 34rpx; font-size: 34rpx;
margin-bottom: 20rpx;
} }
.id { .id {
color: #8e9ab0; color: #8e9ab0;
} }
} }
.qr{
display: flex;
align-items: center;
}
img { img {
width: 18px; width: 18px;
height: 18px; height: 18px;
+20 -21
View File
@@ -32,9 +32,7 @@
import dayjs from "dayjs"; import dayjs from "dayjs";
import InfoItem from "./InfoItem.vue"; import InfoItem from "./InfoItem.vue";
import util from "@/util"; import util from "@/util";
import { import {getPurePath} from "@/util/common";
getPurePath
} from "@/util/common";
export default { export default {
components: { components: {
CustomNavBar, CustomNavBar,
@@ -74,8 +72,9 @@
methods: { methods: {
...util, ...util,
updateNickname() { updateNickname() {
const s = util.aesencode(this.selfInfo);
uni.navigateTo({ uni.navigateTo({
url: `/pages/common/markOrIDPage/index?isSelfNickname=true&sourceInfo=${JSON.stringify(this.selfInfo)}`, url: `/pages/common/markOrIDPage/index?isSelfNickname=true&sourceInfo=${s}`,
}); });
}, },
updateGender() { updateGender() {
@@ -102,23 +101,23 @@
const fileName = path.slice(nameIdx); const fileName = path.slice(nameIdx);
const fileType = path.slice(typeIdx); const fileType = path.slice(typeIdx);
this.loadingState.faceURL = true; this.loadingState.faceURL = true;
const { try{
data: { const res = await IMSDK.asyncApi(IMSDK.IMMethods.UploadFile, IMSDK.uuid(), {
url filepath: getPurePath(tempFilePaths[0]),
}, name: fileName,
} = await IMSDK.asyncApi(IMSDK.IMMethods.UploadFile, IMSDK.uuid(), { contentType: fileType,
filepath: getPurePath(tempFilePaths[0]), uuid: IMSDK.uuid(),
name: fileName, });
contentType: fileType, console.log(res);
uuid: IMSDK.uuid(), this.updateSelfInfo({
}); faceURL: res.data.url,
console.log(url); },
this.updateSelfInfo({ "faceURL",
faceURL: url, );
}, this.loadingState.faceURL = false;
"faceURL", }catch(e){
); console.log(e);
this.loadingState.faceURL = false; }
}, },
}); });
}, },
Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 B

+13 -1
View File
@@ -27,6 +27,18 @@ const mutations = {
}, },
SET_RECV_FRIEND_APPLICATIONS(state, list) { SET_RECV_FRIEND_APPLICATIONS(state, list) {
state.recvFriendApplications = [...list]; state.recvFriendApplications = [...list];
const count = list.filter((item) => item.handleResult === 0);
state.unHandleFriendApplicationNum = count.length;
if(state.unHandleFriendApplicationNum>0){
uni.setTabBarBadge({
index:1,
text:(state.unHandleFriendApplicationNum<100?state.unHandleFriendApplicationNum:'···')+'',
});
}else{
uni.hideTabBarRedDot({
index:1
})
}
}, },
SET_SENT_FRIEND_APPLICATIONS(state, list) { SET_SENT_FRIEND_APPLICATIONS(state, list) {
state.sentFriendApplications = [...list]; state.sentFriendApplications = [...list];
@@ -60,7 +72,7 @@ const actions = {
if (data.length < count) break; if (data.length < count) break;
initialFetch = false; initialFetch = false;
} catch (error) { } catch (error) {
console.error("getFriendListPage error"); console.error("getFriendListPage error",error);
} }
} }
commit("SET_FRIEND_LIST", friendInfoList); commit("SET_FRIEND_LIST", friendInfoList);
+1 -1
View File
@@ -36,4 +36,4 @@
-webkit-line-clamp: $line; -webkit-line-clamp: $line;
overflow: hidden; overflow: hidden;
word-break: break-all; word-break: break-all;
} }
@@ -1,5 +1,32 @@
<template> <template>
<view class="ly-map-wrapper"> <view class="ly-map-wrapper">
<view style="background: transparent;position: absolute;z-index:1998;top:10px;left: 10px;right:10px;display: flex;align-items: center;justify-content: space-between;">
<uni-icons type="left" size="26" color="#333" @click="back"></uni-icons>
<u-button
@click="confirm"
type="primary"
v-if="type == 'chooselocation'"
style="font-size: 15px;width: 100rpx;margin: 0;">确定</u-button>
</view>
<!-- <uni-nav-bar
left-icon="back"
@clickLeft="back"
backgroundColor="transparent"
:border="false"
fixed
statusBar
>
<template slot="right" v-if="type == 'chooselocation'">
<u-button
type="primary"
size="mini"
:customStyle="{
fontSize: '26rpx',
padding: '16rpx auto'
}"
@click="confirm">确定</u-button>
</template>
</uni-nav-bar> -->
<!-- 地图展示 --> <!-- 地图展示 -->
<view :id="mapId" :config="config" :change:config="LyMap.init" :call="option" :change:call="LyMap.call" <view :id="mapId" :config="config" :change:config="LyMap.init" :call="option" :change:call="LyMap.call"
class="ly-map" /> class="ly-map" />
@@ -48,7 +75,8 @@
showLocationIcon: { showLocationIcon: {
type: Boolean, type: Boolean,
default: false, default: false,
} },
type:String
}, },
// //
data() { data() {
@@ -81,6 +109,12 @@
}, },
// //
methods: { methods: {
confirm(){
this.$emit('onUserEvent',{type:'confirm'});
},
back(){
this.$emit('onUserEvent',{type:'back'});
},
// ID // ID
genId() { genId() {
let result = ''; let result = '';
@@ -621,7 +655,7 @@
height: 100%; height: 100%;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
background: #f0f0f0; background: transparent;
.ly-map { .ly-map {
width: 100%; width: 100%;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

+4 -1
View File
@@ -32,7 +32,6 @@ dayjs.updateLocale("zh-cn", {
export const formatMessageTime = (timestemp, keepSameYear = false) => { export const formatMessageTime = (timestemp, keepSameYear = false) => {
if (!timestemp) return ""; if (!timestemp) return "";
const isRecent = dayjs().diff(timestemp, "day") < 7; const isRecent = dayjs().diff(timestemp, "day") < 7;
const keepYear = keepSameYear || !isThisYear(timestemp); const keepYear = keepSameYear || !isThisYear(timestemp);
@@ -211,6 +210,10 @@ export const parseMessageByType = (pmsg) => {
return `[RevokeMessage]`; return `[RevokeMessage]`;
case MessageType.MsgPinned: case MessageType.MsgPinned:
return `[MsgPinned]`; return `[MsgPinned]`;
case 2001:
const body = JSON.parse(pmsg.notificationElem.detail);
body.data = JSON.parse(body.data);
return parseMessageByType(body.data);
default: default:
return "[暂未支持的消息类型]"; return "[暂未支持的消息类型]";
} }
+125 -2
View File
@@ -4,6 +4,7 @@ import base from '@/common/config';
//import store from "@/store"; //import store from "@/store";
import IMSDK from "openim-uniapp-polyfill"; import IMSDK from "openim-uniapp-polyfill";
import CryptoJS from 'crypto-js';
import md5 from "md5"; import md5 from "md5";
import {downloadFile} from "@/uni_modules/network-manage"; import {downloadFile} from "@/uni_modules/network-manage";
@@ -233,8 +234,6 @@ const get_absolute_path = (fn)=>{
} }
const pendingDownloads = new Map(); const pendingDownloads = new Map();
const cacheFile = (url, saveDir,progressCallback) => { const cacheFile = (url, saveDir,progressCallback) => {
let cacheDir = plus.io.convertLocalFileSystemURL(`_doc/{{dir}}/{{key}}.{{ext}}`);
cacheDir = cacheDir.replace('apps/'+plus.runtime.appid+'/doc','cache');
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
if(!url || !url.startsWith('http')){ if(!url || !url.startsWith('http')){
@@ -246,6 +245,8 @@ const cacheFile = (url, saveDir,progressCallback) => {
if(url.toLowerCase().indexOf('.mp4')!==-1){ if(url.toLowerCase().indexOf('.mp4')!==-1){
ext = "mp4"; ext = "mp4";
} }
let cacheDir = plus.io.convertLocalFileSystemURL(`_doc/{{dir}}/{{key}}.{{ext}}`);
cacheDir = cacheDir.replace('apps/'+plus.runtime.appid+'/doc','cache');
const cacheFilePath = cacheDir.replace('{{dir}}',saveDir) const cacheFilePath = cacheDir.replace('{{dir}}',saveDir)
.replace('{{key}}',key) .replace('{{key}}',key)
.replace('{{ext}}',ext); .replace('{{ext}}',ext);
@@ -315,8 +316,130 @@ const cacheFile = (url, saveDir,progressCallback) => {
} }
}); });
}; };
const toMapAPP = (latitude,longitude,name) =>{
let url = "";
if (plus.os.name == "Android") {//判断是安卓端
plus.nativeUI.actionSheet({//选择菜单
title: "选择地图应用",
cancel: "取消",
buttons: [{title: "腾讯地图"},{title: "百度地图"}, {title: "高德地图"}]
}, function(e) {
switch (e.index) {
//下面是拼接url,不同系统以及不同地图都有不同的拼接字段
case 1:
//注意referer=xxx的xxx替换成你在腾讯地图开发平台申请的key
url = `qqmap://map/geocoder?coord=${latitude},${longitude}&referer=xxx`;
break;
case 2:
url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&coord_type=gcj02&src=andr.baidu.openAPIdemo`;
break;
case 3:
url = `androidamap://viewMap?sourceApplication=appname&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`;
break;
default:
break;
}
if (url != "") {
url = encodeURI(url);
//plus.runtime.openURL(url,function(e){})调起手机APP应用
plus.runtime.openURL(url, function(e) {
plus.nativeUI.alert("本机未安装指定的地图应用");
});
}
})
} else {
// iOS上获取本机是否安装了百度高德地图,需要在manifest里配置
// 在manifest.json文件app-plus->distribute->apple->urlschemewhitelist节点下添加
//(如urlschemewhitelist:["iosamap","baidumap"]
plus.nativeUI.actionSheet({
title: "选择地图应用",
cancel: "取消",
buttons: [{title: "腾讯地图"},{title: "百度地图"}, {title: "高德地图"}]
}, function(e) {
switch (e.index) {
case 1:
url = `qqmap://map/geocoder?coord=${latitude},${longitude}&referer=xxx`;
break;
case 2:
url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&content=${name}&src=ios.baidu.openAPIdemo&coord_type=gcj02`;
break;
case 3:
url = `iosamap://viewMap?sourceApplication=applicationName&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`;
break;
default:
break;
}
if (url != "") {
url = encodeURI(url);
plus.runtime.openURL(url, function(e) {
plus.nativeUI.alert("本机未安装指定的地图应用");
});
}
})
}
}
/**
* AES 加密函数
* @param {String|Object|Array} str 要加密的内容
* @param {String} key 加密密钥
* @returns {String} 加密后的Base64字符串
*/
const aesencode = (str, key = 'muNcJyt0XXV6faCGe41VSIaf0ecZeW2jXmgpL0Ak93Kbwjyr')=> {
// 如果是对象或数组,转为JSON字符串
if (typeof str === 'object') {
str = JSON.stringify(str);
}
// 使用SHA-256哈希处理密钥
const hashedKey = CryptoJS.SHA256(key);
// 生成IV(前16字节)
const iv = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 4));
// 加密
const encrypted = CryptoJS.AES.encrypt(str,hashedKey,{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// 返回Base64编码结果
const _str = encrypted.toString();
return _str.replace(/\+/ig,'%2b');
}
/**
* AES 解密函数
* @param {String} str 要解密的Base64字符串
* @param {String} key 解密密钥
* @returns {String} 解密后的原始字符串
*/
const aesdecode = (str, key = 'muNcJyt0XXV6faCGe41VSIaf0ecZeW2jXmgpL0Ak93Kbwjyr') => {
// 使用SHA-256哈希处理密钥
const hashedKey = CryptoJS.SHA256(key);
// 生成IV(前16字节)
const iv = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 4));
str = str.replace(/\%2b/ig,'+');
// 解密
const decrypted = CryptoJS.AES.decrypt(str,hashedKey,{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// 转为UTF-8字符串
let _str = decrypted.toString(CryptoJS.enc.Utf8);
console.log(_str);
const obj = _str.startsWith('{') || _str.startsWith('[') ? JSON.parse(_str) : _str;
return obj;
}
export default{ export default{
aesdecode,
aesencode,
toMapAPP,
cacheFile, cacheFile,
fileExsit, fileExsit,
get_absolute_path, get_absolute_path,