增加群相册功能,长按朋友圈文字可以复制

This commit is contained in:
cansnow
2026-01-20 18:09:59 +08:00
parent db99bebcb4
commit 37b53b54ff
15 changed files with 489 additions and 32 deletions
+2 -2
View File
@@ -18,7 +18,7 @@
//screen.orientation.type = "";
screen.orientation.lock('portrait');
// #endif
// #ifndef MP
// #ifdef MP
console.error(
`暂时不支持运行到小程序端`
);
@@ -540,7 +540,7 @@
_this.checkUpdate();
},
fail(e){
//console.log(e);
console.log(e);
}
});
}
+1 -1
View File
@@ -132,7 +132,7 @@ export const upload = (files,data,onProgress) =>{
console.log(typeof files);
return new Promise((resolve,reject)=>{
var u = uni.uploadFile({
url: config.getRegisterUrl()+"/user/upload", // 仅为示例,非真实的接口地址
url: config.getRegisterUrl()+(data?.url || "/user/upload"),
filePath: files,
//files:files.length > 1 ? files : files[0],
name: "file",
+72
View File
@@ -0,0 +1,72 @@
<template>
<view @longpress="longpress" >
<u-image
@click="click"
:width="width"
:height="height"
:mode="mode"
@error="errorHandle"
:src="cachesrc"></u-image>
</view>
</template>
<script>
import util from "@/util";
export default {
name: "CacheImage",
props: {
src: String,
type: {
type: String,
default: "images",
},
mode:{
type: String,
default: "aspectFill",
},
width: {
type: Number|String,
default: "100",
},
height: {
type: Number|String,
default: "",
},
shape:{
type: String,
default: "square",
}
},
data() {
return {
cachesrc:"",
};
},
created() {
this.init(this.src);
},
methods: {
init(nv){
const _this = this;
if (nv) {
util.cacheFile(util.cdn(nv),this.type).then(res=>{
_this.cachesrc = res;
//console.log(_this.cachesrc);
});
return ;
}
},
errorHandle() {
this.cachesrc="/static/images/default_image.png";
},
click() {
this.$emit("click");
},
longpress() {
this.$emit("longpress");
},
}
};
</script>
<style></style>
-1
View File
@@ -58,6 +58,5 @@ app.REQUEST_TRACE = false;
// 引入请求封装
import request from "./util/request/index";
request(app)
//require("./util/request/index")(app);
app.$mount();
+2 -2
View File
@@ -2,8 +2,8 @@
"name" : "瞬聊",
"appid" : "__UNI__E41111F",
"description" : "一款即时聊天软件",
"versionName" : "3.4.2",
"versionCode" : 342,
"versionName" : "3.4.3",
"versionCode" : 343,
"transformPx" : false,
"app-plus" : {
"bounce" : "none",
+13 -1
View File
@@ -377,6 +377,12 @@
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/conversation/groupAlbum/groupAlbum",
"style": {
"navigationBarTitleText": ""
}
}
],
"tabBar": {
@@ -418,5 +424,11 @@
"app-plus": {
"bounce": "none"
}
}
},
"easycom": {
"autoscan": true,
"custom": {
"^c-(.*)": "@/components/$1/index.vue"
}
}
}
+10
View File
@@ -89,6 +89,16 @@
console.log(r);
this.updateCurrentMsg({});
})
//console.log(this.storeCurrentConversation)
if(process.env.NODE_ENV == 'development'){
// if(this.storeCurrentConversation.groupID){
// setTimeout(()=>{
// uni.navigateTo({
// url:"/pages/conversation/groupAlbum/groupAlbum?groupID="+this.storeCurrentConversation.groupID
// });
// },1000)
// }
}
},
watch:{
storeCurrentMsgID(nv,ov){
@@ -77,15 +77,15 @@
//console.log(this.storeConversationList);
this.freshing = false;
if(process.env.NODE_ENV == 'development'){
// setTimeout(()=>{
// // uni.switchTab({
// // url:"/pages/user/index/index"
// // })
// // uni.navigateTo({
// // url:"/pages/user/vip/vip"
// // });
// //prepareConversationState(this.storeConversationList[1]);
// },1000)
setTimeout(()=>{
// uni.switchTab({
// url:"/pages/user/index/index"
// })
// uni.navigateTo({
// url:"/pages/conversation/groupAlbum/groupAlbum?groupID=1731702760"
// });
//prepareConversationState(this.storeConversationList[0]);
},1000)
}
},
methods: {
@@ -0,0 +1,354 @@
<template>
<view class="group_album_page">
<uni-nav-bar left-icon="back" @clickLeft="back" @clickRight="manage" title="群相册" statusBar fixed>
<view slot="left">
<uni-icons type="back"></uni-icons>
</view>
<view slot="right" v-if="isAdmin">
<text v-if="manageStatus">取消</text>
<text v-else>管理</text>
</view>
</uni-nav-bar>
<view class="list">
<view class="item" v-if="isAdmin">
<view class="pickfile" @click="pickMedia">
<u-icon
color="#D3d3d3"
size="40"
name="plus"
></u-icon>
</view>
</view>
<view v-for="(item,index) in fileList" :key="'fileList'+index" class="item">
<c-CacheImage :src="item.url" width="234rpx" height="234rpx"></c-CacheImage>
<view class="overlay"></view>
<u-line-progress :percentage="item.progress" showText></u-line-progress>
</view>
<view v-for="(item,index) in list" :key="index" class="item" @click="itemClick(item,index)" :class="{cancheck:manageStatus,checked:selectedItemIds.includes(item.id)}">
<c-CacheImage :src="item.url" width="234rpx" height="234rpx" @click="itemClick(item,index)" ></c-CacheImage>
</view>
</view>
<u-loadmore :status="load_status" />
<view class="footer" v-if="manageStatus">
<button @click="selectAll" size="mini">全选</button>
<button @click="deleteItem" type="warn" size="mini">删除({{selectedItemIds.length}})</button>
</view>
</view>
</template>
<script>
import util from "@/util/index.js"
import {upload} from "@/api/login.js"
import {mapGetters} from "vuex";
import {GroupMemberRole} from "openim-uniapp-polyfill";
export default {
data() {
return {
albumWidth: 0,
fileList: [],
list: [
{
id:1,
url: "https://cdn.uviewui.com/uview/album/1.jpg",
},
{
id:2,
url: "https://cdn.uviewui.com/uview/album/2.jpg",
},
{
id:3,
url: "https://cdn.uviewui.com/uview/album/3.jpg",
},
{
id:4,
url: "https://cdn.uviewui.com/uview/album/4.jpg",
},
{
id:5,
url: "https://cdn.uviewui.com/uview/album/5.jpg",
},
{
id:6,
url: "https://cdn.uviewui.com/uview/album/6.jpg",
},
{
id:7,
url: "https://cdn.uviewui.com/uview/album/7.jpg",
},
{
id:8,
url: "https://cdn.uviewui.com/uview/album/8.jpg",
},
{
id:9,
url: "https://cdn.uviewui.com/uview/album/9.jpg",
},
],
manageStatus: false,
selectedItemIds:[],
uploadButtonWidth:0,
load_status:"loadmore",
param: {
groupID: "",
offset: 0,
limit: 10,
trace: 1,
}
};
},
computed: {
...mapGetters([
"storeCurrentConversation",
"storeCurrentMemberInGroup",
"storeCurrentGroup",
]),
isAdmin() {
return this.storeCurrentMemberInGroup.roleLevel > GroupMemberRole.Normal;
},
},
onLoad(opt) {
this.param.groupID = opt.groupID
//this.param.groupID = opt.storeCurrentConversation.groupID;
this.init();
this.uploadButtonWidth = uni.$u.getPx('234rpx');
},
methods: {
init() {
this.getList(true);
},
getList(isFirstPage = false) {
if (isFirstPage === true) {
this.list = [];
this.param.offset = 0;
}
this.load_status = 'loading';
uni.$u.http.post('/group/album_list', this.param).then(res => {
if(res.length>0){
this.param.offset = res[0].id;
this.list = this.list.concat(res);
this.load_status = 'loadmore';
if(res.length < this.param.limit){
this.load_status = 'nomore';
}
return ;
}
this.load_status = 'nomore';
}).catch(e => {
this.load_status = 'loadmore';
})
},
itemClick(item,index) {
if(this.manageStatus && this.isAdmin){
if(this.selectedItemIds.includes(item.id)){
this.selectedItemIds = this.selectedItemIds.filter(id=>item.id!=id)
}else{
this.selectedItemIds.push(item.id);
}
return ;
}
const urls = this.list.map(item=>item.url);
uni.previewImage({
urls:urls,
current:index,
})
},
deleteItem(){
if(!this.isAdmin || this.selectedItemIds.length == 0){
return ;
}
const _this = this;
uni.showModal({
content:"确定删除吗?一旦删除不能恢复",
success(res) {
if(res.confirm){
_this.doDelete();
}
}
})
},
selectAll(){
if(!this.isAdmin){
return ;
}
const arr = [];
this.list.forEach(item=>{
arr.push(item.id);
})
this.selectedItemIds = [...arr];
},
doDelete(){
if(!this.isAdmin || this.selectedItemIds.length == 0){
return ;
}
uni.$u.http.post('/group/album_delete', {ids:this.selectedItemIds}).then(res => {
this.list = this.list.filter(item=>!this.selectedItemIds.includes(item.id));
this.selectedItemIds = [];
this.manageStatus = false;
}).catch(e => {
uni.$u.toast(e?.msg || e);
})
},
back() {
if (this.manageStatus) {
this.manageStatus = false;
return;
}
util.goto(1);
},
manage() {
if(!this.isAdmin){
return ;
}
this.manageStatus = !this.manageStatus;
},
pickMedia(){
if(!this.isAdmin){
return ;
}
const _this = this;
uni.chooseImage({
success(res) {
//res.tempFilePaths[0]
//res.tempFiles[0].path
//res.tempFiles[0].size
let i = 0;
_this.fileList = res.tempFilePaths.map(path=>{
i++;
return {
"id": 'temp_'+i,
"group_id": 0,
"user_id": 0,
"url": path,
"title": path,
"progress": 0,
"status": 0,
};
});
_this.batchUpload();
}
});
// uni.chooseMedia({
// count: 9,
// mediaType: ['image'],
// sourceType: ['album', 'camera'],
// success(res) {
// console.log(res.tempFiles[0].tempFilePath)
// }
// })
},
async batchUpload(){
if(!this.isAdmin){
return ;
}
const _this = this;
const lists = [].concat(this.fileList);
for (let i = 0; i < lists.length; i++) {
const result = await upload(lists[i].url,{
savePath: "album" ,
url:"/group/album_create",
groupID:_this.param.groupID
},(res)=>{
_this.fileList[i].progress = res.progress;
});
_this.fileList.splice(i,1);
_this.list.unshift(result.data);
}
}
},
onPullDownRefresh() {
this.getList(true);
},
onReachBottom() {
this.getList();
}
}
</script>
<style lang="scss" scoped>
.group_album_page{
.footer{
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 44px;
background-color: #fff;
z-index: 10;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20rpx;
uni-button{
margin: 0;
}
}
.list{
display: flex;
align-items: center;
flex-wrap: wrap;
margin-top: 12rpx;
padding-right: 12rpx;
.item{
position: relative;
margin-bottom: 12rpx;
margin-left: 12rpx;
::v-deep .u-upload__button{
margin: 0;
}
&.cancheck::after{
content: " ";
font-family: uicon-iconfont;
position: relative;
display: flex;
flex-direction: row;
align-items: center;
width: 18px;
height: 18px;
font-size: 20px;
text-align: center;
background-color: rgb(255, 255, 255);
border-color: rgb(200, 201, 204);
border-style: solid;
border-width: 1px;
border-radius: 100%;
position: absolute;
bottom: 0;
left: 0;
}
&.cancheck.checked::after{
content: "";
background-color: rgb(41, 121, 255);
border-color: rgb(41, 121, 255);
color:#FFF;
}
.overlay{
background: rgba(0, 0, 0, 0.6);
position: absolute;
z-index: 9;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.u-line-progress{
position: absolute;
z-index: 10;
top:50%;
margin-top: -6px;
width: 80%;
left: 10%;
}
.pickfile{
display: flex;
align-items: center;
justify-content: center;
background-color: #f6f6f6;
width: 234rpx;
height: 234rpx;
}
}
}
}
</style>
+4 -1
View File
@@ -13,7 +13,7 @@
<my-avatar :src="storeCurrentConversation.faceURL" :isGroup="true" size="46" />
</template>
</uni-list-item>
<uni-list-item title="群名称" :rightText="storeCurrentConversation.showName" @click="editGroupName" :clickable="isOwner || isAdmin" :showArrow="isOwner || isAdmin"></uni-list-item>
<uni-list-item title="群名称" :rightText="storeCurrentConversation.showName" @click="editGroupName" :clickable="isOwner || isAdmin" :showArrow="isOwner || isAdmin"></uni-list-item>
<uni-list-item title="群公告" to="/pages/conversation/groupSettings/announcement" clickable showArrow></uni-list-item>
<uni-list-item title="群二维码" :to="getGroupQrcdeUrl" clickable showArrow></uni-list-item>
<uni-list-item v-if="isOwner || isAdmin" title="群管理" to="/pages/conversation/groupManage/index" clickable showArrow></uni-list-item>
@@ -21,6 +21,7 @@
</uni-list>
<u-gap></u-gap>
<uni-list>
<uni-list-item title="群相册" :to="'/pages/conversation/groupAlbum/groupAlbum?groupID='+storeCurrentConversation.groupID" showArrow></uni-list-item>
<uni-list-item title="查找聊天内容" :to="'/pages/common/search/index?type=conversation&conversationID='+storeCurrentConversation.conversationID" showArrow></uni-list-item>
</uni-list>
<u-gap></u-gap>
@@ -204,6 +205,8 @@
return this.storeCurrentGroup.status === GroupStatus.Muted;
},
},
onLoad() {
},
methods: {
editGroupName(){
if(this.isOwner || this.isAdmin){
@@ -6,7 +6,8 @@
<view class="content">
<view class="content-name" @tap="linkToBusinessCard(item.user_id)">{{ item.user.nickname || item.user.remark }}</view>
<view class="content-desc">
<u--text :lines="5" :text="item.body" />
<text class="u-line-5" selectable user-select>{{item.body}}</text>
<!-- <u-text :lines="5" :text="item.body" selectable /> -->
</view>
<!-- 图片,视频 -->
<view class="content-img" v-if="item.files!=null&&item.files.length>0">
@@ -19,7 +20,7 @@
<view slot="error"
class="u-flex u-row-left u-col-center"
style="font-size: 24rpx;width: 200rpx;height: 100rpx;margin-top: -50rpx;">
<u-icon name="photo" size="100" label="加载失败" label-pos="bottom"></u-icon>
<u-icon name="photo" size="100" label="加载失败" label-pos="bottom"></u-icon>
</view>
</u-image>
</view>
@@ -223,6 +224,9 @@
padding-top: 4rpx;
//line-height: 36rpx;
font-size: 32rpx;
uni-text{
}
}
&-img {
@@ -298,8 +302,8 @@
&-content {
word-break: break-all;
}
}
}
}
}
}
+11 -11
View File
@@ -42,18 +42,18 @@
<!-- 朋友圈列表 -->
<view class="content-circle">
<!-- storeCircleData是vuex变量不在本页面定义 -->
<template v-if="storeCircleData!=null&&storeCircleData.length>0">
<template v-for="(item, index) in storeCircleData" >
<CircleItem :key="index" :index="index" :item="item" @userEvent="onUserEvent"></CircleItem>
</template>
<!-- storeCircleData是vuex变量不在本页面定义 -->
<template v-if="storeCircleData!=null&&storeCircleData.length>0">
<template v-for="(item, index) in storeCircleData" >
<CircleItem :key="index" :index="index" :item="item" @userEvent="onUserEvent"></CircleItem>
</template>
<template v-else>
<view style="margin-top: 30%;">
<u-empty text="暂无动态,发一条试试吧~"></u-empty>
</view>
</template>
</view>
</template>
<template v-else>
<view style="margin-top: 30%;">
<u-empty text="暂无动态,发一条试试吧~"></u-empty>
</view>
</template>
</view>
<u-overlay :show="showInput" @click="showInput = false">
<view class="input-box" :style="{
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

+3
View File
@@ -20,6 +20,9 @@ module.exports = (vm) => {
token:uni.getStorageSync("BusinessToken"),
operationID: uuidV4(),
};
if(typeof config.data === 'object'){
config.data = JSON.stringify(config.data);
};
// 可以在此通过vm引用vuex中的变量,具体值在vm.$store.state中
return config;
},
+1 -1
View File
@@ -4,7 +4,7 @@
*/
module.exports = (vm) => {
uni.$u.http.interceptors.response.use((response) => {
if(vm.REQUEST_TRACE){
if(vm.REQUEST_TRACE || response.config?.data.trace){
console.log("\n-"
+"\n============================================================="
+"\nurl:"+response.config.fullPath