Compare commits

..

409 Commits

Author SHA1 Message Date
Lei OT 8d273a2e68 custom service-worker 1 year ago
Lei OT e7c7d7b1be custom service-worker 1 year ago
Lei OT 2650ed63c6 style: 1 year ago
Lei OT bbd729e792 style: 1 year ago
Lei OT 18bbaf01f7 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 42880d0818 input 提示 1 year ago
Lei OT 88a5d3c43c Merge remote-tracking branch 'origin/main' into dev/chat
# Conflicts:
#	src/views/Conversations/Components/Input/MediaUpload.jsx
1 year ago
Lei OT 9dd0ed5102 fix: 模板信息显示 1 year ago
Lei OT 8f2d295eb1 pwa 1 year ago
Lei OT 5321345043 perf: 上传的格式和大小限制 1 year ago
Lei OT cdb840d819 Merge branch 'main' into dev/chat 1 year ago
Lei OT 03339197e6 Merge branch 'main' into dev/chat
# Conflicts:
#	src/lib/msgUtils.js
1 year ago
Lei OT 03d6a7fafe perf: 历史记录: 会话的的时间 1 year ago
Lei OT 0d7117ae6a feat: 新建会话 1 year ago
Lei OT 09e5f3cfba style: 历史记录: 引用的来源title color 1 year ago
Lei OT 445b557e03 perf: 提示文字 1 year ago
Lei OT c643cec93b fix: 模板: 只发送body 1 year ago
Lei OT 6b4c3a0557 perf: 历史记录: 显示绝对时间 1 year ago
Lei OT d242ed3909 perf: 模板: 有header, footer, buttons 1 year ago
Lei OT acd0c198fc PWA 1 year ago
Lei OT dd4d815bdf Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT ceafee6f98 附件格式大小说明 1 year ago
Lei OT 895f7820c4 . 1 year ago
Lei OT 22cf74c100 Merge branch 'main' into dev/chat
# Conflicts:
#	src/views/ChatHistory.jsx
1 year ago
Lei OT ae2b96c3ff fix: 在线聊天: 刷新页面 1 year ago
Lei OT 1efb5ca7ed perf: 历史记录: 匹配消息的提示 1 year ago
Lei OT 4826d3cbb7 perf: 历史记录: 预览 1 year ago
Lei OT f92344687a Merge branch 'main' into dev/chat 1 year ago
Lei OT b01f6b9d81 fix: 订单修改whatsappID之后, 获取新会话 1 year ago
Lei OT b1399739c5 style: 模板 free style 1 year ago
Lei OT 5cd36def65 fix: 历史记录: 转发的消息. 不以引用显示 1 year ago
Lei OT 8a977114d6 Merge branch 'main' into dev/chat 1 year ago
Lei OT 170a982e4a fix: 历史记录: 显示发送人名字 1 year ago
Lei OT a626961c12 Merge branch 'main' into dev/chat 1 year ago
Lei OT 70e29bfabd fix: 历史记录: 显示发送人名字 1 year ago
Lei OT 5e4d07a58b Merge branch 'main' into dev/chat 1 year ago
Lei OT 6da6332613 根据设备来跳转路由 1 year ago
Lei OT 47186ad302 移动端: 返回列表 1 year ago
Lei OT 67cea51bd5 feat: 会话过期提示 1 year ago
Lei OT 8c4ed2f7a9 perf: 模板按钮状态 1 year ago
Lei OT 15dea123b1 Merge branch 'main' into dev/chat 1 year ago
Lei OT 3fc0fb305c fix: 历史记录: 搜索组件 1 year ago
Lei OT f614343462 test: 移动端键盘事件 1 year ago
Lei OT e19907f4c7 fix: ConversationsList navigate replace 1 year ago
Lei OT 9d00a0f436 Merge branch 'main' into dev/chat 1 year ago
Lei OT 316f84a9e5 移动端: 跳转列表页 1 year ago
Lei OT 5fe495a61f 不禁用模板发送 1 year ago
Lei OT 55f4d98d79 消息列表 1 year ago
Lei OT 1ac17f3c0e Merge branch 'main' into dev/chat 1 year ago
Lei OT 0e3a73355e 发送消息 1 year ago
Lei OT dd6a38861e Merge branch 'main' into dev/chat 1 year ago
Lei OT 475245cefe Merge branch 'main' into dev/chat 1 year ago
Lei OT 2b97b7aea7 perf: 移动端 1 year ago
Lei OT e8a638e7b2 fix: 判断是否支持 window.Notification 1 year ago
Lei OT ab6b8241c7 style: Emoji popover 1 year ago
Lei OT 241cbc7032 Merge branch 'main' into dev/chat 1 year ago
Lei OT 918af17798 历史记录: 会话显示Me的名字 1 year ago
Lei OT ddb9f98174 退出登录 1 year ago
Lei OT 6cfc936646 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 7b4fae4820 Emoji picker 使用native 避免下载图片 1 year ago
Lei OT 426c586198 style: 历史记录查询表单 1 year ago
Lei OT b3347e6d6b fix: 更新未读消息数; style: 移动端 1 year ago
Lei OT 84ee40d1b8 移动端 1 year ago
Lei OT 02cc765e9a Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 0de6151270 Merge branch 'main' into dev/chat 1 year ago
Lei OT 2699ae63d6 style: 发送失败的消息 1 year ago
Lei OT 371a29fbeb Merge branch 'main' into dev/chat 1 year ago
Lei OT b9a690d871 style: 发送失败的消息 1 year ago
Lei OT 12af76d634 Merge branch 'main' into dev/chat 1 year ago
Lei OT 43dc473737 websocket 连接重复初始化 1 year ago
Lei OT 45a49a89a2 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 62b7a1f0e6 websocket 连接重复初始化 1 year ago
Lei OT 396f266a78 fix: 消息数重复累计 1 year ago
Lei OT e1ae93822b style: 点击引用 1 year ago
Lei OT 2530107a36 perf: 历史记录的每页加载, 5000 1 year ago
Lei OT c5d2332a0e fix: 收到新会话消息. 当前客户端增加新会话. 包括发出的 1 year ago
Lei OT 3a120f7932 Merge branch 'main' into dev/chat 1 year ago
Lei OT 99d9f1ed32 style: 历史消息 1 year ago
Lei OT 032a9263d5 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 15a377abbe feat: 历史消息查询 1 year ago
Lei OT 1668cc4df9 fix: 历史记录: 模板没有参数显示undefined 1 year ago
Lei OT 46a3590e6d 模板填充: 匹配free style中的参数 1 year ago
Lei OT 4ceeff2ef3 Merge branch 'main' into dev/chat
# Conflicts:
#	src/views/ChatHistory.jsx
1 year ago
Lei OT 54c2364ac2 . 1 year ago
Lei OT 9269b362ac style: ChatHistory loading 1 year ago
Lei OT 1040e66b24 历史记录: 不显示text title 1 year ago
Lei OT d8b19ae287 fix: 有会话才获取消息记录 1 year ago
Lei OT 69d62427ac perf: 会话提示 1 year ago
Lei OT 08558325f7 perf: text消息显示客人的昵称 1 year ago
Lei OT d87136db93 Merge branch 'main' into dev/chat 1 year ago
Lei OT ec8736df91 perf: 联系人消息: 有wa_id 才能发消息 1 year ago
Lei OT 1b53966624 Merge branch 'main' into dev/chat
# Conflicts:
#	src/lib/msgUtils.js
1 year ago
Lei OT 79979ab53c perf: 联系人消息: 商户号显示org.company 1 year ago
Lei OT 3c07b31b03 Merge branch 'main' into dev/chat 1 year ago
Lei OT 42e3d48356 popover forceRender 1 year ago
Lei OT 32b75c0e04 popover forceRender 1 year ago
Lei OT f7dc6b97ba 上传文件重命名, 避免重名覆盖 1 year ago
Lei OT 571298659c perf: 更新会话的下一页参数 1 year ago
Lei OT 15f05dd1a2 联系人名片: 点击开启会话 1 year ago
Lei OT 77966e159e style: 1 year ago
Lei OT c58ee8319e 历史记录: 发送失败显示时间 1 year ago
Lei OT f8dbabe505 历史记录: 使用在线的API, 往上一页加载 1 year ago
Lei OT 1d3be3d077 style: 历史会话: bg-color 区分发送消息, 当会话钟有多个人员服务时 1 year ago
Lei OT 93a198fbdc perf: 模板填充顾问的英文名 1 year ago
Lei OT d3a8f8c927 历史记录里面的template 1 year ago
Lei OT 1ea939c9f5 style: input textarea emoji font 1 year ago
Lei OT d7ae548d1e style: 消息输入: 字数显示: 最大2000. 1 year ago
Lei OT f67ff2b29f todo: 获取会话列表, 多个顾问ID 1 year ago
Lei OT ec16147001 fix: 订单跟踪页面的高级查询的状态 1 year ago
Lei OT dd267e1223 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT eb771497b9 . 1 year ago
Lei OT 27d05620ba perf: 会话列表的昵称null判断 1 year ago
Lei OT bc31645153 debug: emoji in json 1 year ago
Lei OT b35088fd7a fix: whatsapp_name null 1 year ago
Lei OT df9d44c5a0 模板参数输入 1 year ago
Lei OT c3d8295798 在线窗口: 获取消息: 倒序的, 更新本页的最后一条消息座位下一页的开始 1 year ago
Lei OT 2557a19c22 Merge branch 'main' into dev/chat 1 year ago
Lei OT 4110618dcf test: 消息记录 1 year ago
Lei OT 241cff32fc 模板参数输入 1 year ago
Lei OT 9f9b55a9b4 Merge branch 'main' into dev/chat 1 year ago
Lei OT f5e0c94032 在线窗口: 获取消息 1 year ago
Lei OT 9c8a607d4a Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 780d917fb7 Merge branch 'main' into dev/chat 1 year ago
Lei OT d857d8fc69 历史记录: 搜索客人列表 1 year ago
Lei OT c86acb9111 fix: 模板填充 1 year ago
Lei OT 313e3f8478 在线窗口: 加载更多消息 1 year ago
Lei OT 413e3381d8 style: font 1 year ago
Lei OT 7f0a1dc8e7 更新投递成功的时间到会话列表 1 year ago
Lei OT 3f678d09c6 粘贴上传 1 year ago
Lei OT d9ce340780 style: 订单跟踪: 显示WhatsApp状态 1 year ago
Lei OT a1ef6b4c44 . 1 year ago
Lei OT 89e0da1667 Merge branch 'main' into dev/chat 1 year ago
Lei OT 363e000fdc 历史记录 加载更多 1 year ago
Lei OT 8cfaca960a Merge branch 'main' into dev/chat
# Conflicts:
#	src/actions/ConversationActions.js
1 year ago
Lei OT db948b5a4a 历史记录: 搜索顾问 1 year ago
Lei OT df9a5c917d 获取消息记录 1 year ago
Lei OT f50ffe8209 发送引用的消息返回状态时没有原文 1 year ago
Lei OT 81a112fd58 emoji font 1 year ago
Lei OT 51595e4b6b 优化搜索会话 1 year ago
Lei OT a3285eeaec 优化体验: 缓存表单数据: 订单跟踪-高级查询 1 year ago
Lei OT b1b2844238 fix: 从订单进入后没有置顶和选中 1 year ago
Lei OT bf22a4fbdd style: 历史记录; 即时聊天页的点击滚动 1 year ago
Lei OT b7af5b1cd3 优化体验: 缓存表单数据 1 year ago
Lei OT d5f32690a4 优化体验: 缓存表单数据 1 year ago
Lei OT da3a0037c7 Merge branch 'main' into dev/chat 1 year ago
Lei OT 0b0bd0ac04 优化体验: 缓存表单数据 1 year ago
Lei OT d66388b9cb Merge branch 'main' into dev/chat 1 year ago
Lei OT ae246e2975 test: ChatHistory: 查看salesmartly 导过来的会话 1 year ago
Lei OT 361e53d0c7 Merge branch 'main' into dev/chat 1 year ago
Lei OT 92a423ab31 todo: 历史记录 1 year ago
Lei OT 3bbe967b4c Merge branch 'main' into dev/chat 1 year ago
Lei OT 99d95b90b2 读取到消息之后, 未读清零 1 year ago
Lei OT 0ddf156761 取消系统通知的ID, 否则收起之后弹不出来 1 year ago
Lei OT 995c1dd5f7 . 1 year ago
Lei OT aac1c5159c Merge branch 'main' into dev/chat 1 year ago
Lei OT 671cbc7881 会话列表: 搜索会话 1 year ago
Lei OT db774fec09 Merge branch 'main' into dev/chat 1 year ago
Lei OT a0bdda2041 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT b802d47792 会话列表: 搜索会话 1 year ago
Lei OT 972f033928 Merge branch 'main' into dev/chat 1 year ago
Lei OT 75c76f39e3 未读消息设置已读接口 1 year ago
Lei OT 39ce076cdf 会话列表: 显示订单号 1 year ago
Lei OT 2e96375caf Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 1d1207d155 ChatHistory 1 year ago
Lei OT 225d5ab4a0 高德地图尝试唤起 1 year ago
Lei OT 1b6233c6ee 新消息闪烁 1 year ago
Lei OT 4f525effce 滚动 1 year ago
Lei OT 025289eae7 上传文件的类型限制 1 year ago
Lei OT 78b3db5a40 Merge branch 'main' into dev/chat 1 year ago
Lei OT 0beca15c24 消息记录: 类型 location 打开高德地图 1 year ago
Lei OT 3f6e5437ed style: sticker bg transparent 1 year ago
Lei OT ad620c964c Merge branch 'main' into dev/chat 1 year ago
Lei OT 17b9ad50a5 消息类型: 系统消息 1 year ago
Lei OT 269f64d2bc Merge branch 'main' into dev/chat 1 year ago
Lei OT 76f1be63dc 消息记录: 类型unsupported 1 year ago
Lei OT 640f164ee0 Merge branch 'main' into dev/chat
# Conflicts:
#	src/lib/msgUtils.js
1 year ago
Lei OT 7b37713bb1 Merge branch 'main' into dev/chat 1 year ago
Lei OT de474f9e28 上传附件: 发送相应的类型; 消息类型解析: contacts, location 1 year ago
Lei OT fb4e47fcdc Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 8757d5df54 未解析的消息, 显示为不支持 1 year ago
Lei OT c30628681d 消息类型: contact: 复制; location 1 year ago
Lei OT 7002f72cbf todo: 联系人点击发送消息 1 year ago
Lei OT 7013ca56fd todo: 语音和视频有可能格式后缀一样 1 year ago
Lei OT 599962ec40 MediaUpload: 上传附件文件 1 year ago
Lei OT e689f3a33b Merge branch 'main' into dev/chat 1 year ago
Lei OT f72acd987c MediaUpload: 上传马上发送 1 year ago
Lei OT 89c6cb3134 断开连接之后, 取消当前会话 1 year ago
Lei OT 9972a093b8 MediaUpload: videoURL 1 year ago
Lei OT 9540b22eba Merge branch 'main' into dev/chat 1 year ago
Lei OT af419072ac 上传文件 1 year ago
Lei OT a20dd314cf todo: MediaUpload action 1 year ago
Lei OT 08eb3c6bcb fix: 发送的消息无法引用 1 year ago
Lei OT 9c363103d6 关闭会话: 判断更新路由 1 year ago
Lei OT e87fe9222f Merge branch 'main' into dev/chat 1 year ago
Lei OT e4da66d1a9 style: 截断头像上的名称显示 1 year ago
Lei OT 4778081a86 fix: undefined get order info 1 year ago
Lei OT 876d94cacf Merge branch 'main' into dev/chat 1 year ago
Lei OT a9f9e08553 删除 消息记录的loading 1 year ago
Lei OT c9e2c0c69a todo: scroll 1 year ago
Lei OT a7be72ba9c Merge branch 'main' into dev/chat 1 year ago
Lei OT 1618a194a1 输入的emoji 1 year ago
Lei OT 7cdb06e849 Merge branch 'main' into dev/chat 1 year ago
Lei OT 380c2ec247 noto color emoji 1 year ago
Lei OT 472c2004f2 Merge branch 'dev/chat-emoji' into dev/chat 1 year ago
Lei OT b9e69c56c9 # Conflicts:
#	src/views/Conversations/Components/Messages.jsx
#	src/views/Conversations/Conversations.css
1 year ago
Lei OT 118c43093c dowmload google noto color emoji 1 year ago
Lei OT 7811c3ab9a Merge branch 'main' into dev/chat 1 year ago
Lei OT b06d72bde4 google Emoji; 更新totalNotify 1 year ago
Lei OT ed1af0ac7c noto color emoji 1 year ago
Lei OT de7fd30df5 todo: emoji font 1 year ago
Lei OT 4852b0067d 按钮: 滚动到底部 1 year ago
Lei OT 39bf2e717b 引用: 图片, 视频 1 year ago
Lei OT 07b7493a60 初始化之后, 获取最近的消息 1 year ago
Lei OT 403194c3a0 消息类型: 文件: 点击打开; 不支持的消息类型 1 year ago
Lei OT 9725320aa6 消息滚动; 修复预览, 引用 1 year ago
Lei OT f2fcf0324a Merge branch 'main' into dev/chat
# Conflicts:
#	src/views/Conversations/Components/InputComposer.jsx
1 year ago
Lei OT ca637d2a54 模板激活状态 1 year ago
Lei OT 13ae99945b notification click err: null 1 year ago
Lei OT b95fdd12d6 fix: Emoji repeat 1 year ago
Lei OT d49b0496bc 消息列表 滚动 1 year ago
Lei OT 0e8042d256 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 5e73262b58 Merge branch 'main' into dev/chat 1 year ago
Lei OT b486551169 缺少引用 1 year ago
Lei OT a79b8e8167 Merge branch 'main' into dev/chat 1 year ago
Lei OT 32076e9441 新消息提醒和闪烁 1 year ago
Lei OT 323247aa0f 订单会话: 刷新 1 year ago
Lei OT 30202d2e43 Merge branch 'main' into dev/chat 1 year ago
Lei OT 38e18cf4b8 订单会话: 刷新 1 year ago
Lei OT 65a9095b0d todo: 消息数量 1 year ago
Lei OT fa89685dd2 WhatsApp号码判断 1 year ago
Lei OT fda145219e Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 3488d18bbe 消息解析 链接和表情 1 year ago
Lei OT fd204762d7 新消息闪烁提醒 1 year ago
Lei OT f9abf66455 空的消息记录 1 year ago
Lei OT 309f4154ea 消息样式 1 year ago
Lei OT ce4fa20491 修改store 取值 1 year ago
Lei OT 3da599944b style 1 year ago
Lei OT c09e828038 发送时间 1 year ago
Lei OT 68fab01530 显示错误码 1 year ago
Lei OT 5aee197c47 Merge branch 'main' into dev/chat 1 year ago
Lei OT 8495a27035 会话列表显示号码 1 year ago
Lei OT 803187c7d2 Merge branch 'main' into dev/chat 1 year ago
Lei OT b8b9f84d6b # 1 year ago
Lei OT d35e94f504 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT d7fb0167ac 发送失败: errorMessage 1 year ago
Lei OT 509bc4cffd style: 客人名称和头像显示 1 year ago
Lei OT 5f96a4e27b todo: upload 1 year ago
Lei OT caf653ee51 Merge branch 'main' into dev/chat 1 year ago
Lei OT 98efe884c7 # 1 year ago
Lei OT d516a2af65 feat: Emoji 1 year ago
Lei OT 43c28618a6 style: 图片消息样式; 会话列表 1 year ago
Lei OT 8d3f00119a conf: 1 year ago
Lei OT 36d14a4d28 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 4957db8c94 Merge branch 'main' into dev/chat 1 year ago
Lei OT cf22e07288 获取用户信息 1 year ago
Lei OT 0ef2cdf72f Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 487e0e8b09 断开连接 1 year ago
Lei OT 7c50a4c523 重连20次, 间隔10秒 1 year ago
Lei OT 3c0704b0aa Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 6ac55957b6 手动重连; 字母头像 1 year ago
Lei OT ec29e9e40c Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 5f26170df1 信息中的链接识别和样式 1 year ago
Lei OT 87d3bce2f4 发送图片: 图片+文字 1 year ago
Lei OT 141a40d0f4 Merge branch 'main' into dev/chat 1 year ago
Lei OT 641b05f6a8 fix: 不含参数的模板 1 year ago
Lei OT 49e0be4428 解决链接之后上级组件re-render; 获取loginUser 1 year ago
Lei OT b0105a2b9c Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 77b3a135ee 上传图片 1 year ago
Lei OT d5ff6e08ca 主动重连 1 year ago
Lei OT 5615b0b9f8 会话列表和消息右键菜单 1 year ago
Lei OT 01f271fb38 style: 1 year ago
Lei OT 484e8122d4 fix: 折叠 1 year ago
Lei OT b44a3fd40d Merge branch 'main' into dev/chat 1 year ago
Lei OT ce77626f1d Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT dc238a7078 # 1 year ago
Lei OT 64895873c3 feat: 链接识别和可点击 1 year ago
Lei OT 738492da17 style: 1 year ago
Lei OT 4b8cce5f8f Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 18ab4fd5ab Merge branch 'main' into dev/chat 1 year ago
Lei OT d19c70968c 刷新页面, 定位指定的会话 1 year ago
Lei OT 53f6a02032 引用消息显示的颜色 1 year ago
Lei OT 16688f2cf4 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT e769555e3d Messages list loading 1 year ago
Lei OT ac09cce4a8 引用的消息原文 todo: 接收: 引用自客户信息的原文; emoji 1 year ago
Lei OT ea7e430962 Merge branch 'main' into dev/chat 1 year ago
Lei OT 4b76f1cdc0 发: 引用消息的发送, 显示, 读取 1 year ago
Lei OT 34f900469c todo: 引用消息 1 year ago
Lei OT a291f57b8f Merge branch 'main' into dev/chat 1 year ago
Lei OT 7db4d9fd74 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 0ef3a4a2b3 订单进入会话, 获取新会话列表 1 year ago
Lei OT e466d3d414 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT be24c964e0 删除 useReducer 的 ConversationContext, Action, Reducer, Provider 1 year ago
Lei OT c6ed93acd1 style: bg 1 year ago
Lei OT 62e1d9eff0 perf: 会话窗口: 左右折叠 1 year ago
Lei OT 14a6baac43 引用的消息, 不显示号码 1 year ago
Lei OT 80cb0357de Messages, 数组避免多余的属性和方法 1 year ago
Lei OT aa23645e86 Merge branch 'main' into dev/chat 1 year ago
Lei OT 00de8ceedc 模板分页, 3 1 year ago
Lei OT 8282bf6d1b referenceMsg 数据类型 1 year ago
Lei OT e5e17625fe Merge branch 'main' into dev/chat 1 year ago
Lei OT 3a7d293e02 zustand debug 1 year ago
Lei OT a5dade92e6 websocket 1 year ago
Lei OT c7aaa17bea Merge branch 'main' into dev/chat 1 year ago
Lei OT 13ea0ea893 删除context provider 1 year ago
Lei OT a72914c955 useShallow 1 year ago
Lei OT e4b55d6303 # 1 year ago
Lei OT 0b0bf329aa 状态管理: zustand 1 year ago
Lei OT a7ccf7a9b0 日志 黄 1 year ago
Lei OT d083784a71 发送图片链接 1 year ago
Lei OT daa48d4c80 Merge branch 'main' into dev/chat 1 year ago
Lei OT 7cf33bb1c9 消息记录: 引用的消息原文 todo: reaction 的原文 1 year ago
Lei OT f989f257a1 Merge branch 'main' into dev/chat 1 year ago
Lei OT 662b614b60 根据类型, 控制是否允许引用 1 year ago
Lei OT bb3168169c 引用消息 1 year ago
Lei OT ed7c659fb4 context from 1 year ago
Lei OT e2499e9901 会话窗口刷新和获取消息记录 1 year ago
Lei OT 92c5a8636d 关闭会话: 传参 1 year ago
Lei OT 0e257d93f1 Merge branch 'main' into dev/chat 1 year ago
Lei OT bd4b864518 订单号传参 1 year ago
Lei OT f6bc762413 Merge branch 'main' into dev/chat 1 year ago
Lei OT 41a870941e Merge branch 'main' into dev/chat 1 year ago
Lei OT fb6ea485c8 关闭会话 1 year ago
Lei OT 271ed8e089 回复引用 1 year ago
Lei OT e3b5b90a9a Merge branch 'main' into dev/chat 1 year ago
Lei OT d07bafad66 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 1163cb1533 检测是否超过24H 1 year ago
Lei OT 7ba43ebd4f 新消息-新增会话; style: 激活的会话; 会话新消息在列表中置顶 1 year ago
Lei OT 2effad3ef9 Merge branch 'main' into dev/chat 1 year ago
Lei OT 0c0b197439 新消息, 滚动 1 year ago
Lei OT d07848a401 断开连接状态; 发送按钮; 同步显示其他客户端发送的实时消息 1 year ago
Lei OT 94800b91fd Merge branch 'main' into dev/chat 1 year ago
Lei OT aeeb443ef9 style: 1 year ago
Lei OT f6d3a93e15 style: 1 year ago
Lei OT bd61113e3f Merge branch 'main' into dev/chat 1 year ago
Lei OT 7ed6391b81 模板变量输入和替换; 模板搜索和分页; 多行文本输入, 输入区域样式, 回车发送消息; 消息显示支持换行; websocket 连接状态; 重连 1 year ago
Lei OT a5d628b92d websocket 连接状态; 重连 1 year ago
Lei OT 5631ba4997 消息显示支持换行 1 year ago
Lei OT 21c0341a02 多行文本输入, 输入区域样式 1 year ago
Lei OT ff15ef9e2d 模板搜索和分页 1 year ago
Lei OT e80d491c58 模板变量输入和替换, 回车发送 1 year ago
Lei OT e243b5e77c Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT d55157ca2d 发送模板: 变量输入 1 year ago
Lei OT c5f1ba1b5e 发送模板替换变量 1 year ago
Lei OT 44b3dbd8df Merge branch 'main' into dev/chat 1 year ago
Lei OT 591969be40 模板消息: body: 发送参数填充后的整体内容 1 year ago
Lei OT d604f4ebf1 获取消息记录 1 year ago
Lei OT f8b7aad52e 新模板: use_new_whatsapp 1 year ago
Lei OT e229e76222 Merge branch 'main' into dev/chat 1 year ago
Lei OT ed17229b6c 发送消息: 需要会话的订单号 1 year ago
Lei OT 3a403a3fcd 发送的消息的状态; 切换会话,获取相应的订单信息, 再影响到会话; 1 year ago
Lei OT 21a9b80a9d Merge branch 'main' into dev/chat 1 year ago
Lei OT 3ade9778ea Merge branch 'main' into dev/chat 1 year ago
Lei OT e5469aad5c 会话切换 1 year ago
Lei OT 26def60a24 reducer context 管理conversation state; 拆分reducer, 减少re-render; 整理目录; 新消息累加未读数量 test: 关闭会话; 1 year ago
Lei OT 2a333c1e45 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 9a3dbf634f test: 关闭会话; 1 year ago
Lei OT 3a342331d6 新消息累加未读数量 1 year ago
Lei OT 3290b2c161 减少re-render 1 year ago
Lei OT 2b6cf70f48 拆分reducer; 整理目录 1 year ago
Lei OT 4552d0ad58 reducer context 管理conversation state 1 year ago
Lei OT fc556120ce style: 订单预定详情 1 year ago
Lei OT 575178ee7d Merge branch 'main' into dev/chat 1 year ago
Lei OT 61523f3d5f Merge branch 'main' into dev/chat 1 year ago
Lei OT b7e10d1670 关闭会话 1 year ago
Lei OT 006be2a1c4 style: 1 year ago
Lei OT 2dbcf78252 订单进入会话的切换;
暂不做沟通记录
1 year ago
Lei OT a3a57847ec 当前的消息列表; 更新列表的时间 1 year ago
Lei OT 628e37ddfc WhatsApp样式配置; 订单进入会话; 1 year ago
Lei OT 2e39681046 Merge branch 'main' into dev/chat 1 year ago
Lei OT be2aa636ca 接受的消息, 不需要状态 1 year ago
Lei OT 5f4c8863b5 切换会话, conversationid 1 year ago
Lei OT 404105fc40 同步返回结果: API状态; 异步结果 1 year ago
Lei OT 58038b6fe2 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT d0ea6c8b7b 会话无订单时的切换; 测试地址; 测试会话; 1 year ago
Lei OT b91314db0f Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 2d30de03d2 # 1 year ago
Lei OT 30d4b5ca6f 点击会话列表, 替换路由 1 year ago
Lei OT 23fd7dc22f WhatsApp模板参数填充; 增加显示消息类型: 文件; 发送消息的同步回调处理; 自动重连(10次); 1 year ago
Lei OT 9cd3e1d38e 删除测试文件 1 year ago
lot cf093c22ca Merge remote-tracking branch 'origin/main' into dev/chat
# Conflicts:
#	src/views/OrderFollow.jsx
1 year ago
Lei OT d2ef99cd9e 订单进入会话页面, 获取订单信息 1 year ago
Lei OT 6c6989accd 更新消息送达状态 1 year ago
Lei OT 74966d2730 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 491facce74 连接ws:// 传参opisn 1 year ago
Lei OT 806ef7f90f 删除mobx observer 1 year ago
Lei OT 8cebe7da45 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT d8a88be180 整理 ConversationContext .
todo: 使用 useContext useReducer 管理事件触发更新状态
1 year ago
Lei OT 3f31656630 todo: 更新已发送的消息的状态. renderId 1 year ago
Lei OT 7c23a75c26 Merge remote-tracking branch 'origin/main' into dev/chat
# Conflicts:
#	package.json
#	src/main.jsx
#	src/stores/ConversationContext.js
#	src/views/Conversations/ChatWindow.jsx
#	src/views/Conversations/Components/ConversationsList.jsx
#	src/views/Conversations/Components/CustomerProfile.jsx
#	src/views/Conversations/Components/InputBox.jsx
#	src/views/Conversations/Components/Messages.jsx
#	src/views/Conversations/ConversationProvider.jsx
#	src/views/Conversations/Conversations.css
#	tailwind.config.js
#	vite.config.js
1 year ago
Lei OT ef71252617 模板消息等
todo: 更新已发送的消息的状态. renderId
1 year ago
Lei OT 70fbcae715 对话窗口; 发送文本; 解析WhatsApp信息各类型 1 year ago
Lei OT ab124d9be3 build: + tailwind 1 year ago
Lei OT 807edcb74f feat: 会话窗口 1 year ago
Lei OT 5d83ce7662 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 58198062ff feat: 会话窗口 1 year ago
Lei OT 11e4a44de2 feat: 会话窗口 1 year ago
Lei OT d80b83b1f3 Merge remote-tracking branch 'origin/main' into dev/chat
# Conflicts:
#	src/main.jsx
#	src/views/App.jsx
1 year ago
Lei OT acbd36a8b4 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 6ad8148021 Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 2017b373e9 ChatWindow 1 year ago
Lei OT 4ee4eb85bf Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT 90fd95d977 test: 单个会话订阅. 发送和接收 1 year ago
Lei OT 785fdffc56 Merge remote-tracking branch 'origin/main' into dev/chat
# Conflicts:
#	src/main.jsx
1 year ago
Lei OT 499cc91218 conf: eslint 1 year ago
Lei OT e13bc7b096 test: 单个会话订阅. 发送和接收 1 year ago
Lei OT 7bdd2a6eac Merge remote-tracking branch 'origin/main' into dev/chat 1 year ago
Lei OT ca20cfb1a2 Merge branch 'main' into dev/chat 1 year ago
Lei OT 1d8c12ef66 test 1 year ago
Lei OT c0f1f7b369 WebSocketLib 1 1 year ago

