更新小程序仓库
This commit is contained in:
parent
13f54a26df
commit
4506940c2d
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
# Dependency directories
|
||||
node_modules
|
||||
*.log*
|
||||
*.lock
|
||||
.eslintrc.js
|
||||
package-lock.json
|
||||
.history
|
||||
dist/
|
||||
h5/
|
||||
dist.zip
|
||||
wxAppPatient.zip
|
||||
374
TUIService/TUIKit/.github/README.md
vendored
Normal file
374
TUIService/TUIKit/.github/README.md
vendored
Normal file
@ -0,0 +1,374 @@
|
||||
## 关于腾讯云即时通信 IM
|
||||
|
||||
腾讯云即时通信(Instant Messaging,IM)基于 QQ 底层 IM 能力开发,仅需植入 SDK 即可轻松集成聊天、会话、群组、资料管理能力,帮助您实现文字、图片、短语音、短视频等富媒体消息收发,全面满足通信需要。
|
||||
|
||||
## 关于 chat-uikit-wechat
|
||||
|
||||
chat-uikit-wechat 是基于腾讯云 IM SDK 的一款 小程序 UI 组件库,它提供了一些通用的 UI 组件,包含会话、聊天、群组、音视频通话等功能。基于 UI 组件您可以像搭积木一样快速搭建起自己的业务逻辑。
|
||||
chat-uikit-wechat 中的组件在实现 UI 功能的同时,会调用 IM SDK 相应的接口实现 IM 相关逻辑和数据的处理,因而开发者在使用 chat-uikit-wechat 时只需关注自身业务或个性化扩展即可。
|
||||
chat-uikit-wechat 效果如下图所示:
|
||||
<img width="1015" src="https://user-images.githubusercontent.com/40623255/202661227-d4227dcc-bada-42a6-a57b-0d0c0abc098b.png"/>
|
||||
|
||||
本文介绍如何快速集成腾讯云 Web IM SDK 的 VUE UI 组件库。对于其他平台,请参考文档:
|
||||
|
||||
[**chat-uikit-vue**](https://github.com/TencentCloud/chat-uikit-vue)
|
||||
|
||||
[**chat-uikit-react**](https://github.com/TencentCloud/chat-uikit-react)
|
||||
|
||||
[**chat-uikit-uniapp**](https://github.com/TencentCloud/chat-uikit-uniapp)
|
||||
|
||||
[**chat-uikit-ios**](https://github.com/TencentCloud/chat-uikit-ios)
|
||||
|
||||
[**chat-uikit-android**](https://github.com/TencentCloud/chat-uikit-android)
|
||||
|
||||
[**chat-uikit-flutter**](https://github.com/TencentCloud/chat-uikit-flutter)
|
||||
|
||||
|
||||
|
||||
## 发送您的第一条消息
|
||||
|
||||
### 开发环境要求
|
||||
|
||||
- 微信开发者工具
|
||||
- JavaScript
|
||||
|
||||
|
||||
### TUIKit 源码集成 - github方式集成
|
||||
|
||||
#### 步骤1:创建项目
|
||||
|
||||
在微信开发者工具上创建一个小程序项目,选择不使用模版。
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/40623255/202665077-b4f01580-69f2-493c-9fab-4f4ef8e5021a.png"/>
|
||||
|
||||
#### 步骤2:下载 TUIKit 组件
|
||||
|
||||
在微信开发者工具内新建终端。
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/6735b8ead18ffa7c80f2e16cebbdc9d1.png"/>
|
||||
|
||||
通过 `git clone` 方式下载 TUIKit 组件及其相关依赖, 为了方便您的后续使用,建议您通过以下命令将整个 `chat-uikit-wechat` 复制到您项目的根目录下,并重命名为 TUIKit:
|
||||
|
||||
|
||||
```shell
|
||||
# 项目根目录命令行执行
|
||||
git clone https://github.com/TencentCloud/chat-uikit-wechat.git
|
||||
|
||||
|
||||
# 移动并重命名到项目的根目录下
|
||||
# macOS
|
||||
mv chat-uikit-wechat ./TUIKit
|
||||
# windows
|
||||
move chat-uikit-wechat .\TUIKit
|
||||
|
||||
```
|
||||
|
||||
成功后目录结构如图所示:
|
||||
<img width="300" src="https://qcloudimg.tencent-cloud.cn/raw/b2cf42ffef896731a170e138f4dd053f.png"/>
|
||||
|
||||
#### 步骤3:引入 TUIKit 组件
|
||||
|
||||
##### 方式一: 主包引入 (适用于业务逻辑简单的小程序)
|
||||
在 page 页面引用 TUIKit 组件,为此您需要分别修改 index.wxml 、index.js 和 index.json。
|
||||
|
||||
wxml 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/9816f2a2141357fbaced7e77929392f8.png"/>
|
||||
|
||||
```javascript
|
||||
<view>
|
||||
<TUIKit config="{{config}}" id="TUIKit"></TUIKit>
|
||||
</view>
|
||||
```
|
||||
|
||||
js 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/b9c02ec038b4b397f175591c7b5ef876.png"/>
|
||||
|
||||
```javascript
|
||||
import TIM from '../../TUIKit/lib/tim-wx-sdk';
|
||||
import { genTestUserSig } from '../../TUIKit/debug/GenerateTestUserSig';
|
||||
import TIMUploadPlugin from '../../TUIKit/lib/tim-upload-plugin';
|
||||
import TIMProfanityFilterPlugin from '../../TUIKit/lib/tim-profanity-filter-plugin';
|
||||
|
||||
|
||||
Page({
|
||||
data: {
|
||||
config: {
|
||||
userID: '', //User ID
|
||||
SDKAPPID: 0, // Your SDKAppID
|
||||
SECRETKEY: '', // Your secretKey
|
||||
EXPIRETIME: 604800,
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
const userSig = genTestUserSig(this.data.config).userSig
|
||||
wx.$TUIKit = TIM.create({
|
||||
SDKAppID: this.data.config.SDKAPPID
|
||||
})
|
||||
wx.$chat_SDKAppID = this.data.config.SDKAPPID;
|
||||
wx.$chat_userID = this.data.config.userID;
|
||||
wx.$chat_userSig = userSig;
|
||||
wx.$TUIKitTIM = TIM;
|
||||
wx.$TUIKit.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin });
|
||||
wx.$TUIKit.registerPlugin({ 'tim-profanity-filter-plugin': TIMProfanityFilterPlugin });
|
||||
wx.$TUIKit.login({
|
||||
userID: this.data.config.userID,
|
||||
userSig
|
||||
});
|
||||
wx.setStorage({
|
||||
key: 'currentUserID',
|
||||
data: [],
|
||||
});
|
||||
wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.SDK_READY, this.onSDKReady,this);
|
||||
},
|
||||
onUnload() {
|
||||
wx.$TUIKit.off(wx.$TUIKitTIM.EVENT.SDK_READY, this.onSDKReady,this);
|
||||
},
|
||||
onSDKReady() {
|
||||
const TUIKit = this.selectComponent('#TUIKit');
|
||||
TUIKit.init();
|
||||
}
|
||||
});
|
||||
```
|
||||
json 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/866e12c4bf19e08c71c233158cc19106.png"/>
|
||||
|
||||
```javascript
|
||||
{
|
||||
"usingComponents": {
|
||||
"TUIKit": "../../TUIKit/index"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
```
|
||||
|
||||
##### 方式二:分包引入 (适用于业务逻辑复杂,按需载入的小程序)
|
||||
小程序分包有如下好处:
|
||||
- 规避所有逻辑代码放主包,导致主包文件体积超限问题
|
||||
- 支持按需载入,降低小程序载入耗时和页面渲染耗时
|
||||
- 支持更加复杂的功能
|
||||
分包流程:
|
||||
1.在自己项目里创建分包,本文以 TUI-CustomerService 为例。和 pages 同级创建 TUI-CustomerService 文件夹,并在文件夹内部创建 pages 文件夹并且在其下创建 index 页面。
|
||||
创建后的目录结构:
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/bc1352da5ea30bb3a8134bedbc421a9b.png"/>
|
||||
|
||||
2.在 app.json 文件注册分包。
|
||||
|
||||
```javascript
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/index"
|
||||
],
|
||||
"subPackages": [
|
||||
{
|
||||
"root": "TUI-CustomerService",
|
||||
"name": "TUI-CustomerService",
|
||||
"pages": [
|
||||
"pages/index"
|
||||
],
|
||||
"independent": false
|
||||
}
|
||||
],
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#fff",
|
||||
"navigationBarTitleText": "Weixin",
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"style": "v2",
|
||||
"sitemapLocation": "sitemap.json"
|
||||
}
|
||||
```
|
||||
3.将 TUIKit 文件夹复制到分包目录下。
|
||||
成功后的目录结构:
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/5abd5dc90d2e5d53b3ed1a264e0398f8.png"/>
|
||||
|
||||
4.将 TUIKit 文件夹下的 debug 和 lib 文件夹复制到主包。
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/00a9557954be659dd32f00d45195daac.png"/>
|
||||
|
||||
5. 在分包内引用 TUIKit组件,为此需要分别修改分包内部 index.wxml 、index.js 、index.json 文件,以及 app.js 文件。
|
||||
|
||||
wxml 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/072f4f8f78d512f28ac8e82ed9925055.png"/>
|
||||
|
||||
```javascript
|
||||
<view>
|
||||
<TUIKit config="{{config}}" id="TUIKit"></TUIKit>
|
||||
</view>
|
||||
```
|
||||
|
||||
js 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/d36a0543c7fe94def0fc36042eddc28c.png"/>
|
||||
|
||||
```javascript
|
||||
Page({
|
||||
|
||||
// 其他代码
|
||||
|
||||
onLoad() {
|
||||
const TUIKit = this.selectComponent('#TUIKit');
|
||||
TUIKit.init();
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
json 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/4499096c37b9b29abffa21b71fb90e9e.png"/>
|
||||
|
||||
```javascript
|
||||
{
|
||||
"usingComponents": {
|
||||
"TUIKit": "../TUIKit/index"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
```
|
||||
app.js 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/170aa919af6db0e7b32ace5da9d417f1.png"/>
|
||||
|
||||
```javascript
|
||||
import TIM from './lib/tim-wx-sdk';
|
||||
import TIMUploadPlugin from './lib/tim-upload-plugin';
|
||||
import TIMProfanityFilterPlugin from './lib/tim-profanity-filter-plugin';
|
||||
import { genTestUserSig } from './debug/GenerateTestUserSig';
|
||||
App({
|
||||
onLaunch: function () {
|
||||
wx.$TUIKit = TIM.create({
|
||||
SDKAppID: this.globalData.config.SDKAPPID,
|
||||
});
|
||||
const userSig = genTestUserSig(this.globalData.config).userSig
|
||||
wx.$chat_SDKAppID = this.globalData.config.SDKAPPID;
|
||||
wx.$TUIKitTIM = TIM;
|
||||
wx.$chat_userID = this.globalData.config.userID;
|
||||
wx.$chat_userSig = userSig;
|
||||
wx.$TUIKit.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin });
|
||||
wx.$TUIKit.registerPlugin({ 'tim-profanity-filter-plugin': TIMProfanityFilterPlugin });
|
||||
wx.$TUIKit.login({
|
||||
userID: this.globalData.config.userID,
|
||||
userSig
|
||||
});
|
||||
// 监听系统级事件
|
||||
wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.SDK_READY, this.onSDKReady);
|
||||
},
|
||||
globalData: {
|
||||
config: {
|
||||
userID: '', //User ID
|
||||
SECRETKEY: '', // Your secretKey
|
||||
SDKAPPID: 0, // Your SDKAppID
|
||||
EXPIRETIME: 604800,
|
||||
},
|
||||
},
|
||||
onSDKReady() {
|
||||
},
|
||||
});
|
||||
```
|
||||
6. 按需载入分包,您需要修改主包 pages 下的 index.wxml 、index.js。
|
||||
|
||||
wxml 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/86f2698910c2e255727f419625441ed9.png"/>
|
||||
|
||||
```javascript
|
||||
<view class="container" bindtap="handleJump">
|
||||
载入腾讯云 IM 分包
|
||||
</view>
|
||||
```
|
||||
|
||||
js 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/5c41dff77345aa364bde46039f84ffd7.png"/>
|
||||
|
||||
```javascript
|
||||
Page({
|
||||
handleJump() {
|
||||
app.method.navigateTo({
|
||||
url: '../../TUI-CustomerService/pages/index',
|
||||
})
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### 步骤4: 获取 SDKAppID 、密钥与 userID
|
||||
|
||||
设置步骤3示例代码中的相关参数 SDKAPPID、SECRETKEY 以及 userID ,其中 SDKAppID 和密钥等信息,可通过 [即时通信 IM 控制台](https://console.cloud.tencent.com/im) 获取,单击目标应用卡片,进入应用的基础配置页面。例如:
|
||||
<img style="width:600px; max-width: inherit;" src="https://qcloudimg.tencent-cloud.cn/raw/44a331ce39f05f7080cf33ca9bc8e5dd.png"/>
|
||||
userID 信息,可通过 [即时通信 IM 控制台](https://console.cloud.tencent.com/im) 进行创建和获取,单击目标应用卡片,进入应用的账号管理页面,即可创建账号并获取 userID。例如:
|
||||
<img style="width:870px; max-width: inherit;" src="https://qcloudimg.tencent-cloud.cn/raw/94c801b7258612f8a4018728d862252f.png"/>
|
||||
|
||||
### 步骤5:编译小程序
|
||||
|
||||
- 请在本地设置里面勾选上“不校验合法域名、web-view (业务域名)、 TLS 版本以及 HTTPS 证书”。
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/e32530c238362d5bb597c1171f6646ff.png"/>
|
||||
|
||||
- 点击【清缓存】->【全部清除】,避免开发者工具的缓存造成渲染异常。
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/2c68432c6e3399df21517e521c356299.png"/>
|
||||
|
||||
- 点击【编译】。
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/b98aebdadf932e036e9900aea5651c1e.png"/>
|
||||
|
||||
### 步骤6:发送您的第一条消息
|
||||
<img style="width:1000" src="https://user-images.githubusercontent.com/40623255/202665415-ea50357f-4c86-4f18-bacb-e731a64d9a31.png" />
|
||||
<img style="width:1000" src="https://qcloudimg.tencent-cloud.cn/raw/02eb06fbc13cdf27664fe55eb2e10b49.png" />
|
||||
|
||||
### 常见问题
|
||||
#### 1. 什么是 UserSig?
|
||||
|
||||
UserSig 是用户登录即时通信 IM 的密码,其本质是对 UserID 等信息加密后得到的密文。
|
||||
|
||||
#### 2. 如何生成 UserSig?
|
||||
|
||||
UserSig 签发方式是将 UserSig 的计算代码集成到您的服务端,并提供面向项目的接口,在需要 UserSig 时由您的项目向业务服务器发起请求获取动态 UserSig。更多详情请参见 [服务端生成 UserSig](https://cloud.tencent.com/document/product/269/32688#GeneratingdynamicUserSig)。
|
||||
|
||||
> !
|
||||
>
|
||||
> 本文示例代码采用的获取 UserSig 的方案是在客户端代码中配置 SECRETKEY,该方法中 SECRETKEY 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量,因此**该方法仅适合本地跑通功能调试**。 正确的 UserSig 签发方式请参见上文。
|
||||
|
||||
### 3. 小程序如果需要上线或者部署正式环境怎么办?
|
||||
请在**微信公众平台**>**开发**>**开发管理**>**开发设置**>**服务器域名**中进行域名配置:
|
||||
|
||||
从v2.11.2起 SDK 支持了 WebSocket,WebSocket 版本须添加以下域名到 **socket 合法域名**:
|
||||
|
||||
| 域名 | 说明 | 是否必须 |
|
||||
|-------|---------|----|
|
||||
|`wss://wss.im.qcloud.com`| Web IM 业务域名 | 必须|
|
||||
|`wss://wss.tim.qq.com`| Web IM 业务域名 | 必须|
|
||||
|
||||
将以下域名添加到 **request 合法域名**:
|
||||
|
||||
| 域名 | 说明 | 是否必须 |
|
||||
|-------|---------|----|
|
||||
|`https://web.sdk.qcloud.com`| Web IM 业务域名 | 必须|
|
||||
|`https://webim.tim.qq.com` | Web IM 业务域名 | 必须|
|
||||
|`https://api.im.qcloud.com` | Web IM 业务域名 | 必须|
|
||||
|
||||
|
||||
将以下域名添加到 **uploadFile 合法域名**:
|
||||
|
||||
| 域名 | 说明 | 是否必须 |
|
||||
|-------|---------|----|
|
||||
|`https://cos.ap-shanghai.myqcloud.com` | 文件上传域名 | 必须|
|
||||
|`https://cos.ap-shanghai.tencentcos.cn` | 文件上传域名 | 必须|
|
||||
|`https://cos.ap-guangzhou.myqcloud.com` | 文件上传域名 | 必须|
|
||||
|
||||
|
||||
将以下域名添加到 **downloadFile 合法域名**:
|
||||
|
||||
| 域名 | 说明 | 是否必须 |
|
||||
|-------|---------|----|
|
||||
|`https://cos.ap-shanghai.myqcloud.com` | 文件下载域名 | 必须|
|
||||
|`https://cos.ap-shanghai.tencentcos.cn` | 文件下载域名 | 必须|
|
||||
|`https://cos.ap-guangzhou.myqcloud.com` | 文件下载域名 | 必须|
|
||||
|
||||
37
TUIService/TUIKit/CHANGELOG.md
Normal file
37
TUIService/TUIKit/CHANGELOG.md
Normal file
@ -0,0 +1,37 @@
|
||||
## 1.0.12 (2023-1-4)
|
||||
### 新增
|
||||
- 支持本地消息审核[需在控制台开启](https://console.cloud.tencent.com/im/local-audit-setting)
|
||||
### 修复
|
||||
- 修复发送图片重复问题
|
||||
- 修复群提示消息展示问题
|
||||
|
||||
## 1.0.10 (2022-12-10)
|
||||
### 新增
|
||||
- 支持群通话[音视频通话](https://cloud.tencent.com/document/product/269/68378)
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.0.8 (2022-11-20)
|
||||
### 新增
|
||||
- 支持 github 仓库形式接入源码
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
|
||||
## 1.0.5 (2022-10-10)
|
||||
|
||||
### 新增
|
||||
- 支持集成 1V1 音视频通话[音视频通话](https://cloud.tencent.com/document/product/269/68378)
|
||||
- 提供分包接入解决方案
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.0.0 (2022-09-15)
|
||||
|
||||
- 支持组件形式集成
|
||||
|
||||
### 新增
|
||||
- [TUIKit界面库 - 小程序](https://cloud.tencent.com/document/product/269/79721)
|
||||
- [集成基础功能 - 小程序](https://cloud.tencent.com/document/product/269/62768)
|
||||
- [设置界面风格 - 小程序](https://cloud.tencent.com/document/product/269/79083)
|
||||
- [添加自定义消息 - 小程序](https://cloud.tencent.com/document/product/269/62789)
|
||||
358
TUIService/TUIKit/README.md
Normal file
358
TUIService/TUIKit/README.md
Normal file
@ -0,0 +1,358 @@
|
||||
## 关于腾讯云即时通信 IM
|
||||
|
||||
腾讯云即时通信(Instant Messaging,IM)基于 QQ 底层 IM 能力开发,仅需植入 SDK 即可轻松集成聊天、会话、群组、资料管理能力,帮助您实现文字、图片、短语音、短视频等富媒体消息收发,全面满足通信需要。
|
||||
|
||||
## 关于 chat-uikit-wechat
|
||||
|
||||
chat-uikit-wechat 是基于腾讯云 IM SDK 的一款 小程序 UI 组件库,它提供了一些通用的 UI 组件,包含会话、聊天、群组、音视频通话等功能。基于 UI 组件您可以像搭积木一样快速搭建起自己的业务逻辑。
|
||||
chat-uikit-wechat 中的组件在实现 UI 功能的同时,会调用 IM SDK 相应的接口实现 IM 相关逻辑和数据的处理,因而开发者在使用 chat-uikit-wechat 时只需关注自身业务或个性化扩展即可。
|
||||
chat-uikit-wechat 效果如下图所示:
|
||||
<img width="1015" src="https://user-images.githubusercontent.com/40623255/202661227-d4227dcc-bada-42a6-a57b-0d0c0abc098b.png" />
|
||||
|
||||
|
||||
## 发送您的第一条消息
|
||||
|
||||
### 开发环境要求
|
||||
|
||||
- 微信开发者工具
|
||||
- JavaScript
|
||||
- node(12.13.0 <= node版本 <= 17.0.0, 推荐使用 Node.js 官方 LTS 版本 16.17.0)
|
||||
- npm(版本请与 node 版本匹配)
|
||||
|
||||
### TUIKit 源码集成
|
||||
|
||||
#### 步骤1:创建项目
|
||||
|
||||
在微信开发者工具上创建一个小程序项目,选择不使用模版。
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/40623255/202665077-b4f01580-69f2-493c-9fab-4f4ef8e5021a.png"/>
|
||||
|
||||
#### 步骤2:下载 TUIKit 组件
|
||||
|
||||
微信开发者工具创建的小程序不会默认创建 package.json 文件,因此您需要先创建 package.json 文件。新建终端,如下:
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/6735b8ead18ffa7c80f2e16cebbdc9d1.png"/>
|
||||
|
||||
输入:
|
||||
|
||||
```javascript
|
||||
npm init
|
||||
```
|
||||
然后通过 npm 方式下载 TUIKit 组件, 为了方便您后续的拓展,建议您将 TUIKit 组件复制到自己的小程序目录下:
|
||||
|
||||
macOS端
|
||||
```javascript
|
||||
npm i @tencentcloud/chat-uikit-wechat
|
||||
```
|
||||
```javascript
|
||||
mkdir -p ./TUIKit && cp -r node_modules/@tencentcloud/chat-uikit-wechat/ ./TUIKit
|
||||
```
|
||||
Windows端
|
||||
```javascript
|
||||
npm i @tencentcloud/chat-uikit-wechat
|
||||
```
|
||||
```javascript
|
||||
xcopy node_modules\@tencentcloud\chat-uikit-wechat .\TUIKit /i /e
|
||||
```
|
||||
成功后目录结构如图所示:
|
||||
<img width="300" src="https://qcloudimg.tencent-cloud.cn/raw/8f0b5274acd80602f2a431313034a2b9.png"/>
|
||||
|
||||
#### 步骤3:引入 TUIKit 组件
|
||||
|
||||
##### 方式一: 主包引入 (适用于业务逻辑简单的小程序)
|
||||
在 page 页面引用 TUIKit 组件,为此您需要分别修改 index.wxml 、index.js 和 index.json。
|
||||
|
||||
wxml 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/9816f2a2141357fbaced7e77929392f8.png"/>
|
||||
|
||||
```javascript
|
||||
<view>
|
||||
<TUIKit config="{{config}}" id="TUIKit"></TUIKit>
|
||||
</view>
|
||||
```
|
||||
|
||||
js 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/b9c02ec038b4b397f175591c7b5ef876.png"/>
|
||||
|
||||
```javascript
|
||||
import TIM from '../../TUIKit/lib/tim-wx-sdk';
|
||||
import { genTestUserSig } from '../../TUIKit/debug/GenerateTestUserSig';
|
||||
import TIMUploadPlugin from '../../TUIKit/lib/tim-upload-plugin';
|
||||
import TIMProfanityFilterPlugin from '../../TUIKit/lib/tim-profanity-filter-plugin';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
config: {
|
||||
userID: '', //User ID
|
||||
SDKAPPID: 0, // Your SDKAppID
|
||||
SECRETKEY: '', // Your secretKey
|
||||
EXPIRETIME: 604800,
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
const userSig = genTestUserSig(this.data.config).userSig
|
||||
wx.$TUIKit = TIM.create({
|
||||
SDKAppID: this.data.config.SDKAPPID
|
||||
})
|
||||
wx.$chat_SDKAppID = this.data.config.SDKAPPID;
|
||||
wx.$chat_userID = this.data.config.userID;
|
||||
wx.$chat_userSig = userSig;
|
||||
wx.$TUIKitTIM = TIM;
|
||||
wx.$TUIKit.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin });
|
||||
wx.$TUIKit.registerPlugin({ 'tim-profanity-filter-plugin': TIMProfanityFilterPlugin });
|
||||
wx.$TUIKit.login({
|
||||
userID: this.data.config.userID,
|
||||
userSig
|
||||
});
|
||||
wx.setStorage({
|
||||
key: 'currentUserID',
|
||||
data: [],
|
||||
});
|
||||
wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.SDK_READY, this.onSDKReady,this);
|
||||
},
|
||||
onUnload() {
|
||||
wx.$TUIKit.off(wx.$TUIKitTIM.EVENT.SDK_READY, this.onSDKReady,this);
|
||||
},
|
||||
onSDKReady() {
|
||||
const TUIKit = this.selectComponent('#TUIKit');
|
||||
TUIKit.init();
|
||||
}
|
||||
});
|
||||
```
|
||||
json 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/866e12c4bf19e08c71c233158cc19106.png"/>
|
||||
|
||||
```javascript
|
||||
{
|
||||
"usingComponents": {
|
||||
"TUIKit": "../../TUIKit/index"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
```
|
||||
|
||||
##### 方式二:分包引入 (适用于业务逻辑复杂,按需载入的小程序)
|
||||
小程序分包有如下好处:
|
||||
- 规避所有逻辑代码放主包,导致主包文件体积超限问题
|
||||
- 支持按需载入,降低小程序载入耗时和页面渲染耗时
|
||||
- 支持更加复杂的功能
|
||||
分包流程:
|
||||
1.在自己项目里创建分包,本文以 TUI—CustomerService 为例。和 pages 同级创建 TUI—CustomerService 文件夹,并在文件夹内部创建 pages 文件夹并且其下创建 index 页面。
|
||||
创建后的目录结构:
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/bc1352da5ea30bb3a8134bedbc421a9b.png"/>
|
||||
|
||||
2.在 app.json 文件注册分包。
|
||||
|
||||
```javascript
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/index"
|
||||
],
|
||||
"subPackages": [
|
||||
{
|
||||
"root": "TUI-CustomerService",
|
||||
"name": "TUI-CustomerService",
|
||||
"pages": [
|
||||
"pages/index"
|
||||
],
|
||||
"independent": false
|
||||
}
|
||||
],
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#fff",
|
||||
"navigationBarTitleText": "Weixin",
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"style": "v2",
|
||||
"sitemapLocation": "sitemap.json"
|
||||
}
|
||||
```
|
||||
3.将 TUIKit 文件夹复制到分包目录下。
|
||||
成功后的目录结构:
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/5abd5dc90d2e5d53b3ed1a264e0398f8.png"/>
|
||||
|
||||
4.将 TUIKit 文件夹下的 debug 和 lib 文件夹复制到主包。
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/00a9557954be659dd32f00d45195daac.png"/>
|
||||
|
||||
5. 在分包内引用 TUIKit组件,为此需要分别修改分包内部 index.wxml 、index.js 、index.json 文件,以及 app.js 文件。
|
||||
|
||||
wxml 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/072f4f8f78d512f28ac8e82ed9925055.png"/>
|
||||
|
||||
```javascript
|
||||
<view>
|
||||
<TUIKit config="{{config}}" id="TUIKit"></TUIKit>
|
||||
</view>
|
||||
```
|
||||
|
||||
js 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/d36a0543c7fe94def0fc36042eddc28c.png"/>
|
||||
|
||||
```javascript
|
||||
Page({
|
||||
|
||||
// 其他代码
|
||||
|
||||
onLoad() {
|
||||
const TUIKit = this.selectComponent('#TUIKit');
|
||||
TUIKit.init();
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
json 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/4499096c37b9b29abffa21b71fb90e9e.png"/>
|
||||
|
||||
```javascript
|
||||
{
|
||||
"usingComponents": {
|
||||
"TUIKit": "../TUIKit/index"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
```
|
||||
app.js 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/170aa919af6db0e7b32ace5da9d417f1.png"/>
|
||||
|
||||
```javascript
|
||||
import TIM from './lib/tim-wx-sdk';
|
||||
import TIMUploadPlugin from './lib/tim-upload-plugin';
|
||||
import TIMProfanityFilterPlugin from './lib/tim-profanity-filter-plugin';
|
||||
import { genTestUserSig } from './debug/GenerateTestUserSig';
|
||||
App({
|
||||
onLaunch: function () {
|
||||
wx.$TUIKit = TIM.create({
|
||||
SDKAppID: this.globalData.config.SDKAPPID,
|
||||
});
|
||||
const userSig = genTestUserSig(this.globalData.config).userSig
|
||||
wx.$chat_SDKAppID = this.globalData.config.SDKAPPID;
|
||||
wx.$TUIKitTIM = TIM;
|
||||
wx.$chat_userID = this.globalData.config.userID;
|
||||
wx.$chat_userSig = userSig;
|
||||
wx.$TUIKit.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin });
|
||||
wx.$TUIKit.registerPlugin({ 'tim-profanity-filter-plugin': TIMProfanityFilterPlugin });
|
||||
wx.$TUIKit.login({
|
||||
userID: this.globalData.config.userID,
|
||||
userSig
|
||||
});
|
||||
// 监听系统级事件
|
||||
wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.SDK_READY, this.onSDKReady);
|
||||
},
|
||||
globalData: {
|
||||
config: {
|
||||
userID: '', //User ID
|
||||
SECRETKEY: '', // Your secretKey
|
||||
SDKAPPID: 0, // Your SDKAppID
|
||||
EXPIRETIME: 604800,
|
||||
},
|
||||
},
|
||||
onSDKReady() {
|
||||
},
|
||||
});
|
||||
```
|
||||
6. 按需载入分包,您需要修改主包 pages 下的 index.wxml 、index.js。
|
||||
|
||||
wxml 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/86f2698910c2e255727f419625441ed9.png"/>
|
||||
|
||||
```javascript
|
||||
<view class="container" bindtap="handleJump">
|
||||
载入腾讯云 IM 分包
|
||||
</view>
|
||||
```
|
||||
|
||||
js 文件
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/5c41dff77345aa364bde46039f84ffd7.png"/>
|
||||
|
||||
```javascript
|
||||
Page({
|
||||
handleJump() {
|
||||
app.method.navigateTo({
|
||||
url: '../../TUI-CustomerService/pages/index',
|
||||
})
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### 步骤4: 获取 SDKAppID 、密钥与 userID
|
||||
|
||||
设置步骤3示例代码中的相关参数 SDKAPPID、SECRETKEY 以及 userID ,其中 SDKAppID 和密钥等信息,可通过 [即时通信 IM 控制台](https://console.cloud.tencent.com/im) 获取,单击目标应用卡片,进入应用的基础配置页面。例如:
|
||||
<img style="width:600px; max-width: inherit;" src="https://qcloudimg.tencent-cloud.cn/raw/44a331ce39f05f7080cf33ca9bc8e5dd.png"/>
|
||||
userID 信息,可通过 [即时通信 IM 控制台](https://console.cloud.tencent.com/im) 进行创建和获取,单击目标应用卡片,进入应用的账号管理页面,即可创建账号并获取 userID。例如:
|
||||
<img style="width:870px; max-width: inherit;" src="https://qcloudimg.tencent-cloud.cn/raw/94c801b7258612f8a4018728d862252f.png"/>
|
||||
|
||||
### 步骤5:编译小程序
|
||||
|
||||
- 请在本地设置里面勾选上“不校验合法域名、web-view (业务域名)、 TLS 版本以及 HTTPS 证书”。
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/e32530c238362d5bb597c1171f6646ff.png"/>
|
||||
|
||||
- 点击【清缓存】->【全部清除】,避免开发者工具的缓存造成渲染异常。
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/2c68432c6e3399df21517e521c356299.png"/>
|
||||
|
||||
- 点击【编译】。
|
||||
|
||||
<img src="https://qcloudimg.tencent-cloud.cn/raw/b98aebdadf932e036e9900aea5651c1e.png"/>
|
||||
|
||||
### 步骤6:发送您的第一条消息
|
||||
<img style="width:1000" src="https://qcloudimg.tencent-cloud.cn/raw/4673f24d0fc8319c4788d505d9fde774.png" />
|
||||
<img style="width:1000" src="https://qcloudimg.tencent-cloud.cn/raw/02eb06fbc13cdf27664fe55eb2e10b49.png" />
|
||||
|
||||
### 常见问题
|
||||
#### 1. 什么是 UserSig?
|
||||
|
||||
UserSig 是用户登录即时通信 IM 的密码,其本质是对 UserID 等信息加密后得到的密文。
|
||||
|
||||
#### 2. 如何生成 UserSig?
|
||||
|
||||
UserSig 签发方式是将 UserSig 的计算代码集成到您的服务端,并提供面向项目的接口,在需要 UserSig 时由您的项目向业务服务器发起请求获取动态 UserSig。更多详情请参见 [服务端生成 UserSig](https://cloud.tencent.com/document/product/269/32688#GeneratingdynamicUserSig)。
|
||||
|
||||
> !
|
||||
>
|
||||
> 本文示例代码采用的获取 UserSig 的方案是在客户端代码中配置 SECRETKEY,该方法中 SECRETKEY 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量,因此**该方法仅适合本地跑通功能调试**。 正确的 UserSig 签发方式请参见上文。
|
||||
|
||||
### 3. 小程序如果需要上线或者部署正式环境怎么办?
|
||||
请在**微信公众平台**>**开发**>**开发管理**>**开发设置**>**服务器域名**中进行域名配置:
|
||||
|
||||
从v2.11.2起 SDK 支持了 WebSocket,WebSocket 版本须添加以下域名到 **socket 合法域名**:
|
||||
|
||||
| 域名 | 说明 | 是否必须 |
|
||||
|-------|---------|----|
|
||||
|`wss://wss.im.qcloud.com`| Web IM 业务域名 | 必须|
|
||||
|`wss://wss.tim.qq.com`| Web IM 业务域名 | 必须|
|
||||
|
||||
将以下域名添加到 **request 合法域名**:
|
||||
|
||||
| 域名 | 说明 | 是否必须 |
|
||||
|-------|---------|----|
|
||||
|`https://web.sdk.qcloud.com`| Web IM 业务域名 | 必须|
|
||||
|`https://webim.tim.qq.com` | Web IM 业务域名 | 必须|
|
||||
|`https://api.im.qcloud.com` | Web IM 业务域名 | 必须|
|
||||
|
||||
|
||||
| 域名 | 说明 | 是否必须 |
|
||||
|-------|---------|----|
|
||||
|`https://cos.ap-shanghai.myqcloud.com` | 文件上传域名 | 必须|
|
||||
|`https://cos.ap-shanghai.tencentcos.cn` | 文件上传域名 | 必须|
|
||||
|`https://cos.ap-guangzhou.myqcloud.com` | 文件上传域名 | 必须|
|
||||
|
||||
|
||||
将以下域名添加到 **downloadFile 合法域名**:
|
||||
|
||||
| 域名 | 说明 | 是否必须 |
|
||||
|-------|---------|----|
|
||||
|`https://cos.ap-shanghai.myqcloud.com` | 文件下载域名 | 必须|
|
||||
|`https://cos.ap-shanghai.tencentcos.cn` | 文件下载域名 | 必须|
|
||||
|`https://cos.ap-guangzhou.myqcloud.com` | 文件下载域名 | 必须|
|
||||
@ -0,0 +1,3 @@
|
||||
Component({
|
||||
|
||||
})
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
},
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
}
|
||||
@ -0,0 +1,151 @@
|
||||
import { parseAudio } from '../../../../../utils/message-parse';
|
||||
|
||||
// 创建audio控件
|
||||
const myaudio = wx.createInnerAudioContext();
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
renderDom: parseAudio(newVal),
|
||||
message: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
messageList: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.filtterAudioMessage(newVal);
|
||||
this.setData({
|
||||
audioMessageList: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
isMine: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
|
||||
lifetimes: {
|
||||
detached() {
|
||||
myaudio.stop();
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
message: '',
|
||||
renderDom: [],
|
||||
Audio: [],
|
||||
audioMessageList: [],
|
||||
audioSave: [],
|
||||
audKey: '', // 当前选中的音频key
|
||||
indexAudio: Number,
|
||||
isPlay: false,
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
// 过滤语音消息,从消息列表里面筛选出语音消息
|
||||
filtterAudioMessage(messageList) {
|
||||
const list = [];
|
||||
for (let index = 0; index < messageList.length; index++) {
|
||||
if (messageList[index].type === 'TIMSoundElem') {
|
||||
list.push(messageList[index]);
|
||||
Object.assign(messageList[index], {
|
||||
isPlaying: false,
|
||||
}),
|
||||
this.data.audioSave = list;
|
||||
this.setData({
|
||||
audioSave: this.data.audioSave,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 音频播放
|
||||
audioPlay(e) {
|
||||
const { id } = e.currentTarget.dataset;
|
||||
const { audioSave } = this.data;
|
||||
|
||||
// 设置状态
|
||||
audioSave.forEach((message, index) => {
|
||||
message.isPlaying = false;
|
||||
if (audioSave[index].ID == id) {
|
||||
message.isPlaying = true;
|
||||
const indexAudio = audioSave.findIndex(value => value.ID == audioSave[index].ID);
|
||||
this.setData({
|
||||
indexAudio,
|
||||
isPlay: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
this.setData({
|
||||
audioSave,
|
||||
audKey: this.data.indexAudio,
|
||||
isPlay: true,
|
||||
});
|
||||
myaudio.autoplay = true;
|
||||
const { audKey } = this.data;
|
||||
const playSrc = audioSave[audKey].payload.url;
|
||||
myaudio.src = playSrc;
|
||||
myaudio.play();
|
||||
// 开始监听
|
||||
myaudio.onPlay(() => {
|
||||
console.log('开始播放');
|
||||
});
|
||||
|
||||
// 结束监听
|
||||
myaudio.onEnded(() => {
|
||||
console.log('自动播放完毕');
|
||||
audioSave[this.data.indexAudio].isPlaying = false;
|
||||
this.setData({
|
||||
audioSave,
|
||||
isPlay: false,
|
||||
});
|
||||
});
|
||||
|
||||
// 错误回调
|
||||
myaudio.onError((err) => {
|
||||
console.log(err);
|
||||
audioSave[this.data.indexAudio].isPlaying = false;
|
||||
this.setData({
|
||||
audioSave,
|
||||
});
|
||||
return;
|
||||
});
|
||||
},
|
||||
|
||||
// 音频停止
|
||||
audioStop(e) {
|
||||
const { key } = e.currentTarget.dataset;
|
||||
const { audioSave } = this.data;
|
||||
// 设置状态
|
||||
audioSave.forEach((message, index) => {
|
||||
message.isPlaying = false;
|
||||
});
|
||||
this.setData({
|
||||
audioSave,
|
||||
isPlay: false,
|
||||
});
|
||||
myaudio.stop();
|
||||
|
||||
// 停止监听
|
||||
myaudio.onStop(() => {
|
||||
console.log('停止播放');
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
<block>
|
||||
<view class="audio-message {{isMine?'my-audio':''}}">
|
||||
<!-- 默认状态 未播放 -->
|
||||
<view class='audio' wx:if="{{!isPlay}}" bindtap='audioPlay' data-id="{{message.ID}}" >
|
||||
<image class="image {{isMine?'my-image':''}}" src="../../../../../static/images/sendingaudio.png"/> {{renderDom[0].second}}s
|
||||
</view>
|
||||
<!-- 当前正在播放状态 -->
|
||||
<view class='audio' wx:else data-value="{{message}}" bindtap='audioStop' data-id="{{message.ID}}" >
|
||||
<image class="image {{isMine?'my-image':''}}" src="../../../../../static/images/sendingaudio.png"/> {{renderDom[0].second}}s
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
.audio-message {
|
||||
padding: 10rpx 18rpx;
|
||||
border-radius: 2px 10px 10px 10px;
|
||||
border: 1px solid #D9D9D9;
|
||||
}
|
||||
.my-audio {
|
||||
border-radius: 10px 2px 10px 10px;
|
||||
background: rgba(0,110,255,0.10);
|
||||
border: 1px solid rgba(0,110,255,0.30);
|
||||
}
|
||||
.audio {
|
||||
/*border-radius: 2px 10px 10px 10px;*/
|
||||
height: 60rpx;
|
||||
font-family: PingFangSC-Medium;
|
||||
font-size: 28rpx;
|
||||
color: #000000;
|
||||
line-height: 28rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.image{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
.my-image{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transform:rotate(180deg)
|
||||
}
|
||||
@ -0,0 +1,329 @@
|
||||
import formateTime from '../../../../../utils/formate-time';
|
||||
import constant from '../../../../../utils/constant';
|
||||
import {
|
||||
getCurrentPageUrl,
|
||||
getCurrentPageParam
|
||||
} from "../../../../../../../utils/getUrl"
|
||||
import {
|
||||
getRate
|
||||
} from "../../../../../../../api/consultOrder"
|
||||
const app = getApp()
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
message: newVal,
|
||||
renderDom: this.parseCustom(newVal),
|
||||
});
|
||||
},
|
||||
},
|
||||
patient_data:{
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
patient_data: newVal,
|
||||
});
|
||||
}
|
||||
},
|
||||
isMine: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
pageLifetimes:{
|
||||
show: function() {
|
||||
this.setData({
|
||||
img_host:app.hostConfig().imghost
|
||||
});
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
displayServiceEvaluation: false,
|
||||
score: 0,
|
||||
img_host:'https://oss.prod.applets.igandanyiyuan.com/applet/patient/static',
|
||||
commentDetail: null
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
// async getDom(id,renderDom){
|
||||
// let result = await this.handleGetRate(id,renderDom);
|
||||
// return result
|
||||
// },
|
||||
handleGetRate(id) {
|
||||
getRate(id).then(data => {
|
||||
let commentDetail = null;
|
||||
if (data) {
|
||||
commentDetail = data
|
||||
} else {
|
||||
commentDetail = {
|
||||
avg_score: 0,
|
||||
content: "",
|
||||
evaluation_id: "",
|
||||
is_evaluation: false,
|
||||
order_inquiry_id:id,
|
||||
reply_progress: 0,
|
||||
reply_quality: 0,
|
||||
service_attitude: 0
|
||||
|
||||
}
|
||||
}
|
||||
this.triggerEvent("popComment",commentDetail);
|
||||
})
|
||||
},
|
||||
async handleAllRate(id, renderDom) {
|
||||
let result = null;
|
||||
await getRate(id).then(data => {
|
||||
if (data) {
|
||||
renderDom[0].is_evaluation = true;
|
||||
renderDom[0].score = data.avg_score;
|
||||
}
|
||||
})
|
||||
|
||||
this.setData({
|
||||
renderDom: renderDom
|
||||
})
|
||||
},
|
||||
showPop(event) {
|
||||
let id = event.currentTarget.dataset.id;
|
||||
console.log(id);
|
||||
this.handleGetRate(id);
|
||||
},
|
||||
|
||||
// 解析音视频通话消息
|
||||
extractCallingInfoFromMessage(message) {
|
||||
const callingmessage = JSON.parse(message.payload.data);
|
||||
if (callingmessage.businessID !== 1) {
|
||||
return '';
|
||||
}
|
||||
const objectData = JSON.parse(callingmessage.data);
|
||||
switch (callingmessage.actionType) {
|
||||
case 1: {
|
||||
if (objectData.call_end >= 0) {
|
||||
return `通话时长:${formateTime(objectData.call_end)}`;
|
||||
}
|
||||
if (objectData.data && objectData.data.cmd === 'switchToAudio') {
|
||||
return '切换语音通话';
|
||||
}
|
||||
if (objectData.data && objectData.data.cmd === 'switchToVideo') {
|
||||
return '切换视频通话';
|
||||
}
|
||||
return '发起通话';
|
||||
}
|
||||
case 2:
|
||||
return '取消通话';
|
||||
case 3:
|
||||
if (objectData.data && objectData.data.cmd === 'switchToAudio') {
|
||||
return '切换语音通话';
|
||||
}
|
||||
if (objectData.data && objectData.data.cmd === 'switchToVideo') {
|
||||
return '切换视频通话';
|
||||
}
|
||||
return '已接听';
|
||||
case 4:
|
||||
return '拒绝通话';
|
||||
case 5:
|
||||
if (objectData.data && objectData.data.cmd === 'switchToAudio') {
|
||||
return '切换语音通话';
|
||||
}
|
||||
if (objectData.data && objectData.data.cmd === 'switchToVideo') {
|
||||
return '切换视频通话';
|
||||
}
|
||||
return '无应答';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
},
|
||||
parseCustom(message) {
|
||||
const {
|
||||
BUSINESS_ID_TEXT
|
||||
} = constant;
|
||||
// 群消息解析
|
||||
if (message.payload.data === BUSINESS_ID_TEXT.CREATE_GROUP) {
|
||||
const renderDom = [{
|
||||
type: 'group_create',
|
||||
text: message.payload.extension,
|
||||
}];
|
||||
return renderDom;
|
||||
}
|
||||
try {
|
||||
const customMessage = JSON.parse(message.payload.data);
|
||||
let avastar = '';
|
||||
if (message.flow == "in") {
|
||||
avastar = message.avatar;
|
||||
}
|
||||
// 约定自定义消息的 data 字段作为区分,不解析的不进行展示
|
||||
if (customMessage.businessID === BUSINESS_ID_TEXT.ORDER) {
|
||||
const renderDom = [{
|
||||
type: 'order',
|
||||
name: 'custom',
|
||||
title: customMessage.title || '',
|
||||
imageUrl: customMessage.imageUrl || '',
|
||||
price: customMessage.price || 0,
|
||||
description: customMessage.description,
|
||||
}];
|
||||
return renderDom;
|
||||
}
|
||||
// 服务评价
|
||||
if (customMessage.businessID === BUSINESS_ID_TEXT.EVALUATION) {
|
||||
const renderDom = [{
|
||||
type: 'evaluation',
|
||||
title: message.payload.description,
|
||||
score: customMessage.score,
|
||||
description: customMessage.comment,
|
||||
}];
|
||||
return renderDom;
|
||||
}
|
||||
// native 自定义消息解析
|
||||
if (customMessage.businessID === BUSINESS_ID_TEXT.LINK) {
|
||||
const renderDom = [{
|
||||
type: 'text_link',
|
||||
text: customMessage.text,
|
||||
}];
|
||||
return renderDom;
|
||||
}
|
||||
// 自定义消息类型(1:消息内页横条 2:订单结束评价弹出 3:医生端系统通知 4:医生端服务通知 5:患者端系统消息 6:处方开具成功(医生端) 7:处方审核通过(患者端))",
|
||||
if (customMessage.message_type == 1) {
|
||||
const renderDom = [{
|
||||
type: 'msg_tip',
|
||||
text: customMessage.title,
|
||||
desc: customMessage.desc
|
||||
}];
|
||||
return renderDom;
|
||||
}
|
||||
|
||||
if (customMessage.message_type == 2) {
|
||||
let renderDom = [{
|
||||
type: 'msg_comment',
|
||||
text: customMessage.title,
|
||||
order_inquiry_id: customMessage.data.order_inquiry_id,
|
||||
is_evaluation: false,
|
||||
score: 0,
|
||||
desc: customMessage.desc,
|
||||
avatar: avastar
|
||||
}];
|
||||
|
||||
this.handleAllRate(customMessage.data.order_inquiry_id, renderDom);
|
||||
|
||||
return renderDom;
|
||||
};
|
||||
if (customMessage.message_type == 7) {
|
||||
let data = customMessage.data;
|
||||
const renderDom = [{
|
||||
type: 'msg_prescribe',
|
||||
product_name: data.product_name,
|
||||
order_inquiry_id: data.order_inquiry_id,
|
||||
order_prescription_id: data.order_prescription_id,
|
||||
pharmacist_verify_time: data.pharmacist_verify_time.substring(0, 10),
|
||||
}];
|
||||
return renderDom;
|
||||
};
|
||||
if (customMessage.message_type == 10) {
|
||||
let data = customMessage.data;
|
||||
const renderDom = [{
|
||||
type: 'msg_checksugar',
|
||||
title:customMessage.title,
|
||||
order_no:data.order_no,
|
||||
message_path:data.message_path,
|
||||
disease_class_names: data.disease_class_names
|
||||
}];
|
||||
return renderDom;
|
||||
}
|
||||
|
||||
} catch (error) {}
|
||||
// 客服咨询
|
||||
try {
|
||||
const extension = JSON.parse(message.payload.extension);
|
||||
if (message.payload.data === BUSINESS_ID_TEXT.CONSULTION) {
|
||||
const renderDom = [{
|
||||
type: 'consultion',
|
||||
title: extension.title || '',
|
||||
item: extension.item || 0,
|
||||
description: extension.description,
|
||||
}];
|
||||
return renderDom;
|
||||
}
|
||||
} catch (error) {}
|
||||
// 音视频通话消息解析
|
||||
try {
|
||||
const callingmessage = JSON.parse(message.payload.data);
|
||||
if (callingmessage.businessID === 1) {
|
||||
if (message.conversationType === wx.$TUIKitTIM.TYPES.CONV_GROUP) {
|
||||
if (message.payload.data.actionType === 5) {
|
||||
message.nick = message.payload.data.inviteeList ? message.payload.data.inviteeList.join(',') : message.from;
|
||||
}
|
||||
const _text = this.extractCallingInfoFromMessage(message);
|
||||
const groupText = `${_text}`;
|
||||
const renderDom = [{
|
||||
type: 'groupCalling',
|
||||
text: groupText,
|
||||
userIDList: [],
|
||||
}];
|
||||
return renderDom;
|
||||
}
|
||||
if (message.conversationType === wx.$TUIKitTIM.TYPES.CONV_C2C) {
|
||||
const c2cText = this.extractCallingInfoFromMessage(message);
|
||||
const renderDom = [{
|
||||
type: 'c2cCalling',
|
||||
text: c2cText,
|
||||
}];
|
||||
return renderDom;
|
||||
}
|
||||
}
|
||||
return [{
|
||||
type: 'notSupport',
|
||||
text: '[自定义消息]',
|
||||
}];
|
||||
} catch (error) {}
|
||||
},
|
||||
openLink(e) {
|
||||
if (e.currentTarget.dataset.value.key === '立即前往') {
|
||||
app.method.navigateTo({
|
||||
url: '/pages/TUI-User-Center/webview/webview?url=https://cloud.tencent.com/act/pro/imnew?from=16975&wechatMobile',
|
||||
});
|
||||
} else if (e.currentTarget.dataset.value.key === '立即体验') {
|
||||
app.method.navigateTo({
|
||||
url: '/pages/TUI-User-Center/webview/webview?url=https://cloud.tencent.com/document/product/269/68091',
|
||||
});
|
||||
}
|
||||
},
|
||||
goReport(event){
|
||||
let {url,id} = event.currentTarget.dataset;
|
||||
app.method.navigateTo({
|
||||
url: '/pages/checkOrderDetail/checkOrderDetail?order_detection_id='+id
|
||||
})
|
||||
},
|
||||
goPrescriptDetail(event) {
|
||||
let url = event.currentTarget.dataset.url;
|
||||
let redirectUrl = getCurrentPageUrl();
|
||||
let options = getCurrentPageParam();
|
||||
let params = ""
|
||||
for (const key in options) {
|
||||
if (params) {
|
||||
params = params + '&' + key + '=' + options[key];
|
||||
} else {
|
||||
params = params + key + '=' + options[key];
|
||||
}
|
||||
};
|
||||
//console.log(url + "&fromType=" + redirectUrl + "?" + params)
|
||||
app.method.navigateTo({
|
||||
url: url + "&fromType=" + encodeURIComponent(redirectUrl + "?" + params)
|
||||
})
|
||||
}
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-rate": "@vant/weapp/rate/index"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
<view class="custom_wrap {{isMine?'':'your-custom'}}">
|
||||
<view wx:if="{{renderDom[0].type ==='order'}}" class="custom-message {{isMine?'my-custom':''}}">
|
||||
<image class="custom-image" src="{{renderDom[0].imageUrl}}" />
|
||||
<view class="custom-content">
|
||||
<view class="custom-content-title">{{renderDom[0].title}}</view>
|
||||
<view class="custom-content-description">{{renderDom[0].description}}</view>
|
||||
<view class="custom-content-price">{{renderDom[0].price}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type ==='consultion'}}" class="custom-message {{isMine?'my-custom':''}}">
|
||||
<view class="custom-content">
|
||||
<view>
|
||||
<text class="custom-content-title">{{renderDom[0].title}}</text>
|
||||
<text class="custom-content-hyperlinks" bindtap="openLink" data-value="{{renderDom[0].hyperlinks_text}}">{{renderDom[0].hyperlinks_text.key}}</text>
|
||||
<view class="custom-content-description" wx:for="{{renderDom[0].item}}" wx:key="index" id="{{item.key}}">{{item.key}}
|
||||
</view>
|
||||
</view>
|
||||
<text class="custom-content-description">{{renderDom[0].description}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type ==='evaluation'}}" class="custom-message {{isMine?'my-custom':''}}">
|
||||
<view class="custom-content">
|
||||
<view class="custom-content-title">{{renderDom[0].title}}</view>
|
||||
<view class="custom-content-score">
|
||||
<image class="score-star" wx:for="{{renderDom[0].score}}" wx:key="*this" src="../../../../../static/images/star.png" />
|
||||
</view>
|
||||
<view class="custom-content-description">{{renderDom[0].description}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type === 'text_link'}}" class="message-body-span text-message">
|
||||
<view class="message-body-span-text">{{renderDom[0].text}}</view>
|
||||
<text class="message-body-span-link">查看详情>></text>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type ==='group_create'}}" class="custom-message {{isMine?'my-custom':''}}">
|
||||
<view class="custom-content-text">{{renderDom[0].text}}</view>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type ==='c2cCalling' || renderDom[0].type ==='groupCalling'}}" class="custom-message {{isMine?'my-custom':''}}">
|
||||
<view class="custom-content-text">{{renderDom[0].text}}</view>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type ==='notSupport'}}" class="message-body-span text-message">
|
||||
<view class="message-body-span-text">{{renderDom[0].text}}</view>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type ==='msg_tip'}}" class="message-body-span text-message custom-tip-message">
|
||||
<view class="message-body-span-text">{{renderDom[0].text}}</view>
|
||||
<view class="message-body-span-desc">{{renderDom[0].desc}}</view>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type ==='msg_comment'}}" class="message-body-span text-message custom-tip-message" >
|
||||
<!-- <view class="message-body-span-text">{{renderDom[0].text}}</view> -->
|
||||
<view class="commentbox" bindtap="showPop" data-id="{{renderDom[0].order_inquiry_id}}">
|
||||
<view class="title">请您对本次问诊服务进行评价</view>
|
||||
<view class="ratebox">
|
||||
<van-rate value="{{renderDom[0].score}}" size="{{ 22 }}" color="#ed9c00" void-icon="star" void-color="#e7e7e7" readonly gutter="20" />
|
||||
</view>
|
||||
|
||||
<view class="button" wx:if="{{!(renderDom[0].is_evaluation)}}">点击评价</view>
|
||||
<view class="button" wx:else>查看评价</view>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type==='msg_prescribe'}}"
|
||||
class="gdxz_custom_order_prescribe_message"
|
||||
data-url="/pages/prescriptDetail/prescriptDetail?order_prescription_id={{renderDom[0].order_prescription_id}}"
|
||||
bindtap="goPrescriptDetail">
|
||||
<view class="prescribe_title">
|
||||
处方已开具
|
||||
</view>
|
||||
<view class="content_prescribe">
|
||||
<view class="left">
|
||||
<image src="{{img_host+'/chufang.png'}}" class="prescribeImg"></image>
|
||||
</view>
|
||||
<view class="prescribe_box">
|
||||
<view class="prescribe_box_top">
|
||||
<view class="prescribe_box_top_product_name"><text style="color: #999;"> RP:</text>{{renderDom[0].product_name}}</view>
|
||||
<view class="prescribe_box_top_pharmacist_verify_time"><text style="color: #999;">开方日期:</text> {{renderDom[0].pharmacist_verify_time}}</view>
|
||||
</view>
|
||||
<view class="prescribe_box_bottom" data-order_prescription_id="{{renderDom[0].order_prescription_id}}">
|
||||
<view class="prescribe_box_buy">去购买</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{renderDom[0].type==='msg_checksugar'}}" class="sugarbox">
|
||||
<view class="sugarcon">
|
||||
<view class="title">
|
||||
{{renderDom[0].title}}报告
|
||||
</view>
|
||||
<view class="patient_info">
|
||||
<view class="name">就诊人:{{patient_data.patient_name}}(<text wx:if="{{patient_data.patient_sex==1}}">男</text><text wx:elif="{{patient_data.patient_sex==2}}">女</text><text wx:else>未知</text>|{{patient_data.patient_age}}岁)</view>
|
||||
<view class="sick"> 所患疾病:{{renderDom[0].disease_class_names}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail" bindtap="goReport" data-url="{{renderDom[0].message_path}}" data-id="{{renderDom[0].order_no}}">
|
||||
<view class="left">查看报告</view>
|
||||
<image src="../../../../../static/images/back.png" class="back" mode=""/>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
@ -0,0 +1,324 @@
|
||||
.custom-message {
|
||||
background: #FBFBFB;
|
||||
border-radius: 4rpx 20rpx 20rpx 20rpx;
|
||||
display: flex;
|
||||
padding: 10rpx 24rpx;
|
||||
background-color: #fff;
|
||||
border: 1px solid #D9D9D9;
|
||||
}
|
||||
.content_prescribe{
|
||||
margin:0 20rpx;
|
||||
display: flex;
|
||||
}
|
||||
.prescribeImg{
|
||||
margin-top: 25rpx;
|
||||
flex-shrink: 0;
|
||||
width:68rpx;
|
||||
height:68rpx;
|
||||
}
|
||||
.my-custom {
|
||||
border-radius: 10px 2px 10px 10px;
|
||||
border: 1px solid rgba(0, 110, 255, 0.30);
|
||||
}
|
||||
|
||||
.custom-content-title {
|
||||
font-family: PingFangSC-Medium;
|
||||
max-width: 268rpx;
|
||||
height: 34rpx;
|
||||
font-size: 28rpx;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
margin-bottom: 12rpx;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.custom-content-description {
|
||||
font-family: PingFangSC-Regular;
|
||||
width: 278rpx;
|
||||
line-height: 34rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
line-height: 40rpx;
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 12rpx;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.custom-content-price {
|
||||
font-family: PingFangSC-Medium;
|
||||
line-height: 50rpx;
|
||||
color: #FF7201;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.custom-image {
|
||||
width: 135rpx;
|
||||
height: 135rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 10rpx;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.custom-content-score {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.custom-content-score .score-star {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.text-message {
|
||||
display: inline-flex;
|
||||
max-width: 60vw;
|
||||
line-height: 52rpx;
|
||||
padding: 12rpx 24rpx;
|
||||
background: #F8F8F8;
|
||||
border: 1px solid #D9D9D9;
|
||||
border-radius: 2px 10px 10px 10px;
|
||||
}
|
||||
|
||||
.my-text {
|
||||
border-radius: 10px 2px 10px 10px;
|
||||
border: 1px solid rgba(0, 110, 255, 0.30);
|
||||
background: rgba(0, 110, 255, 0.10);
|
||||
}
|
||||
|
||||
.message-body-span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/*justify-content: flex-start;*/
|
||||
flex-wrap: wrap;
|
||||
outline: none;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
position: relative;
|
||||
max-width: 60vw;
|
||||
}
|
||||
|
||||
.message-body-span-text {
|
||||
/* width: 434rpx; */
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
line-height: 42rpx;
|
||||
}
|
||||
|
||||
.message-body-span-link {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.message-body-span-link {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.message-body-span-link {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.custom-content-text {
|
||||
font-family: PingFangSC-Regular;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
font-size: 28rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.custom-content-hyperlinks {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: #006EFF;
|
||||
letter-spacing: 0;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
.custom-tip-message {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
font-size: 28rpx;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
max-width:95vw;
|
||||
background: none;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.custom-tip-message .message-body-span-text{
|
||||
max-width:95vw;
|
||||
min-width: 60vw;
|
||||
height: 40rpx;
|
||||
text-align: center;
|
||||
background: #E1E1E1;
|
||||
}
|
||||
.message-body-span-desc{
|
||||
margin-top: 30rpx;
|
||||
width:90vw;
|
||||
font-size: 24rpx;
|
||||
text-align: center;
|
||||
font-family: PingFangSC-Regular;
|
||||
color: #666666;
|
||||
line-height: 36rpx;
|
||||
}
|
||||
.commentbox{
|
||||
margin-top: 30rpx;
|
||||
width:590rpx;
|
||||
height:240rpx;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 0 10rpx 0 #ccc;
|
||||
}
|
||||
.commentbox .title{
|
||||
padding: 15rpx 0;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
font-weight: 400;
|
||||
|
||||
color: #333333;
|
||||
}
|
||||
.commentbox .ratebox{
|
||||
width:100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
.commentbox .button{
|
||||
height: 75rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background:#ebf9f8;
|
||||
font-weight:500;
|
||||
font-size: 34rpx;
|
||||
color: #3CC7C0;
|
||||
}
|
||||
.custom_wrap{
|
||||
display: flex;
|
||||
width:100%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.your-custom{
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.custom_wrap .custom-tip-message{
|
||||
margin:0 auto;
|
||||
}
|
||||
/* 开具处方样式 */
|
||||
.gdxz_custom_order_prescribe_message{
|
||||
width: 60vw;
|
||||
position: relative;
|
||||
border-radius: 10px 10px 10px 10px;
|
||||
background: rgb(255, 255, 255);
|
||||
border: 1rpx solid #D8D8D8;
|
||||
/* background: rgb(255, 255, 255);
|
||||
border: 1rpx solid #E7E7E7; */
|
||||
}
|
||||
.gdxz_custom_order_prescribe_message::after{
|
||||
content:'';
|
||||
position: absolute;
|
||||
top: 35rpx;
|
||||
left: 0;
|
||||
transform: translate(-50%,-50%) rotate(45deg);
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
background: rgb(255, 255, 255);
|
||||
border: 1rpx solid #D8D8D8;
|
||||
border-style: none none solid solid
|
||||
}
|
||||
.prescribe_title{
|
||||
font-size: 34rpx;
|
||||
border-bottom: 1px solid #E7E7E7;
|
||||
margin: 0 20rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
.prescribe_box{
|
||||
margin: 0 20rpx;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.prescribe_box_top_pharmacist_verify_time{
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
.prescribe_box_bottom{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.prescribe_box_buy{
|
||||
margin: 20rpx 20rpx 0 20rpx;
|
||||
background-color: #3CC7C0;
|
||||
color: #fff;
|
||||
padding: 15rpx 30rpx;
|
||||
border-radius: 40rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
/* 糖组检测 */
|
||||
|
||||
.back{
|
||||
width:24rpx;
|
||||
height:48rpx;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.sugarbox{
|
||||
|
||||
position: relative;
|
||||
width: 420rpx;
|
||||
background: rgb(212, 239, 241);
|
||||
border: 1rpx solid #1ACAD3;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
.sugarbox::after{
|
||||
content:'';
|
||||
position: absolute;
|
||||
top: 35rpx;
|
||||
right: -19rpx;
|
||||
transform: translate(-50%,-50%) rotate(-135deg);
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
background: rgb(212, 239, 241);
|
||||
border: 1rpx solid #1ACAD3;
|
||||
border-style: none none solid solid
|
||||
}
|
||||
.sugarcon{
|
||||
margin:0rpx 24rpx 0;
|
||||
|
||||
}
|
||||
.patient_info{
|
||||
font-size: 28rpx;
|
||||
font-weight: 400;
|
||||
color: rgba(0,0,0,0.65);
|
||||
line-height: 40rpx;
|
||||
}
|
||||
.sugarcon{
|
||||
border-bottom: 1rpx solid rgba(0,0,0,0.12);
|
||||
padding-bottom: 24rpx;
|
||||
}
|
||||
.sugarcon .title{
|
||||
margin:24rpx 0 20rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: #3CC7C0;
|
||||
}
|
||||
.sugarbox .detail{
|
||||
display: flex;
|
||||
margin:0 24rpx;
|
||||
height:88rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 400;
|
||||
color: rgba(0,0,0,0.85);
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
import { emojiName, emojiUrl, emojiMap } from '../../../../../utils/emojiMap';
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
emojiList: [],
|
||||
},
|
||||
|
||||
lifetimes: {
|
||||
attached() {
|
||||
for (let i = 0; i < emojiName.length; i++) {
|
||||
this.data.emojiList.push({
|
||||
emojiName: emojiName[i],
|
||||
url: emojiUrl + emojiMap[emojiName[i]],
|
||||
});
|
||||
}
|
||||
this.setData({
|
||||
emojiList: this.data.emojiList,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
handleEnterEmoji(event) {
|
||||
this.triggerEvent('enterEmoji', {
|
||||
message: event.currentTarget.dataset.name,
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
<scroll-view scroll-y="true" enable-flex="true" class="TUI-Emoji">
|
||||
<view class="TUI-emoji-image" wx:for="{{emojiList}}" wx:key="index" >
|
||||
<image data-name="{{item.emojiName}}" src="{{item.url}}" bindtap="handleEnterEmoji" />
|
||||
</view>>
|
||||
</scroll-view>
|
||||
@ -0,0 +1,19 @@
|
||||
.TUI-Emoji {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-left: 4vw;
|
||||
}
|
||||
|
||||
.TUI-emoji-image {
|
||||
width: 9vw;
|
||||
height: 9vw;
|
||||
margin: 2vw;
|
||||
}
|
||||
|
||||
.TUI-emoji-image > image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
renderDom: this.parseFace(newVal),
|
||||
});
|
||||
},
|
||||
},
|
||||
isMine: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
renderDom: [],
|
||||
percent: 0,
|
||||
faceUrl: 'https://web.sdk.qcloud.com/im/assets/face-elem/',
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
// 解析face 消息
|
||||
parseFace(message) {
|
||||
// 兼容android的大表情格式
|
||||
if (message.payload.data.indexOf('@2x') < 0) {
|
||||
message.payload.data = `${message.payload.data}@2x`;
|
||||
}
|
||||
const renderDom = {
|
||||
src: `${this.data.faceUrl + message.payload.data}.png`,
|
||||
};
|
||||
return renderDom;
|
||||
},
|
||||
|
||||
previewImage() {
|
||||
wx.previewImage({
|
||||
current: this.data.renderDom[0].src, // 当前显示图片的http链接
|
||||
urls: [this.data.renderDom[0].src],
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
<view class="TUI-faceMessage" bindtap="previewImage">
|
||||
<image class="face-message" src="{{renderDom.src}}" />
|
||||
</view>
|
||||
@ -0,0 +1,13 @@
|
||||
.TUI-faceMessage {
|
||||
width: 150px;
|
||||
height: 110px;
|
||||
max-width: 60vw;
|
||||
}
|
||||
.face-message {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 10px 10px 10px 10px;
|
||||
}
|
||||
.my-image {
|
||||
border-radius: 10px 2px 10px 10px;
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
filePayload: newVal.payload,
|
||||
});
|
||||
},
|
||||
},
|
||||
isMine: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
Show: false,
|
||||
filePayload: {},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
download() {
|
||||
this.setData({
|
||||
Show: true,
|
||||
});
|
||||
},
|
||||
downloadConfirm() {
|
||||
wx.downloadFile({
|
||||
url: this.data.filePayload.fileUrl,
|
||||
success(res) {
|
||||
const filePath = res.tempFilePath;
|
||||
wx.openDocument({
|
||||
filePath,
|
||||
success() {
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
cancel() {
|
||||
this.setData({
|
||||
Show: false,
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
<view class="TUI-fileMessage">
|
||||
<view class="fileMessage">
|
||||
<view class="fileMessage-box">
|
||||
<image class="file-icon" src="../../../../static/images/file.png" />
|
||||
<label bindtap="download" class="file-title">{{filePayload.fileName}}</label>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pop" wx:if="{{Show}}">
|
||||
<view class="text-box">
|
||||
<text class="download-confirm" catchtap="downloadConfirm">下载</text>
|
||||
</view>
|
||||
<view class="text-box">
|
||||
<text class="abandon" bindtap="cancel">取消</text>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,57 @@
|
||||
.TUI-fileMessage {
|
||||
display: flex;
|
||||
padding: 10rpx 24rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 2px 10px 10px 10px;
|
||||
border: 1px solid #D9D9D9;
|
||||
}
|
||||
.fileMessage{
|
||||
display: flex;
|
||||
}
|
||||
.fileMessage-box{
|
||||
display: flex;
|
||||
background: white;
|
||||
align-items: center;
|
||||
height: 150rpx;
|
||||
}
|
||||
.file-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
.pop{
|
||||
position: fixed;
|
||||
width: 50%;
|
||||
bottom: 400rpx;
|
||||
margin-left: 90rpx;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
z-index: 99999;
|
||||
}
|
||||
.text-box{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 112rpx;
|
||||
}
|
||||
.download-confirm{
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 16px;
|
||||
color: #E85454;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
line-height: 22px;
|
||||
}
|
||||
.abandon{
|
||||
opacity: 0.8;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
line-height: 22px;
|
||||
}
|
||||
.file-title {
|
||||
max-width: 53vw;
|
||||
display: inline;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
import { parseImage } from '../../../../../utils/message-parse';
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
renderDom: parseImage(newVal),
|
||||
percent: newVal.percent,
|
||||
});
|
||||
},
|
||||
},
|
||||
isMine: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
renderDom: [],
|
||||
percent: 0,
|
||||
showSave: false,
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
previewImage() {
|
||||
wx.previewImage({
|
||||
current: this.data.renderDom[0].src, // 当前显示图片的http链接
|
||||
urls: [this.data.renderDom[0].src], // 图片链接必须是数组
|
||||
success: () => {
|
||||
this.setData({
|
||||
showSave: true,
|
||||
});
|
||||
},
|
||||
complete: () => {
|
||||
this.setData({
|
||||
showSave: false,
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-image": "@vant/weapp/image/index",
|
||||
"van-loading": "@vant/weapp/loading/index"
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
<view class="TUI-ImageMessage" bindtap="previewImage">
|
||||
<!-- <image class="image-message {{isMine?'my-image':''}}" mode="aspectFill" src="{{renderDom[0].src}}" />
|
||||
<image wx:if="{{showSave}}" class="image-message {{isMine?'my-image':''}}" mode="aspectFill" src="{{renderDom[0].src}}" show-menu-by-longpress="{{true}}"/> -->
|
||||
|
||||
<van-image use-loading-slot fit="cover" class="image-message {{isMine?'my-image':''}}" width="100%" height="100" src="{{renderDom[0].src}}" radius="6px">
|
||||
<van-loading slot="loading" type="spinner" size="20" vertical />
|
||||
</van-image>
|
||||
|
||||
|
||||
|
||||
<van-image wx:if="{{showSave}}" use-loading-slot fit="cover" class="image-message {{isMine?'my-image':''}}" width="100%" height="100" src="{{renderDom[0].src}}" radius="6px" show-menu-by-longpress="{{true}}">
|
||||
<van-loading slot="loading" type="spinner" size="20" vertical />
|
||||
</van-image>
|
||||
</view>
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
.TUI-ImageMessage {
|
||||
width: 150px;
|
||||
}
|
||||
.image-message {
|
||||
width: 100%;
|
||||
max-height: 300rpx;
|
||||
height: 300rpx;
|
||||
border-radius: 10px 10px 10px 10px;
|
||||
}
|
||||
.my-image {
|
||||
height: 300rpx;
|
||||
border-radius: 10px 10px 10px 10px;
|
||||
}
|
||||
.big-image {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
position: fix;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
van-image__error, .van-image__img, .van-image__loading {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
message: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
isMine: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
<!--TUI-CustomerService/components/tui-chat/message-elements/relay-message/index.wxml-->
|
||||
<text class="message-body-span text-message">[聊天记录]</text>
|
||||
@ -0,0 +1,21 @@
|
||||
/* TUI-CustomerService/components/tui-chat/message-elements/relay-message/index.wxss */
|
||||
.message-body-span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/*justify-content: flex-start;*/
|
||||
flex-wrap: wrap;
|
||||
outline: none;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
position: relative;
|
||||
max-width: 60vw;
|
||||
}
|
||||
.text-message {
|
||||
display: inline-flex;
|
||||
max-width: 60vw;
|
||||
line-height: 52rpx;
|
||||
padding: 12rpx 24rpx;
|
||||
background: #F8F8F8;
|
||||
border: 1px solid #D9D9D9;
|
||||
border-radius: 2px 10px 10px 10px;
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
message: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
isMine: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
message: ''
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
resendMessage(e) {
|
||||
this.triggerEvent('resendMessage', {
|
||||
message: e.currentTarget.dataset.value.payload.text
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
<view class="revoke" data-value="{{message}}">
|
||||
<label class="name" wx:if="{{message.flow === 'in'}}">{{message.nick || message.from}}</label>
|
||||
<label class="name" wx:else>你</label>
|
||||
<span class="name">撤回了一条消息</span>
|
||||
<span class="edit" wx:if="{{message.flow === 'out' && message.type === 'TIMTextElem'}}" bindtap="resendMessage" data-value="{{message}}">重新编辑</span>
|
||||
</view>
|
||||
@ -0,0 +1,18 @@
|
||||
|
||||
.revoke{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center
|
||||
}
|
||||
.name {
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
padding: 6px 0px;
|
||||
}
|
||||
.edit{
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 14px;
|
||||
color: #006eff;
|
||||
letter-spacing: 0;
|
||||
padding-left: 8px
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
import { parseGroupSystemNotice } from '../../../../../utils/message-parse';
|
||||
import { caculateTimeago } from '../../../../../utils/common';
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
message: newVal,
|
||||
messageTime: caculateTimeago(newVal.time * 1000),
|
||||
renderDom: parseGroupSystemNotice(newVal),
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
message: {},
|
||||
options: '处理',
|
||||
messageTime: '',
|
||||
renderDom: '',
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
// 在组件实例进入页面节点树时执行
|
||||
},
|
||||
detached() {
|
||||
// 在组件实例被从页面节点树移除时执行
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
handleClick() {
|
||||
wx.showActionSheet({
|
||||
itemList: ['同意', '拒绝'],
|
||||
success: (res) => {
|
||||
this.triggerEvent('changeSystemMessageList', {
|
||||
message: this.data.message,
|
||||
});
|
||||
const option = {
|
||||
handleAction: 'Agree',
|
||||
handleMessage: '欢迎进群',
|
||||
message: this.data.message,
|
||||
};
|
||||
if (res.tapIndex === 1) {
|
||||
this.triggerEvent('changeSystemMessageList', {
|
||||
message: this.data.message,
|
||||
});
|
||||
option.handleAction = 'Reject';
|
||||
option.handleMessage = '拒绝申请';
|
||||
}
|
||||
wx.$TUIKit.handleGroupApplication(option)
|
||||
.then(() => {
|
||||
wx.showToast({ title: option.handleAction === 'Agree' ? '已同意申请' : '已拒绝申请' });
|
||||
})
|
||||
.catch((error) => {
|
||||
wx.showToast({
|
||||
title: error.message || '处理失败',
|
||||
icon: 'none',
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
<view class="container">
|
||||
<view wx:if="{{message.payload.operationType === 1}}" class="card handle">
|
||||
<view>
|
||||
<view class="time" >{{messageTime}}</view>
|
||||
{{renderDom}}
|
||||
</view>
|
||||
<view class="choose">
|
||||
<view class="button" bindtap="handleClick"> {{options}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card" wx:else>
|
||||
<view class="time">{{messageTime}}</view>
|
||||
{{renderDom}}
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,24 @@
|
||||
.handle {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.card{
|
||||
font-size: 14px;
|
||||
margin: 20px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #abdcff;
|
||||
background-color: #f0faff;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.time {
|
||||
|
||||
}
|
||||
.button{
|
||||
color: blue;
|
||||
border-radius: 8px;
|
||||
line-height: 30px;
|
||||
font-size: 16px;
|
||||
width: 70px;
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
import { parseText } from '../../../../../utils/message-parse';
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
// console.log(parseText(newVal));
|
||||
this.setData({
|
||||
renderDom: parseText(newVal),
|
||||
});
|
||||
},
|
||||
},
|
||||
isMine: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
renderDom:[]
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
// 在组件实例进入页面节点树时执行
|
||||
},
|
||||
detached() {
|
||||
// 在组件实例被从页面节点树移除时执行
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
<wxs src="../../../../../../../filters/filter.wxs" module="module"></wxs>
|
||||
<!-- <view >{{ module.toS(renderDom)}}</view> -->
|
||||
<view class="text-message {{isMine?'my-text':'your-text'}}" >
|
||||
|
||||
<view class="message-body-span" wx:for="{{renderDom}}" wx:key="index">
|
||||
<span class="message-body-span-text" wx:if="{{item.name === 'span'}}">{{item.text}}</span>
|
||||
<image wx:if="{{item.name === 'img'}}" class="emoji-icon" src="{{item.src}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,80 @@
|
||||
.text-message {
|
||||
max-width: 60vw;
|
||||
min-height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
padding: 10rpx 24rpx;
|
||||
background: #F8F8F8;
|
||||
border: 1rpx solid #D9D9D9;
|
||||
border-radius: 2px 10px 10px 10px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.my-text {
|
||||
position: relative;
|
||||
border-radius: 10px 10px 10px 10px;
|
||||
background: rgb(212, 239, 241);
|
||||
border: 1rpx solid #1ACAD3;
|
||||
}
|
||||
.my-text::after{
|
||||
content:'';
|
||||
position: absolute;
|
||||
top: 35rpx;
|
||||
right: -19rpx;
|
||||
transform: translate(-50%,-50%) rotate(-135deg);
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
background: rgb(212, 239, 241);
|
||||
border: 1rpx solid #1ACAD3;
|
||||
border-style: none none solid solid
|
||||
}
|
||||
.your-text {
|
||||
position: relative;
|
||||
border-radius: 10px 10px 10px 10px;
|
||||
background: rgb(255, 255, 255);
|
||||
border: 1rpx solid #D8D8D8;
|
||||
}
|
||||
.your-text::after{
|
||||
content:'';
|
||||
position: absolute;
|
||||
top: 35rpx;
|
||||
left: 0;
|
||||
transform: translate(-50%,-50%) rotate(45deg);
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
background: rgb(255, 255, 255);
|
||||
border: 1rpx solid #D8D8D8;
|
||||
border-style: none none solid solid
|
||||
}
|
||||
.message-body-span {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
/*justify-content: flex-start;*/
|
||||
flex-wrap: wrap;
|
||||
word-break: break-word;
|
||||
outline: none;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
position: relative;
|
||||
max-width: 60vw;
|
||||
}
|
||||
.message-body-span-text {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
line-height: 40rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.message-body-span-image {
|
||||
display: inline-block;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin: 0 4rpx;
|
||||
}
|
||||
.emoji-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
import { parseGroupTip } from '../../../../../utils/message-parse';
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
renderDom: parseGroupTip(newVal),
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
// 在组件实例进入页面节点树时执行
|
||||
},
|
||||
detached() {
|
||||
// 在组件实例被从页面节点树移除时执行
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
<view class="tip-message">
|
||||
<view class="text-message">{{renderDom[0].text}}</view>
|
||||
</view>
|
||||
@ -0,0 +1,9 @@
|
||||
.tip-message {
|
||||
width: 100%;
|
||||
}
|
||||
.text-message {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
import { parseVideo } from '../../../../../utils/message-parse';
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
message: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
message: newVal,
|
||||
renderDom: parseVideo(newVal),
|
||||
});
|
||||
},
|
||||
},
|
||||
isMine: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
message: {},
|
||||
showSaveFlag: Number,
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
showVideoFullScreenChange(event) {
|
||||
if (event.detail.fullScreen) {
|
||||
this.setData({
|
||||
showSaveFlag: 1,
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
showSaveFlag: 2,
|
||||
});
|
||||
}
|
||||
},
|
||||
// 1代表当前状态处于全屏,2代表当前状态不处于全屏。
|
||||
handleLongPress(e) {
|
||||
if (this.data.showSaveFlag === 1) {
|
||||
wx.showModal({
|
||||
content: '确认保存该视频?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.downloadFile({
|
||||
url: this.data.message.payload.videoUrl,
|
||||
success(res) {
|
||||
// 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
|
||||
if (res.statusCode === 200) {
|
||||
wx.saveVideoToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success() {
|
||||
wx.showToast({
|
||||
title: '保存成功!',
|
||||
duration: 800,
|
||||
icon: 'none',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
fail(error) {
|
||||
wx.showToast({
|
||||
title: '保存失败!',
|
||||
duration: 800,
|
||||
icon: 'none',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
<view class="video-message" >
|
||||
<video class="video-box {{isMine?'my-video':''}}" src="{{renderDom[0].src}}"
|
||||
poster="{{message.payload.thumbUrl}}" error="videoError" bindfullscreenchange="showVideoFullScreenChange"
|
||||
bind:longpress="handleLongPress"></video>
|
||||
</view>
|
||||
@ -0,0 +1,12 @@
|
||||
.video-message {
|
||||
width: 150px;
|
||||
height: 110px;
|
||||
max-width: 60vw;
|
||||
}
|
||||
.video-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.my-video {
|
||||
border-radius: 10px 2px 10px 10px;
|
||||
}
|
||||
@ -0,0 +1,987 @@
|
||||
import logger from '../../../../utils/logger';
|
||||
import constant from '../../../../utils/constant';
|
||||
import {
|
||||
finishConsult
|
||||
} from "../../../../../../api/consultOrder"
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
conversation: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
conversation: newVal,
|
||||
},()=>{
|
||||
//this.getMessageone(this.data.conversation)
|
||||
});
|
||||
},
|
||||
},
|
||||
order_inquiry_id: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
order_inquiry_id:newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
inquiry_type: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
inquiry_type:newVal
|
||||
});
|
||||
},
|
||||
},
|
||||
patient_family_data:{
|
||||
type: Object,
|
||||
value:{},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
patient_family_data:newVal
|
||||
});
|
||||
},
|
||||
},
|
||||
msgData:{
|
||||
type: Object,
|
||||
value:{},
|
||||
observer(newVal) {
|
||||
|
||||
this.setData({
|
||||
msgData:newVal
|
||||
},()=>{
|
||||
|
||||
//console.log(newVal);
|
||||
// this.setMsgRound();
|
||||
});
|
||||
},
|
||||
},
|
||||
message_rounds:{
|
||||
type: Number,
|
||||
value: 0,
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
message_rounds:newVal
|
||||
});
|
||||
},
|
||||
},
|
||||
times_number:{
|
||||
type: Number,
|
||||
value: 0,
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
times_number:newVal
|
||||
},()=>{
|
||||
|
||||
});
|
||||
},
|
||||
},
|
||||
duration:{
|
||||
type: Number,
|
||||
value: 0,
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
duration:newVal
|
||||
});
|
||||
},
|
||||
},
|
||||
rest_time:{
|
||||
type: Number,
|
||||
value: 0,
|
||||
rest_time(newVal) {
|
||||
this.setData({
|
||||
rest_time:newVal
|
||||
},()=>{
|
||||
//console.log('剩余时间:'+newVal)
|
||||
});
|
||||
},
|
||||
},
|
||||
hasCallKit: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
observer(hasCallKit) {
|
||||
this.setData({
|
||||
hasCallKit,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
conversation: {},
|
||||
showCustomer:false,
|
||||
order_inquiry_id:'',
|
||||
inquiry_type:'',
|
||||
patient_family_data:{},
|
||||
message: '',
|
||||
message_rounds:0,
|
||||
times_number:0,//总共回合数
|
||||
msgData:{},
|
||||
rest_time:0,
|
||||
duration:0,
|
||||
hideText:false,
|
||||
showTip:true,
|
||||
|
||||
extensionArea: false,
|
||||
sendMessageBtn: false,
|
||||
displayFlag: '',
|
||||
isAudio: false,
|
||||
bottomVal: 0,
|
||||
startPoint: 0,
|
||||
popupToggle: false,
|
||||
isRecording: false,
|
||||
canSend: true,
|
||||
text: '按住说话',
|
||||
title: ' ',
|
||||
notShow: false,
|
||||
isShow: true,
|
||||
commonFunction: [
|
||||
{ name: '常用语', key: '0' },
|
||||
{ name: '发送订单', key: '1' },
|
||||
{ name: '服务评价', key: '2' },
|
||||
],
|
||||
displayServiceEvaluation: false,
|
||||
showErrorImageFlag: 0,
|
||||
messageList: [],
|
||||
isFirstSendTyping: true,
|
||||
time: 0,
|
||||
focus: false,
|
||||
isEmoji: false,
|
||||
fileList: [],
|
||||
hasCallKit: false,
|
||||
},
|
||||
|
||||
lifetimes: {
|
||||
attached() {
|
||||
|
||||
|
||||
// 加载声音录制管理器
|
||||
this.recorderManager = wx.getRecorderManager();
|
||||
this.recorderManager.onStop((res) => {
|
||||
wx.hideLoading();
|
||||
if (this.data.canSend) {
|
||||
if (res.duration < 1000) {
|
||||
wx.showToast({
|
||||
title: '录音时间太短',
|
||||
icon: 'none',
|
||||
});
|
||||
} else {
|
||||
// res.tempFilePath 存储录音文件的临时路径
|
||||
const message = wx.$TUIKit.createAudioMessage({
|
||||
to: this.getToAccount(),
|
||||
conversationType: this.data.conversation.type,
|
||||
payload: {
|
||||
file: res,
|
||||
},
|
||||
});
|
||||
this.$sendTIMMessage(message);
|
||||
}
|
||||
}
|
||||
this.setData({
|
||||
startPoint: 0,
|
||||
popupToggle: false,
|
||||
isRecording: false,
|
||||
canSend: true,
|
||||
title: ' ',
|
||||
text: '按住说话',
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
ready(){
|
||||
// wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.SDK_READY,this.$onMessageReady,this);
|
||||
},
|
||||
detached() {
|
||||
// 一定要解除相关的事件绑定
|
||||
//wx.$TUIKit.off(wx.$TUIKitTIM.EVENT.SDK_READY, this.$onMessageReady,this);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
showTooltip(){
|
||||
this.setData({
|
||||
showTip:!this.data.showTip,
|
||||
});
|
||||
},
|
||||
handlefinishConsult(){
|
||||
let {order_inquiry_id}=this.data;
|
||||
finishConsult(order_inquiry_id).then(data=>{
|
||||
this.triggerEvent("freshChatStatus",order_inquiry_id)
|
||||
})
|
||||
},
|
||||
getMessageone(conversation){
|
||||
wx.$TUIKit.getMessageListHopping({
|
||||
conversationID: conversation.conversationID,
|
||||
direction: 0,
|
||||
count: 1,
|
||||
}).then((res) => {
|
||||
console.log("one");
|
||||
console.log(res);
|
||||
const { messageList } = res.data;
|
||||
this.getLatestMessageList(messageList);
|
||||
});
|
||||
},
|
||||
// 获取消息列表来判断是否发送正在输入状态
|
||||
getMessageList(conversation) {
|
||||
wx.$TUIKit.getMessageList({
|
||||
conversationID: conversation.conversationID,
|
||||
nextReqMessageID: this.data.nextReqMessageID,
|
||||
count: 15,
|
||||
}).then((res) => {
|
||||
const { messageList } = res.data;
|
||||
this.setData({
|
||||
messageList,
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
// 打开录音开关
|
||||
switchAudio() {
|
||||
this.setData({
|
||||
isAudio: !this.data.isAudio,
|
||||
isEmoji: false,
|
||||
text: '按住说话',
|
||||
focus: false,
|
||||
});
|
||||
},
|
||||
|
||||
// 长按录音
|
||||
handleLongPress(e) {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'messageType',
|
||||
ext1: 'messageType-audio',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
this.recorderManager.start({
|
||||
duration: 60000, // 录音的时长,单位 ms,最大值 600000(10 分钟)
|
||||
sampleRate: 44100, // 采样率
|
||||
numberOfChannels: 1, // 录音通道数
|
||||
encodeBitRate: 192000, // 编码码率
|
||||
format: 'aac', // 音频格式,选择此格式创建的音频消息,可以在即时通信 IM 全平台(Android、iOS、微信小程序和Web)互通
|
||||
});
|
||||
this.setData({
|
||||
startPoint: e.touches[0],
|
||||
title: '正在录音',
|
||||
// isRecording : true,
|
||||
// canSend: true,
|
||||
notShow: true,
|
||||
isShow: false,
|
||||
isRecording: true,
|
||||
popupToggle: true,
|
||||
});
|
||||
},
|
||||
|
||||
// 录音时的手势上划移动距离对应文案变化
|
||||
handleTouchMove(e) {
|
||||
if (this.data.isRecording) {
|
||||
if (this.data.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 100) {
|
||||
this.setData({
|
||||
text: '抬起停止',
|
||||
title: '松开手指,取消发送',
|
||||
canSend: false,
|
||||
});
|
||||
} else if (this.data.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 20) {
|
||||
this.setData({
|
||||
text: '抬起停止',
|
||||
title: '上划可取消',
|
||||
canSend: true,
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
text: '抬起停止',
|
||||
title: '正在录音',
|
||||
canSend: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 手指离开页面滑动
|
||||
handleTouchEnd() {
|
||||
this.setData({
|
||||
isRecording: false,
|
||||
popupToggle: false,
|
||||
|
||||
});
|
||||
wx.hideLoading();
|
||||
this.recorderManager.stop();
|
||||
},
|
||||
// 选中表情消息
|
||||
handleEmoji() {
|
||||
let targetFlag = 'emoji';
|
||||
if (this.data.displayFlag === 'emoji') {
|
||||
targetFlag = '';
|
||||
}
|
||||
this.setData({
|
||||
isAudio: false,
|
||||
isEmoji: true,
|
||||
displayFlag: targetFlag,
|
||||
focus: false,
|
||||
});
|
||||
},
|
||||
|
||||
// 选自定义消息
|
||||
handleExtensions() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'chooseExtensions',
|
||||
ext1: 'chooseExtensions',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
let targetFlag = 'extension';
|
||||
if (this.data.displayFlag === 'extension') {
|
||||
targetFlag = '';
|
||||
}
|
||||
this.setData({
|
||||
displayFlag: targetFlag,
|
||||
});
|
||||
},
|
||||
|
||||
error(e) {
|
||||
console.log(e.detail);
|
||||
},
|
||||
|
||||
handleSendPicture() {
|
||||
this.sendMediaMessage('camera', 'image');
|
||||
},
|
||||
|
||||
handleSendImage() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'messageType',
|
||||
ext1: 'messageType-image',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
this.sendMediaMessage('album', 'image');
|
||||
},
|
||||
|
||||
sendMediaMessage(type, mediaType) {
|
||||
if(this.setMsgRound()){
|
||||
const { fileList } = this.data;
|
||||
wx.chooseMedia({
|
||||
count: 9,
|
||||
sourceType: [type],
|
||||
mediaType: [mediaType],
|
||||
success: (res) => {
|
||||
this.sendCallback();
|
||||
const mediaInfoList = res.tempFiles;
|
||||
mediaInfoList.forEach((mediaInfo) => {
|
||||
fileList.push({ type: res.type, tempFiles: [{ tempFilePath: mediaInfo.tempFilePath }] });
|
||||
});
|
||||
fileList.forEach((file) => {
|
||||
if (file.type === 'image') {
|
||||
this.handleSendImageMessage(file);
|
||||
}
|
||||
if (file.type === 'video') {
|
||||
this.handleSendVideoMessage(file);
|
||||
}
|
||||
});
|
||||
this.data.fileList = [];
|
||||
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// 发送图片消息
|
||||
handleSendImageMessage(file) {
|
||||
const message = wx.$TUIKit.createImageMessage({
|
||||
to: this.getToAccount(),
|
||||
conversationType: this.data.conversation.type,
|
||||
payload: {
|
||||
file,
|
||||
},
|
||||
cloudCustomData: JSON.stringify({
|
||||
order_inquiry_id:this.data.order_inquiry_id,
|
||||
inquiry_type:this.data.inquiry_type,
|
||||
message_rounds:this.data.msgData.msg_round,
|
||||
patient_family_data:this.data.patient_family_data,
|
||||
is_system:0
|
||||
}),
|
||||
onProgress: (percent) => {
|
||||
message.percent = percent;
|
||||
},
|
||||
});
|
||||
this.$sendTIMMessage(message);
|
||||
},
|
||||
|
||||
// 发送视频消息
|
||||
handleSendVideoMessage(file) {
|
||||
const message = wx.$TUIKit.createVideoMessage({
|
||||
to: this.getToAccount(),
|
||||
conversationType: this.data.conversation.type,
|
||||
payload: {
|
||||
file,
|
||||
},
|
||||
onProgress: (percent) => {
|
||||
message.percent = percent;
|
||||
},
|
||||
});
|
||||
this.$sendTIMMessage(message);
|
||||
},
|
||||
|
||||
handleShootVideo() {
|
||||
this.sendMediaMessage('camera', 'video');
|
||||
},
|
||||
|
||||
handleSendVideo() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'messageType',
|
||||
ext1: 'messageType-video',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
this.sendMediaMessage('album', 'video');
|
||||
},
|
||||
|
||||
handleCommonFunctions(e) {
|
||||
switch (e.target.dataset.function.key) {
|
||||
case '0':
|
||||
this.setData({
|
||||
displayCommonWords: true,
|
||||
});
|
||||
break;
|
||||
case '1':
|
||||
this.setData({
|
||||
displayOrderList: true,
|
||||
});
|
||||
break;
|
||||
case '2':
|
||||
this.setData({
|
||||
displayServiceEvaluation: true,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handleSendOrder() {
|
||||
this.setData({
|
||||
displayOrderList: true,
|
||||
});
|
||||
},
|
||||
|
||||
appendMessage(e) {
|
||||
this.setData({
|
||||
message: this.data.message + e.detail.message,
|
||||
sendMessageBtn: true,
|
||||
hideText:true
|
||||
});
|
||||
},
|
||||
|
||||
getToAccount() {
|
||||
if (!this.data.conversation || !this.data.conversation.conversationID) {
|
||||
return '';
|
||||
}
|
||||
switch (this.data.conversation.type) {
|
||||
case wx.$TUIKitTIM.TYPES.CONV_C2C:
|
||||
return this.data.conversation.conversationID.replace(wx.$TUIKitTIM.TYPES.CONV_C2C, '');
|
||||
case wx.$TUIKitTIM.TYPES.CONV_GROUP:
|
||||
return this.data.conversation.conversationID.replace(wx.$TUIKitTIM.TYPES.CONV_GROUP, '');
|
||||
default:
|
||||
return this.data.conversation.conversationID;
|
||||
}
|
||||
},
|
||||
async handleCheckAuthorize(e) {
|
||||
const type = e.currentTarget.dataset.value;
|
||||
wx.getSetting({
|
||||
success: async (res) => {
|
||||
const isRecord = res.authSetting['scope.record'];
|
||||
const isCamera = res.authSetting['scope.camera'];
|
||||
if (!isRecord && type === 1) {
|
||||
const title = '麦克风权限授权';
|
||||
const content = '使用语音通话,需要在设置中对麦克风进行授权允许';
|
||||
try {
|
||||
await wx.authorize({ scope: 'scope.record' });
|
||||
this.handleCalling(e);
|
||||
} catch (e) {
|
||||
this.handleShowModal(title, content);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((!isRecord || !isCamera) && type === 2) {
|
||||
const title = '麦克风、摄像头权限授权';
|
||||
const content = '使用视频通话,需要在设置中对麦克风、摄像头进行授权允许';
|
||||
try {
|
||||
await wx.authorize({ scope: 'scope.record' });
|
||||
await wx.authorize({ scope: 'scope.camera' });
|
||||
this.handleCalling(e);
|
||||
} catch (e) {
|
||||
this.handleShowModal(title, content);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.handleCalling(e);
|
||||
},
|
||||
});
|
||||
},
|
||||
handleShowModal(title, content) {
|
||||
wx.showModal({
|
||||
title,
|
||||
content,
|
||||
confirmText: '去设置',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.openSetting();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
handleCalling(e) {
|
||||
if (!this.data.hasCallKit) {
|
||||
wx.showToast({
|
||||
title: '请先集成 TUICallKit 组件',
|
||||
icon: 'none',
|
||||
});
|
||||
return;
|
||||
}
|
||||
const type = e.currentTarget.dataset.value;
|
||||
const conversationType = this.data.conversation.type;
|
||||
if (conversationType === wx.$TUIKitTIM.TYPES.CONV_GROUP) {
|
||||
if (type === 1) {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'audioCall',
|
||||
ext1: 'audioCall-group',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
} else if (type === 2) {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'videoCall',
|
||||
ext1: 'videoCall-group',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
}
|
||||
this.triggerEvent('handleCall', {
|
||||
type,
|
||||
conversationType,
|
||||
});
|
||||
}
|
||||
if (conversationType === wx.$TUIKitTIM.TYPES.CONV_C2C) {
|
||||
const { userID } = this.data.conversation.userProfile;
|
||||
if (type === 1) {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'audioCall',
|
||||
ext1: 'audioCall-1v1',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
} else if (type === 2) {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'videoCall',
|
||||
ext1: 'videoCall-1v1',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
}
|
||||
this.triggerEvent('handleCall', {
|
||||
conversationType,
|
||||
type,
|
||||
userID,
|
||||
});
|
||||
}
|
||||
this.setData({
|
||||
displayFlag: '',
|
||||
});
|
||||
},
|
||||
orderMsg(){
|
||||
let that=this;
|
||||
wx.requestSubscribeMessage({
|
||||
tmplIds: ['82rKSdbKkbFK_tHmIMnHyfyRJq9ujvmAsTjRHdxmCdE'],
|
||||
success (res) {
|
||||
that.setData({
|
||||
showCustomer:true
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
//发送成功之后回合数+1;
|
||||
sendCallback(){
|
||||
let {times_number,msgData}=this.data;
|
||||
let rounds=msgData.msg_round;
|
||||
if(msgData.msg_type==1){
|
||||
rounds=rounds+1;
|
||||
this.setData({
|
||||
'msgData.msg_round':rounds
|
||||
})
|
||||
};
|
||||
this.triggerEvent("getMessageRounds",{
|
||||
msg_round:rounds,
|
||||
msg_type:2
|
||||
});
|
||||
setTimeout(() => {
|
||||
if(times_number>=0){
|
||||
if(rounds==times_number){
|
||||
wx.showToast({
|
||||
title: '沟通已达到限制的'+times_number+'个回合',
|
||||
icon:"none"
|
||||
})
|
||||
this.triggerEvent("changeTimeStatus",true);
|
||||
this.handlefinishConsult();
|
||||
}
|
||||
};
|
||||
}, 300);
|
||||
|
||||
},
|
||||
setMsgRound(){
|
||||
let {duration,rest_time}=this.data;
|
||||
if(duration!=0 && rest_time==0){
|
||||
wx.showToast({
|
||||
title: '沟通时长已超过限制时间',
|
||||
icon:"none"
|
||||
})
|
||||
this.triggerEvent("changeTimeStatus",true);
|
||||
this.handlefinishConsult();
|
||||
return false;
|
||||
};
|
||||
return true
|
||||
|
||||
},
|
||||
//发送前获取最新的一条消息
|
||||
getLatestMessageList(messageList) {
|
||||
let list=messageList;
|
||||
if(list.length>0){
|
||||
const messageList =list[list.length-1];
|
||||
console.log(messageList);
|
||||
let customdata=JSON.parse(messageList.cloudCustomData);
|
||||
let msg_rounds=customdata.message_rounds;
|
||||
let from=messageList.flow;
|
||||
let type=messageList.type;
|
||||
this.setData({
|
||||
message_rounds:msg_rounds || 0
|
||||
});
|
||||
if(this.data.times_number>=0){
|
||||
let rest_rounds=this.data.times_number-this.data.message_rounds;
|
||||
this.triggerEvent("getMessageRounds",rest_rounds);
|
||||
}
|
||||
|
||||
|
||||
if(this.data.duration!=0 && this.data.rest_time==0){
|
||||
wx.showToast({
|
||||
title: '沟通时长已超过限制时间',
|
||||
icon:"none"
|
||||
})
|
||||
this.handlefinishConsult();
|
||||
return false;
|
||||
}
|
||||
if(this.data.times_number>=0){
|
||||
if(msg_rounds==this.data.times_number){
|
||||
wx.showToast({
|
||||
title: '沟通已达到限制的'+this.data.times_number+'个回合',
|
||||
icon:"none"
|
||||
})
|
||||
|
||||
this.handlefinishConsult();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(this.data.times_number>=0){
|
||||
if(from=="in" && type!="TIMCustomElem"){
|
||||
msg_rounds=msg_rounds+1;
|
||||
this.setData({
|
||||
message_rounds:msg_rounds
|
||||
})
|
||||
|
||||
}
|
||||
console.log("total:"+this.data.times_number,"message_rounds:"+this.data.message_rounds)
|
||||
let rest_rounds=this.data.times_number-this.data.message_rounds;
|
||||
this.triggerEvent("getMessageRounds",rest_rounds);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return true
|
||||
|
||||
},
|
||||
sendTextMessage(msg, flag) {
|
||||
if(!this.data.message){
|
||||
wx.showToast({
|
||||
title: '输入内容不能为空',
|
||||
icon:'none'
|
||||
})
|
||||
return false
|
||||
};
|
||||
if(this.setMsgRound()){
|
||||
wx.aegis.reportEvent({
|
||||
name: 'messageType',
|
||||
ext1: 'messageType-text',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
const to =this.getToAccount();
|
||||
const text = flag ? msg : this.data.message;
|
||||
const { FEAT_NATIVE_CODE } = constant;
|
||||
this.sendCallback();
|
||||
const message = wx.$TUIKit.createTextMessage({
|
||||
to,
|
||||
conversationType: this.data.conversation.type,
|
||||
payload: {
|
||||
text,
|
||||
},
|
||||
cloudCustomData: JSON.stringify({
|
||||
order_inquiry_id:this.data.order_inquiry_id,
|
||||
inquiry_type:this.data.inquiry_type,
|
||||
message_rounds:this.data.msgData.msg_round,
|
||||
patient_family_data:this.data.patient_family_data,
|
||||
is_system:0
|
||||
}),
|
||||
});
|
||||
this.setData({
|
||||
message: '',
|
||||
sendMessageBtn: false,
|
||||
hideText:false
|
||||
});
|
||||
|
||||
this.$sendTIMMessage(message);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
// 监听输入框value值变化
|
||||
onInputValueChange(event) {
|
||||
if (event.detail.message || event.detail.value) {
|
||||
this.setData({
|
||||
message: event.detail.message || event.detail.value,
|
||||
sendMessageBtn: true,
|
||||
hideText:true
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
sendMessageBtn: false,
|
||||
hideText:false
|
||||
});
|
||||
}
|
||||
//event.detail.value && this.sendTypingStatusMessage();
|
||||
},
|
||||
|
||||
// 发送正在输入状态消息
|
||||
sendTypingStatusMessage() {
|
||||
const { BUSINESS_ID_TEXT, FEAT_NATIVE_CODE } = constant;
|
||||
// 创建正在输入状态消息, "typingStatus":1,正在输入中1, 输入结束0, "version": 1 兼容老版本,userAction:0, // 14表示正在输入,actionParam:"EIMAMSG_InputStatus_Ing" //"EIMAMSG_InputStatus_Ing" 表示正在输入, "EIMAMSG_InputStatus_End" 表示输入结束
|
||||
const typingMessage = wx.$TUIKit.createCustomMessage({
|
||||
to: this.getToAccount(),
|
||||
conversationType: this.data.conversation.type,
|
||||
payload: {
|
||||
data: JSON.stringify({
|
||||
businessID: BUSINESS_ID_TEXT.USER_TYPING,
|
||||
typingStatus: FEAT_NATIVE_CODE.ISTYPING_STATUS,
|
||||
version: FEAT_NATIVE_CODE.NATIVE_VERSION,
|
||||
userAction: FEAT_NATIVE_CODE.ISTYPING_ACTION,
|
||||
actionParam: constant.TYPE_INPUT_STATUS_ING,
|
||||
}),
|
||||
description: '',
|
||||
extension: '',
|
||||
},
|
||||
cloudCustomData: JSON.stringify({
|
||||
order_inquiry_id:this.data.order_inquiry_id,
|
||||
inquiry_type:this.data.inquiry_type,
|
||||
message_rounds:this.data.msgData.msg_round,
|
||||
patient_family_data:this.data.patient_family_data,
|
||||
is_system:0
|
||||
}),
|
||||
});
|
||||
// 在消息列表中过滤出对方的消息,并且获取最新消息的时间。
|
||||
const inList = this.data.messageList.filter(item => item.flow === 'in');
|
||||
if (inList.length === 0) return;
|
||||
const sortList = inList.sort((firstItem, secondItem) => secondItem.time - firstItem.time);
|
||||
const newMessageTime = sortList[0].time * 1000;
|
||||
// 发送正在输入状态消息的触发条件。
|
||||
const isSendTypingMessage = this.data.messageList.every((item) => {
|
||||
try {
|
||||
const sendTypingMessage = JSON.parse(item.cloudCustomData);
|
||||
return sendTypingMessage.messageFeature.needTyping;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// 获取当前编辑时间,与收到对方最新的一条消息时间相比,时间小于30s则发送正在输入状态消息/
|
||||
const now = new Date().getTime();
|
||||
const timeDifference = (now - newMessageTime);
|
||||
|
||||
if (isSendTypingMessage && timeDifference > (1000 * 30)) return;
|
||||
if (this.data.isFirstSendTyping) {
|
||||
this.$sendTypingMessage(typingMessage);
|
||||
this.setData({
|
||||
isFirstSendTyping: false,
|
||||
});
|
||||
} else {
|
||||
this.data.time = setTimeout(() => {
|
||||
this.$sendTypingMessage(typingMessage);
|
||||
}, (1000 * 4));
|
||||
}
|
||||
},
|
||||
// 监听是否获取焦点,有焦点则向父级传值,动态改变input组件的高度。
|
||||
inputBindFocus(event) {
|
||||
this.setData({
|
||||
focus: true,
|
||||
});
|
||||
this.getMessageList(this.data.conversation);
|
||||
this.triggerEvent('pullKeysBoards', {
|
||||
event,
|
||||
});
|
||||
// 有焦点则关闭除键盘之外的操作界面,例如表情组件。
|
||||
this.handleClose();
|
||||
},
|
||||
|
||||
// 监听是否失去焦点
|
||||
inputBindBlur(event) {
|
||||
const { BUSINESS_ID_TEXT, FEAT_NATIVE_CODE } = constant;
|
||||
const typingMessage = wx.$TUIKit.createCustomMessage({
|
||||
to: this.getToAccount(),
|
||||
conversationType: this.data.conversation.type,
|
||||
payload: {
|
||||
data: JSON.stringify({
|
||||
businessID: BUSINESS_ID_TEXT.USER_TYPING,
|
||||
typingStatus: FEAT_NATIVE_CODE.NOTTYPING_STATUS,
|
||||
version: FEAT_NATIVE_CODE.NATIVE_VERSION,
|
||||
userAction: FEAT_NATIVE_CODE.NOTTYPING_ACTION,
|
||||
actionParam: constant.TYPE_INPUT_STATUS_END,
|
||||
}),
|
||||
cloudCustomData: JSON.stringify({ messageFeature:
|
||||
{
|
||||
needTyping: FEAT_NATIVE_CODE.FEAT_TYPING,
|
||||
version: FEAT_NATIVE_CODE.NATIVE_VERSION,
|
||||
},
|
||||
}),
|
||||
description: '',
|
||||
extension: '',
|
||||
},
|
||||
});
|
||||
//this.$sendTypingMessage(typingMessage);
|
||||
this.setData({
|
||||
isFirstSendTyping: true,
|
||||
});
|
||||
clearTimeout(this.data.time);
|
||||
this.triggerEvent('downKeysBoards', {
|
||||
event,
|
||||
});
|
||||
},
|
||||
|
||||
$handleSendTextMessage(event) {
|
||||
|
||||
this.sendTextMessage(event.detail.message, true);
|
||||
this.setData({
|
||||
displayCommonWords: false,
|
||||
});
|
||||
},
|
||||
|
||||
$handleSendCustomMessage(e) {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'messageType',
|
||||
ext1: 'messageType-custom',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
const message = wx.$TUIKit.createCustomMessage({
|
||||
to: this.getToAccount(),
|
||||
conversationType: this.data.conversation.type,
|
||||
payload: e.detail.payload,
|
||||
});
|
||||
this.$sendTIMMessage(message);
|
||||
this.setData({
|
||||
displayOrderList: false,
|
||||
displayCommonWords: false,
|
||||
});
|
||||
},
|
||||
|
||||
$handleCloseCards(e) {
|
||||
switch (e.detail.key) {
|
||||
case '0':
|
||||
this.setData({
|
||||
displayCommonWords: false,
|
||||
});
|
||||
break;
|
||||
case '1':
|
||||
this.setData({
|
||||
displayOrderList: false,
|
||||
});
|
||||
break;
|
||||
case '2':
|
||||
this.setData({
|
||||
displayServiceEvaluation: false,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 发送正在输入消息
|
||||
$sendTypingMessage(message) {
|
||||
wx.$TUIKit.sendMessage(message, {
|
||||
onlineUserOnly: true,
|
||||
});
|
||||
},
|
||||
|
||||
$sendTIMMessage(message) {
|
||||
this.triggerEvent('sendMessage', {
|
||||
message,
|
||||
});
|
||||
wx.$TUIKit.sendMessage(message, {
|
||||
offlinePushInfo: {
|
||||
disablePush: true,
|
||||
},
|
||||
}).then(() => {
|
||||
const firstSendMessage = wx.getStorageSync('isFirstSendMessage');
|
||||
if (firstSendMessage) {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'sendMessage',
|
||||
ext1: 'sendMessage-success',
|
||||
ext2: 'imTuikitExternal',
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.log(`| TUI-chat | message-input | sendMessageError: ${error.code} `);
|
||||
wx.aegis.reportEvent({
|
||||
name: 'sendMessage',
|
||||
ext1: `sendMessage-failed#error: ${error}`,
|
||||
ext2: 'imTuikitExternal',
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
this.triggerEvent('showMessageErrorImage', {
|
||||
showErrorImageFlag: error.code,
|
||||
message,
|
||||
});
|
||||
});
|
||||
this.setData({
|
||||
displayFlag: '',
|
||||
});
|
||||
},
|
||||
|
||||
handleClose() {
|
||||
this.setData({
|
||||
displayFlag: '',
|
||||
});
|
||||
},
|
||||
|
||||
handleServiceEvaluation() {
|
||||
this.setData({
|
||||
displayServiceEvaluation: true,
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"Emoji": "../MessageElements/Emoji/index",
|
||||
"CommonWords": "../MessagePrivate/CommonWords/index",
|
||||
"OrderList": "../MessagePrivate/OrderList/index",
|
||||
"ServiceEvaluation": "../MessagePrivate/ServiceEvaluation/index",
|
||||
"van-dialog": "@vant/weapp/dialog/index",
|
||||
"van-popup": "@vant/weapp/popup/index"
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
|
||||
<view class="TUI-message-input-container">
|
||||
|
||||
<view class="TUI-commom-function functionbox">
|
||||
<view class="more" bindtap="showTooltip">
|
||||
更多
|
||||
|
||||
</view>
|
||||
<view class="contact" hidden="{{showTip}}" bindtap="orderMsg">
|
||||
联系客服
|
||||
</view>
|
||||
<!-- <view class="TUI-commom-function-item" wx:for="{{commonFunction}}" wx:key="index" data-function="{{item}}" bindtap="handleCommonFunctions">{{item.name}}</view> -->
|
||||
</view>
|
||||
<view class="TUI-message-input">
|
||||
|
||||
<!-- <image class="TUI-icon" bindtap="switchAudio" src="{{isAudio ? '../../../../static/assets/keyboard.svg' : '../../../../static/assets/audio.svg'}}" /> -->
|
||||
<view wx:if="{{!isAudio || isEmoji}}" class="TUI-message-input-main {{ focus && 'TUI-message-input-main-focus'}}">
|
||||
<view class="textbox" hidden="{{hideText}}">
|
||||
|
||||
</view>
|
||||
<textarea class="TUI-message-input-area" adjust-position="{{true}}" cursor-spacing="-300" placeholder="请输入文字" value="{{message}}" bindinput="onInputValueChange" maxlength="-1" type="text" auto-height="{{true}}" placeholder-class="textarea-placeholder" confirm-type="send" show-confirm-bar="{{false}}" disable-default-padding="{{true}}" bindfocus="inputBindFocus" bindblur="inputBindBlur" bindconfirm="sendTextMessage" />
|
||||
</view>
|
||||
<view wx:if="{{isAudio}}" class="TUI-message-input-main" bind:longpress="handleLongPress" bind:touchmove="handleTouchMove" bind:touchend="handleTouchEnd" style="display: flex; justify-content: center; font-size: 32rpx; font-family: PingFangSC-Regular; height: 30px">
|
||||
<text>{{text}}</text>
|
||||
</view>
|
||||
<view class="TUI-message-input-functions" hover-class="none">
|
||||
<view class="TUI-sendMessage-btn">
|
||||
<image class="TUI-icon" bindtap="handleEmoji" src="../../../../static/images/emoji.png" />
|
||||
</view>
|
||||
<!-- <view wx:if="{{!sendMessageBtn}}" bindtap="handleExtensions" class="TUI-sendMessage-btn">
|
||||
<image class="TUI-icon" src="../../../../static/assets/more.svg" />
|
||||
</view>
|
||||
<view wx:else class="TUI-sendMessage-btn sendBtn" bindtap="sendTextMessage">
|
||||
发送
|
||||
</view> -->
|
||||
<view class="TUI-sendMessage-btn sendBtn" bindtap="sendTextMessage">
|
||||
发送
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tool">
|
||||
<view class="toolcell" bindtap="handleSendPicture">
|
||||
<image class="toolicon" src="../../../../static/images/camera.png" />
|
||||
<view class="name">相机</view>
|
||||
</view>
|
||||
<view class="toolcell" bindtap="handleSendImage">
|
||||
<image class="toolicon" src="../../../../static/images/album.png" />
|
||||
<view class="name">相册</view>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{displayFlag === 'emoji'}}" class="TUI-Emoji-area">
|
||||
<Emoji bind:enterEmoji="appendMessage" />
|
||||
</view>
|
||||
<view wx:if="{{displayFlag === 'extension'}}" class="TUI-Extensions">
|
||||
<view class="TUI-Extension-slot" bindtap="handleSendPicture">
|
||||
<image class="TUI-Extension-icon" src="../../../../static/assets/take-photo.svg" />
|
||||
<view class="TUI-Extension-slot-name">拍摄照片</view>
|
||||
</view>
|
||||
<view class="TUI-Extension-slot" bindtap="handleSendImage">
|
||||
<image class="TUI-Extension-icon" src="../../../../static/assets/send-img.svg" />
|
||||
<view class="TUI-Extension-slot-name">发送图片</view>
|
||||
</view>
|
||||
<view class="TUI-Extension-slot" bindtap="handleShootVideo">
|
||||
<image class="TUI-Extension-icon" src="../../../../static/assets/take-video.svg" />
|
||||
<view class="TUI-Extension-slot-name">拍摄视频</view>
|
||||
</view>
|
||||
<view class="TUI-Extension-slot" bindtap="handleSendVideo">
|
||||
<image class="TUI-Extension-icon" src="../../../../static/assets/send-video.svg" />
|
||||
<view class="TUI-Extension-slot-name">发送视频</view>
|
||||
</view>
|
||||
<view class="TUI-Extension-slot" data-value="{{1}}" bindtap="handleCheckAuthorize">
|
||||
<image class="TUI-Extension-icon" src="../../../../static/assets/audio-calling.svg" />
|
||||
<view class="TUI-Extension-slot-name">语音通话</view>
|
||||
</view>
|
||||
<view class="TUI-Extension-slot" data-value="{{2}}" bindtap="handleCheckAuthorize">
|
||||
<image class="TUI-Extension-icon" src="../../../../static/assets/video-calling.svg" />
|
||||
<view class="TUI-Extension-slot-name">视频通话</view>
|
||||
</view>
|
||||
<view class="TUI-Extension-slot" bindtap="handleServiceEvaluation">
|
||||
<image class="TUI-Extension-icon" src="../../../../static/assets/service-assess.svg" />
|
||||
<view class="TUI-Extension-slot-name">服务评价</view>
|
||||
</view>
|
||||
<view class="TUI-Extension-slot" bindtap="handleSendOrder">
|
||||
<image class="TUI-Extension-icon" src="../../../../static/assets/send-order.svg" />
|
||||
<view class="TUI-Extension-slot-name">发送订单</view>
|
||||
</view>
|
||||
</view>
|
||||
<CommonWords class="tui-cards" display="{{displayCommonWords}}" bind:sendMessage="$handleSendTextMessage" bind:close="$handleCloseCards" />
|
||||
<OrderList class="tui-cards" display="{{displayOrderList}}" bind:sendCustomMessage="$handleSendCustomMessage" bind:close="$handleCloseCards" />
|
||||
<ServiceEvaluation class="tui-cards" display="{{displayServiceEvaluation}}" bind:sendCustomMessage="$handleSendCustomMessage" bind:close="$handleCloseCards" />
|
||||
</view>
|
||||
|
||||
<view class="record-modal" wx:if="{{popupToggle}}" bind:longpress="handleLongPress" bind:touchmove="handleTouchMove" bind:touchend="handleTouchEnd">
|
||||
<view class="wrapper">
|
||||
<view class="modal-loading">
|
||||
</view>
|
||||
</view>
|
||||
<view class="modal-title">
|
||||
{{title}}
|
||||
</view>
|
||||
</view>
|
||||
<van-dialog
|
||||
title="温馨提示"
|
||||
show="{{ showCustomer }}"
|
||||
message="立即联系客服"
|
||||
bind:confirm="confirmOrder"
|
||||
show-cancel-button
|
||||
confirm-button-color="#3CC7C0"
|
||||
confirm-button-open-type="contact"
|
||||
>
|
||||
</van-dialog>
|
||||
@ -0,0 +1,271 @@
|
||||
.TUI-message-input-container {
|
||||
/* background-color: #F1F1F1; */
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.TUI-message-input {
|
||||
display: flex;
|
||||
position: relative;
|
||||
padding-bottom: 16rpx;
|
||||
margin: 30rpx 32rpx 0;
|
||||
/* background-color: #F1F1F1; */
|
||||
/* width: 100vw; */
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.TUI-commom-function {
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
width: 750rpx;
|
||||
padding:8rpx 0 ;
|
||||
/* background-color: #F1F1F1; */
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.TUI-commom-function-item {
|
||||
display: flex;
|
||||
width: 136rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
height: 48rpx;
|
||||
margin-left: 16rpx;
|
||||
border-radius: 24rpx;
|
||||
background-color: #00C8DC;
|
||||
}
|
||||
|
||||
.TUI-commom-function-item:first-child {
|
||||
margin-left: 48rpx;
|
||||
}
|
||||
|
||||
.TUI-message-input-functions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.TUI-message-input-main {
|
||||
position: relative;
|
||||
|
||||
max-height: 300rpx;
|
||||
background: #F2F2F2;
|
||||
flex: 1;
|
||||
padding: 22rpx 10rpx;
|
||||
margin: 0 10rpx;
|
||||
border-radius: 44rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.TUI-message-input-main-focus {
|
||||
|
||||
max-height: 300rpx;
|
||||
flex: 1;
|
||||
background: #F2F2F2;
|
||||
border-radius: 44rpx;
|
||||
margin: 0 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.textbox {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 15rpx;
|
||||
left: 35rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.TUI-message-input-area {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
max-height: 300rpx;
|
||||
/* 最多显示10行 */
|
||||
z-index: 2;
|
||||
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.TUI-icon {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
margin: 0 16rpx;
|
||||
}
|
||||
|
||||
.TUI-Extensions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100vw;
|
||||
height: 450rpx;
|
||||
margin-left: 14rpx;
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.TUI-Extension-slot {
|
||||
width: 128rpx;
|
||||
height: 170rpx;
|
||||
margin-left: 26rpx;
|
||||
margin-right: 26rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.TUI-Extension-icon {
|
||||
width: 128rpx;
|
||||
height: 128rpx;
|
||||
border-radius: 25%;
|
||||
}
|
||||
|
||||
.TUI-sendMessage-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 8rpx;
|
||||
|
||||
}
|
||||
.sendBtn {
|
||||
margin: 0;
|
||||
width: 120rpx;
|
||||
height: 70rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
background: #3CC7C0;
|
||||
border-radius: 6rpx
|
||||
}
|
||||
|
||||
.TUI-Emoji-area {
|
||||
width: 100vw;
|
||||
height: 450rpx;
|
||||
}
|
||||
|
||||
.TUI-Extension-slot-name {
|
||||
line-height: 34rpx;
|
||||
font-size: 24rpx;
|
||||
color: #333333;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.record-modal {
|
||||
height: 300rpx;
|
||||
width: 60vw;
|
||||
background-color: #000;
|
||||
opacity: 0.8;
|
||||
position: fixed;
|
||||
top: 670rpx;
|
||||
z-index: 9999;
|
||||
left: 20vw;
|
||||
border-radius: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.record-modal .wrapper {
|
||||
display: flex;
|
||||
height: 200rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 10vw;
|
||||
}
|
||||
|
||||
.record-modal .wrapper .modal-loading {
|
||||
opacity: 1;
|
||||
width: 40rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 4rpx;
|
||||
background-color: #006fff;
|
||||
animation: loading 2s cubic-bezier(0.17, 0.37, 0.43, 0.67) infinite;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
transform: translate(0, 0)
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translate(30vw, 0);
|
||||
background-color: #f5634a;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.tool {
|
||||
display: flex;
|
||||
margin: 10rpx 32rpx 0rpx;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.toolcell {
|
||||
display: flex;
|
||||
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolcell .toolicon {
|
||||
width: 40rpx;
|
||||
height: 35rpx;
|
||||
}
|
||||
|
||||
.toolcell .name {
|
||||
color: #999999;
|
||||
font-size: 28rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.toolcell:last-child {
|
||||
margin-left: 90rpx;
|
||||
}
|
||||
.more {
|
||||
width: 120rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
margin-right: 32rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #F8F8F8;
|
||||
color: #353535;
|
||||
font-size: 26rpx;
|
||||
border-radius: 6rpx;
|
||||
border: 1px solid rgba(5, 5, 5, 0.1)
|
||||
}
|
||||
|
||||
.functionbox {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
border: 1rpx solid #E7E7E7;
|
||||
}
|
||||
.contact {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
line-height: 60rpx;
|
||||
justify-content: center;
|
||||
top: -62rpx;
|
||||
width: 128rpx;
|
||||
height: 66rpx;
|
||||
color: #333333;
|
||||
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABCCAYAAACfHt50AAACV0lEQVR4Xu3XvaoaQRjG8Vl3AxERBYOICAYRUmgK2cUy/Umq3EFuI5eQG8gNpEiRKkXgdKZfvwpTBWGJeECbTSFRIjuGTXGaQHDTTZ7/qU4xg7Pz/Hjfeb3pdHox/MnegJcDCMNQ9gKUP3w2mxkACAsAgHD4+acDAAC0AGUDVADl9GkB4ukDAAC0AHEDAAAAU4CyASqAcvo8AsXTBwAAaAHiBgAAAKYAZQNUAOX0eQSKpw8AANACxA0AAABMAcoGqADK6fMIFE8fAACgBYgbAAAAmAKUDVABlNPnESiePgAAQAsQNwAAADAFKBugAiinzyNQPH0AAIAWIG4AAABgClA2QAVQTp9HoHj6AAAALUDcAAAAwBSgbIAKoJw+j0Dx9AEAAFqAuAEAAIApQNkAFUA5fR6B4ukDAAC0AHED9wCGw+F/fRW+75sgCAp94/l8NtbaQntcW7xarX5PAV9dO3jR8wZB0O33+w8qlcpVW9M0NUmS/LDW3l21weFFnsNnv/rocRzf+L7/odfrVWq12l/37fd7s9ls7qy1L8bj8fLqH3F0oQSAPJvlcjnOsuxTt9t91Gg0/ojrcrmY7XZrdrvdF2PM8yiKvjmaaaFjywDIbyWO4yelUum23W4/brVa9xeV9/okSUyapp993385Go2+F7pFhxdLAchzms/nbWvtbbPZfNrpdEyWZWa9XpvD4fC+XC6/GgwGPx3Os/DR5QDkN7RYLOrW2o/1ev3Z8Xg0p9PpTRiGrz3PuxS+Qcc3SALIM5tMJg+r1eq7/N8oit46nuM/H/8XJ/zgYgJgSv4AAAAASUVORK5CYII=) no-repeat center center;
|
||||
background-size: cover;
|
||||
}
|
||||
.contactCustom{
|
||||
display: flex;
|
||||
line-height: 60rpx;
|
||||
padding: 0;
|
||||
justify-content: center;
|
||||
width:100%;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
var concat = function() {
|
||||
if (arguments[0] === 'GROUP' && arguments[2].indexOf('@TGS#') !== -1) {
|
||||
arguments[2] = arguments[2].replace('@TGS#', '')
|
||||
}
|
||||
return arguments[1] + arguments[2]
|
||||
}
|
||||
var connect = function() {
|
||||
return arguments[0] + arguments[1]
|
||||
}
|
||||
module.exports = {
|
||||
concat: concat,
|
||||
connect: connect
|
||||
};
|
||||
@ -0,0 +1,757 @@
|
||||
import dayjs from '../../../../utils/dayjs';
|
||||
import logger from '../../../../utils/logger';
|
||||
import constant from '../../../../utils/constant';
|
||||
// eslint-disable-next-line no-undef
|
||||
const app = getApp();
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
conversation: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
if (!newVal.conversationID) return;
|
||||
this.setData({
|
||||
conversation: newVal,
|
||||
}, () => {
|
||||
this.getMessageList(this.data.conversation);
|
||||
});
|
||||
},
|
||||
},
|
||||
order_inquiry_id: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer(order_inquiry_id) {
|
||||
this.setData({
|
||||
order_inquiry_id,
|
||||
});
|
||||
},
|
||||
},
|
||||
unreadCount: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
unreadCount: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
comment_id:{
|
||||
type: String,
|
||||
value:'',
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
comment_id: newVal,
|
||||
},()=>{
|
||||
if(newVal){
|
||||
this.changeCommnentStatus(newVal)
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
avatar: '',
|
||||
userID: '',
|
||||
isLostsOfUnread: false,
|
||||
unreadCount: '',
|
||||
conversation: {}, // 当前会话
|
||||
messageList: [],
|
||||
comment_id:'',
|
||||
order_inquiry_id:'',
|
||||
// 自己的 ID 用于区分历史消息中,哪部分是自己发出的
|
||||
scrollView: '',
|
||||
triggered: true,
|
||||
nextReqMessageID: '', // 下一条消息标志
|
||||
isCompleted: false, // 当前会话消息是否已经请求完毕
|
||||
messagepopToggle: false,
|
||||
messageID: '',
|
||||
checkID: '',
|
||||
selectedMessage: {},
|
||||
deleteMessage: '',
|
||||
RevokeID: '', // 撤回消息的ID用于处理对方消息展示界面
|
||||
showName: '',
|
||||
showDownJump: false,
|
||||
showUpJump: false,
|
||||
jumpAim: '',
|
||||
messageIndex: '',
|
||||
isShow: false,
|
||||
Show: false,
|
||||
UseData: '',
|
||||
chargeLastmessage: '',
|
||||
groupOptionsNumber: '',
|
||||
showNewMessageCount: [],
|
||||
messageTime: '',
|
||||
messageHistoryTime: '',
|
||||
messageTimeID: {},
|
||||
showMessageTime: false,
|
||||
showMessageHistoryTime: false,
|
||||
showMessageError: false,
|
||||
personalProfile: {},
|
||||
showPersonalProfile: false,
|
||||
resendMessage: {},
|
||||
msgData:{
|
||||
msg_round:0,
|
||||
msg_type:2 // 1 是医生 2是患者,
|
||||
},//回合数
|
||||
showOnlyOnce: false,
|
||||
lastMessageSequence: '',
|
||||
isRewrite: false,
|
||||
isMessageTime: {},
|
||||
firstTime: Number,
|
||||
newArr: {},
|
||||
errorMessage: {},
|
||||
errorMessageID: '',
|
||||
typingMessage: {},
|
||||
|
||||
},
|
||||
|
||||
lifetimes: {
|
||||
attached() {
|
||||
},
|
||||
ready() {
|
||||
if (this.data.unreadCount > 12) {
|
||||
if (this.data.unreadCount > 99) {
|
||||
this.setData({
|
||||
isLostsOfUnread: true,
|
||||
showUpJump: true,
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
showUpJump: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
wx.$TUIKit.getMyProfile().then((res) => {
|
||||
|
||||
this.data.avatar = res.data.avatar;
|
||||
this.data.userID = res.data.userID;
|
||||
});
|
||||
wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.MESSAGE_RECEIVED, this.$onMessageReceived, this);
|
||||
wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.MESSAGE_READ_BY_PEER, this.$onMessageReadByPeer, this);
|
||||
wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.MESSAGE_REVOKED, this.$onMessageRevoked, this);
|
||||
},
|
||||
|
||||
detached() {
|
||||
// 一定要解除相关的事件绑定
|
||||
wx.$TUIKit.off(wx.$TUIKitTIM.EVENT.MESSAGE_RECEIVED, this.$onMessageReceived);
|
||||
wx.$TUIKit.off(wx.$TUIKitTIM.EVENT.MESSAGE_READ_BY_PEER, this.$onMessageReadByPeer);
|
||||
wx.$TUIKit.off(wx.$TUIKitTIM.EVENT.MESSAGE_REVOKED, this.$onMessageRevoked);
|
||||
},
|
||||
},
|
||||
pageLifetimes: {
|
||||
// 组件所在页面的生命周期函数
|
||||
show() {
|
||||
this.setData({
|
||||
img_host:app.hostConfig().imghost
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
popComment(e){
|
||||
this.triggerEvent("popComment",e.detail);
|
||||
|
||||
},
|
||||
changeCommnentStatus(id){
|
||||
let cpn = this.selectComponent(".custom"+id);
|
||||
let renderDom=cpn.data.renderDom;
|
||||
cpn.handleAllRate(id,renderDom);
|
||||
},
|
||||
// 刷新消息列表
|
||||
refresh() {
|
||||
if (this.data.isCompleted) {
|
||||
this.setData({
|
||||
isCompleted: true,
|
||||
triggered: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.getMessageList(this.data.conversation);
|
||||
setTimeout(() => {
|
||||
this.setData({
|
||||
triggered: false,
|
||||
});
|
||||
}, 2000);
|
||||
},
|
||||
// 获取消息列表
|
||||
getMessageList(conversation) {
|
||||
if (!this.data.isCompleted) {
|
||||
wx.$TUIKit.getMessageList({
|
||||
conversationID: conversation.conversationID,
|
||||
nextReqMessageID: this.data.nextReqMessageID,
|
||||
count: 15,
|
||||
}).then((res) => {
|
||||
this.showMoreHistoryMessageTime(res.data.messageList);
|
||||
const { messageList } = res.data; // 消息列表。
|
||||
this.data.nextReqMessageID = res.data.nextReqMessageID; // 用于续拉,分页续拉时需传入该字段。
|
||||
this.data.isCompleted = res.data.isCompleted; // 表示是否已经拉完所有消息。
|
||||
this.data.messageList = [...messageList, ...this.data.messageList];
|
||||
if (messageList.length > 0 && this.data.messageList.length < this.data.unreadCount) {
|
||||
this.getMessageList(conversation);
|
||||
}
|
||||
this.$handleMessageRender(this.data.messageList, messageList);
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
// 历史消息渲染
|
||||
$handleMessageRender(messageList, currentMessageList) {
|
||||
console.log(messageList)
|
||||
this.showHistoryMessageTime(currentMessageList);
|
||||
if (messageList.length > 0) {
|
||||
if (this.data.conversation.type === '@TIM#SYSTEM') {
|
||||
this.filterRepateSystemMessage(messageList);
|
||||
} else {
|
||||
|
||||
// let tepmList=this.deepClone(currentMessageList).reverse();
|
||||
|
||||
let item=null;
|
||||
//判断是否是撤回或者删除消息,跳到底部id
|
||||
for (let i = currentMessageList.length-1;i>=0;i--){
|
||||
if(!currentMessageList[i].isDeleted && !currentMessageList[i].isRevoked){
|
||||
item=currentMessageList[i];
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
//判断消息是否是处方消息; 这里需要messgaeList,要不然回合数会错误;
|
||||
for (let i = messageList.length-1;i>=0;i--) {
|
||||
if(!messageList[i].cloudCustomData){
|
||||
continue;
|
||||
}
|
||||
|
||||
let cloudCustomData=JSON.parse(messageList[i].cloudCustomData);
|
||||
if(messageList[i].type!='TIMCustomElem'){
|
||||
// let jsonData=JSON.parse(messageList[i].payload.data);
|
||||
this.setData({
|
||||
'msgData.msg_round':cloudCustomData.message_rounds,
|
||||
'msgData.msg_type':messageList[i].flow=="in"?1:2
|
||||
});
|
||||
|
||||
this.triggerEvent("getMessageRounds",this.data.msgData);
|
||||
break;
|
||||
|
||||
}else{
|
||||
let jsonData=JSON.parse(messageList[i].payload.data);
|
||||
if(jsonData.message_type==1){
|
||||
this.setData({
|
||||
'msgData.msg_round':0,
|
||||
'msgData.msg_type':2
|
||||
});
|
||||
// if(cloudCustomData.order_inquiry_id!=this.data.order_inquiry_id){
|
||||
// return false;
|
||||
// };
|
||||
this.triggerEvent("getMessageRounds",this.data.msgData);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
this.setData({
|
||||
messageList,
|
||||
// 消息ID前拼接字符串为了解决scroll-into-view,无法跳转以数字开头的ID。
|
||||
//jumpAim: `ID-${this.filterSystemMessageID(currentMessageList[currentMessageList.length - 1].ID)}`,
|
||||
jumpAim: `ID-${this.filterSystemMessageID(item.ID)}`
|
||||
|
||||
}, () => {
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
},
|
||||
// 系统消息去重
|
||||
filterRepateSystemMessage(messageList) {
|
||||
const noRepateMessage = [];
|
||||
for (let index = 0; index < messageList.length; index++) {
|
||||
if (!noRepateMessage.some(item => item && item.ID === messageList[index].ID)) {
|
||||
noRepateMessage.push(messageList[index]);
|
||||
}
|
||||
}
|
||||
this.setData({
|
||||
messageList: noRepateMessage,
|
||||
});
|
||||
},
|
||||
// 消息已读更新
|
||||
$onMessageReadByPeer(event) {
|
||||
this.updateReadByPeer(event);
|
||||
},
|
||||
// 更新已读更新
|
||||
updateReadByPeer(event) {
|
||||
event.data.forEach((item) => {
|
||||
const index = this.data.messageList.findIndex(element => element.ID === item.ID);
|
||||
this.data.messageList[index] = item;
|
||||
this.setData({
|
||||
messageList: this.data.messageList,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 收到的消息
|
||||
$onMessageReceived(value) {
|
||||
const message = value.data[0];
|
||||
let cloudCustomData=JSON.parse(message.cloudCustomData);
|
||||
console.log("cloudCustom_id:"+cloudCustomData.order_inquiry_id,this.data.order_inquiry_id)
|
||||
if(cloudCustomData.order_inquiry_id==this.data.order_inquiry_id){
|
||||
if(message.type=="TIMCustomElem"){
|
||||
let jsonData=JSON.parse(message.payload.data);
|
||||
|
||||
if(jsonData.message_type){
|
||||
if(jsonData.message_type==1 || jsonData.message_type==2){
|
||||
this.triggerEvent("freshChatStatus",cloudCustomData.order_inquiry_id)
|
||||
};
|
||||
if(jsonData.message_type==2){
|
||||
this.triggerEvent("freshChatStatus",cloudCustomData.order_inquiry_id)
|
||||
};
|
||||
if(jsonData.message_type==1){
|
||||
this.setData({
|
||||
'msgData.msg_round':0,
|
||||
'msgData.msg_type':2
|
||||
});
|
||||
this.triggerEvent("getMessageRounds",this.data.msgData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
console.log(this.data.msgData);
|
||||
let chat_rounds=cloudCustomData.message_rounds || 0;
|
||||
let rounds=this.data.msgData.msg_round>=chat_rounds?this.data.msgData.msg_round:chat_rounds;
|
||||
|
||||
this.setData({
|
||||
'msgData.msg_round':rounds,
|
||||
'msgData.msg_type':message.flow=="in"?1:2
|
||||
});
|
||||
this.triggerEvent("getMessageRounds",this.data.msgData);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
wx.$TUIKit.setMessageRead({ conversationID: this.data.conversation.conversationID }).then(() => {
|
||||
logger.log('| MessageList | setMessageRead | ok');
|
||||
});
|
||||
const { BUSINESS_ID_TEXT, MESSAGE_TYPE_TEXT } = constant;
|
||||
this.messageTimeForShow(message);
|
||||
this.setData({
|
||||
UseData: value,
|
||||
});
|
||||
value.data.forEach((item) => {
|
||||
if (item.conversationID !== this.data.conversation.conversationID) {
|
||||
return;
|
||||
}
|
||||
// 判断收到的消息是否是正在输入状态消息。由于正在输入状态消息是自定义消息,需要对自定义消息进行一个过滤,是自定义消息但不是正在输入状态消息,则新消息未读数加1,不是自定义消息则新消息未读数直接加1
|
||||
if (this.data.messageList.length > 12 && !message.isRead) {
|
||||
try {
|
||||
const typingMessage = JSON.parse(item.payload.data);
|
||||
this.setData({
|
||||
typingMessage,
|
||||
});
|
||||
} catch (error) {
|
||||
}
|
||||
if ((item.type === MESSAGE_TYPE_TEXT.TIM_CUSTOM_ELEM && this.data.typingMessage.businessID !== BUSINESS_ID_TEXT.USER_TYPING) || item.type !== MESSAGE_TYPE_TEXT.TIM_CUSTOM_ELEM) {
|
||||
this.data.showNewMessageCount.push(message);
|
||||
this.setData({
|
||||
showNewMessageCount: this.data.showNewMessageCount,
|
||||
showDownJump: true,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.setData({
|
||||
showDownJump: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
// 若需修改消息,需将内存的消息复制一份,不能直接更改消息,防止修复内存消息,导致其他消息监听处发生消息错误
|
||||
// 将收到的消息存入messageList之前需要进行过滤,正在输入状态消息不用存入messageList.
|
||||
const list = [];
|
||||
value.data.forEach((item) => {
|
||||
if (item.conversationID === this.data.conversation.conversationID && item.type === MESSAGE_TYPE_TEXT.TIM_CUSTOM_ELEM) {
|
||||
try {
|
||||
const typingMessage = JSON.parse(item.payload.data);
|
||||
if (typingMessage.businessID !== BUSINESS_ID_TEXT.USER_TYPING) {
|
||||
list.push(item);
|
||||
} else {
|
||||
this.triggerEvent('typing', {
|
||||
typingMessage,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
}
|
||||
} else if (item.conversationID === this.data.conversation.conversationID) {
|
||||
list.push(item);
|
||||
}
|
||||
});
|
||||
this.data.messageList = this.data.messageList.concat(list);
|
||||
console.log("messageList------------------")
|
||||
console.log(this.data.messageList);
|
||||
this.setData({
|
||||
messageList: this.data.messageList,
|
||||
groupOptionsNumber: this.data.messageList.slice(-1)[0].payload.operationType,
|
||||
});
|
||||
if (this.data.conversation.type === 'GROUP') {
|
||||
this.triggerEvent('changeMemberCount', {
|
||||
groupOptionsNumber: this.data.messageList.slice(-1)[0].payload.operationType,
|
||||
});
|
||||
};
|
||||
this.handleJumpNewMessage()
|
||||
},
|
||||
// 自己的消息上屏
|
||||
updateMessageList(message) {
|
||||
if (message.conversationID !== this.data.conversation.conversationID) return;
|
||||
wx.$TUIKit.setMessageRead({ conversationID: this.data.conversation.conversationID }).then(() => {
|
||||
logger.log('| MessageList | setMessageRead | ok');
|
||||
});
|
||||
const { BUSINESS_ID_TEXT, MESSAGE_TYPE_TEXT } = constant;
|
||||
// this.$onMessageReadByPeer();
|
||||
this.messageTimeForShow(message);
|
||||
if (message.type === MESSAGE_TYPE_TEXT.TIM_CUSTOM_ELEM) {
|
||||
const typingMessage = JSON.parse(message.payload.data);
|
||||
if (typingMessage.businessID === BUSINESS_ID_TEXT.USER_TYPING) {
|
||||
this.setData({
|
||||
messageList: this.data.messageList,
|
||||
});
|
||||
} else {
|
||||
this.data.messageList.push(message);
|
||||
}
|
||||
} else {
|
||||
this.data.messageList.push(message);
|
||||
}
|
||||
if(this.data.messageList.length>0){
|
||||
this.setData({
|
||||
lastMessageSequence: this.data.messageList.slice(-1)[0].sequence,
|
||||
messageList: this.data.messageList,
|
||||
jumpAim: `ID-${this.filterSystemMessageID((this.data.messageList[this.data.messageList.length - 1]).ID)}`,
|
||||
}, () => {
|
||||
this.setData({
|
||||
messageList: this.data.messageList,
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
// 兼容 scrollView
|
||||
filterSystemMessageID(messageID) {
|
||||
const index = messageID.indexOf('@TIM#');
|
||||
const groupIndex = messageID.indexOf('@TGS#');
|
||||
if (index === 0) {
|
||||
messageID = messageID.replace('@TIM#', '');
|
||||
}
|
||||
if (groupIndex === 0) {
|
||||
messageID = messageID.replace('@TGS#', '');
|
||||
}
|
||||
return messageID;
|
||||
},
|
||||
// 获取消息ID
|
||||
handleLongPress(e) {
|
||||
for (let index = 0; index < this.data.messageList.length; index++) {
|
||||
if (this.data.messageList[index].status === 'success') {
|
||||
const { index } = e.currentTarget.dataset;
|
||||
this.setData({
|
||||
messageID: e.currentTarget.id,
|
||||
selectedMessage: this.data.messageList[index],
|
||||
Show: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
// 更新 messagelist
|
||||
updateMessageByID(deleteMessageID) {
|
||||
const { messageList } = this.data;
|
||||
const deleteMessageArr = messageList.filter(item => item.ID === deleteMessageID);
|
||||
this.setData({
|
||||
messageList,
|
||||
});
|
||||
return deleteMessageArr;
|
||||
},
|
||||
// 删除消息
|
||||
deleteMessage() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'messageOptions',
|
||||
ext1: 'messageOptions-delete',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
wx.$TUIKit.deleteMessage([this.data.selectedMessage])
|
||||
.then((imResponse) => {
|
||||
this.updateMessageByID(imResponse.data.messageList[0].ID);
|
||||
wx.showToast({
|
||||
title: '删除成功!',
|
||||
duration: 800,
|
||||
icon: 'none',
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
wx.showToast({
|
||||
title: '删除失败!',
|
||||
duration: 800,
|
||||
icon: 'error',
|
||||
});
|
||||
});
|
||||
},
|
||||
// 撤回消息
|
||||
revokeMessage() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'messageOptions',
|
||||
ext1: 'messageOptions-revoke',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
wx.$TUIKit.revokeMessage(this.data.selectedMessage)
|
||||
.then((imResponse) => {
|
||||
this.setData({
|
||||
resendMessage: imResponse.data.message,
|
||||
});
|
||||
this.updateMessageByID(imResponse.data.message.ID);
|
||||
// 消息撤回成功
|
||||
})
|
||||
.catch((imError) => {
|
||||
wx.showToast({
|
||||
title: '超过2分钟消息不支持撤回',
|
||||
duration: 800,
|
||||
icon: 'none',
|
||||
}),
|
||||
this.setData({
|
||||
Show: false,
|
||||
});
|
||||
// 消息撤回失败
|
||||
console.warn('revokeMessage error:', imError);
|
||||
});
|
||||
},
|
||||
// 撤回消息重新发送
|
||||
resendMessage(e) {
|
||||
this.triggerEvent('resendMessage', {
|
||||
message: e.detail.message,
|
||||
});
|
||||
},
|
||||
// 关闭弹窗
|
||||
handleEditToggleAvatar() {
|
||||
this.setData({
|
||||
Show: false,
|
||||
});
|
||||
},
|
||||
// 向对方通知消息撤回事件
|
||||
$onMessageRevoked(event) {
|
||||
this.updateMessageByID(event.data[0].ID);
|
||||
},
|
||||
// 复制消息
|
||||
copyMessage() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'messageOptions',
|
||||
ext1: 'messageOptions-copy',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
wx.setClipboardData({
|
||||
data: this.data.selectedMessage.payload.text,
|
||||
success() {
|
||||
wx.getClipboardData({
|
||||
success(res) {
|
||||
logger.log(`| TUI-chat | message-list | copyMessage: ${res.data} `);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
this.setData({
|
||||
Show: false,
|
||||
});
|
||||
},
|
||||
// 消息跳转到最新
|
||||
handleJumpNewMessage() {
|
||||
if(this.data.messageList.length>0){
|
||||
this.setData({
|
||||
jumpAim: `ID-${this.filterSystemMessageID((this.data.messageList[this.data.messageList.length - 1]).ID)}`,
|
||||
showDownJump: false,
|
||||
showNewMessageCount: [],
|
||||
});
|
||||
}
|
||||
},
|
||||
// 消息跳转到最近未读
|
||||
handleJumpUnreadMessage() {
|
||||
if (this.data.unreadCount > 15) {
|
||||
this.getMessageList(this.data.conversation);
|
||||
this.setData({
|
||||
jumpAim: `ID-${this.filterSystemMessageID(this.data.messageList[this.data.messageList.length - this.data.unreadCount].ID)}`,
|
||||
showUpJump: false,
|
||||
});
|
||||
} else {
|
||||
this.getMessageList(this.data.conversation);
|
||||
this.setData({
|
||||
jumpAim: `ID-${this.filterSystemMessageID(this.data.messageList[this.data.messageList.length - this.data.unreadCount].ID)}`,
|
||||
showUpJump: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
// 滑动到最底部置跳转事件为false
|
||||
scrollHandler() {
|
||||
this.setData({
|
||||
jumpAim: `ID-${this.filterSystemMessageID(this.data.messageList[this.data.messageList.length - 1].ID)}`,
|
||||
showDownJump: false,
|
||||
});
|
||||
},
|
||||
// 删除处理掉的群通知消息
|
||||
changeSystemMessageList(event) {
|
||||
this.updateMessageByID(event.detail.message.ID);
|
||||
},
|
||||
// 展示消息时间
|
||||
messageTimeForShow(messageTime) {
|
||||
const interval = 5 * 60 * 1000;
|
||||
const nowTime = Math.floor(messageTime.time / 10) * 10 * 1000;
|
||||
if (this.data.messageList.length > 0) {
|
||||
const lastTime = this.data.messageList.slice(-1)[0].time * 1000;
|
||||
if (nowTime - lastTime > interval) {
|
||||
Object.assign(messageTime, {
|
||||
isShowTime: true,
|
||||
}),
|
||||
this.data.messageTime = dayjs(nowTime);
|
||||
this.setData({
|
||||
messageTime: dayjs(nowTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
showMessageTime: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
// 渲染历史消息时间
|
||||
showHistoryMessageTime(messageList) {
|
||||
const cut = 30 * 60 * 1000;
|
||||
for (let index = 0; index < messageList.length; index++) {
|
||||
const nowadayTime = Math.floor(messageList[index].time / 10) * 10 * 1000;
|
||||
const firstTime = messageList[0].time * 1000;
|
||||
if (nowadayTime - firstTime > cut) {
|
||||
const indexbutton = messageList.map(item => item).indexOf(messageList[index]); // 获取第一个时间大于30分钟的消息所在位置的下标
|
||||
const firstTime = nowadayTime; // 找到第一个数组时间戳大于30分钟的将其值设为初始值
|
||||
const showHistoryTime = Math.floor(messageList[indexbutton].time / 10) * 10 * 1000;
|
||||
Object.assign(messageList[indexbutton], {
|
||||
isShowHistoryTime: true,
|
||||
}),
|
||||
this.setData({
|
||||
firstTime: nowadayTime,
|
||||
messageHistoryTime: dayjs(showHistoryTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
showMessageHistoryTime: true,
|
||||
});
|
||||
return firstTime;
|
||||
}
|
||||
}
|
||||
},
|
||||
// 拉取更多历史消息渲染时间
|
||||
showMoreHistoryMessageTime(messageList) {
|
||||
if (messageList.length > 0) {
|
||||
const showHistoryTime = messageList[0].time * 1000;
|
||||
Object.assign(messageList[0], {
|
||||
isShowMoreHistoryTime: true,
|
||||
});
|
||||
this.data.newArr[messageList[0].ID] = dayjs(showHistoryTime).format('YYYY-MM-DD HH:mm:ss');
|
||||
this.setData({
|
||||
newArr: this.data.newArr,
|
||||
});
|
||||
}
|
||||
},
|
||||
// 消息发送失败
|
||||
sendMessageError(event) {
|
||||
this.setData({
|
||||
errorMessage: event.detail.message,
|
||||
errorMessageID: event.detail.message.ID,
|
||||
});
|
||||
const errorCode = event.detail.showErrorImageFlag;
|
||||
const { MESSAGE_ERROR_CODE, TOAST_TITLE_TEXT } = constant;
|
||||
switch (errorCode) {
|
||||
case MESSAGE_ERROR_CODE.DIRTY_WORDS:
|
||||
this.showToast(TOAST_TITLE_TEXT.DIRTY_WORDS);
|
||||
break;
|
||||
case MESSAGE_ERROR_CODE.UPLOAD_FAIL:
|
||||
this.showToast(TOAST_TITLE_TEXT.UPLOAD_FAIL);
|
||||
break;
|
||||
case MESSAGE_ERROR_CODE.REQUESTOR_TIME || MESSAGE_ERROR_CODE.DISCONNECT_NETWORK:
|
||||
this.showToast(TOAST_TITLE_TEXT.CONNECT_ERROR);
|
||||
break;
|
||||
case MESSAGE_ERROR_CODE.DIRTY_MEDIA:
|
||||
this.showToast(TOAST_TITLE_TEXT.DIRTY_MEDIA);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 消息发送失败后重新发送
|
||||
ResendMessage() {
|
||||
const { MESSAGE_ERROR_CODE, TOAST_TITLE_TEXT } = constant;
|
||||
wx.showModal({
|
||||
content: '确认重发该消息?',
|
||||
success: (res) => {
|
||||
if (!res.confirm) {
|
||||
return;
|
||||
}
|
||||
wx.$TUIKit.resendMessage(this.data.errorMessage) // 传入需要重发的消息实例
|
||||
.then(() => {
|
||||
this.showToast(TOAST_TITLE_TEXT.RESEND_SUCCESS);
|
||||
this.setData({
|
||||
showMessageError: false,
|
||||
});
|
||||
})
|
||||
.catch((imError) => {
|
||||
switch (imError.code) {
|
||||
case MESSAGE_ERROR_CODE.DIRTY_WORDS:
|
||||
this.showToast(TOAST_TITLE_TEXT.DIRTY_WORDS);
|
||||
break;
|
||||
case MESSAGE_ERROR_CODE.UPLOAD_FAIL:
|
||||
this.showToast(TOAST_TITLE_TEXT.UPLOAD_FAIL);
|
||||
break;
|
||||
case MESSAGE_ERROR_CODE.REQUESTOR_TIME || MESSAGE_ERROR_CODE.DISCONNECT_NETWORK:
|
||||
this.showToast(TOAST_TITLE_TEXT.CONNECT_ERROR);
|
||||
break;
|
||||
case MESSAGE_ERROR_CODE.DIRTY_MEDIA:
|
||||
this.showToast(TOAST_TITLE_TEXT.DIRTY_MEDIA);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
showToast(toastTitle) {
|
||||
if (this.data.showMessageError) {
|
||||
wx.showToast({
|
||||
title: toastTitle,
|
||||
duration: 800,
|
||||
icon: 'none',
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
showMessageError: true,
|
||||
});
|
||||
wx.showToast({
|
||||
title: toastTitle,
|
||||
duration: 800,
|
||||
icon: 'none',
|
||||
});
|
||||
}
|
||||
},
|
||||
deepClone(obj){
|
||||
if(typeof obj!="object");return obj;
|
||||
let result=obj instanceof Array?[]:{};
|
||||
for(let key in obj){
|
||||
result[key]=this.deepClone(obj[key]);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
// 点击购买链接跳转
|
||||
handleJumpLink(e) {
|
||||
if (app?.globalData?.reportType !== constant.OPERATING_ENVIRONMENT) return;
|
||||
const { BUSINESS_ID_TEXT } = constant;
|
||||
const dataLink = JSON.parse(e.currentTarget.dataset.value.payload.data);
|
||||
if (dataLink.businessID === BUSINESS_ID_TEXT.ORDER || dataLink.businessID === BUSINESS_ID_TEXT.LINK) {
|
||||
const url = `/pages/TUI-User-Center/webview/webview?url=${dataLink.link}&wechatMobile`;
|
||||
app.method.navigateTo({
|
||||
url: encodeURI(url),
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"component": true,
|
||||
"enablePullDownRefresh": true,
|
||||
"usingComponents": {
|
||||
"TextMessage": "../MessageElements/TextMessage/index",
|
||||
"ImageMessage": "../MessageElements/ImageMessage/index",
|
||||
"VideoMessage": "../MessageElements/VideoMessage/index",
|
||||
"AudioMessage": "../MessageElements/AudioMessage/index",
|
||||
"CustomMessage": "../MessageElements/CustomMessage/index",
|
||||
"TipMessage": "../MessageElements/TipMessage/index",
|
||||
"SystemMessage": "../MessageElements/SystemMessage/index",
|
||||
"FaceMessage": "../MessageElements/FaceMessage/index",
|
||||
"FileMessage": "../MessageElements/FileMessage/index",
|
||||
"MergerMessage": "../MessageElements/MergerMessage/index",
|
||||
"RevokeMessage": "../MessageElements/RevokeMessage/index"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
<wxs src="../../../../../../filters/filter.wxs" module="filter"></wxs>
|
||||
<view class="container">
|
||||
<scroll-view class="message-list-container" scroll-y="true" scroll-into-view="{{jumpAim}}" refresher-enabled="{{true}}" bindrefresherrefresh="refresh" refresher-triggered="{{triggered}}" lower-threshold="200" bindscrolltolower="scrollHandler">
|
||||
<view class="no-message" wx:if="{{isCompleted}}">没有更多啦</view>
|
||||
<text style="display: none;">{{filter.toS(messageList[messageList.length-1])}}</text>
|
||||
<view class="t-message" wx:if="{{conversation.type !== '@TIM#SYSTEM'}}" wx:for="{{messageList}}" wx:key="index" data-index ='{{index}}' >
|
||||
<view class="time-pop-mask" data-value="{{item.time}}" wx:if="{{showMessageTime}}">
|
||||
<view class="showmessagetime" wx:if="{{item.isShowTime}}">
|
||||
<text class="time" wx:if="{{!item.isDeleted && !item.isRevoked}}">{{messageTime}} </text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="time-pop-mask" data-value="{{item.time}}" wx:if="{{showMessageHistoryTime}}">
|
||||
<view class="showmessagetime" wx:if="{{item.isShowHistoryTime && !item.isShowTime && !item.isShowMoreHistoryTime}}">
|
||||
<text class="time" wx:if="{{!item.isDeleted && !item.isRevoked}}">{{messageHistoryTime}} </text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="time-pop-mask" wx:if="{{item.isShowMoreHistoryTime}}">
|
||||
<view class="showmessagetime">
|
||||
<text class="time">{{newArr[item.ID]}} </text>
|
||||
</view>
|
||||
</view>
|
||||
<RevokeMessage wx:if="{{item.isRevoked}}" message="{{item}}" isMine="{{item.flow === 'out'}}" bind:resendMessage="resendMessage"/>
|
||||
<view class="t-message-item" wx:if="{{!item.isDeleted && !item.isRevoked }}" bindtap="handleEditToggleAvatar" >
|
||||
<view wx:if="{{Show}}" catchtap="handleEditToggleAvatar">
|
||||
<view class="label-pop" wx:if="{{messageID === concat.connect('ID-',item.ID) && item.type!='TIMCustomElem'}}" class="{{item.flow === 'out' ? 'label-self-body' : 'label-recieve-body'}}" >
|
||||
<view class="label-pop-mask" >
|
||||
<view class="copymessage" wx:if="{{item.type === 'TIMTextElem'|| item.type === 'TIMFaceElem'}}" catchtap="copyMessage" > <text>复制</text>
|
||||
</view>
|
||||
<!-- <view class="deletemessage" catchtap="deleteMessage" > <text> 删除</text>
|
||||
</view> -->
|
||||
<!-- <view class="revokemessage" wx:if="{{item.flow === 'out'}}" bindtap="revokeMessage"><text> |撤回</text>
|
||||
</view>-->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<TipMessage wx:if="{{item.type === 'TIMGroupTipElem'}}" message="{{item}}"/>
|
||||
<view wx:if="{{item.type !== 'TIMGroupTipElem'}}" class="{{item.flow === 'out' ? 't-self-message':'t-recieve-message'}} {{item.type=='TIMCustomElem'?'custom_center':''}}" >
|
||||
<image class="t-message-avatar" wx:if="{{(item.flow === 'in' && item.type!='TIMCustomElem') || filter.formateText(item.payload.data).message_type==7}}" src="{{item.avatar || img_host+'/doctor_avatar.png'}}" data-value="{{item}}" bindtap="getMemberProfile" />
|
||||
<view class="read-receipts" wx:if="{{conversation.type === 'C2C' && item.flow==='out' }}">
|
||||
<view wx:if="{{item.isPeerRead}}" >已读</view>
|
||||
<view wx:else>未读</view>
|
||||
</view>
|
||||
<view wx:if="{{item.flow === 'out' && item.ID === errorMessageID || item.status === 'fail'}}" class="t-message-error-box">
|
||||
<image class="t-message-error" wx:if="{{showMessageError}}" src='../../../../static/images/tuikit-msg-error.png' bindtap="ResendMessage" />
|
||||
</view>
|
||||
<view class="{{item.flow === 'out' ? 't-self-message-body':'t-recieve-message-body'}}" catch:longpress="handleLongPress" data-index='{{index}}' data-value='{{item}}' id="{{concat.concat(conversation.type,'ID-',item.ID)}}" message-value="{{item}}" >
|
||||
<TextMessage wx:if="{{item.type === 'TIMTextElem'}}" message="{{item}}" isMine="{{item.flow === 'out'}}" />
|
||||
<ImageMessage wx:if="{{item.type === 'TIMImageElem'}}" message="{{item}}" isMine="{{item.flow === 'out'}}" />
|
||||
<VideoMessage wx:if="{{item.type === 'TIMVideoFileElem'}}" message="{{item}}" isMine="{{item.flow === 'out'}}"/>
|
||||
<AudioMessage wx:if="{{item.type === 'TIMSoundElem'}}" message="{{item}}" data-index ='{{index}}' messageList="{{messageList}}" isMine="{{item.flow === 'out'}}"/>
|
||||
<CustomMessage style="width:100vw" bind:popComment="popComment" wx:if="{{item.type === 'TIMCustomElem' && filter.formateText(item.payload.data).message_type!=6 && filter.formateText(item.payload.data).message_type!=11}}" message="{{item}}" isMine="{{item.flow === 'out'}}" bindtap="handleJumpLink" data-value = "{{item}}" class="{{(item.type === 'TIMCustomElem' && filter.formateText(item.payload.data).message_type==2)?'custom'+filter.formateText(item.payload.data).data.order_inquiry_id:''}}" patient_data="{{filter.formateText(item.cloudCustomData).patient_family_data}}"/>
|
||||
<FaceMessage wx:if="{{item.type === 'TIMFaceElem'}}" message="{{item}}" isMine="{{item.flow === 'out'}}"/>
|
||||
<FileMessage wx:if="{{item.type === 'TIMFileElem'}}" message="{{item}}" isMine="{{item.flow === 'out'}}"/>
|
||||
<MergerMessage wx:if="{{item.type === 'TIMRelayElem'}}" message="{{item}}" isMine="{{item.flow === 'out'}}"/>
|
||||
</view>
|
||||
<image class="t-message-avatar" wx:if="{{(item.flow === 'out' && item.type!='TIMCustomElem') || (item.flow=== 'out' && item.type=='TIMCustomElem' && filter.formateText(item.payload.data).message_type==10)}}" src="{{item.avatar || 'https://img.applets.igandanyiyuan.com/applet/patient/static/patient_avatar.png'}}" data-value="{{item}}" bindtap="getMemberProfile"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="t-message" wx:if="{{conversation.type === '@TIM#SYSTEM'}}" wx:for="{{messageList}}" wx:key="index" id="{{filterSystemMessageID}}" data-value="{{item.ID}}">
|
||||
<SystemMessage message="{{item}}" bind:changeSystemMessageList="changeSystemMessageList"></SystemMessage>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view wx:if="{{showDownJump}}" bindtap="handleJumpNewMessage" style="display: none;">
|
||||
<view class="new-message-item" >
|
||||
<view class="new-message-box">
|
||||
<image class="icon-left" src="../../../static/assets/down.svg"/>
|
||||
<text>{{showNewMessageCount.length}}条新消息</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{showUpJump}}" bindtap="handleJumpUnreadMessage" >
|
||||
<view class="unread-message-item" >
|
||||
<view class="unread-message-box">
|
||||
<image class="icon-left" src="../../../static/assets/up.svg"/>
|
||||
<text wx:if="{{isLostsOfUnread}}"> 99+条未读</text>
|
||||
<text wx:else> {{unreadCount}}条未读</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<wxs src = './concat.wxs' module = 'concat'/>
|
||||
@ -0,0 +1,269 @@
|
||||
.container{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #F4F4F4;
|
||||
}
|
||||
.message-list-container {
|
||||
/* margin-top: 20rpx; */
|
||||
width: 100%;
|
||||
height: calc(100%);
|
||||
background-color: #F4F4F4;
|
||||
}
|
||||
.t-message-item {
|
||||
/*max-width: 60vw;*/
|
||||
padding: 14rpx 0;
|
||||
}
|
||||
.t-message{
|
||||
position: relative;
|
||||
z-index: -9;
|
||||
box-sizing: border-box;
|
||||
/* width: calc(100vw - 40rpx);
|
||||
margin:0 auto; */
|
||||
padding: 10rpx 20rpx 20rpx 12rpx;
|
||||
}
|
||||
.t-recieve-message {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-items: flex-start;
|
||||
width: 100%;
|
||||
}
|
||||
.t-message-avatar {
|
||||
margin-left: 20rpx;
|
||||
margin-right: 12rpx;
|
||||
border-radius: 10rpx;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.t-self-message {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
word-break: break-all;
|
||||
}
|
||||
.t-self-message-body {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
outline: none;
|
||||
}
|
||||
.t-recieve-message-body {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
outline: none;
|
||||
/*background: #F8F8F8;*/
|
||||
/* border-radius: 2px 10px 10px 10px; */
|
||||
width:100%;
|
||||
/* box-sizing: border-box;
|
||||
margin-left: 8rpx;
|
||||
margin-right: 8rpx; */
|
||||
}
|
||||
|
||||
.read-receipts {
|
||||
line-height: 42px;
|
||||
height: 42px;
|
||||
font-size: 12px;
|
||||
color: #6e7981;
|
||||
margin-right: 10px;
|
||||
display: none;
|
||||
}
|
||||
.no-message {
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
color: #a5b5c1;
|
||||
height: 40px;
|
||||
top: -40px;
|
||||
right: 0;
|
||||
}
|
||||
.label-pop{
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
left: 70px;
|
||||
background: white;
|
||||
width: 200rpx;
|
||||
}
|
||||
.label-pop-mask {
|
||||
/* padding: 2px 4px; */
|
||||
|
||||
display: flex;
|
||||
background-color: transparent;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.label-recieve-body{
|
||||
/* padding: 4px; */
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
/* left: 65px; */
|
||||
left: 69px;
|
||||
background: black;
|
||||
/* padding-right: 3px;
|
||||
padding-left: 3px; */
|
||||
background-color: black;
|
||||
z-index: 100;
|
||||
box-shadow: 0 2px 16px 0 rgba(0,0,0,0.08);
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
/* .label-recieve-body:after{
|
||||
content: "";
|
||||
display: block;
|
||||
border-width: 20px;
|
||||
position: absolute;
|
||||
bottom: -27px;
|
||||
left: 8px;
|
||||
border-style: solid dashed dashed;
|
||||
border-color: black transparent transparent;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
margin-left: 9px;
|
||||
border-top-width: 8px;
|
||||
border-right-width: 3px;
|
||||
border-bottom-width: 20px;
|
||||
border-left-width: 3px;
|
||||
border-top-style: solid;
|
||||
border-right-style: dashed;
|
||||
border-bottom-style: dashed;
|
||||
border-left-style: dashed;
|
||||
border-top-color: black;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
border-left-color: transparent;
|
||||
} */
|
||||
.label-self-body{
|
||||
position: absolute;
|
||||
padding: 4px;
|
||||
top: -25px;
|
||||
/* right: 50px; */
|
||||
right: 66px;
|
||||
background: black;
|
||||
/* padding-right: 3px;
|
||||
padding-left: 3px; */
|
||||
background-color: black;
|
||||
z-index: 100;
|
||||
box-shadow: 0 2px 16px 0 rgba(0,0,0,0.08);
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
/* .label-self-body:after{
|
||||
content: "";
|
||||
display: block;
|
||||
border-width: 20px;
|
||||
position: absolute;
|
||||
bottom: -27px;
|
||||
left: 55px;
|
||||
border-style: solid dashed dashed;
|
||||
border-color: black transparent transparent;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
margin-left: 9px;
|
||||
border-top-width: 8px;
|
||||
border-right-width: 3px;
|
||||
border-bottom-width: 20px;
|
||||
border-left-width: 3px;
|
||||
border-top-style: solid;
|
||||
border-right-style: dashed;
|
||||
border-bottom-style: dashed;
|
||||
border-left-style: dashed;
|
||||
border-top-color: black;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
border-left-color: transparent;
|
||||
} */
|
||||
.deletemessage{
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
}
|
||||
.revokemessage{
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
}
|
||||
.copymessage{
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.new-message-item{
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
bottom: 180px;
|
||||
background: black;
|
||||
padding-right: 3px;
|
||||
padding-left: 3px;
|
||||
background-color: black;
|
||||
z-index: 6;
|
||||
box-shadow: 0 2px 16px 0 rgba(0,0,0,0.08);
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
.new-message-box{
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
padding: 2px;
|
||||
}
|
||||
.icon-left{
|
||||
height: 28rpx;
|
||||
width: 28rpx;
|
||||
color: black;
|
||||
background-color: black;
|
||||
padding-top: 2px;
|
||||
}
|
||||
.videomessage-show{
|
||||
background: black
|
||||
}
|
||||
.change-message{
|
||||
width: 100%;
|
||||
height: 200rpx
|
||||
}
|
||||
.unread-message-item{
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 180px;
|
||||
background: black;
|
||||
padding-right: 3px;
|
||||
padding-left: 3px;
|
||||
background-color: black;
|
||||
z-index: 9;
|
||||
box-shadow: 0 2px 16px 0 rgba(0,0,0,0.08);
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
.unread-message-box{
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
padding: 2px;
|
||||
}
|
||||
.time-self-body{
|
||||
position: absolute;
|
||||
top: -14px;
|
||||
right: 67px;
|
||||
}
|
||||
.time-recieve-body{
|
||||
position: absolute;
|
||||
top: -13px;
|
||||
left: 65px;
|
||||
}
|
||||
.time{
|
||||
font-size: 26rpx;
|
||||
color: #333333;
|
||||
}
|
||||
.t-message-error-box{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 6px;
|
||||
}
|
||||
.t-message-error{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.showmessagetime{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.rewrite{
|
||||
padding-left: 5px;
|
||||
color: blue;
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
const commonWordsList = [
|
||||
'什么时候发货',
|
||||
'发什么物流',
|
||||
'为什么物流一直没更新',
|
||||
'最新优惠',
|
||||
'包邮吗',
|
||||
'修改地址信息',
|
||||
'修改收件人信息',
|
||||
'物流一直显示正在揽收',
|
||||
'问题A',
|
||||
'问题B',
|
||||
];
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
display: {
|
||||
type: Boolean,
|
||||
value: '',
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
displayTag: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
displayTag: true,
|
||||
words: '',
|
||||
commonWordsMatch: commonWordsList,
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
handleClose() {
|
||||
this.triggerEvent('close', {
|
||||
key: '0',
|
||||
});
|
||||
},
|
||||
wordsInput(e) {
|
||||
this.data.commonWordsMatch = [],
|
||||
commonWordsList.forEach((item) => {
|
||||
if (item.indexOf(e.detail.value) > -1) {
|
||||
this.data.commonWordsMatch.push(item);
|
||||
}
|
||||
});
|
||||
this.setData({
|
||||
words: e.detail.value,
|
||||
commonWordsMatch: this.data.commonWordsMatch,
|
||||
});
|
||||
},
|
||||
sendMessage(e) {
|
||||
this.triggerEvent('sendMessage', {
|
||||
message: e.currentTarget.dataset.words,
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
<view wx:if="{{displayTag}}" class="tui-common-words-container">
|
||||
<view class="tui-common-words-box">
|
||||
<view class="tui-common-words-title">
|
||||
<view>请选择你要发送的常用语</view>
|
||||
<view style="color: #006EFF; font-family: PingFangSC-Regular;" class="tui-common-words-close" bindtap="handleClose">关闭</view>
|
||||
</view>
|
||||
<view class="tui-search-bar">
|
||||
<image class="tui-searchcion" src="../../../../static/assets/serach-icon.svg" />
|
||||
<input class="tui-search-bar-input" value="{{words}}" placeholder="请输入您想要提出的问题" bindinput='wordsInput'/>
|
||||
</view>
|
||||
<scroll-view class="tui-common-words-list" scroll-y="true" enable-flex="true">
|
||||
<view class="tui-common-words-item" wx:key="index" bindtap="sendMessage" data-words="{{item}}" wx:for="{{commonWordsMatch}}">{{item}}</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,82 @@
|
||||
.tui-common-words-container {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.tui-common-words-box {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 60%;
|
||||
bottom: 0;
|
||||
background: rgba(255,255,255,1);
|
||||
padding-bottom: 68rpx;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
.tui-common-words-title {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
padding-left: 40rpx;
|
||||
padding-right: 40rpx;
|
||||
padding-top: 48rpx;
|
||||
font-family: PingFangSC-Medium;
|
||||
font-size: 36rpx;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
line-height: 50rpx;
|
||||
}
|
||||
|
||||
.tui-search-bar {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
margin: 32rpx 40rpx;
|
||||
width: 670rpx;
|
||||
height: 80rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 40rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
|
||||
.tui-searchcion {
|
||||
display: inline-block;
|
||||
margin-left: 24rpx;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
.tui-search-bar-input {
|
||||
margin-left: 16rpx;
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tui-common-words-list {
|
||||
position: absolute;
|
||||
top: 242rpx;
|
||||
bottom: 68rpx;
|
||||
width: 750rpx;
|
||||
}
|
||||
|
||||
.tui-common-words-item {
|
||||
width: 750rpx;
|
||||
height: 112rpx;
|
||||
border-bottom: 2rpx solid #EEF0F3;
|
||||
background-color: #FFFFFF;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
letter-spacing: 0;
|
||||
line-height: 44rpx;
|
||||
padding: 0 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
import constant from '../../../../../utils/constant';
|
||||
|
||||
const orderList = [
|
||||
{
|
||||
orderNum: 1,
|
||||
time: '2021-7-20 20:45',
|
||||
title: '即时通信 IM 首购活动',
|
||||
description: '单用户限购1件',
|
||||
imageUrl: 'https://sdk-web-1252463788.cos.ap-hongkong.myqcloud.com/component/TUIKit/assets/im.jpg',
|
||||
link: 'https://cloud.tencent.com/act/pro/imnew?from=16262',
|
||||
imageWidth: 135,
|
||||
imageHeight: 135,
|
||||
price: '0.9折起',
|
||||
},
|
||||
{
|
||||
orderNum: 2,
|
||||
time: '2021-7-20 22:45',
|
||||
title: '即时通信 IM 老客户热销专区',
|
||||
description: '购买时长越长越优惠',
|
||||
imageUrl: 'https://sdk-web-1252463788.cos.ap-hongkong.myqcloud.com/component/TUIKit/assets/im.jpg',
|
||||
link: 'https://cloud.tencent.com/act/pro/imnew?from=16262',
|
||||
imageWidth: 135,
|
||||
imageHeight: 135,
|
||||
price: '7.2折起',
|
||||
},
|
||||
];
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
display: {
|
||||
type: Boolean,
|
||||
value: '',
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
displayTag: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
conversation: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
conversation: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
displayTag: true,
|
||||
words: '',
|
||||
orderMatch: orderList,
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
handleClose() {
|
||||
this.triggerEvent('close', {
|
||||
key: '1',
|
||||
});
|
||||
},
|
||||
wordsInput(e) {
|
||||
this.data.orderMatch = [],
|
||||
orderList.forEach((item) => {
|
||||
if (item.title.indexOf(e.detail.value) > -1 || item.orderNum === ~~e.detail.value) {
|
||||
this.data.orderMatch.push(item);
|
||||
}
|
||||
});
|
||||
this.setData({
|
||||
words: e.detail.value,
|
||||
orderMatch: this.data.orderMatch,
|
||||
});
|
||||
},
|
||||
sendMessage(e) {
|
||||
const { BUSINESS_ID_TEXT, FEAT_NATIVE_CODE } = constant;
|
||||
const { order } = e.currentTarget.dataset;
|
||||
this.triggerEvent('sendCustomMessage', { // 传递给父组件,在父组件处调用SDK的接口,来进行自定消息的发送
|
||||
payload: {
|
||||
data: JSON.stringify({
|
||||
businessID: BUSINESS_ID_TEXT.ORDER,
|
||||
version: FEAT_NATIVE_CODE.NATIVE_VERSION,
|
||||
title: order.title,
|
||||
imageUrl: order.imageUrl,
|
||||
imageWidth: order.imageWidth,
|
||||
imageHeight: order.imageHeight,
|
||||
link: order.link,
|
||||
price: order.price,
|
||||
description: order.description,
|
||||
}), // data字段用于标识该消息类型
|
||||
description: order.title, // 获取自定义消息的具体描述
|
||||
extension: order.title, // 自定义消息的具体内容
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
<view wx:if="{{displayTag}}" class="tui-cards-container">
|
||||
<view class="tui-cards-box">
|
||||
<view class="tui-cards-title">
|
||||
<view>请选择你要发送的订单</view>
|
||||
<view style="color: #006EFF; font-family: PingFangSC-Regular;" class="tui-cards-close" bindtap="handleClose">关闭</view>
|
||||
</view>
|
||||
<view class="tui-search-bar">
|
||||
<image class="tui-searchcion" src="../../../../static/assets/serach-icon.svg" />
|
||||
<input class="tui-search-bar-input" value="{{words}}" placeholder="搜索" bindinput='wordsInput'/>
|
||||
</view>
|
||||
<scroll-view class="tui-order-list" scroll-y="true" enable-flex="true">
|
||||
<view class="tui-order-item" wx:key="index" wx:for="{{orderMatch}}" >
|
||||
<view class="order-title">
|
||||
<view class="order-number">订单编号: {{item.orderNum}}</view>
|
||||
<view class="order-time">{{item.time}}</view>
|
||||
</view>
|
||||
<view class="order-info">
|
||||
<image class="order-image" src="{{item.imageUrl}}" />
|
||||
<view class="order-content">
|
||||
<view class="order-content-title">{{item.title}}</view>
|
||||
<view class="order-content-description">{{item.description}}</view>
|
||||
<view style="display: flex; flex-wrap: no-wrap; justify-content: space-between;">
|
||||
<view class="order-content-price">{{item.price}}</view>
|
||||
<view class="btn-send-order" data-order="{{item}}" catch:tap="sendMessage">
|
||||
<text class="btn-send-text">发送此订单</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,173 @@
|
||||
.tui-cards-container {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.tui-cards-box {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 60%;
|
||||
bottom: 0;
|
||||
background: #F4F5F9;
|
||||
padding-bottom: 68rpx;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
.tui-cards-title {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
padding-left: 40rpx;
|
||||
padding-right: 40rpx;
|
||||
padding-top: 48rpx;
|
||||
font-family: PingFangSC-Medium;
|
||||
font-size: 36rpx;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
line-height: 50rpx;
|
||||
}
|
||||
|
||||
.tui-search-bar {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
margin: 32rpx 40rpx;
|
||||
width: 670rpx;
|
||||
height: 80rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 40rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
|
||||
.tui-searchcion {
|
||||
display: inline-block;
|
||||
margin-left: 24rpx;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
.tui-search-bar-input {
|
||||
margin-left: 16rpx;
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tui-order-list {
|
||||
position: absolute;
|
||||
top: 242rpx;
|
||||
bottom: 68rpx;
|
||||
width: 750rpx;
|
||||
}
|
||||
|
||||
.tui-order-item {
|
||||
width: 670rpx;
|
||||
margin: 32rpx 40rpx;
|
||||
height: 388rpx;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.order-title {
|
||||
width: 670rpx;
|
||||
height: 102rpx;
|
||||
padding: 32rpx 40rpx;
|
||||
padding-bottom: 0;
|
||||
border-bottom: 2rpx solid #EEF0F3;
|
||||
}
|
||||
|
||||
.order-title > .order-number {
|
||||
font-family: PingFangSC-Medium;
|
||||
font-size: 32rpx;
|
||||
line-height: 44rpx;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.order-title > .order-time {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 24rpx;
|
||||
line-height: 34rpx;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.order-info {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
width: 670rpx;
|
||||
height: 236rpx;
|
||||
padding: 32rpx 40rpx;
|
||||
}
|
||||
|
||||
.order-content {
|
||||
width: 450rpx;
|
||||
margin-left: 32rpx;
|
||||
}
|
||||
|
||||
.order-content-title {
|
||||
font-family: PingFangSC-Medium;
|
||||
width: 378rpx;
|
||||
line-height: 34rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.order-content-description {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
font-family: PingFangSC-Regular;
|
||||
max-width: 410rpx;
|
||||
line-height: 34rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.order-content-price {
|
||||
font-family: PingFangSC-Medium;
|
||||
font-size: 36rpx;
|
||||
line-height: 50rpx;
|
||||
color: #FF7201;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.order-image {
|
||||
width: 156rpx;
|
||||
height: 156rpx;
|
||||
}
|
||||
|
||||
.btn-send-order {
|
||||
width: 176rpx;
|
||||
height: 58rpx;
|
||||
background-color: #006EFF;
|
||||
border-radius: 14.5px;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
.btn-send-text{
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 12px;
|
||||
color: #FFFFFF;
|
||||
line-height: 14px;
|
||||
}
|
||||
@ -0,0 +1,246 @@
|
||||
import constant from '../../../../../utils/constant';
|
||||
import {
|
||||
evaluation
|
||||
} from '../../../../../../../api/consult'
|
||||
import {
|
||||
throttle
|
||||
} from "../../../../../../../utils/util"
|
||||
let app=getApp();
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
display: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
observer(newVal) {
|
||||
console.log(newVal);
|
||||
this.setData({
|
||||
displayTag: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
doctor_id: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
doctor_id: newVal,
|
||||
});
|
||||
},
|
||||
},
|
||||
commentDetail: {
|
||||
type: Object,
|
||||
value: null,
|
||||
observer(newVal) {
|
||||
if (newVal) {
|
||||
this.setData({
|
||||
commentDetail: newVal,
|
||||
reply_quality: newVal.reply_quality,
|
||||
service_attitude: newVal.service_attitude,
|
||||
reply_progress: newVal.reply_progress,
|
||||
content: newVal.content?newVal.content:'感谢您的服务',
|
||||
score: newVal.avg_score,
|
||||
is_evaluation: newVal.is_evaluation,
|
||||
order_inquiry_id: newVal.order_inquiry_id
|
||||
});
|
||||
if(!newVal.is_evaluation){
|
||||
this.setData({
|
||||
reply_quality: 5,
|
||||
service_attitude: 5,
|
||||
reply_progress: 5,
|
||||
score:5
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
},
|
||||
doctor_info: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(newVal) {
|
||||
this.setData({
|
||||
doctor_info: newVal,
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
lifetimes: {
|
||||
attached: function () {
|
||||
|
||||
// 在组件实例进入页面节点树时执行
|
||||
},
|
||||
},
|
||||
pageLifetimes: {
|
||||
show: function() {
|
||||
this.setData({
|
||||
img_host:app.hostConfig().imghost
|
||||
});
|
||||
|
||||
},
|
||||
hide: function() {
|
||||
|
||||
// 页面被隐藏
|
||||
},
|
||||
resize: function(size) {
|
||||
// 页面尺寸变化
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
img_host:'https://oss.prod.applets.igandanyiyuan.com/applet/patient/static',
|
||||
displayTag: false,
|
||||
doctor_info: null,
|
||||
commentDetail: null,
|
||||
doctor_id: '',
|
||||
is_evaluation: false,
|
||||
message: '',
|
||||
scoreList: [1, 2, 3, 4, 5],
|
||||
score: 0,
|
||||
comment: '',
|
||||
order_inquiry_id: '',
|
||||
reply_quality: 0,
|
||||
service_attitude: 0,
|
||||
reply_progress: 0,
|
||||
content: '感谢您的服务'
|
||||
},
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
onChangeContent(event) {
|
||||
this.setData({
|
||||
content: event.detail
|
||||
})
|
||||
},
|
||||
handleEvaluation: throttle(function () {
|
||||
let {
|
||||
order_inquiry_id,
|
||||
doctor_info,
|
||||
reply_quality,
|
||||
service_attitude,
|
||||
reply_progress,
|
||||
content
|
||||
} = this.data;
|
||||
if (reply_quality == '') {
|
||||
wx.showToast({
|
||||
title: '请评论回复质量',
|
||||
icon: "none"
|
||||
});
|
||||
return false;
|
||||
};
|
||||
if (service_attitude == '') {
|
||||
wx.showToast({
|
||||
title: '请评论服务态度',
|
||||
icon: "none"
|
||||
});
|
||||
return false;
|
||||
};
|
||||
if (content == '') {
|
||||
wx.showToast({
|
||||
title: '请填写您对医生的印象',
|
||||
icon: "none"
|
||||
});
|
||||
return false;
|
||||
};
|
||||
if (reply_progress == '') {
|
||||
wx.showToast({
|
||||
title: '请评论回复速度',
|
||||
icon: "none"
|
||||
});
|
||||
return false;
|
||||
};
|
||||
evaluation({
|
||||
order_inquiry_id,
|
||||
doctor_id:doctor_info.doctor_id,
|
||||
reply_quality,
|
||||
service_attitude,
|
||||
reply_progress,
|
||||
content,
|
||||
}).then(data => {
|
||||
this.setData({
|
||||
displayTag: false
|
||||
});
|
||||
this.triggerEvent("freshRate",order_inquiry_id);
|
||||
this.triggerEvent('close', {
|
||||
score: Number(this.data.score)
|
||||
});
|
||||
wx.showToast({
|
||||
title: '评价成功',
|
||||
icon: "none"
|
||||
})
|
||||
})
|
||||
}),
|
||||
handleClose() {
|
||||
this.triggerEvent('close', {
|
||||
score: this.data.is_evaluation ? this.data.score : 0
|
||||
});
|
||||
},
|
||||
onChange(event) {
|
||||
this.setData({
|
||||
[event.target.dataset.id]: event.detail
|
||||
});
|
||||
let {
|
||||
reply_quality,
|
||||
service_attitude,
|
||||
reply_progress
|
||||
} = this.data;
|
||||
if (reply_quality && service_attitude && reply_progress) {
|
||||
let score = (reply_quality * 0.4) + (service_attitude * 0.3) + (reply_progress * 0.3);
|
||||
this.setData({
|
||||
score: Math.floor(score)
|
||||
})
|
||||
}
|
||||
},
|
||||
handleScore(e) {
|
||||
let {
|
||||
score
|
||||
} = e.currentTarget.dataset;
|
||||
if (score === this.data.score) {
|
||||
score = 0;
|
||||
}
|
||||
this.setData({
|
||||
score,
|
||||
});
|
||||
},
|
||||
bindTextAreaInput(e) {
|
||||
this.setData({
|
||||
comment: e.detail.value,
|
||||
});
|
||||
},
|
||||
sendMessage() {
|
||||
const {
|
||||
BUSINESS_ID_TEXT,
|
||||
STRING_TEXT,
|
||||
FEAT_NATIVE_CODE
|
||||
} = constant;
|
||||
this.triggerEvent('sendCustomMessage', {
|
||||
payload: {
|
||||
// data 字段作为表示,可以自定义
|
||||
data: JSON.stringify({
|
||||
businessID: BUSINESS_ID_TEXT.EVALUATION,
|
||||
version: FEAT_NATIVE_CODE.NATIVE_VERSION,
|
||||
score: this.data.score,
|
||||
comment: this.data.comment,
|
||||
}),
|
||||
description: STRING_TEXT.TYPETEXT, // 获取骰子点数
|
||||
extension: STRING_TEXT.TYPETEXT,
|
||||
},
|
||||
});
|
||||
|
||||
this.setData({
|
||||
score: 0,
|
||||
comment: '',
|
||||
});
|
||||
this.handleClose();
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
@ -0,0 +1,10 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"van-rate": "@vant/weapp/rate/index",
|
||||
"van-field": "@vant/weapp/field/index"
|
||||
},
|
||||
|
||||
"styleIsolation": "shared"
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
<view class="tui-cards-container" catch:tap="handleClose" wx:if="{{displayTag}}">
|
||||
<view class="service-evaluation" catch:tap="()=>{}">
|
||||
<view class="header">
|
||||
<!-- <label>请对本次服务进行评价</label> -->
|
||||
|
||||
<image src="../../../../../static/images/chat_close.png" class="chatclose" catch:tap="handleClose">
|
||||
|
||||
</image>
|
||||
|
||||
</view>
|
||||
<view class="main">
|
||||
<view class="doctorInfo">
|
||||
<image src="{{doctor_info.avatar}}" class="doctorAvatar" mode="aspectFill" wx:if="{{doctor_info.avatar}}"> </image>
|
||||
<image src="{{img_host+'/doctor_avatar.png'}}" class="doctorAvatar" wx:else> </image>
|
||||
|
||||
<view class="namebox">
|
||||
<view class="name">{{doctor_info.user_name}}</view>
|
||||
<view class="position" wx:if="{{doctor_info.doctor_title_name}}">{{doctor_info.doctor_title_name}}</view>
|
||||
|
||||
</view>
|
||||
<view class="viewstar">
|
||||
<van-rate value="{{ score }}" size="{{ 26 }}" color="#ed9c00" void-icon="star" void-color="#eee" bind:change="onChange" gutter="16" readonly />
|
||||
</view>
|
||||
</view>
|
||||
<view class="linebox">
|
||||
<view class="line"></view>
|
||||
<view class="pingjia">非常满意</view>
|
||||
<view class="line"></view>
|
||||
</view>
|
||||
<view class="ratebox">
|
||||
<view class="starbox">
|
||||
<view class="name"> 回复质量</view>
|
||||
<van-rate value="{{reply_quality}}" size="{{ 20 }}" color="#ed9c00" void-icon="star" void-color="#eee" bind:change="onChange" gutter="8" data-id="reply_quality" readonly="{{is_evaluation}}" />
|
||||
<view class="quality" wx:if="{{reply_quality>=4}}">好评</view>
|
||||
<view class="quality" wx:elif="{{reply_quality==3}}">中评</view>
|
||||
<view class="quality" wx:else="{{reply_quality<=2}}">差评</view>
|
||||
</view>
|
||||
<view class="starbox">
|
||||
<view class="name"> 服务态度</view>
|
||||
<van-rate value="{{service_attitude}}" size="{{ 20 }}" color="#ed9c00" void-icon="star" void-color="#eee" bind:change="onChange" gutter="8" data-id="service_attitude" readonly="{{is_evaluation}}" />
|
||||
<view class="quality" wx:if="{{service_attitude>=4}}">好评</view>
|
||||
<view class="quality" wx:elif="{{service_attitude==3}}">中评</view>
|
||||
<view class="quality" wx:else="{{service_attitude<=2}}">差评</view>
|
||||
</view>
|
||||
<view class="starbox">
|
||||
<view class="name">回复速度</view>
|
||||
|
||||
<van-rate value="{{reply_progress}}" size="{{ 20 }}" color="#ed9c00" void-icon="star" void-color="#eee" bind:change="onChange" gutter="8" data-id="reply_progress" readonly="{{is_evaluation}}"/>
|
||||
<view class="quality" wx:if="{{reply_progress>=4}}">好评</view>
|
||||
<view class="quality" wx:elif="{{reply_progress==3}}">中评</view>
|
||||
<view class="quality" wx:else="{{reply_progress<=2}}">差评</view>
|
||||
</view>
|
||||
</view>
|
||||
<van-field maxlength="200" class="commentArea" input-class="ipt" custom-style="height: 240rpx; border-radius: 10rpx;background: #fff;border:1px solid #ccc;" placeholder="请您对本次服务进行评价" show-word-limit value="{{ content }}" label="" type="textarea" border="{{ false }}" bind:change="onChangeContent" disabled="{{is_evaluation}}"></van-field>
|
||||
<!-- <view class="main-evaluation-score">
|
||||
<image class="score-star" wx:for="{{scoreList}}" wx:key="*this" data-score="{{item}}" src="{{'../../../../../static/images/star' + (item > score ? '-grey': '') + '.png'}}" bind:tap="handleScore" />
|
||||
</view> -->
|
||||
<!-- <textarea cols="20" rows="10" bindinput="bindTextAreaInput" placeholder="请输入评语" placeholder-style="textarea-placeholder" confirm-type="done" show-confirm-bar="{{false}}"></textarea> -->
|
||||
</view>
|
||||
<view class="footer">
|
||||
<!-- bind:tap="sendMessage" -->
|
||||
<button class="btn" type="primary" bindtap="handleEvaluation" disabled="{{is_evaluation}}">匿名评价</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,180 @@
|
||||
.tui-cards-container {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index:9999999;
|
||||
top: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.service-evaluation {
|
||||
flex: 1;
|
||||
background: #FFFFFF;
|
||||
padding: 38rpx 40rpx 38rpx;
|
||||
border-radius: 40rpx 40rpx 0 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-family: PingFangSC-Regular;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: auto !important;
|
||||
padding: 0;
|
||||
margin: 0 !important;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.header label {
|
||||
font-size: 18px;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
line-height: 25px;
|
||||
}
|
||||
.van-field__body--textarea{
|
||||
width:600rpx;
|
||||
}
|
||||
.header .btn {
|
||||
font-size: 16px;
|
||||
color: #006EFF;
|
||||
letter-spacing: 0;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 8rpx 0 38rpx;
|
||||
}
|
||||
|
||||
.main-evaluation-score {
|
||||
padding: 0 60rpx 48rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.main-evaluation-score .score-star {
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
}
|
||||
|
||||
.main textarea {
|
||||
background: #F8F8F8;
|
||||
border: 0 solid #D9D9D9;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
padding: 16rpx 32rpx;
|
||||
}
|
||||
|
||||
.textarea-placeholder {
|
||||
color: #B0B0B0;
|
||||
}
|
||||
.footer .btn{
|
||||
height: 80rpx;
|
||||
width:100%;
|
||||
background: #3CC7C0;
|
||||
color:#fff;
|
||||
display: flex;
|
||||
font-size: 30rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10rpx
|
||||
}
|
||||
.chatclose {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
position: absolute;
|
||||
padding:10rpx 30rpx;
|
||||
|
||||
right: 10rpx;
|
||||
}
|
||||
|
||||
.doctorInfo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.doctorAvatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.namebox {
|
||||
display: flex;
|
||||
margin-top: 18rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.namebox .name {
|
||||
color: #333333;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.viewstar {
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
|
||||
.namebox .position {
|
||||
color: #333333;
|
||||
font-size: 24rpx;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
.linebox{
|
||||
display: flex;
|
||||
margin-top: 20rpx;
|
||||
align-items: center;
|
||||
}
|
||||
.linebox .line {
|
||||
flex: 1;
|
||||
height:1rpx;
|
||||
background: #CCCCCC;
|
||||
}
|
||||
|
||||
.linebox .pingjia {
|
||||
margin: 0 40rpx;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.starbox{
|
||||
margin-bottom: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #333333;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.ratebox{
|
||||
margin-top: 34rpx;
|
||||
}
|
||||
|
||||
.starbox .name{
|
||||
margin-right:22rpx;
|
||||
}
|
||||
.starbox .quality{
|
||||
margin-left:22rpx;
|
||||
}
|
||||
.ipt{
|
||||
height:165rpx;
|
||||
background-color: transparent!important;
|
||||
padding:8rpx!important;
|
||||
}
|
||||
.commentArea{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.commentArea .van-field__word-limit{
|
||||
position: absolute!important;
|
||||
left:10rpx;
|
||||
right:10rpx;
|
||||
text-align: right;
|
||||
bottom:5rpx;
|
||||
color: #ccc!important;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
792
TUIService/TUIKit/components/TUIChat/index.js
Normal file
792
TUIService/TUIKit/components/TUIChat/index.js
Normal file
@ -0,0 +1,792 @@
|
||||
// TUIKit-WChat/Chat/index.js
|
||||
import logger from '../../utils/logger';
|
||||
import constant from '../../utils/constant';
|
||||
const dayjs = require("../../utils/dayjs.js");
|
||||
import {
|
||||
getRate
|
||||
} from "../../../../api/consultOrder"
|
||||
// eslint-disable-next-line no-undef
|
||||
import {
|
||||
fllowDoctor,
|
||||
notfllowDoctor,
|
||||
doctorDetail,
|
||||
} from "../../../../api/consultExpert"
|
||||
|
||||
|
||||
import {
|
||||
chatMsg
|
||||
} from "../../../../api/common"
|
||||
import {throttle} from "../../../../utils/util"
|
||||
|
||||
const app = getApp();
|
||||
const inputStyle = `
|
||||
--padding: 25px
|
||||
`;
|
||||
|
||||
let newInputStyle = `
|
||||
--padding: 0px
|
||||
`;
|
||||
|
||||
const setNewInputStyle = (number) => {
|
||||
const height = number;
|
||||
newInputStyle = `--padding: ${height}px`;
|
||||
};
|
||||
let pageY = 0;
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
currentConversationID: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer(currentConversationID) {
|
||||
this.setData({
|
||||
conversationID: currentConversationID,
|
||||
});
|
||||
},
|
||||
},
|
||||
order_inquiry_id: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer(order_inquiry_id) {
|
||||
this.setData({
|
||||
order_inquiry_id,
|
||||
});
|
||||
},
|
||||
},
|
||||
fromType: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer(newval) {
|
||||
this.setData({
|
||||
fromType: newval
|
||||
});
|
||||
},
|
||||
},
|
||||
inquiry_type: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer(inquiry_type) {
|
||||
this.setData({
|
||||
inquiry_type
|
||||
});
|
||||
},
|
||||
},
|
||||
hasCallKit: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
observer(hasCallKit) {
|
||||
this.setData({
|
||||
hasCallKit,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
lifetimes: {
|
||||
attached() {
|
||||
if (app?.globalData?.reportType === constant.OPERATING_ENVIRONMENT) {
|
||||
this.setData({
|
||||
showTips: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
ready() {
|
||||
|
||||
}
|
||||
},
|
||||
pageLifetimes: {
|
||||
show: function() {
|
||||
this.setData({
|
||||
img_host:app.hostConfig().imghost
|
||||
});
|
||||
wx.onNetworkStatusChange((res) => {
|
||||
let msg = ''
|
||||
if (!res.isConnected) {
|
||||
msg = '当前网络不可用,请检查你的网络设置'
|
||||
} else if (res.networkType === 'none') {
|
||||
msg = '网络开小差了,请在网络良好后重试'
|
||||
}
|
||||
if (msg) {
|
||||
wx.showToast({
|
||||
title: msg,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log(this.data.order_inquiry_id);
|
||||
this.handleChatMsg(this.data.order_inquiry_id);
|
||||
|
||||
},
|
||||
hide: function() {
|
||||
this.setData({
|
||||
showAgain:false
|
||||
})
|
||||
// 页面被隐藏
|
||||
},
|
||||
resize: function(size) {
|
||||
// 页面尺寸变化
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
img_host:'https://oss.prod.applets.igandanyiyuan.com/applet/patient/static',
|
||||
conversationName: '',
|
||||
isEvaluation:false,
|
||||
conversation: {},
|
||||
doctor_info: '',
|
||||
messageList: [],
|
||||
isShow: false,
|
||||
showImage: false,
|
||||
showChat: true,
|
||||
commentDetail: null,
|
||||
conversationID: '',
|
||||
order_inquiry_id: '',
|
||||
comment_id:'',//评论订单id
|
||||
fromType: '',
|
||||
inquiry_type: '',
|
||||
patient_family_data: {},
|
||||
rest_rounds: 0,//剩余回合数
|
||||
msgData:{
|
||||
msg_round:0,
|
||||
msg_type:1
|
||||
},
|
||||
message: '',
|
||||
doctorChatData: {
|
||||
is_evaluation: false,
|
||||
inquiry_status: '',
|
||||
follow: false,
|
||||
times_number: 0,
|
||||
duration: 0,
|
||||
reception_time: null,
|
||||
rest_time: 0,
|
||||
doctor_id: '',
|
||||
timeData: {},
|
||||
},
|
||||
doctorDetail: {
|
||||
avatar: '',
|
||||
be_good_at: '',
|
||||
user_name: '',
|
||||
doctor_title_name: '',
|
||||
department_custom_name: '',
|
||||
doctor_inquiry_config: [],
|
||||
hospital: {},
|
||||
doctor_id:'',
|
||||
multi_point_status: '',
|
||||
multi_point_enable:0
|
||||
},
|
||||
current_inquiry_config: {},
|
||||
config: {
|
||||
sdkAppID: '',
|
||||
userID: '',
|
||||
userSig: '',
|
||||
type: 1,
|
||||
tim: null,
|
||||
},
|
||||
unreadCount: 0,
|
||||
hasCallKit: false,
|
||||
viewData: {
|
||||
style: inputStyle,
|
||||
},
|
||||
showHead: false,
|
||||
showDialog: false,
|
||||
overlay: false,
|
||||
blockHeight:"300rpx", //菜单卡片高度
|
||||
KeyboardHeight: 0,
|
||||
showPop: true,
|
||||
showTips: false,
|
||||
showGroupTips: false,
|
||||
showAll: false,
|
||||
displayServiceEvaluation: false,
|
||||
score: 0,
|
||||
startX: 0, //touchStart开始坐标
|
||||
startY: 0,
|
||||
isFlag:true,
|
||||
isEnd:false
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
handleGetRate(id) {
|
||||
getRate(id).then(data => {
|
||||
if (data) {
|
||||
this.setData({
|
||||
isEvaluation:true,
|
||||
commentDetail: data,
|
||||
score: data.avg_score
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
},
|
||||
openHelp() {
|
||||
this.setData({
|
||||
showDialog: true
|
||||
})
|
||||
},
|
||||
closeHead() {
|
||||
this.setData({
|
||||
showHead: true
|
||||
})
|
||||
},
|
||||
// 显示遮罩层
|
||||
showModal() {
|
||||
this.setData({
|
||||
hideModal: true,
|
||||
blockHeight:"1130rpx"
|
||||
})
|
||||
},
|
||||
// 隐藏遮罩层
|
||||
hideModal() {
|
||||
|
||||
this.setData({
|
||||
hideModal: false,
|
||||
blockHeight:"300rpx"
|
||||
})
|
||||
},
|
||||
touchstart(e) {
|
||||
this.setData({
|
||||
startX: e.changedTouches[0].clientX,
|
||||
startY: e.changedTouches[0].clientY
|
||||
})
|
||||
},
|
||||
angle(start, end) {
|
||||
var _X = end.X - start.X,
|
||||
_Y = end.Y - start.Y;
|
||||
//返回角度 Math.atan()返回数字的反正切值
|
||||
return 360 * Math.atan(_Y / _X) / (2 * Math.PI);
|
||||
},
|
||||
touchend(e) {
|
||||
let {startX,startY} = this.data;
|
||||
let slidingRange = 45; //
|
||||
let touchMoveX = e.changedTouches[0].clientX;
|
||||
let touchMoveY = e.changedTouches[0].clientY;
|
||||
let angle = this.angle({
|
||||
X: startX,
|
||||
Y: startY
|
||||
}, {
|
||||
X: touchMoveX,
|
||||
Y: touchMoveY
|
||||
});
|
||||
//为了方便计算取绝对值判断
|
||||
if (Math.abs(angle) > slidingRange && touchMoveY < startY) {
|
||||
|
||||
this.showModal()
|
||||
// 向上滑动
|
||||
};
|
||||
if (Math.abs(angle) > slidingRange && touchMoveY > startY ) {
|
||||
this.hideModal()
|
||||
// 向下滑动
|
||||
}
|
||||
},
|
||||
onClose() {
|
||||
this.setData({
|
||||
showPop: false,
|
||||
});
|
||||
},
|
||||
changeTimeStatus(event){
|
||||
if(event.detail){
|
||||
this.setData({
|
||||
isEnd:true
|
||||
})
|
||||
}
|
||||
},
|
||||
goExpertDetail:throttle(function(){
|
||||
let id = this.data.doctorChatData.doctor_id;
|
||||
// wx.redirectTo({
|
||||
// url: "/pages/expertDetail/expertDetail?doctor_id=" + id
|
||||
// })
|
||||
app.method.navigateTo({
|
||||
url: "/pages/expertDetail/expertDetail?doctor_id=" + id
|
||||
})
|
||||
}),
|
||||
loopArr(arr,type){
|
||||
let inquiry_mode='';
|
||||
let inquiry_price='';
|
||||
let recieveStatus='';
|
||||
let order_type=type;
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if(arr[i].inquiry_type==type){
|
||||
recieveStatus=arr[i].work_num_day-arr[i].times_number;
|
||||
inquiry_mode=arr[i].inquiry_mode;
|
||||
inquiry_price=arr[i].inquiry_price;
|
||||
}
|
||||
};
|
||||
//如果公益问诊 次数为0 则去看是否有专家问诊
|
||||
if(type==3 && recieveStatus==0){
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if(arr[i].inquiry_type==1){
|
||||
order_type=1;
|
||||
recieveStatus=arr[i].work_num_day-arr[i].order_inquiry_count;
|
||||
inquiry_mode=arr[i].inquiry_mode;
|
||||
inquiry_price=arr[i].inquiry_price;
|
||||
duration=arr[i].duration;
|
||||
work_num_day=arr[i].work_num_day;
|
||||
times_number=arr[i].times_number;
|
||||
order_inquiry_count=arr[i].order_inquiry_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.setData({
|
||||
current_inquiry_config: {
|
||||
inquiry_type: order_type,
|
||||
inquiry_mode:inquiry_mode,
|
||||
inquiry_price:inquiry_price,
|
||||
recieveStatus:recieveStatus
|
||||
}
|
||||
})
|
||||
},
|
||||
formatInquiryStatus(arr){
|
||||
var a='3';
|
||||
if(arr){
|
||||
for (var i = 0; i < arr.length; ++i) {
|
||||
if(arr[i].is_enable==1 && arr[i].inquiry_type==1){
|
||||
a='2'
|
||||
};
|
||||
if(arr[i].is_enable==1 && arr[i].inquiry_type==3){
|
||||
return '1'
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
return a
|
||||
},
|
||||
getDoctorDetail(id) {
|
||||
doctorDetail(id).then(data => {
|
||||
let obj = this.data.doctorDetail;
|
||||
for (const key in obj) {
|
||||
let item = `doctorDetail.${key}`
|
||||
this.setData({
|
||||
[item]: data[key]
|
||||
})
|
||||
};
|
||||
let doctor_inquiry_config = data.doctor_inquiry_config;
|
||||
let inquiryType=this.formatInquiryStatus(doctor_inquiry_config);
|
||||
if(inquiryType==1){
|
||||
this.loopArr(doctor_inquiry_config,3);
|
||||
}else if(inquiryType==2){
|
||||
this.loopArr(doctor_inquiry_config,1);
|
||||
}else{
|
||||
this.setData({
|
||||
current_inquiry_config:null
|
||||
})
|
||||
}
|
||||
// if(data.is_img_expert_reception==1 && data.is_img_welfare_reception==1){
|
||||
// this.loopArr(doctor_inquiry_config,3);
|
||||
// // 1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药
|
||||
// this.setData({
|
||||
// isHide:true
|
||||
// })
|
||||
// }else if(data.is_img_expert_reception==1 && data.is_img_welfare_reception==0){
|
||||
// this.loopArr(doctor_inquiry_config,1);
|
||||
|
||||
// }else if(data.is_img_welfare_reception== 1 && data.is_img_expert_reception==0){
|
||||
// this.loopArr(doctor_inquiry_config,3);
|
||||
// }else{
|
||||
// this.setData({
|
||||
// current_inquiry_config:null
|
||||
// })
|
||||
// }
|
||||
})
|
||||
},
|
||||
goOrderDetail:throttle(function(){
|
||||
let {
|
||||
order_inquiry_id
|
||||
} = this.data;
|
||||
// wx.redirectTo({
|
||||
// url: '/pages/orderDetail/orderDetail?order_inquiry_id='+order_inquiry_id
|
||||
// })
|
||||
console.log("订单详情");
|
||||
app.method.navigateTo({
|
||||
url: '/pages/orderDetail/orderDetail?order_inquiry_id='+order_inquiry_id
|
||||
})
|
||||
}),
|
||||
getMessageRounds(event) {
|
||||
console.log('detail======')
|
||||
console.log(event)
|
||||
this.setData({
|
||||
msgData: event.detail
|
||||
})
|
||||
console.log(this.data.doctorChatData.times_number)
|
||||
if(this.data.doctorChatData.times_number>=0){
|
||||
let rest_rounds=this.data.doctorChatData.times_number-event.detail.msg_round;
|
||||
console.log("rest_rounds:"+rest_rounds)
|
||||
this.setData({
|
||||
rest_rounds:rest_rounds
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
onChangeTime(e) {
|
||||
this.setData({
|
||||
'doctorChatData.timeData': e.detail,
|
||||
});
|
||||
},
|
||||
toggleFllow() {
|
||||
if (this.data.doctorChatData.follow) {
|
||||
this.handenotfllowDoctor()
|
||||
} else {
|
||||
this.handelfllowDoctor()
|
||||
}
|
||||
},
|
||||
handleChatMsg(id) {
|
||||
chatMsg(id).then(data => {
|
||||
// console.log("接口请求收到时间66666"+dayjs().format("YYYY-MM-DD HH:mm:ss:SSS"));
|
||||
// console.log(data);
|
||||
let obj = this.data.doctorChatData;
|
||||
for (const key in obj) {
|
||||
let item = `doctorChatData.${key}`
|
||||
this.setData({
|
||||
[item]: data[key]
|
||||
})
|
||||
};
|
||||
this.getDoctorDetail(data.doctor_id);
|
||||
let patient_family_data = {
|
||||
patient_name: data.patient_family_name,
|
||||
patient_sex: data.patient_family_sex,
|
||||
patient_age: data.patient_family_age
|
||||
};
|
||||
this.setData({
|
||||
patient_family_data: patient_family_data
|
||||
})
|
||||
let duration=''
|
||||
if( data.duration == 0){
|
||||
duration='不限时长';
|
||||
}else if((data.duration / 60)>0 && (data.duration / 60)<=1){
|
||||
duration=data.duration+"分钟内";
|
||||
}else{
|
||||
duration=(data.duration / 60) + "小时内";
|
||||
};
|
||||
console.log(duration);
|
||||
let number = data.times_number == 0 ? '不限次' : data.times_number + "回合";
|
||||
let message='';
|
||||
if(data.inquiry_type==4 || data.inquiry_type==2){
|
||||
message=`医生接诊后${duration}${number}沟通。超过5分钟未接诊,平台会在1个工作日内全额退还费用,如使用优惠劵,一并退回。`
|
||||
}else if(data.inquiry_type==1 || data.inquiry_type==3){
|
||||
message=`医生接诊后${duration}${number}沟通。医生超过24小时未接诊,平台会在1个工作日内全额退还费用,如使用优惠劵,一并退回`
|
||||
}
|
||||
this.setData({
|
||||
message:message
|
||||
})
|
||||
if (data.inquiry_status == 3) {
|
||||
this.setData({
|
||||
"doctorChatData.rest_time": -1 //待接诊 可以沟通
|
||||
});
|
||||
if (data.times_number == 0) {
|
||||
this.setData({
|
||||
"doctorChatData.times_number": -1
|
||||
})
|
||||
} else {
|
||||
this.setData({
|
||||
message_rounds: data.times_number
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
} else if (data.inquiry_status == 4) {
|
||||
if (data.times_number == 0) {
|
||||
this.setData({
|
||||
"doctorChatData.times_number": -1
|
||||
})
|
||||
} else {
|
||||
this.setData({
|
||||
message_rounds: data.times_number
|
||||
})
|
||||
|
||||
}
|
||||
if (data.duration != 0) {
|
||||
if (data.reception_time) {
|
||||
let endtime = dayjs(data.reception_time).add(data.duration, 'minute').format('YYYY-MM-DD HH:mm:ss');
|
||||
let nowtime = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||||
let countdown = dayjs(endtime).diff(nowtime, "millisecond");
|
||||
let countdownTime = countdown > 0 ? countdown : 0;
|
||||
console.log("countdownTime--------");
|
||||
console.log(countdownTime);
|
||||
this.setData({
|
||||
"doctorChatData.rest_time": countdownTime
|
||||
})
|
||||
} else {
|
||||
this.setData({
|
||||
"doctorChatData.rest_time": 0
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.setData({
|
||||
"doctorChatData.rest_time": -2 //接诊不限时间
|
||||
})
|
||||
}
|
||||
}
|
||||
// console.log("times_number:----"+data.times_number,this.data.msgData.msg_round)
|
||||
if(data.times_number>=0){
|
||||
let rest_rounds=data.times_number-this.data.msgData.msg_round;
|
||||
console.log("rest_rounds:----"+rest_rounds)
|
||||
this.setData({
|
||||
rest_rounds:rest_rounds
|
||||
})
|
||||
|
||||
}
|
||||
if(this.data.isFlag){
|
||||
this.scrollBottom();
|
||||
this.setData({
|
||||
isFlag:false
|
||||
})
|
||||
}
|
||||
if(data.inquiry_status == 4 && data.duration!==0){
|
||||
if(this.data.doctorChatData.rest_time==0){
|
||||
//console.log("结束了");
|
||||
this.selectComponent('#MessageInput').handlefinishConsult()
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
handelfllowDoctor() {
|
||||
let id = this.data.doctorChatData.doctor_id;
|
||||
fllowDoctor(id).then(data => {
|
||||
this.setData({
|
||||
"doctorChatData.follow": true
|
||||
})
|
||||
wx.showToast({
|
||||
title: '关注成功',
|
||||
icon: "none"
|
||||
})
|
||||
})
|
||||
},
|
||||
handenotfllowDoctor() {
|
||||
let id = this.data.doctorChatData.doctor_id;
|
||||
notfllowDoctor(id).then(data => {
|
||||
this.setData({
|
||||
"doctorChatData.follow": false
|
||||
})
|
||||
wx.showToast({
|
||||
title: '已取消关注',
|
||||
icon: "none"
|
||||
})
|
||||
})
|
||||
},
|
||||
$handleCloseCards(event) {
|
||||
let commentDetail={
|
||||
avg_score:event.detail.score,
|
||||
is_evaluation:event.detail.score>0?true:false
|
||||
};
|
||||
this.setData({
|
||||
displayServiceEvaluation: false,
|
||||
commentDetail:commentDetail
|
||||
});
|
||||
},
|
||||
handleServiceEvaluation(e) {
|
||||
let commentDetail=e.detail;
|
||||
if( commentDetail && commentDetail.avg_score){
|
||||
commentDetail.is_evaluation=true
|
||||
}else{
|
||||
commentDetail.is_evaluation=false
|
||||
}
|
||||
this.setData({
|
||||
displayServiceEvaluation:true,
|
||||
commentDetail:commentDetail,
|
||||
});
|
||||
},
|
||||
init() {
|
||||
//this.handleGetRate(this.data.order_inquiry_id);
|
||||
wx.$TUIKit.setMessageRead({
|
||||
conversationID: this.data.conversationID
|
||||
}).then((data) => {
|
||||
logger.log('| TUI-chat | setMessageRead | ok');
|
||||
});
|
||||
wx.$TUIKit.getConversationProfile(this.data.conversationID).then((res) => {
|
||||
const {
|
||||
conversation
|
||||
} = res.data;
|
||||
app.globalData.chatNumber = app.globalData.chatNumber - conversation.unreadCount;
|
||||
this.setData({
|
||||
conversationName: this.getConversationName(conversation),
|
||||
conversation,
|
||||
isShow: conversation.type === wx.$TUIKitTIM.TYPES.CONV_GROUP,
|
||||
});
|
||||
if (conversation.type !== wx.$TUIKitTIM.TYPES.CONV_GROUP) return;
|
||||
if (!this.data.showTips) {
|
||||
this.setData({
|
||||
showGroupTips: true,
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
showAll: true,
|
||||
});
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
getConversationName(conversation) {
|
||||
if (conversation.type === '@TIM#SYSTEM') {
|
||||
this.setData({
|
||||
showChat: false,
|
||||
});
|
||||
return '系统通知';
|
||||
}
|
||||
if (conversation.type === wx.$TUIKitTIM.TYPES.CONV_C2C) {
|
||||
return conversation.remark || conversation.userProfile.nick || conversation.userProfile.userID;
|
||||
}
|
||||
if (conversation.type === wx.$TUIKitTIM.TYPES.CONV_GROUP) {
|
||||
return conversation.groupProfile.name || conversation.groupProfile.groupID;
|
||||
}
|
||||
},
|
||||
sendMessage(event) {
|
||||
// 将自己发送的消息写进消息列表里面
|
||||
this.selectComponent('#MessageList').updateMessageList(event.detail.message);
|
||||
},
|
||||
showMessageErrorImage(event) {
|
||||
this.selectComponent('#MessageList').sendMessageError(event);
|
||||
},
|
||||
triggerClose() {
|
||||
try {
|
||||
this.selectComponent('#MessageInput').handleClose();
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
},
|
||||
handleCall(event) {
|
||||
if (event.detail.conversationType === wx.$TUIKitTIM.TYPES.CONV_GROUP) {
|
||||
this.selectComponent('#TUIGroup').callShowMoreMember(event);
|
||||
} else {
|
||||
this.triggerEvent('handleCall', event.detail);
|
||||
}
|
||||
},
|
||||
groupCall(event) {
|
||||
const {
|
||||
selectedUserIDList,
|
||||
type,
|
||||
groupID
|
||||
} = event.detail;
|
||||
const userIDList = selectedUserIDList;
|
||||
this.triggerEvent('handleCall', {
|
||||
userIDList,
|
||||
type,
|
||||
groupID
|
||||
});
|
||||
},
|
||||
goBack() {
|
||||
//this.triggerEvent('showConversationList');
|
||||
if (app.globalData.origion == 1) {
|
||||
wx.reLaunch({
|
||||
url: '/pages/index/index',
|
||||
})
|
||||
} else if (app.globalData.origion == 2) {
|
||||
wx.reLaunch({
|
||||
url: '/pages/index/index',
|
||||
})
|
||||
} else {
|
||||
wx.$TUIKit.setMessageRead({
|
||||
conversationID: this.data.conversationID,
|
||||
}).then(() => {
|
||||
if (this.data.fromType) {
|
||||
wx.reLaunch({
|
||||
url: "/pages/index/index"
|
||||
})
|
||||
} else {
|
||||
wx.navigateBack({
|
||||
delta: 1,
|
||||
fail:function(){
|
||||
wx.reLaunch({
|
||||
url: '/pages/index/index',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
showConversationList() {
|
||||
this.triggerEvent('showConversationList');
|
||||
},
|
||||
freshChatStatus(event) {
|
||||
console.log("freshChatStatus");
|
||||
if (event.detail) {
|
||||
this.setData({
|
||||
order_inquiry_id:event.detail
|
||||
})
|
||||
this.handleChatMsg(event.detail);
|
||||
|
||||
}
|
||||
},
|
||||
freshRate(event){
|
||||
console.log('comment_id:'+event.detail);
|
||||
if (event.detail) {
|
||||
this.setData({
|
||||
comment_id:event.detail
|
||||
});
|
||||
//this.handleGetRate(event.detail);
|
||||
|
||||
}
|
||||
},
|
||||
changeMemberCount(event) {
|
||||
this.selectComponent('#TUIGroup').updateMemberCount(event.detail.groupOptionsNumber);
|
||||
},
|
||||
resendMessage(event) {
|
||||
this.selectComponent('#MessageInput').onInputValueChange(event);
|
||||
},
|
||||
//触发滚动到底部
|
||||
scrollBottom(){
|
||||
console.log("触发");
|
||||
wx.nextTick(() => {
|
||||
let compoment=this.selectComponent(".mylist");
|
||||
compoment.handleJumpNewMessage();
|
||||
});
|
||||
},
|
||||
// 监听键盘,获取焦点时将输入框推到键盘上方
|
||||
pullKeysBoards(event) {
|
||||
setNewInputStyle(event.detail.event.detail.height);
|
||||
this.setData({
|
||||
'viewData.style': newInputStyle,
|
||||
});
|
||||
this.scrollBottom();
|
||||
},
|
||||
|
||||
// 监听键盘,失去焦点时收起键盘
|
||||
downKeysBoards(event) {
|
||||
this.scrollBottom();
|
||||
this.setData({
|
||||
'viewData.style': inputStyle,
|
||||
});
|
||||
},
|
||||
typing(event) {
|
||||
const {
|
||||
STRING_TEXT,
|
||||
FEAT_NATIVE_CODE
|
||||
} = constant;
|
||||
if (this.data.conversation.type === wx.$TUIKitTIM.TYPES.CONV_C2C) {
|
||||
if (event.detail.typingMessage.typingStatus === FEAT_NATIVE_CODE.ISTYPING_STATUS && event.detail.typingMessage.actionParam === constant.TYPE_INPUT_STATUS_ING) {
|
||||
this.setData({
|
||||
conversationName: STRING_TEXT.TYPETYPING,
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.setData({
|
||||
conversationName: this.getConversationName(this.data.conversation),
|
||||
});
|
||||
}, (1000 * 30));
|
||||
} else if (event.detail.typingMessage.typingStatus === FEAT_NATIVE_CODE.NOTTYPING_STATUS && event.detail.typingMessage.actionParam === constant.TYPE_INPUT_STATUS_END) {
|
||||
this.setData({
|
||||
conversationName: this.getConversationName(this.data.conversation),
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
handleReport() {
|
||||
const url = '/pages/TUI-User-Center/webview/webview?url=https://cloud.tencent.com/apply/p/xc3oaubi98g';
|
||||
app.method.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
14
TUIService/TUIKit/components/TUIChat/index.json
Normal file
14
TUIService/TUIKit/components/TUIChat/index.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"MessageList": "./components/MessageList/index",
|
||||
"MessageInput": "./components/MessageInput/index",
|
||||
"TUIGroup": "../TUIGroup/index",
|
||||
"ServiceEvaluation":"./components/MessagePrivate/ServiceEvaluation/index",
|
||||
"van-count-down": "@vant/weapp/count-down/index",
|
||||
"van-popup": "@vant/weapp/popup/index",
|
||||
"consult-list":"../../../../components/consultList/consultList",
|
||||
"dialog":"../../../../components/dialog/dialog",
|
||||
"nav":"../../../../components/nav/nav"
|
||||
}
|
||||
}
|
||||
135
TUIService/TUIKit/components/TUIChat/index.wxml
Normal file
135
TUIService/TUIKit/components/TUIChat/index.wxml
Normal file
@ -0,0 +1,135 @@
|
||||
<!--TUIKit-WChat/Chat/index.wxml-->
|
||||
|
||||
|
||||
<view class="container">
|
||||
<view class="tui-navigatorbar">
|
||||
<image class="tui-navigatorbar-back" bindtap="goBack" src="../../static/assets/back.png" />
|
||||
<view class="conversation-title">{{doctorDetail.user_name}}医生</view>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="headbox" hidden="{{showHead}}" bindtap="goExpertDetail">
|
||||
<image src="{{doctorDetail.avatar}}" class="headicon" wx:if="{{doctorDetail.avatar}}" mode="aspectFill"></image>
|
||||
<image src="{{img_host+'/doctor_avatar.png'}}" class="headicon" wx:else></image>
|
||||
<image src="../../static/images/close.png" class="close" catchtap="closeHead"></image>
|
||||
<view class="guanzhu" wx:if="{{doctorChatData.follow}}" catchtap="toggleFllow">已关注</view>
|
||||
<view class="guanzhu" wx:else catchtap="toggleFllow">关注</view>
|
||||
</view>
|
||||
<view class="list-box {{ showTips && 'list-box-notips'}} || {{ showGroupTips && 'list-box-group'}} || {{ showAll && 'list-box-group-notips' }} {{(doctorChatData.inquiry_status==5 || doctorChatData.inquiry_status==6)?'nobottom':''}} ">
|
||||
<view wx:if="{{showTips}}" class="safetytips-box">
|
||||
<view class="safetytips">
|
||||
<text>【安全提示】本 APP 仅用于体验腾讯云即时通信 IM 产品功能,不可用于业务洽谈与拓展。请勿轻信汇款、中奖等涉及钱款等信息,勿轻易拨打陌生电话,谨防上当受骗。</text>
|
||||
<span class="report" bindtap="handleReport">点此投诉</span>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view class="message-list" bindtap="triggerClose">
|
||||
<view class="statusbox" wx:if="{{doctorChatData.inquiry_status==3}}">
|
||||
<view class="status">
|
||||
<view class="circle"></view>
|
||||
<view>等待接诊中</view>
|
||||
<image src="../../static/images/help.png" class="help" bindtap="openHelp"></image>
|
||||
</view>
|
||||
<view class="statusdesc">医生将在空闲时尽快接诊,请耐心等待</view>
|
||||
</view>
|
||||
<view class="statusbox" wx:elif="{{doctorChatData.inquiry_status==4}}">
|
||||
<view class="status">
|
||||
<view class="circle"></view>
|
||||
<view>问诊中</view>
|
||||
<view class="bar" wx:if="{{doctorChatData.rest_time!==0 && !isEnd}}">|</view>
|
||||
<view class="desc" wx:if="{{doctorChatData.rest_time!==0 && !isEnd}}">
|
||||
<view class="desc"wx:if="{{doctorChatData.rest_time==-2}}">不限时间</view>
|
||||
<view class="desc" wx:elif="{{doctorChatData.rest_time>0}}">
|
||||
剩余<van-count-down use-slot time="{{doctorChatData.rest_time}}" bind:change="onChangeTime" format="HH:mm:ss">
|
||||
<!-- <text class="item" hidden="{{doctorChatData.timeData.days==0}}">{{doctorChatData.timeData.days }}天</text> -->
|
||||
<text class="item" hidden="{{doctorChatData.timeData.hours== 0 && doctorChatData.timeData.days==0}}">{{(doctorChatData.timeData.days*24)+doctorChatData.timeData.hours }}小时</text>
|
||||
<text class="item" wx:if="{{doctorChatData.timeData.hours==0}}">{{ doctorChatData.timeData.minutes }}分</text>
|
||||
<text class="item" wx:if="{{doctorChatData.timeData.hours==0}}">{{ doctorChatData.timeData.seconds }}秒</text>
|
||||
</van-count-down>
|
||||
</view>
|
||||
<text class="red" decode="true" wx:if="{{doctorChatData.times_number==-1}}"> 不限</text>
|
||||
<text class="red" decode="true" wx:else> {{rest_rounds>=0?rest_rounds:0}}</text>
|
||||
<text>个沟通回合</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="statusbox" wx:elif="{{doctorChatData.inquiry_status==7}}">
|
||||
<view class="status">
|
||||
<view class="circle"></view>
|
||||
<view>问诊已取消</view>
|
||||
</view>
|
||||
<view class="orderDetail" bindtap="goOrderDetail">订单详情</view>
|
||||
</view>
|
||||
<view class="statusbox" wx:elif="{{doctorChatData.inquiry_status== 5}}">
|
||||
<view class="status">
|
||||
<view class="circle"></view>
|
||||
<view>问诊完成</view>
|
||||
</view>
|
||||
<view class="orderDetail" bindtap="goOrderDetail">订单详情</view>
|
||||
</view>
|
||||
<view class="statusbox" wx:elif="{{doctorChatData.inquiry_status== 6}}">
|
||||
<view class="status">
|
||||
<view class="circle"></view>
|
||||
<view>问诊结束</view>
|
||||
</view>
|
||||
<view class="orderDetail" bindtap="goOrderDetail">订单详情</view>
|
||||
</view>
|
||||
<MessageList id="MessageList" bind:popComment="handleServiceEvaluation" class="mylist" conversation="{{conversation}}" unreadCount="{{unreadCount}}" bind:freshChatStatus="freshChatStatus" order_inquiry_id="{{order_inquiry_id}}" comment_id="{{comment_id}}" bind:changeMemberCount="changeMemberCount" bind:resendMessage="resendMessage" bind:getMessageRounds="getMessageRounds" bind:typing="typing"></MessageList>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="group-profile">
|
||||
|
||||
<TUIGroup id="TUIGroup" wx:if="{{isShow}}" conversation="{{conversation}}" bind:groupCall="groupCall" bind:showConversationList="showConversationList"></TUIGroup>
|
||||
</view>
|
||||
<view class="input-area" wx:if="{{doctorChatData.inquiry_status==3 || doctorChatData.inquiry_status==4}}">
|
||||
<view class="message-input" style="{{viewData.style}}" wx:if="{{showChat}}">
|
||||
<MessageInput id="MessageInput" duration="{{doctorChatData.duration}}" rest_time="{{doctorChatData.rest_time}}" times_number="{{doctorChatData.times_number}}" msgData="{{msgData}}" order_inquiry_id="{{order_inquiry_id}}" inquiry_type="{{inquiry_type}}" conversation="{{conversation}}" patient_family_data="{{patient_family_data}}" hasCallKit="{{hasCallKit}}" bind:sendMessage="sendMessage" bind:freshChatStatus="freshChatStatus"
|
||||
bind:changeTimeStatus="changeTimeStatus"
|
||||
bind:downKeysBoards="downKeysBoards" bind:pullKeysBoards="pullKeysBoards" bind:showMessageErrorImage="showMessageErrorImage" bind:handleCall="handleCall" bind:getMessageRounds="getMessageRounds"></MessageInput>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<ServiceEvaluation display="{{displayServiceEvaluation}}" doctor_info="{{doctorDetail}}" bind:close="$handleCloseCards" bind:handleServiceEvaluation="handleServiceEvaluation" commentDetail="{{commentDetail}}" bind:freshRate="freshRate"></ServiceEvaluation>
|
||||
<!-- show="{{doctorChatData.inquiry_status==5 || doctorChatData.inquiry_status==6}}" -->
|
||||
<van-popup class="mypop" id="mypop" show="{{doctorChatData.inquiry_status==5 || doctorChatData.inquiry_status==6}}" position="bottom" overlay="{{blockHeight=='1130rpx'?true:false}}" duration="500" z-index="9999" custom-style=" border-radius:8rpx;transition: height 0.5s;height:{{blockHeight}}" bind:close="onClose">
|
||||
<view class="popwrper" id="popwrper" bindtouchstart="touchstart" bindtouchend="touchend" style="height:{{blockHeight}}" >
|
||||
<view class="top">
|
||||
<image src="../../static/images/up.png" class="up {{blockHeight=='1130rpx'?'active':''}}"></image>
|
||||
</view>
|
||||
<view class="popname">
|
||||
再次咨询
|
||||
</view>
|
||||
<view class="infobox" style="margin-top: 32rpx;margin-bottom: 0rpx;padding-bottom: 0;">
|
||||
<view class="namebox" style="justify-content: flex-start;">
|
||||
<image src="{{doctorDetail.avatar}}" class="head" wx:if="{{doctorDetail.avatar}}" mode="aspectFill"></image>
|
||||
<image src="{{img_host+'/doctor_avatar.png'}}" class="head" wx:else></image>
|
||||
<view class="namewraper">
|
||||
<view class="row">
|
||||
<view class="name">{{doctorDetail.user_name}}</view>
|
||||
<!-- <view class="position">{{doctorDetail.doctor_title_name}}</view> -->
|
||||
<view class="type" wx:if="{{doctorDetail.hospital.hospital_level_name!='未知' && doctorDetail.hospital.hospital_level_name}}">{{doctorDetail.hospital.hospital_level_name}}</view>
|
||||
<view class="type" wx:if="{{doctorDetail.multi_point_status==1 && doctorDetail.multi_point_enable==1}}">可处方</view>
|
||||
</view>
|
||||
<view class="hospital"><text wx:if="{{doctorDetail.doctor_title_name}}" class="doctor_title">{{doctorDetail.doctor_title_name}}</text><text>{{doctorDetail.department_custom_name}}</text></view>
|
||||
<view class="hospital">{{doctorDetail.hospital.hospital_name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="borderbox">
|
||||
<view class="goodjob" style="margin-top: 30rpx;">
|
||||
擅长:{{doctorDetail.be_good_at}}
|
||||
</view>
|
||||
<view class="consultbox">
|
||||
<view class="leftname" wx:if="{{current_inquiry_config.inquiry_price}}">图文问诊:<text class="price" decode> ¥{{current_inquiry_config.inquiry_price}}</text></view>
|
||||
<view class="btn" bindtap="goExpertDetail">再次咨询</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="remommendbox">
|
||||
<consult-list> </consult-list>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</van-popup>
|
||||
<dialog showDialog="{{showDialog}}" cancelBtn="{{false}}" confirmtext="知道了" message="{{message}}"></dialog>
|
||||
|
||||
636
TUIService/TUIKit/components/TUIChat/index.wxss
Normal file
636
TUIService/TUIKit/components/TUIChat/index.wxss
Normal file
@ -0,0 +1,636 @@
|
||||
.container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
|
||||
.safetytips-box {
|
||||
background: rgba(255, 149, 0, 0.1);
|
||||
padding: 9px;
|
||||
}
|
||||
|
||||
.safetytips {
|
||||
font-family: 'PingFang SC';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 24rpx;
|
||||
line-height: 36rpx;
|
||||
text-align: justify;
|
||||
color: #FF8C39;
|
||||
}
|
||||
|
||||
.report {
|
||||
float: right;
|
||||
color: #006EFF;
|
||||
}
|
||||
|
||||
.tui-navigatorbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 750rpx;
|
||||
height: 172rpx;
|
||||
background: rgba(237, 237, 237, 0.9);
|
||||
backdrop-filter: blur(20px);
|
||||
}
|
||||
.tui-navigatorbar-back {
|
||||
position: absolute;
|
||||
width: 30rpx;
|
||||
height: 60rpx;
|
||||
left:0rpx;
|
||||
padding-left:40rpx;
|
||||
padding-right:40rpx;
|
||||
bottom: 15rpx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.tui-chatroom-navigatorbar {
|
||||
position: relative;
|
||||
/*top: 0;*/
|
||||
flex-shrink: 0;
|
||||
width: 750rpx;
|
||||
height: 176rpx;
|
||||
|
||||
}
|
||||
|
||||
.tui-chatroom-navigatorbar-back {
|
||||
position: absolute;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
left: 24rpx;
|
||||
bottom: 15rpx;
|
||||
}
|
||||
|
||||
.conversation-title {
|
||||
position: absolute;
|
||||
width: 350rpx;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
font-size: 36rpx;
|
||||
color: #000;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
bottom: 0;
|
||||
left:50%;
|
||||
text-align: center;
|
||||
transform: translateX(-50%);
|
||||
|
||||
}
|
||||
.list-box{
|
||||
width: 100vw;
|
||||
flex:1;
|
||||
margin-top: 172rpx;
|
||||
|
||||
}
|
||||
.list-box.nobottom{
|
||||
margin-bottom: 300rpx;
|
||||
}
|
||||
/* 旧样式 */
|
||||
/* .list-box {
|
||||
position: absolute;
|
||||
width: 100vw;
|
||||
height: calc(100vh - 250px);
|
||||
top: 172rpx;
|
||||
}
|
||||
.list-box.nobottom{
|
||||
background-color: red;
|
||||
height: calc(100vh - 172rpx);
|
||||
} */
|
||||
.list-box-notips {
|
||||
height: calc(100vh - 284px);
|
||||
}
|
||||
|
||||
.list-box-group {
|
||||
background:blue;
|
||||
height: calc(100vh - 248px);
|
||||
top: 254rpx;
|
||||
}
|
||||
|
||||
.list-box-group-notips {
|
||||
background:red;
|
||||
height: calc(100vh - 320px) !important;
|
||||
top: 246rpx;
|
||||
}
|
||||
.input-area{
|
||||
height:auto;
|
||||
}
|
||||
/* 旧样式 */
|
||||
/* .input-area {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
} */
|
||||
|
||||
.message-list {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height:100%;
|
||||
}
|
||||
.mylist{
|
||||
position: absolute;
|
||||
top:94rpx;
|
||||
width:100%;
|
||||
bottom: 0px;
|
||||
flex:1;
|
||||
}
|
||||
.message-input {
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
padding-bottom: var(--padding);
|
||||
/* background-color: #F1F1F1; */
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.calling {
|
||||
position: fixed;
|
||||
z-index: 199;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.group-profile {
|
||||
top: 151rpx;
|
||||
left: 0;
|
||||
z-index: 8;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.statusbox {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
/* position: absolute;
|
||||
top: 172rpx; */
|
||||
align-items: center;
|
||||
z-index: 22;
|
||||
height: 94rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 4px 10px 0px rgba(204, 204, 204, 0.5);
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.statusbox .status {
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
color: #333333;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.statusbox .bar{
|
||||
margin:0 20rpx;
|
||||
}
|
||||
|
||||
.listwraper{
|
||||
border-bottom:1rpx solid #E7E7E7;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding:30rpx 0rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.listwraper:last-child{
|
||||
border-bottom:none;
|
||||
}
|
||||
.statusbox .orderDetail{
|
||||
padding:0 20rpx;
|
||||
height: 60rpx;
|
||||
white-space: nowrap;
|
||||
background: #F8F8F8;
|
||||
margin-right: 32rpx;
|
||||
border-radius: 6rpx;
|
||||
transform: rotateZ(360deg);
|
||||
border: 1rpx solid rgba(5,5,5,0.1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 26rpx;
|
||||
color: #353535;
|
||||
}
|
||||
.statusbox .red{
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color:rgba(239, 79, 32, 1);
|
||||
}
|
||||
.circle {
|
||||
margin-left: 32rpx;
|
||||
margin-right: 16rpx;
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
background: #2FCED7;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.statusbox .desc{
|
||||
display: flex;
|
||||
align-items:baseline;
|
||||
}
|
||||
.statusbox .item{
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.statusdesc {
|
||||
height: 94rpx;
|
||||
line-height: 94rpx;
|
||||
margin-right: 32rpx;
|
||||
white-space: nowrap;
|
||||
color: #999999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.headbox {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
z-index: 222;
|
||||
bottom: 410rpx;
|
||||
width: 140rpx;
|
||||
display: flex;
|
||||
|
||||
align-items: center;
|
||||
height: 160rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 4rpx 10rpx 0rpx rgba(204, 204, 204, 0.5);
|
||||
border-radius: 20rpx 0px 0px 20rpx;
|
||||
}
|
||||
|
||||
.headbox .guanzhu {
|
||||
width: 100rpx;
|
||||
height: 40rpx;
|
||||
position: absolute;
|
||||
bottom: 15rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: #3CC7C0;
|
||||
border-radius: 20rpx;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.headicon {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.headbox .close {
|
||||
top: -15rpx;
|
||||
left: -15rpx;
|
||||
position: absolute;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.help{
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.functionbox {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
border: 1rpx solid #E7E7E7;
|
||||
}
|
||||
|
||||
.contact {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
line-height: 60rpx;
|
||||
justify-content: center;
|
||||
top: -62rpx;
|
||||
width: 128rpx;
|
||||
height: 66rpx;
|
||||
color: #333333;
|
||||
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABCCAYAAACfHt50AAACV0lEQVR4Xu3XvaoaQRjG8Vl3AxERBYOICAYRUmgK2cUy/Umq3EFuI5eQG8gNpEiRKkXgdKZfvwpTBWGJeECbTSFRIjuGTXGaQHDTTZ7/qU4xg7Pz/Hjfeb3pdHox/MnegJcDCMNQ9gKUP3w2mxkACAsAgHD4+acDAAC0AGUDVADl9GkB4ukDAAC0AHEDAAAAU4CyASqAcvo8AsXTBwAAaAHiBgAAAKYAZQNUAOX0eQSKpw8AANACxA0AAABMAcoGqADK6fMIFE8fAACgBYgbAAAAmAKUDVABlNPnESiePgAAQAsQNwAAADAFKBugAiinzyNQPH0AAIAWIG4AAABgClA2QAVQTp9HoHj6AAAALUDcAAAAwBSgbIAKoJw+j0Dx9AEAAFqAuAEAAIApQNkAFUA5fR6B4ukDAAC0AHED9wCGw+F/fRW+75sgCAp94/l8NtbaQntcW7xarX5PAV9dO3jR8wZB0O33+w8qlcpVW9M0NUmS/LDW3l21weFFnsNnv/rocRzf+L7/odfrVWq12l/37fd7s9ls7qy1L8bj8fLqH3F0oQSAPJvlcjnOsuxTt9t91Gg0/ojrcrmY7XZrdrvdF2PM8yiKvjmaaaFjywDIbyWO4yelUum23W4/brVa9xeV9/okSUyapp993385Go2+F7pFhxdLAchzms/nbWvtbbPZfNrpdEyWZWa9XpvD4fC+XC6/GgwGPx3Os/DR5QDkN7RYLOrW2o/1ev3Z8Xg0p9PpTRiGrz3PuxS+Qcc3SALIM5tMJg+r1eq7/N8oit46nuM/H/8XJ/zgYgJgSv4AAAAASUVORK5CYII=) no-repeat center center;
|
||||
background-size: cover;
|
||||
}
|
||||
.contactCustom{
|
||||
display: flex;
|
||||
line-height: 60rpx;
|
||||
padding: 0;
|
||||
justify-content: center;
|
||||
width:100%;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.infobox {
|
||||
position: relative;
|
||||
|
||||
z-index: 1;
|
||||
/* overflow-y: scroll;
|
||||
-webkit-overflow-scrolling: touch; */
|
||||
margin-top: 40rpx;
|
||||
padding: 22rpx 20rpx 40rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.namebox .head {
|
||||
width: 80rpx;
|
||||
height:80rpx;
|
||||
flex-shrink: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.namebox .guanzhu image {
|
||||
width: 28rpx;
|
||||
height: 26rpx;
|
||||
}
|
||||
|
||||
.namebox {
|
||||
display: flex;
|
||||
|
||||
}
|
||||
|
||||
.namewraper {
|
||||
max-width:530rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.namebox .row {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
}
|
||||
|
||||
.namebox {
|
||||
display: flex;
|
||||
padding:0 52rpx;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.namebox .name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.position {
|
||||
font-size: 30rpx;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
.doctor_title{
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.hospital {
|
||||
color: #333333;
|
||||
margin-top: 12rpx;
|
||||
font-size: 28rpx;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
.type {
|
||||
height: 32rpx;
|
||||
display: flex;
|
||||
margin-bottom: 6rpx;
|
||||
line-height: 32rpx;
|
||||
white-space: nowrap;
|
||||
align-items: center;
|
||||
margin-left: 18rpx;
|
||||
padding: 0rpx 6rpx;
|
||||
background: #ED9C00;
|
||||
border-radius: 4rpx;
|
||||
color: #FFFFFF;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.namebox .position {
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
margin-left: 15rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.descbox {
|
||||
padding: 0 15rpx;
|
||||
margin-top: 20rpx;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.descbox .number {
|
||||
color: #333333;
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.descbox .name {
|
||||
margin-top: 15rpx;
|
||||
color: #999999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.goodjob {
|
||||
color: #666666;
|
||||
margin-top: 38rpx;
|
||||
line-height: 42rpx;
|
||||
margin-left: 100rpx;
|
||||
font-size: 28rpx;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
|
||||
}
|
||||
.renzhenbox {
|
||||
margin-top: 18rpx;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.renzhenbox view {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.renzhen image {
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
}
|
||||
|
||||
.renzhen text {
|
||||
font-weight: 600;
|
||||
color: #3CC7C0;
|
||||
font-size: 24rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.intro image {
|
||||
width: 10rpx;
|
||||
height: 18rpx;
|
||||
}
|
||||
|
||||
.intro text {
|
||||
color: #333333;
|
||||
margin-right: 10rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.van-icon-cross{
|
||||
color:#333;
|
||||
|
||||
}
|
||||
.van-popup__close-icon{
|
||||
position: absolute!important;
|
||||
|
||||
}
|
||||
.van-popup--bottom
|
||||
.rowintro{
|
||||
margin-top: 30rpx;
|
||||
display: flex;
|
||||
color: #333333;
|
||||
font-size: 34rpx;
|
||||
align-items: center;
|
||||
}
|
||||
.rowintro image{
|
||||
width: 32rpx;
|
||||
height:35rpx;
|
||||
}
|
||||
.rowintro text{
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
.borderbox{
|
||||
position: relative;
|
||||
padding-bottom: 30rpx;
|
||||
margin:0 52rpx;
|
||||
border-bottom:1rpx solid #E7E7E7;
|
||||
}
|
||||
|
||||
.ellipsis{
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden
|
||||
}
|
||||
.goodat{
|
||||
display: flex
|
||||
}
|
||||
.mypop{
|
||||
box-shadow: 0 0 10px #ccc;
|
||||
}
|
||||
.consultwraper{
|
||||
overflow-y:scroll ;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
.popwrper{
|
||||
top:0rpx;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
transition: height 0.5s;
|
||||
width:100%;
|
||||
overflow: hidden;
|
||||
height:100%;
|
||||
bottom:0px;
|
||||
}
|
||||
.close{
|
||||
z-index:9;
|
||||
width: 32rpx;
|
||||
height:32rpx;
|
||||
position: absolute;
|
||||
right:30rpx;
|
||||
top:30rpx;
|
||||
}
|
||||
.popname{
|
||||
margin-top: 45rpx;
|
||||
padding:20rpx 52rpx 0;
|
||||
font-size: 34rpx;
|
||||
color:#333;
|
||||
font-weight: 600;
|
||||
}
|
||||
.consultbox{
|
||||
margin-left: 100rpx;
|
||||
display: flex;
|
||||
margin-top: 20rpx;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.consultbox{
|
||||
color: #333333;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.consultbox .btn{
|
||||
width: 160rpx;
|
||||
height: 60rpx;
|
||||
background: #3CC7C0;
|
||||
color:#fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
.price{
|
||||
color:#EF4F20;
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.viewwrap{
|
||||
border-bottom:1rpx solid #E7E7E7;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding:30rpx 0rpx 30rpx;
|
||||
margin:0 52rpx;
|
||||
display: flex;
|
||||
}
|
||||
.viewwrap .right{
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.viewwrap .price{
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
.viewwrap .name{
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #333333
|
||||
}
|
||||
.top{
|
||||
position: absolute;
|
||||
top:20rpx;
|
||||
width:100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding:20rpx 0;
|
||||
}
|
||||
.top .up{
|
||||
width:40rpx;
|
||||
height:22rpx;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
.top .up.active{
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.leftimg{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
.price .unit{
|
||||
color:#333;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.zxicon{
|
||||
width:80rpx;
|
||||
height:80rpx;
|
||||
}
|
||||
@ -0,0 +1,338 @@
|
||||
import { caculateTimeago } from '../../../../utils/common';
|
||||
const app = getApp();
|
||||
// eslint-disable-next-line no-undef
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
conversation: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(conversation) {
|
||||
this.setData({
|
||||
conversationName: this.getConversationName(conversation),
|
||||
setConversationAvatar: this.setConversationAvatar(conversation),
|
||||
});
|
||||
this.setMuteIcon(conversation);
|
||||
this.showMuteIconImg(conversation);
|
||||
this.$updateTimeAgo(conversation);
|
||||
this.setPinName(conversation.isPinned);
|
||||
},
|
||||
},
|
||||
charge: {
|
||||
type: Boolean,
|
||||
value: {},
|
||||
observer(charge) {
|
||||
if (!charge) {
|
||||
this.setData({
|
||||
xScale: 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
statusList: {
|
||||
type: Array,
|
||||
value: [],
|
||||
observer(statusList) {
|
||||
this.setUserStatus(this.data.conversation, statusList);
|
||||
},
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
xScale: 0,
|
||||
conversationName: '',
|
||||
conversationAvatar: '',
|
||||
conversation: {},
|
||||
showName: '',
|
||||
showMessage: '',
|
||||
showPin: '置顶聊天',
|
||||
showMute: '消息免打扰',
|
||||
popupToggle: false,
|
||||
isTrigger: false,
|
||||
num: 0,
|
||||
setShowName: '',
|
||||
showMuteIcon: false,
|
||||
showStatus: false,
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
},
|
||||
|
||||
},
|
||||
pageLifetimes: {
|
||||
// 展示已经置顶的消息和更新时间戳
|
||||
show() {
|
||||
this.showMuteIconImg(this.data.conversation);
|
||||
this.setPinName(this.data.conversation.isPinned);
|
||||
this.setMuteIcon(this.data.conversation);
|
||||
this.$updateTimeAgo(this.data.conversation);
|
||||
},
|
||||
// 隐藏动画
|
||||
hide() {
|
||||
this.setData({
|
||||
xScale: 0,
|
||||
});
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
// 切换置顶聊天状态
|
||||
setPinName(isPinned) {
|
||||
this.setData({
|
||||
showPin: isPinned ? '取消置顶' : '置顶聊天',
|
||||
});
|
||||
},
|
||||
// 切换免打扰状态
|
||||
setMuteIcon(conversation) {
|
||||
this.setData({
|
||||
showMute: (conversation.messageRemindType === 'AcceptNotNotify') ? '取消免打扰' : '消息免打扰',
|
||||
});
|
||||
},
|
||||
// 先查 remark;无 remark 查 (c2c)nick/(group)name;最后查 (c2c)userID/(group)groupID
|
||||
// 群会话,先展示namecard,无namecard展示nick,最展示UserID
|
||||
getConversationName(conversation) {
|
||||
if (conversation.type === '@TIM#SYSTEM') {
|
||||
return '系统通知';
|
||||
}
|
||||
if (conversation.type === 'C2C') {
|
||||
return conversation.remark || conversation.userProfile.nick || conversation.userProfile.userID;
|
||||
}
|
||||
if (conversation.type === 'GROUP') {
|
||||
if (conversation.lastMessage.nameCard !== '') {
|
||||
this.data.setShowName = conversation.lastMessage.nameCard;
|
||||
} else if (conversation.lastMessage.nick !== '') {
|
||||
this.data.setShowName = conversation.lastMessage.nick;
|
||||
} else {
|
||||
if (conversation.lastMessage.fromAccount === wx.$chat_userID) {
|
||||
this.data.setShowName = '我';
|
||||
} else {
|
||||
this.data.setShowName = conversation.lastMessage.fromAccount;
|
||||
}
|
||||
}
|
||||
this.setData({
|
||||
showName: this.data.setShowName,
|
||||
});
|
||||
return conversation.groupProfile.name || conversation.groupProfile.groupID;
|
||||
}
|
||||
},
|
||||
// 设置会话的头像
|
||||
setConversationAvatar(conversation) {
|
||||
if (conversation.type === '@TIM#SYSTEM') {
|
||||
return 'https://web.sdk.qcloud.com/component/TUIKit/assets/system.png';
|
||||
}
|
||||
if (conversation.type === 'C2C') {
|
||||
return conversation.userProfile.avatar || 'https://sdk-web-1252463788.cos.ap-hongkong.myqcloud.com/component/TUIKit/assets/avatar_21.png';
|
||||
}
|
||||
if (conversation.type === 'GROUP') {
|
||||
return conversation.groupProfile.avatar || '../../../../static/assets/gruopavatar.svg';
|
||||
}
|
||||
},
|
||||
// 删除会话
|
||||
deleteConversation() {
|
||||
wx.showModal({
|
||||
content: '确认删除会话?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'conversationOptions',
|
||||
ext1: 'conversation-delete',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
wx.$TUIKit.deleteConversation(this.data.conversation.conversationID);
|
||||
this.setData({
|
||||
conversation: {},
|
||||
xScale: 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
// 消息置顶
|
||||
pinConversation() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'conversationOptions',
|
||||
ext1: 'conversation-top',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
wx.$TUIKit.pinConversation({ conversationID: this.data.conversation.conversationID, isPinned: true })
|
||||
.then(() => {
|
||||
this.setData({
|
||||
xScale: 0,
|
||||
});
|
||||
})
|
||||
.catch((imError) => {
|
||||
console.warn('pinConversation error:', imError); // 置顶会话失败的相关信息
|
||||
});
|
||||
if (this.data.showPin === '取消置顶') {
|
||||
wx.$TUIKit.pinConversation({ conversationID: this.data.conversation.conversationID, isPinned: false })
|
||||
.then(() => {
|
||||
this.setData({
|
||||
xScale: 0,
|
||||
});
|
||||
})
|
||||
.catch((imError) => {
|
||||
console.warn('pinConversation error:', imError); // 置顶会话失败的相关信息
|
||||
});
|
||||
}
|
||||
},
|
||||
// 是否显示免打扰图标
|
||||
showMuteIconImg(conversation) {
|
||||
if (conversation.messageRemindType === 'AcceptNotNotify') {
|
||||
this.setData({
|
||||
showMuteIcon: true,
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
showMuteIcon: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
// 消息免打扰
|
||||
muteNotifications() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'conversationOptions',
|
||||
ext1: 'conversation-mutenotifications',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
let newShowMute = '';
|
||||
let newShowMuteIcon = false;
|
||||
let messageRemindType = wx.$TUIKitTIM.TYPES.MSG_REMIND_ACPT_NOT_NOTE;
|
||||
if (this.data.showMute === '消息免打扰') {
|
||||
newShowMute = '取消免打扰';
|
||||
newShowMuteIcon = true;
|
||||
messageRemindType = wx.$TUIKitTIM.TYPES.MSG_REMIND_ACPT_NOT_NOTE;
|
||||
}
|
||||
if (this.data.showMute === '取消免打扰') {
|
||||
newShowMute = '消息免打扰';
|
||||
newShowMuteIcon = false;
|
||||
messageRemindType = wx.$TUIKitTIM.TYPES.MSG_REMIND_ACPT_AND_NOTE;
|
||||
}
|
||||
|
||||
if (this.data.conversation.type === 'C2C') {
|
||||
// C2C 消息免打扰,一般的实现是在线接收消息,离线不接收消息(在有离线推送的情况下),v2.16.0起支持
|
||||
const { userID } = this.data.conversation.userProfile;
|
||||
wx.$TUIKit.setMessageRemindType({
|
||||
userIDList: [userID],
|
||||
messageRemindType,
|
||||
})
|
||||
.then((imResponse) => {
|
||||
this.setData({
|
||||
xScale: 0,
|
||||
showMuteIcon: newShowMuteIcon,
|
||||
showMute: newShowMute,
|
||||
});
|
||||
})
|
||||
.catch((imError) => {
|
||||
console.warn('setMessageRemindType error:', imError);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.data.conversation.type === 'GROUP') {
|
||||
const { groupID } = this.data.conversation.groupProfile;
|
||||
// 群消息免打扰,一般的实现是在线接收消息,离线不接收消息(在有离线推送的情况下)
|
||||
wx.$TUIKit.setMessageRemindType({
|
||||
groupID,
|
||||
messageRemindType,
|
||||
})
|
||||
.then((imResponse) => {
|
||||
this.setData({
|
||||
xScale: 0,
|
||||
showMuteIcon: newShowMuteIcon,
|
||||
showMute: newShowMute,
|
||||
});
|
||||
// 设置消息免打扰成功
|
||||
})
|
||||
.catch((imError) => {
|
||||
// 设置消息免打扰失败
|
||||
console.warn('setMessageRemindType error:', imError);
|
||||
});
|
||||
}
|
||||
},
|
||||
// 控制左滑动画
|
||||
handleTouchMove(e) {
|
||||
this.setData({
|
||||
num: e.detail.x,
|
||||
});
|
||||
if (e.detail.x < 0 && !this.data.isTrigger) {
|
||||
this.setData({
|
||||
isTrigger: true,
|
||||
});
|
||||
this.triggerEvent('transCheckID', {
|
||||
checkID: this.data.conversation.conversationID,
|
||||
});
|
||||
}
|
||||
if (e.detail.x === 0) {
|
||||
this.setData({
|
||||
isTrigger: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
handleTouchEnd() {
|
||||
if (this.data.num < -wx.getSystemInfoSync().windowWidth / 5) {
|
||||
this.setData({
|
||||
xScale: -wx.getSystemInfoSync().windowWidth,
|
||||
});
|
||||
}
|
||||
if (this.data.num >= -wx.getSystemInfoSync().windowWidth / 5 && this.data.num < 0) {
|
||||
this.setData({
|
||||
xScale: 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
// 更新会话的时间戳,显示会话里的最后一条消息
|
||||
$updateTimeAgo(conversation) {
|
||||
if (conversation.conversationID && conversation.lastMessage.lastTime) {
|
||||
conversation.lastMessage.timeago = caculateTimeago(conversation.lastMessage.lastTime * 1000);
|
||||
if (conversation.lastMessage.isRevoked) {
|
||||
this.setData({
|
||||
showMessage: '撤回了一条消息',
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
showMessage: conversation.lastMessage.messageForShow,
|
||||
});
|
||||
}
|
||||
this.setData({
|
||||
conversation,
|
||||
});
|
||||
}
|
||||
},
|
||||
// 会话头像显示失败显示的默认头像
|
||||
handleimageerro() {
|
||||
this.setData({
|
||||
setConversationAvatar: '../../../../static/assets/gruopavatar.svg',
|
||||
});
|
||||
},
|
||||
// 判断该用户的状态并展示出来
|
||||
setUserStatus(conversation, statusList) {
|
||||
// if (!wx.getStorageSync('showOnlineStatus')) return;
|
||||
const currentUserID = wx.getStorageSync('currentUserID');
|
||||
if (currentUserID.includes(wx.$chat_userID)) {
|
||||
this.setData({
|
||||
getStatus: wx.getStorageSync(wx.$chat_userID),
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
getStatus: true,
|
||||
});
|
||||
}
|
||||
if (conversation.type !== wx.$TUIKitTIM.TYPES.CONV_C2C) return;
|
||||
statusList.forEach((item) => {
|
||||
if (item.userID !== conversation.userProfile.userID) return;
|
||||
const showStatus = (item.statusType === 1);
|
||||
this.setData({
|
||||
showStatus,
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
<movable-area wx:if="{{conversation.conversationID}}" class="t-conversation-item-container">
|
||||
<movable-view
|
||||
class="t-conversation-item {{conversation.isPinned && 't-conversation-pinneditem'}}"
|
||||
bind:touchend="handleTouchEnd" direction="horizontal" bindchange="handleTouchMove" damping="100"
|
||||
x="{{xScale}}" inertia out-of-bounds
|
||||
>
|
||||
<view class="avatar-box">
|
||||
<image class="t-conversation-item-avatar" src="{{setConversationAvatar}}" binderror="handleimageerro">
|
||||
</image>
|
||||
<view class="right-box">
|
||||
<view
|
||||
class="unread"
|
||||
wx:if="{{conversation.unreadCount !== 0 && conversation.messageRemindType !== 'AcceptNotNotify'}}"
|
||||
>
|
||||
<view class="read-text" wx:if="{{conversation.unreadCount > 99}}">99+</view>
|
||||
<view class="read-text" wx:else>{{conversation.unreadCount}}</view>
|
||||
</view>
|
||||
<view wx:if="{{conversation.unreadCount !== 0}}">
|
||||
<view class="unread-mute" wx:if="{{conversation.messageRemindType === 'AcceptNotNotify'}}">
|
||||
</view>
|
||||
</view>
|
||||
<i wx:if="{{conversation.type === 'C2C' && getStatus && showStatus}}" class="status {{showStatus && 'status-online'}}"></i>
|
||||
<i wx:if="{{conversation.type === 'C2C' && getStatus && !showStatus}}" class="statusType {{!showStatus && 'status-offline'}}"></i>
|
||||
</view>
|
||||
</view>
|
||||
<view class="t-conversation-item-content">
|
||||
<label class="tui-conversation-item-name">{{conversationName}}</label>
|
||||
<view class="tui-conversation-box">
|
||||
<view class="tui-conversation-lastName" wx:if="{{conversation.type === 'GROUP'}}">
|
||||
<text>{{showName}}:</text>
|
||||
</view>
|
||||
<view class="tui-conversation-lastMessage"
|
||||
wx:if="{{conversation.unreadCount !== 0 && conversation.messageRemindType === 'AcceptNotNotify'}}">
|
||||
<view class="text-box">
|
||||
<text>[{{conversation.unreadCount}}条]</text>
|
||||
<text class="lastMessage-payload">{{showMessage}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:else class="tui-conversation-lastMessage">
|
||||
<text class="lastMessage-payload">{{showMessage}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="t-conversation-item-box">
|
||||
<view class="t-conversation-item-info">
|
||||
{{conversation.lastMessage.timeago}}
|
||||
</view>
|
||||
<view wx:if="{{showMuteIcon}}" class="t-conversation-item-mutenotifications">
|
||||
<image class="t-conversation-mutenotifications-img" src="../../../../static/images/mutenotifications.png"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="t-conversation-box">
|
||||
<view class="t-conversation-mutenotifications" catchtap="muteNotifications">{{showMute}}</view>
|
||||
<view class="t-conversation-pinconversation" catchtap="pinConversation">{{showPin}}</view>
|
||||
<view class="t-conversation-delete" catchtap="deleteConversation">删除</view>
|
||||
</view>
|
||||
</movable-view>
|
||||
</movable-area>
|
||||
|
||||
@ -0,0 +1,188 @@
|
||||
.t-conversation-item-container {
|
||||
width: 100vw;
|
||||
height: 150rpx;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
.t-conversation-item {
|
||||
width: 162vw;
|
||||
height: 150rpx;
|
||||
display: flex;
|
||||
left: 0;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 2rpx solid #EEF0F3;
|
||||
}
|
||||
.t-conversation-pinneditem{
|
||||
width: 162vw;
|
||||
height: 150rpx;
|
||||
display: flex;
|
||||
left: 0;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1rpx solid #999999;
|
||||
background-color: #EEF0F3
|
||||
}
|
||||
.text-box{
|
||||
display: flex;
|
||||
}
|
||||
.avatar-box{
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
}
|
||||
.t-conversation-item-avatar{
|
||||
position: relative;
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
border-radius: 14rpx;
|
||||
/*padding-left: 40rpx;*/
|
||||
/*padding-right: 24rpx;*/
|
||||
/*padding-bottom: 28rpx;*/
|
||||
/*padding-top: 28rpx;*/
|
||||
margin: 0 16rpx;
|
||||
overflow: auto;
|
||||
}
|
||||
.t-conversation-item-content {
|
||||
flex: 1;
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
.t-conversation-item-info {
|
||||
line-height: 34rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.t-error {
|
||||
background-color: #fb5250;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.t-conversation-delete {
|
||||
width: 144rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #E85454;
|
||||
color: #FFFFFF;
|
||||
line-height: 44rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.t-conversation-item-mutenotifications{
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
.t-conversation-mutenotifications-img{
|
||||
height: 34rpx;
|
||||
width: 28rpx;
|
||||
float: right;
|
||||
}
|
||||
.t-conversation-pinconversation{
|
||||
width: 144rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #006EFF;
|
||||
color: #FFFFFF;
|
||||
line-height: 44rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.t-conversation-mutenotifications{
|
||||
width: 180rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: orange;
|
||||
color: #FFFFFF;
|
||||
line-height: 44rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.tui-conversation-item-name {
|
||||
line-height: 50rpx;
|
||||
font-size: 36rpx;
|
||||
font-family: 'PingFangSC-Regular';
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.tui-conversation-lastMessage {
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
font-family: 'PingFangSC-Regular';
|
||||
color: #999999;
|
||||
max-width: 64vw;
|
||||
display: inline-block;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.right-box{
|
||||
display:flex;
|
||||
position: absolute;
|
||||
top: -10rpx;
|
||||
right: 31rpx;
|
||||
}
|
||||
.unread {
|
||||
position: absolute;
|
||||
top: -5rpx;
|
||||
right: -25rpx;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #ffffff;
|
||||
background-color: red;
|
||||
justify-content: center;
|
||||
}
|
||||
.unread-mute{
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
background: #FA5151;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0rpx;
|
||||
right: -20rpx;
|
||||
}
|
||||
.read-text {
|
||||
line-height: 15px;
|
||||
font-size: 10px;
|
||||
}
|
||||
.tui-conversation-box{
|
||||
display: flex;
|
||||
}
|
||||
.tui-conversation-lastName{
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
font-family: 'PingFangSC-Regular';
|
||||
color: #999999;
|
||||
}
|
||||
.t-conversation-box{
|
||||
height: 150rpx;
|
||||
display: flex
|
||||
}
|
||||
.status {
|
||||
position: relative;
|
||||
top: 84rpx;
|
||||
left: 23rpx;
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
opacity: 1;
|
||||
border-radius: 8px;
|
||||
background: #29CC85;
|
||||
}
|
||||
.statusType {
|
||||
position: relative;
|
||||
top: 84rpx;
|
||||
left: 23rpx;
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
opacity: 1;
|
||||
border-radius: 8px;
|
||||
background: #A4A4A4;
|
||||
}
|
||||
.status-online {
|
||||
border: 4rpx solid white;
|
||||
}
|
||||
.status-offline{
|
||||
border: 4rpx solid white;
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
// Component Object
|
||||
Component({
|
||||
properties: {
|
||||
myProperty: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer() {},
|
||||
},
|
||||
|
||||
},
|
||||
data: {
|
||||
userID: '',
|
||||
searchUser: {},
|
||||
myID: '',
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
this.triggerEvent('showConversation');
|
||||
},
|
||||
// 获取输入的 UserID
|
||||
userIDInput(e) {
|
||||
this.setData({
|
||||
userID: e.detail.value,
|
||||
searchUser: {},
|
||||
});
|
||||
},
|
||||
// 获取该 UserID 对应的个人资料
|
||||
getuserProfile() {
|
||||
wx.$TUIKit.getUserProfile({
|
||||
userIDList: [this.data.userID],
|
||||
}).then((imRes) => {
|
||||
if (imRes.data.length > 0) {
|
||||
this.setData({
|
||||
searchUser: imRes.data[0],
|
||||
});
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: '用户不存在',
|
||||
icon: 'error',
|
||||
});
|
||||
this.setData({
|
||||
userID: '',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 选择发起会话
|
||||
handleChoose() {
|
||||
this.data.searchUser.isChoose = !this.data.searchUser.isChoose;
|
||||
this.setData({
|
||||
searchUser: this.data.searchUser,
|
||||
});
|
||||
},
|
||||
// 确认邀请
|
||||
bindConfirmInvite() {
|
||||
if (this.data.searchUser.isChoose) {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'conversationType',
|
||||
ext1: 'conversationType-c2c',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
this.triggerEvent('searchUserID', { searchUserID: `C2C${this.data.searchUser.userID}` });
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: '请选择相关用户',
|
||||
icon: 'none',
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
},
|
||||
attached() {
|
||||
this.setData({
|
||||
myID: wx.$chat_userID,
|
||||
});
|
||||
},
|
||||
ready() {
|
||||
|
||||
},
|
||||
moved() {
|
||||
|
||||
},
|
||||
detached() {
|
||||
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<view class="TUI-Create-conversation-container">
|
||||
<view class="tui-navigatorbar">
|
||||
<image class="tui-navigatorbar-back" bindtap="goBack" src="../../../../static/assets/back.png" />
|
||||
<view class="conversation-title">发起会话</view>
|
||||
</view>
|
||||
<view class="tui-search-area">
|
||||
<view class="tui-search-bar">
|
||||
<image class="tui-searchcion" src="../../../../static/assets/serach-icon.svg" />
|
||||
<input class="tui-search-bar-input" value="{{userID}}" placeholder="请输入用户ID" bindinput='userIDInput' bindconfirm="getuserProfile" bindblur="getuserProfile"/>
|
||||
|
||||
</view>
|
||||
<view class="tui-showID">您的用户ID {{myID}}</view>
|
||||
</view>
|
||||
<view class="tui-person-to-invite" wx:if="{{searchUser.userID}}" bindtap="handleChoose" >
|
||||
<image class="tui-normal-choose" src="{{searchUser.isChoose ? '../../../../static/assets/single-choice-hover.svg' : '../../../../static/assets/single-choice-normal.svg'}}" />
|
||||
<view class="tui-person-profile">
|
||||
<image class="tui-person-profile-avatar" src="{{searchUser.avatar || 'https://sdk-web-1252463788.cos.ap-hongkong.myqcloud.com/component/TUIKit/assets/avatar_21.png' }}" />
|
||||
<view>
|
||||
<view class="tui-person-profile-nick">{{searchUser.nick}}</view>
|
||||
<view class="tui-person-profile-userID">用户ID:{{searchUser.userID}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tui-confirm-btn" bindtap="bindConfirmInvite">确认邀请</view>
|
||||
</view>
|
||||
@ -0,0 +1,138 @@
|
||||
.TUI-Create-conversation-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #F4F5F9;
|
||||
}
|
||||
|
||||
.tui-navigatorbar{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 750rpx;
|
||||
height: 170rpx;
|
||||
background-color: #006EFF;
|
||||
}
|
||||
|
||||
.tui-navigatorbar-back{
|
||||
position: absolute;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
left: 24rpx;
|
||||
bottom: 15rpx;
|
||||
}
|
||||
|
||||
.conversation-title {
|
||||
position:absolute;
|
||||
width: 350rpx;
|
||||
height: 88rpx;
|
||||
line-height: 56rpx;
|
||||
font-size: 36rpx;
|
||||
color: #FFFFFF;
|
||||
bottom: 0;
|
||||
left: 200rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tui-search-area {
|
||||
position: absolute;
|
||||
top: 170rpx;
|
||||
width: 750rpx;
|
||||
background-color: #006EFF;
|
||||
}
|
||||
.tui-showID {
|
||||
padding-left: 80rpx;
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: white;
|
||||
height: 50rpx;
|
||||
padding-top: 18rpx;
|
||||
}
|
||||
.tui-search-bar {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
margin-left: 40rpx;
|
||||
margin-top: 32rpx;
|
||||
width: 670rpx;
|
||||
height: 80rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 40rpx;
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
|
||||
.tui-searchcion {
|
||||
display: inline-block;
|
||||
margin-left: 24rpx;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
.tui-search-bar-input {
|
||||
margin-left: 16rpx;
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tui-person-to-invite {
|
||||
position: absolute;
|
||||
top: 352rpx;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
width: 750rpx;
|
||||
height: 150rpx;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.tui-normal-choose {
|
||||
margin-left: 40rpx;
|
||||
margin-right: 40rpx;
|
||||
margin-top: 52rpx;
|
||||
margin-bottom: 50rpx;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
.tui-person-profile {
|
||||
width: 622rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tui-person-profile-avatar {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.tui-person-profile-nick {
|
||||
color: #333333;
|
||||
line-height: 50rpx;
|
||||
font-size: 36rpx;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.tui-person-profile-userID {
|
||||
color: #999999;
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.tui-confirm-btn {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
bottom: 100rpx;
|
||||
width: 670rpx;
|
||||
height: 96rpx;
|
||||
background: #006EFF;
|
||||
color: #FFFFFF;
|
||||
border-radius: 48rpx;
|
||||
border-radius: 48rpx;
|
||||
margin-left: 40rpx;
|
||||
line-height: 44rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
// miniprogram/pages/TUI-Group/create-group/create.js
|
||||
import logger from '../../../../utils/logger';
|
||||
|
||||
Component({
|
||||
properties: {
|
||||
|
||||
},
|
||||
data: {
|
||||
groupTypeList: [
|
||||
],
|
||||
groupType: '',
|
||||
Type: '',
|
||||
name: '',
|
||||
groupID: '',
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
this.triggerEvent('showConversation');
|
||||
},
|
||||
// 展示群列表
|
||||
showGroupTypeList() {
|
||||
this.setData({
|
||||
popupToggle: true,
|
||||
});
|
||||
},
|
||||
// 获取输入的群ID
|
||||
bindGroupIDInput(e) {
|
||||
const id = e.detail.value;
|
||||
this.setData({
|
||||
groupID: id,
|
||||
});
|
||||
},
|
||||
// 获取输入的群名称
|
||||
bindGroupNameInput(e) {
|
||||
const groupname = e.detail.value;
|
||||
this.setData({
|
||||
name: groupname,
|
||||
});
|
||||
},
|
||||
// 创建群聊时,传点击事件对应的值
|
||||
click(e) {
|
||||
this.setData({
|
||||
groupType: e.currentTarget.dataset.value.groupType,
|
||||
Type: e.currentTarget.dataset.value.Type,
|
||||
name: e.currentTarget.dataset.value.name,
|
||||
popupToggle: false,
|
||||
});
|
||||
},
|
||||
// 确认创建群聊
|
||||
bindConfirmCreate() {
|
||||
logger.log(`| TUI-Group | create-group | bindConfirmCreate | groupID: ${this.data.groupID}`);
|
||||
wx.$TUIKit.createGroup({
|
||||
type: this.data.Type,
|
||||
name: this.data.name,
|
||||
groupID: this.data.groupID,
|
||||
}).then((imResponse) => { // 创建成功
|
||||
this.triggerEvent('createGroupID', { createGroupID: `GROUP${imResponse.data.group.groupID}` });
|
||||
// 创建的群的资料
|
||||
wx.aegis.reportEvent({
|
||||
name: 'conversationType',
|
||||
ext1: 'conversationType-group',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
})
|
||||
.catch((imError) => {
|
||||
if (imError.code === 10021) {
|
||||
wx.showToast({
|
||||
title: '该群组ID被使用,请更换群ID',
|
||||
icon: 'none',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 点击空白区域关闭弹窗
|
||||
handleChooseToggle() {
|
||||
this.setData({
|
||||
popupToggle: false,
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
attached() {
|
||||
|
||||
},
|
||||
ready() {
|
||||
const groupTypeList = [
|
||||
{ groupType: '品牌客户群(Work)', Type: wx.$TUIKitTIM.TYPES.GRP_WORK },
|
||||
{ groupType: 'VIP专属群(Public)', Type: wx.$TUIKitTIM.TYPES.GRP_PUBLIC },
|
||||
{ groupType: '临时会议群 (Meeting)', Type: wx.$TUIKitTIM.TYPES.GRP_MEETING },
|
||||
{ groupType: '直播群(AVChatRoom)', Type: wx.$TUIKitTIM.TYPES.GRP_CHATROOM },
|
||||
];
|
||||
this.setData({
|
||||
groupTypeList,
|
||||
});
|
||||
},
|
||||
moved() {
|
||||
|
||||
},
|
||||
detached() {
|
||||
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
<!--miniprogram/pages/TUI-Group/create-group/create.wxml-->
|
||||
<view class="container">
|
||||
<view class="tui-navigatorbar">
|
||||
<image class="tui-navigatorbar-back" bindtap="goBack" src="../../../../static/assets/back.png" />
|
||||
<view class="conversation-title">发起群聊</view>
|
||||
</view>
|
||||
<view class="group-area">
|
||||
<view class="item" catchtap="showGroupTypeList">
|
||||
<view class="group-type" >
|
||||
<view class="icon-box">
|
||||
<text class="icon">*</text>
|
||||
<text class="aside-left">群类型</text>
|
||||
<text class= "aside-right" bindtap="click">{{groupType}}</text>
|
||||
</view>
|
||||
|
||||
<image class=" listimage" src="../../../static/detail.svg"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="group-ID">
|
||||
<text class="aside-left">群ID</text>
|
||||
<input class="input" type="number" placeholder="请输入群ID" bindinput='bindGroupIDInput' placeholder-style="color:#BBBBBB;"/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="item">
|
||||
<view class="group-name">
|
||||
<view class="icon-box">
|
||||
<text class="icon">*</text>
|
||||
<text class="aside-left">群名称</text>
|
||||
</view>
|
||||
<input class="inputname" placeholder="请输入群名称" bindinput='bindGroupNameInput' placeholder-style="color:#BBBBBB;"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="create-area">
|
||||
<view class="group-create" bindtap="bindConfirmCreate">
|
||||
<text>发起群聊</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="pop-mask" wx:if="{{popupToggle}}" catchtap="handleChooseToggle" >
|
||||
<view class="popup-main" catchtap="handleCatchTap">
|
||||
<view wx:for="{{groupTypeList}}" wx:key="id" class="type {{item.groupType === groupType &&'type-active'}}" data-value="{{item}}" bindtap="click">
|
||||
<view class="group-type-list" data-item="{{item}}">
|
||||
<view class="list-type">
|
||||
<view>{{item.groupType}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,182 @@
|
||||
/* miniprogram/pages/TUI-Group/create-group/create.wxss */
|
||||
.container{
|
||||
background: #EEF0F3;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
.tui-navigatorbar{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 750rpx;
|
||||
height: 170rpx;
|
||||
background-color: #006EFF;
|
||||
}
|
||||
|
||||
.tui-navigatorbar-back{
|
||||
position: absolute;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
left: 24rpx;
|
||||
bottom: 15rpx;
|
||||
}
|
||||
|
||||
.conversation-title {
|
||||
position:absolute;
|
||||
width: 350rpx;
|
||||
height: 88rpx;
|
||||
line-height: 56rpx;
|
||||
font-size: 36rpx;
|
||||
color: #FFFFFF;
|
||||
bottom: 0;
|
||||
left: 200rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.group-area{
|
||||
position: absolute;
|
||||
top: 170rpx;
|
||||
width: 750rpx;
|
||||
background-color: #006EFF;
|
||||
}
|
||||
.item{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
}
|
||||
.icon-box{
|
||||
display: flex;
|
||||
}
|
||||
.icon{
|
||||
color:red;
|
||||
padding-top: 34rpx;
|
||||
}
|
||||
.group-type{
|
||||
background: #FFFFFF;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
padding-left: 20px;
|
||||
border-bottom: 1px solid #EEF0F3;
|
||||
border-top: 8px solid #FFFFFF;
|
||||
}
|
||||
.group-ID{
|
||||
background: #FFFFFF;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
padding-left: 20px;
|
||||
border-bottom: 1px solid #EEF0F3;
|
||||
border-top: 8px solid #FFFFFF;
|
||||
}
|
||||
.listimage{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 10px;
|
||||
}
|
||||
.group-name{
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
padding-left: 20px;
|
||||
border-bottom: 1px solid #EEF0F3;
|
||||
border-top: 8px solid #FFFFFF;
|
||||
}
|
||||
.aside-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
float: left;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
letter-spacing: 0;
|
||||
line-height: 56px;
|
||||
}
|
||||
.aside-right{
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 16px;
|
||||
color: black;
|
||||
letter-spacing: 0;
|
||||
padding-left: 104px;
|
||||
line-height: 56px;
|
||||
z-index: 999;
|
||||
}
|
||||
.input{
|
||||
float: right;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 16px;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
text-align: right;
|
||||
line-height: 56px;
|
||||
padding-top: 19px;
|
||||
padding-right: 48px;
|
||||
width: 70%;
|
||||
/* z-index: 999; */
|
||||
}
|
||||
.inputname{
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 16px;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
text-align: right;
|
||||
line-height: 56px;
|
||||
padding-left: 180rpx;
|
||||
padding-top: 19px;
|
||||
width: 50%;
|
||||
}
|
||||
.group-create{
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
bottom: 100rpx;
|
||||
width: 670rpx;
|
||||
height: 96rpx;
|
||||
background: #006EFF;
|
||||
color: #FFFFFF;
|
||||
border-radius: 48rpx;
|
||||
border-radius: 48rpx;
|
||||
line-height: 44rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.pop-mask{
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background: rgba(0,0,0,0.60);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
.create-area{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center
|
||||
}
|
||||
.popup-main{
|
||||
width: 100vw;
|
||||
height: 30%;
|
||||
background: #FFFFFF;
|
||||
padding: 32px 20px;
|
||||
}
|
||||
.group-type-list{
|
||||
width: 100vw;
|
||||
height: 112rpx
|
||||
}
|
||||
.list-type{
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
letter-spacing: 0;
|
||||
line-height: 22px;
|
||||
}
|
||||
.type-active{
|
||||
color: #006EFF;
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
import logger from '../../../../utils/logger';
|
||||
// Component Object
|
||||
Component({
|
||||
properties: {
|
||||
myProperty: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer() {},
|
||||
},
|
||||
|
||||
},
|
||||
data: {
|
||||
groupID: '',
|
||||
searchGroup: {},
|
||||
},
|
||||
methods: {
|
||||
// 回退
|
||||
goBack() {
|
||||
this.triggerEvent('showConversation');
|
||||
},
|
||||
// 获取输入的群ID
|
||||
getGroupIDInput(e) {
|
||||
this.setData({
|
||||
groupID: e.detail.value,
|
||||
});
|
||||
},
|
||||
// 通过输入的群ID来查找群
|
||||
searchGroupByID() {
|
||||
wx.$TUIKit.searchGroupByID(this.data.groupID)
|
||||
.then((imResponse) => {
|
||||
if (imResponse.data.group.groupID !== '') {
|
||||
this.setData({
|
||||
searchGroup: imResponse.data.group,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((imError) => {
|
||||
wx.hideLoading();
|
||||
if (imError.code === 10007) {
|
||||
wx.showToast({
|
||||
title: '讨论组类型群不允许申请加群',
|
||||
icon: 'none',
|
||||
});
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: '未找到该群组',
|
||||
icon: 'none',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 选择查找到的群
|
||||
handleChoose() {
|
||||
this.data.searchGroup.isChoose = !this.data.searchGroup.isChoose;
|
||||
this.setData({
|
||||
searchGroup: this.data.searchGroup,
|
||||
});
|
||||
},
|
||||
// 确认加入
|
||||
bindConfirmJoin() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'conversationType',
|
||||
ext1: 'conversationType-join',
|
||||
ext2: wx.$chat_reportType,
|
||||
ext3: wx.$chat_SDKAppID,
|
||||
});
|
||||
logger.log(`| TUI-Group | join-group | bindConfirmJoin | groupID: ${this.data.groupID}`);
|
||||
wx.$TUIKit.joinGroup({ groupID: this.data.groupID, type: this.data.searchGroup.type })
|
||||
.then((imResponse) => {
|
||||
if (this.data.searchGroup.isChoose) {
|
||||
if (imResponse.data.status === 'WaitAdminApproval') {
|
||||
wx.showToast({
|
||||
title: '等待管理员同意',
|
||||
icon: 'none',
|
||||
});
|
||||
} else {
|
||||
this.triggerEvent('searchGroupID', { searchGroupID: `GROUP${this.data.searchGroup.groupID}` });
|
||||
}
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: '请选择相关群聊',
|
||||
icon: 'error',
|
||||
});
|
||||
}
|
||||
switch (imResponse.data.status) {
|
||||
case wx.$TUIKitTIM.TYPES.JOIN_STATUS_WAIT_APPROVAL:
|
||||
// 等待管理员同意
|
||||
break;
|
||||
case wx.$TUIKitTIM.TYPES.JOIN_STATUS_SUCCESS: // 加群成功
|
||||
break;
|
||||
case wx.$TUIKitTIM.TYPES.JOIN_STATUS_ALREADY_IN_GROUP: // 已经在群中
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
})
|
||||
.catch((imError) => {
|
||||
console.warn('joinGroup error:', imError); // 申请加群失败的相关信息
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
attached() {
|
||||
|
||||
},
|
||||
ready() {
|
||||
|
||||
},
|
||||
moved() {
|
||||
|
||||
},
|
||||
detached() {
|
||||
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<!--miniprogram/pages/TUI-Group/join-group/join.wxml-->
|
||||
<view class="TUI-Create-conversation-container">
|
||||
<view class="tui-navigatorbar">
|
||||
<image class="tui-navigatorbar-back" bindtap="goBack" src="../../../../static/assets/back.png" />
|
||||
<view class="conversation-title">加入群聊</view>
|
||||
</view>
|
||||
<view class="tui-search-area">
|
||||
<view class="tui-search-bar">
|
||||
<image class="tui-searchcion" src="../../../../static/assets/serach-icon.svg" />
|
||||
<input class="tui-search-bar-input" value="{{groupID}}" placeholder="请输入群ID" bindinput='getGroupIDInput' bindconfirm="searchGroupByID" bindblur="searchGroupByID"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tui-person-to-invite" wx:if="{{searchGroup.groupID}}" bindtap="handleChoose">
|
||||
<image class="tui-normal-choose" src="{{searchGroup.isChoose ? '../../../../static/assets/single-choice-hover.svg' : '../../../../static/assets/single-choice-normal.svg'}}" />
|
||||
<view class="tui-person-profile">
|
||||
<image class="tui-person-profile-avatar" src="{{searchGroup.group.avatar || '../../../../static/assets/gruopavatar.svg' }}" />
|
||||
<view>
|
||||
<view class="tui-person-profile-nick"> {{searchGroup.name}}</view>
|
||||
<view class="tui-person-profile-userID">群ID:{{searchGroup.groupID}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tui-confirm-btn" bindtap="bindConfirmJoin">确认加入</view>
|
||||
</view>
|
||||
|
||||
@ -0,0 +1,132 @@
|
||||
.TUI-Create-conversation-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #F4F5F9;
|
||||
}
|
||||
|
||||
.tui-navigatorbar{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 750rpx;
|
||||
height: 176rpx;
|
||||
background-color: #006EFF;
|
||||
}
|
||||
|
||||
.tui-navigatorbar-back{
|
||||
position: absolute;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
left: 24rpx;
|
||||
bottom: 15rpx;
|
||||
}
|
||||
|
||||
.conversation-title {
|
||||
position:absolute;
|
||||
width: 350rpx;
|
||||
height: 88rpx;
|
||||
line-height: 56rpx;
|
||||
font-size: 36rpx;
|
||||
color: #FFFFFF;
|
||||
bottom: 0;
|
||||
left: 200rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tui-search-area {
|
||||
position: absolute;
|
||||
top: 176rpx;
|
||||
width: 750rpx;
|
||||
height: 144rpx;
|
||||
background-color: #006EFF;
|
||||
}
|
||||
|
||||
.tui-search-bar {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
margin-left: 40rpx;
|
||||
margin-top: 32rpx;
|
||||
width: 670rpx;
|
||||
height: 80rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 40rpx;
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
|
||||
.tui-searchcion {
|
||||
display: inline-block;
|
||||
margin-left: 24rpx;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
.tui-search-bar-input {
|
||||
margin-left: 16rpx;
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tui-person-to-invite {
|
||||
position: absolute;
|
||||
top: 320rpx;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
width: 750rpx;
|
||||
height: 150rpx;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.tui-normal-choose {
|
||||
margin-left: 40rpx;
|
||||
margin-right: 40rpx;
|
||||
margin-top: 52rpx;
|
||||
margin-bottom: 50rpx;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
.tui-person-profile {
|
||||
width: 622rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tui-person-profile-avatar {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.tui-person-profile-nick {
|
||||
color: #333333;
|
||||
line-height: 50rpx;
|
||||
font-size: 36rpx;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.tui-person-profile-userID {
|
||||
color: #999999;
|
||||
line-height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.tui-confirm-btn {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
bottom: 100rpx;
|
||||
width: 670rpx;
|
||||
height: 96rpx;
|
||||
background: #006EFF;
|
||||
color: #FFFFFF;
|
||||
border-radius: 48rpx;
|
||||
border-radius: 48rpx;
|
||||
margin-left: 40rpx;
|
||||
line-height: 44rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
255
TUIService/TUIKit/components/TUIConversation/index.js
Normal file
255
TUIService/TUIKit/components/TUIConversation/index.js
Normal file
@ -0,0 +1,255 @@
|
||||
import constant from "../../utils/constant";
|
||||
|
||||
// TUIKitWChat/Conversation/index.js
|
||||
const app = getApp();
|
||||
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
config: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer(config) {
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
conversationList: [],
|
||||
currentConversationID: '',
|
||||
showSelectTag: false,
|
||||
array: [
|
||||
{ id: 1, name: '发起会话' },
|
||||
{ id: 2, name: '发起群聊' },
|
||||
{ id: 3, name: '加入群聊' },
|
||||
],
|
||||
index: Number,
|
||||
unreadCount: 0,
|
||||
conversationInfomation: {},
|
||||
transChenckID: '',
|
||||
userIDList: [],
|
||||
statusList: [],
|
||||
currentUserIDList: [],
|
||||
showConversationList: true,
|
||||
showCreateConversation: false,
|
||||
showCreateGroup: false,
|
||||
showJoinGroup: false,
|
||||
handleChangeStatus: false,
|
||||
storageList: [],
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
},
|
||||
detached() {
|
||||
wx.$TUIKit.off(wx.$TUIKitTIM.EVENT.CONVERSATION_LIST_UPDATED, this.onConversationListUpdated, this);
|
||||
wx.$TUIKit.off(wx.$TUIKitTIM.EVENT.USER_STATUS_UPDATED, this.onUserStatusUpdate, this);
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
init() {
|
||||
wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.CONVERSATION_LIST_UPDATED, this.onConversationListUpdated, this);
|
||||
wx.$TUIKit.on(wx.$TUIKitTIM.EVENT.USER_STATUS_UPDATED, this.onUserStatusUpdate, this);
|
||||
this.getConversationList();
|
||||
wx.getStorageInfo({
|
||||
success(res) {
|
||||
wx.setStorage({
|
||||
key: 'storageList',
|
||||
data: res.keys,
|
||||
});
|
||||
},
|
||||
});
|
||||
this.setData({
|
||||
handleChangeStatus: wx.getStorageSync(app?.globalData?.userInfo?.userID) ? wx.getStorageSync(app?.globalData?.userInfo?.userID) : true,
|
||||
}, () => {
|
||||
if (!wx.getStorageSync('storageList').includes('showOnlineStatus')) {
|
||||
this.handleChangeStatus();
|
||||
}
|
||||
});
|
||||
},
|
||||
goBack() {
|
||||
if (app?.globalData?.reportType !== constant.OPERATING_ENVIRONMENT) {
|
||||
wx.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
} else {
|
||||
wx.switchTab({
|
||||
url: '/pages/TUI-Index/index',
|
||||
});
|
||||
}
|
||||
},
|
||||
// 更新会话列表
|
||||
onConversationListUpdated(event) {
|
||||
this.setData({
|
||||
conversationList: event.data,
|
||||
});
|
||||
this.filterUserIDList(event.data);
|
||||
},
|
||||
transCheckID(event) {
|
||||
this.setData({
|
||||
transChenckID: event.detail.checkID,
|
||||
});
|
||||
},
|
||||
// 更新状态
|
||||
onUserStatusUpdate(event) {
|
||||
event.data.forEach((element) => {
|
||||
const index = this.data.statusList.findIndex(item => item.userID === element.userID);
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
this.data.statusList[index] = element;
|
||||
this.setData({
|
||||
statusList: this.data.statusList,
|
||||
});
|
||||
});
|
||||
},
|
||||
getConversationList() {
|
||||
wx.$TUIKit.getConversationList().then((imResponse) => {
|
||||
this.setData({
|
||||
conversationList: imResponse.data.conversationList,
|
||||
});
|
||||
this.filterUserIDList(imResponse.data.conversationList);
|
||||
});
|
||||
},
|
||||
// 跳转到子组件需要的参数
|
||||
handleRoute(event) {
|
||||
const flagIndex = this.data.conversationList.findIndex(item => item.conversationID === event.currentTarget.id);
|
||||
this.setData({
|
||||
index: flagIndex,
|
||||
});
|
||||
this.getConversationList();
|
||||
this.setData({
|
||||
currentConversationID: event.currentTarget.id,
|
||||
unreadCount: this.data.conversationList[this.data.index].unreadCount,
|
||||
});
|
||||
this.triggerEvent('currentConversationID', { currentConversationID: event.currentTarget.id,
|
||||
unreadCount: this.data.conversationList[this.data.index].unreadCount });
|
||||
},
|
||||
// 展示发起会话/发起群聊/加入群聊
|
||||
showSelectedTag() {
|
||||
wx.aegis.reportEvent({
|
||||
name: 'conversationType',
|
||||
ext1: 'conversationType-all',
|
||||
});
|
||||
this.setData({
|
||||
showSelectTag: !this.data.showSelectTag,
|
||||
});
|
||||
},
|
||||
handleOnTap(event) {
|
||||
this.setData({
|
||||
showSelectTag: false,
|
||||
}, () => {
|
||||
switch (event.currentTarget.dataset.id) {
|
||||
case 1:
|
||||
this.setData({
|
||||
showCreateConversation: true,
|
||||
showConversationList: false,
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
this.setData({
|
||||
showCreateGroup: true,
|
||||
showConversationList: false,
|
||||
});
|
||||
break;
|
||||
case 3:
|
||||
this.setData({
|
||||
showJoinGroup: true,
|
||||
showConversationList: false,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 点击空白区域关闭showMore弹窗
|
||||
handleEditToggle() {
|
||||
this.setData({
|
||||
showSelectTag: false,
|
||||
});
|
||||
},
|
||||
showConversation(event) {
|
||||
this.setData({
|
||||
showConversationList: true,
|
||||
showCreateConversation: false,
|
||||
showCreateGroup: false,
|
||||
showJoinGroup: false,
|
||||
});
|
||||
},
|
||||
searchUserID(event) {
|
||||
this.triggerEvent('currentConversationID', { currentConversationID: event.detail.searchUserID });
|
||||
},
|
||||
searchGroupID(event) {
|
||||
this.triggerEvent('currentConversationID', { currentConversationID: event.detail.searchGroupID });
|
||||
},
|
||||
createGroupID(event) {
|
||||
this.triggerEvent('currentConversationID', { currentConversationID: event.detail.createGroupID });
|
||||
},
|
||||
// 处理当前登录账号是否开启在线状态
|
||||
handleChangeStatus() {
|
||||
const currentID = wx.$chat_userID;
|
||||
const cacheList = wx.getStorageSync('currentUserID');
|
||||
const nowList = [];
|
||||
nowList.push(wx.$chat_userID);
|
||||
if (cacheList.length === 0 || !cacheList.includes(wx.$chat_userID)) {
|
||||
wx.setStorage({
|
||||
key: 'currentUserID',
|
||||
data: wx.getStorageSync('currentUserID').concat(nowList),
|
||||
});
|
||||
}
|
||||
wx.setStorage({
|
||||
key: currentID,
|
||||
data: this.data.handleChangeStatus,
|
||||
});
|
||||
},
|
||||
// 订阅在线状态
|
||||
subscribeOnlineStatus(userIDList) {
|
||||
wx.$TUIKit.getUserStatus({ userIDList }).then((imResponse) => {
|
||||
const { successUserList } = imResponse.data;
|
||||
this.setData({
|
||||
statusList: successUserList,
|
||||
});
|
||||
})
|
||||
.catch((imError) => {
|
||||
console.warn('getUserStatus error:', imError); // 获取用户状态失败的相关信息
|
||||
});
|
||||
wx.$TUIKit.subscribeUserStatus({ userIDList });
|
||||
},
|
||||
|
||||
// 过滤会话列表,找出C2C会话,以及需要订阅状态的userIDList
|
||||
filterUserIDList(conversationList) {
|
||||
if (conversationList.length === 0) return;
|
||||
const userIDList = [];
|
||||
conversationList.forEach((element) => {
|
||||
if (element.type === wx.$TUIKitTIM.TYPES.CONV_C2C) {
|
||||
userIDList.push(element.userProfile.userID);
|
||||
}
|
||||
});
|
||||
const currentUserID = wx.getStorageSync('currentUserID');
|
||||
if (currentUserID.includes(wx.$chat_userID)) {
|
||||
const currentStatus = wx.getStorageSync(wx.$chat_userID);
|
||||
if (currentStatus) {
|
||||
this.subscribeOnlineStatus(userIDList);
|
||||
}
|
||||
} else {
|
||||
this.subscribeOnlineStatus(userIDList);
|
||||
}
|
||||
},
|
||||
|
||||
learnMore() {
|
||||
if (app?.globalData?.reportType !== constant.OPERATING_ENVIRONMENT) return;
|
||||
app.method.navigateTo({
|
||||
url: '/pages/TUI-User-Center/webview/webview?url=https://cloud.tencent.com/product/im',
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
10
TUIService/TUIKit/components/TUIConversation/index.json
Normal file
10
TUIService/TUIKit/components/TUIConversation/index.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"ConversationItem": "./components/ConversationItem/index",
|
||||
"CreateConversation": "./components/CreateConversation/index",
|
||||
"CreateGroup": "./components/CreateGroup/index",
|
||||
"JoinGroup": "./components/JoinGroup/index"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
28
TUIService/TUIKit/components/TUIConversation/index.wxml
Normal file
28
TUIService/TUIKit/components/TUIConversation/index.wxml
Normal file
@ -0,0 +1,28 @@
|
||||
<!--TUIKitWChat/Conversation/index.wxml-->
|
||||
<view class="container" wx:if="{{showConversationList}}">
|
||||
<view class="container">
|
||||
<view class="tui-navigatorbar">
|
||||
<image class="tui-navigatorbar-back" bindtap="goBack" src="../../static/assets/back.png" />
|
||||
<view class="conversation-title">最近联系人</view>
|
||||
</view>
|
||||
|
||||
<view class="conversation-list-area">
|
||||
<scroll-view class="scoll-view" scroll-y="true">
|
||||
<ConversationItem wx:for="{{conversationList}}" wx:key="index" id="{{item.conversationID}}" data-type="{{item.type}}" conversation="{{item}}" bindtap="handleRoute" statusList="{{statusList}}" bind:transCheckID="transCheckID" charge="{{transChenckID===item.conversationID}}">
|
||||
</ConversationItem>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{showSelectTag}}" class="conversation-bubble" catchtap="handleEditToggle">
|
||||
<view class="picker" wx:for="{{array}}" wx:key="index" data-name="{{item.name}}" data-id="{{item.id}}" bindtap="handleOnTap">
|
||||
{{item.name}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom-area">
|
||||
<image bindtap="showSelectedTag" class="btn-show-more" src="../../static/assets/add.svg" />
|
||||
<view bindtap="learnMore" class="im-link">了解更多IM功能</view>
|
||||
</view>
|
||||
</view>
|
||||
<CreateConversation wx:if="{{showCreateConversation}}" bind:showConversation="showConversation" bind:searchUserID="searchUserID" ></CreateConversation>
|
||||
<CreateGroup wx:if="{{showCreateGroup}}" bind:showConversation="showConversation" bind:createGroupID="createGroupID"></CreateGroup>
|
||||
<JoinGroup wx:if="{{showJoinGroup}}" bind:searchGroupID="searchGroupID" bind:showConversation="showConversation"></JoinGroup>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user