实现普通群创建和项目群创建;实现群头像修改功能;实现项目群和普通群的管理员设置、移除、查看

This commit is contained in:
wangyifeng 2025-01-22 16:37:28 +08:00
parent d516ce00ef
commit 489fb71be5
20 changed files with 646 additions and 262 deletions

View File

@ -1,79 +1,114 @@
<script setup>
import {ref,nextTick} from 'vue'
import WdPopup from "@/uni_modules/wot-design-uni/components/wd-popup/wd-popup.vue";
import TmButton from "@/uni_modules/tmui/components/tm-button/tm-button.vue";
import {language} from "@/uni_modules/tmui/tool/lib/language"
const confirmState=ref(false)
const cancel=ref(true)
let onConfirm=null
let onCancel=null
const confirm=ref(true)
const contentText=ref('')
const imageRef=ref('')
const confirmLabel=ref('确定')
const cancelLabel=ref('取消')
const confirmC=ref('#46299D')
const cancelC=ref('#1A1A1A')
const sendCancel=()=>{
confirmState.value=false
if (typeof onCancel==='function'){
import { ref, nextTick } from 'vue'
import WdPopup from '@/uni_modules/wot-design-uni/components/wd-popup/wd-popup.vue'
import TmButton from '@/uni_modules/tmui/components/tm-button/tm-button.vue'
import { language } from '@/uni_modules/tmui/tool/lib/language'
const confirmState = ref(false)
const cancel = ref(true)
let onConfirm = null
let onCancel = null
const confirm = ref(true)
const contentText = ref('')
const subContentText = ref('')
const subContentC = ref('#000')
const imageRef = ref('')
const confirmLabel = ref('确定')
const cancelLabel = ref('取消')
const confirmC = ref('#46299D')
const cancelC = ref('#1A1A1A')
const sendCancel = () => {
confirmState.value = false
if (typeof onCancel === 'function') {
onCancel()
}
}
const sendConfirm=()=>{
confirmState.value=false
if (typeof onConfirm==='function'){
const sendConfirm = () => {
confirmState.value = false
if (typeof onConfirm === 'function') {
onConfirm()
}
}
const showConfirm=({content,image,onConfirm:confirm,onCancel:cancel,confirmText,cancelText,confirmColor,cancelColor})=>{
confirmState.value=true
contentText.value=content
imageRef.value = image?image:''
onConfirm=confirm
onCancel=cancel
const showConfirm = ({
content,
image,
onConfirm: confirm,
onCancel: cancel,
confirmText,
cancelText,
confirmColor,
cancelColor,
subContent,
subContentColor,
}) => {
confirmState.value = true
contentText.value = content
imageRef.value = image ? image : ''
onConfirm = confirm
onCancel = cancel
confirmLabel.value = confirmText || confirmLabel.value
cancelLabel.value = cancelText || cancelLabel.value
confirmC.value = confirmColor || confirmC.value
cancelC.value = cancelColor || cancelC.value
subContentText.value = subContent || subContentText.value
subContentC.value = subContentColor || subContentC.value
}
defineExpose({
showConfirm
showConfirm,
})
</script>
<template>
<wd-popup custom-style="border-radius: 16rpx;" modal-style="background-color: #000000;opacity: 0.6;" v-model="confirmState">
<wd-popup
custom-style="border-radius: 16rpx;"
modal-style="background-color: #000000;opacity: 0.6;"
v-model="confirmState"
>
<div class="flex flex-col w-[640rpx]">
<div v-if="imageRef===''" class="flex justify-center items-center h-[288rpx] text-[32rpx] font-bold text-[#1A1A1A]">
{{contentText}}
<div
v-if="imageRef === ''"
class="flex flex-col justify-center items-center h-[288rpx] text-[#1A1A1A] popup-content"
>
<span class="text-[32rpx] font-bold">{{ contentText }}</span>
<span
class="text-[28rpx] font-regular"
v-if="subContentText"
:style="{ color: subContentC }"
>
{{ subContentText }}
</span>
</div>
<div v-else class="flex flex-col items-center h-[456rpx] text-[32rpx] font-bold text-[#1A1A1A]" >
<div class="wrap1 mt-[32rpx] mb-[44rpx]" >
<img :src="imageRef" alt="">
<div
v-else
class="flex flex-col items-center h-[456rpx] text-[32rpx] font-bold text-[#1A1A1A]"
>
<div class="wrap1 mt-[32rpx] mb-[44rpx]">
<img :src="imageRef" alt="" />
</div>
<div class="mb-[56rpx]" > {{contentText}} </div>
<div class="mb-[56rpx]">{{ contentText }}</div>
</div>
<div class="flex flex-grow border-t-solid border-[#E7E7E7] border-1rpx text-[32rpx]">
<div
class="flex flex-grow border-t-solid border-[#E7E7E7] border-1rpx text-[32rpx]"
>
<div class="flex justify-center items-center text-[#1A1A1A]">
<tm-button
@click="sendCancel"
:width="319"
@touchstart="cancel=false"
@touchend="cancel=true"
@touchstart="cancel = false"
@touchend="cancel = true"
:fontSize="32"
:height="112"
:margin="[0]"
:font-color="cancelC"
:transprent="cancel"
text
:label="cancelLabel"></tm-button>
:label="cancelLabel"
></tm-button>
</div>
<div class="h-[112rpx] w-[1rpx] bg-[#E7E7E7]"></div>
<div class="flex justify-center items-center text-[#CF3050]">
<tm-button
@click="sendConfirm"
@touchstart="confirm=false"
@touchend="confirm=true"
@touchstart="confirm = false"
@touchend="confirm = true"
:width="319"
:fontSize="32"
:transprent="confirm"
@ -81,17 +116,23 @@ defineExpose({
:margin="[0]"
:font-color="confirmC"
text
:label="confirmLabel"></tm-button>
:label="confirmLabel"
></tm-button>
</div>
</div>
</div>
</wd-popup>
</template>
<style scoped lang="scss">
.popup-content {
span {
line-height: 44rpx;
}
}
.wrap1 {
img {
width: 381.59rpx;
height: 280.14rpx;
}
}
img {
width: 381.59rpx;
height: 280.14rpx;
}
}
</style>

View File

@ -43,7 +43,11 @@
</div>
</div>
</div>
<div class="group-member-list-each">
<div
class="group-member-list-each"
@click="groupAddMembers"
v-if="props?.groupType == 1 || props?.groupType == 3"
>
<div class="group-member-each">
<div class="group-member-avatar" :style="{ background: 'unset' }">
<img src="/src/static/image/chatSettings/add-member.png" />
@ -53,7 +57,12 @@
</div>
</div>
</div>
<div class="group-member-list-each" v-if="props?.is_manager">
<div
class="group-member-list-each"
v-if="
props?.is_manager && (props?.groupType == 1 || props?.groupType == 3)
"
>
<div class="group-member-each">
<div class="group-member-avatar" :style="{ background: 'unset' }">
<img src="/src/static/image/chatSettings/remove-member.png" />
@ -71,6 +80,7 @@ const props = defineProps({
memberList: Array, //
memberListsLimit: Number, //
is_manager: Boolean, //
groupType: Number, //
})
//
@ -81,6 +91,9 @@ const toUserDetailPage = (userItem) => {
'/pages/dialog/dialogDetail/userDetail?erpUserId=' + userItem.erp_user_id,
})
}
//
const groupAddMembers = () => {}
</script>
<style scoped lang="scss">
.group-member-list {

View File

@ -16,23 +16,56 @@
<img :src="state.groupAvatar" />
</div>
</div>
<customBtn :btnText="$t('button.text.edit')"></customBtn>
<customBtn
:btnText="$t('button.text.edit')"
@click="editAvatar"
></customBtn>
</ZPaging>
</div>
</div>
</template>
<script setup>
import customBtn from '@/components/custom-btn/custom-btn.vue'
import { ServeEditGroup } from '@/api/group/index.js'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import { onLoad } from '@dcloudio/uni-app'
import { reactive } from 'vue'
import { reactive, computed, watch } from 'vue'
import { useGroupStore, useDialogueStore, useDialogueListStore } from '@/store'
import { uploadImg } from '@/api/chat'
import { uniqueId } from '@/utils'
const groupStore = useGroupStore()
const groupParams = reactive({
groupInfo: computed(() => groupStore.groupInfo),
})
const dialogueStore = useDialogueStore()
const dialogueParams = reactive({
receiver_id: computed(() => dialogueStore.talk.receiver_id),
})
const state = reactive({
pageTitle: '', //
groupAvatar: '', //
groupName: '', //
})
watch(
() => groupParams.groupInfo,
(newGroupInfo) => {
state.groupAvatar = newGroupInfo.avatar
},
{ deep: true },
)
const onProgressFn = (progress, id) => {
console.log((progress.loaded / progress.total) * 100, 'progress')
useDialogueListStore().updateUploadProgress(
id,
(progress.loaded / progress.total) * 100,
)
}
onLoad((options) => {
console.log(options)
if (options.groupAvatar) {
@ -40,14 +73,55 @@ onLoad((options) => {
}
})
//
const clearGroupNameInput = () => {
state.groupName = ''
}
//
const confirmEdit = () => {
console.log(state.groupName)
//
const editAvatar = () => {
uni.chooseImage({
sourceType: ['album'],
count: 1,
success: async (res) => {
console.log(res, 'res')
res.tempFiles.forEach(async (file) => {
console.log(file)
let image = new Image()
image.src = URL.createObjectURL(file)
image.onload = () => {
const form = new FormData()
form.append('file', file)
form.append('source', 'fonchain-chat')
form.append('urlParam', `width=${image.width}&height=${image.height}`)
let randomId = uniqueId()
uploadImg(form, (e) => onProgressFn(e, randomId)).then(
({ status, data, msg }) => {
console.log(status, data, msg)
if (status == 0) {
let avatar = data.ori_url
let params = {
group_id: dialogueParams.receiver_id,
group_name: groupParams.groupInfo.group_name,
avatar: avatar,
}
console.log(params)
const resp = ServeEditGroup(params)
resp.then(({ code }) => {
if (code == 200) {
groupStore.updateGroupInfo({
avatar: data.ori_url,
})
// uni.navigateBack({
// delta: 1,
// })
} else {
}
})
resp.catch(() => {})
} else {
}
},
)
}
})
},
})
}
</script>
<style scoped lang="scss">
@ -56,7 +130,7 @@ const confirmEdit = () => {
background-image: url('@/static/image/mine/background.png');
background-size: cover;
background-repeat: no-repeat;
background-position:center bottom;
background-position: center bottom;
}
.edit-group-info {

View File

@ -91,6 +91,7 @@ const confirmEdit = () => {
let params = {
group_id: dialogueParams.receiver_id,
group_name: state.groupName,
avatar: groupParams.groupInfo.avatar,
}
console.log(params)
const resp = ServeEditGroup(params)
@ -125,7 +126,6 @@ const confirmEdit = () => {
.edit-group-info {
.group-avatar {
padding: 250rpx 0 88rpx;
border-radius: 50%;
display: flex;
flex-direction: row;
align-items: center;
@ -133,6 +133,7 @@ const confirmEdit = () => {
img {
width: 192rpx;
height: 192rpx;
border-radius: 50%;
}
}
.group-name {

View File

@ -23,10 +23,32 @@
>
<div
class="group-admin-list-each"
:style="{
padding:
groupParams?.groupInfo?.group_type == 1 ||
groupParams?.groupInfo?.group_type == 3
? '18rpx 26rpx 18rpx 14rpx'
: '',
}"
v-for="(item, index) in state?.groupAdminList"
:key="index"
>
<span>{{ item.deptPos }}</span>
<selectMemberItem
v-if="
groupParams?.groupInfo?.group_type == 1 ||
groupParams?.groupInfo?.group_type == 3
"
:groupType="groupParams.groupInfo.group_type"
:memberItem="item"
></selectMemberItem>
<span
v-if="
groupParams?.groupInfo?.group_type == 2 ||
groupParams?.groupInfo?.group_type == 4
"
>
{{ item.deptPos }}
</span>
<div class="group-admin-list-each-btns">
<img
v-if="item.is_mine"
@ -62,11 +84,15 @@
</div>
</template>
<script setup>
import selectMemberItem from '../components/select-member-item.vue'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import { onLoad } from '@dcloudio/uni-app'
import { computed, onMounted, reactive, watch } from 'vue'
import { ServeEditGroupAdmin } from '@/api/group/index.js'
import {
ServeEditGroupAdmin,
ServeGroupAssignAdmin,
} from '@/api/group/index.js'
import { useGroupStore, useDialogueStore } from '@/store'
import { useAuth } from '@/store/auth'
@ -90,7 +116,7 @@ const state = reactive({
})
watch(
() => groupParams?.groupInfo,
[() => groupParams?.groupInfo, , () => dialogueParams?.adminList],
(newGroupInfo) => {
getGroupAdminList()
},
@ -107,35 +133,53 @@ onMounted(async () => {
//
const getGroupAdminList = () => {
let myPositionsList = []
if (groupParams?.groupInfo?.groupAdminList?.length > 0) {
groupParams?.groupInfo?.groupAdminList.forEach((groupAdminItem) => {
if (userInfo?.value?.PositionUsers?.length > 0) {
userInfo?.value?.PositionUsers.forEach((item) => {
// console.log(item.DepartmentId + '-' + item.PositionID)
if (item.PositionID === groupAdminItem.position_id) {
myPositionsList.push(groupAdminItem)
}
})
}
})
}
if (
groupParams?.groupInfo?.groupAdminList?.length > 0 &&
myPositionsList?.length > 0
groupParams?.groupInfo?.group_type == 1 ||
groupParams?.groupInfo?.group_type == 3
) {
groupParams.groupInfo.groupAdminList.forEach((ele) => {
myPositionsList.forEach((item) => {
if (ele.deptPos === item.deptPos) {
if (dialogueParams?.adminList?.length > 0) {
dialogueParams?.adminList.forEach((item) => {
if (item?.erp_user_id == userInfo?.value?.ID) {
item.is_mine = true
if (myPositionsList?.length == 1) {
item.cannotRemove = true
}
item.cannotRemove = true
}
})
})
}
state.groupAdminList = dialogueParams?.adminList
} else if (
groupParams?.groupInfo?.group_type == 2 ||
groupParams?.groupInfo?.group_type == 4
) {
let myPositionsList = []
if (groupParams?.groupInfo?.groupAdminList?.length > 0) {
groupParams?.groupInfo?.groupAdminList.forEach((groupAdminItem) => {
if (userInfo?.value?.PositionUsers?.length > 0) {
userInfo?.value?.PositionUsers.forEach((item) => {
// console.log(item.DepartmentId + '-' + item.PositionID)
if (item.PositionID === groupAdminItem.position_id) {
myPositionsList.push(groupAdminItem)
}
})
}
})
}
if (
groupParams?.groupInfo?.groupAdminList?.length > 0 &&
myPositionsList?.length > 0
) {
groupParams.groupInfo.groupAdminList.forEach((ele) => {
myPositionsList.forEach((item) => {
if (ele.deptPos === item.deptPos) {
item.is_mine = true
if (myPositionsList?.length == 1) {
item.cannotRemove = true
}
}
})
})
}
state.groupAdminList = groupParams?.groupInfo?.groupAdminList
}
state.groupAdminList = groupParams?.groupInfo?.groupAdminList
}
//
@ -147,35 +191,59 @@ const toSelectMembersPage = () => {
//
const removeGroupAdmin = (adminItem) => {
let positionInfos = []
if (state?.groupAdminList?.length > 0) {
state?.groupAdminList.forEach((item) => {
if (
item.dept_id != adminItem.dept_id ||
item.position_id != adminItem.position_id
) {
positionInfos.push({
position_id: item.position_id,
position_name: item.deptPos,
})
}
})
if (
groupParams?.groupInfo?.group_type == 1 ||
groupParams?.groupInfo?.group_type == 3
) {
let params = {
source: 'app',
id: dialogueParams.receiverId,
deptInfos: groupParams.groupInfo.deptInfos,
positionInfos: positionInfos,
mode: 2, //12
group_id: dialogueParams.receiverId, //id
user_ids: String(adminItem.id),
}
console.log(params)
const resp = ServeEditGroupAdmin(params)
const resp = ServeGroupAssignAdmin(params)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
groupStore.ServeGroupDetail()
useDialogueStore().updateGroupMembers()
} else {
}
})
resp.catch(() => {})
} else if (
groupParams?.groupInfo?.group_type == 2 ||
groupParams?.groupInfo?.group_type == 4
) {
let positionInfos = []
if (state?.groupAdminList?.length > 0) {
state?.groupAdminList.forEach((item) => {
if (
item.dept_id != adminItem.dept_id ||
item.position_id != adminItem.position_id
) {
positionInfos.push({
position_id: item.position_id,
position_name: item.deptPos,
})
}
})
let params = {
source: 'app',
id: dialogueParams.receiverId,
deptInfos: groupParams.groupInfo.deptInfos,
positionInfos: positionInfos,
}
console.log(params)
const resp = ServeEditGroupAdmin(params)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
groupStore.ServeGroupDetail()
} else {
}
})
resp.catch(() => {})
}
}
}
</script>
@ -196,18 +264,23 @@ const removeGroupAdmin = (adminItem) => {
.group-admin-list {
.group-admin-list-each {
padding: 36rpx 0;
margin: 0 32rpx;
padding: 36rpx 26rpx 36rpx 14rpx;
margin: 0 18rpx;
border-bottom: 1px solid $theme-border-color;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
::v-deep .select-member-item {
padding: 0;
border-bottom: 0;
}
.group-admin-list-each-btns {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-shrink: 0;
img {
width: 52rpx;
height: 52rpx;

View File

@ -21,6 +21,8 @@
</template>
<div class="group-members-list">
<groupMemberList
:groupType="groupParams?.groupInfo?.group_type"
:is_manager="groupParams?.groupInfo?.is_manager"
:memberList="talkParams?.memberList"
></groupMemberList>
</div>
@ -33,13 +35,18 @@ import groupMemberList from '../components/groupMembersList.vue'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
import { ref, computed, reactive } from 'vue'
import { useDialogueStore } from '@/store'
import { useDialogueStore, useGroupStore } from '@/store'
const dialogueStore = useDialogueStore()
const talkParams = reactive({
memberList: computed(() => dialogueStore.members),
})
const groupStore = useGroupStore()
const groupParams = reactive({
groupInfo: computed(() => groupStore.groupInfo),
})
const zPaging = ref()
useZPaging(zPaging)
</script>

View File

@ -166,7 +166,11 @@ import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
import { computed, onMounted, reactive, ref, watch, nextTick } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { ServeGroupNoSpeak, ServeEditGroupAdmin } from '@/api/group/index.js'
import {
ServeGroupNoSpeak,
ServeEditGroupAdmin,
ServeGroupAssignAdmin,
} from '@/api/group/index.js'
import { useDialogueStore, useGroupStore, useGroupTypeStore } from '@/store'
const zPaging = ref()
@ -369,6 +373,25 @@ const confirmSilenceMember = () => {
resp.catch(() => {})
} else if (state.manageType === 'admin') {
if (
groupParams.groupInfo.group_type == 1 ||
groupParams.groupInfo.group_type == 3
) {
let params = {
mode: 1, //12
group_id: dialogueParams.receiverId, //id
user_ids: selectedUserIds,
}
console.log(params)
const resp = ServeGroupAssignAdmin(params)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
useDialogueStore().updateGroupMembers()
} else {
}
})
resp.catch(() => {})
} else if (
groupParams.groupInfo.group_type == 2 ||
groupParams.groupInfo.group_type == 4
) {

View File

@ -24,6 +24,7 @@
</span>
</div>
<div
v-if="groupParams?.groupInfo?.group_type !== 1"
class="base-info-tag"
:style="{
borderColor:
@ -62,9 +63,17 @@
@toManagePage="toManagePage"
></settingFormItem>
<groupMemberList
:groupType="groupParams?.groupInfo?.group_type"
:is_manager="groupParams?.groupInfo?.is_manager"
:memberList="dialogueParams?.memberList"
:memberListsLimit="groupParams?.groupInfo?.is_manager ? 13 : 14"
:memberListsLimit="
groupParams?.groupInfo?.group_type == 1 ||
groupParams?.groupInfo?.group_type == 3
? groupParams?.groupInfo?.is_manager
? 13
: 14
: 15
"
></groupMemberList>
</div>
</div>
@ -125,12 +134,16 @@
</div>
</div>
<div class="clear-chat-record-btn chat-settings-card">
<div class="clear-chat-record-btn-each">
<div
@click="showConfirmPrompt(1)"
class="clear-chat-record-btn-each"
>
<span class="text-[32rpx] font-regular">
{{ $t('chat.settings.clearChatRecord') }}
</span>
</div>
<div
@click="showConfirmPrompt(2)"
class="clear-chat-record-btn-each"
v-if="groupParams?.groupInfo?.is_manager"
>
@ -139,6 +152,7 @@
</span>
</div>
<div
@click="showConfirmPrompt(3)"
class="clear-chat-record-btn-each"
v-if="groupParams?.groupInfo?.is_manager"
>
@ -153,10 +167,11 @@
</div>
</template>
<script setup>
import zu4992 from '@/static/image/chatList/zu4992@2x.png'
import zu4991 from '@/static/image/chatList/zu4991@2x.png'
import zu4989 from '@/static/image/chatList/zu4989@2x.png'
import zu5296 from '@/static/image/chatList/zu5296@2x.png'
import useConfirm from '@/components/x-confirm/useConfirm.js'
import groupDepartment from '@/static/image/chatList/groupDepartment.png'
import groupProject from '@/static/image/chatList/groupProject.png'
import groupNormal from '@/static/image/chatList/groupNormal.png'
import groupCompany from '@/static/image/chatList/groupCompany.png'
import recordSearchTypeIcon_groupMember from '@/static/image/chatSettings/recordSearchTypeGroupMembers.png'
import recordSearchTypeIcon_date from '@/static/image/chatSettings/recordSearchTypeDate.png'
import recordSearchTypeIcon_imgAndVideo from '@/static/image/chatSettings/recordSearchTypeImgAndVideo.png'
@ -177,6 +192,7 @@ import { ServeTopTalkList, ServeSetNotDisturb } from '@/api/chat/index'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
import customInput from '@/components/custom-input/custom-input.vue'
const { showConfirm } = useConfirm()
const userStore = useUserStore()
const talkStore = useTalkStore()
const dialogueStore = useDialogueStore()
@ -310,22 +326,23 @@ const groupTypeMapping = {
defaultImg: 'textImg',
},
1: {
defaultImg: zu4992,
result_type: t('index.mine.normal'),
defaultImg: groupNormal,
},
2: {
result_type: t('index.mine.department'),
result_type_color: '#377EC6',
defaultImg: zu4989,
defaultImg: groupDepartment,
},
3: {
result_type: t('index.mine.project'),
result_type_color: '#C1681C',
defaultImg: zu4991,
defaultImg: groupProject,
},
4: {
result_type: t('index.type.company'),
result_type_color: '#7A58DE',
defaultImg: zu5296,
defaultImg: groupCompany,
},
}
@ -519,6 +536,35 @@ const changeSwitch = (switchStatus, label) => {
resp.catch(() => {})
}
//
const showConfirmPrompt = (flag) => {
let confirmContent = ''
let subContent = ''
let subContentColor = ''
if (flag === 1) {
confirmContent = t('ok') + t('chat.settings.clearChatRecord')
} else if (flag === 2) {
confirmContent = t('ok') + t('group.quit.btn')
subContent = t('groupManage.disband.hint')
subContentColor = '#CF3050'
} else if (flag === 3) {
confirmContent = t('ok') + t('group.quit.btn')
subContent = t('groupManage.quit.hint')
subContentColor = '#B4B4B4'
}
showConfirm({
subContent: subContent,
subContentColor: subContentColor,
confirmColor: '#CF3050',
content: confirmContent,
contentText: t('ok'),
confirmText: t('ok'),
cancelText: t('cancel'),
onConfirm: () => {},
onCancel: () => {},
})
}
</script>
<style scoped lang="scss">
.outer-layer {

View File

@ -1,29 +1,31 @@
<template>
<div class="outer-layer">
<div>
<tm-navbar :hideBack="false" hideHome title="发起群聊" :leftWidth="320">
</tm-navbar>
<tm-navbar
:hideBack="false"
hideHome
title="发起群聊"
:leftWidth="220"
></tm-navbar>
</div>
<div class="root">
<div class="w-full pl-[32rpx] pr-[32rpx] mb-[20rpx]" >
<div class="w-full mt-[60rpx] flex justify-center" >
<div v-if="groupActiveIndex === -1" class="avatar-placeholder">
</div>
<div class="w-full pl-[32rpx] pr-[32rpx] mb-[20rpx]">
<div class="w-full mt-[60rpx] flex justify-center">
<div v-if="groupActiveIndex === -1" class="avatar-placeholder"></div>
<div class="mb-[40rpx]" v-else>
<tm-image
:width="192"
:height="192"
:round="12"
:round="24"
:src="avatarImg"
></tm-image>
</div>
</div>
<div class="input-group flex items-center justify-between" >
<div class="input-group flex items-center justify-between">
<div class="input-item">
群名称
</div>
<div class="input-box" >
<div class="input-box">
<tm-input
v-model="groupName"
:followTheme="false"
@ -35,113 +37,159 @@
:height="40"
:transprent="true"
placeholder="请输入群名称1~20个字"
:padding="[0,0]"
:padding="[0, 0]"
align="right"
>
</tm-input>
></tm-input>
</div>
</div>
<div class="input-group w-full flex flex-col mt-[20rpx] leading-[40rpx]" >
<div class="flex items-center justify-between" >
<div
class="input-group w-full flex flex-col mt-[20rpx] leading-[40rpx]"
>
<div class="flex items-center justify-between">
<div class="input-item">
群类型
</div>
<div @click="chooseGroupType" class="left-box" >
<div class="text-[#B4B4B4] text-[28rpx] font-bold" >
<span v-if="groupActiveIndex ===-1">请选择群类型</span>
<span v-else-if="groupActiveIndex ===0">普通群</span>
<span v-else-if="groupActiveIndex ===1">部门群</span>
<span v-else-if="groupActiveIndex ===2">项目群</span>
<div @click="chooseGroupType" class="left-box">
<div class="text-[#B4B4B4] text-[28rpx] font-bold">
<span v-if="groupActiveIndex === -1">请选择群类型</span>
<span v-else-if="groupActiveIndex === 0">普通群</span>
<span v-else-if="groupActiveIndex === 1">部门群</span>
<span v-else-if="groupActiveIndex === 2">项目群</span>
</div>
<div class="ml-[32rpx]" >
<tm-icon :font-size="22" color="#747474" name="tmicon-angle-right"></tm-icon>
<div class="ml-[32rpx]">
<tm-icon
:font-size="22"
color="#747474"
name="tmicon-angle-right"
></tm-icon>
</div>
</div>
</div>
<div v-if="depCheckedKeys.length" class="mt-[32rpx]" >
<div v-if="depCheckedKeys.length" class="mt-[32rpx]">
<div
v-for="(item,index) in depCheckedKeys"
v-for="(item, index) in depCheckedKeys"
class="text-[#747474] text-[28rpx] leading-[40rpx] font-bold"
:class="[
index !==0 ? 'mt-[10rpx]':'',
depsNoExpanded&&index>4 ? 'hidden':''
index !== 0 ? 'mt-[10rpx]' : '',
depsNoExpanded && index > 4 ? 'hidden' : '',
]"
>
{{ item.name }}
</div>
<div class="text-[#46299D] text-[28rpx] mt-[20rpx] font-bold flex justify-center" >
<div v-if="depCheckedKeys.length>5" @click="depsNoExpanded = !depsNoExpanded" class="w-[100rpx]">
{{ depsNoExpanded? '展开':'收起' }}
<div
class="text-[#46299D] text-[28rpx] mt-[20rpx] font-bold flex justify-center"
>
<div
v-if="depCheckedKeys.length > 5"
@click="depsNoExpanded = !depsNoExpanded"
class="w-[100rpx]"
>
{{ depsNoExpanded ? '展开' : '收起' }}
</div>
</div>
</div>
</div>
<div v-if="groupActiveIndex===0" class="input-group w-full flex flex-col mt-[20rpx] leading-[40rpx]" >
<div class="flex items-center justify-between" >
<div
v-if="groupActiveIndex === 0 || groupActiveIndex === 2"
class="input-group w-full flex flex-col mt-[20rpx] leading-[40rpx]"
>
<div class="flex items-center justify-between">
<div class="input-item">
群成员
</div>
<div @click="chooseMembers" class="left-box" >
<div class="ml-[32rpx] flex items-center" >
<div v-if="!groupAdmins.length" class="text-[#B4B4B4] text-[28rpx] font-bold mr-[32rpx]">全部({{ 0 }})</div>
<tm-icon :font-size="22" color="#747474" name="tmicon-angle-right"></tm-icon>
<div @click="chooseMembers" class="left-box">
<div class="ml-[32rpx] flex items-center">
<div
v-if="!groupAdmins.length"
class="text-[#B4B4B4] text-[28rpx] font-bold mr-[32rpx]"
>
全部({{ 0 }})
</div>
<tm-icon
:font-size="22"
color="#747474"
name="tmicon-angle-right"
></tm-icon>
</div>
</div>
</div>
<div v-if="groupAdmins.length" class="mt-[32rpx]" >
<div v-if="groupAdmins.length" class="mt-[32rpx]">
<div
v-for="(item,index) in groupAdmins"
v-for="(item, index) in groupAdmins"
class="text-[#747474] text-[28rpx] leading-[40rpx] font-bold"
:class="[
index !==0 ? 'mt-[10rpx]':'',
depsNoExpanded&&index>4 ? 'hidden':''
index !== 0 ? 'mt-[10rpx]' : '',
depsNoExpanded && index > 4 ? 'hidden' : '',
]"
>
{{ item.name }}
</div>
<div class="text-[#46299D] text-[28rpx] mt-[20rpx] font-bold flex justify-center" >
<div v-if="groupAdmins.length>5" @click="depsNoExpanded = !depsNoExpanded" class="w-[100rpx]">
{{ depsNoExpanded? '展开':'收起' }}
<div
class="text-[#46299D] text-[28rpx] mt-[20rpx] font-bold flex justify-center"
>
<div
v-if="groupAdmins.length > 5"
@click="depsNoExpanded = !depsNoExpanded"
class="w-[100rpx]"
>
{{ depsNoExpanded ? '展开' : '收起' }}
</div>
</div>
</div>
</div>
<div v-if="groupActiveIndex===1" class="input-group w-full flex flex-col mt-[20rpx] leading-[40rpx]" >
<div class="flex items-center justify-between" >
<div
v-if="groupActiveIndex === 1"
class="input-group w-full flex flex-col mt-[20rpx] leading-[40rpx]"
>
<div class="flex items-center justify-between">
<div class="input-item">
群管理员
</div>
<div @click="chooseGroupAdmin" class="left-box" >
<div class="ml-[32rpx] flex items-center" >
<div v-if="!groupAdmins.length" class="text-[#B4B4B4] text-[28rpx] font-bold mr-[32rpx]">请选择群管理员</div>
<tm-icon :font-size="22" color="#747474" name="tmicon-angle-right"></tm-icon>
<div @click="chooseGroupAdmin" class="left-box">
<div class="ml-[32rpx] flex items-center">
<div
v-if="!groupAdmins.length"
class="text-[#B4B4B4] text-[28rpx] font-bold mr-[32rpx]"
>
请选择群管理员
</div>
<tm-icon
:font-size="22"
color="#747474"
name="tmicon-angle-right"
></tm-icon>
</div>
</div>
</div>
<div v-if="groupAdmins.length" class="mt-[32rpx]" >
<div v-if="groupAdmins.length" class="mt-[32rpx]">
<div
v-for="(item,index) in groupAdmins"
v-for="(item, index) in groupAdmins"
class="text-[#747474] text-[28rpx] leading-[40rpx] font-bold"
:class="[
index !==0 ? 'mt-[10rpx]':'',
depsNoExpanded&&index>4 ? 'hidden':''
index !== 0 ? 'mt-[10rpx]' : '',
depsNoExpanded && index > 4 ? 'hidden' : '',
]"
>
{{ item.name }}
</div>
<div class="text-[#46299D] text-[28rpx] mt-[20rpx] font-bold flex justify-center" >
<div v-if="groupAdmins.length>5" @click="depsNoExpanded = !depsNoExpanded" class="w-[100rpx]">
{{ depsNoExpanded? '展开':'收起' }}
<div
class="text-[#46299D] text-[28rpx] mt-[20rpx] font-bold flex justify-center"
>
<div
v-if="groupAdmins.length > 5"
@click="depsNoExpanded = !depsNoExpanded"
class="w-[100rpx]"
>
{{ depsNoExpanded ? '展开' : '收起' }}
</div>
</div>
</div>
</div>
</div>
<div class="h-[162rpx] flex justify-center bg-[#FFFFFF]">
<div class="mt-[14rpx] btnBox" >
<div class="mt-[14rpx] btnBox">
<tm-button
@click="handleConfirm"
color="#46299D"
@ -153,114 +201,169 @@
:height="76"
size="large"
label="发起群聊"
>
</tm-button>
></tm-button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, watch, computed } from "vue";
import { onShow, onLoad } from "@dcloudio/uni-app";
import { useChatList } from "@/store/chatList/index.js";
import { useAuth } from "@/store/auth";
import { useTalkStore, useUserStore } from "@/store";
import addCircle from "@/static/image/chatList/addCircle.png";
import cahtPopover from "@/static/image/chatList/cahtPopover.png";
import zu4992 from "@/static/image/chatList/zu4992@2x.png";
import zu4991 from "@/static/image/chatList/zu4991@2x.png";
import zu4989 from "@/static/image/chatList/zu4989@2x.png";
import { useGroupTypeStore } from "@/store/groupType";
import { ref, watch, computed } from 'vue'
import { onShow, onLoad } from '@dcloudio/uni-app'
import { useChatList } from '@/store/chatList/index.js'
import { useAuth } from '@/store/auth'
import { useTalkStore, useUserStore } from '@/store'
import addCircle from '@/static/image/chatList/addCircle.png'
import cahtPopover from '@/static/image/chatList/cahtPopover.png'
import groupDepartment from '@/static/image/chatList/groupDepartment.png'
import groupProject from '@/static/image/chatList/groupProject.png'
import groupNormal from '@/static/image/chatList/groupNormal.png'
import { ServeCreateGroup } from '@/api/group/index'
import { useGroupTypeStore } from '@/store/groupType'
const { groupName,groupActiveIndex,depCheckedKeys,groupAdmins,createDepGroup,resetGroupInfo } = useGroupTypeStore();
const talkStore = useTalkStore();
const userStore = useUserStore();
const { userInfo } = useAuth();
const {
groupName,
groupActiveIndex,
depCheckedKeys,
groupAdmins,
createDepGroup,
resetGroupInfo,
allChooseMembers,
} = useGroupTypeStore()
const talkStore = useTalkStore()
const userStore = useUserStore()
const { userInfo } = useAuth()
const groupChatType = ref('');
const depsNoExpanded = ref(true);
const groupChatType = ref('')
const depsNoExpanded = ref(true)
const avatarImg = computed(() => {
let srcT = "";
let srcT = ''
switch (groupActiveIndex.value) {
case 0:
srcT = zu4992;
break;
srcT = groupNormal
break
case 1:
srcT = zu4989;
break;
srcT = groupDepartment
break
case 2:
srcT = zu4991;
break;
srcT = groupProject
break
default:
srcT = zu4992;
srcT = groupNormal
}
return srcT;
return srcT
})
const chooseGroupType = () => {
uni.navigateTo({
url: '/pages/chooseGroupType/index'
url: '/pages/chooseGroupType/index',
})
}
const chooseGroupAdmin = () => {
uni.navigateTo({
url: '/pages/chooseGroupAdmin/index'
url: '/pages/chooseGroupAdmin/index',
})
}
const chooseMembers = () => {
uni.navigateTo({
url: '/pages/chooseMembers/index'
url: '/pages/chooseMembers/index',
})
}
const handleConfirm = async () => {
console.log(allChooseMembers.value)
let erp_ids = ''
if (allChooseMembers?.value?.length > 0) {
allChooseMembers?.value?.forEach((ele) => {
if (!erp_ids) {
erp_ids = ele.ID
} else {
erp_ids += ',' + ele.ID
}
})
}
if (groupActiveIndex.value === 0) {
}else if(groupActiveIndex.value === 1){
//
let params = {
avatar: '',
name: groupName.value,
erp_ids: erp_ids,
type: 1,
profile: '',
}
console.log(params)
const res = await ServeCreateGroup(params)
if (res.code === 200) {
resetGroupInfo()
uni.navigateBack()
}
} else if (groupActiveIndex.value === 1) {
//
const res = await createDepGroup()
if (res.code === 200) {
resetGroupInfo()
uni.navigateBack()
}
}else {
} else if (groupActiveIndex.value === 2) {
//
let params = {
avatar: '',
name: groupName.value,
erp_ids: erp_ids,
type: 3,
profile: '',
}
console.log(params)
const res = await ServeCreateGroup(params)
if (res.code === 200) {
resetGroupInfo()
uni.navigateBack()
}
} else {
}
}
const confirmBtnStatus = computed(() => {
let disabledT = false;
if (groupName.value === "" || !groupActiveIndex.value) {
return true;
let disabledT = false
console.log(groupActiveIndex.value !== -1)
if (
groupName.value === '' ||
(groupActiveIndex.value && groupActiveIndex.value === -1) ||
(!groupActiveIndex.value && groupActiveIndex.value !== 0)
) {
return true
}
switch (groupActiveIndex.value) {
case 0:
break;
if (allChooseMembers?.value?.length < 3) {
return true
}
break
case 1:
if (!depCheckedKeys.value.length) {
disabledT = true;
disabledT = true
}
if (!groupAdmins.value.length) {
disabledT = true;
disabledT = true
}
break;
break
case 2:
break;
if (allChooseMembers?.value?.length < 3) {
return true
}
break
default:
break;
break
}
return disabledT
})
onShow(() => {
depsNoExpanded.value = true;
depsNoExpanded.value = true
})
</script>
<style scoped lang="scss">
uni-page-body,
@ -270,7 +373,7 @@ page {
.outer-layer {
overflow-y: auto;
flex: 1;
background-image: url("@/static/image/clockIn/z3280@3x.png");
background-image: url('@/static/image/clockIn/z3280@3x.png');
background-size: cover;
padding-bottom: 0;
display: flex;
@ -282,9 +385,9 @@ page {
flex-direction: column;
justify-content: space-between;
}
.divider{
.divider {
height: 1rpx;
background-color: #7C7C7C;
background-color: #7c7c7c;
opacity: 0.6;
}
.avatar-placeholder {
@ -321,7 +424,7 @@ page {
align-items: center;
}
.btnBox {
:deep(uni-button[disabled="true"]) {
:deep(uni-button[disabled='true']) {
color: #bebebe !important;
}
}

View File

@ -77,10 +77,10 @@ import { beautifyTime } from "@/utils/datetime";
import { ServeClearTalkUnreadNum } from "@/api/chat";
import { useTalkStore, useDialogueStore } from "@/store";
import { useSessionMenu } from "@/hooks";
import zu4989 from "@/static/image/chatList/zu4989@2x.png";
import zu4991 from "@/static/image/chatList/zu4991@2x.png";
import zu4992 from "@/static/image/chatList/zu4992@2x.png";
import zu5296 from "@/static/image/chatList/zu5296@2x.png";
import groupDepartment from "@/static/image/chatList/groupDepartment.png";
import groupProject from "@/static/image/chatList/groupProject.png";
import groupNormal from "@/static/image/chatList/groupNormal.png";
import groupCompany from "@/static/image/chatList/groupCompany.png";
const talkStore = useTalkStore();
const { onToTopTalk } = useSessionMenu();
@ -105,16 +105,16 @@ const avatarCpt = computed(() => {
} else {
switch (props.data.group_type) {
case 1:
avatar = zu4992;
avatar = groupNormal;
break;
case 2:
avatar = zu4989;
avatar = groupDepartment;
break;
case 3:
avatar = zu4991;
avatar = groupProject;
break;
case 4:
avatar = zu5296;
avatar = groupCompany;
break;
}
}

View File

@ -75,10 +75,10 @@
</div>
</template>
<script setup>
import zu4992 from '@/static/image/chatList/zu4992@2x.png'
import zu4991 from '@/static/image/chatList/zu4991@2x.png'
import zu4989 from '@/static/image/chatList/zu4989@2x.png'
import zu5296 from '@/static/image/chatList/zu5296@2x.png'
import groupDepartment from '@/static/image/chatList/groupDepartment.png'
import groupProject from '@/static/image/chatList/groupProject.png'
import groupNormal from '@/static/image/chatList/groupNormal.png'
import groupCompany from '@/static/image/chatList/groupCompany.png'
import {
ref,
watch,
@ -198,22 +198,22 @@ const groupTypeMapping = {
defaultImg: 'textImg',
},
1: {
defaultImg: zu4992,
defaultImg: groupNormal,
},
2: {
result_type: t('index.mine.department'),
result_type_color: '#377EC6',
defaultImg: zu4989,
defaultImg: groupDepartment,
},
3: {
result_type: t('index.mine.project'),
result_type_color: '#C1681C',
defaultImg: zu4991,
defaultImg: groupProject,
},
4: {
result_type: t('index.type.company'),
result_type_color: '#7A58DE',
defaultImg: zu5296,
defaultImg: groupCompany,
},
}
//

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -131,5 +131,8 @@
"groupNotice.quit.edit": "退出本次编辑",
"groupNotice.continue.edit": "继续编辑",
"groupNotice.confirm.quit": "退出",
"chatSettings.btn.removeAdmin": "移除"
"chatSettings.btn.removeAdmin": "移除",
"groupManage.disband.hint": "退出后,本群将被解散",
"groupManage.quit.hint": "退出后,聊天记录将被清空",
"index.mine.normal": "普通"
}