index.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <template>
  2. <ToolbarItemContainer
  3. :iconFile="imageToolbarForShow.icon"
  4. :title="imageToolbarForShow.title"
  5. :iconWidth="isUniFrameWork ? '32px' : '21px'"
  6. :iconHeight="isUniFrameWork ? '25px' : '18px'"
  7. :needDialog="false"
  8. @onIconClick="onIconClick"
  9. >
  10. <div
  11. v-if="!isUniFrameWork"
  12. :class="['image-upload', !isPC && 'image-upload-h5']"
  13. >
  14. <input
  15. ref="inputRef"
  16. title="图片"
  17. type="file"
  18. data-type="image"
  19. accept="image/gif,image/jpeg,image/jpg,image/png,image/bmp,image/webp"
  20. @change="sendImageInWeb"
  21. >
  22. </div>
  23. </ToolbarItemContainer>
  24. </template>
  25. <script lang="ts" setup>
  26. import {
  27. TUIChatService,
  28. TUIStore,
  29. StoreName,
  30. IConversationModel,
  31. SendMessageParams,
  32. } from '@tencentcloud/chat-uikit-engine';
  33. import { TUIGlobal } from '@tencentcloud/universal-api';
  34. import { ref, computed } from '../../../../adapter-vue';
  35. import { isPC, isWeChat, isUniFrameWork } from '../../../../utils/env';
  36. import ToolbarItemContainer from '../toolbar-item-container/index.vue';
  37. import imageIcon from '../../../../assets/icon/image.png';
  38. import imageUniIcon from '../../../../assets/icon/image-uni.png';
  39. import cameraUniIcon from '../../../../assets/icon/camera-uni.png';
  40. import { isEnabledMessageReadReceiptGlobal } from '../../utils/utils';
  41. const props = defineProps({
  42. // 图片源, 仅uniapp版本有效, web版本仅支持从相册中选择图片
  43. // album: 从相册中选择
  44. // camera: 使用相机拍摄
  45. imageSourceType: {
  46. type: String,
  47. default: 'album',
  48. },
  49. });
  50. const inputRef = ref();
  51. const currentConversation = ref<IConversationModel>();
  52. const IMAGE_TOOLBAR_SHOW_MAP = {
  53. web_album: {
  54. icon: imageIcon,
  55. title: '图片',
  56. },
  57. uni_album: {
  58. icon: imageUniIcon,
  59. title: '图片',
  60. },
  61. uni_camera: {
  62. icon: cameraUniIcon,
  63. title: '拍照',
  64. },
  65. };
  66. TUIStore.watch(StoreName.CONV, {
  67. currentConversation: (conversation: IConversationModel) => {
  68. currentConversation.value = conversation;
  69. },
  70. });
  71. const imageToolbarForShow = computed((): { icon: string; title: string } => {
  72. if (isUniFrameWork) {
  73. return props.imageSourceType === 'camera'
  74. ? IMAGE_TOOLBAR_SHOW_MAP['uni_camera']
  75. : IMAGE_TOOLBAR_SHOW_MAP['uni_album'];
  76. } else {
  77. return IMAGE_TOOLBAR_SHOW_MAP['web_album'];
  78. }
  79. });
  80. const onIconClick = () => {
  81. // uniapp 环境 发送图片
  82. if (isUniFrameWork) {
  83. // 增加 TUIGlobal.chooseMedia 条件限制,防御 uni 打包其他平台小程序时由于打包问题导致 isWeChat 为 true 出现运行时报错
  84. if (isWeChat && TUIGlobal?.chooseMedia) {
  85. // 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替
  86. TUIGlobal?.chooseMedia({
  87. count: 1,
  88. mediaType: ['image'], // 图片
  89. sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
  90. sourceType: [props.imageSourceType], // 从相册选择或使用相机拍摄
  91. success: function (res: any) {
  92. sendImageMessage(res);
  93. },
  94. });
  95. } else {
  96. // uniapp h5/app 发送图片
  97. TUIGlobal?.chooseImage({
  98. count: 1,
  99. sourceType: [props.imageSourceType], // 从相册选择或使用相机拍摄
  100. success: function (res) {
  101. sendImageMessage(res);
  102. },
  103. });
  104. }
  105. } else {
  106. if (inputRef.value?.click) {
  107. inputRef.value.click();
  108. }
  109. }
  110. };
  111. const sendImageInWeb = (e: any) => {
  112. if (e?.target?.files?.length <= 0) {
  113. return;
  114. }
  115. sendImageMessage(e?.target);
  116. e.target.value = '';
  117. };
  118. const sendImageMessage = (files: any) => {
  119. if (!files) {
  120. return;
  121. }
  122. const options = {
  123. to:
  124. currentConversation?.value?.groupProfile?.groupID
  125. || currentConversation?.value?.userProfile?.userID,
  126. conversationType: currentConversation?.value?.type,
  127. payload: {
  128. file: files,
  129. },
  130. needReadReceipt: isEnabledMessageReadReceiptGlobal(),
  131. } as SendMessageParams;
  132. // todo: 需要处理uniapp文件没有宽高的变形问题,需要linda看看
  133. TUIChatService.sendImageMessage(options);
  134. };
  135. </script>
  136. <style lang="scss" scoped>
  137. @import "../../../../assets/styles/common";
  138. </style>