SOURCE

import React, { useEffect, useState } from 'react'
import style from './index.module.less'
import './index.less'
import { ConversationItem, GroupMemberItem } from '@/utils/lib/types/entity'
import { useAppDispatch, useAppSelector } from '@/api/hooks'
import { shallowEqual } from 'react-redux'
import { buttonClick, loadMsg, onChange } from '@/utils/types/function'
import MemberPer from '@/pages/Conversation/components/MemberPer'
import XimSvg from '@/components/svg'
import SwitchBut from '@/components/buttons/SwitchBut'
import RightArrowBut from '@/components/buttons/RightArrowBut'
import { Badge, Button, Drawer, Input, message, Modal, QRCode, Upload } from 'antd'
import { ArrowLeftOutlined, CloseOutlined, ExclamationCircleFilled, ExclamationCircleOutlined, LeftOutlined } from '@ant-design/icons'
import { OpenIM } from '@/api/im'
import {
  GetGroupMemberParams,
  GroupBaseInfo,
  InviteGroupParams,
  MemberNameParams,
  PinCveParams
} from '@/utils/lib/types/params'
import { contactsAsyncActions, cveActions, cveAsyncActions, userAsyncActions } from '@/store/actions'
import RightArrowEdit from '@/components/buttons/RightArrowEdit'
import CreateGroup from '@/components/CreateGroup'
import { getUploadProps } from '@/utils/upload/uploadAvatar'
import upload from '@/utils/upload'
import groupApi from '@/api/modules/group.api'
import store from '@/store'
import { OpenIMMember } from '@/utils/types/custom'
import { getAssets } from '@/utils/assests'
import DisabledChat from '@/components/DisabledChat'

const { confirm } = Modal
const { TextArea } = Input

/**
 * 上传群头像
 */

const uploadProps = getUploadProps((file) => {
  const group_id = store.getState().cve.currentCve?.groupID
  if (!group_id) return
  upload(file)
    .then((res) => {
      const d = {
        // 群ID  number
        group_id: parseInt(group_id),
        face_url: res.uuid
      }
      groupApi.editProfile(d).then((res) => {
        message.success('修改群头像成功')
        //重新加载群头像
        store.dispatch(cveAsyncActions.getCveList())
        // dispatch(cveActions.setCurrentCve({}))
      })
    })
    .catch((e) => {
      console.log(e)
      message.error('上传图片失败!')
    })
})

/**
 * 群设置
 * @constructor
 */
