This commit is contained in:
cansnow
2026-02-09 07:29:02 +08:00
parent 2860c46ec1
commit 6720c15e30
19 changed files with 996 additions and 207 deletions
+9 -7
View File
@@ -128,14 +128,14 @@
uni.request({
url:url,
success(res){
//console.log(res.data);
console.log(res.data);
const result = res.data.result;
_this.address = result.formatted_address;
console.log( {
lng: result.location.lon,
lat: result.location.lat,
address: result.formatted_address
});
// console.log( {
// lng: result.location.lon,
// lat: result.location.lat,
// address: result.formatted_address
// });
//return 1;
// 通过事件通道返回数据给父页面
const eventChannel = _this.getOpenerEventChannel();
@@ -143,7 +143,9 @@
eventChannel.emit('onConfirm', {
lng: result.location.lon,
lat: result.location.lat,
address: result.formatted_address
name: result.addressComponent.town,
address: result.formatted_address,
addressComponent:result.addressComponent
});
uni.navigateBack();
},
+1
View File
@@ -30,6 +30,7 @@
to="/pages/contact/applicationList/index?applicationType=NewGroup"
thumb="/static/images/contact_new_group.png"></uni-list-item>
<uni-list-item
v-if="1==2"
title="群聊"
thumbSize="lg"
to="/pages/contact/groupList/index"
@@ -67,7 +67,9 @@
import SimpleEditor from "./SimpleEditor";
import ChatingActionBar from "./ChatingActionBar";
import Recoder from "./Recoder";
import {upload} from "@/api/login.js"
import IM from "@/util/im.js";
import permision from "@/js_sdk/wa-permission/permission.js"
const needClearTypes = [MessageType.TextMessage];
const rtcChoose = [
@@ -177,8 +179,12 @@
if (needClearTypes.includes(message.contentType)) {
this.$refs.customEditor.clear();
}
let method = IMMethods.SendMessage;
if([MessageType.PictureMessage,MessageType.VoiceMessage,MessageType.VideoMessage,MessageType.FileMessage].includes(message.contentType)){
method = IMMethods.SendMessageNotOss;
}
this.$emit("scrollToBottom");
IMSDK.asyncApi(IMMethods.SendMessage, IMSDK.uuid(), {
IMSDK.asyncApi(method, IMSDK.uuid(), {
recvID: user_id,
groupID: group_id,
message,
@@ -211,7 +217,6 @@
});
},
recordAudioMsg(){
if (uni.getSystemInfoSync().platform == "android") {
permission.requestAndroid("android.permission.RECORD_AUDIO"); //Android请求录音权限
} else {
@@ -281,36 +286,15 @@
sendMediaMesage(paths) {
const _this = this;
paths.forEach(async (item) => {
console.log(item);
try {
let message = null;
if(item.search('.mp4')>0){
const realVideoPath = await getPurePath(item);
console.log('处理后的可用路径', realVideoPath);
const info = await getVideoInfo(realVideoPath);
//const cover = await getVideoCover(item);
const res1 = await IMSDK.getVideoCover(item);
//console.log(res1.path);
const videoParams = {
videoPath: realVideoPath,
videoType: "mp4",
duration: info.duration,
snapshotPath: getPurePath(res1.path),
//snapshotPath: getPurePath(cover),
};
console.log('videoParams', videoParams);
message = await IMSDK.asyncApi(
IMMethods.CreateVideoMessageFromFullPath,
IMSDK.uuid(),
videoParams
);
message = await IM.createVideoMessage(item);
}else{
message = await IMSDK.asyncApi(
IMMethods.CreateImageMessageFromFullPath,
IMSDK.uuid(),
getPurePath(item)
);
message = await IM.createImageMessage(item);
}
//console.log(message);
console.log(message);
if(message){
_this.sendMessage(message,_this.storeCurrentConversation.userID,_this.storeCurrentConversation.groupID);
}
@@ -401,6 +385,31 @@
break;
}
},
pickMedia(){
const _this = this;
plus.gallery.pick(({files})=>{
console.log(files);
_this.sendMediaMesage(files);
}, (error )=>{
console.log(error);
}, {
animation:true,
confirmText:"确定",
//crop:null,
editable:true,
filename:"_doc/",
//filter:"none",//image,none,video
filter:"image",
maximum:9,
multiple:true,
permissionAlert:true,
//popover:{},
//selected:[""],
onmaxed(){
console.log("超出最大选择数");
},
});
},
onUserEvent(e){
const _this = this;
switch(e.type){
@@ -455,33 +464,8 @@
return ;
}
if(e.source == "album"){
// IMSDK.pickFile().then(res=>{
// console.log(res);
// }).catch(e=>{
// console.log(e);
// });
// return;
plus.gallery.pick(({files})=>{
_this.sendMediaMesage(files);
}, (error )=>{
console.log(error);
}, {
animation:true,
confirmText:"确定",
//crop:null,
editable:true,
filename:"_doc/",
filter:"none",
maximum:9,
multiple:true,
permissionAlert:true,
//popover:{},
//selected:[""],
onmaxed(){
console.log("超出最大选择数");
},
});
}
_this.pickMedia();
}
break;
case "prepend_call_message":
this.actionSheetMenu = [...rtcChoose];
@@ -1,14 +1,13 @@
<template>
<view>
<view class="video_message_container" @click="clickMediaItem">
<view class="video_message_container">
<u--image
:showLoading="true"
:src="src"
:width="imgWidth"
:height="maxHeight"
mode="widthFix"
@load="onLoaded"
@click="clickMediaItem">
@load="onLoaded" >
<template v-slot:loading>
<u-loading-icon color="red"></u-loading-icon>
</template>
@@ -21,8 +20,8 @@
</view>
<text class="progress-text">{{ videoDownloadProgress }}%</text>
</view>
<u-icon v-else-if="videoExists" class="play_icon" name="play-circle" size="48" color="#fff"></u-icon>
<uni-icons v-else class="play_icon" type="cloud-download" size="48" color="#fff"></uni-icons>
<u-icon v-else-if="videoExists" class="play_icon" name="play-circle" size="48" color="#ccc"></u-icon>
<uni-icons v-else class="play_icon" type="cloud-download" size="48" color="#ccc"></uni-icons>
</view>
</view>
<!-- 视频播放器组件 -->
@@ -116,23 +115,17 @@
},
methods: {
async init(){
const self = this;
const _this = this;
console.log(this.message?.videoElem,this.conversationID);
const snapshotUrl = this.message?.videoElem?.snapshotUrl;
self.coverDownloading = true;
_this.coverDownloading = true;
//console.log(snapshotUrl);
util.cacheFile(snapshotUrl,`${this.conversationID}`).then((fn)=>{
self.coverDownloading = false;
self.src = fn;
_this.coverDownloading = false;
_this.src = fn;
//console.log(fn);
});
},
clickMediaItem() {
uni.previewImage({
current: 0,
urls: [this.message.videoElem?.snapshotUrl],
indicator: "none",
});
_this.videoExists = util.fileExsit(util.getCachePath(_this.message?.videoElem?.videoUrl,`${_this.conversationID}`));
},
async onLoaded() {
this.loadingWidth = "auto";
@@ -1,8 +1,8 @@
<template>
<view v-if="isNoticeMessage" class="notice_message_container" style="margin: 0 auto;" :id="`auchor${source.clientMsgID}`">
<view v-if="isNoticeMessage" class="notice_message_container" :id="`auchor${source.clientMsgID}`">
<text>{{ getNoticeContent }}</text>
</view>
<view v-else-if="source.contentType == 1519" class="notice_message_container" style="margin: 0 auto;" :id="`auchor${source.clientMsgID}`">
<view v-else-if="source.contentType == 1519" class="notice_message_container" :id="`auchor${source.clientMsgID}`">
<text @click="toAnnouncement">{{ announcementElem.opUser.nickname }}更新了群公告</text>
</view>
<view v-else class="message_wrapper">
@@ -282,7 +282,7 @@
margin-bottom: 6rpx;
}
.message_content_wrap_shadow {
box-shadow: 0px 0px 2px rgba(0,0,0,0.1);
box-shadow: 0px 0px 0px rgba(0,0,0,0.1);
}
.message_content_wrap {
@include vCenterBox();
@@ -345,7 +345,7 @@
// text-align: end;
align-items: flex-end;
.message_content_wrap_shadow {
box-shadow: 0px 0px 2px #95e261;
box-shadow: 0px 0px 0px #95e261;
}
.message_content_wrap {
flex-direction: row-reverse;
@@ -375,10 +375,14 @@
.notice_message_container {
@include ellipsisWithLine(2);
text-align: center;
margin: 24rpx 48rpx;
padding: 24rpx 48rpx;
word-break: break-word;
// font-size: 24rpx;
font-size: 0.85rem;
text-align: center;
color: #999;
width: 100%;
box-sizing: border-box;
position: relative;
}
@@ -6,7 +6,7 @@
:autoBack="true"
>
<view class="u-nav-slot" slot="right" v-if="isOwner || isAdmin">
<u-button type="primary" size="mini" @click="save">保存</u-button>
<u-button type="primary" @click="save">保存</u-button>
</view>
</u-navbar>
<u-parse v-if="!isOwner && !isAdmin" :content="announcement"></u-parse>
@@ -16,7 +16,7 @@
focus
autoHeight
height="500"
maxlength="-1"
maxlength="1500"
border="none"
:adjustPosition="false"
class="textarea"
@@ -77,4 +77,9 @@
<style scoped lang="scss">
.textarea{
}
.u-nav-slot{
.u-button{
height: 60rpx;
}
}
</style>
@@ -47,6 +47,7 @@
</view>
<u-toast ref="uToast"></u-toast>
<c-cut-avatar ref="cutAvatar" @save="saveAvatar" />
</view>
</template>
@@ -60,6 +61,7 @@
import GroupMemberRow from "./components/GroupMemberRow.vue";
import {getPurePath} from "@/util/common";
import util from "@/util/index.js"
import {upload} from "@/api/login.js";
const ConfirmTypes = {
Dismiss: "Dismiss",
@@ -273,6 +275,22 @@
console.log(e);
})
},
saveAvatar(e){
if (!this.isAdmin && !this.isOwner) {
return;
}
this.tempFilePath = e.path;
upload(e.path,{
'url':"/group/avatar",
savePath: "groupavatar",
groupID: this.storeCurrentConversation.groupID,
}).then((res) => {
console.log("上传成功",res);
//userStore.selfInfo.faceURL = res.data.faceURL;
}).catch((res1) => {
console.log("上传失败",res1);
});
},
updateGroupAvatar() {
if (!this.isAdmin && !this.isOwner) {
return;
@@ -285,6 +303,8 @@
tempFilePaths
}) => {
const path = tempFilePaths[0];
this.$refs.cutAvatar.enterEditor(path);
return ;
const nameIdx = path.lastIndexOf("/") + 1;
const typeIdx = path.lastIndexOf(".") + 1;
const fileName = path.slice(nameIdx);
+14 -6
View File
@@ -1,12 +1,17 @@
<template>
<view class="content">
<u-navbar title="选择背景图" :background="{ background: '#ffffff'}"
:border-bottom="false">
<view class="slot-wrap" slot="right">
<uni-nav-bar
left-icon="back"
@clickLeft="uni.$u.route({type:'back'})"
statusBar
backgroundColor="#ffffff"
:border="false"
title="选择背景图">
<template v-slot:footer>
<u-button :custom-style="customBtnStyle" size="mini" :disabled="submitFlag"
:type="submitFlag?'info ':'success'" @click="handleLink()">设置</u-button>
</view>
</u-navbar>
</template>
</uni-nav-bar>
<u-grid @click="clickGrid">
<u-grid-item v-for="(item, index) in bgList" :key="index" :index="index" :custom-style="item.isCheck?girdItemCustomStyle:{}">
<u-image :src="item.src" width="200rpx" height="200rpx" mode="aspectFill"></u-image>
@@ -46,7 +51,10 @@ export default {
handleLink(){
const item = this.bgList.find(it=>it.isCheck);
if(item){
this.$u.vuex('circleBgImg', item.src);
this.$store.commit('circle/SET_SETTINGS',{
...this.$store.storeCircleSettings,
bg:item.src
});
uni.navigateBack({
delta:2
})
+23 -29
View File
@@ -1,22 +1,21 @@
<template>
<view>
<u-cell-group>
<u-cell-item title="选择内置背景图" :title-style="titleStyle"
:border-bottom="false" :border-top="false"
@click="linkToBuiltinBgImg"></u-cell-item>
</u-cell-group>
<u-gap :height="16" bg-color="#f4f4f5"></u-gap>
<u-cell-group>
<u-cell-item title="通过手机选择" :title-style="titleStyle"
:border-bottom="false" :border-top="false"
@click="chooseImg"></u-cell-item>
</u-cell-group>
<u-toast ref="uToast" />
<uni-nav-bar
left-icon="back"
@clickLeft="uni.$u.route({type:'back'})"
statusBar
backgroundColor="#ffffff"
title="选择背景图">
</uni-nav-bar>
<uni-list>
<uni-list-item disabled="true" title="选择内置背景图" @click="linkToBuiltinBgImg" clickable showArrow></uni-list-item>
<uni-list-item title="通过手机选择" @click="chooseImg" clickable showArrow></uni-list-item>
</uni-list>
</view>
</template>
<script>
import {upload} from "@/api/login"
export default {
data() {
return {
@@ -46,26 +45,21 @@ export default {
//上传返回图片
myUpload(filePath) {
let that=this;
let _this=this;
let obj = {
filePath:filePath,
savePath: "friendCircle" //文件存放目录
'url':"/friendcircle/upload_bg",
savePath: "circle" //文件存放目录
}
console.log("通过手机选择",obj);
this.globalUtil.globalUpload(that,{
param:obj,
success: (res1) => {
console.log("上传成功",res1);
let avatar= res1.result.url;
that.$u.vuex('circleBgImg',avatar);
uni.navigateBack();
},
fail:(res1) => {
console.log("上传失败",res1);
},
complete: (res1) => {
console.log("上传完成",res1);
}
upload(filePath,obj).then((res1) => {
_this.$store.commit('circle/SET_SETTINGS',{
..._this.$store.storeCircleSettings,
bg:res1.data.url
});
uni.navigateBack();
}).catch((res1) => {
console.log("上传失败",res1);
});
},
@@ -39,14 +39,9 @@
<!-- 视频 -->
<view class="u-m-b-30 u-m-t-30 u-flex u-row-left u-col-center"
<view class="u-m-b-30 u-m-t-30 u-flex u-row-left u-col-center"
v-if="item.files.length > 0&&item.releaseType==2" @tap="previewImg(0, item)">
<view v-if="vuex_OSPlat=='ios'">
<u-image width="280rpx" :src="getVideoPoster(item.files[0])" mode="widthFix">
<u-loading-icon slot="loading"></u-loading-icon>
</u-image>
</view>
<view v-else class="u-flex u-row-center u-col-center"
<view class="u-flex u-row-center u-col-center"
style="border: 1rpx solid #36648b;width:280rpx;height:120rpx;border-radius: 16rpx;">
<u-icon name="play-circle" size="48" color="#36648b"
label="点击查看视频" label-pos="bottom"></u-icon>
@@ -55,9 +50,9 @@
</view>
<!-- 地点 -->
<view v-if="(item.address&&item.address.chooseFlag)==true" class="u-line-2 u-m-t-10 u-m-b-10" style="font-size: 30rpx;color: #36648b;">
<u-icon name="map" color="#36648b" size="30" :custom-style="{marginLeft:'-4rpx'}"></u-icon>
<text> {{ item.address.name}}</text>
<view v-if="(item.address&&item.address.chooseFlag)==true" @click="gotomap(item)" class="content-address">
<u-icon name="map" color="#36648b"></u-icon>
<u-text class="name" :lines="1" :text="item.address.name"></u-text>
</view>
<!-- 相对时间 点赞按钮等 -->
@@ -182,6 +177,12 @@
return "http://192.168.31.125:9090/we-chat/images/friendCircle/1715421601709.mp4";
//return videoSrc;
},
gotomap(item){
const addr = item.address;
uni.navigateTo({
url:`/pages/common/map?type=viewlocation&lng=${addr.longitude}&lat=${addr.latitude}&address=${addr.address}`
})
},
cdn:util.cdn
}
}
@@ -254,7 +255,18 @@
}
}
}
&-address{
font-size: 26rpx;
color: #36648b;
display: flex;
align-items: center;
margin-top: 10rpx;
.u-icon{
}
.name{
}
}
.msg-box {
width: 100%;
background-color: #FFF;
+7 -4
View File
@@ -16,7 +16,7 @@
</u-navbar>
<!-- 我的朋友圈基本信息 -->
<view class="content-imgbox" :class="{top:scrollTop>bannarHeight}">
<image class="bgimg" v-if="storeCircleSettings.bg" :src="storeCircleSettings.bg" mode="scaleToFill" @tap="showSheet"></image>
<image class="bgimg" v-if="storeCircleSettings.bg" :src="cdn(storeCircleSettings.bg)" mode="scaleToFill" @tap="showSheet"></image>
<view class="bgimg" v-else @tap="showSheet"></view>
<MyAvatar class="headimg" :src="storeSelfInfo.faceURL" :desc="storeSelfInfo.nickname || storeSelfInfo.remark"
@@ -90,9 +90,9 @@
import {getFriendCircle} from "@/api/login.js"
import UserBase from "@/components/User.vue"
import MyAvatar from "@/components/MyAvatar/index.vue";
import util from "@/util/index.js";
import CircleItem from "./components/circleItem.vue"
import { mapGetters } from "vuex";
import util from "@/util";
export default {
name: 'firendCircle',
mixins:[UserBase],
@@ -185,6 +185,7 @@
methods: {
goto:util.goto,
cdn:util.cdn,
clearUnReadCount(){
this.$store.dispatch('circle/updateUnreadCount',0-this.unreadCount);
},
@@ -244,11 +245,13 @@
showTypeSheet() {
const _this = this;
uni.showActionSheet({
itemList:['选择照片','选择视频'],
itemList:['文字','照片'/*,'视频'*/],
success: function (res) {
//toChooseRelease
if(res.tapIndex<2){
if([1,2].includes(res.tapIndex)){
_this.toChooseRelease(res.tapIndex);
}else{
_this.linkToRelease({releaseType:0})
}
},
fail: function (res) {
@@ -22,7 +22,7 @@
:adjust-position="true" :auto-blur="true" @linechange="inputLineChange" @input="inputing"
:confirm-hold="true" :show-confirm-bar="false"
:focus="inputFocusFlag" :disable-default-padding="true"
v-model="content" :cursor="content.length" :maxlength="-1" />
v-model="content" :cursor="content.length" :maxlength="1500" />
</scroll-view>
<!-- 文件选择区 -->
<view v-if="releaseType!=0" class="uploadBox">
@@ -49,29 +49,33 @@
</view>
<!-- 选项 -->
<view class="tips">
<u-cell-group>
<!-- :value="address.name" :value-style="customValueStyle" :label="address.address" -->
<u-cell bg-color="#ffffff"
:title="address.chooseFlag?(address.name):'所在位置'" :title-style="customTitleStyle"
:value="address.chooseFlag?(address.address):'请选择'" isLink
@click="toChooseLocation()">
<view slot="icon" class="u-flex u-row-center u-col-center">
<u-icon name="map" size="32" :color="address.chooseFlag?'#19be6b':'#606266'"></u-icon>
</view>
</u-cell>
<u-cell bg-color="#ffffff" title="提醒谁看" :title-style="customTitleStyle" @click="toRemind">
<view slot="icon" class="u-flex u-row-center u-col-center">
<u-icon name="/static/images/friendCircle/at.png" width="24" height="24" color="#606266"></u-icon>
</view>
</u-cell>
<u-cell bg-color="#ffffff" @click="toSetPromission()"
title="谁可以看" :title-style="customTitleStyle"
:value="'公开'" :value-style="customValueStyle">
<view slot="icon" class="u-flex u-row-center u-col-center">
<u-icon name="account" size="32" color="#606266"></u-icon>
</view>
</u-cell>
</u-cell-group>
<uni-list>
<uni-list-item
title="所在位置"
:rightText="address.chooseFlag?(address.name):'请选择'"
:show-extra-icon="true"
:extra-icon="{color: '#666',size: '22',type: 'location-filled'}"
clickable
showArrow
@click="toChooseLocation">
</uni-list-item>
<uni-list-item v-if="1==2"
title="提醒谁看"
:rightText="address.chooseFlag?(address.address):'请选择'"
clickable
showArrow
@click="toRemind">
</uni-list-item>
<uni-list-item
title="谁可以看"
rightText="公开"
:show-extra-icon="true"
:extra-icon="{color: '#666',size: '22',type: 'notification-filled'}"
clickable
showArrow
@click="toSetPromission">
</uni-list-item>
</uni-list>
</view>
</view>
@@ -273,21 +277,23 @@
//去选择所在位置
toChooseLocation:function(){
let that=this;
uni.chooseLocation({
success: function (res) {
// console.log('位置名称' + res.name);
// console.log('详细地址' + res.address);
// console.log('纬度' + res.latitude);
//console.log('经度' + res.longitude);
that.address=res;
that.address.chooseFlag=true;
//console.log("that.address",that.address);
},
fail:function(){
that.address={};
that.address.chooseFlag=false;
uni.navigateTo({
url:"/pages/common/map",
events:{
onConfirm(res) {
//_this.sendLocationMessage(res);
that.address={
address:res.address,
name:`${res.addressComponent.city}${res.addressComponent.town}`,
latitude:res.lat,
longitude:res.lng,
};
that.address.chooseFlag=true;
console.log(res);
}
}
});
})
return ;
},
//设置发布朋友圈的查看权限
toSetPromission:function(){
@@ -422,28 +428,16 @@
let that=this;
console.error('submitPublish');
uni.$u.http.post('/friendcircle/create',param).then(res => {
let newCircle=res;
if(newCircle.address!=null&&newCircle.address.length>0){
newCircle.address=JSON.parse(newCircle.address);
}else{
newCircle.address={"chooseFlag":false};
}
if(newCircle.fileList!=null&&newCircle.fileList.length>0){
newCircle.fileList=JSON.parse(newCircle.fileList);
}else{
newCircle.fileList=[];
}
if(newCircle.praise!=null){
newCircle.praise=JSON.parse(newCircle.praise);
}else{
newCircle.praise=[];
}
if(newCircle.comment!=null){
newCircle.comment=JSON.parse(newCircle.comment);
}
else{
newCircle.comment=[];
}
console.log("发布成功",res);
let newCircle=res.data;
newCircle['user'] = {
"id": this.$store.getters.storeSelfInfo.userID,
"nickname": this.$store.getters.storeSelfInfo.nickname,
"avatar": this.$store.getters.storeSelfInfo.faceURL,
};
newCircle['likes'] = [];
newCircle['comments'] = [];
newCircle['is_liked'] = false;
let circleDataList=[...this.circleData];
circleDataList.unshift(newCircle);
that.$store.commit('circle/SET_LIST',circleDataList);
+21 -4
View File
@@ -19,13 +19,13 @@
<u-datetime-picker :minDate="0" :maxDate="nowDate" :show="showDatePicker" @confirm="confirmDate"
@cancel="() => (showDatePicker = false)" v-model="selfInfo.birth" mode="date" />
<c-cut-avatar ref="cutAvatar" @save="saveAvatar" />
</view>
</template>
<script>
import {
businessInfoUpdate
} from "@/api/login";
import {businessInfoUpdate,upload} from "@/api/login";
import IMSDK from "openim-uniapp-polyfill";
import CustomNavBar from "@/components/CustomNavBar/index.vue";
import MyAvatar from "@/components/MyAvatar/index.vue";
@@ -87,14 +87,31 @@
},
});
},
saveAvatar(e){
this.tempFilePath = e.path;
upload(e.path,{
'url':"/user/avatar",
savePath: "avatar"
}).then((res) => {
console.log("上传成功",res);
this.$store.commit("user/SET_SELF_INFO",{
...this.$store.getters.storeSelfInfo,
faceURL: res.data.avatar,
});
}).catch((res1) => {
console.log("上传失败",res1);
});
},
updateAvatar() {
uni.chooseImage({
count: 1,
sizeType: ["compressed"],
sizeType: ["original"],
success: async ({
tempFilePaths
}) => {
const path = tempFilePaths[0];
this.$refs.cutAvatar.enterEditor(path);
return ;
const nameIdx = path.lastIndexOf("/") + 1;
const typeIdx = path.lastIndexOf(".") + 1;
const fileName = path.slice(nameIdx);