update
init
@@ -0,0 +1 @@
|
||||
TUIPlugin/TUICallKit/*
|
||||
@@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/typescript/recommended'],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
},
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'@typescript-eslint/no-var-requires': 0,
|
||||
'prefer-const': 0,
|
||||
'vue/multi-word-component-names': 0,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
TUIPlugin/TUICallKit
|
||||
node_modules
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
@@ -0,0 +1,4 @@
|
||||
TUIPlugin/TUICallKit
|
||||
node_modules
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
@@ -0,0 +1,104 @@
|
||||
## 1.4.3 (2023-05-10)
|
||||
### 修复
|
||||
- 修复 会话列表 消息在线状态 失效问题
|
||||
|
||||
## 1.4.2 (2023-04-26)
|
||||
### 新增
|
||||
- 支持 创建群聊消息提示 解析显示
|
||||
|
||||
|
||||
## 1.4.1 (2023-03-31)
|
||||
### 新增
|
||||
- 支持 消息记录列表 显示消息时间
|
||||
### 修复
|
||||
- 修复 样式污染问题
|
||||
- 修复 H5 系统键盘覆盖输入框 问题
|
||||
- 修复 H5 大表情样式 问题
|
||||
|
||||
## 1.4.0 (2023-03-24)
|
||||
### 新增
|
||||
- 支持 vite & webpack 接入,详见[集成 TUIKit](https://cloud.tencent.com/document/product/269/68493)
|
||||
- 支持 音视频通话(TUICallKit) 功能自动集成
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.3.6 (2023-03-21)
|
||||
### 新增
|
||||
- 优化“音视频通话”集成方式, 详见[使用音视频通话](https://cloud.tencent.com/document/product/269/79861)
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.3.5 (2023-03-16)
|
||||
### 新增
|
||||
- 支持消息输入区多类型消息混合输入
|
||||
- 支持消息输入区图片文件拖拽上传
|
||||
- 发布[ demo 源码](https://github.com/TencentCloud/chat-uikit-vue/)
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.3.4 (2023-03-03)
|
||||
### 修复
|
||||
- 修复安卓特定版本浏览器图片发送变形问题
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.3.3 (2023-02-17)
|
||||
### 新增
|
||||
- 新增消息通知插件 TUINotification,支持 Web 端离线消息通知功能。
|
||||
### 修复
|
||||
- 修复消息重发失败问题,提升稳定性
|
||||
|
||||
## 1.3.2 (2023-02-10)
|
||||
### 新增
|
||||
- 新增图片预览功能:支持缩放、旋转、切换图片,并在 H5 环境下支持手势操作
|
||||
- 改进媒体类消息上屏逻辑,加入骨架屏占位功能
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
# 1.3.1 (2023-01-12)
|
||||
### 新增
|
||||
- 支持本地审核功能,使用本地审核功能请点击 [控制台](https://console.cloud.tencent.com/im/local-audit-setting) 开启,详情参见 [内容审核](https://cloud.tencent.com/document/product/269/79139)。
|
||||
- 支持群聊点击群成员列表头像跳转至用户信息界面
|
||||
- 支持接口开关直接控制 消息已读回执、对方正在输入、用户在线状态、消息表情评论 等功能
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.3.0 (2023-01-03)
|
||||
### 新增
|
||||
- 支持消息回复功能
|
||||
- 支持表情回应功能
|
||||
- 支持C2C会话单条消息已读
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.2.5 (2022-12-05)
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.2.4 (2022-11-18)
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.2.3 (2022-11-16)
|
||||
### 新增
|
||||
- 支持 github 仓库形式接入源码
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
|
||||
## 1.2.2 (2022-11-10)
|
||||
|
||||
### 新增
|
||||
- 支持集成 [音视频通话](https://cloud.tencent.com/document/product/269/79861)
|
||||
### 修复
|
||||
- 修复已知问题,提升稳定性
|
||||
|
||||
## 1.0.0 (2022-09-15)
|
||||
|
||||
### 新增
|
||||
- [TUIKit界面库 - Web](https://cloud.tencent.com/document/product/269/79737)
|
||||
- [TUIKit界面库 - H5](https://cloud.tencent.com/document/product/269/79738)
|
||||
- [集成基础功能 - Web & H5](https://cloud.tencent.com/document/product/269/68493)
|
||||
- [设置界面风格 - Web](https://cloud.tencent.com/document/product/269/79113)
|
||||
- [设置界面风格 - H5](https://cloud.tencent.com/document/product/269/79836)
|
||||
- [添加自定义消息 - Web](https://cloud.tencent.com/document/product/269/79115)
|
||||
- [添加自定义消息 - H5](https://cloud.tencent.com/document/product/269/79837)
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#444444"
|
||||
d="M384 512L731.733333 202.666667c17.066667-14.933333 19.2-42.666667 4.266667-59.733334-14.933333-17.066667-42.666667-19.2-59.733333-4.266666l-384 341.333333c-10.666667 8.533333-14.933333 19.2-14.933334 32s4.266667 23.466667 14.933334 32l384 341.333333c8.533333 6.4 19.2 10.666667 27.733333 10.666667 12.8 0 23.466667-4.266667 32-14.933333 14.933333-17.066667 14.933333-44.8-4.266667-59.733334L384 512z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 701 B |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>画板</title>
|
||||
<g id="画板" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="at" fill-rule="nonzero">
|
||||
<g id="编组-11">
|
||||
<circle id="蒙版" fill="#006EFF" cx="9" cy="9" r="9"></circle>
|
||||
<path d="M9.66185229,2.28113733 C6.35797576,1.9652543 3.31197412,4.08255376 2.47142946,7.27925624 C1.63088481,10.4759587 3.24414254,13.8075738 6.27970227,15.1439012 C7.13080638,15.5270729 8.05149341,15.7333128 8.98542228,15.75 C10.4722047,15.75 11.9176115,15.2625575 13.0981167,14.3627071 C13.3947741,14.1374908 13.4522747,13.7156728 13.2266384,13.4198867 C13.1178721,13.276076 12.9558003,13.1816064 12.776601,13.1575656 C12.5974017,13.1335248 12.415994,13.1819143 12.2728721,13.2919325 C10.3435542,14.7428224 7.68158841,14.7434418 5.75158944,13.29345 C3.82159048,11.8434583 3.09194171,9.29474777 3.96409619,7.04962006 C4.83625067,4.80449236 7.09854886,3.40780813 9.50627338,3.62802361 C12.3207581,3.95233736 14.4329906,6.34319268 14.3968623,9.16372615 L14.3968623,9.62166747 C14.3952895,9.9342631 14.2661407,10.232791 14.0390751,10.4486938 C13.8120095,10.6645966 13.5065396,10.7793212 13.1928169,10.7665208 C12.550363,10.6962989 12.071833,10.14342 12.0970003,9.50044771 L12.0970003,6.59117338 C12.0970003,6.21924101 11.7941523,5.91773024 11.4205703,5.91773024 C11.0787978,5.91484427 10.78856,6.16623611 10.7441403,6.50362577 C10.1146233,5.91340542 9.28194317,5.58565993 8.41722108,5.58774312 C6.79570933,5.59984582 5.40245718,6.73673734 5.07217831,8.31729266 C4.74189943,9.89784798 5.56412488,11.4936147 7.04624976,12.1485503 C8.52837464,12.8034859 10.2686288,12.3400523 11.2244056,11.0358981 C11.622024,11.6482852 12.275384,12.0499682 13.0034289,12.1296342 C13.7314737,12.2093002 14.4568676,11.9584868 14.9785921,11.4466984 C15.4798496,10.9719157 15.7593539,10.3104139 15.7497223,9.62166747 L15.7497223,9.16372615 C15.7810534,5.6593071 13.1575247,2.69329944 9.66185229,2.28113733 Z M8.43074968,11.0965079 C7.27638137,11.0965079 6.34058097,10.1648397 6.34058097,9.01556866 C6.34058097,7.86629763 7.27638137,6.93462938 8.43074968,6.93462938 C9.58511798,6.93462938 10.5209184,7.86629763 10.5209184,9.01556866 C10.5172055,10.1633051 9.58357657,11.0928115 8.43074968,11.0965079 L8.43074968,11.0965079 Z" id="形状" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48px" height="48px" viewBox="0 0 48 48" version="1.1">
|
||||
<title>ic_back_white</title>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="02.-查看信息-示例好友" transform="translate(-32.000000, -200.000000)">
|
||||
<g id="编组-6" transform="translate(0.000000, 176.000000)">
|
||||
<g id="ic_back_white" transform="translate(32.000000, 24.000000)">
|
||||
<g id="ic_back_black" fill="#444444" fill-rule="nonzero">
|
||||
<path d="M9.51231071,24 L23.5198286,38.7290411 C23.785378,39.0082689 23.7753168,39.4496082 23.4973187,39.7164448 L21.6255915,41.5130226 C21.3466827,41.7807332 20.9035602,41.7716553 20.6358496,41.4927466 C20.6351032,41.491969 20.6343586,41.4911896 20.6336157,41.4904085 L4.45876399,24.4823948 C4.2017544,24.2121467 4.2017544,23.7878533 4.45876399,23.5176052 L20.6336157,6.50959152 C20.900035,6.22944906 21.3431109,6.21832422 21.6232533,6.48474351 C21.6240344,6.48548634 21.6248138,6.48623097 21.6255915,6.48697741 L23.4973187,8.28355524 C23.7753168,8.55039175 23.785378,8.99173114 23.5198286,9.27095893 L9.51231071,24 L9.51231071,24 Z" id="Path-2"></path>
|
||||
</g>
|
||||
<rect id="矩形" x="0" y="0" width="48" height="48"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="43px" height="42px" viewBox="0 0 43 42" version="1.1">
|
||||
<title>编组 3</title>
|
||||
<defs>
|
||||
<path d="M52.1440033,262.168279 C53.7071313,260.607213 56.2397907,260.608885 57.8008563,262.172013 L57.8008563,262.172013 L71.61,275.999572 L301,276 C308.731986,276 315,282.268014 315,290 L315,449 C315,456.731986 308.731986,463 301,463 L29,463 C21.2680135,463 15,456.731986 15,449 L15,290 C15,282.268014 21.2680135,276 29,276 L38.33,275.999572 L52.1402692,262.172013 L52.1402692,262.172013 Z" id="path-1"></path>
|
||||
<filter x="-6.7%" y="-7.9%" width="113.3%" height="119.8%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="6" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="信息页-发起聊天" transform="translate(-47.000000, -311.000000)">
|
||||
<rect fill="#000000" x="0" y="0" width="750" height="1624"></rect>
|
||||
<rect id="矩形" fill="#FFFFFF" x="0" y="0" width="750" height="1624"></rect>
|
||||
<rect id="矩形" fill-opacity="0.1" fill="#FFFFFF" x="0" y="284" width="750" height="144"></rect>
|
||||
<g id="编组-5" transform="translate(32.000000, 298.000000)">
|
||||
<g id="位图" transform="translate(0.000000, 8.000000)">
|
||||
<rect id="矩形" fill="#006EFF" x="0" y="0" width="96" height="96" rx="8"></rect>
|
||||
<path d="M42.4156863,59.7575758 C42.5411765,59.6363636 42.7921569,59.6363636 42.917647,59.7575758 C42.917647,59.7575758 44.172549,60.8484849 47.0588235,60.8484849 C47.6862744,60.8484849 48.1882353,60.8484849 48.8156863,60.7272727 C52.9568628,60.2424242 53.9607843,58.5454545 53.9607843,58.5454545 C54.0862745,58.4242424 54.3372549,58.3030303 54.4627451,58.4242424 C54.5882353,58.5454545 54.7137255,58.6666666 54.7137255,58.9090909 C53.8352941,61.3333333 51.5764706,63.1515151 48.9411764,63.5151515 L48.0627451,63.5151515 C45.6784314,63.5151515 43.4196078,62.3030302 42.1647058,60.3636364 C42.2901961,60 42.2901961,59.8787878 42.4156863,59.7575758 L42.4156863,59.7575758 Z M47.5607843,21.3333333 C58.6039216,21.3333333 67.7647059,28.8484848 70.1490196,38.7878788 L70.2745098,38.7878788 C72.7843137,38.7878788 74.6666667,40.7272727 74.6666667,43.0303031 L74.6666667,51.5151515 C74.6666667,53.3333333 73.5372549,54.7878788 71.9058823,55.3939394 C70.1490196,64.969697 61.4901961,71.2727273 50.6980392,72.1212121 C50.1960784,73.5757576 48.8156863,74.6666667 47.0588235,74.6666667 C44.9254902,74.6666667 43.2941176,73.0909091 43.2941176,71.030303 C43.2941176,68.969697 45.0509803,67.3939394 47.0588235,67.3939394 C48.6901961,67.3939394 50.0705882,68.3636363 50.572549,69.6969697 C59.8588235,68.9696969 67.3882353,63.8787878 69.2705882,55.6363636 C68.1411764,55.3939394 67.1372549,54.7878788 66.5098039,53.8181818 C64.8784314,58.5454545 61.4901961,62.5454545 57.0980392,64.8484849 L56.972549,64.9696969 L56.5960784,64.9696969 C56.4915032,64.8686868 56.474074,64.8518518 56.4711692,64.7789001 L56.4705882,64.7272727 C56.4705882,64.6060606 56.4705882,64.6060606 56.5960784,64.4848485 C60.9882353,60.6060606 61.2392157,56.8484849 60.7372549,51.2727273 C60.3607843,46.4242424 57.3490196,41.8181818 55.9686275,39.7575758 L55.8431372,39.8787879 C55.717647,39.7575757 55.5921569,39.6363636 55.4666667,39.6363636 C55.2156863,39.6363636 55.0901961,39.7575758 54.9647058,40 C54.8392156,41.4545455 54.462745,42.4242424 54.2117647,42.9090909 C53.2078431,44.9696969 51.5764706,46.3030303 49.1921569,46.6666667 C45.427451,47.2727273 41.6627451,48.1212121 38.0235294,48.7272727 C35.6392156,49.0909091 33.6313725,51.6363636 34.1333333,54.3030303 C34.9926684,59.9947299 38.974432,64.1784384 40.2044901,65.1519921 L40.2153333,65.1603333 L40.2039215,65.1515151 C40.1568627,65.1212121 40.0941176,65.0909091 40.0313725,65.0909091 C39.9058824,65.0909091 39.9058823,65.2121212 39.7803922,65.2121212 C39.6549019,65.3333333 39.5294118,65.5757576 39.5294117,65.5757576 C34.6352941,63.5151515 30.745098,59.5151516 28.8627451,54.6666667 C28.1098039,55.6363636 26.8549019,56.2424243 25.6,56.2424242 C23.2156862,56.2424242 21.3333333,54.3030303 21.3333333,52 L21.3333333,43.6363636 C21.3333333,41.5757576 22.8392157,39.8787879 24.8470588,39.5151515 C26.8549019,29.2121212 36.2666666,21.3333333 47.5607843,21.3333333 Z M47.5607843,25.0909091 C38.0235294,25.0909091 29.9921569,31.8787879 28.4862745,40.7272727 C28.6117647,40.8484849 28.8627451,40.969697 28.9882352,41.2121212 C31.8745097,33.939394 39.1529411,28.7272727 47.6862745,28.7272727 C56.2196078,28.7272727 63.4980392,33.939394 66.3843137,41.3333333 L66.7607843,40.6060606 C65.0039216,31.7575757 57.0980392,25.0909091 47.5607843,25.0909091 Z" id="形状" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="形状结合">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<path stroke="#E0E0E0" stroke-width="2" d="M54.8888733,262.000133 C55.625226,261.979907 56.3673182,262.22911 56.9545645,262.748115 L56.9545645,262.748115 L71.1955708,276.999572 L301,277 C304.589851,277 307.839851,278.455075 310.192388,280.807612 C312.544925,283.160149 314,286.410149 314,290 L314,290 L314,449 C314,452.589851 312.544925,455.839851 310.192388,458.192388 C307.839851,460.544925 304.589851,462 301,462 L301,462 L29,462 C25.4101491,462 22.1601491,460.544925 19.8076118,458.192388 C17.4550746,455.839851 16,452.589851 16,449 L16,449 L16,290 C16,286.410149 17.4550746,283.160149 19.8076118,280.807612 C22.1601491,278.455075 25.4101491,277 29.0000458,277 L29.0000458,277 L38.7445991,276.999553 L52.8469102,262.879585 C53.4135391,262.313702 54.1483154,262.020475 54.8888733,262.000133 Z" stroke-linejoin="square" fill="#FFFFFF" fill-rule="evenodd"></path>
|
||||
</g>
|
||||
<g id="编组-3" transform="translate(47.000000, 305.000000)" stroke="#666666" stroke-width="4">
|
||||
<g id="编组-24" transform="translate(6.142857, 11.000000)">
|
||||
<path d="M18.7142857,22 C21.4757095,22 23.9757095,23.1192881 25.7853535,24.9289322 C27.5949976,26.7385763 28.7142857,29.2385763 28.7142857,32 L28.7142857,32 L2,32 L2.0057986,31.6562146 C2.09061716,29.145562 3.10093106,26.8695956 4.70635331,25.1587023 L4.92893219,24.9289322 C6.73857625,23.1192881 9.23857625,22 12,22 L12,22 Z" id="矩形"></path>
|
||||
<ellipse id="椭圆形" cx="15.3571429" cy="9" rx="7.21428571" ry="7"></ellipse>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 430 B |
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
|
||||
<title>清除</title>
|
||||
<g id="页面-2备份" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="创建群聊" transform="translate(-1243.000000, -413.000000)">
|
||||
<g id="Group-1364" transform="translate(650.000000, 343.000000)">
|
||||
<g id="Group-1363" transform="translate(290.000000, 46.000000)">
|
||||
<g id="Group-1358" transform="translate(0.000000, 24.000000)">
|
||||
<g id="清除" transform="translate(303.000000, 0.000000)">
|
||||
<path d="M0,0 L16,0 L16,16 L0,16 L0,0 Z" id="矩形"></path>
|
||||
<path d="M1,8 C1,11.8659999 4.13400006,15 8,15 C11.8659999,15 15,11.8659999 15,8 C15,4.13400006 11.8659999,1 8,1 L8,1 C4.13400006,1 1,4.13400006 1,8 Z" fill="#999999"></path>
|
||||
<g id="编组" transform="translate(8.000000, 8.000000) rotate(-315.000000) translate(-8.000000, -8.000000) translate(4.000000, 4.000000)" fill="#FFFFFF">
|
||||
<rect id="矩形备份" transform="translate(4.000000, 4.000000) rotate(-90.000000) translate(-4.000000, -4.000000) " x="1.8189894e-12" y="3.5" width="8" height="1" rx="0.5"></rect>
|
||||
<rect id="矩形备份" transform="translate(4.000000, 4.000000) rotate(-360.000000) translate(-4.000000, -4.000000) " x="0" y="3.5" width="8" height="1" rx="0.5"></rect>
|
||||
</g>
|
||||
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 278 B |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="-0.5" width="15.8" height="15.8" rx="7.9" transform="matrix(1 0 0 -1 0 16.3999)" stroke="#666666"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.15745 10.4828C4.00124 10.3266 4.00124 10.0733 4.15745 9.91711L8.11724 5.95731C8.27345 5.8011 8.52672 5.8011 8.68293 5.95731L8.82435 6.09873C8.82645 6.10083 8.82852 6.10295 8.83057 6.10509L12.6427 9.91725C12.7989 10.0735 12.7989 10.3267 12.6427 10.4829L12.5013 10.6244C12.3451 10.7806 12.0918 10.7806 11.9356 10.6244L8.40002 7.08875L4.86455 10.6242C4.70834 10.7804 4.45508 10.7804 4.29887 10.6242L4.15745 10.4828Z" fill="#666666"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 703 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 631 B |
@@ -0,0 +1 @@
|
||||
<svg t="1660053550964" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3181" width="200" height="200"><path d="M95.658667 461.354667a71.637333 71.637333 0 0 0 0 101.290666l365.696 365.696a71.637333 71.637333 0 0 0 101.290666 0l365.696-365.696a71.637333 71.637333 0 1 0-101.248-101.290666L512 776.448l-315.093333-315.093333a71.594667 71.594667 0 0 0-101.248 0z" p-id="3182" fill="#bfbfbf"></path><path d="M95.658667 95.658667a71.637333 71.637333 0 0 0 0 101.248l365.696 365.738666a71.594667 71.594667 0 0 0 101.290666 0l365.696-365.738666a71.637333 71.637333 0 0 0-101.248-101.248L512 410.709333 196.906667 95.658667a71.637333 71.637333 0 0 0-101.248 0z" p-id="3183" fill="#bfbfbf"></path></svg>
|
||||
|
After Width: | Height: | Size: 739 B |
|
After Width: | Height: | Size: 311 B |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 579 B |
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
|
||||
<title>ic/消息备份 8</title>
|
||||
<defs>
|
||||
<circle id="path-1" cx="8" cy="8" r="8"></circle>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="16" height="16" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="new" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.795168922">
|
||||
<g id="消息列表" transform="translate(-816.000000, -700.000000)">
|
||||
<g id="输入框" transform="translate(796.000000, 686.000000)">
|
||||
<g id="编组-11" transform="translate(20.000000, 11.000000)">
|
||||
<g transform="translate(0.000000, 3.000000)" id="ic/消息备份-8">
|
||||
<g id="编组-8备份">
|
||||
<path d="M0,0 L16,0 L16,16 L0,16 L0,0 Z" id="矩形备份-3"></path>
|
||||
</g>
|
||||
<path d="M0,0 L16,0 L16,16 L0,16 L0,0 Z" id="矩形"></path>
|
||||
<use id="椭圆形" stroke="#232832" mask="url(#mask-2)" stroke-width="2" stroke-dasharray="0,0" xlink:href="#path-1"></use>
|
||||
<path d="M6,6 C6,6.55228475 5.55228475,7 5,7 C4.44771525,7 4,6.55228475 4,6 C4,5.44771525 4.44771525,5 5,5 C5.55228475,5 6,5.44771525 6,6 Z" id="矩形" fill="#232832"></path>
|
||||
<path d="M12,6 C12,6.55228475 11.5522847,7 11,7 C10.4477153,7 10,6.55228475 10,6 C10,5.44771525 10.4477153,5 11,5 C11.5522847,5 12,5.44771525 12,6 Z" id="矩形备份" fill="#232832"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
|
||||
<title>编组 9备份 4</title>
|
||||
<defs>
|
||||
<rect id="path-1" x="1" y="1" width="14" height="14" rx="2.25"></rect>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="14" height="14" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="new" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.795168922">
|
||||
<g id="消息列表" transform="translate(-1040.000000, -700.000000)">
|
||||
<g id="输入框" transform="translate(796.000000, 686.000000)">
|
||||
<g id="编组-11" transform="translate(20.000000, 11.000000)">
|
||||
<g transform="translate(0.000000, 3.000000)" id="编组-9备份-4">
|
||||
<g transform="translate(224.000000, 0.000000)">
|
||||
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
|
||||
<use id="矩形" stroke="#232832" mask="url(#mask-2)" stroke-width="2" stroke-dasharray="0,0" transform="translate(8.000000, 8.000000) rotate(-90.000000) translate(-8.000000, -8.000000) " xlink:href="#path-1"></use>
|
||||
<path d="M7.90693177,10.0489289 L6.00755342,11.0474912 C5.9097845,11.0988913 5.78885907,11.061302 5.73745891,10.9635331 C5.7169911,10.924601 5.70992816,10.8800074 5.71736353,10.8366559 L6.08011252,8.72166698 C6.09124011,8.65678817 6.06973041,8.59058813 6.02259319,8.5446407 L4.48596383,7.04679726 C4.40686711,6.96969701 4.40524865,6.84307436 4.48234889,6.76397764 C4.51305061,6.73248092 4.55327909,6.71198348 4.5968065,6.70565858 L6.72037606,6.39708586 C6.78551809,6.38762017 6.84183121,6.34670629 6.87096361,6.2876776 L7.82065278,4.36339715 C7.86953724,4.26434642 7.98946241,4.22367862 8.08851314,4.27256308 C8.12795566,4.29202912 8.15988117,4.32395463 8.17934722,4.36339715 L9.12903639,6.2876776 C9.15816879,6.34670629 9.21448191,6.38762017 9.27962394,6.39708586 L11.4031935,6.70565858 C11.5125025,6.7215421 11.5882388,6.82303067 11.5723552,6.93233965 C11.5660303,6.97586705 11.5455329,7.01609553 11.5140362,7.04679726 L9.97740681,8.5446407 C9.93026959,8.59058813 9.90875989,8.65678817 9.91988748,8.72166698 L10.2826365,10.8366559 C10.3013087,10.9455231 10.2281911,11.0489143 10.1193238,11.0675865 C10.0759723,11.0750219 10.0313787,11.067959 9.99244658,11.0474912 L8.09306823,10.0489289 C8.03480342,10.0182972 7.96519658,10.0182972 7.90693177,10.0489289 Z" id="星形" stroke="#232832"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="-0.5" width="15.8" height="15.8" rx="7.9" transform="matrix(1 0 0 -1 0 16.3999)" stroke="#666666"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.6427 7.24255C12.7989 7.39876 12.7989 7.65202 12.6427 7.80823L8.68293 11.768C8.52672 11.9242 8.27345 11.9242 8.11724 11.768L7.97582 11.6266C7.97408 11.6249 7.97236 11.6231 7.97067 11.6214L4.15744 7.80814C4.00123 7.65193 4.00123 7.39867 4.15744 7.24246L4.29887 7.10103C4.45508 6.94482 4.70834 6.94482 4.86455 7.10103L8.40013 10.6366L11.9356 7.10113C12.0918 6.94492 12.3451 6.94492 12.5013 7.10113L12.6427 7.24255Z" fill="#666666"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 703 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 902 B |
|
After Width: | Height: | Size: 657 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 62 62" class="design-iconfont">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path fill="#4D4D4D" d="M31 0A31 31 0 1 0 31 62A31 31 0 1 0 31 0Z"/>
|
||||
<path d="M20.768687,18.3379271 L31,28.569 L41.231313,18.3379271 C41.5917969,17.9774431 42.159028,17.9497136 42.5513192,18.2547385 L42.6455265,18.3379271 L43.6620729,19.3544735 C44.0525972,19.7449978 44.0525972,20.3781627 43.6620729,20.768687 L43.6620729,20.768687 L33.431,31 L43.6620729,41.231313 C44.0525972,41.6218373 44.0525972,42.2550022 43.6620729,42.6455265 L42.6455265,43.6620729 C42.2550022,44.0525972 41.6218373,44.0525972 41.231313,43.6620729 L31,33.431 L20.768687,43.6620729 C20.4082031,44.0225569 19.840972,44.0502864 19.4486808,43.7452615 L19.3544735,43.6620729 L18.3379271,42.6455265 C17.9474028,42.2550022 17.9474028,41.6218373 18.3379271,41.231313 L18.3379271,41.231313 L28.569,31 L18.3379271,20.768687 C17.9474028,20.3781627 17.9474028,19.7449978 18.3379271,19.3544735 L19.3544735,18.3379271 C19.7449978,17.9474028 20.3781627,17.9474028 20.768687,18.3379271 Z" fill="#FFF" fill-rule="nonzero"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 62 62" class="design-iconfont">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path fill="#4D4D4D" d="M31 0A31 31 0 1 0 31 62A31 31 0 1 0 31 0Z"/>
|
||||
<path d="M14.7359124,0 C15.2881971,-1.01453063e-16 15.7359124,0.44771525 15.7359124,1 L15.735,21.344 L23.7580265,13.6968792 C24.1578097,13.3158576 24.790775,13.3310181 25.1718581,13.7307426 L26.5518275,15.1783906 C26.9328955,15.5781475 26.9177451,16.2111312 26.5179882,16.5921992 L14.4478609,28.0980396 C14.0646983,28.463289 13.4632705,28.466657 13.0760413,28.1057217 L0.731506115,16.5994137 C0.327506443,16.2228467 0.305267874,15.5900724 0.68183488,15.1860727 L2.04550464,13.7230605 C2.42208199,13.3190823 3.05484394,13.2968371 3.45886079,13.673373 L11.735,21.388 L11.7359124,1 C11.7359124,0.44771525 12.1836276,1.01453063e-16 12.7359124,0 L14.7359124,0 Z" transform="translate(17 17)" fill="#FFF" fill-rule="nonzero"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 935 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="20" viewBox="0 0 22 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.09661 19.8415C1.38654 19.8415 0 18.4764 0 16.7919V12.9796C0 12.5587 0.346831 12.2173 0.774001 12.2173H2.3226C2.75004 12.2173 3.0966 12.5587 3.0966 12.9796V15.267C3.0966 16.1093 3.78974 16.7919 4.6449 16.7919H17.0317C17.8869 16.7919 18.58 16.1093 18.58 15.267V12.9796C18.58 12.5587 18.9266 12.2173 19.3543 12.2173H20.9026C21.3301 12.2173 21.6766 12.5587 21.6766 12.9796V16.7919C21.6766 18.4764 20.2904 19.8415 18.58 19.8415H18.58H3.09661ZM5.67942 4.88325L9.2903 8.43944V0.762639C9.2903 0.341674 9.63693 0 10.0643 0H11.6126C12.0401 0 12.3869 0.341674 12.3869 0.762639V8.43944L15.9978 4.88325C16.311 4.57485 16.8189 4.57485 17.1321 4.88325L18.2668 6.00088C18.58 6.30935 18.58 6.80951 18.2668 7.11823L11.8728 13.4154C11.8452 13.4426 11.3477 13.7421 10.8471 13.7423C10.3411 13.7425 9.83204 13.4429 9.80436 13.4154L3.41009 7.11823C3.09687 6.80949 3.09687 6.30935 3.41009 6.00088L4.54488 4.88325H4.54487C4.85807 4.57485 5.3662 4.57485 5.67942 4.88325Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 781 B |
|
After Width: | Height: | Size: 1001 B |
|
After Width: | Height: | Size: 622 B |
|
After Width: | Height: | Size: 842 B |
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<title>编组 14</title>
|
||||
<defs>
|
||||
<path d="M467,0 C474.731986,-2.71135202e-14 481,6.2680135 481,14 L481,247 C481,254.731986 474.731986,261 467,261 L353.036,261 L340.862492,273.204941 C339.302377,274.769018 336.769719,274.77223 335.205642,273.212116 C335.203247,273.209727 335.200856,273.207335 335.198467,273.204941 L323.024,261 L14,261 C6.2680135,261 2.72325209e-15,254.731986 0,247 L0,14 C8.29461588e-16,6.2680135 6.2680135,3.19669972e-15 14,0 L467,0 Z" id="path-1"></path>
|
||||
<filter x="-10.1%" y="-14.0%" width="120.2%" height="135.4%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feOffset dx="0" dy="10" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="14.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="消息状态" transform="translate(-541.000000, -196.000000)">
|
||||
<g id="编组-11" transform="translate(499.000000, 163.000000)">
|
||||
<g id="形状结合">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="编组-19" transform="translate(8.000000, 1.000000)" fill-rule="nonzero">
|
||||
<g id="编组-17" transform="translate(34.000000, 32.000000)">
|
||||
<g id="编组-14" transform="translate(0.000000, 0.249660)">
|
||||
<rect id="矩形" stroke="#444444" stroke-width="4" x="6" y="11.7115453" width="20.4869565" height="24.5849258" rx="1"></rect>
|
||||
<path d="M36,2.01560374 L36,28.7262543 C36,29.0023967 35.7761424,29.2262543 35.5,29.2262543 L32.4652074,29.2262543 C32.1890657,29.2262525 31.9652084,29.002396 31.9652057,28.7262543 L31.9651258,6.04681123 L31.9651258,6.04681123 L12.2913043,6.04719144 C12.015162,6.04720643 11.7913,5.82335314 11.7912947,5.54721076 C11.7912947,5.54720754 11.7912947,5.54720432 11.7913043,5.5472011 L11.7913043,2.51560374 C11.7913043,2.23946137 12.015162,2.01560374 12.2913043,2.01560374 L36,2.01560374 L36,2.01560374 Z" id="路径-3" fill="#444444"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<title>矩形</title>
|
||||
<defs>
|
||||
<path d="M467,0 C474.731986,-2.71135202e-14 481,6.2680135 481,14 L481,247 C481,254.731986 474.731986,261 467,261 L353.036,261 L340.862492,273.204941 C339.302377,274.769018 336.769719,274.77223 335.205642,273.212116 C335.203247,273.209727 335.200856,273.207335 335.198467,273.204941 L323.024,261 L14,261 C6.2680135,261 2.72325209e-15,254.731986 0,247 L0,14 C8.29461588e-16,6.2680135 6.2680135,3.19669972e-15 14,0 L467,0 Z" id="path-1"></path>
|
||||
<filter x="-10.1%" y="-14.0%" width="120.2%" height="135.4%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feOffset dx="0" dy="10" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="14.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="消息状态" transform="translate(-779.000000, -326.000000)">
|
||||
<g id="编组-11" transform="translate(499.000000, 163.000000)">
|
||||
<g id="形状结合">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="编组-13备份" transform="translate(246.000000, 131.583780)">
|
||||
<g id="编组-17" transform="translate(34.000000, 31.416220)">
|
||||
<g id="编组-18" transform="translate(4.000000, 2.847939)">
|
||||
<path d="M27,8.04349833 L27,34.26099 L5,34.26099 L5,8.04349833 L27,8.04349833 Z" id="路径-5" stroke="#444444" stroke-width="4"></path>
|
||||
<rect id="矩形" fill="#444444" x="9.14285714" y="0" width="14" height="4.02899889"></rect>
|
||||
<rect id="矩形" fill="#444444" x="0" y="6.04349833" width="32" height="4.02899889"></rect>
|
||||
<path d="M14,15.1087458 L14,27.1957425 L10,27.1957425 L10,15.1087458 L14,15.1087458 Z M22,15.1087458 L22,27.1957425 L18,27.1957425 L18,15.1087458 L22,15.1087458 Z" id="形状结合" fill="#444444"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="编组-19" transform="translate(8.000000, 1.000000)"></g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<title>编组</title>
|
||||
<defs>
|
||||
<path d="M467,0 C474.731986,-2.71135202e-14 481,6.2680135 481,14 L481,247 C481,254.731986 474.731986,261 467,261 L353.036,261 L340.862492,273.204941 C339.302377,274.769018 336.769719,274.77223 335.205642,273.212116 C335.203247,273.209727 335.200856,273.207335 335.198467,273.204941 L323.024,261 L14,261 C6.2680135,261 2.72325209e-15,254.731986 0,247 L0,14 C8.29461588e-16,6.2680135 6.2680135,3.19669972e-15 14,0 L467,0 Z" id="path-1"></path>
|
||||
<filter x="-10.1%" y="-14.0%" width="120.2%" height="135.4%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feOffset dx="0" dy="10" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="14.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="消息状态" transform="translate(-660.000000, -196.000000)">
|
||||
<g id="编组-11" transform="translate(499.000000, 163.000000)">
|
||||
<g id="形状结合">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="编组-19" transform="translate(8.000000, 1.000000)" fill-rule="nonzero" stroke="#444444" stroke-width="4">
|
||||
<g id="编组-13" transform="translate(119.000000, 0.000000)">
|
||||
<g id="编组-17" transform="translate(34.000000, 32.000000)">
|
||||
<g id="编组" transform="translate(0.000000, 0.249660)">
|
||||
<path d="M23.1265517,6.28055724 L35.7271185,19.5748426 L23.0577232,32.8831329 L23.0577232,25.1147287 C22.2832234,25.0144246 21.6206186,24.9731478 21.1119625,24.9593482 C19.8469875,24.9250298 17.622079,25.0087745 15.0567889,25.7301995 C10.5501298,27.0035633 6.83444935,29.6335962 4.00998374,33.593477 C3.98525766,32.7188606 3.9976824,31.6416134 4.10230378,30.4471653 C4.26498285,28.6221312 4.60551504,26.8911737 5.12965716,25.3080362 C5.77312173,23.3656805 6.68732788,21.6451437 7.85433875,20.1962611 C11.1297915,16.1439451 16.3122766,14.2888953 23.1265517,14.4503809 L23.1265517,14.4503809 L23.1265517,6.28055724 Z" id="路径"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="130px" height="130px" viewBox="0 0 130 130" version="1.1">
|
||||
<title>编组</title>
|
||||
<defs>
|
||||
<filter x="-20.0%" y="-20.0%" width="140.0%" height="140.0%" filterUnits="objectBoundingBox" id="filter-1">
|
||||
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
|
||||
<feMerge>
|
||||
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
|
||||
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="消息状态" transform="translate(-1210.000000, -966.000000)">
|
||||
<g id="编组-3" transform="translate(1055.000000, 783.000000)">
|
||||
<g id="编组-17" transform="translate(60.000000, 37.996517)">
|
||||
<g id="编组-14" transform="translate(0.000000, 0.003483)">
|
||||
<g id="编组" transform="translate(110.000000, 160.000000)" filter="url(#filter-1)">
|
||||
<rect id="矩形" x="0" y="0" width="100" height="100"></rect>
|
||||
<path d="M67.4424727,46.9165576 L41.2606545,30.5526788 C40.1396848,29.8520727 38.7265939,29.8147394 37.5704727,30.4557091 C36.4143515,31.0966788 35.6970182,32.3143758 35.6970182,33.6363152 L35.6970182,66.3635879 C35.6970182,67.6855273 36.4143515,68.9032242 37.5704727,69.5441939 C38.1198061,69.8486788 38.7268364,69.9999515 39.3331394,69.9999515 C40.0029576,69.9999515 40.6720485,69.8152242 41.2604121,69.4472242 L67.4422303,53.0838303 C68.505503,52.4193455 69.1513213,51.2540121 69.1513213,50.0001939 C69.1513213,48.7463758 68.5057455,47.5810424 67.4424727,46.9165576" id="Fill-1" fill="#FFFFFF"></path>
|
||||
<path d="M50,10 C27.944,10 10,27.944 10,50 C10,72.0557576 27.944,90 50,90 C72.056,90 90,72.0557576 90,50 C90,27.944 72.056,10 50,10" id="路径" stroke="#FFFFFF" stroke-width="6"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 41" class="design-iconfont">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path d="M34,2 L34,28.6209709 L20.7153357,28.6209709 L17.9993455,31.4022694 L15.2847485,28.6219998 L2,28.6219998 L2,2 L34,2 Z" transform="translate(2 3.273066)" fill-rule="nonzero" stroke="#444" stroke-width="4"/>
|
||||
<path fill="#444" d="M11 16.12483H15V20.15603749H11z" transform="translate(0 .24966)"/>
|
||||
<path fill="#444" d="M18 16.12483H22V20.15603749H18z" transform="translate(0 .24966)"/>
|
||||
<path fill="#444" d="M25 16.12483H29V20.15603749H25z" transform="translate(0 .24966)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 631 B |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<title>编组 12</title>
|
||||
<defs>
|
||||
<path d="M467,0 C474.731986,-2.71135202e-14 481,6.2680135 481,14 L481,247 C481,254.731986 474.731986,261 467,261 L353.036,261 L340.862492,273.204941 C339.302377,274.769018 336.769719,274.77223 335.205642,273.212116 C335.203247,273.209727 335.200856,273.207335 335.198467,273.204941 L323.024,261 L14,261 C6.2680135,261 2.72325209e-15,254.731986 0,247 L0,14 C8.29461588e-16,6.2680135 6.2680135,3.19669972e-15 14,0 L467,0 Z" id="path-1"></path>
|
||||
<filter x="-10.1%" y="-14.0%" width="120.2%" height="135.4%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feOffset dx="0" dy="10" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="14.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="消息状态" transform="translate(-541.000000, -328.000000)">
|
||||
<g id="编组-11" transform="translate(499.000000, 163.000000)">
|
||||
<g id="形状结合">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="编辑功能" transform="translate(8.000000, 131.583780)" fill-rule="nonzero">
|
||||
<g id="编组-17" transform="translate(34.000000, 32.416220)">
|
||||
<g id="编组" transform="translate(0.000000, 3.000000)">
|
||||
<path d="M30,2 L30,24.7410578 L11.7126857,24.7410578 L8.99940621,27.5321142 L6.28736501,24.7420913 L2,24.7420913 L2,2 L30,2 Z" id="路径" stroke="#444444" stroke-width="4"></path>
|
||||
<path d="M38,12.0541319 C38.5522847,12.0541319 39,12.5038667 39,13.0586428 L39,13.0586428 L39,32.7691572 C39,33.3239333 38.5522847,33.7736682 38,33.7736682 L38,33.7736682 L33.5577151,33.7736682 L30.6995611,36.7141728 C30.3044253,37.101771 29.671305,37.0942155 29.2854474,36.6972972 L29.2854474,36.6972972 L26.4422849,33.7726347 L15,33.7726347 C14.4477153,33.7726347 14,33.3228998 14,32.7681237 L14,32.7681237 L14,26.7401319 L18,26.7401319 L18,29.7536155 L28.1270436,29.7545907 L30.001,31.6812721 L31.8726235,29.7556243 L35,29.75462 L35,16.0721758 L32,16.0721319 L32,12.0541319 Z" id="形状结合" fill="#444444"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="编组-19" transform="translate(8.000000, 1.000000)"></g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<title>矩形</title>
|
||||
<defs>
|
||||
<path d="M467,0 C474.731986,-2.71135202e-14 481,6.2680135 481,14 L481,247 C481,254.731986 474.731986,261 467,261 L353.036,261 L340.862492,273.204941 C339.302377,274.769018 336.769719,274.77223 335.205642,273.212116 C335.203247,273.209727 335.200856,273.207335 335.198467,273.204941 L323.024,261 L14,261 C6.2680135,261 2.72325209e-15,254.731986 0,247 L0,14 C8.29461588e-16,6.2680135 6.2680135,3.19669972e-15 14,0 L467,0 Z" id="path-1"></path>
|
||||
<filter x="-10.1%" y="-14.0%" width="120.2%" height="135.4%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feOffset dx="0" dy="10" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="14.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="消息状态" transform="translate(-660.000000, -327.000000)">
|
||||
<g id="编组-11" transform="translate(499.000000, 163.000000)">
|
||||
<g id="形状结合">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="编组-19" transform="translate(8.000000, 1.000000)" fill="#444444" fill-rule="nonzero">
|
||||
<g id="编组-13" transform="translate(119.000000, 131.000000)">
|
||||
<g id="编组-21" transform="translate(34.000000, 32.000000)">
|
||||
<path d="M9.94902685,18.825399 C9.94902685,19.1015414 9.72516923,19.325399 9.44902685,19.325399 C9.31552791,19.325399 9.18757266,19.2720125 9.09366105,19.1771306 L2.13687841,12.1484693 C1.94403281,11.9536312 1.94403281,11.6398441 2.13687841,11.445006 L9.09366105,4.41634471 C9.28791708,4.2200816 9.60449539,4.21845454 9.8007585,4.41271056 C9.89564042,4.50662217 9.94902685,4.63457741 9.94902685,4.76807636 L9.94824421,9.73507632 L22.6994692,9.73558854 C31.0812313,9.73558854 38,15.6504194 38,23.1330579 C38,30.5145797 31.2669616,36.3703807 23.0384554,36.5272976 L22.6994692,36.5305273 L10.4390092,36.5305273 C9.88672441,36.5305273 9.43900916,36.082812 9.43900916,35.5305273 L9.43900916,33.408229 C9.43900916,32.8559443 9.88672441,32.408229 10.4390092,32.408229 L22.6994692,32.408229 C28.9648068,32.408229 33.9198585,28.1721729 33.9198585,23.1330579 C33.9198585,18.1779281 29.1285988,13.9993117 23.0116273,13.861401 L22.6994692,13.8578868 L9.94824421,13.8570763 L9.94902685,18.825399 Z" id="路径"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" class="design-iconfont">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path d="M4.13744611,6.61713753 L20.551,23 L0,23 L0,21 L3,21 L3,11 C3,9.40883362 3.41291862,7.91410954 4.13744611,6.61713753 Z M21.481,21 L24,21 L24,23 L23.485,23 L21.481,21 Z M12,2 C16.9705627,2 21,6.02943725 21,11 L21,20.52 L5.36684476,4.91705738 C7.01203082,3.12402075 9.37475086,2 12,2 Z" fill="#CCC" transform="translate(4 3)"/>
|
||||
<path fill="#CCC" fill-rule="nonzero" d="M13 0L13 4 11 4 11 0z" transform="translate(4 3)"/>
|
||||
<path stroke="#CCC" d="M8.5 24.5H15.5V25.5H8.5z" transform="translate(4 3)"/>
|
||||
<path stroke="#CCC" stroke-width="2" transform="matrix(-1 0 0 1 31.089472 3)" d="M25.4499982 0.1546001L1.63947409 23.8855564"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 786 B |
|
After Width: | Height: | Size: 964 B |
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="6" cy="6" r="6" fill="#006EFF"/>
|
||||
<circle cx="3" cy="6" r="1" fill="white"/>
|
||||
<circle cx="6" cy="6" r="1" fill="white"/>
|
||||
<circle cx="9" cy="6" r="1" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 285 B |
|
After Width: | Height: | Size: 225 B |
|
After Width: | Height: | Size: 975 B |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#444444"
|
||||
d="M672 418H144c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32z m-44 402H188V494h440v326zM819.3 328.5c-78.8-100.7-196-153.6-314.6-154.2l-0.2-64c0-6.5-7.6-10.1-12.6-6.1l-128 101c-4 3.1-3.9 9.1 0 12.3L492 318.6c5.1 4 12.7 0.4 12.6-6.1v-63.9c12.9 0.1 25.9 0.9 38.8 2.5 42.1 5.2 82.1 18.2 119 38.7 38.1 21.2 71.2 49.7 98.4 84.3 27.1 34.7 46.7 73.7 58.1 115.8 11 40.7 14 82.7 8.9 124.8-0.7 5.4-1.4 10.8-2.4 16.1h74.9c14.8-103.6-11.3-213-81-302.3z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 792 B |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#444444"
|
||||
d="M480.5 251.2c13-1.6 25.9-2.4 38.8-2.5v63.9c0 6.5 7.5 10.1 12.6 6.1L660 217.6c4-3.2 4-9.2 0-12.3l-128-101c-5.1-4-12.6-0.4-12.6 6.1l-0.2 64c-118.6 0.5-235.8 53.4-314.6 154.2-69.6 89.2-95.7 198.6-81.1 302.4h74.9c-0.9-5.3-1.7-10.7-2.4-16.1-5.1-42.1-2.1-84.1 8.9-124.8 11.4-42.2 31-81.1 58.1-115.8 27.2-34.7 60.3-63.2 98.4-84.3 37-20.6 76.9-33.6 119.1-38.8zM880 418H352c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32z m-44 402H396V494h440v326z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 792 B |
|
After Width: | Height: | Size: 693 B |
|
After Width: | Height: | Size: 555 B |
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
|
||||
<title>编组 14</title>
|
||||
<defs>
|
||||
<filter x="-10.6%" y="-5.4%" width="121.2%" height="110.9%" filterUnits="objectBoundingBox" id="filter-1">
|
||||
<feOffset dx="0" dy="7" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="10" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
|
||||
<feMerge>
|
||||
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
|
||||
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="new" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="自定义消息" transform="translate(-458.000000, -318.000000)">
|
||||
<g id="编组-32" filter="url(#filter-1)" transform="translate(44.000000, 60.000000)">
|
||||
<g id="编组-24" transform="translate(30.000000, 250.000000)">
|
||||
<g id="编组-14" transform="translate(384.000000, 8.000000)">
|
||||
<circle id="椭圆形" fill="#006EFF" fill-rule="nonzero" cx="8" cy="8" r="8"></circle>
|
||||
<polyline id="路径-4" stroke="#FFFFFF" stroke-width="2" transform="translate(8.042641, 6.242641) rotate(-315.000000) translate(-8.042641, -6.242641) " points="6.04264069 10.2426407 10.0426407 10.2426407 10.0426407 2.24264069"></polyline>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="34px" height="33px" viewBox="0 0 34 33" version="1.1">
|
||||
<title>编组 10</title>
|
||||
<defs>
|
||||
<filter x="-27.3%" y="-28.6%" width="154.5%" height="157.1%" filterUnits="objectBoundingBox" id="filter-1">
|
||||
<feGaussianBlur stdDeviation="2" in="SourceGraphic"></feGaussianBlur>
|
||||
</filter>
|
||||
<linearGradient x1="72.4956041%" y1="27.6077921%" x2="39.6032421%" y2="74.5944688%" id="linearGradient-2">
|
||||
<stop stop-color="#FFF235" offset="0%"></stop>
|
||||
<stop stop-color="#F9C600" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<path d="M23.276778,8.12077882 L16.0081718,7.05943334 L12.7576045,0.434939378 C12.4730744,-0.144979793 11.5274548,-0.144979793 11.2429246,0.434939378 L7.99235731,7.05943334 L0.72375111,8.12077882 C0.405448806,8.16747802 0.141181906,8.39163419 0.0415541289,8.69899984 C-0.0580736481,9.00636549 0.024668065,9.34344882 0.255162837,9.56930313 L5.51432744,14.7248949 L4.27235744,22.006574 C4.21832203,22.3249777 4.34834472,22.6467776 4.60839011,22.8369707 C4.8692798,23.028862 5.2137555,23.0526361 5.49744137,22.9015005 L12.0002646,19.4644393 L18.5022435,22.9015005 C18.6255117,22.9668794 18.7606003,22.9991443 18.8948445,22.9991443 C19.0696152,22.9991443 19.244386,22.9448034 19.3912947,22.8369707 C19.6513401,22.6467776 19.7813628,22.3249777 19.7273274,22.006574 L18.4853574,14.7248949 L23.744522,9.56930313 C23.9750168,9.34344882 24.0577585,9.00636549 23.958975,8.69899984 C23.8593472,8.39163419 23.5950803,8.16747802 23.276778,8.12077882 Z" id="path-3"></path>
|
||||
<filter x="-15.1%" y="-10.7%" width="128.1%" height="131.2%" filterUnits="objectBoundingBox" id="filter-5">
|
||||
<feMorphology radius="0.2" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
|
||||
<feOffset dx="0" dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
|
||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.495153147 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<filter x="-25.5%" y="-21.5%" width="149.0%" height="153.0%" filterUnits="objectBoundingBox" id="filter-6">
|
||||
<feGaussianBlur stdDeviation="2" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
|
||||
<feOffset dx="0" dy="-2" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
|
||||
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
|
||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.735756187 0 0 0 0 0 0 0 0 0.782696064 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
|
||||
<feGaussianBlur stdDeviation="2.5" in="SourceAlpha" result="shadowBlurInner2"></feGaussianBlur>
|
||||
<feOffset dx="0" dy="3" in="shadowBlurInner2" result="shadowOffsetInner2"></feOffset>
|
||||
<feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
|
||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.977846179 0 0 0 0 0.736284656 0 0 0 0.709552898 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
|
||||
<feMerge>
|
||||
<feMergeNode in="shadowMatrixInner1"></feMergeNode>
|
||||
<feMergeNode in="shadowMatrixInner2"></feMergeNode>
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="页面-2备份" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="评价" transform="translate(-1023.000000, -440.000000)">
|
||||
<g id="编组-12" transform="translate(954.000000, 401.000000)">
|
||||
<g id="编组-25" transform="translate(20.000000, 41.000000)">
|
||||
<g id="编组-10" transform="translate(54.000000, 0.000000)">
|
||||
<path d="M22.3370465,11.4146241 L15.6741575,10.4455696 L12.6944708,4.39711856 C12.4336515,3.86762715 11.5668336,3.86762715 11.3060142,4.39711856 L8.32632754,10.4455696 L1.66343852,11.4146241 C1.37166141,11.4572625 1.12941675,11.6619269 1.03809128,11.9425651 C0.946765823,12.2232033 1.02261239,12.530975 1.23389927,12.7371898 L6.05480015,17.4444693 L4.91632765,24.0929589 C4.8667952,24.3836753 4.98598266,24.6774926 5.2243576,24.8511472 C5.46350648,25.0263523 5.77927587,25.0480591 6.03932126,24.9100657 L12.0002425,21.7718794 L17.9603899,24.9100657 C18.0733858,24.9697595 18.1972169,24.9992187 18.3202741,24.9992187 C18.4804806,24.9992187 18.6406872,24.9496031 18.7753535,24.8511472 C19.0137284,24.6774926 19.1329159,24.3836753 19.0833835,24.0929589 L17.944911,17.4444693 L22.7658118,12.7371898 C22.9770987,12.530975 23.0529453,12.2232033 22.9623938,11.9425651 C22.8710683,11.6619269 22.6288237,11.4572625 22.3370465,11.4146241 Z" id="路径" fill-opacity="0.6957231" fill="#FFCA23" fill-rule="nonzero" filter="url(#filter-1)"></path>
|
||||
<mask id="mask-4" fill="white">
|
||||
<use xlink:href="#path-3"></use>
|
||||
</mask>
|
||||
<g id="路径" fill-rule="nonzero">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-3"></use>
|
||||
<use fill="url(#linearGradient-2)" xlink:href="#path-3"></use>
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-3"></use>
|
||||
<path stroke-opacity="0.8" stroke="#FFFFFF" stroke-width="0.2" d="M11.2266591,0.241080187 L16.0645854,6.96661028 L23.454788,8.045711 L18.5910086,14.7495608 L19.8315027,22.0225866 C19.2622565,23.1360849 19.0671242,23.0979502 18.8707721,23.099179 L18.8707721,23.099179 L12.0009684,19.5771763 L5.39709804,23.0676459 L5.41424065,14.766815 L0.0672527664,9.52512944 L7.92123191,6.97737585 L11.2266591,0.241080187 Z"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="23px" viewBox="0 0 24 23" version="1.1">
|
||||
<title>路径</title>
|
||||
<g id="页面-2备份" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="评价" transform="translate(-1145.000000, -442.000000)" fill="#E5E7E9" fill-rule="nonzero">
|
||||
<g id="编组-12" transform="translate(954.000000, 401.000000)">
|
||||
<g id="编组-25" transform="translate(20.000000, 41.000000)">
|
||||
<g id="编组-9" transform="translate(54.000000, 0.000000)">
|
||||
<path d="M140.958975,8.69899984 C140.859347,8.39163419 140.59508,8.16747802 140.276778,8.12077882 L133.008172,7.05943334 L129.757605,0.434939378 C129.473074,-0.144979793 128.527455,-0.144979793 128.242925,0.434939378 L124.992357,7.05943334 L117.723751,8.12077882 C117.405449,8.16747802 117.141182,8.39163419 117.041554,8.69899984 C116.941926,9.00636549 117.024668,9.34344882 117.255163,9.56930313 L122.514327,14.7248949 L121.272357,22.006574 C121.218322,22.3249777 121.348345,22.6467776 121.60839,22.8369707 C121.86928,23.028862 122.213755,23.0526361 122.497441,22.9015005 L129.000265,19.4644393 L135.502243,22.9015005 C135.625512,22.9668794 135.7606,22.9991443 135.894844,22.9991443 C136.069615,22.9991443 136.244386,22.9448034 136.391295,22.8369707 C136.65134,22.6467776 136.781363,22.3249777 136.727327,22.006574 L135.485357,14.7248949 L140.744522,9.56930313 C140.975017,9.34344882 141.057758,9.00636549 140.958975,8.69899984 L140.958975,8.69899984 Z" id="路径"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
|
||||
<circle r="2.61111" transform="matrix(1 0 0 -1 8.55545 3.88889)" stroke="#4C5059"></circle>
|
||||
<circle r="2.61111" transform="matrix(1 0 0 -1 4.66678 3.88889)" fill="#F4F5F9" stroke="#4C5059"></circle>
|
||||
<path d="M5.16675 11.7778C5.16675 9.84484 6.73375 8.27783 8.66675 8.27783H10.0001C11.9331 8.27783 13.5001 9.84484 13.5001 11.7778V12.7223H5.16675V11.7778Z" stroke="#4C5059"></path>
|
||||
<path d="M0.5 11.7778C0.5 9.84484 2.067 8.27783 4 8.27783H5.33333C7.26633 8.27783 8.83333 9.84484 8.83333 11.7778V12.7223H0.5V11.7778Z" fill="#F4F5F9" stroke="#4C5059"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 666 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 887 B |
|
After Width: | Height: | Size: 751 B |
|
After Width: | Height: | Size: 629 B |
|
After Width: | Height: | Size: 664 B |
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
|
||||
<title>编组 9备份 5</title>
|
||||
<defs>
|
||||
<path d="M3.25,1 L12.75,1 C13.9926407,1 15,2.00735931 15,3.25 L15,8.80223083 L15,8.80223083 L15,10.6730769 C15,11.9157176 13.9926407,12.9230769 12.75,12.9230769 L9.60349397,12.9230769 L9.60349397,12.9230769 L8.41095925,14.4677057 C8.24220503,14.6862843 7.9282097,14.726675 7.70963106,14.5579208 C7.6710256,14.5281153 7.63698877,14.4928218 7.60860204,14.4531614 L6.51344888,12.9230769 L6.51344888,12.9230769 L3.25,12.9230769 C2.00735931,12.9230769 1,11.9157176 1,10.6730769 L1,3.25 C1,2.00735931 2.00735931,1 3.25,1 Z" id="path-1"></path>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="14" height="14" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="new" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.795168922">
|
||||
<g id="消息列表" transform="translate(-1076.000000, -700.000000)">
|
||||
<g id="输入框" transform="translate(796.000000, 686.000000)">
|
||||
<g id="编组-11" transform="translate(20.000000, 11.000000)">
|
||||
<g transform="translate(0.000000, 3.000000)" id="编组-9备份-5">
|
||||
<g transform="translate(260.000000, 0.000000)">
|
||||
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
|
||||
<use id="矩形" stroke="#232832" mask="url(#mask-2)" stroke-width="2" stroke-dasharray="0,0" xlink:href="#path-1"></use>
|
||||
<polyline id="路径-10" stroke="#232832" stroke-linecap="round" stroke-linejoin="round" points="9.29062678 3.74278634 5.97267016 6.33120496 9.88720003 7.13345401 6.6167373 9.74278634"></polyline>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#444444"
|
||||
d="M945.066667 898.133333l-189.866667-189.866666c55.466667-64 87.466667-149.333333 87.466667-241.066667 0-204.8-168.533333-373.333333-373.333334-373.333333S96 264.533333 96 469.333333 264.533333 842.666667 469.333333 842.666667c91.733333 0 174.933333-34.133333 241.066667-87.466667l189.866667 189.866667c6.4 6.4 14.933333 8.533333 23.466666 8.533333s17.066667-2.133333 23.466667-8.533333c8.533333-12.8 8.533333-34.133333-2.133333-46.933334zM469.333333 778.666667C298.666667 778.666667 160 640 160 469.333333S298.666667 160 469.333333 160 778.666667 298.666667 778.666667 469.333333 640 778.666667 469.333333 778.666667z" />
|
||||
<path fill="#444444"
|
||||
d="M597.333333 437.333333h-96V341.333333c0-17.066667-14.933333-32-32-32s-32 14.933333-32 32v96H341.333333c-17.066667 0-32 14.933333-32 32s14.933333 32 32 32h96V597.333333c0 17.066667 14.933333 32 32 32s32-14.933333 32-32v-96H597.333333c17.066667 0 32-14.933333 32-32s-14.933333-32-32-32z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="#444444"
|
||||
d="M945.066667 898.133333l-189.866667-189.866666c55.466667-64 87.466667-149.333333 87.466667-241.066667 0-204.8-168.533333-373.333333-373.333334-373.333333S96 264.533333 96 469.333333 264.533333 842.666667 469.333333 842.666667c91.733333 0 174.933333-34.133333 241.066667-87.466667l189.866667 189.866667c6.4 6.4 14.933333 8.533333 23.466666 8.533333s17.066667-2.133333 23.466667-8.533333c8.533333-12.8 8.533333-34.133333-2.133333-46.933334zM469.333333 778.666667C298.666667 778.666667 160 640 160 469.333333S298.666667 160 469.333333 160 778.666667 298.666667 778.666667 469.333333 640 778.666667 469.333333 778.666667z" />
|
||||
<path fill="#444444"
|
||||
d="M597.333333 437.333333H341.333333c-17.066667 0-32 14.933333-32 32s14.933333 32 32 32h256c17.066667 0 32-14.933333 32-32s-14.933333-32-32-32z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,3 @@
|
||||
import Dialog from './index.vue';
|
||||
|
||||
export default Dialog;
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div class="dialog" :class="[isH5 ? 'dialog-h5' : '', center ? 'center' : '']" v-if="show" @click.self="toggleView">
|
||||
<main class="dialog-main" :style="!background && {'background': 'none'}">
|
||||
<header v-if="isHeaderShow">
|
||||
<h1>{{title}}</h1>
|
||||
<i class="icon icon-close" @click="toggleView"></i>
|
||||
</header>
|
||||
<div class="dialog-main-content">
|
||||
<slot />
|
||||
</div>
|
||||
<footer v-if="isFooterShow">
|
||||
<button class="btn btn-cancel" @click="toggleView">{{$t('component.取消')}}</button>
|
||||
<button class="btn btn-default" @click="submit">{{$t('component.确定')}}</button>
|
||||
</footer>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, watchEffect, toRefs } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
isHeaderShow: {
|
||||
type: Boolean,
|
||||
default: () => true,
|
||||
},
|
||||
isFooterShow: {
|
||||
type: Boolean,
|
||||
default: () => true,
|
||||
},
|
||||
background: {
|
||||
type: Boolean,
|
||||
default: () => true,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
isH5: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
center: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
},
|
||||
setup(props:any, ctx:any) {
|
||||
const data = reactive({
|
||||
show: false,
|
||||
isHeaderShow: true,
|
||||
isFooterShow: true,
|
||||
background: true,
|
||||
title: '',
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.show = props.show;
|
||||
data.title = props.title;
|
||||
data.isHeaderShow = props.isHeaderShow;
|
||||
data.isFooterShow = props.isFooterShow;
|
||||
data.background = props.background;
|
||||
});
|
||||
|
||||
const toggleView = () => {
|
||||
data.show = !data.show;
|
||||
ctx.emit('update:show', data.show);
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
ctx.emit('submit');
|
||||
toggleView();
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
toggleView,
|
||||
submit,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped src="./style/dialog.scss"></style>
|
||||
@@ -0,0 +1,34 @@
|
||||
.dialog {
|
||||
background: rgba(0 ,0, 0, .3);
|
||||
header {
|
||||
h1 {
|
||||
font-family: PingFangSC-Medium;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
&-main {
|
||||
background: #FFFFFF;
|
||||
header {
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
&-content {
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn {
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0;
|
||||
&-cancel {
|
||||
border: 1px solid #dddddd;
|
||||
color: #666666;
|
||||
}
|
||||
&-default {
|
||||
background: #006EFF;
|
||||
border: 1px solid #006EFF;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
@import "./color.scss";
|
||||
@import "./web.scss";
|
||||
@import "./h5.scss";
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
@@ -0,0 +1,46 @@
|
||||
.dialog-h5 {
|
||||
height: 100%;
|
||||
top: 0;
|
||||
align-items: inherit;
|
||||
|
||||
.dialog {
|
||||
&-main {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
&-content {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
footer {
|
||||
border-top: 1px solid #DDDDDD;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
background: none;
|
||||
border-right: 1px solid #DDDDDD;
|
||||
|
||||
&-default {
|
||||
color: #FF584C;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
.dialog {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 6;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
header {
|
||||
h1 {
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
&-main {
|
||||
min-width: 368px;
|
||||
border-radius: 10px;
|
||||
padding: 20px 30px;
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
&-content {
|
||||
padding: 20px 0 40px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 8px 20px;
|
||||
margin: 0 6px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
import Drag from './index.vue';
|
||||
export default Drag;
|
||||
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div class="drag-container" v-show="show">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, toRefs, onMounted, watch, watchEffect } from 'vue';
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
domClassName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup(props: any, ctx: any) {
|
||||
const data = reactive({
|
||||
show: false,
|
||||
domClassName: '',
|
||||
startPosition: {
|
||||
left: '',
|
||||
top: '',
|
||||
cssText: '',
|
||||
},
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.show = props.show;
|
||||
data.domClassName = props.domClassName;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const dragDom = document.getElementsByClassName(
|
||||
props.domClassName ? props.domClassName : 'drag-container'
|
||||
)[0] as HTMLElement;
|
||||
if (!dragDom) return;
|
||||
let isDrag = false;
|
||||
watch(
|
||||
() => data.show,
|
||||
(newVal, oldVal) => {
|
||||
data.show = newVal;
|
||||
if (newVal === oldVal) return;
|
||||
if (data.show === true) {
|
||||
dragDom.style.left = data.startPosition?.left;
|
||||
dragDom.style.top = data.startPosition?.top;
|
||||
dragDom.style.cssText = data.startPosition?.cssText;
|
||||
}
|
||||
}
|
||||
);
|
||||
const mouseDown = (e: MouseEvent) => {
|
||||
isDrag = true;
|
||||
const X = e.clientX - dragDom.offsetLeft;
|
||||
const Y = e.clientY - dragDom.offsetTop;
|
||||
const move = (e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
if (isDrag) {
|
||||
dragDom.style.left = `${e.clientX - X}px`;
|
||||
dragDom.style.top = `${e.clientY - Y}px`;
|
||||
}
|
||||
};
|
||||
document.addEventListener('mousemove', throttle(move, 20), false);
|
||||
document.addEventListener('mouseup', () => {
|
||||
isDrag = false;
|
||||
document.removeEventListener('mousemove', move);
|
||||
});
|
||||
};
|
||||
dragDom.addEventListener('mousedown', mouseDown);
|
||||
});
|
||||
|
||||
function throttle(fn: { (e: MouseEvent): void; apply?: any }, timer: number) {
|
||||
let initTime = 0;
|
||||
return function (...args: any) {
|
||||
const nowTime = +new Date();
|
||||
if (nowTime - initTime > timer) {
|
||||
initTime = nowTime;
|
||||
fn.apply(ctx, args);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
throttle,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../styles/common.scss');
|
||||
@import url('../../styles/icon.scss');
|
||||
.drag-container {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="mask" @click.self="toggleView" v-if="show">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, watchEffect, toRefs } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
},
|
||||
setup(props:any, ctx:any) {
|
||||
const data = reactive({
|
||||
show: false,
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.show = props.show;
|
||||
});
|
||||
|
||||
const toggleView = () => {
|
||||
data.show = !data.show;
|
||||
ctx.emit('update:show', data.show);
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
toggleView,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../styles/common.scss');
|
||||
@import url('../../styles/icon.scss');
|
||||
.mask {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 99;
|
||||
background: rgba(#000000, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
main {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,75 @@
|
||||
import { createVNode, render, ComponentPublicInstance, VNode } from 'vue';
|
||||
import MessageConstructor from './index.vue';
|
||||
|
||||
const instances:any = [];
|
||||
let seed = 1;
|
||||
|
||||
const appendTo: HTMLElement | null = document.body;
|
||||
|
||||
const message = function (options:any) {
|
||||
const tempVm: any = instances.find((item:any) => `${item.vm.props?.message ?? ''}`
|
||||
=== `${(options as any).message ?? ''}`);
|
||||
if (tempVm) {
|
||||
tempVm.vm.component!.props.repeatNum += 1;
|
||||
return {
|
||||
close: () => ((
|
||||
vm.component!.proxy as ComponentPublicInstance<{
|
||||
visible: boolean
|
||||
}>
|
||||
).visible = false),
|
||||
};
|
||||
}
|
||||
let verticalOffset = options.offset || 20;
|
||||
instances.forEach(({ vm }:any) => {
|
||||
verticalOffset += (vm.el?.offsetHeight || 0) + 20;
|
||||
});
|
||||
verticalOffset += 20;
|
||||
const id = `message_${seed += 1}`;
|
||||
const userOnClose = options.onClose;
|
||||
const props:any = {
|
||||
zIndex: 20 + seed,
|
||||
offset: verticalOffset,
|
||||
id,
|
||||
...options,
|
||||
onClose: () => {
|
||||
close(id, userOnClose);
|
||||
},
|
||||
};
|
||||
const vm = createVNode(
|
||||
MessageConstructor,
|
||||
props,
|
||||
);
|
||||
const container = document.createElement('div');
|
||||
vm.props!.onDestroy = () => {
|
||||
render(null, container);
|
||||
};
|
||||
render(vm, container);
|
||||
instances.push({ vm });
|
||||
appendTo.appendChild(container.firstElementChild!);
|
||||
return {
|
||||
close: () => ((
|
||||
vm.component!.proxy as ComponentPublicInstance<{
|
||||
visible: boolean
|
||||
}>
|
||||
).visible = false),
|
||||
};
|
||||
};
|
||||
|
||||
export function close(id: string, userOnClose?: (vm: VNode) => void): void {
|
||||
const idx = instances.findIndex(({ vm }: any) => id === vm.component!.props.id);
|
||||
if (idx === -1) return;
|
||||
const { vm } = instances[idx];
|
||||
if (!vm) return;
|
||||
userOnClose?.(vm);
|
||||
const removedHeight = vm.el!.offsetHeight;
|
||||
instances.splice(idx, 1);
|
||||
// adjust other instances vertical offset
|
||||
const len = instances.length;
|
||||
if (len < 1) return;
|
||||
for (let i = idx; i < len; i++) {
|
||||
const pos = Number.parseInt(instances[i].vm.el!.style.top, 10) - removedHeight - 16;
|
||||
instances[i].vm.component!.props.offset = pos;
|
||||
}
|
||||
}
|
||||
|
||||
export default message;
|
||||
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<transition name="fade" @before-leave="onClose" @after-leave="$emit('destroy')">
|
||||
<div class="message" :class="[handleStyle(type), isH5 && 'message-h5']" :style="customStyle" v-show="visible">
|
||||
<p v-if="!isH5">{{ message }}</p>
|
||||
<span v-if="isH5">{{ message }}</span>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { useTimeoutFn } from '@vueuse/core';
|
||||
import { computed, CSSProperties, defineComponent, onMounted, ref, watch } from 'vue';
|
||||
export default defineComponent({
|
||||
name: 'TUIMessage',
|
||||
props: {
|
||||
message: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 3000,
|
||||
},
|
||||
repeatNum: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
onClose: {
|
||||
type: Function,
|
||||
required: false,
|
||||
},
|
||||
offset: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
isH5: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const visible = ref(false);
|
||||
|
||||
let stopTimer: (() => void) | undefined = undefined;
|
||||
|
||||
function startTimer() {
|
||||
if (props.duration > 0) {
|
||||
({ stop: stopTimer } = useTimeoutFn(() => {
|
||||
if (visible.value) close();
|
||||
}, props.duration));
|
||||
}
|
||||
}
|
||||
|
||||
function clearTimer() {
|
||||
stopTimer?.();
|
||||
}
|
||||
|
||||
function close() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.repeatNum,
|
||||
() => {
|
||||
clearTimer();
|
||||
startTimer();
|
||||
}
|
||||
);
|
||||
|
||||
const customStyle = computed<CSSProperties>(() => ({
|
||||
top: `${props.offset}px`,
|
||||
zIndex: props.zIndex,
|
||||
}));
|
||||
|
||||
onMounted(() => {
|
||||
startTimer();
|
||||
visible.value = true;
|
||||
});
|
||||
|
||||
const handleStyle = (type?: string) => {
|
||||
if (type && (type === 'error' || type === 'success' || type === 'warning')) return type;
|
||||
return 'normal';
|
||||
};
|
||||
|
||||
return {
|
||||
visible,
|
||||
customStyle,
|
||||
handleStyle,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../styles/common.scss');
|
||||
@import url('../../styles/icon.scss');
|
||||
.message {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
max-width: 450px;
|
||||
width: fit-content;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
p {
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
padding: 10px 15px;
|
||||
width: fit-content;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
.message-h5 {
|
||||
position: absolute;
|
||||
top: 300px !important;
|
||||
margin: 0 auto;
|
||||
width: fit-content;
|
||||
max-width: 80%;
|
||||
width: fit-content;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
padding: 10px 15px;
|
||||
span {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
.success {
|
||||
border: 1px solid #e4f2da;
|
||||
background: #f2f9ec;
|
||||
color: #7ebf50;
|
||||
}
|
||||
.error {
|
||||
border: 1px solid #fde2e2;
|
||||
background: #fef0f0;
|
||||
color: #f46c6e;
|
||||
}
|
||||
.normal {
|
||||
border: 1px solid #e9e9eb;
|
||||
background: #f4f4f5;
|
||||
color: #909398;
|
||||
}
|
||||
.warning {
|
||||
border: 1px solid #faf0e2;
|
||||
background: #fdf8f1;
|
||||
color: #e4b877;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="slider-box" :class="[open && 'slider-open']" @click="toggle">
|
||||
<span class="slider-block"></span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, watchEffect, toRefs } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
open: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
},
|
||||
setup(props:any, ctx:any) {
|
||||
const data = reactive({
|
||||
open: false,
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.open = props.open;
|
||||
});
|
||||
|
||||
|
||||
const toggle = () => {
|
||||
data.open = !data.open;
|
||||
ctx.emit('change', data.open);
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
toggle,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../styles/common.scss');
|
||||
@import url('../../styles/icon.scss');
|
||||
.slider {
|
||||
&-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 34px;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
background: #E1E1E3;
|
||||
}
|
||||
&-open {
|
||||
background: #006EFF !important;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
&-block {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 8px;
|
||||
margin: 0 2px;
|
||||
background: #FFFFFF;
|
||||
border: 0 solid rgba(0,0,0,0.85);
|
||||
box-shadow: 0 2px 4px 0 #D1D1D1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
import Transfer from './index.vue';
|
||||
|
||||
export default Transfer;
|
||||
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<div class="transfer" :class="[isH5 ? 'transfer-h5' : '']">
|
||||
<header class="transfer-h5-header" v-if="isH5">
|
||||
<i class="icon icon-back" @click="cancel"></i>
|
||||
<span class="title">{{ title }}</span>
|
||||
</header>
|
||||
<main class="main">
|
||||
<div class="left">
|
||||
<header v-if="isSearch">
|
||||
<input
|
||||
type="text"
|
||||
@keyup.enter="handleInput"
|
||||
:placeholder="$t('component.请输入userID')"
|
||||
enterkeyhint="search"
|
||||
/>
|
||||
</header>
|
||||
<main>
|
||||
<ul class="list">
|
||||
<li class="list-item" @click="selectedAll" v-if="optional.length > 1 && !isRadio">
|
||||
<i
|
||||
class="icon"
|
||||
:class="[selectedList.length === optional.length ? 'icon-selected' : 'icon-unselected']"
|
||||
></i>
|
||||
<span class="all">{{ $t('component.全选') }}</span>
|
||||
</li>
|
||||
<li class="list-item" v-for="(item, index) in list" :key="index" @click="selected(item)">
|
||||
<i
|
||||
class="icon"
|
||||
:class="[
|
||||
item?.isDisabled && 'disabled',
|
||||
selectedList.indexOf(item) > -1 ? 'icon-selected' : 'icon-unselected',
|
||||
]"
|
||||
></i>
|
||||
<template v-if="!isCustomItem">
|
||||
<img
|
||||
class="avatar"
|
||||
:src="item?.avatar || 'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"
|
||||
onerror="this.src='https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"
|
||||
/>
|
||||
<span class="name">{{ item?.nick || item?.userID }}</span>
|
||||
<span v-if="item?.isDisabled">({{ $t('component.已在群聊中') }})</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<slot name="left" :data="item" />
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
</main>
|
||||
</div>
|
||||
<div class="right">
|
||||
<header v-if="!isH5">{{ title }}</header>
|
||||
<ul class="list" v-show="resultShow">
|
||||
<p v-if="selectedList.length > 0 && !isH5">
|
||||
{{ $t('component.已选中') }}{{ selectedList.length }}{{ $t('component.人') }}
|
||||
</p>
|
||||
<li class="list-item space-between" v-for="(item, index) in selectedList" :key="index">
|
||||
<aside>
|
||||
<template v-if="!isCustomItem">
|
||||
<img
|
||||
class="avatar"
|
||||
:src="item?.avatar || 'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"
|
||||
onerror="this.src='https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"
|
||||
/>
|
||||
<span v-if="!isH5">{{ item.nick || item.userID }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<slot name="right" :data="item" />
|
||||
</template>
|
||||
</aside>
|
||||
<i class="icon icon-cancel" @click="selected(item)" v-if="!isH5"></i>
|
||||
</li>
|
||||
</ul>
|
||||
<footer>
|
||||
<button class="btn btn-cancel" @click="cancel">{{ $t('component.取消') }}</button>
|
||||
<button v-if="selectedList.length > 0" class="btn" @click="submit">{{ $t('component.完成') }}</button>
|
||||
<button v-else class="btn btn-no" @click="submit">{{ $t('component.完成') }}</button>
|
||||
</footer>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, watchEffect, toRefs, computed } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
selectedList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
isSearch: {
|
||||
type: Boolean,
|
||||
default: () => true,
|
||||
},
|
||||
isRadio: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
isCustomItem: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: () => '',
|
||||
},
|
||||
isH5: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
resultShow: {
|
||||
type: Boolean,
|
||||
default: () => true,
|
||||
},
|
||||
},
|
||||
setup(props: any, ctx: any) {
|
||||
const data = reactive({
|
||||
type: '',
|
||||
list: [],
|
||||
selectedList: [],
|
||||
isSearch: true,
|
||||
isCustomItem: false,
|
||||
title: '',
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.isCustomItem) {
|
||||
for (let index = 0; index < props.list.length; index++) {
|
||||
if (props.list[index].conversationID.indexOf('@TIM#SYSTEM') > -1) {
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
props.list.splice(index, 1);
|
||||
}
|
||||
data.list = props.list;
|
||||
}
|
||||
} else {
|
||||
data.list = props.list;
|
||||
}
|
||||
data.selectedList = props.selectedList;
|
||||
data.isSearch = props.isSearch;
|
||||
data.isCustomItem = props.isCustomItem;
|
||||
data.title = props.title;
|
||||
data.type = props.type;
|
||||
});
|
||||
|
||||
// 可选项
|
||||
const optional = computed(() => data.list.filter((item: any) => !item.isDisabled));
|
||||
|
||||
const handleInput = (e: any) => {
|
||||
ctx.emit('search', e.target.value);
|
||||
};
|
||||
|
||||
const selected = (item: any) => {
|
||||
if (item.isDisabled) {
|
||||
return;
|
||||
}
|
||||
let list: any = data.selectedList;
|
||||
const index: number = list.indexOf(item);
|
||||
if (index > -1) {
|
||||
return data.selectedList.splice(index, 1);
|
||||
}
|
||||
if (props.isRadio) {
|
||||
list = [];
|
||||
}
|
||||
list.push(item);
|
||||
data.selectedList = list;
|
||||
};
|
||||
|
||||
const selectedAll = () => {
|
||||
if (data.selectedList.length === optional.value.length) {
|
||||
data.selectedList = [];
|
||||
} else {
|
||||
data.selectedList = [...optional.value];
|
||||
}
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
ctx.emit('submit', data.selectedList);
|
||||
};
|
||||
|
||||
const cancel = () => {
|
||||
ctx.emit('cancel');
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
optional,
|
||||
handleInput,
|
||||
selected,
|
||||
selectedAll,
|
||||
submit,
|
||||
cancel,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped src="./style/transfer.scss"></style>
|
||||
@@ -0,0 +1,63 @@
|
||||
.main {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #E0E0E0;
|
||||
box-shadow: 0 -4px 12px 0 rgba(0,0,0,0.06);
|
||||
.left {
|
||||
border-right: 1px solid #E8E8E9;
|
||||
}
|
||||
header {
|
||||
font-weight: 500;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
input {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #DEE0E3;
|
||||
font-weight: 500;
|
||||
color: #8F959E;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
}
|
||||
.list {
|
||||
p {
|
||||
font-weight: 500;
|
||||
color: #8F959E;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
&-item {
|
||||
.disabled {
|
||||
background: #eeeeee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.avatar {
|
||||
background: #F4F5F9;
|
||||
color: #000000;
|
||||
}
|
||||
.btn {
|
||||
background: #3370FF;
|
||||
border: 0 solid #2F80ED;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
&-cancel {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #DDDDDD;
|
||||
color: #828282;
|
||||
}
|
||||
}
|
||||
.btn-no {
|
||||
background: #e8e8e9;
|
||||
border: 1px solid #DDDDDD;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.transfer-h5-header {
|
||||
background: #FFFFFF;
|
||||
.title {
|
||||
font-family: PingFangSC-Medium;
|
||||
font-weight: 500;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
.transfer-h5 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
&-header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
padding: 16px 18px;
|
||||
.icon {
|
||||
position: absolute;
|
||||
left: 18px;
|
||||
top: 18px;
|
||||
}
|
||||
}
|
||||
.main {
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
width: auto;
|
||||
height: auto;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
max-height: calc( 100% - 54px);
|
||||
padding: 0;
|
||||
.avatar {
|
||||
border-radius: 0;
|
||||
}
|
||||
.left {
|
||||
padding: 0;
|
||||
flex: 1;
|
||||
border: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
padding: 0 18px;
|
||||
input {
|
||||
border-radius: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.list {
|
||||
padding: 0 18px;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
flex: 0;
|
||||
padding: 0;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
box-shadow: inset 0 1px 0 0 #EEEEEE;
|
||||
padding: 0 18px 8px;
|
||||
.list {
|
||||
flex-direction: row;
|
||||
width: 0;
|
||||
}
|
||||
footer {
|
||||
padding: 6px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.btn {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
@import "./color.scss";
|
||||
@import "./web.scss";
|
||||
@import "./h5.scss";
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
@@ -0,0 +1,135 @@
|
||||
.main {
|
||||
box-sizing: border-box;
|
||||
width: 620px;
|
||||
height: 394px;
|
||||
display: flex;
|
||||
border-radius: 8px;
|
||||
padding: 20px 0;
|
||||
|
||||
.right {
|
||||
padding: 0 20px;
|
||||
flex: 1;
|
||||
|
||||
ul {
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
overflow-y: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
header {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
footer {
|
||||
align-self: flex-end;
|
||||
|
||||
.btn-cancel {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
header {
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
padding-bottom: 20px;
|
||||
|
||||
input {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
border-radius: 30px;
|
||||
font-size: 10px;
|
||||
line-height: 14px;
|
||||
padding: 9px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
font-size: 10px;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
&-item {
|
||||
padding: 6px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
|
||||
aside {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
margin: 0 5px 0 8px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
img,
|
||||
.avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 4px 28px;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.btn-no {
|
||||
padding: 4px 28px;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.space-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.all {
|
||||
padding-left: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
/**
|
||||
* class IComponentServer
|
||||
*
|
||||
* IComponentServer 组件 server 基类
|
||||
*/
|
||||
export default class IComponentServer {
|
||||
/**
|
||||
* 组件销毁
|
||||
*/
|
||||
public destroyed() {}
|
||||
|
||||
/**
|
||||
* 数据监听回调
|
||||
*
|
||||
* @param {any} oldValue 旧数据
|
||||
* @param {any} newValue 新数据
|
||||
*/
|
||||
protected updateStore(oldValue:any, newValue:any) {}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import MessageText from './message-text.vue';
|
||||
import MessageImage from './message-image.vue';
|
||||
import MessageVideo from './message-video.vue';
|
||||
import MessageAudio from './message-audio.vue';
|
||||
import MessageFile from './message-file.vue';
|
||||
import MessageFace from './message-face.vue';
|
||||
import MessageLocation from './message-location.vue';
|
||||
import MessageMerger from './message-merger.vue';
|
||||
import MessageCustom from './message-custom.vue';
|
||||
import MessageTip from './message-tip.vue';
|
||||
import MessageBubble from './message-bubble.vue';
|
||||
import MessageRevoked from './message-revoked.vue';
|
||||
import MessageSystem from './message-system.vue';
|
||||
import MessageTool from './message-tool.vue';
|
||||
import MessageEmojiReact from './message-emoji-react.vue';
|
||||
import MessageItem from './index.vue';
|
||||
import MessageTimestamp from './message-timestamp.vue'
|
||||
|
||||
export {
|
||||
MessageText,
|
||||
MessageImage,
|
||||
MessageVideo,
|
||||
MessageAudio,
|
||||
MessageFile,
|
||||
MessageFace,
|
||||
MessageLocation,
|
||||
MessageMerger,
|
||||
MessageCustom,
|
||||
MessageTip,
|
||||
MessageTimestamp,
|
||||
MessageBubble,
|
||||
MessageRevoked,
|
||||
MessageSystem,
|
||||
MessageTool,
|
||||
MessageEmojiReact,
|
||||
MessageItem
|
||||
};
|
||||
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<div class="message-item">
|
||||
<MessageTip v-if="isMessageTip(message) && message.type !== types.MSG_CUSTOM" :data="handleTipMessageShowContext(message)" />
|
||||
<MessageBubble
|
||||
style="background: #f5f5f5 !important"
|
||||
v-else-if="!message.isRevoked"
|
||||
:data="message"
|
||||
:isH5="env.isH5"
|
||||
:types="types"
|
||||
:messagesList="messageList"
|
||||
:needGroupReceipt="displayGroupMessageReadReceipt"
|
||||
:needReplies="true"
|
||||
:needEmojiReact="displayEmojiReactions"
|
||||
@resendMessage="resendMessage"
|
||||
@showReadReceiptDialog="showReadReceiptDialog"
|
||||
@showRepliesDialog="showRepliesDialog"
|
||||
>
|
||||
<MessageText v-if="message.type === types.MSG_TEXT" :data="handleTextMessageShowContext(message)" />
|
||||
<MessageImage
|
||||
v-if="message.type === types.MSG_IMAGE"
|
||||
:isH5="env.isH5"
|
||||
:data="handleImageMessageShowContext(message)"
|
||||
@uploading="uploading"
|
||||
@previewImage="previewImage"
|
||||
/>
|
||||
<MessageVideo
|
||||
v-if="message.type === types.MSG_VIDEO"
|
||||
:isH5="env.isH5"
|
||||
:data="handleVideoMessageShowContext(message)"
|
||||
@uploading="uploading"
|
||||
/>
|
||||
<MessageAudio v-if="message.type === types.MSG_AUDIO" :data="handleAudioMessageShowContext(message)" />
|
||||
<MessageFile v-if="message.type === types.MSG_FILE" :data="handleFileMessageShowContext(message)" />
|
||||
<MessageFace v-if="message.type === types.MSG_FACE" :data="handleFaceMessageShowContext(message)" :isH5="env.isH5" />
|
||||
<MessageLocation v-if="message.type === types.MSG_LOCATION" :data="handleLocationMessageShowContext(message)" />
|
||||
<MessageCustom v-if="message.type === types.MSG_CUSTOM" :data="handleCustomMessageShowContext(message)" />
|
||||
<MessageMerger v-if="message.type === types.MSG_MERGER" :data="handleMergerMessageShowContext(message)" />
|
||||
<template #dialog>
|
||||
<MessageTool :message="message" :needEmojiReact="displayEmojiReactions" @handleMessage="handleMessage" />
|
||||
<MessageEmojiReact v-if="!env?.isH5 && displayEmojiReactions" :message="message" type="dropdown" />
|
||||
</template>
|
||||
</MessageBubble>
|
||||
<MessageRevoked v-else :isEdit="message.type === types.MSG_TEXT" :data="message" @edit="handleEdit(message)" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRefs, defineProps, defineEmits } from 'vue';
|
||||
import MessageBubble from './message-bubble.vue';
|
||||
import MessageText from './message-text.vue';
|
||||
import MessageImage from './message-image.vue';
|
||||
import MessageVideo from './message-video.vue';
|
||||
import MessageAudio from './message-audio.vue';
|
||||
import MessageFile from './message-file.vue';
|
||||
import MessageFace from './message-face.vue';
|
||||
import MessageLocation from './message-location.vue';
|
||||
import MessageMerger from './message-merger.vue';
|
||||
import MessageCustom from './message-custom.vue';
|
||||
import MessageTip from './message-tip.vue';
|
||||
import MessageTool from './message-tool.vue';
|
||||
import MessageEmojiReact from './message-emoji-react.vue';
|
||||
import MessageRevoked from './message-revoked.vue';
|
||||
|
||||
import {
|
||||
handleTextMessageShowContext,
|
||||
handleImageMessageShowContext,
|
||||
handleVideoMessageShowContext,
|
||||
handleAudioMessageShowContext,
|
||||
handleFileMessageShowContext,
|
||||
handleFaceMessageShowContext,
|
||||
handleLocationMessageShowContext,
|
||||
handleMergerMessageShowContext,
|
||||
handleTipMessageShowContext,
|
||||
handleCustomMessageShowContext,
|
||||
isMessageTip,
|
||||
} from '../utils/utils';
|
||||
import { Message } from 'tim-js-sdk/tim-js-friendship';
|
||||
import constant from '../../constant';
|
||||
import { MessageItem } from '@/TUIKit/TUIComponents/container/TUIChat/components/index';
|
||||
|
||||
const props = defineProps({
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
beforeMessage: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
types: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
env: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
messageList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 开关控制位
|
||||
displayGroupMessageReadReceipt: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
displayEmojiReactions: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(['handleEditor', 'showDialog', 'uploading', 'jumpID', 'resendMessage']);
|
||||
const { message, types, env, messageList, displayGroupMessageReadReceipt, displayEmojiReactions } = toRefs(props);
|
||||
// console.log('message========================')
|
||||
// console.log(JSON.stringify(message))
|
||||
const handleEdit = (message: any) => {
|
||||
emits('handleEditor', message, 'reedit');
|
||||
};
|
||||
|
||||
const handleMessage = (message: Message, type: string) => {
|
||||
if (!message || !type) {
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case constant.handleMessage.forward:
|
||||
emits('showDialog', message, constant.handleMessage.forward);
|
||||
break;
|
||||
case constant.handleMessage.reference:
|
||||
emits('handleEditor', message, constant.handleMessage.reference);
|
||||
break;
|
||||
case constant.handleMessage.reply:
|
||||
emits('handleEditor', message, constant.handleMessage.reply);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const previewImage = (message: Message) => {
|
||||
if (message) {
|
||||
emits('showDialog', message, 'previewImage');
|
||||
}
|
||||
};
|
||||
|
||||
const showReadReceiptDialog = (message: Message) => {
|
||||
if (message) {
|
||||
emits('showDialog', message, 'receipt');
|
||||
}
|
||||
};
|
||||
|
||||
const showRepliesDialog = (message: Message) => {
|
||||
if (message) {
|
||||
emits('showDialog', message, 'replies');
|
||||
}
|
||||
};
|
||||
|
||||
const jumpID = (messageID: string) => {
|
||||
if (messageID) {
|
||||
emits('jumpID', messageID);
|
||||
}
|
||||
};
|
||||
|
||||
const uploading = () => {
|
||||
emits('uploading');
|
||||
};
|
||||
|
||||
const resendMessage = (message: Message) => {
|
||||
if (message) {
|
||||
emits('resendMessage', message);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
|
||||
.message-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div class="message-audio" :class="[data.message.flow === 'out' && 'reserve']" @click.stop="play" :style="`width: ${data?.second * 10 + 40}px`">
|
||||
<i class="icon icon-voice" :class="[data.message.flow === 'out' && 'icon-reserve']"></i>
|
||||
<label>{{ data.second }}s</label>
|
||||
<audio
|
||||
ref="audio"
|
||||
:src="data.url.indexOf('http') === -1 ? `${hrefParams.urlF.replace('lol', '://')}/file/show/${data.url}` : data.url"
|
||||
></audio>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watch, reactive, toRefs, ref } from 'vue';
|
||||
import hrefParams from '@/utils/herfParams';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
setup(props: any, ctx: any) {
|
||||
const data = reactive({
|
||||
data: {},
|
||||
show: false,
|
||||
});
|
||||
|
||||
const audio = ref(null);
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
() => {
|
||||
data.data = props.data;
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
const play = () => {
|
||||
const audios = document.getElementsByTagName('audio');
|
||||
for (const audio of audios) {
|
||||
if (!audio.paused) {
|
||||
audio.pause();
|
||||
audio.load();
|
||||
}
|
||||
}
|
||||
const audioPlayer: any = audio.value;
|
||||
if (audioPlayer.paused) {
|
||||
audioPlayer.play();
|
||||
data.show = true;
|
||||
} else {
|
||||
audioPlayer.pause();
|
||||
audioPlayer.load();
|
||||
data.show = false;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
audio,
|
||||
play,
|
||||
hrefParams,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
.message-audio {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
.icon {
|
||||
margin: 0 4px;
|
||||
}
|
||||
audio {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
.reserve {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,674 @@
|
||||
<template>
|
||||
<div class="message-bubble" :class="[message.flow === 'in' ? '' : 'reverse']" ref="htmlRefHook">
|
||||
<!-- <img-->
|
||||
<!-- class="avatar"-->
|
||||
<!-- :src="message?.avatar || 'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"-->
|
||||
<!-- onerror="this.src='https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"-->
|
||||
<!-- alt=""-->
|
||||
<!-- />-->
|
||||
<img class="avatar" v-if="getSrc(message)" :src="getSrc(message)" alt="" />
|
||||
<img class="avatar" v-else src="@/assets/image/default_avatar.png" alt="" />
|
||||
<main class="message-area">
|
||||
<label class="name" v-if="message.flow === 'in' && message.conversationType === 'GROUP'">
|
||||
{{ message.nameCard || message.nick || message.from }}
|
||||
</label>
|
||||
<div :class="handleImageOrVideoBubbleStyle(message)" @click.prevent.right="toggleDialog">
|
||||
<div
|
||||
class="message-replie-area"
|
||||
:class="[message?.flow === 'in' ? '' : 'message-replies-area-reverse']"
|
||||
v-if="message?.cloudCustomData && referenceMessage && referenceMessage?.messageRootID"
|
||||
@click="showRepliesDialog(message, false)"
|
||||
>
|
||||
<MessageReference
|
||||
:message="message"
|
||||
:referenceMessage="referenceMessage"
|
||||
:referenceForShow="referenceForShow"
|
||||
:url="url"
|
||||
:face="face"
|
||||
:allMessageID="allMessageID"
|
||||
type="reply"
|
||||
/>
|
||||
</div>
|
||||
<slot />
|
||||
<div v-if="dropdown" ref="dropdownRef" class="dropdown-inner">
|
||||
<div class="dialog" :class="[message.flow === 'in' ? '' : 'dialog-right']" @click="dropdown = false">
|
||||
<slot name="dialog" />
|
||||
</div>
|
||||
</div>
|
||||
<MessageEmojiReact :message="message" type="content" v-if="needEmojiReact && isEmojiReactionInMessage(message)" />
|
||||
</div>
|
||||
</main>
|
||||
<label class="message-label fail" v-if="message.status === 'fail'" @click="resendMessage(message)">!</label>
|
||||
<!-- <label-->
|
||||
<!-- class="message-label"-->
|
||||
<!-- :class="readReceiptStyle(message)"-->
|
||||
<!-- v-if="showReadReceiptTag(message)"-->
|
||||
<!-- @click="showReadReceiptDialog(message)"-->
|
||||
<!-- >-->
|
||||
<!-- <span>{{ readReceiptCont(message) }}</span>-->
|
||||
<!-- </label>-->
|
||||
</div>
|
||||
<div
|
||||
class="message-reference-area"
|
||||
:class="[message.flow === 'in' ? '' : 'message-reference-area-reverse']"
|
||||
v-if="message?.cloudCustomData && referenceMessage && !referenceMessage?.messageRootID"
|
||||
@click="jumpToAim(referenceMessage)"
|
||||
>
|
||||
<MessageReference
|
||||
:message="message"
|
||||
:referenceMessage="referenceMessage"
|
||||
:referenceForShow="referenceForShow"
|
||||
:url="url"
|
||||
:face="face"
|
||||
:allMessageID="allMessageID"
|
||||
type="reference"
|
||||
/>
|
||||
</div>
|
||||
<label
|
||||
class="message-replies"
|
||||
:class="[message.flow === 'in' ? '' : 'message-replies-reverse']"
|
||||
v-if="replies?.length"
|
||||
@click="showRepliesDialog(message, true)"
|
||||
>
|
||||
<i class="icon icon-msg-replies"></i>
|
||||
<span>{{ replies?.length + $t('TUIChat.条回复') }}</span>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { decodeText } from '../utils/decodeText';
|
||||
import constant from '../../constant';
|
||||
import { defineComponent, watchEffect, reactive, toRefs, ref, nextTick, watch } from 'vue';
|
||||
import { onClickOutside, onLongPress, useElementBounding } from '@vueuse/core';
|
||||
import { deepCopy, JSONToObject } from '../utils/utils';
|
||||
import { handleErrorPrompts } from '../../utils';
|
||||
import TUIChat from '../index.vue';
|
||||
import MessageReference from './message-reference.vue';
|
||||
import { Message } from '../interface';
|
||||
import { TUIEnv } from '../../../../../TUIKit/TUIPlugin';
|
||||
import MessageEmojiReact from './message-emoji-react.vue';
|
||||
import TIM from '../../../../TUICore/tim/index';
|
||||
|
||||
const messageBubble = defineComponent({
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
messagesList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
isH5: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
needGroupReceipt: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
needReplies: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
flow: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
needEmojiReact: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['jumpID', 'resendMessage', 'showReadReceiptDialog', 'showRepliesDialog', 'dropDownOpen'],
|
||||
components: {
|
||||
MessageReference,
|
||||
MessageEmojiReact,
|
||||
},
|
||||
setup(props: any, ctx: any) {
|
||||
const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
|
||||
const { TUIServer } = TUIChat;
|
||||
const data = reactive({
|
||||
env: TUIEnv(),
|
||||
message: {} as Message,
|
||||
messagesList: [],
|
||||
show: false,
|
||||
type: {},
|
||||
referenceMessage: {},
|
||||
referenceForShow: {},
|
||||
allMessageID: '',
|
||||
needGroupReceipt: false,
|
||||
needReplies: true,
|
||||
replies: [],
|
||||
face: [],
|
||||
url: '',
|
||||
needEmojiReact: false,
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.type = constant;
|
||||
data.messagesList = props.messagesList;
|
||||
data.needEmojiReact = props.needEmojiReact;
|
||||
data.message = deepCopy(data.messagesList?.find((item: any) => (item as any)?.ID === props.message?.ID) || props.data);
|
||||
data.needGroupReceipt = props.needGroupReceipt;
|
||||
data.needReplies = props.needReplies;
|
||||
if ((data.message as any).cloudCustomData) {
|
||||
const messageIDList: any[] = [];
|
||||
const cloudCustomData = JSONToObject((data.message as any).cloudCustomData);
|
||||
data.replies = cloudCustomData?.messageReplies?.replies || [];
|
||||
data.referenceMessage = cloudCustomData.messageReply ? cloudCustomData.messageReply : '';
|
||||
for (let index = 0; index < (data.messagesList as any).length; index++) {
|
||||
// To determine whether the referenced message is still in the message list, the corresponding field of the referenced message is displayed if it is in the message list. Otherwise, messageabstract/messagesender is displayed
|
||||
messageIDList.push((data.messagesList as any)[index].ID);
|
||||
(data as any).allMessageID = JSON.stringify(messageIDList);
|
||||
if ((data.messagesList as any)[index].ID === (data.referenceMessage as any)?.messageID) {
|
||||
data.referenceForShow = (data.messagesList as any)[index];
|
||||
if ((data.referenceMessage as any).messageType === constant.typeText) {
|
||||
(data as any).face = decodeText((data.referenceForShow as any).payload);
|
||||
}
|
||||
if ((data.referenceMessage as any).messageType === constant.typeFace) {
|
||||
(data as any).url = `https://web.sdk.qcloud.com/im/assets/face-elem/${
|
||||
(data.referenceForShow as any).payload.data
|
||||
}@2x.png`;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data.replies = [];
|
||||
}
|
||||
});
|
||||
|
||||
const htmlRefHook = ref<HTMLElement | null>(null);
|
||||
const dropdown = ref(false);
|
||||
const dropdownRef = ref(null);
|
||||
|
||||
const toggleDialog = (e: any) => {
|
||||
dropdown.value = !dropdown.value;
|
||||
if (dropdown.value) {
|
||||
ctx.emit('dropDownOpen', dropdownRef);
|
||||
nextTick(() => {
|
||||
const dialogDom = (dropdownRef as any)?.value?.children[0];
|
||||
const dialogElement = document.getElementsByClassName('dialog-item')[0] as HTMLElement;
|
||||
const parentDom = (dropdownRef as any)?.value?.offsetParent;
|
||||
const parentBound = useElementBounding(parentDom);
|
||||
const messageListDom = document.getElementById('messageEle') as HTMLElement;
|
||||
const messageListBound = useElementBounding(messageListDom);
|
||||
const leftRange = messageListBound?.left?.value;
|
||||
const rightRange = messageListBound?.left?.value + (messageListDom as any).clientWidth - dialogDom.clientWidth + 76;
|
||||
const topRange = messageListBound?.top?.value;
|
||||
const bottomRange = messageListBound?.top?.value + (messageListDom as any).clientHeight - dialogDom.clientHeight;
|
||||
const { clientX, clientY } = e;
|
||||
if (data?.env?.isH5) {
|
||||
if (parentBound?.top?.value <= dialogElement?.clientHeight) {
|
||||
dialogDom.style.bottom = `-${dialogElement?.clientHeight}px`;
|
||||
} else {
|
||||
if (data?.message?.flow === 'in') {
|
||||
dialogDom.style.top = `-${dialogElement?.clientHeight - 20}px`;
|
||||
} else {
|
||||
dialogDom.style.top = `-${dialogElement?.clientHeight}px`;
|
||||
}
|
||||
}
|
||||
const centerWidth = parentBound?.left?.value + parentBound?.width?.value / 2;
|
||||
if (
|
||||
centerWidth > dialogElement.clientWidth / 2 &&
|
||||
centerWidth < messageListDom?.clientWidth - dialogElement.clientWidth / 2
|
||||
) {
|
||||
dialogDom.style.left = 'calc(50% - 135px)';
|
||||
} else if (centerWidth <= dialogElement.clientWidth / 2) {
|
||||
dialogDom.style.left = '-20px';
|
||||
} else {
|
||||
dialogDom.style.left = `-${dialogElement.clientWidth / 2 + 10}px`;
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (true) {
|
||||
case clientX > leftRange && clientX < rightRange:
|
||||
dialogDom.style.left = `${Math.max(e.clientX - parentBound?.left?.value - 76, -40)}px`;
|
||||
break;
|
||||
case clientX <= leftRange:
|
||||
dialogDom.style.left = '20px';
|
||||
break;
|
||||
case clientX >= rightRange:
|
||||
dialogDom.style.right = `${Math.max(parentBound?.left?.value + parentDom?.clientWidth - e.clientX - 256, -10)}px`;
|
||||
break;
|
||||
}
|
||||
switch (true) {
|
||||
case clientY > topRange && clientY < bottomRange:
|
||||
dialogDom.style.top = `${e.clientY - parentBound?.top?.value}px`;
|
||||
dialogDom.style.cssText = dialogDom.style.cssText.replace('align-items:end;', '');
|
||||
break;
|
||||
case clientY <= topRange:
|
||||
dialogDom.style.top = '0px';
|
||||
dialogDom.style.cssText = dialogDom.style.cssText.replace('align-items:end;', '');
|
||||
break;
|
||||
case clientY >= bottomRange:
|
||||
dialogDom.style.bottom = `${parentBound?.top?.value + parentDom?.clientHeight - e.clientY}px`;
|
||||
dialogDom.style.cssText += 'align-items:end;';
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const jumpToAim = (message: any) => {
|
||||
if ((data.referenceMessage as any)?.messageID && data.allMessageID.includes((data.referenceMessage as any)?.messageID)) {
|
||||
ctx.emit('jumpID', (data.referenceMessage as any).messageID);
|
||||
} else {
|
||||
const message = t('TUIChat.无法定位到原消息');
|
||||
handleErrorPrompts(message, props);
|
||||
}
|
||||
};
|
||||
|
||||
onClickOutside(dropdownRef, () => {
|
||||
dropdown.value = false;
|
||||
});
|
||||
|
||||
const toggleDialogH5 = (e: any) => {
|
||||
if (data?.env?.isH5) toggleDialog(e);
|
||||
return;
|
||||
};
|
||||
|
||||
onLongPress(htmlRefHook, toggleDialogH5);
|
||||
|
||||
const resendMessage = (message: any) => {
|
||||
ctx.emit('resendMessage', message);
|
||||
};
|
||||
|
||||
const showReadReceiptTag = (message: any) => {
|
||||
if (message.flow === 'out' && message.status === 'success' && message.needReadReceipt && message.conversationType !== 'GROUP') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const readReceiptStyle = (message: any) => {
|
||||
if (
|
||||
message?.readReceiptInfo?.isPeerRead ||
|
||||
(message?.readReceiptInfo?.isPeerRead === undefined && message?.isPeerRead) ||
|
||||
message?.readReceiptInfo?.unreadCount === 0
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
return 'unRead';
|
||||
};
|
||||
|
||||
const readReceiptCont = (message: any) => {
|
||||
// console.log('message=======================')
|
||||
// console.log(JSON.stringify(message))
|
||||
console.log(message.conversationType);
|
||||
switch (message.conversationType) {
|
||||
case TUIServer.TUICore.TIM.TYPES.CONV_C2C:
|
||||
if (message?.readReceiptInfo?.isPeerRead || (message?.readReceiptInfo?.isPeerRead === undefined && message?.isPeerRead)) {
|
||||
return t('TUIChat.已读');
|
||||
}
|
||||
return t('TUIChat.未读');
|
||||
case TUIServer.TUICore.TIM.TYPES.CONV_GROUP:
|
||||
if (message.readReceiptInfo.unreadCount === 0) {
|
||||
return t('TUIChat.全部已读');
|
||||
}
|
||||
if (
|
||||
message.readReceiptInfo.readCount === 0 ||
|
||||
(message.readReceiptInfo.unreadCount === undefined && message.readReceiptInfo.readCount === undefined)
|
||||
) {
|
||||
return t('TUIChat.未读');
|
||||
}
|
||||
return `${message.readReceiptInfo.readCount + t('TUIChat.人已读')}`;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const showReadReceiptDialog = (message: any) => {
|
||||
ctx.emit('showReadReceiptDialog', message, 'receipt');
|
||||
};
|
||||
|
||||
const showRepliesDialog = (message: any, isRoot: boolean) => {
|
||||
if (isRoot) {
|
||||
ctx.emit('showRepliesDialog', message, 'replies');
|
||||
return;
|
||||
}
|
||||
if ((data.referenceMessage as any)?.messageRootID) {
|
||||
const message = data.messagesList?.find((item: Message) => item.ID === (data.referenceMessage as any)?.messageRootID);
|
||||
if (message) {
|
||||
ctx.emit('showRepliesDialog', message, 'replies');
|
||||
return;
|
||||
} else {
|
||||
const message = t('TUIChat.无法定位到原消息');
|
||||
handleErrorPrompts(message, props);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleImageOrVideoBubbleStyle = (message: Message) => {
|
||||
const classNameList = ['content'];
|
||||
if (!message) return classNameList;
|
||||
classNameList.push(`content-${data.message.flow}`);
|
||||
if (data.message.type === TIM.TYPES.MSG_IMAGE && !isEmojiReactionInMessage(message)) {
|
||||
classNameList.push('content-image');
|
||||
}
|
||||
if (data.message.type === TIM.TYPES.MSG_VIDEO && !isEmojiReactionInMessage(message)) {
|
||||
classNameList.push('content-video');
|
||||
}
|
||||
return classNameList;
|
||||
};
|
||||
|
||||
const isEmojiReactionInMessage = (message: Message) => {
|
||||
try {
|
||||
if (!message?.cloudCustomData) return;
|
||||
const reactList = JSONToObject(message?.cloudCustomData)?.messageReact?.reacts;
|
||||
if (!reactList || Object.keys(reactList).length === 0) return false;
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const getSrc = (message: any) => {
|
||||
let s = message?.avatar.split('/');
|
||||
if (message?.avatar && s[s.length - 1]) {
|
||||
return message?.avatar;
|
||||
// return require('@/assets/image/avatar_02.png')
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
getSrc,
|
||||
...toRefs(data),
|
||||
toggleDialog,
|
||||
htmlRefHook,
|
||||
jumpToAim,
|
||||
dropdown,
|
||||
dropdownRef,
|
||||
resendMessage,
|
||||
showReadReceiptTag,
|
||||
readReceiptStyle,
|
||||
readReceiptCont,
|
||||
showReadReceiptDialog,
|
||||
showRepliesDialog,
|
||||
handleImageOrVideoBubbleStyle,
|
||||
isEmojiReactionInMessage,
|
||||
TIM,
|
||||
};
|
||||
},
|
||||
});
|
||||
export default messageBubble;
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
|
||||
.reverse {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.message-bubble {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.line-left {
|
||||
border: 1px solid rgba(0, 110, 255, 0.5);
|
||||
}
|
||||
|
||||
.message-reference-area {
|
||||
display: flex;
|
||||
background: #f2f2f2;
|
||||
border-radius: 0.5rem;
|
||||
border-radius: 0.63rem;
|
||||
align-self: start;
|
||||
margin-left: 44px;
|
||||
margin-right: 8px;
|
||||
|
||||
&-show {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: inherit;
|
||||
justify-content: center;
|
||||
padding: 6px;
|
||||
|
||||
p {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
font-size: 0.88rem;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
word-break: keep-all;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
span {
|
||||
height: 1.25rem;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
font-size: 0.88rem;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-replies {
|
||||
display: flex;
|
||||
align-self: start;
|
||||
margin-left: 44px;
|
||||
margin-right: 8px;
|
||||
padding: 2px;
|
||||
color: #999999;
|
||||
font-size: 10px;
|
||||
|
||||
i {
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
span {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.message-reference-area-reverse,
|
||||
.message-replies-reverse {
|
||||
align-self: end;
|
||||
margin-right: 44px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.message-img {
|
||||
max-width: min(calc(100vw - 180px), 300px);
|
||||
max-height: min(calc(100vw - 180px), 300px);
|
||||
}
|
||||
|
||||
.message-video-cover {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
content: '';
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
border: 15px solid transparent;
|
||||
border-left: 20px solid #ffffff;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.message-videoimg {
|
||||
max-width: min(calc(100vw - 160px), 300px);
|
||||
max-height: min(calc(100vw - 160px), 300px);
|
||||
}
|
||||
|
||||
.face-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.text-img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.message-audio {
|
||||
padding-left: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.icon {
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
audio {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.reserve {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.message-area {
|
||||
max-width: calc(100% - 54px);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 8px;
|
||||
|
||||
.name {
|
||||
padding-bottom: 4px;
|
||||
font-weight: 400;
|
||||
font-size: 0.8rem;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.reference-content {
|
||||
padding: 12px;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: burlywood;
|
||||
letter-spacing: 0;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
animation: reference 800ms;
|
||||
}
|
||||
|
||||
@-webkit-keyframes reference {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
background-color: #ff9c19;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes reference {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
background-color: #ff9c19;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 12px;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #000000;
|
||||
letter-spacing: 0;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
width: fit-content;
|
||||
|
||||
&-in {
|
||||
background: #f5f5f5;
|
||||
border-radius: 0px 10px 10px 10px;
|
||||
}
|
||||
|
||||
&-out {
|
||||
background: #dceafd;
|
||||
border-radius: 10px 0px 10px 10px;
|
||||
}
|
||||
|
||||
&-image {
|
||||
padding: 0px;
|
||||
height: fit-content;
|
||||
border-radius: 10px 0px 10px 10px;
|
||||
}
|
||||
|
||||
&-video {
|
||||
padding: 0px;
|
||||
height: fit-content;
|
||||
background: transparent;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-label {
|
||||
align-self: flex-end;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #b6b8ba;
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.fail {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 15px;
|
||||
background: red;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.unRead {
|
||||
color: #679ce1;
|
||||
}
|
||||
|
||||
.dropdown-inner {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: fit-content;
|
||||
|
||||
&-right {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,453 @@
|
||||
<template>
|
||||
<div class="custom">
|
||||
<template v-if="isCustom === constant.typeService">
|
||||
<div>
|
||||
<h1>
|
||||
<label>{{ extension.title }}</label>
|
||||
<a v-if="extension.hyperlinks_text" :href="extension.hyperlinks_text.value" target="view_window">{{
|
||||
extension.hyperlinks_text.key
|
||||
}}</a>
|
||||
</h1>
|
||||
<ul v-if="extension.item && extension.item.length > 0">
|
||||
<li v-for="(item, index) in extension.item" :key="index">
|
||||
<a v-if="isUrl(item.value)" :href="item.value" target="view_window">{{ item.key }}</a>
|
||||
<p v-else>{{ item.key }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
<article>{{ extension.description }}</article>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isCustom.businessID === constant.typeEvaluate">
|
||||
<div class="evaluate">
|
||||
<h1>{{ $t('message.custom.对本次服务评价') }}</h1>
|
||||
<ul>
|
||||
<li class="evaluate-list-item" v-for="(item, index) in ~~isCustom.score" :key="index">
|
||||
<i class="icon icon-star-light"></i>
|
||||
</li>
|
||||
</ul>
|
||||
<article>{{ isCustom.comment }}</article>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isCustom.businessID === constant.typeOrder">
|
||||
<div class="order" @click="openLink(isCustom.link)">
|
||||
<img :src="isCustom.imageUrl" alt="" />
|
||||
<main>
|
||||
<h1>{{ isCustom.title }}</h1>
|
||||
<p>{{ isCustom.description }}</p>
|
||||
<span>{{ isCustom.price }}</span>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isCustom.businessID === constant.typeTextLink">
|
||||
<div class="textLink">
|
||||
<p>{{ isCustom.text }}</p>
|
||||
<a :href="isCustom.link" target="view_window">{{ $t('message.custom.查看详情>>') }}</a>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isCustom.businessID === constant.TYPE_CALL_MESSAGE">
|
||||
<div class="call" @click="handleCallAgain" :class="`call-${data?.message?.conversationType}`">
|
||||
<i class="icon" :class="handleCallMessageIcon()"></i>
|
||||
<span>{{
|
||||
data.custom.substring(0, data.custom.indexOf('"')) + data.custom.substring(data.custom.lastIndexOf('"') + 1, data.custom.length)
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isCustom.businessID === constant.typeArchives">
|
||||
<div style="display: flex">
|
||||
<div class="img-list" style="cursor: pointer" @click="showDialog">
|
||||
<div style="height: 25px; line-height: 25px">
|
||||
{{ isCustom?.name + ' ' + isCustom?.gender + ' 丨 ' + isCustom?.age }}
|
||||
</div>
|
||||
<div style="color: #7d7d7dff; font-size: 12px; margin-bottom: 5px">
|
||||
{{ `病症描述:${isCustom?.symptomDescription}` }}
|
||||
</div>
|
||||
<div style="display: flex; flex-wrap: wrap">
|
||||
<div style="padding: 0 5px 5px" v-for="(item, index) in isCustom?.imageList" :key="'imageList' + index">
|
||||
<img :src="item.bigImageUrl" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isCustom.businessID === constant.typeMedicalExaminationReport">
|
||||
<div class="business-type" style="cursor: pointer">
|
||||
<div>
|
||||
<div style="padding-left: 10px; height: 25px; line-height: 25px">
|
||||
{{ isCustom?.name + '-' + (isCustom?.gender || isCustom?.sex) + '-' + isCustom?.age }}
|
||||
</div>
|
||||
<div style="padding-left: 10px; height: 25px; color: #7d7d7dff; font-size: 12px">
|
||||
{{ isCustom?.hospital + '-' + isCustom?.createTime }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isCustom.businessID === constant.typeSystem">
|
||||
<div class="business-type" style="cursor: pointer">
|
||||
<div>
|
||||
<div style="padding-left: 10px; height: 25px; line-height: 25px">
|
||||
{{ isCustom?.title }}
|
||||
</div>
|
||||
<img v-if="isCustom?.messageImageUrl" :src="isCustom?.messageImageUrl" alt="" style="margin: 5px 10px" />
|
||||
<div style="padding-left: 10px; height: 25px; color: #7d7d7dff; font-size: 12px">
|
||||
{{ isCustom?.content }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="isCustom.businessID === constant.typeBusinessCard">
|
||||
<div style="cursor: pointer; min-width: 180px">
|
||||
<div class="business-type">
|
||||
<div>
|
||||
<!-- <img v-if="isCustom?.doctorHeadImg" :src="isCustom?.doctorHeadImg" alt="" />-->
|
||||
<el-image style="width: 60px; height: 60px; border-radius: 10px" :src="isCustom?.doctorHeadImg">
|
||||
<template #error>
|
||||
<div>
|
||||
<img
|
||||
style="width: 60px; height: 60px; border-radius: 10px"
|
||||
src="../../../../../assets/image/doctor-img.webp"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</div>
|
||||
<div>
|
||||
<div style="padding-left: 10px; height: 30px; line-height: 35px">
|
||||
{{ `${isCustom?.doctorName}` }}
|
||||
(
|
||||
<span style="color: #7d7d7dff; font-size: 14px">{{ `${isCustom?.doctorTitle}` }}</span>
|
||||
)
|
||||
</div>
|
||||
<div style="padding-left: 10px; height: 30px; color: #7d7d7dff; font-size: 12px">
|
||||
{{
|
||||
`${isCustom?.organization ? isCustom?.organization : ''}-${isCustom?.departmentName ? isCustom?.departmentName : ''}`
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="color: #7d7d7dff; font-size: 12px; margin-top: 5px; border-top: 1px solid #7d7d7dff; padding-top: 1px"> 个人名片 </div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span v-html="data.custom"></span>
|
||||
</template>
|
||||
<el-dialog v-model="visible" :title="`${isCustom?.name}档案`" width="60%" @open="openDialog">
|
||||
<span style="font-size: 18px; font-weight: bold; color: #000000; margin-bottom: 10px">咨询档案</span>
|
||||
<el-form v-model="archives" label-width="100px">
|
||||
<el-form-item label="档案名称:">
|
||||
<el-input disabled v-model="archives.recordsName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="患病时长:">
|
||||
<el-input disabled v-model="archives.haveTime_dictText" />
|
||||
</el-form-item>
|
||||
<el-form-item label="问题描述:">
|
||||
<el-input disabled v-model="archives.medicalDescribe" :rows="3" type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item label="就诊医院:">
|
||||
<el-input disabled v-model="archives.lookOffice" />
|
||||
</el-form-item>
|
||||
<el-form-item label="病情资料:">
|
||||
<div
|
||||
style="padding: 0 5px 5px; width: 100px; height: 100px"
|
||||
v-for="(item, index) in archives?.imageList"
|
||||
:key="'imageList' + index"
|
||||
>
|
||||
<el-image
|
||||
style="width: 100px; height: 100px"
|
||||
:src="`${hrefParams.urlF.replace('lol', '://')}/file/show/${item}`"
|
||||
:zoom-rate="1.2"
|
||||
:preview-src-list="[`${hrefParams.urlF.replace('lol', '://')}file/show/${item}`]"
|
||||
:initial-index="0"
|
||||
:hide-on-click-modal="true"
|
||||
fit="cover"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="期望帮助:">
|
||||
<el-input disabled v-model="archives.desire" :rows="3" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span style="font-size: 18px; font-weight: bold; color: #000000; margin: 10px 0">健康信息</span>
|
||||
<el-form label-width="100px" :inline="true">
|
||||
<template v-for="(item, index) in Object.keys(archives.map)" :key="'item' + index">
|
||||
<el-form-item :label="`${item}:`">
|
||||
<el-input v-model="archives.map[item]" disabled />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watchEffect, reactive, toRefs } from 'vue';
|
||||
import { isUrl, JSONToObject } from '../utils/utils';
|
||||
import constant from '../../constant';
|
||||
import TUIAegis from '../../../../utils/TUIAegis';
|
||||
import { useStore } from 'vuex';
|
||||
import { post } from '@/api/fourApi';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import hrefParams from '@/utils/herfParams';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
setup(props: any, ctx: any) {
|
||||
const VuexStore = ((window as any)?.TUIKitTUICore?.isOfficial && useStore && useStore()) || {};
|
||||
// console.log('props.data===========================')
|
||||
// console.log(props.data)
|
||||
const data = reactive({
|
||||
data: {} as any,
|
||||
extension: {},
|
||||
isCustom: '',
|
||||
constant: constant,
|
||||
visible: false,
|
||||
archives: {
|
||||
recordsName: '',
|
||||
medicalDescribe: '',
|
||||
image: '',
|
||||
imageList: [],
|
||||
haveTime_dictText: '',
|
||||
desire: '',
|
||||
lookOffice: '',
|
||||
map: {},
|
||||
},
|
||||
});
|
||||
watchEffect(() => {
|
||||
data.data = props.data;
|
||||
const {
|
||||
message: { payload },
|
||||
} = props.data;
|
||||
data.isCustom = payload.data || ' ';
|
||||
data.isCustom = JSONToObject(payload.data);
|
||||
if (payload.data === constant.typeService) {
|
||||
data.extension = JSONToObject(payload.extension);
|
||||
}
|
||||
// console.log(data)
|
||||
});
|
||||
const openLink = (url: any) => {
|
||||
window.open(url);
|
||||
};
|
||||
const handleCallMessageIcon = () => {
|
||||
const callType = JSON.parse(JSON.parse(data?.data?.message?.payload?.data)?.data)?.call_type;
|
||||
let className = '';
|
||||
switch (callType) {
|
||||
case 1:
|
||||
className = 'icon-call-voice';
|
||||
break;
|
||||
case 2:
|
||||
className = 'icon-call-video';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return className;
|
||||
};
|
||||
|
||||
const handleCallAgain = async () => {
|
||||
const callType = JSON.parse(JSON.parse(props?.data?.message?.payload?.data)?.data)?.call_type;
|
||||
TUIAegis.getInstance().reportEvent({
|
||||
name: 'callOptions',
|
||||
ext1: 'clickCall',
|
||||
});
|
||||
switch (data?.data?.message?.conversationType) {
|
||||
case (window as any).TUIKitTUICore.TIM.TYPES.CONV_C2C:
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const { flow, to, from } = data?.data?.message;
|
||||
if (to === from) break;
|
||||
try {
|
||||
await (window as any)?.TUIKitTUICore?.TUIServer?.TUICallKit?.call({
|
||||
userID: flow === 'out' ? to : from,
|
||||
type: callType,
|
||||
});
|
||||
(window as any)?.TUIKitTUICore?.isOfficial && VuexStore?.commit && VuexStore?.commit('handleTask', 6);
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
if ((window as any)?.TUIKitTUICore?.TUIServer?.TUICallKit) {
|
||||
TUIAegis.getInstance().reportEvent({
|
||||
name: 'callOptions',
|
||||
ext1: 'clickCall-success',
|
||||
});
|
||||
TUIAegis.getInstance().reportEvent({
|
||||
name: 'callOptions',
|
||||
ext1: 'call-c2c',
|
||||
});
|
||||
}
|
||||
break;
|
||||
case (window as any).TUIKitTUICore.TIM.TYPES.CONV_GROUP:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const showDialog = () => {
|
||||
window.parent.postMessage(
|
||||
JSON.stringify({
|
||||
code: 'showConsultation',
|
||||
archivesId: (data.isCustom as any)?.archivesId,
|
||||
archivesName: (data.isCustom as any)?.name,
|
||||
}),
|
||||
'*'
|
||||
);
|
||||
// data.archives = {
|
||||
// recordsName: '',
|
||||
// medicalDescribe: '',
|
||||
// image: '',
|
||||
// imageList: [],
|
||||
// haveTime_dictText: '',
|
||||
// desire: '',
|
||||
// lookOffice: '',
|
||||
// map: {}
|
||||
// }
|
||||
// data.visible = true;
|
||||
};
|
||||
|
||||
const openDialog = async () => {
|
||||
window.parent.postMessage(
|
||||
JSON.stringify({
|
||||
code: 'showConsultation',
|
||||
archivesId: (data.isCustom as any)?.archivesId,
|
||||
archivesName: (data.isCustom as any)?.name,
|
||||
}),
|
||||
'*'
|
||||
);
|
||||
// await post(`/health-consultation/consultation/conSession/getMedicalRecord?id=${(data.isCustom as any)?.archivesId}`, {id: (data.isCustom as any)?.archivesId})
|
||||
// .then((res: any) => {
|
||||
// if (res.code === 200) {
|
||||
// console.log(res)
|
||||
// res.result.lookOffice = res.result.lookOffice || '无';
|
||||
// res.result['imageList'] = res.result.image.split(',');
|
||||
// data.archives = {...data.archives, ...res.result};
|
||||
// } else {
|
||||
// ElMessage({
|
||||
// type: 'error',
|
||||
// message: res.message
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// .catch((e) => {
|
||||
// console.log(e)
|
||||
// })
|
||||
};
|
||||
|
||||
return {
|
||||
showDialog,
|
||||
openDialog,
|
||||
...toRefs(data),
|
||||
isUrl,
|
||||
openLink,
|
||||
handleCallMessageIcon,
|
||||
handleCallAgain,
|
||||
hrefParams,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 0 30px 20px;
|
||||
}
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
|
||||
.business-type {
|
||||
display: flex;
|
||||
|
||||
img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.img-list {
|
||||
img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
border-radius: 10px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #679ce1;
|
||||
}
|
||||
|
||||
.custom {
|
||||
font-size: 14px;
|
||||
|
||||
h1 {
|
||||
font-size: 14px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
h1,
|
||||
a,
|
||||
p {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.evaluate {
|
||||
ul {
|
||||
display: flex;
|
||||
padding-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.order {
|
||||
display: flex;
|
||||
|
||||
main {
|
||||
padding-left: 5px;
|
||||
|
||||
p {
|
||||
font-family: PingFangSC-Regular;
|
||||
width: 145px;
|
||||
line-height: 17px;
|
||||
font-size: 14px;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
margin-bottom: 6px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
span {
|
||||
font-family: PingFangSC-Regular;
|
||||
line-height: 25px;
|
||||
color: #ff7201;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 67px;
|
||||
height: 67px;
|
||||
}
|
||||
}
|
||||
|
||||
.call {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
&-C2C {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-GROUP {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<div class="dialog-emoji" :class="env?.isH5?'dialog-emoji-h5':''" v-if="type === 'dropdown'">
|
||||
<div class="face-list collapse">
|
||||
<ul class="face-list-collapse">
|
||||
<li
|
||||
class="face-list-item"
|
||||
v-for="(childrenItem, childrenIndex) in emojiCollapseList"
|
||||
:key="childrenIndex"
|
||||
@click.stop="select(childrenItem)"
|
||||
>
|
||||
<img :src="emojiUrl + emojiMap[childrenItem]" />
|
||||
</li>
|
||||
</ul>
|
||||
<div class="face-list-button" @click.stop="isCollapse = !isCollapse">
|
||||
<i class="icon" :class="[isCollapse ? 'icon-expand' : 'icon-collapse']"></i>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="face-list face-list-expand" v-show="!isCollapse">
|
||||
<li
|
||||
class="face-list-item"
|
||||
v-for="(childrenItem, childrenIndex) in emojiExpandList"
|
||||
:key="childrenIndex"
|
||||
@click.stop="select(childrenItem)"
|
||||
>
|
||||
<img :src="emojiUrl + emojiMap[childrenItem]" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div v-if="type === 'content'" class="emoji-content">
|
||||
<ul class="emoji-react" ref="container">
|
||||
<li
|
||||
class="emoji-react-item"
|
||||
v-for="(val, key) in handleEmojiReact(message)"
|
||||
:key="key"
|
||||
v-show="val && val?.length"
|
||||
@click.stop="select(key)"
|
||||
>
|
||||
<img :src="emojiUrl + emojiMap[key]" />
|
||||
<div class="emoji-react-item-content">
|
||||
<span>{{ handleEmojiReactItem(val) }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, watch, reactive, toRefs, computed, ref, onMounted, nextTick } from 'vue';
|
||||
import TIM from '../../../../TUICore/tim';
|
||||
import { emojiUrl, emojiMap, emojiName } from '../utils/emojiMap';
|
||||
import { JSONToObject } from '../utils/utils';
|
||||
import TUIChat from '../index.vue';
|
||||
import { Message } from 'tim-js-sdk';
|
||||
export default defineComponent({
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
emojiList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
emits: ['handleCollapse'],
|
||||
setup(props: any, ctx: any) {
|
||||
const { TUIServer } = TUIChat;
|
||||
const data = reactive({
|
||||
message: {} as Message,
|
||||
emojiUrl,
|
||||
emojiMap,
|
||||
emojiName,
|
||||
isCollapse: true,
|
||||
types: TIM.TYPES,
|
||||
env: TUIServer.TUICore.TUIEnv,
|
||||
type: props.type,
|
||||
emojiReacts: {},
|
||||
allMemberList: [],
|
||||
});
|
||||
|
||||
const container = ref({} as HTMLElement);
|
||||
|
||||
const emojiCollapseList = computed(() => {
|
||||
return data.emojiName.slice(0, 6);
|
||||
});
|
||||
|
||||
const emojiExpandList = computed(() => {
|
||||
return data.emojiName.slice(6);
|
||||
});
|
||||
|
||||
const select = (item: any) => {
|
||||
TUIServer.emojiReact(data.message, item);
|
||||
};
|
||||
|
||||
const handleEmojiReact = (message: any) => {
|
||||
try {
|
||||
if (!message?.cloudCustomData) return;
|
||||
const reactList = JSONToObject(message?.cloudCustomData)?.messageReact?.reacts;
|
||||
if (!reactList) return;
|
||||
data.emojiReacts = reactList;
|
||||
return reactList;
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
};
|
||||
|
||||
const handleEmojiReactItem = (userIDList: any) => {
|
||||
let res = '';
|
||||
userIDList?.forEach((item: any, index: any) => {
|
||||
const memberInfo = data.allMemberList?.find((member: any) => member.userID === item);
|
||||
res = res + (memberInfo ? (memberInfo as any)?.nick : item) + ', ';
|
||||
});
|
||||
if (res.length) res = res.substring(0, res.lastIndexOf(','));
|
||||
return res;
|
||||
};
|
||||
|
||||
const handleAllMemberList = (message: any) => {
|
||||
const TUIChatStore = TUIServer?.currentStore;
|
||||
switch (message?.conversationType) {
|
||||
case TIM.TYPES.CONV_C2C:
|
||||
data.allMemberList = [
|
||||
{
|
||||
userID: TUIChatStore?.conversation?.userProfile?.userID,
|
||||
nick: TUIChatStore?.conversation?.userProfile?.nick,
|
||||
},
|
||||
{
|
||||
userID: TUIChatStore?.selfInfo?.userID,
|
||||
nick: TUIChatStore?.selfInfo?.nick,
|
||||
},
|
||||
] as any;
|
||||
break;
|
||||
case TIM.TYPES.CONV_GROUP:
|
||||
data.allMemberList = TUIChatStore?.allMemberList?.memberList;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.message,
|
||||
(newVal: any, oldVal: any) => {
|
||||
data.message = props.message;
|
||||
if (newVal?.conversationID !== oldVal?.conversationID) {
|
||||
handleAllMemberList(newVal);
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
()=>data.isCollapse,
|
||||
(newVal, oldVal) => {
|
||||
if (newVal === oldVal) return;
|
||||
if (!data?.env?.isH5) return;
|
||||
ctx.emit('handleCollapse', newVal);
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
emojiCollapseList,
|
||||
emojiExpandList,
|
||||
select,
|
||||
handleEmojiReact,
|
||||
handleEmojiReactItem,
|
||||
container,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
.dialog-emoji {
|
||||
margin-left: 2px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e0e0e0;
|
||||
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.06);
|
||||
width: 242px;
|
||||
min-height: 28px;
|
||||
height: fit-content;
|
||||
padding: 2px 6px;
|
||||
word-break: keep-all;
|
||||
top: 30px;
|
||||
border-radius: 8px;
|
||||
&-h5{
|
||||
margin: 0 5px;
|
||||
border: none;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
box-shadow: none;
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
.collapse {
|
||||
padding: 2px 0px;
|
||||
}
|
||||
.face-list {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
flex-wrap: nowrap;
|
||||
flex-direction: row;
|
||||
&-collapse {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
&-expand {
|
||||
border-top: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
overflow-x: hidden;
|
||||
flex-wrap: wrap;
|
||||
max-height: 90px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
&-button {
|
||||
padding: 5px 7px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
i {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
li {
|
||||
margin: 4px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
img {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.emoji-content {
|
||||
.emoji-react {
|
||||
margin-top: 3px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
&-item {
|
||||
width: fit-content;
|
||||
height: 20px;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
border-radius: 12px;
|
||||
padding: 2px 6px;
|
||||
margin: 2px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 200px;
|
||||
display: flex;
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 2px;
|
||||
}
|
||||
&-content {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 10px;
|
||||
color: #999999;
|
||||
align-self: center;
|
||||
span {
|
||||
margin: 2px;
|
||||
font-size: 10px;
|
||||
color: #999999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div class="message-image" ref="skeleton">
|
||||
<img class="message-img" :src="data.url" :style="
|
||||
isH5
|
||||
? {
|
||||
maxWidth: data.width ? data.width + 'px' : 'calc(100vw - 180px)',
|
||||
maxHeight: data.height ? data.height + 'px' : 'calc(100vw - 180px)',
|
||||
}
|
||||
: {}
|
||||
"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watchEffect, reactive, toRefs, nextTick, ref } from 'vue';
|
||||
import { handleSkeletonSize } from '../utils/utils';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
isH5: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup(props: any, ctx: any) {
|
||||
const data = reactive({
|
||||
data: {},
|
||||
});
|
||||
|
||||
const skeleton: any = ref();
|
||||
|
||||
watchEffect(() => {
|
||||
data.data = props.data;
|
||||
if (!data.data) return;
|
||||
nextTick(() => {
|
||||
const containerWidth = document.getElementById('messageEle')?.clientWidth || 0;
|
||||
const max = props.isH5 ? Math.min(containerWidth - 172, 300) : 300;
|
||||
const size = handleSkeletonSize(240, 240, max, max);
|
||||
skeleton?.value?.style && (skeleton.value.style.width = `${size.width}px`);
|
||||
skeleton?.value?.style && (skeleton.value.style.height = `${size.height}px`);
|
||||
});
|
||||
});
|
||||
return {
|
||||
...toRefs(data),
|
||||
skeleton,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
.text-img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.message-img {
|
||||
max-width: min(calc(100vw - 180px), 300px);
|
||||
max-height: min(calc(100vw - 180px), 300px);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div class="message-file">
|
||||
<div class="box" @click="download" :title="$t('TUIChat.单击下载')">
|
||||
<i class="icon icon-files"></i>
|
||||
<div class="message-file-content">
|
||||
<label>{{ data.name }}</label>
|
||||
<span>{{ data.size }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<progress v-if="data.progress" :value="data.progress" max="1"></progress>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watchEffect, reactive, toRefs } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
setup(props: any, ctx: any) {
|
||||
const data = reactive({
|
||||
data: {},
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.data = props.data;
|
||||
});
|
||||
|
||||
const download = () => {
|
||||
const file: any = data.data;
|
||||
const option: any = {
|
||||
mode: 'cors',
|
||||
headers: new Headers({
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}),
|
||||
};
|
||||
// 浏览器支持fetch则用blob下载,避免浏览器点击a标签,跳转到新页面预览的行为
|
||||
// If the browser supports fetch, use blob to download, so as to avoid the browser clicking the a tag and jumping to the preview of the new page
|
||||
if ((window as any).fetch) {
|
||||
fetch(file.url, option)
|
||||
.then((res) => res.blob())
|
||||
.then((blob) => {
|
||||
const a = document.createElement('a');
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
a.href = url;
|
||||
a.download = file.name;
|
||||
a.click();
|
||||
});
|
||||
} else {
|
||||
const a = document.createElement('a');
|
||||
a.href = file.url;
|
||||
a.target = '_blank';
|
||||
a.download = file.name;
|
||||
a.click();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
download,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
.message-file {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
.message-file-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
progress {
|
||||
width: 100%;
|
||||
color: #006eff;
|
||||
appearance: none;
|
||||
border-radius: 0.25rem;
|
||||
background: rgba(#ffffff, 1);
|
||||
width: 100%;
|
||||
height: 0.5rem;
|
||||
&::-webkit-progress-value {
|
||||
background-color: #006eff;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
&::-webkit-progress-bar {
|
||||
border-radius: 0.25rem;
|
||||
background: rgba(#ffffff, 1);
|
||||
}
|
||||
&::-moz-progress-bar {
|
||||
color: #006eff;
|
||||
background: #006eff;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<div class="message-image" @click.self="toggleShow" ref="skeleton">
|
||||
<img
|
||||
class="message-img"
|
||||
:src="data.url.indexOf('http') === -1 ? `${hrefParams.urlF.replace('lol', '://')}/file/show/${data.url}` : data.url"
|
||||
:width="data.width"
|
||||
:height="data.height"
|
||||
:style="
|
||||
isH5
|
||||
? {
|
||||
maxWidth: data.width ? data.width + 'px' : 'calc(100vw - 180px)',
|
||||
maxHeight: data.height ? data.height + 'px' : 'calc(100vw - 180px)',
|
||||
}
|
||||
: {}
|
||||
"
|
||||
alt=""
|
||||
/>
|
||||
<div class="progress" v-if="data.progress">
|
||||
<progress :value="data.progress" max="1"></progress>
|
||||
</div>
|
||||
<div class="dialog" v-if="show" @click.self="toggleShow">
|
||||
<header v-if="!isH5">
|
||||
<i class="icon icon-close" @click.stop="toggleShow"></i>
|
||||
</header>
|
||||
<div class="dialog-box" :class="[isH5 ? 'dialog-box-h5' : '']" @click.self="toggleShow">
|
||||
<img :class="[isWidth ? 'isWidth' : 'isHeight']" :src="data.message.payload.imageInfoArray[0].url" @click.self="toggleShow" />
|
||||
<div v-if="isH5" class="dialog-box-h5-footer">
|
||||
<p @click="toggleShow">
|
||||
<img src="../../../assets/icon/close-image.png" />
|
||||
</p>
|
||||
<p @click.stop="downloadImage(data.message)">
|
||||
<img src="../../../assets/icon/downaload-image.png" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watchEffect, reactive, toRefs, computed, ref, nextTick } from 'vue';
|
||||
import { handleSkeletonSize } from '../utils/utils';
|
||||
import hrefParams from '@/utils/herfParams';
|
||||
|
||||
export default defineComponent({
|
||||
methods: {},
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
isH5: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['uploading', 'previewImage'],
|
||||
setup(props: any, ctx: any) {
|
||||
const data = reactive({
|
||||
data: {
|
||||
progress: 0,
|
||||
},
|
||||
show: false,
|
||||
});
|
||||
|
||||
const skeleton: any = ref();
|
||||
|
||||
const isWidth = computed(() => {
|
||||
const { width = 0, height = 0 } = (data.data as any)?.message?.payload?.imageInfoArray[0];
|
||||
return width >= height;
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.data = props.data;
|
||||
if (!data.data) return;
|
||||
nextTick(() => {
|
||||
if (!data.data.progress) {
|
||||
const { width = 0, height = 0 } = data.data as any;
|
||||
if (width === 0 || height === 0) return;
|
||||
const containerWidth = document.getElementById('app')?.clientWidth || 0;
|
||||
const max = props.isH5 ? Math.min(containerWidth - 180, 300) : 300;
|
||||
const size = handleSkeletonSize(width, height, max, max);
|
||||
skeleton?.value?.style && (skeleton.value.style.width = `${size.width}px`);
|
||||
skeleton?.value?.style && (skeleton.value.style.height = `${size.height}px`);
|
||||
} else {
|
||||
ctx.emit('uploading');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const toggleShow = () => {
|
||||
if (!data.data.progress) {
|
||||
ctx.emit('previewImage', (data.data as any).message);
|
||||
}
|
||||
};
|
||||
const downloadImage = (message: any) => {
|
||||
const targetImage = document.createElement('a');
|
||||
const downloadImageName = message.payload.imageInfoArray[0].instanceID;
|
||||
targetImage.setAttribute('download', downloadImageName);
|
||||
const image = new Image();
|
||||
image.src = message.payload.imageInfoArray[0].url;
|
||||
image.setAttribute('crossOrigin', 'Anonymous');
|
||||
image.onload = () => {
|
||||
targetImage.href = getImageDataURL(image);
|
||||
targetImage.click();
|
||||
};
|
||||
};
|
||||
|
||||
const getImageDataURL = (image: any) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = image.width;
|
||||
canvas.height = image.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx?.drawImage(image, 0, 0, image.width, image.height);
|
||||
const extension = image.src.substring(image.src.lastIndexOf('.') + 1).toLowerCase();
|
||||
return canvas.toDataURL(`image/${extension}`, 1);
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
toggleShow,
|
||||
skeleton,
|
||||
isWidth,
|
||||
downloadImage,
|
||||
hrefParams,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
|
||||
.message-image {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
opacity: 1;
|
||||
padding: 10px;
|
||||
background: #f5f5f5;
|
||||
|
||||
.message-img {
|
||||
max-width: min(calc(100vw - 180px), 300px);
|
||||
max-height: min(calc(100vw - 180px), 300px);
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
.progress {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 20px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: rgba(#000000, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
progress {
|
||||
color: #006eff;
|
||||
appearance: none;
|
||||
border-radius: 0.25rem;
|
||||
background: rgba(#ffffff, 1);
|
||||
width: 100%;
|
||||
height: 0.5rem;
|
||||
|
||||
&::-webkit-progress-value {
|
||||
background-color: #006eff;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
&::-webkit-progress-bar {
|
||||
border-radius: 0.25rem;
|
||||
background: rgba(#ffffff, 1);
|
||||
}
|
||||
|
||||
&::-moz-progress-bar {
|
||||
color: #006eff;
|
||||
background: #006eff;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog {
|
||||
position: fixed;
|
||||
z-index: 12;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(#000000, 0.3);
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
background: rgba(0, 0, 0, 0.49);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
&-box {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
max-height: 100%;
|
||||
padding: 6rem;
|
||||
box-sizing: border-box;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-box-h5 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #000000;
|
||||
padding: 30px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&-footer {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
display: flex;
|
||||
width: 90vw;
|
||||
justify-content: space-between;
|
||||
|
||||
p {
|
||||
width: 3.88rem;
|
||||
height: 3.88rem;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
i {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.isWidth {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.isHeight {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<a class="message-location" :href="data.href" target="_blank" title="点击查看详情">
|
||||
<span class="el-icon-location-outline">{{data.description}}</span>
|
||||
<img :src="data.url" />
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watchEffect, reactive, toRefs } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
setup(props:any, ctx:any) {
|
||||
const data = reactive({
|
||||
data: {},
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.data = props.data;
|
||||
});
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
.message-location {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="message-merger">
|
||||
<div class="merger-box" :data-value="data.message">
|
||||
<p class="merger-title">{{data.title}}</p>
|
||||
<p class="merger-text" v-for="(item, index) in data.abstractList" :key="index">
|
||||
{{item}}
|
||||
</p>
|
||||
</div>
|
||||
<span class="merger-label"> 聊天记录</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watchEffect, reactive, toRefs } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
setup(props:any, ctx:any) {
|
||||
const data = reactive({
|
||||
data: {},
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.data = props.data;
|
||||
});
|
||||
return {
|
||||
...toRefs(data),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
.message-merger {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.merger-label {
|
||||
border-top: 1px solid #dddddd;
|
||||
margin-top: 10px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="referenceMessage?.messageID && allMessageID.indexOf(referenceMessage.messageID) !== -1"
|
||||
:class="`${type} ${message.flow === 'in' && type + '-reverse'}`"
|
||||
>
|
||||
<p class="message-reference-user">
|
||||
<span class="nick">{{ referenceForShow.nick || referenceForShow.from }}</span>
|
||||
<span class="colon">{{ type === 'reference' ? ':' : '' }}</span>
|
||||
</p>
|
||||
<div class="face-box" v-if="referenceMessage.messageType === constant.typeText">
|
||||
<div v-for="(item, index) in face" :key="index">
|
||||
<span class="text-box" v-if="item.name === 'text'">{{ item.text }}</span>
|
||||
<img class="text-img" v-else-if="item.name === 'img'" :src="item.src" />
|
||||
</div>
|
||||
</div>
|
||||
<span v-if="referenceMessage.messageType === constant.typeCustom">{{ referenceMessage.messageAbstract }}</span>
|
||||
<img
|
||||
v-if="referenceMessage.messageType === constant.typeImage"
|
||||
class="message-img"
|
||||
:src="referenceForShow.payload.imageInfoArray[1].url"
|
||||
/>
|
||||
<div v-if="referenceMessage.messageType === constant.typeVideo" class="message-video-cover">
|
||||
<img
|
||||
class="message-videoimg"
|
||||
:src="referenceForShow?.payload?.snapshotUrl || referenceForShow?.payload?.thumbUrl"
|
||||
/>
|
||||
</div>
|
||||
<img v-if="referenceMessage.messageType === constant.typeFace" class="message-img" :src="url" />
|
||||
<span
|
||||
v-if="referenceMessage.messageType === constant.typeFile || referenceMessage.messageType === constant.typeAudio"
|
||||
>{{ referenceMessage?.messageAbstract }}</span
|
||||
>
|
||||
</div>
|
||||
<div v-else :class="`${type} ${message.flow === 'in' && type + '-reverse'}`">
|
||||
<p>{{ referenceMessage?.messageSender }}</p>
|
||||
<span>{{ referenceMessage?.messageAbstract }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Message } from '../interface';
|
||||
import { defineComponent, reactive, toRefs, watch, watchEffect } from 'vue';
|
||||
import constant from '../../constant';
|
||||
const MessageReference = defineComponent({
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
default: {} as Message,
|
||||
},
|
||||
referenceMessage: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
referenceForShow: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
face: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
allMessageID: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
deafault: '',
|
||||
},
|
||||
},
|
||||
setup(props: any, ctx: any) {
|
||||
const data = reactive({
|
||||
message: {},
|
||||
referenceMessage: {},
|
||||
referenceForShow: {},
|
||||
allMessageID: '',
|
||||
face: [],
|
||||
url: '',
|
||||
type: '',
|
||||
});
|
||||
watchEffect(() => {
|
||||
data.message = props.message;
|
||||
data.referenceMessage = props.referenceMessage;
|
||||
data.referenceForShow = props.referenceForShow;
|
||||
data.face = props.face;
|
||||
data.url = props.url;
|
||||
data.allMessageID = props.allMessageID;
|
||||
data.type = props.type;
|
||||
});
|
||||
watch(
|
||||
() => props.referenceForShow,
|
||||
() => {
|
||||
data.referenceForShow = props.referenceForShow;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
return {
|
||||
...toRefs(data),
|
||||
constant,
|
||||
};
|
||||
},
|
||||
});
|
||||
export default MessageReference;
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
.reference {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: inherit;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
line-height: 20px;
|
||||
.message-img,
|
||||
.message-video-cover,
|
||||
.message-videoimg {
|
||||
max-width: min(calc(100vw - 230px), 300px);
|
||||
max-height: min(calc(100vw - 230px), 300px);
|
||||
}
|
||||
.face-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
&-name {
|
||||
padding-right: 5px;
|
||||
}
|
||||
.text-img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
p {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
padding-right: 5px;
|
||||
max-width: 100px;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
}
|
||||
span {
|
||||
line-height: 20px;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
letter-spacing: 0;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
display: inline-block;
|
||||
p {
|
||||
font-weight: 800;
|
||||
}
|
||||
}
|
||||
}
|
||||
.reply {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-self: start;
|
||||
border-left: 2px solid rgba(0, 110, 255, 0.499298);
|
||||
&-reverse {
|
||||
border-left: 2px solid rgba(153, 153, 153, 0.3);
|
||||
}
|
||||
padding-left: 7px;
|
||||
margin-bottom: 5px;
|
||||
color: #999999;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
min-width: 40px;
|
||||
.message-img,
|
||||
.message-video-cover,
|
||||
.message-videoimg {
|
||||
max-width: min(calc(100vw - 180px), 300px);
|
||||
max-height: min(calc(100vw - 180px), 300px);
|
||||
object-fit: contain;
|
||||
align-self: flex-start;
|
||||
}
|
||||
.face-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
.text-img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
p {
|
||||
font-weight: 800;
|
||||
max-width: min(calc(100vw - 180px), 300px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.message-reference-user{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.nick{
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.colon{
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div class="revoke">
|
||||
<label v-if="message.flow === 'in'">{{message.nick || message.from}}</label>
|
||||
<label v-else>{{$t('TUIChat.您')}}</label>
|
||||
<span>{{$t("TUIChat.撤回了一条消息")}}</span>
|
||||
<span class="edit" v-if="message.flow === 'out'&&isEdit" @click="edit">{{$t('TUIChat.重新编辑')}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watchEffect, reactive, toRefs } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
},
|
||||
setup(props:any, ctx:any) {
|
||||
const data = reactive({
|
||||
message: {},
|
||||
isEdit: false,
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
data.message = props.data;
|
||||
data.isEdit = props.isEdit;
|
||||
});
|
||||
|
||||
const edit = () => {
|
||||
ctx.emit('edit', data.message);
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
edit,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url('../../../styles/common.scss');
|
||||
@import url('../../../styles/icon.scss');
|
||||
.revoke {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
color: #999999;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
.edit {
|
||||
padding: 0 5px;
|
||||
color: #006EFF;
|
||||
}
|
||||
}
|
||||
</style>
|
||||