const GroupSetting = (props: {
  open: boolean
  loadMsg?: loadMsg
  onClose: buttonClick
  onChange?: onChange
  memberList: OpenIMMember[],
}) => {
  const { loadMsg, open, onClose, onChange, memberList } = props
  const dispatch = useAppDispatch()
  const curCve = useAppSelector((state) => state.cve.currentCve, shallowEqual)
  // const userId = useAppSelector((state) => state.user.userID, shallowEqual)
  // 数字userID从localStorage中取
  const userId = localStorage.getItem('im_user_id')
  const [group, setGroup] = useState<{
    face_url: string // 群头像
    group_name: string // 群名称
    code: string // 群ID
    member_count: number // 群人数
    notification: string // 群公告
    creator_user_id: number //创建者
    group_type: number //群类型
    owner_user_id: number //群主
    is_real: boolean //是否需要实名认证才能加群
  }>()
  useEffect(() => {
    if (open) {
      getGroupInfo(curCve)
      getGroupMembersInfo(curCve)
    }
  }, [open])
  const [qrShow, setQrShow] = useState(false)
  // 公告
  const [showNot, setShowNot] = useState(false)
  // 申请加群
  const [showApplyInfo, setShowApplyInfo] = useState(false)
  // 全员禁言
  const [allPersonDisabledChat, setAllPersonDisabledChat] = useState(false)
  const [isGroupCrator, setIsGroupCrator] = useState(false)
  // 禁言
  const [disabledPersonChat, setDisabledPersonChat] = useState(false)
  const [notValue, setNotValue] = useState('')
  const [myNickname, setMyNickname] = useState('')
  const [createOpen, setCreateOpen] = useState(false)
  const [applyGroupList, setApplyGroupList] = useState([])

  /**
   * 获取申请加群的用户列表
   */
  useEffect(() => {
    OpenIM.getRecvGroupApplicationList().then(({data}) => {
      const list = [{
        id: '1',
        showName: 'koa'
      }, {
        id: '2',
        showName: 'koa2'
      }] // data && JSON.parse(data as string)
      setApplyGroupList(list as any)
    }).catch(err => {
      setApplyGroupList([])
      throw Error(err)
    })
  }, [])
  
  /**
   * 获取群信息
   * @param curCve
   */
  const getGroupInfo = (curCve?: ConversationItem | null) => {
    if (curCve?.groupID) {
      groupApi
        .profile({ group_id: Number(curCve.groupID) })
        .then((data) => {
          if (data) {
            setGroup(data)
            console.log(data, '群信息------------------')
          } else {
            message.error('获取群信息失败')
          }
        })
        .catch((err) => {
          console.log('获取成员失败')
        })
    }
  }
  /**
   * 获取个人呢在群中的信息
   * @param curCve
   */
  const getGroupMembersInfo = (curCve?: ConversationItem | null) => {
    if (userId && curCve?.groupID) {
      const options: Omit<InviteGroupParams, 'reason'> = {
        groupID: curCve.groupID,
        userIDList: [userId]
      }
      OpenIM.getGroupMembersInfo(options)
        .then(({ data }) => {
          const members = JSON.parse(data)
          if (members && members.length > 0) {
            setMyNickname(members[0].nickname)
          } else {
            setMyNickname('')
          }
        })
        .catch((err) => {
          console.log('获取好友信息失败')
        })
    }
  }
  /**
   * 删除聊天记录
   */
  const deleteHistoryMessage = () => {
    confirm({
      title: '是否删除所有聊天记录?',
      icon: <ExclamationCircleOutlined />,
      okText: '删除',
      cancelText: '取消',
      okButtonProps: { danger: true },
      onOk() {
        if (curCve?.groupID) {
          OpenIM.clearGroupHistoryMessageFromLocalAndSvr(curCve?.groupID)
            .then(({ data }) => {
              console.log('删除成功')
              onClose()
              if (loadMsg) {
                loadMsg()
              }
            })
            .catch((err) => {
              console.log('删除失败')
            })
        }
      },
      onCancel() {
        console.log('Cancel')
      }
    })
  }
  /**
   * 置顶会话
   */
  const pinCvn = (value: boolean) => {
    if (curCve?.conversationID) {
      const options: PinCveParams = {
        conversationID: curCve.conversationID,
        isPinned: value
      }
      OpenIM.pinConversation(options)
        .then((res) => {
          const newCve = { ...curCve }
          newCve.isPinned = value
          dispatch(cveActions.setCurrentCve(newCve))
        })
        .catch((err) => {
          console.log('置顶错误', err)
        })
    }
  }
  /**
   * 删除群
   */
  const deleteGroup = () => {
    confirm({
      title: '是否退出该群聊?',
      icon: <ExclamationCircleOutlined />,
      okText: '退出',
      cancelText: '取消',
      okButtonProps: { danger: true },
      onOk() {
        if (curCve?.groupID) {
          if (getIsOwner()) {
            //群主并且解散群
            groupApi
              .dismissMember({ group_id: Number(curCve.groupID) })
              .then(() => {
                delCvn()
                dispatch(contactsAsyncActions.getJoinedGroupData())
                console.log('解散群成功')
              })
              .catch((err) => {
                console.log('解散群失败', err)
              })
          } else {
            groupApi
              .quitGroup({ group_id: Number(curCve.groupID) })
              .then((res) => {
                delCvn()
              })
              .catch((err) => {
                console.log('删除好友出错')
              })
          }
        }
      },
      onCancel() {
        console.log('Cancel')
      }
    })
  }
  /**
   * 删除会话
   */
  const delCvn = () => {
    onClose()
    if (curCve?.conversationID) {
      OpenIM.deleteConversationFromLocalAndSvr(curCve.conversationID)
        .then(({ data }) => {
          console.log('删除会话成功')
          //重新加载会话列表
          dispatch(cveAsyncActions.getCveList())
          //重新加载会话列表
          dispatch(cveActions.setCurrentCve({}))
        })
        .catch((err) => {
          console.log('删除会话失败')
        })
    }
  }
  /**
   * 发布群公告
   */
  const updateGroupNot = () => {
    if (!notValue) {
      message.warning('公告内容不能为空')
    }
    if (group && curCve?.groupID) {
      groupApi
        .editProfile({
          group_id: Number(curCve.groupID),
          group_name: group.group_name,
          notification: notValue,
          face_url: group.face_url
        })
        .then((data) => {
          message.success('发布公告成功')
          setShowNot(false)
        })
      updateGroup({ notification: notValue })
    }
  }

  /**
   * 设置认证群
   * @param v
   */
  const setReal = (v: boolean) => {
    if (userId && parseInt(userId) !== group?.creator_user_id) {
      message.info('只有群主才能设置群实名状态')
      return
    }
    Modal.confirm({
      title: `确认要将该群设置为${v ? '实名群' : '普通群'}吗?`,
      icon: <ExclamationCircleFilled />,
      onOk() {
        if (group && curCve?.groupID) {
          groupApi
            .editProfile({
              group_id: parseInt(curCve.groupID),
              is_real: v
            })
            .then((res) => {
              setGroup({ ...group, is_real: v })
            })
        }
      }
    })
  }
  /**
   * 修改群昵称
   */
  const updateGroupName = (value?: string) => {
    if (!value) {
      return true
    }
    if (group && curCve?.groupID) {
      groupApi
        .editProfile({
          group_id: Number(curCve.groupID),
          group_name: value,
          notification: group.notification,
          face_url: group.face_url
        })
        .then((data) => {
          console.log('群群名称修改成功')
          if (onChange) {
            onChange({ type: 'name', val: value })
          }
          getGroupInfo(curCve)
        })
      updateGroup({ groupName: value })
    }
  }
  /**
   * 更新群资料
   * @param groupName
   * @param introduction
   * @param notification
   * @param faceURL
   */
  const updateGroup = (opt: { groupName?: string; introduction?: string; notification?: string; faceURL?: string }) => {
    //群资料
    const groupInfo: any = {
      groupName: opt.groupName ? opt.groupName : group?.group_name,
      introduction: opt.introduction ? opt.introduction : '',
      notification: opt.notification ? opt.notification : group?.notification,
      faceURL: opt.faceURL ? opt.faceURL : group?.face_url
    }
    const options: any = {
      groupID: curCve?.groupID,
      groupInfo
    }
    OpenIM.setGroupInfo(options).then(({ data }) => {
      console.log('修改失败')
    })
  }
  /**
   * 设置群成员的昵称
   */
  const updateMemberNickname = (value?: string) => {
    console.log(value)
    if (!value) {
      return true
    }
    if (group && curCve?.groupID) {
      groupApi
        .editMemberNickname({
          group_id: Number(curCve.groupID),
          nickname: value
        })
        .then((data) => {
          console.log('群昵称修改成功')
        })
      //更新名称
      const options: MemberNameParams = {
        groupID: curCve?.groupID,
        userID: userId ?? '',
        GroupMemberNickname: value
      }
      OpenIM.setGroupMemberNickname(options).then(({ data }) => {
        console.log('修改成功')
      })
    }
  }
  /**
   * 是否群管理
   */
  const getIsOwner = (): boolean => {
    if (group?.owner_user_id && userId && group.owner_user_id === Number(userId)) {
      return true
    }
    return false
  }
  /**
   * 全员禁言/取消禁言(只有群主能操作)
   */
  const setAllPersonChat = () => {
    const group_id = store.getState().cve.currentCve?.groupID
    // 禁言状态下
    if (allPersonDisabledChat) {
      groupApi.abledGroupChat({group_id: Number(group_id)}).then(res => {
        console.log(res)
        setAllPersonDisabledChat(false)
      })
    } else {
      // 非禁言状态下
      groupApi.disabledGroupChat({group_id: Number(group_id)}).then(res => {
        setAllPersonDisabledChat(true)
      })
    }
  }
  /**
   * 禁言
   */
  const showDisabledChat = () => {
    setDisabledPersonChat(!disabledPersonChat)
    return
    const options = {
      groupID: "",
      userID: "",
      mutedSeconds:0
    }
    OpenIM.changeGroupMemberMute(options).then(({ data })=>{
      console.log('已禁言')
    })
  }
  /**
   * 
   * @param user_id 
   * @param type 
   */
  const itemClick = (user_id: number, type: number) => {
    const group_id = store.getState().cve.currentCve && store.getState().cve.currentCve?.groupID
    console.log('-------', user_id, type, group_id)
    groupApi.dealAddGroupRequest({group_id: Number(group_id), user_id, handle_result: type})
  }
  /**
   * 显示隐藏进群申请Draw
   */
  const applyGroupInfo = () => {
    setShowApplyInfo(true)
  }

  return (
    <div className="setting-con">
      <div className="member-info">
        <div className="member-list">
          {memberList
            ? memberList.map((item, index) => {
                return <MemberPer nickName={item.nickname} faceURL={item.faceURL} key={index} userId={item.userID} />
              })
            : ''}
          <div
            className="add-but"
            onClick={() => {
              setCreateOpen(true)
            }}
          >
            <XimSvg name="add" />
          </div>
        </div>
        {/*<div className="more-member">*/}
        {/*  查看更多群成员*/}
        {/*  <XimSvg name="arrow" size={14} />*/}
        {/*</div>*/}
      </div>
      
      <div className="other-setting">
        <RightArrowEdit title="群聊名称" defValue={group?.group_name} isEdit={getIsOwner()} blur={updateGroupName} />
        <RightArrowBut text="群二维码" buttonClick={() => setQrShow(true)} />
        <RightArrowBut
          text="群公告"
          buttonClick={() => {
            setShowNot(true)
            setNotValue('')
          }}
        />
        {/*FIXME 这个功能有BUG 修改之后本人在群成员中会消失*/}
        <RightArrowEdit title="我在本群的昵称" defValue={myNickname} isEdit={true} blur={updateMemberNickname} />

        <div style={{ display: 'flex' }}>
          <Upload {...uploadProps} className={style.upload}>
            <RightArrowBut text="修改群头像" />
          </Upload>
        </div>

        <SwitchBut value={curCve?.isPinned} text="置顶聊天" switchClick={pinCvn} />
        <SwitchBut value={group?.is_real} text="实名群" switchClick={setReal} />
        {
          memberList.map(item => {
            if (item.userID === localStorage.getItem('im_user_id') && item.roleLevel === '3') {
                return <SwitchBut value={allPersonDisabledChat} text="全员禁言" switchClick={setAllPersonChat} />
            }
          })
        }
        
        <RightArrowBut text="清空聊天记录" rightTxt="聊天记录" buttonClick={deleteHistoryMessage} />
        <RightArrowBut text="禁言" buttonClick={showDisabledChat} />
        <RightArrowBut text="进群申请" buttonClick={applyGroupInfo} />
        
        <div className="delete-but">
          <Button type="primary" block onClick={deleteGroup}>
            {getIsOwner() ? '解散并退出群聊' : '退出群聊'}
          </Button>
        </div>
      </div>
      <Modal width={246} open={qrShow} footer={false} closable={false} onCancel={() => setQrShow(false)}>
        <QRCode value={`code=${group?.code},type=2`} size={200} />
      </Modal>
      {/**发布公告 */}
      <Drawer
        width={320}
        closable={false}
        onClose={() => setShowNot(false)}
        open={showNot}
        closeIcon={<ArrowLeftOutlined /> }
      >
        <div className="group-not-con">
          <div className="group-not-header">
            <LeftOutlined onClick={() => setShowNot(false)} />
          </div>
          <div className="group-not-body">
            <div className="not-input">
              <TextArea
                rows={6}
                placeholder="请输入群公告"
                maxLength={200}
                showCount
                bordered={false}
                value={notValue}
                onChange={(e) => setNotValue(e.target.value)}
              />
            </div>
            <div className="group-not-but">
              <Button type="primary" block onClick={updateGroupNot}>
                提交
              </Button>
            </div>
          </div>
        </div>
      </Drawer>
      {/**申请进群通知 */}
      <Drawer
        width={320}
        closable={false}
        onClose={() => setShowApplyInfo(false)}
        open={showApplyInfo}
      >
        <div className="group-not-con">
          <div className="group-not-header apply-group">
            <div className='group-no-header-left'>
              <LeftOutlined onClick={() => setShowApplyInfo(false)} />
              <span style={{ marginLeft: '5px'}}>进群申请</span>
            </div>
            <CloseOutlined onClick={() => setShowApplyInfo(false)} />
          </div>
          <div className="group-not-body">
            {
              applyGroupList.length && applyGroupList.map(item => {
                return (
                  <div
                    key={item.id}
                    className='cvn-item apply-item'
                  >
                    <div className='cvn-left'>
                      <div className="cvn-avatar">
                        <Badge>
                          <img
                                src={
                                  getAssets('img/def_avatar.png')
                                }
                            />
                        </Badge>
                      </div>
                    
                      <div className="title">
                        {item.showName}
                      </div>
                    </div>
                    <div>
                      <Button type="primary" size='small' onClick={() => itemClick(item.id, 1)}>
                        同意
                      </Button>
                      <Button style={{marginLeft: '8px'}} type="default" size='small' onClick={() => itemClick(item.id, 2)}>
                        拒绝
                      </Button>
                    </div>
                  </div>
                )
              })
            }
            
          </div>
        </div>
      </Drawer>
      {/**群成员禁烟 */}
      <DisabledChat
        isOpen={disabledPersonChat}
        groupId={curCve?.groupID}
        groupMember={memberList}
        invitation={true}
        onClose={() => {
          setDisabledPersonChat(false)
          onClose()
        }}
      />
      <CreateGroup
        isOpen={createOpen}
        groupId={curCve?.groupID}
        groupMember={memberList}
        invitation={true}
        onClose={() => {
          setCreateOpen(false)
          onClose()
        }}
      />
    </div>
  )
}

export default React.memo(GroupSetting)
console 命令行工具 X clear

                    
>
console