@ -7,7 +7,7 @@ module.exports = {
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['node_modules/*', 'dist', '.eslintrc.cjs'],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
settings: { react: { version: '18.2' } },
plugins: ['react-refresh'],

15
.gitignore vendored

@ -11,11 +11,6 @@ node_modules
dist
dist-ssr
*.local
distTest
dev-dist
tmp
schema*
.gitkeep
# Editor directories and files
.vscode/*
@ -29,13 +24,3 @@ schema*
*.sw?
/package-lock.json
**/LexicalEditor0
*.zip
.env.*
vonage-client*
**/test
*.bak

@ -1,18 +0,0 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 200,
"tabWidth": 2,
"useTabs": false,
"semi": false,
"quoteProps": "as-needed",
"jsxSingleQuote": true,
"bracketSpacing": true,
"jsxBracketSameLine": true,
"singleAttributePerLine": false,
"arrowParens": "always",
"requirePragma": false,
"insertPragma": false,
"proseWrap": "preserve",
"htmlWhitespaceSensitivity": "ignore"
}

@ -1,46 +1,14 @@
# Global sales
销售平台通过邮件、WhatsApp Business Account、WhatsApp 和客人沟通。
聊天式销售平台
## 开发设置
所有命令都在 cmd 目录,
1. 安装组件npm install
2. 运行开发环境dev.bat
3. 打包代码build.bat
## 版本设置
遵循 [Semantic Versioning 2.0.0](http://semver.org/lang/zh-CN/) 语义化版本规范。
修订版本号:日常 bugfix 更新。(如果有紧急的 bugfix则任何时候都可发布
次版本号:有新特性的向下兼容的版本。
主版本号:含有破坏性更新和新特性。
2. 运行开发环境npm run dev 或者 start.bat
3. 打包代码npm run build 或者 build.bat
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
npm version preminor --preid alpha --no-git-tag-version
npm version preminor --preid beta --no-git-tag-version
1.2.0 -> 1.3.0-beta.0
npm version premajor --no-git-tag-version
1.0.0 -> 2.0.0-0
npm version prerelease --no-git-tag-version
2.0.0-0 -> 2.0.0-1 -> 2.0.0-2 ..n -> 2.0.0-n
npm version patch --no-git-tag-version
2.0.0-n -> 2.0.0
## 相关文档
[聊天式销售平台需求文档](https://www.kdocs.cn/l/calaUjgmCmDA?from=docs&reqtype=kdocs&startTime=1703645330177&createDirect=true&newFile=true)
## vonage语音视频
安装模块 npm i @vonage/client-sdk
## 本机测试账号
GLOBAL_SALES_LOGIN_USER
{"userId":"383","userIdStr":"383,609","emailList":[{"opi_sn":383,"mat_sn":760,"email":"lyj@asiahighlights.com","default":false,"backup":false},{"opi_sn":383,"mat_sn":759,"email":"lyj@chinahighlights.com","default":false,"backup":false},{"opi_sn":383,"mat_sn":758,"email":"lyj@hainatravel.com","default":false,"backup":false},{"opi_sn":383,"mat_sn":761,"email":"lyj@chinahighlights.net","default":true,"backup":false}],"username":"廖一军","avatarUrl":"https://static-legacy.dingtalk.com/media/lALPBDDrhXr716HNAoDNAoA_640_640.png","mobile":"+86-18777396951","email":"lyj@hainatravel.com","whatsAppBusiness":"8617458471254","openId":"iioljiPmZ4RPoOYpkFiSn7IKAiEiE","accountList":[{"OPI_SN":383,"OPI_Code":"LYJ","OPI_NameCN":"廖一军","OPI_DEI_SN":7,"OPI_NameEN":"Jimmy Liow"},{"OPI_SN":609,"OPI_Code":"LYJAH","OPI_NameCN":"廖一军ah","OPI_DEI_SN":28,"OPI_NameEN":"Jimmy Liow"}]}

@ -1 +0,0 @@
npm run build

@ -1 +0,0 @@
npm run dev

@ -1 +0,0 @@
npm version patch

@ -1 +0,0 @@
npm version prerelease

@ -1,83 +0,0 @@
## 发送template 消息
### 模板原文
```json
{
"wabaId": "190290134156880",
"name": "order_updated_specialist_assigned_sharon",
"language": "en",
"messageSendTtlSeconds": -1,
"components": [
{
"type": "BODY",
"text": "Hi {{customer_name}}, this is {{your_name1}} your trip advisor. \nHow are you? {{free_style}} \nKindest regards, {{your_name2}}. ",
"example": {
"body_text": [
[
"Mike",
"Coco",
"I'm following up on your itinerary",
"Coco2"
]
]
}
}
],
"category": "UTILITY",
"status": "APPROVED",
"qualityRating": "UNKNOWN",
"reason": "NONE",
"createTime": "2024-12-11T08:31:11.290Z",
"updateTime": "2024-12-11T08:31:34.610Z",
"statusUpdateEvent": "APPROVED"
}
```
### 发送模板消息, 数据结构
```json
{
"action": "message", // 固定值
"actionId": "190.3c8322de-68df-4f9e-be8e-d92e7a13b7d7", // .uuid()
"renderId": "190.3c8322de-68df-4f9e-be8e-d92e7a13b7d7", // 忽略
"externalId": 190, // 留空
"to": "8613557032060",
"from": "+8617607730395",
"msgtype": "template", // 固定值
"msgcontent": {
"name": "order_updated_specialist_assigned_sharon", // 模板名称. 从原文
"language": {
"code": "en" // 语言. 从原文
},
"components": [ // 没有参数的组件, 建议不传. 组件顺序也会报错
{
"type": "body",
"parameters": [ // 模板参数. 按 当前 `type` 中的参数顺序排列
{
"type": "text",
"text": "test OT 22" // 参数值: 不能换行, 连续空格<4
},
{
"type": "text",
"text": "yoyo"
},
{
"type": "text",
"text": "111"
},
{
"type": "text",
"text": "yoyo"
}
],
"text": "Hi test OT 22, this is yoyo your trip advisor. \nHow are you? 111 \nKindest regards, yoyo. " // 拼接一个完整内容
}
]
},
"opi_sn": "404", // 发送人 ID
"coli_sn": 1082591,
"conversationid": 190 // 忽略
}
```

Binary file not shown.

@ -1,182 +0,0 @@
## 查找出掉线的 WhatsApp
select *
from whatsapp_individual.connections
where status IN ('offline')
and wa_id not in ('8618777396951', '8613557032060','8613317835586')
and wa_id <> 'null'
//
SELECT group_concat(opi_sn separator ',') as 'sn_list' FROM (
SELECT
opi_sn,COUNT(*)
FROM whatsapp_session
where opi_sn is not null and opi_sn not in (29,383,404,227)
AND (last_send_time >= '2024-4-15' AND last_send_time <= '2024-4-21')
GROUP by opi_sn
) session_count
SELECT
OPI_SN, OPI_Code,OPI_Name,OPI_DEI_SN,OPI_FirstName,OPI_RealName
FROM
dbo.OperatorInfo
where
DeleteFlag = 0 and
OPI_SN in (162,31,32,33,34,599,600,353,352,350,351,35,606,495,293,525,114,587,585,519,522,476,354,451,216,143,586,539,370,512)
// HT
SELECT opi.OPI_Code,
opi.OPI_Name, tpa.* FROM dbo.ThirdPlatformAccount_Bind tpa
left join OperatorInfo opi
on opi.opi_sn = tpa.TPA_OPI_SN
where opi.DeleteFlag = 0
//
SELECT *
FROM whatsapp_session
WHERE coli_sn = 0 AND last_received_time IS NOT NULL ## AND opi_sn = 599
ORDER BY last_received_time DESC
// WA
SELECT *
FROM whatsapp_session
WHERE whatsapp_phone_number_bak IS not NULL
/**
* ---------------------------------------------------------
*
*/
-- title: query order info
SELECT cli.COLI_ID,cli.COLI_SN
,cli.COLI_GRI_SN
,mi.MEI_SN
-- ,cl.CUL_SN
,oi.OPI2_Name AS
,'#-------#'
,cli.COLI_OrderStartDate
,(mi.MEI_FirstName + ' | '+ mi.MEI_LastName) AS member_name
,cli.*
,'#-------#',cl.*
,'#-------#', mi.*
FROM ConfirmLineInfo AS cli
LEFT JOIN CUstomerList AS cl ON cli.COLI_SN = cl.CUL_COLI_SN
LEFT JOIN MEmberInfo AS mi ON mi.MEI_SN = cl.CUL_CUI_SN
LEFT JOIN OperatorInfo2 AS oi ON oi.opi2_opi_sn = cli.COLI_OPI_ID AND oi.OPI2_LGC =2
WHERE 1 = 1
-- AND mi.MEI_FirstName = 'CHEN WANG'
AND COLI_ID = 'Lib231120146'
-- AND CUL_COLI_SN = 1086888
--
;
UPDATE whatsapp_session
SET coli_sn = 1075451
WHERE sn = 57 AND whatsapp_phone_number = '14048496022';
UPDATE whatsapp_inboundmessage msg
INNER JOIN whatsapp_session s ON s.whatsapp_phone_number = msg.froms
AND msg.msg_direction = 'inbound'
SET msg.coli_sn = s.coli_sn
WHERE ifnull(msg.coli_sn, 0) = 0
AND msg.msg_direction = 'inbound'
AND msg.froms = '393343998897';
UPDATE whatsapp_inboundmessage msg
INNER JOIN whatsapp_session s ON s.whatsapp_phone_number = msg.tos
AND msg.msg_direction = 'outbound'
SET msg.coli_sn = s.coli_sn
WHERE ifnull(msg.coli_sn, 0) = 0
AND msg.msg_direction = 'outbound'
AND msg.tos = '393343998897';
/**
* end
* ---------------------------------------------------------
*/
/**
* ---------------------------------------------------------
*
*/
INSERT INTO sale_system.whatsapp_session (
whatsapp_phone_number,whatsapp_name, opi_sn,coli_sn,session_enable)
VALUES ('6282145142470','',162,0,1);
/**
* end
* ---------------------------------------------------------
*/
/**
* ---------------------------------------------------------
*
* , WhatsApp
* 1. coli_sn, coli_id, whatsapp_name
* 2. : tos, coli_sn
*/
UPDATE sale_system.whatsapp_session
SET whatsapp_name='Luiz Ribeiro', coli_sn=1092511, coli_id='L240509014'
WHERE whatsapp_phone_number='553499923993' AND opi_sn = 587;
UPDATE sale_system.whatsapp_inboundmessage
SET tos='553499923993', coli_sn=1092511
WHERE tos = '5534999923993' AND opi_sn = 587;
/**
* end
* ---------------------------------------------------------
*/
/**
WhatsApp
*/
select * from whatsapp_user
##where wau_opi_sn in (252, 261,264,265,330,360,376,413,421,453,605,620) ## 国际部
where wau_opi_sn in (495, 143, 370, 114, 513, 514, 517, 522, 550, 587,354, 414, 599, 606, 639, 648, 654, 662, 674, 676,391, 451, 476, 501, 512, 525, 528, 585, 586, 644) ## GH
-- 查找每个服务器在线的 WA 数量
select connect_name, count(*)
from whatsapp_individual.connections
where status IN ('open')
group by connect_name
set SESSION group_concat_max_len=4294967295;
-- 查找已经配置 WAI 服务的顾问
select group_concat(wau_whatsapp separator ''',''') as 'sn_list'
from sale_system.whatsapp_user
where wau_wai_server is not null
## 查找在线的 WhatsApp
SELECT group_concat(sesson_id separator ''',''') as 'sesson_list'
FROM whatsapp_individual.connections
where status = 'open'
-- 查找掉线的顾问
select group_concat(sesson_id separator ''',''') as 'sesson_list' from whatsapp_individual.connections
where status IN ('offline')
and wa_id not in ('8618777396951', '8613557032060','8613317835586')
## 查找 GH 没有扫码登录的顾问
select group_concat(wau_opi_sn separator ',') as 'sn_list'
from whatsapp_user
where wau_whatsapp not in ('8613317835586','8617607732272','8613978392676','8618378304803','8617607730629','8619107833371','8619107835971','8617607731491','8615080129281','8617607737720','8618777396951','8618078444860','8615778462307','8617774702925','8615078398450','8619178340224','8617607731153','8617607735120','8617607737646','8618877388203','8615778493040','8613617733956','8618290167273','8617776515283','8617607736381','8613557032060','8613667839691','8618378388403','8613635132972','8617607734598','8617607732512','8615878340720')
and wau_opi_sn in (495, 143, 370, 114, 513, 514, 517, 522, 550, 587,354, 414, 599, 606, 639, 648, 654, 662, 674, 676,391, 451, 476, 501, 512, 525, 528, 585, 586, 644)
-- 查找使用 WhatsApp 顾问信息
SELECT
OPI_SN, OPI_Code,OPI_Name,OPI_DEI_SN,OPI_FirstName,OPI_RealName, DeleteFlag
FROM
dbo.OperatorInfo WHERE
OPI_SN in (143,476,528,391)
--OPI_SN in (495, 143, 370, 114, 513, 514, 517, 522, 550, 587)
SELECT OPI_RealName + '(' + CAST(OPI_SN AS VARCHAR(100)) + ')',OPI_SN
FROM
dbo.OperatorInfo
where
--DeleteFlag = 0 and
OPI_SN in (79,85,114,119,135,143,155,162,178,210,216,222,225,252,261,264,265,273,293,296,311,330,343,347,348,354,360,370,376,387,391,412,413,414,421,441,444,451,453,456,466,468,476,495,497,501,509,512,513,514,517,519,522,525,527,528,539,550,573,585,586,587,592,599,600,605,606,611,617,620,639,644,648,654,656,659,662,663,674,676,690,691)
and OPI_RealName in ('兰芬','孙俊垚','王继伟','曾君','潘宏宇','郑美珍','张丽娟','张倩倩','赵泽菲','王影','陆力影','吕燕珍','何秋云','沈慧香')

File diff suppressed because it is too large Load Diff

@ -4,13 +4,11 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>销售平台</title>
<link rel="preconnect" crossorigin="anonymous" href="https://haina-sale-system.oss-cn-shenzhen.aliyuncs.com">
<link rel="preconnect" crossorigin="anonymous" href="https://hiana-crm.oss-ap-southeast-1.aliyuncs.com">
<title>聊天式销售平台</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
<p style="display: none;">VERSION: %BUILD_VERSION%</p>
<p style="display: none;">BUILD_DATE: %BUILD_DATE%</p>
</body>
</html>

@ -1,18 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title>Sales CRM Maintenance</title>
</head>
<body>
<div id="maintenance-root"></div>
<script type="module" src="/src/maintenance.jsx"></script>
</body>
</html>

@ -1,7 +1,7 @@
{
"name": "global-sales",
"private": true,
"version": "1.5.0-1",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
@ -10,37 +10,32 @@
"preview": "vite preview"
},
"dependencies": {
"@dckj/react-better-modal": "^0.1.2",
"@lexical/react": "^0.20.0",
"@vonage/client-sdk": "^2.0.0",
"antd": "^5.25.2",
"dayjs": "^1.11.13",
"dingtalk-jsapi": "^3.0.41",
"emoji-picker-react": "^4.12.0",
"lexical": "^0.20.0",
"react": "^18.3.1",
"react-chat-elements": "^12.0.17",
"react-dom": "^18.3.1",
"react-router-dom": "^6.30.1",
"antd": "^5.14.0",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.10",
"emoji-picker-react": "^4.8.0",
"react": "^18.2.0",
"react-chat-elements": "^12.0.11",
"react-dom": "^18.2.0",
"react-router-dom": "^6.21.1",
"rxjs": "^7.8.1",
"uuid": "^9.0.1",
"zustand": "^4.5.7"
"vite-plugin-pwa": "^0.19.6",
"zustand": "^4.5.0"
},
"devDependencies": {
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.17",
"eslint": "^8.45.0",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.14",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.15",
"eslint-plugin-react-refresh": "^0.4.3",
"postcss": "^8.4.33",
"tailwindcss": "^3.4.1",
"vite": "^4.5.1",
"vite-plugin-css-modules": "^0.0.1",
"vite-plugin-pwa": "^0.21.0",
"vite-plugin-svgr": "^4.3.0",
"vite-plugin-windicss": "^1.9.3",
"windicss": "^3.5.6"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -1 +0,0 @@
<?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 t="1721878224733" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5115" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M926.47619 355.644952V780.190476a73.142857 73.142857 0 0 1-73.142857 73.142857H170.666667a73.142857 73.142857 0 0 1-73.142857-73.142857V355.644952l304.103619 257.828572a170.666667 170.666667 0 0 0 220.745142 0L926.47619 355.644952zM853.333333 170.666667a74.044952 74.044952 0 0 1 26.087619 4.778666 72.704 72.704 0 0 1 30.622477 22.186667 73.508571 73.508571 0 0 1 10.678857 17.67619c3.169524 7.509333 5.12 15.652571 5.607619 24.210286L926.47619 243.809524v24.380952L559.469714 581.241905a73.142857 73.142857 0 0 1-91.306666 2.901333l-3.632762-2.925714L97.52381 268.190476v-24.380952a72.899048 72.899048 0 0 1 40.155428-65.292191A72.97219 72.97219 0 0 1 170.666667 170.666667h682.666666z" p-id="5116" fill="#7162AD"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

@ -1 +0,0 @@
<?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 t="1721877281911" class="icon" viewBox="0 0 1036 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2369" xmlns:xlink="http://www.w3.org/1999/xlink" width="202.34375" height="200"><path d="M759.466667 827.733333H98.133333c-55.466667 0-98.133333-42.666667-98.133333-98.133333V328.533333c0-55.466667 42.666667-98.133333 98.133333-98.133333h827.733334c55.466667 0 98.133333 42.666667 98.133333 98.133333v234.666667c0 12.8-8.533333 21.333333-21.333333 21.333333s-21.333333-8.533333-21.333334-21.333333V328.533333c0-29.866667-25.6-55.466667-55.466666-55.466666H98.133333C68.266667 273.066667 42.666667 298.666667 42.666667 328.533333V725.333333c0 29.866667 25.6 55.466667 55.466666 55.466667h661.333334c12.8 0 21.333333 8.533333 21.333333 21.333333s-8.533333 25.6-21.333333 25.6z" fill="#7162AD" p-id="2370"></path><path d="M917.333333 827.733333H823.466667c-12.8 0-21.333333-8.533333-21.333334-21.333333s8.533333-21.333333 21.333334-21.333333h93.866666c34.133333 0 64-29.866667 64-64v-85.333334c0-12.8 8.533333-21.333333 21.333334-21.333333s21.333333 8.533333 21.333333 21.333333v85.333334c0 55.466667-46.933333 106.666667-106.666667 106.666666z" fill="#A495FC" p-id="2371"></path><path d="M512 554.666667c-12.8 0-29.866667-4.266667-42.666667-8.533334L17.066667 358.4c-12.8-4.266667-17.066667-17.066667-12.8-29.866667 4.266667-12.8 17.066667-17.066667 29.866666-12.8l456.533334 187.733334c17.066667 8.533333 34.133333 8.533333 51.2 0l448-187.733334c12.8-4.266667 21.333333 0 29.866666 12.8 4.266667 12.8 0 21.333333-12.8 29.866667l-448 187.733333c-21.333333 8.533333-34.133333 8.533333-46.933333 8.533334z" fill="#7162AD" p-id="2372"></path></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

@ -1,5 +0,0 @@
OpenMoji
https://openmoji.org
Licensed under Attribution-ShareAlike 4.0 International
https://creativecommons.org/licenses/by-sa/4.0/

@ -1,5 +0,0 @@
Bootstrap Icons
https://icons.getbootstrap.com
Licensed under MIT license
https://github.com/twbs/icons/blob/main/LICENSE.md

@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"/>
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"/>
</svg>

Before

Width:  |  Height:  |  Size: 352 B

@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z"/>
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z"/>
</svg>

Before

Width:  |  Height:  |  Size: 359 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8 19.9967V14.9967H10V19.9967H19V12.9967H5V19.9967H8ZM4 10.9967H20V7.9967H14V3.9967H10V7.9967H4V10.9967ZM3 20.9967V12.9967H2V6.9967C2 6.44442 2.44772 5.9967 3 5.9967H8V2.9967C8 2.44442 8.44772 1.9967 9 1.9967H15C15.5523 1.9967 16 2.44442 16 2.9967V5.9967H21C21.5523 5.9967 22 6.44442 22 6.9967V12.9967H21V20.9967C21 21.549 20.5523 21.9967 20 21.9967H4C3.44772 21.9967 3 21.549 3 20.9967Z"></path></svg>

Before

Width:  |  Height:  |  Size: 491 B

@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chat-square-quote" viewBox="0 0 16 16">
<path d="M14 1a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-2.5a2 2 0 0 0-1.6.8L8 14.333 6.1 11.8a2 2 0 0 0-1.6-.8H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h12zM2 0a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2.5a1 1 0 0 1 .8.4l1.9 2.533a1 1 0 0 0 1.6 0l1.9-2.533a1 1 0 0 1 .8-.4H14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
<path d="M7.066 4.76A1.665 1.665 0 0 0 4 5.668a1.667 1.667 0 0 0 2.561 1.406c-.131.389-.375.804-.777 1.22a.417.417 0 1 0 .6.58c1.486-1.54 1.293-3.214.682-4.112zm4 0A1.665 1.665 0 0 0 8 5.668a1.667 1.667 0 0 0 2.561 1.406c-.131.389-.375.804-.777 1.22a.417.417 0 1 0 .6.58c1.486-1.54 1.293-3.214.682-4.112z"/>
</svg>

Before

Width:  |  Height:  |  Size: 735 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-down" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
</svg>

Before

Width:  |  Height:  |  Size: 290 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-code" viewBox="0 0 16 16">
<path d="M5.854 4.854a.5.5 0 1 0-.708-.708l-3.5 3.5a.5.5 0 0 0 0 .708l3.5 3.5a.5.5 0 0 0 .708-.708L2.707 8l3.147-3.146zm4.292 0a.5.5 0 0 1 .708-.708l3.5 3.5a.5.5 0 0 1 0 .708l-3.5 3.5a.5.5 0 0 1-.708-.708L13.293 8l-3.147-3.146z"/>
</svg>

Before

Width:  |  Height:  |  Size: 362 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8.58564 8.85449L3.63589 13.8042L8.83021 18.9985L9.99985 18.9978V18.9966H11.1714L14.9496 15.2184L8.58564 8.85449ZM9.99985 7.44027L16.3638 13.8042L19.1922 10.9758L12.8283 4.61185L9.99985 7.44027ZM13.9999 18.9966H20.9999V20.9966H11.9999L8.00229 20.9991L1.51457 14.5113C1.12405 14.1208 1.12405 13.4877 1.51457 13.0971L12.1212 2.49053C12.5117 2.1 13.1449 2.1 13.5354 2.49053L21.3136 10.2687C21.7041 10.6592 21.7041 11.2924 21.3136 11.6829L13.9999 18.9966Z"></path></svg>

Before

Width:  |  Height:  |  Size: 555 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-break"><path d="M0 10.5a.5.5 0 0 1 .5-.5h15a.5.5 0 0 1 0 1H.5a.5.5 0 0 1-.5-.5zM12 0H4a2 2 0 0 0-2 2v7h1V2a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v7h1V2a2 2 0 0 0-2-2zm2 12h-1v2a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-2H2v2a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-2z"/></svg>

Before

Width:  |  Height:  |  Size: 348 B

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-journal-code" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8.646 5.646a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L10.293 8 8.646 6.354a.5.5 0 0 1 0-.708zm-1.292 0a.5.5 0 0 0-.708 0l-2 2a.5.5 0 0 0 0 .708l2 2a.5.5 0 0 0 .708-.708L5.707 8l1.647-1.646a.5.5 0 0 0 0-.708z"/>
<path d="M3 0h10a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-1h1v1a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v1H1V2a2 2 0 0 1 2-2z"/>
<path d="M1 5v-.5a.5.5 0 0 1 1 0V5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1zm0 3v-.5a.5.5 0 0 1 1 0V8h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1zm0 3v-.5a.5.5 0 0 1 1 0v.5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 772 B

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-journal-text" viewBox="0 0 16 16">
<path d="M5 10.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5z"/>
<path d="M3 0h10a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-1h1v1a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v1H1V2a2 2 0 0 1 2-2z"/>
<path d="M1 5v-.5a.5.5 0 0 1 1 0V5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1zm0 3v-.5a.5.5 0 0 1 1 0V8h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1zm0 3v-.5a.5.5 0 0 1 1 0v.5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 759 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-justify" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M2 12.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/>
</svg>

Before

Width:  |  Height:  |  Size: 414 B

@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-link" viewBox="0 0 16 16">
<path d="M6.354 5.5H4a3 3 0 0 0 0 6h3a3 3 0 0 0 2.83-4H9c-.086 0-.17.01-.25.031A2 2 0 0 1 7 10.5H4a2 2 0 1 1 0-4h1.535c.218-.376.495-.714.82-1z"/>
<path d="M9 5.5a3 3 0 0 0-2.83 4h1.098A2 2 0 0 1 9 6.5h3a2 2 0 1 1 0 4h-1.535a4.02 4.02 0 0 1-.82 1H12a3 3 0 1 0 0-6H9z"/>
</svg>

Before

Width:  |  Height:  |  Size: 403 B

@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-list-ol" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M5 11.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5z"/>
<path d="M1.713 11.865v-.474H2c.217 0 .363-.137.363-.317 0-.185-.158-.31-.361-.31-.223 0-.367.152-.373.31h-.59c.016-.467.373-.787.986-.787.588-.002.954.291.957.703a.595.595 0 0 1-.492.594v.033a.615.615 0 0 1 .569.631c.003.533-.502.8-1.051.8-.656 0-1-.37-1.008-.794h.582c.008.178.186.306.422.309.254 0 .424-.145.422-.35-.002-.195-.155-.348-.414-.348h-.3zm-.004-4.699h-.604v-.035c0-.408.295-.844.958-.844.583 0 .96.326.96.756 0 .389-.257.617-.476.848l-.537.572v.03h1.054V9H1.143v-.395l.957-.99c.138-.142.293-.304.293-.508 0-.18-.147-.32-.342-.32a.33.33 0 0 0-.342.338v.041zM2.564 5h-.635V2.924h-.031l-.598.42v-.567l.629-.443h.635V5z"/>
</svg>

Before

Width:  |  Height:  |  Size: 983 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-list-ul" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M5 11.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm-3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 447 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5 4.9967V7.9967H19V4.9967H5ZM4 2.9967H20C20.5523 2.9967 21 3.44442 21 3.9967V8.9967C21 9.54899 20.5523 9.9967 20 9.9967H4C3.44772 9.9967 3 9.54899 3 8.9967V3.9967C3 3.44442 3.44772 2.9967 4 2.9967ZM6 11.9967H12C12.5523 11.9967 13 12.4444 13 12.9967V15.9967H14V21.9967H10V15.9967H11V13.9967H5C4.44772 13.9967 4 13.549 4 12.9967V10.9967H6V11.9967ZM17.7322 13.7289L19.5 11.9612L21.2678 13.7289C22.2441 14.7052 22.2441 16.2882 21.2678 17.2645C20.2915 18.2408 18.7085 18.2408 17.7322 17.2645C16.7559 16.2882 16.7559 14.7052 17.7322 13.7289Z"></path></svg>

Before

Width:  |  Height:  |  Size: 640 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-fill" viewBox="0 0 16 16">
<path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"/>
</svg>

Before

Width:  |  Height:  |  Size: 589 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus"><path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/></svg>

Before

Width:  |  Height:  |  Size: 223 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-text-center" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4 12.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/>
</svg>

Before

Width:  |  Height:  |  Size: 416 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-text-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M2 12.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/>
</svg>

Before

Width:  |  Height:  |  Size: 412 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-text-paragraph" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M2 12.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm4-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5z"/>
</svg>

Before

Width:  |  Height:  |  Size: 417 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-text-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6 12.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-4-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm4-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-4-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/>
</svg>

Before

Width:  |  Height:  |  Size: 415 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-bold" viewBox="0 0 16 16">
<path d="M8.21 13c2.106 0 3.412-1.087 3.412-2.823 0-1.306-.984-2.283-2.324-2.386v-.055a2.176 2.176 0 0 0 1.852-2.14c0-1.51-1.162-2.46-3.014-2.46H3.843V13H8.21zM5.908 4.674h1.696c.963 0 1.517.451 1.517 1.244 0 .834-.629 1.32-1.73 1.32H5.908V4.673zm0 6.788V8.598h1.73c1.217 0 1.88.492 1.88 1.415 0 .943-.643 1.449-1.832 1.449H5.907z"/>
</svg>

Before

Width:  |  Height:  |  Size: 470 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-h1" viewBox="0 0 16 16">
<path d="M8.637 13V3.669H7.379V7.62H2.758V3.67H1.5V13h1.258V8.728h4.62V13h1.259zm5.329 0V3.669h-1.244L10.5 5.316v1.265l2.16-1.565h.062V13h1.244z"/>
</svg>

Before

Width:  |  Height:  |  Size: 282 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-h2" viewBox="0 0 16 16">
<path d="M7.638 13V3.669H6.38V7.62H1.759V3.67H.5V13h1.258V8.728h4.62V13h1.259zm3.022-6.733v-.048c0-.889.63-1.668 1.716-1.668.957 0 1.675.608 1.675 1.572 0 .855-.554 1.504-1.067 2.085l-3.513 3.999V13H15.5v-1.094h-4.245v-.075l2.481-2.844c.875-.998 1.586-1.784 1.586-2.953 0-1.463-1.155-2.556-2.919-2.556-1.941 0-2.966 1.326-2.966 2.74v.049h1.223z"/>
</svg>

Before

Width:  |  Height:  |  Size: 482 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-h3" viewBox="0 0 16 16">
<path d="M7.637 13V3.669H6.379V7.62H1.758V3.67H.5V13h1.258V8.728h4.62V13h1.259zm3.625-4.272h1.018c1.142 0 1.935.67 1.949 1.674.013 1.005-.78 1.737-2.01 1.73-1.08-.007-1.853-.588-1.935-1.32H9.108c.069 1.327 1.224 2.386 3.083 2.386 1.935 0 3.343-1.155 3.309-2.789-.027-1.51-1.251-2.16-2.037-2.249v-.068c.704-.123 1.764-.91 1.723-2.229-.035-1.353-1.176-2.4-2.954-2.385-1.873.006-2.857 1.162-2.898 2.358h1.196c.062-.69.711-1.299 1.696-1.299.998 0 1.695.622 1.695 1.525.007.922-.718 1.592-1.695 1.592h-.964v1.074z"/>
</svg>

Before

Width:  |  Height:  |  Size: 646 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-italic" viewBox="0 0 16 16">
<path d="M7.991 11.674 9.53 4.455c.123-.595.246-.71 1.347-.807l.11-.52H7.211l-.11.52c1.06.096 1.128.212 1.005.807L6.57 11.674c-.123.595-.246.71-1.346.806l-.11.52h3.774l.11-.52c-1.06-.095-1.129-.211-1.006-.806z"/>
</svg>

Before

Width:  |  Height:  |  Size: 351 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-strikethrough" viewBox="0 0 16 16">
<path d="M6.333 5.686c0 .31.083.581.27.814H5.166a2.776 2.776 0 0 1-.099-.76c0-1.627 1.436-2.768 3.48-2.768 1.969 0 3.39 1.175 3.445 2.85h-1.23c-.11-1.08-.964-1.743-2.25-1.743-1.23 0-2.18.602-2.18 1.607zm2.194 7.478c-2.153 0-3.589-1.107-3.705-2.81h1.23c.144 1.06 1.129 1.703 2.544 1.703 1.34 0 2.31-.705 2.31-1.675 0-.827-.547-1.374-1.914-1.675L8.046 8.5H1v-1h14v1h-3.504c.468.437.675.994.675 1.697 0 1.826-1.436 2.967-3.644 2.967z"/>
</svg>

Before

Width:  |  Height:  |  Size: 579 B

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-underline" viewBox="0 0 16 16">
<path d="M5.313 3.136h-1.23V9.54c0 2.105 1.47 3.623 3.917 3.623s3.917-1.518 3.917-3.623V3.136h-1.23v6.323c0 1.49-.978 2.57-2.687 2.57-1.709 0-2.687-1.08-2.687-2.57V3.136zM12.5 15h-9v-1h9v1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 334 B

@ -1 +0,0 @@
<svg class="prefix__icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M513.554 814.327h-.124a307.518 307.518 0 01-156.195-42.549l-11.211-6.638-116.136 30.331 31.002-112.71-7.291-11.547a303.616 303.616 0 01-46.928-162.533c.071-168.395 137.728-305.382 307.006-305.382a305.54 305.54 0 01216.947 89.565 302.822 302.822 0 0189.794 216.064c-.07 168.395-137.71 305.4-306.864 305.4zM774.727 249.01c-69.72-69.456-162.446-107.75-261.173-107.768-203.53 0-369.135 164.83-369.223 367.405a365.462 365.462 0 0049.293 183.702l-52.383 190.41 195.726-51.093a370.353 370.353 0 00176.428 44.72h.159c203.476 0 369.116-164.846 369.205-367.44.035-98.162-38.33-190.499-108.05-259.954z" fill="#25D366"/><path d="M379.339 686.963c-4.184-2.437-8.263-4.555-8.263-17.814.106-65.713.212-217.689 0-273.885-.106-35.399-4.837-58.297 26.43-58.297 84.568 0 208.155-15.678 236.933 53.53 29.025 69.968-17.938 103.883-28.249 121.891 70.48 19.51 74.346 175.952-76.305 175.952-32.239 0-77.577.106-130.119.212-12.359 0-17.832 0-20.427-1.59zm65.236-57.344h76.5c32.574-.106 61.581-15.042 60.822-47.069-.53-30.102-20.833-40.06-49.1-42.814-26.764.318-57.484.318-88.222.318v89.565zm0-150.07c56.62-.758 78.442 2.208 109.391-5.42 21.275-11.864 30.508-56.072.106-71.008-21.062-10.4-83.597-6.886-109.497-5.827v82.238z" fill="#25D366"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

@ -1 +0,0 @@
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M16.065 29.045h-.005a13.27 13.27 0 01-6.74-1.836l-.484-.287-5.012 1.31 1.338-4.865-.315-.498a13.102 13.102 0 01-2.025-7.014C2.825 8.588 8.766 2.676 16.071 2.676a13.185 13.185 0 019.362 3.866 13.068 13.068 0 013.875 9.324c-.003 7.267-5.943 13.18-13.243 13.18zM27.336 4.65A15.868 15.868 0 0016.066 0C7.281-.002.135 7.111.131 15.853a15.771 15.771 0 002.127 7.927l-2.26 8.217 8.446-2.205a15.982 15.982 0 007.614 1.93h.006c8.781 0 15.93-7.114 15.933-15.856a15.724 15.724 0 00-4.663-11.219z" fill="#25D366"/><path d="M10.273 23.549c-.18-.105-.356-.197-.356-.769.004-2.836.009-9.394 0-11.82-.005-1.527-.209-2.515 1.14-2.515 3.65 0 8.983-.677 10.225 2.31 1.253 3.02-.774 4.483-1.219 5.26 3.042.842 3.208 7.593-3.293 7.593-1.391 0-3.348.005-5.615.01-.533 0-.77 0-.882-.07zm2.816-2.475h3.301c1.406-.004 2.657-.649 2.625-2.031-.023-1.3-.9-1.729-2.12-1.848-1.154.014-2.48.014-3.806.014v3.865zm0-6.476c2.443-.033 3.385.095 4.72-.234.918-.512 1.317-2.42.005-3.064-.909-.45-3.608-.297-4.725-.252v3.55z" fill="#25D366"/></svg>

@ -1,33 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(0, 0)">
<g transform="matrix(1.3809472322464, 0, 0, 1.3809472322464, 0, 0)">
<g transform="translate(0, 0)">
<g transform="matrix(0.827589750289917, 0, 0, 0.827589750289917, 0, 0)">
<g class="prefix__icon" transform="translate(-5.3347, -5.3347)">
<g transform="matrix(1.20832681655884, 0, 0, 1.20832681655884, 0, 0)">
<g transform="matrix(0.03125, 0, 0, 0.03125, 0, 0)">
<path d="M513.554, 814.327L513.43, 814.327A307.518 307.518 0 0 1 357.235, 771.778L346.024, 765.14L229.888, 795.471L260.89, 682.761L253.599, 671.214A303.616 303.616 0 0 1 206.671, 508.681C206.742, 340.286 344.399, 203.299 513.677, 203.299A305.54 305.54 0 0 1 730.624, 292.864A302.822 302.822 0 0 1 820.418, 508.928C820.348, 677.323 682.708, 814.328 513.554, 814.328zM774.727, 249.01C705.007, 179.554 612.281, 141.26 513.554, 141.242C310.024, 141.242 144.419, 306.072 144.331, 508.647A365.462 365.462 0 0 0 193.624, 692.349L141.241, 882.759L336.967, 831.666A370.353 370.353 0 0 0 513.395, 876.386L513.554, 876.386C717.03, 876.386 882.67, 711.54 882.759, 508.946C882.794, 410.784 844.429, 318.447 774.709, 248.992z" fill="#25D366" />
</g>
</g>
</g>
</g>
</g>
</g>
</g>
<g transform="translate(-2.67028807954262E-07, -8.39233399219097E-07)">
<g transform="matrix(1.3809472322464, 0, 0, 1.3809472322464, 0, 0)">
<g transform="translate(1.33514403977131E-07, 1.71661376668908E-07)">
<g transform="matrix(0.827589750289917, 0, 0, 0.827589750289917, 0, 0)">
<g class="prefix__icon" transform="translate(-5.33470045776367, -5.33470049591064)">
<g transform="matrix(1.20832681655884, 0, 0, 1.20832681655884, 0, 0)">
<g transform="matrix(0.03125, 0, 0, 0.03125, 0, 0)">
<path d="M379.339, 686.963C375.155, 684.526 371.076, 682.408 371.076, 669.149C371.182, 603.436 371.288, 451.46 371.076, 395.264C370.97, 359.865 366.239, 336.967 397.506, 336.967C482.074, 336.967 605.661, 321.289 634.439, 390.497C663.464, 460.465 616.501, 494.38 606.19, 512.388C676.67, 531.898 680.536, 688.34 529.885, 688.34C497.646, 688.34 452.308, 688.446 399.766, 688.552C387.407, 688.552 381.934, 688.552 379.339, 686.962zM444.575, 629.619L521.075, 629.619C553.649, 629.513 582.656, 614.577 581.897, 582.55C581.367, 552.448 561.064, 542.49 532.797, 539.736C506.033, 540.054 475.313, 540.054 444.575, 540.054L444.575, 629.619zM444.575, 479.549C501.195, 478.791 523.017, 481.757 553.966, 474.129C575.241, 462.265 584.474, 418.057 554.072, 403.121C533.01, 392.721 470.475, 396.235 444.575, 397.294L444.575, 479.532z" fill="#25D366" />
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1,39 @@
function openWebSocket() {
console.log('open websocket');
}
self.addEventListener('install', function(event) {
self.skipWaiting();
console.log('Installed', event);
});
self.addEventListener('activate', (event) => {
// event.waitUntil(self.clients.claim());
event.waitUntil(openWebSocket());
self.clients.claim();
});
self.addEventListener('push', (event) => {
const data = event.data.json();
const title = data.title || 'New Message';
const options = {
body: data.body || 'You have a new message',
icon: 'path/to/icon.png',
badge: 'path/to/badge.png',
vibrate: [200, 100, 200], // 振动
// Other notification options
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});
// Send a message to all clients every minute
setInterval(function() {
self.clients.matchAll().then(function(clients) {
clients.forEach(function(client) {
client.postMessage('Service worker is still running');
});
});
}, 60000); // 60000 ms = 1 minute

@ -9,14 +9,6 @@ export const fetchSalesAgent = async (q) => {
return errcode !== 0 ? [] : result.map((ele) => ({ ...ele, label: ele.cn_name, value: ele.op_id }));
};
/**
* 绑定钉钉的顾问列表
*/
export const fetchSalesAgentWithDD = async (q) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/opi_with_dingtalk`, { q });
return errcode !== 0 ? [] : result.map((ele) => ({ ...ele, label: ele.cn_name, value: ele.op_id, key: ele.op_id }));
};
/**
* 客人列表
*/

@ -1,161 +1,55 @@
import { groupBy, isNotEmpty, pick, sortArrayByOrder, sortBy } from '@/utils/commons';
import { fetchJSON, postJSON, postForm } from '@/utils/request'
import { parseRenderMessageList } from '@/channel/bubbleMsgUtils';
import { groupBy, pick, sortArrayByOrder } from '@/utils/utils';
import { fetchJSON, postJSON } from '@/utils/request'
import { parseRenderMessageList } from '@/lib/msgUtils';
import { API_HOST } from '@/config';
import { isEmpty } from '@/utils/commons';
import dayjs from 'dayjs';
/**
* @param {object} params { waba }
*/
export const fetchTemplates = async (params) => {
const data = await fetchJSON(`${API_HOST}/listtemplates`, params);
const topName = [
'agent_intro_with_update_v1',
'online_inquiry_received',
'say_hello_again',
'order_updated_specialist_assigned_christy',
'order_resumed_specialist_followup_schedule_sharon',
'travel_service_update_v2',
'travel_service_update_v1',
'order_updated_specialist_assigned_sharon',
'first_message_for_not_reply',
// 'free_style_3',
// 'free_style_4',
];
// shouwcase
const scNames = ['trip_planner_showcase', 'showcase_different', 'order_status_updated'];
// 客运
const crNames = [
'notification_of_next_trip_planning',
// 'notification_of_following_up_by_cr_v3',
'notification_of_one_day_before_ending_the_trip_by_cr_v2',
'one_day_after_payment_by_yuni',
'notification_of_status_changed',
'notification_of_one_day_before_ending_the_trip_by_cr','one_day_after_payment_by_customer_relations',
'one_day_before_ending_the_trip_contacted_by_yuni','one_day_before_ending_the_trip_first_time_by_yuni',
'post_booking_confirmation_welcome',
];
const crNamesOmit = [
'birthday_greetings_by_marketing','one_day_before_ending_the_trip_by_marketing',
'introduce_the_voucher_one_day_before_ending_the_trip_by_marketing',
'birthday_greetings_by_customer_relations_0',
'post_trip_voucher_issued',
'account_updated_order_ref',
'post_trip_account_updated_from_cr',
'post_trip_account_updated',
'account_update_birthday',
'post_trip_birthday_reward',
'birthday_greetings_by_customer_relations_2',
'birthday_greetings_by_customer_relations_1',
'notification_of_account_updated_by_cr',
'birthday_greetings_by_customer_relations',
'one_day_before_ending_the_trip_by_customer_relations',
]
export const fetchTemplates = async () => {
const data = await fetchJSON(`${API_HOST}/listtemplates`);
const canUseTemplates = (data?.result?.items || [])
.filter((_t) => _t.status === 'APPROVED' && !['say_hello_from_trip_advisor', 'free_style_7', 'free_style_1', 'free_style_2'].includes(_t.name))
.map((ele, i) => ({
...ele,
components_origin: ele.components,
components: groupBy(ele.components, (_c) => _c.type.toLowerCase()),
key: ele.name,
// displayName: ele.name.startsWith('order_updated') ? templatesDisplayNameMap['order_updated']+`_${i}` : templatesDisplayNameMap?.[ele.name] || ele.name,
displayName: templatesDisplayNameMap?.[ele.name] || (ele.name.startsWith('order_updated') ? templatesDisplayNameMap['order_updated']+`_${i}` : ele.name),
displayLanguage: crNamesOmit.includes(ele.name) ? '客运-' : (crNames.includes(ele.name) || ele.name.includes('by_cr')) ? ele.language + '-客运' : scNames.includes(ele.name) ? ele.language + '-示例' : ele.language,
}))
const top2Name = topName.concat(canUseTemplates.filter(_t => _t.name.startsWith('order_updated')).map(_tem => _tem.name));
const top = sortArrayByOrder( canUseTemplates.filter((_t) => top2Name.includes(_t.name)), 'name', topName);
const second = canUseTemplates.filter(_t => _t.name.includes('free_style'));
const secondS = second.sort(sortBy('name'));
const raw = canUseTemplates.filter((_t) => !top2Name.includes(_t.name) && !_t.name.includes('free_style'));
// 剩下的排序
const rawS = sortArrayByOrder(raw, 'name', [...crNames, ...scNames, ...crNamesOmit ]);
return [...top, ...secondS, ...rawS];
};
/**
* 上面的模板名称bak
* order_updated_specialist_assigned_sharon : free_style_7
* order_updated_specialist_assigned_christy : free_style_1
* online_inquiry_received: say_hello_from_trip_advisor
* order_resumed_specialist_followup_schedule_sharon: free_style_2
*/
const templatesDisplayNameMap = {
'order_updated_specialist_assigned_sharon': 'specialist_followup',
'order_updated_specialist_assigned_christy': 'specialist_followup_1',
'online_inquiry_received': 'online_inquiry_received/say_hello',
'order_resumed_specialist_followup_schedule_sharon': 'order_resumed/specialist_followup',
'order_updated': 'specialist_followup',
'agent_intro_with_update_v1': 'quick_update_v1',
.filter((_t) => _t.status !== 'REJECTED')
.map((ele) => ({ ...ele, components_origin: ele.components, components: groupBy(ele.components, (_c) => _c.type.toLowerCase()) }));
const topName = ['say_hello_from_trip_advisor', 'free_style_7', 'free_style_2', 'free_style_1', 'free_style_3', 'free_style_4'];
const top = sortArrayByOrder( canUseTemplates.filter((_t) => topName.includes(_t.name)), 'name', topName);
const raw = canUseTemplates.filter((_t) => !topName.includes(_t.name));
return [...top, ...raw];
};
export const CONVERSATION_PAGE_SIZE = 100;
/**
*
* @param {object} params { opisn }
*/
export const fetchConversationsList = async (params) => {
const defaultParams = {
opisn: '',
pagesize: CONVERSATION_PAGE_SIZE,
lastpagetime: '',
tags: '',
olabel: '',
keyword: '',
ostate: '',
intour: '',
session_enable: 1,
lastactivetime: '',
top_state: '',
}
const combinedFilterStr = Object.values(pick(params, ['keyword', 'tags', 'olabel', 'intour', 'ostate'])).join('')
if (isNotEmpty(combinedFilterStr) || params.session_enable === 0) {
params.lastactivetime = '';
}
const { errcode, result: data } = await fetchJSON(`${API_HOST}/getconversations`, { ...defaultParams, ...params })
const { errcode, result: data } = await fetchJSON(`${API_HOST}/getconversations`, params);
if (errcode !== 0) return [];
const list = (data || []).map((ele) => ({
...ele,
customer_name: `${ele.whatsapp_name || ''}`.trim(),
whatsapp_name: `${ele.whatsapp_name || ''}`.trim(),
show_default: ele.conversation_memo || ele.whatsapp_name || ele?.channels?.whatsapp_phone_number || ele?.channels?.phone_number || ele?.channels?.email || '',
// coli_id: ele.COLI_ID,
top_state: ele.top_state || 0,
}))
const list = (data || []).map((ele) => ({ ...ele, customer_name: `${ele.whatsapp_name || ''}`.trim(), whatsapp_name: `${ele.whatsapp_name || ''}`.trim() }));
return list;
};
/**
*
* @param {object} params { opisn, whatsappid, colisn, email }
* @param {object} params { opisn, whatsappid, colisn }
* * opisn, colisn : 用于查询
* * whatsappid, email: 用于创建会话
* * whatsappid: 用于创建会话
*/
export const fetchOrderConversationsList = async (params) => {
const { errcode, result: data } = await fetchJSON(`${API_HOST}/getorderconversation`, params);
if (errcode !== 0) return [];
const list = data.map((ele) => ({
...ele,
customer_name: `${ele.whatsapp_name || ''}`.trim(),
whatsapp_name: `${ele.whatsapp_name || ''}`.trim(),
show_default: ele.conversation_memo || ele.whatsapp_name || ele?.channels?.whatsapp_phone_number || ele?.channels?.phone_number || ele?.channels?.email || '',
}))
const list = data.map((ele) => ({ ...ele, customer_name: `${ele.whatsapp_name || ''}`.trim(), whatsapp_name: `${ele.whatsapp_name || ''}`.trim() }));
return list;
};
export const MESSAGE_PAGE_SIZE = 50;
/**
*
* @param {object} params { coli_sn, opisn, whatsappid, conversationid, lasttime, pagesize }
* @param {object} params { opisn, whatsappid, lasttime, pagesize }
*/
export const fetchMessages = async (params) => {
const defaultParams = {
// opisn: '',
// whatsappid: '',
coli_sn: '',
conversationid: '',
opisn: '',
whatsappid: '',
lasttime: '',
pagesize: MESSAGE_PAGE_SIZE,
};
@ -175,63 +69,19 @@ export const fetchConversationItemClose = async (body) => {
/**
* @param {object} body { phone_number, name }
*/
export const postNewOrEditConversationItem = async (body) => {
body.whatsapp_phone_number = `${body.whatsapp_phone_number || ''}`.trim();
const formData = new FormData();
Object.keys(body).forEach(function (key) {
formData.append(key, body[key]);
});
const { errcode, result } = await postForm(`${API_HOST}/new_conversation`, formData);
if (errcode !== 0) {
return {};
}
const resultItem = result?.[0] || {};
return {
...resultItem,
customer_name: `${resultItem.whatsapp_name || ''}`.trim(),
whatsapp_name: `${resultItem.whatsapp_name || ''}`.trim(),
// channels: {},
// tags: [],
// last_message: {},
top_state: 0,
// conversation_memo: resultItem.session_memo,
};
};
/**
* @param {object} params { conversationid, coli_sn }
*/
export const postEditConversationItemColiAction = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/update_conversation_orderid`, params);
export const postNewConversationItem = async (body) => {
const { errcode, result } = await postJSON(`${API_HOST}/newconversation`, body);
return errcode !== 0 ? {} : result;
};
/**
* @param {object} params { opisn, conversationid }
* @param {object} params { opisn, whatsappid }
*/
export const fetchCleanUnreadMsgCount = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/clean_unread_msg_count`, params);
return errcode !== 0 ? {} : result;
};
/**
* 标记未未读
* @param {object} body conversationItem: { sn, ... }
*/
export const UNREAD_MARK = 999;
export const fetchConversationItemUnread = async (body) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/set_state_unread`, body);
return errcode !== 0 ? {} : result;
};
/**
* 设置置顶
* @param {object} body { conversationid, top_state }
*/
export const fetchConversationItemTop = async (body) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/set_top_conversation`, body);
return errcode !== 0 ? {} : result;
};
/**
* ------------------------------------------------------------------------------------------------
* 历史记录
@ -247,16 +97,12 @@ export const fetchConversationsSearch = async (params) => {
? []
: (data || []).map((ele) => ({
...ele,
sn: ele.conversationid,
customer_name: `${ele.whatsapp_name || ''}`.trim(),
whatsapp_name: `${ele.whatsapp_name || ''}`.trim(),
opi_sn: ele.OPI_SN || ele.opi_sn || 0,
OPI_Name: `${ele.OPI_Name || ele.opi_name || ''}`.trim(),
opi_name: `${ele.OPI_Name || ele.opi_name || ''}`.trim(),
dateText: dayjs((ele.lasttime)).format('MM-DD HH:mm'),
dateText: dayjs((ele.last_received_time || ele.last_send_time)).format('MM-DD HH:mm'),
matchMsgList: parseRenderMessageList((ele.msglist_AsJOSN || [])), // .reverse()),
coli_id: '',
show_default: ele.session_memo || ele.whatsapp_name || ele?.whatsapp_phone_number || ele?.guest_email || '',
}));
return list;
};
@ -267,88 +113,17 @@ export const fetchConversationsSearch = async (params) => {
*/
export const fetchMessagesHistory = async (params) => {
const defaultParams = {
// opisn: '',
// whatsappid: '',
conversationid: '',
opisn: '',
whatsappid: '',
lasttime: '2024-01-01T00:00:00',
pagesize: MESSAGE_PAGE_SIZE,
pagedir: 'next',
};
const _params = pick(params, Object.keys(defaultParams));
if (isEmpty(_params.conversationid)) {
if (isEmpty(_params.opisn) || isEmpty(_params.whatsappid)) {
return [];
}
const { errcode, result } = await fetchJSON(`${API_HOST}/get_item_messages`, {...defaultParams, ..._params});
const data = errcode !== 0 ? [] : result; // _params.pagedir === 'next' ? result.reverse() : result;
return parseRenderMessageList(data);
}
/**
* @param {object} params { opisn, phone_number_from, phone_number_mergeto }
*/
export const fetchConversationMerge = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/merge_session`, params);
return errcode !== 0 ? {} : result;
};
/**
* ------------------------------------------------------------------------------------------------
* 未分配
*/
export const fetchConversationsUnassigned = async (params) => {
const { errcode, result: data } = await fetchJSON(`${API_HOST}/unassigned-conversation`, params);
const list =
errcode !== 0
? []
: (data || []).map((ele) => ({
...ele,
customer_name: `${ele.whatsapp_name || ''}`.trim(),
whatsapp_name: `${ele.whatsapp_name || ''}`.trim(),
opi_sn: ele.OPI_SN || ele.opi_sn || 0,
OPI_Name: `${ele.OPI_Name || ele.opi_name || ''}`.trim(),
dateText: dayjs((ele.last_received_time)).format('MM-DD HH:mm'),
}));
return list;
};
/**
* @param {object} params { opi_sn, conversationid }
*/
export const postAssignConversation = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/assign_conversation`, params);
return errcode !== 0 ? {} : result;
}
/**
* ------------------------------------------------------------------------------------------------
*
*/
/**
* 顾问的自定义标签
* @param {object} params { opisn, }
*/
export const fetchTags = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/get_opi_tags`, params);
return errcode !== 0 ? [] : result.map(ele => ({ label: ele.tag_label, key: ele.tag_key, value: ele.tag_key, }));
}
/**
* 会话设置标签
* @param {object} body { opisn, conversationid, tag_label, tag_id }
*/
export const postConversationTags = async (body) => {
const formData = new FormData();
Object.keys(body).forEach(function (key) {
formData.append(key, body[key]);
});
const { errcode, result } = await postForm(`${API_HOST}/set_conversation_tags_add`, formData);
return errcode !== 0 ? {} : result[0];
}
/**
* 会话删除标签
* @param {object} params { opisn, conversationid, tag_id }
*/
export const deleteConversationTags = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/set_conversation_tags_del`, params);
return errcode !== 0 ? {} : result;
}

@ -1,491 +0,0 @@
import { fetchJSON, postForm, postJSON } from '@/utils/request';
import { API_HOST, API_HOST_V3, DATE_FORMAT, DATEEND_FORMAT, DATETIME_FORMAT, EMAIL_HOST, EMAIL_HOST_v3 } from '@/config';
import { buildTree, groupBy, isEmpty, objectMapper, omitEmpty, uniqWith } from '@/utils/commons';
import { readIndexDB, writeIndexDB } from '@/utils/indexedDB';
import dayjs from 'dayjs';
import { internalEventEmitter } from '@/utils/EventEmitterService';
export const parseHTMLString = (html, needText = false) => {
const parser = new DOMParser()
const doc = parser.parseFromString(html, 'text/html')
let bodyContent = doc.body.innerHTML
// bodyContent = bodyContent.replace(/<img/g, '<img onerror="this.onerror=null;this.src=\'https://hiana-crm.oss-accelerate.aliyuncs.com/WAMedia/afe412d4-3acf-4e79-a623-048aeb4d696a.png\';"')
const bodyText = (doc.body.innerText);
return needText ? { html, bodyContent, bodyText } : bodyContent
}
export const EMAIL_CHANNEL_NAME = 'mailbox_changes';
let emailChangesChannel = null;
export function getEmailChangesChannel() {
if (!emailChangesChannel) {
emailChangesChannel = new BroadcastChannel(EMAIL_CHANNEL_NAME)
}
return emailChangesChannel
}
// 通知邮件列表数据更新
const notifyMailboxUpdate = (payload) => {
const notificationPayload = payload
// - 多个tab
const channel = getEmailChangesChannel()
channel.postMessage(notificationPayload)
// - 当前tab
internalEventEmitter.emit(EMAIL_CHANNEL_NAME, notificationPayload)
}
/**
* 获取顾问签名
* @param {object} { opi_sn }
*/
export const getSalesSignatureAction = async (params) => {
try {
const { result } = await fetchJSON(`${EMAIL_HOST}/email_sign`, params)
const { SignContent: html } = result
const bodyContent = parseHTMLString(html);
return bodyContent;
} catch (error) {
return '';
}
};
/**
* 发送邮件
*/
export const postSendEmail = async (body) => {
const { attaList=[], atta, content, ...bodyData } = body;
bodyData.ordertype = 227001;
const formData = new FormData();
Object.keys(bodyData).forEach(function (key) {
formData.append(key, bodyData[key]);
});
attaList.forEach(function (item) {
formData.append('attachment', item);
});
const { result } = await postForm(`${EMAIL_HOST}/sendmail`, formData);
return result;
};
/**
* 重发邮件
* @param {object} { mai_sn }
*/
export const postResendEmailAction = async (body) => {
const { attaList, atta, content, ...bodyData } = body;
const formData = new FormData();
Object.keys(bodyData).forEach(function (key) {
formData.append(key, bodyData[key]);
});
return await postForm(`${EMAIL_HOST}/email_resend`, formData);
};
const encodeEmailInfo = (info) => {
const encodeQuote = (str = '') => str.replace(/"/g, ''); //.replace(/</g,'&lt;').replace(/>/g,'&gt;')
const CSsClean = encodeQuote(info.MAI_CS).includes(',') ? encodeQuote(info.MAI_CS).split(',') : encodeQuote(info.MAI_CS).split(';');
const tosClean = (encodeQuote(info.MAI_To).includes(',') ? encodeQuote(info.MAI_To).split(',') : encodeQuote(info.MAI_To).split(';')).concat(CSsClean).filter(s => s);
const replyTo = info.MAI_Direction === 1 ? info.MAI_To : info.MAI_From;
const replyToAll = (tosClean.length > 1) ?
(info.MAI_Direction === 1 ? tosClean.join(',') : [...tosClean, info.MAI_From].join(','))
: (info.MAI_Direction === 1 ? info.MAI_To : info.MAI_From)
return {
...info,
MAI_From: encodeQuote(info.MAI_From),
MAI_To: encodeQuote(info.MAI_To),
tos: [...new Set(tosClean)],
replyToAll,
replyTo,
}
};
/**
* 邮件详情
* @param {object} { mai_sn }
*/
export const getEmailDetailAction = async (params) => {
// const cacheKey = params.mai_sn;
// const readCache = await readIndexDB(cacheKey, 'mailinfo', 'mailbox');
// if (!isEmpty(readCache)) { // todo: 除了草稿
// return readCache.data;
// }
const { result } = await fetchJSON(`${EMAIL_HOST}/getmail`, params);
let mailType = result.MailInfo?.[0]?.MAI_ContentType || '';
mailType = mailType === '' && (result.MailContent||'').includes('<html') ? 'text/html' : mailType;
const emailInfo = encodeEmailInfo(result.MailInfo?.[0] || {});
const isFromHub = emailInfo.MAI_From.includes('info@chinahighlights.net');
const delLinefeed = mailType === 'text/html' ? (result.MailContent||'').includes('<html') ? true : false : true;
const cleanContent = (result.MailContent || '').replace(/\r\n/g, delLinefeed ? '' : (isFromHub ? '<br>' : ''));
const { html, bodyContent, bodyText } = mailType === 'text/html' ? parseHTMLString(cleanContent, true) : { html: '', bodyContent: '', bodyText: '' };
const attachments = (isEmpty(result?.AttachList) ? [] : result.AttachList).filter(ele => isEmpty(ele.ATI_ContentID) || ele.ATI_ContentID == '0');
const insideAttachments = (isEmpty(result?.AttachList) ? [] : result.AttachList).filter(ele => !isEmpty(ele.ATI_ContentID) && ele.ATI_ContentID != '0');
const ret = {
info: { ...encodeEmailInfo(result.MailInfo?.[0] || {}), mailType },
content: mailType === 'text/html' ? html : result.MailContent || '',
abstract: bodyText || result.MailContent || '',
attachments,
insideAttachments,
AttachList: isEmpty(result?.AttachList) ? [] : result.AttachList,
}
// writeIndexDB([{key: cacheKey, data: ret}], 'mailinfo', 'mailbox')
return ret;
}
export const getEmailOrderAction = async ({ colisn }) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/getorderinfo`, { colisn })
return errcode === 0 ? { ...result[0], customerDetail: result[0].contact[0] } : {}
}
/**
* 主动收邮件, 单个账户
* @param {object} { opi_sn, }
*/
export const getEmailFetchAction = async (params) => {
const { opi_sn, } = params
const { result } = await fetchJSON(`${EMAIL_HOST}/email_fetch`, {
opi_sn,
})
return result
};
/**
* 报价信邮件草稿
* @param {object} { sfi_sn, coli_sn, lgc }
*/
export const getEmailQuotationDraftAction = async (params) => {
const { result } = await fetchJSON(`${EMAIL_HOST}/QuotationLetter`, params)
return { subject: (result.Subject || ''), content: parseHTMLString((result.MailContent || '').replace(/\r\n/g, '')) }
}
/**
* 单个邮件绑定订单
* @param {object} { conversationid, mai_sn, coli_sn, coli_id, sourcetype }
*/
export const fetchEmailBindOrderAction = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/mailinfo_bindorder`, params)
return errcode === 0 ? true : false;
}
const todoTypes = {
// 1新订单2WhatsApp未读消息3需一催4需二催5需三催6未处理邮件入境提醒coli_ordertype=7余款提醒coli_ordertype=8
1: '新订单',
2: '未读WhatsApp',
3: '一催',
4: '二催',
5: '三催',
6: '老邮件',
7: '入境提醒',
8: '余款提醒',
}
/**
* 顾问的邮箱目录
* @param {object} params { opi_sn, year, by_start_date, by_success, important, if_want_book, if_thinking }
* @param {boolean} retOrder 是否直接返回订单列表 -- 忽略
*/
export const getEmailDirAction = async (params = { opi_sn: '' }, retOrder=false) => {
const defaultParams = { opi_sn: 0, year: dayjs().year(), by_start_date: -1, by_success: -1, important: -1, if_want_book: -1, if_thinking: -1 }
const { errcode, result } = await fetchJSON(`${API_HOST_V3}/email_dir`, { ...defaultParams, ...params })
const mailboxSort = result //.sort(sortBy('MDR_Order'));
let tree = buildTree(mailboxSort, { key: 'VKey', parent: 'VParent', name: 'VName', iconIndex: 'ImageIndex', rootKeys: [1], ignoreKeys: [-227001, -227002] })
tree = tree.filter((ele) => ele.key !== 1)
const retTree = errcode === 0 ? tree : [];
const orderList = groupBy(result, row => `${row.IsTrue}`)?.['0'] || [];
return retOrder !== false ? orderList : { [`${params.opi_sn}`]: retTree }
};
export const getMailboxCountAction = async (params = { opi_sn: '' }, update = true) => {
const defaultParams = {
opi_sn: 0,
// date1: dayjs().subtract(1, 'year').startOf('year').format(DATE_FORMAT),
date1: dayjs().subtract(180, 'days').format(DATE_FORMAT),
date2: dayjs().format(DATEEND_FORMAT)
}
const { errcode, result } = await fetchJSON(`${API_HOST_V3}/dir_count`, {...defaultParams, ...params})
const ret = errcode !== 0 ? { [`${params.opi_sn}`]: {} } : { [`${params.opi_sn}`]: result }
// 更新数量
if (update !== false) {
const readCacheDir = (await readIndexDB(Number(params.opi_sn), 'dirs', 'mailbox')) || {};
const mailboxDir = isEmpty(readCacheDir) ? [] : readCacheDir.tree.filter(node => node?._raw?.IsTrue === 1);
const _MapDir = new Map(mailboxDir.map((obj) => [obj.key, obj]))
Object.keys(result).map(dirKey => {
_MapDir.set(Number(dirKey), {..._MapDir.get(Number(dirKey)), count: result[dirKey]});
})
const _newToUpdate = Array.from(_MapDir.values());
const _MapRoot = new Map((readCacheDir?.tree || []).map((obj) => [obj.key, obj]))
_newToUpdate.forEach((row) => {
_MapRoot.set(row.key, row)
})
const _newRoot = Array.from(_MapRoot.values())
writeIndexDB([{ ...readCacheDir, key: Number(params.opi_sn), tree: _newRoot }], 'dirs', 'mailbox')
notifyMailboxUpdate({ type: 'dirs', key: Number(params.opi_sn) })
}
return ret;
};
export const getTodoOrdersAction = async (params) => {
const opi_arr = params.opisn.split(',')
const defaultStickyTree = opi_arr.reduce(
(a, ele) => ({
...a,
[ele]: [
{
key: ele + '-today',
title: '今日任务',
getMails: false,
iconIndex: 'star',
children: [],
COLI_SN: 0,
},
{
key: ele + '-todo',
title: '待办任务',
getMails: false,
iconIndex: 'calendar',
children: [],
COLI_SN: 0,
},
// {
// key: ele.OPI_DEI_SN + '-reminder',
// title: '催信',
// getMails: false,iconIndex: 'reminder',
// icon: <BellTwoTone />,
// children: [], COLI_SN: 0,
// },
],
}),
{},
)
const { errcode, result } = await fetchJSON(`${API_HOST}/getwlorder`, params)
// 订单重复时, 取后一个状态, 因此翻转两次
const _result_unique = uniqWith(result.reverse(), (a, b) => a.COLI_SN === b.COLI_SN).reverse();
const orderList = errcode === 0 ? _result_unique : []
const byOPI = groupBy(orderList, 'OPI_SN')
const byState = Object.keys(byOPI).reduce((acc, key) => {
const sticky = groupBy(byOPI[key], (ele) => ([1, 6].includes(ele.coli_ordertype) ? 0 : [2, 3, 4, 5].includes(ele.coli_ordertype) ? 1 : 2))
const treeNode = [
{
key: key + '-today',
title: '今日任务',
getMails: false,
iconIndex: 'star',
_raw: { COLI_SN: 0, IsTrue: 0 },
children: (sticky[0] || []).map((o) => ({
key: `today-${o.COLI_SN}`,
title: `(${todoTypes[o.coli_ordertype] || o.COLI_State}) ${o.COLI_ID}`,
iconIndex: 13,
parent: key + '-today',
parentTitle: '今日任务',
parentIconIndex: 'star',
_raw: { ...o, VKey: o.COLI_SN, VName: o.COLI_ID, VParent: key + '-today', IsTrue: 0, ApplyDate: '', OrderSourceType: 227001, parent: key + '-today' },
})),
},
{
key: key + '-todo',
title: '待办任务',
getMails: false,
iconIndex: 'calendar',
_raw: { COLI_SN: 0, IsTrue: 0 },
children: (sticky[2] || []).map((o) => ({
key: `todo-${o.COLI_SN}`,
title: `(${todoTypes[o.coli_ordertype] || o.COLI_State}) ${o.COLI_ID}`,
iconIndex: 13,
parent: key + '-todo',
parentTitle: '待办任务',
parentIconIndex: 'calendar',
_raw: { ...o, VKey: o.COLI_SN, VName: o.COLI_ID, VParent: key + '-todo', IsTrue: 0, ApplyDate: '', OrderSourceType: 227001, parent: key + '-todo' },
})),
},
...(!isEmpty(sticky[1] || [])
? [
{
key: key + '-reminder',
title: '催信',
getMails: false,
iconIndex: 'reminder',
_raw: { COLI_SN: 0, IsTrue: 0 },
children: (sticky[1] || []).map((o) => ({
key: `reminder-${o.COLI_SN}`,
title: `(${todoTypes[o.coli_ordertype] || o.COLI_State}) ${o.COLI_ID}`,
iconIndex: 13,
parent: key + '-reminder',
parentTitle: '催信',
parentIconIndex: 'reminder',
_raw: { ...o, VKey: o.COLI_SN, VName: o.COLI_ID, VParent: key + '-reminder', IsTrue: 0, ApplyDate: '', OrderSourceType: 227001, parent: key + '-reminder' },
})),
},
]
: []),
]
return { ...acc, [key]: treeNode }
}, defaultStickyTree)
return errcode === 0 ? byState : defaultStickyTree
};
/**
* 获取待办目录和邮箱目录
* @param {object} params { opi_sn, userIdStr }
* @param {number} params.opi_sn
* @param {string} params.userIdStr - 用户ID字符串默认为空
*/
export const getRootMailboxDirAction = async ({ opi_sn = 0, userIdStr = '' } = {}) => {
const [stickyTree, ...mailboxDir] = await Promise.all([
getTodoOrdersAction({ opisn: userIdStr || String(opi_sn), otype: 'today' }),
...(userIdStr.split(',').map(_opi => getEmailDirAction({ opi_sn: _opi }))),
])
const mailBoxCount = await Promise.all(userIdStr.split(',').map(_opi => getMailboxCountAction({ opi_sn: _opi }, false)));
const mailboxDirCountByOPI = mailBoxCount.reduce((a, c) => ({ ...a, ...c, }), {})
const mailboxDirByOPI = mailboxDir.reduce((a, c) => ({ ...a, ...(Object.keys(c).reduce((a, opi) => ({...a, [opi]: c[`${opi}`].map((dir) => ({ ...dir, count: mailboxDirCountByOPI[opi][`${dir.key}`] })) }), {} )) }), {})
const rootTree = Object.keys(stickyTree).map((opi) => ({ key: Number(opi), tree: [...stickyTree[opi], ...(mailboxDirByOPI?.[opi] || [])], treeTimestamp: Date.now() }))
writeIndexDB(rootTree, 'dirs', 'mailbox')
const _mapped = groupBy(rootTree, 'key')
return _mapped[opi_sn]?.[0]?.tree || []
}
/**
* 获取邮件列表
* @usage 邮件目录下的邮件列表
* @usage 订单的邮件列表
*/
export const queryEmailListAction = async ({ opi_sn = '', pagesize = 10, last_id = '', node = {}, } = {}) => {
const _params = {
vkey: 0,
vparent: 0,
order_source_type: 0,
// mai_senddate1: dayjs().subtract(1, 'year').startOf('year').format(DATE_FORMAT),
mai_senddate1: dayjs().subtract(180, 'days').format(DATE_FORMAT),
mai_senddate2: dayjs().format(DATEEND_FORMAT),
...omitEmpty({
...node,
opi_sn,
}),
}
_params.mai_senddate1 = dayjs(_params.mai_senddate1).format(DATE_FORMAT)
const cacheKey = isEmpty(_params.coli_sn) ? `dir-${node.vkey}` : `order-${node.vkey}`;
const { errcode, result } = await fetchJSON(`${API_HOST_V3}/mail_list`, _params)
const ret = errcode === 0 ? result : []
if (!isEmpty(ret)) {
const listids = [...new Set(ret.map(ele => ele.MAI_SN))];
writeIndexDB([{key: cacheKey, data: listids}], 'maillist', 'mailbox')
writeIndexDB(ret.map(ele => ({ data: {...ele, listKey: cacheKey }, key: ele.MAI_SN})), 'listrow', 'mailbox')
}
return ret;
}
export const searchEmailListAction = async ({opi_sn = '', mailboxtype = 'ALL', sender = '', receiver = '', subject = '', content=''}={}) => {
const formData = new FormData()
formData.append('opi_sn', opi_sn)
formData.append('mailboxtype', mailboxtype)
formData.append('sender', sender)
formData.append('receiver', receiver)
formData.append('subject', subject)
// formData.append('content', content)
const { errcode, result } = await postForm(`${API_HOST_V3}/mail_search`, formData)
const ret = errcode === 0 ? result : []
notifyMailboxUpdate({ type: 'maillist-search-result', query: [sender, receiver, subject].filter(s => s).join(' '), data: ret.map(ele => ({...ele, key: ele.MAI_SN, showFolder: true })) })
return ret;
}
const removeFromCurrentList = async (params) => {
const readRow0 = await readIndexDB(params.mai_sn_list[0], 'listrow', 'mailbox')
const listKey = readRow0?.data?.listKey || ''
if (listKey) {
const readCache = await readIndexDB(listKey, 'maillist', 'mailbox')
const updatedMailList = readCache.data.filter((mai_sn) => !params.mai_sn_list.includes(mai_sn))
writeIndexDB([{ key: listKey, data: updatedMailList }], 'maillist', 'mailbox')
notifyMailboxUpdate({ type: 'listrow', listKey, affectKeys: params.mai_sn_list })
}
}
const updateEmailKeyMap = { read: 'MOI_ReadState' };
const updateEmailKeyFun = {
read: async (params) => {
const readCache = await readIndexDB(params.mai_sn_list, 'listrow', 'mailbox')
const updateField = Object.keys(params.set).reduce((a, c) => ({ ...a, [updateEmailKeyMap[c]]: params.set[c] }), {})
writeIndexDB(
params.mai_sn_list.map((ele) => ({ data: { ...(readCache.get(ele)?.data || {}), ...updateField }, key: ele })),
'listrow',
'mailbox',
)
// 通知邮件列表数据更新
const listKey = readCache.get(params.mai_sn_list[0])?.data?.listKey || '';
const notificationPayload = { type: 'listrow', listKey, affectKeys: params.mai_sn_list }
notifyMailboxUpdate(notificationPayload)
},
processed: removeFromCurrentList,
delete: removeFromCurrentList
}
/**
* 更新邮件属性
*/
export const updateEmailAction = async (params = { opi_sn: 0, mai_sn_list: [], set: {} }) => {
if (isEmpty(params.mai_sn_list)) {
throw new Error('没有需要更新的邮件');
}
const { errcode, result } = await postJSON(`${API_HOST_V3}/mail_update`, params)
if (errcode === 0 ) {
for (const [key, value] of Object.entries(params.set)) {
const updateFun = updateEmailKeyFun[key] || (() => {});
updateFun(params)
}
}
getMailboxCountAction({ opi_sn: params.opi_sn });
return errcode === 0 ? result : {}
}
/**
* 获取邮件模板
* @param {object} params - Parameters for the email template request.
* @param {number} [params.coli_sn] - Customer order line item serial number.
* @param {number} [params.lgc] - Language code.
* @param {number} [params.opi_sn] - Order product item serial number.
* @param {string} [params.remind_type] - Type of reminder.
* @param {number} [params.remind_index] - Index of the reminder.
*/
export const getReminderEmailTemplateAction = async (params = { coli_sn: 0, lgc: 1, opi_sn: 0, remind_type: '', remind_index: 0 }) => {
const { errcode, result } = await fetchJSON(`${API_HOST_V3}/reminder_letter`, params)
const { html, bodyContent, bodyText } = parseHTMLString(result?.MailContent, true) ;
return errcode === 0 ? {...result, bodyContent }: {}
}
/**
* 保存邮件草稿
* @param {object} body - The body of the email.
* @param {boolean} [isDraft=false] - Whether the email is a draft.
*/
export const saveEmailDraftOrSendAction = async (body, isDraft = false) => {
const url = isDraft !== false ? `${API_HOST_V3}/email_draft_save` : `${EMAIL_HOST_v3}/sendmail`;
const { attaList=[], atta, content, ...bodyData } = body;
bodyData.ordertype = 227001;
const formData = new FormData();
Object.keys(bodyData).forEach(function (key) {
formData.append(key, bodyData[key] || '');
});
// 附件只传新增的
attaList.filter(ele => !ele.fullPath).forEach(function (item) {
formData.append('attachment', item);
});
const { errcode, result } = await postForm(url, formData);
return errcode === 0 ? (result || {}) : {}
};
/**
* 删除邮件附件
*/
export const deleteEmailAttachmentAction = async (ati_sn_list) => {
const { errcode, result } = await postJSON(`${API_HOST_V3}/mail_attachment_delete`, { ati_sn_list })
return errcode === 0 ? result : {}
};
export const queryHTOrderListAction = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/query_order`, params)
return errcode !== 0 ? [] : result
}
export const queryOPIOrderAction = async (params) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/getdvancedwlorder`, params)
return errcode !== 0 ? [] : result
};

@ -1,25 +0,0 @@
import { fetchJSON, postForm, postJSON } from '@/utils/request'
import { usingStorage } from '@/utils/usingStorage'
const WAI_SERVER_KEY = 'G-STR:WAI_SERVER'
const WAI_API_VER = '/api/v1'
export const postSendMsg = async (body) => {
const { waiServer } = usingStorage(WAI_SERVER_KEY)
// const { attaList = [], atta, content, ...bodyData } = body
// const formData = new FormData()
// Object.keys(bodyData).forEach(function (key) {
// formData.append(key, bodyData[key])
// })
// attaList.forEach(function (item) {
// formData.append('attachment', item)
// })
const { result } = await postJSON(`${waiServer}${WAI_API_VER}/messages/send`, body)
return result
}
export const fetchQRCode = (phone) => {
const { waiServer } = usingStorage(WAI_SERVER_KEY)
return fetchJSON(`${waiServer}${WAI_API_VER}/channels/qrcode`, { phone })
}

@ -1,6 +1,6 @@
.logo {
float: left;
height: 68px;
margin: 0 6px 0 0;
height: 36px;
margin: 16px 24px 16px 0;
background: rgba(255, 255, 255, 0.3);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22 20V7L20 3H4L2 7.00353V20C2 20.5523 2.44772 21 3 21H21C21.5523 21 22 20.5523 22 20ZM4 9H20V19H4V9ZM5.236 5H18.764L19.764 7H4.237L5.236 5ZM15 11H9V13H15V11Z"></path></svg>

Before

Width:  |  Height:  |  Size: 262 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32" fill="currentColor"><path d="M3 10H21V20.0044C21 20.5543 20.5551 21 20.0066 21H3.9934C3.44476 21 3 20.5552 3 20.0044V10ZM9 12V14H15V12H9ZM2 3.99981C2 3.44763 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.44372 22 3.99981V8H2V3.99981Z"></path></svg>

Before

Width:  |  Height:  |  Size: 326 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32" fill="currentColor"><path d="M3 10H2V4.00293C2 3.44903 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.43788 22 4.00293V10H21V20.0015C21 20.553 20.5551 21 20.0066 21H3.9934C3.44476 21 3 20.5525 3 20.0015V10ZM19 10H5V19H19V10ZM4 5V8H20V5H4ZM9 12H15V14H9V12Z"></path></svg>

Before

Width:  |  Height:  |  Size: 347 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32" fill="currentColor"><path d="M20.997 2.9918L20.9998 21.0082C20.9998 21.5447 20.5552 22 20.0066 22H3.9934C3.44495 22 3 21.556 3 21.0082V2.9918C3 2.45531 3.44468 2 3.99322 2H20.0036C20.5519 2 20.9969 2.44405 20.997 2.9918ZM9 13V9C9 8.44772 9.44772 8 10 8C10.5523 8 11 8.44772 11 9V13C11 13.5523 11.4477 14 12 14C12.5523 14 13 13.5523 13 13V9C13 7.34315 11.6569 6 10 6C8.34315 6 7 7.34315 7 9V13C7 15.7614 9.23858 18 12 18C14.7614 18 17 15.7614 17 13V8H15V13C15 14.6569 13.6569 16 12 16C10.3431 16 9 14.6569 9 13Z"></path></svg>

Before

Width:  |  Height:  |  Size: 608 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32" fill="currentColor"><path d="M14 13.5V8C14 5.79086 12.2091 4 10 4C7.79086 4 6 5.79086 6 8V13.5C6 17.0899 8.91015 20 12.5 20C16.0899 20 19 17.0899 19 13.5V4H21V13.5C21 18.1944 17.1944 22 12.5 22C7.80558 22 4 18.1944 4 13.5V8C4 4.68629 6.68629 2 10 2C13.3137 2 16 4.68629 16 8V13.5C16 15.433 14.433 17 12.5 17C10.567 17 9 15.433 9 13.5V8H11V13.5C11 14.3284 11.6716 15 12.5 15C13.3284 15 14 14.3284 14 13.5Z"></path></svg>

Before

Width:  |  Height:  |  Size: 502 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M13.9999 18.9966H20.9999V20.9966H11.9999L8.00229 20.9991L1.51457 14.5113C1.12405 14.1208 1.12405 13.4877 1.51457 13.0971L12.1212 2.49053C12.5117 2.1 13.1449 2.1 13.5354 2.49053L21.3136 10.2687C21.7041 10.6592 21.7041 11.2924 21.3136 11.6829L13.9999 18.9966ZM15.6567 14.5113L19.1922 10.9758L12.8283 4.61185L9.29275 8.14738L15.6567 14.5113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 442 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8.58564 8.85449L3.63589 13.8042L8.83021 18.9985L9.99985 18.9978V18.9966H11.1714L14.9496 15.2184L8.58564 8.85449ZM9.99985 7.44027L16.3638 13.8042L19.1922 10.9758L12.8283 4.61185L9.99985 7.44027ZM13.9999 18.9966H20.9999V20.9966H11.9999L8.00229 20.9991L1.51457 14.5113C1.12405 14.1208 1.12405 13.4877 1.51457 13.0971L12.1212 2.49053C12.5117 2.1 13.1449 2.1 13.5354 2.49053L21.3136 10.2687C21.7041 10.6592 21.7041 11.2924 21.3136 11.6829L13.9999 18.9966Z"></path></svg>

Before

Width:  |  Height:  |  Size: 555 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32" fill="currentColor"><path d="M2 3H21.1384C21.4146 3 21.6385 3.22386 21.6385 3.5C21.6385 3.58701 21.6157 3.67252 21.5725 3.74807L18 10L21.5725 16.2519C21.7095 16.4917 21.6262 16.7971 21.3865 16.9341C21.3109 16.9773 21.2254 17 21.1384 17H4V22H2V3Z"></path></svg>

Before

Width:  |  Height:  |  Size: 343 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32" fill="currentColor"><path d="M21.1384 3C21.4146 3 21.6385 3.22386 21.6385 3.5C21.6385 3.58701 21.6157 3.67252 21.5725 3.74807L18 10L21.5725 16.2519C21.7095 16.4917 21.6262 16.7971 21.3865 16.9341C21.3109 16.9773 21.2254 17 21.1384 17H4V22H2V3H21.1384ZM18.5536 5H4V15H18.5536L15.6965 10L18.5536 5Z"></path></svg>

Before

Width:  |  Height:  |  Size: 394 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12.6512 14.0654L11.6047 20H9.57389L10.9247 12.339L3.51465 4.92892L4.92886 3.51471L20.4852 19.0711L19.071 20.4853L12.6512 14.0654ZM11.7727 7.53009L12.0425 5.99999H10.2426L8.24257 3.99999H19.9999V5.99999H14.0733L13.4991 9.25652L11.7727 7.53009Z"></path></svg>

Before

Width:  |  Height:  |  Size: 347 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5 3C4.5313 3 4.12549 3.32553 4.02381 3.78307L2.02381 12.7831C2.00799 12.8543 2 12.927 2 13V20C2 20.5523 2.44772 21 3 21H21C21.5523 21 22 20.5523 22 20V13C22 12.927 21.992 12.8543 21.9762 12.7831L19.9762 3.78307C19.8745 3.32553 19.4687 3 19 3H5ZM19.7534 12H15C15 13.6569 13.6569 15 12 15C10.3431 15 9 13.6569 9 12H4.24662L5.80217 5H18.1978L19.7534 12Z"></path></svg>

Before

Width:  |  Height:  |  Size: 455 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4.02381 3.78307C4.12549 3.32553 4.5313 3 5 3H19C19.4687 3 19.8745 3.32553 19.9762 3.78307L21.9762 12.7831C21.992 12.8543 22 12.927 22 13V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V13C2 12.927 2.00799 12.8543 2.02381 12.7831L4.02381 3.78307ZM5.80217 5L4.24662 12H9C9 13.6569 10.3431 15 12 15C13.6569 15 15 13.6569 15 12H19.7534L18.1978 5H5.80217ZM16.584 14C15.8124 15.7659 14.0503 17 12 17C9.94968 17 8.1876 15.7659 7.41604 14H4V19H20V14H16.584Z"></path></svg>

Before

Width:  |  Height:  |  Size: 565 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22 13.3414C21.3744 13.1203 20.7013 13 20 13C16.6863 13 14 15.6863 14 19C14 19.7013 14.1203 20.3744 14.3414 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V13.3414ZM12.0606 11.6829L5.64722 6.2377L4.35278 7.7623L12.0731 14.3171L19.6544 7.75616L18.3456 6.24384L12.0606 11.6829ZM21 18H24V20H21V23H19V20H16V18H19V15H21V18Z"></path></svg>

Before

Width:  |  Height:  |  Size: 460 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22 13H20V7.23792L12.0718 14.338L4 7.21594V19H14V21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V13ZM4.51146 5L12.0619 11.662L19.501 5H4.51146ZM21 18H24V20H21V23H19V20H16V18H19V15H21V18Z"></path></svg>

Before

Width:  |  Height:  |  Size: 328 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22 13.3414C21.3744 13.1203 20.7013 13 20 13C16.6863 13 14 15.6863 14 19C14 19.7013 14.1203 20.3744 14.3414 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V13.3414ZM12.0606 11.6829L5.64722 6.2377L4.35278 7.7623L12.0731 14.3171L19.6544 7.75616L18.3456 6.24384L12.0606 11.6829ZM19 22L15.4645 18.4645L16.8787 17.0503L19 19.1716L22.5355 15.636L23.9497 17.0503L19 22Z"></path></svg>

Before

Width:  |  Height:  |  Size: 504 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22 14H20V7.23792L12.0718 14.338L4 7.21594V19H14V21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V14ZM4.51146 5L12.0619 11.662L19.501 5H4.51146ZM19 22L15.4645 18.4645L16.8787 17.0503L19 19.1716L22.5355 15.636L23.9497 17.0503L19 22Z"></path></svg>

Before

Width:  |  Height:  |  Size: 372 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20 7.23792L12.0718 14.338L4 7.21594V19H13V21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V12H20V7.23792ZM19.501 5H4.51146L12.0619 11.662L19.501 5ZM20 18H23L19 22L15 18H18V14H20V18Z"></path></svg>

Before

Width:  |  Height:  |  Size: 323 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32" fill="currentColor"><path d="M3 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3ZM20 7.23792L12.0718 14.338L4 7.21594V19H20V7.23792ZM4.51146 5L12.0619 11.662L19.501 5H4.51146Z"></path></svg>

Before

Width:  |  Height:  |  Size: 340 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32" fill="currentColor"><path d="M2.24283 6.85435L11.4895 1.3086C11.8062 1.11865 12.2019 1.11872 12.5185 1.30878L21.7573 6.85433C21.9079 6.9447 22 7.10743 22 7.28303V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V7.28315C2 7.10748 2.09218 6.94471 2.24283 6.85435ZM4 8.13261V19H20V8.13214L12.0037 3.33237L4 8.13261ZM12.0597 13.6983L17.3556 9.23532L18.6444 10.7647L12.074 16.3017L5.36401 10.7717L6.63599 9.2283L12.0597 13.6983Z"></path></svg>

Before

Width:  |  Height:  |  Size: 531 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M2 5.5V3.9934C2 3.44476 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.44495 22 3.9934V20.0066C22 20.5552 21.5447 21 21.0082 21H2.9918C2.44405 21 2 20.5551 2 20.0066V19H20V7.3L12 14.5L2 5.5ZM0 10H5V12H0V10ZM0 15H8V17H0V15Z"></path></svg>

Before

Width:  |  Height:  |  Size: 320 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M21 3C21.5523 3 22 3.44772 22 4V20.0066C22 20.5552 21.5447 21 21.0082 21H2.9918C2.44405 21 2 20.5551 2 20.0066V19H20V7.3L12 14.5L2 5.5V4C2 3.44772 2.44772 3 3 3H21ZM8 15V17H0V15H8ZM5 10V12H0V10H5ZM19.5659 5H4.43414L12 11.8093L19.5659 5Z"></path></svg>

Before

Width:  |  Height:  |  Size: 340 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M18.8032 8.4928C19.4663 8.81764 20.2118 9 21 9C21.3425 9 21.6769 8.96557 22 8.89998V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H16.1C16.0344 3.32311 16 3.65753 16 4C16 5.23672 16.449 6.36857 17.1929 7.24142L12.0606 11.6829L5.64722 6.2377L4.35278 7.7623L12.0731 14.3171L18.8032 8.4928ZM21 7C19.3431 7 18 5.65685 18 4C18 2.34315 19.3431 1 21 1C22.6569 1 24 2.34315 24 4C24 5.65685 22.6569 7 21 7Z"></path></svg>

Before

Width:  |  Height:  |  Size: 539 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M16.1 3C16.0344 3.32311 16 3.65753 16 4C16 4.34247 16.0344 4.67689 16.1 5H4.51146L12.0619 11.662L17.1098 7.14141C17.5363 7.66888 18.0679 8.10787 18.6728 8.42652L12.0718 14.338L4 7.21594V19H20V8.89998C20.3231 8.96557 20.6575 9 21 9C21.3425 9 21.6769 8.96557 22 8.89998V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H16.1ZM21 1C22.6569 1 24 2.34315 24 4C24 5.65685 22.6569 7 21 7C19.3431 7 18 5.65685 18 4C18 2.34315 19.3431 1 21 1Z"></path></svg>

Before

Width:  |  Height:  |  Size: 572 B

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5 4.9967V7.9967H19V4.9967H5ZM4 2.9967H20C20.5523 2.9967 21 3.44442 21 3.9967V8.9967C21 9.54899 20.5523 9.9967 20 9.9967H4C3.44772 9.9967 3 9.54899 3 8.9967V3.9967C3 3.44442 3.44772 2.9967 4 2.9967ZM6 11.9967H12C12.5523 11.9967 13 12.4444 13 12.9967V15.9967H14V21.9967H10V15.9967H11V13.9967H5C4.44772 13.9967 4 13.549 4 12.9967V10.9967H6V11.9967ZM17.7322 13.7289L19.5 11.9612L21.2678 13.7289C22.2441 14.7052 22.2441 16.2882 21.2678 17.2645C20.2915 18.2408 18.7085 18.2408 17.7322 17.2645C16.7559 16.2882 16.7559 14.7052 17.7322 13.7289Z"></path></svg>

Before

Width:  |  Height:  |  Size: 640 B

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save