Explorar el Código

客服:根据代码评审进行 fix

puhui999 hace 10 meses
padre
commit
a4a8548b5a

+ 1 - 1
.env

@@ -5,7 +5,7 @@ SHOPRO_VERSION = v1.8.3
 SHOPRO_BASE_URL = http://api-dashboard.yudao.iocoder.cn
 
 # 后端接口 - 测试环境(通过 process.env.NODE_ENV = development)
-SHOPRO_DEV_BASE_URL = http://192.168.1.105:48080
+SHOPRO_DEV_BASE_URL = http://127.0.0.1:48080
 ### SHOPRO_DEV_BASE_URL = http://yunai.natapp1.cc
 
 # 后端接口前缀(一般不建议调整)

+ 226 - 214
manifest.json

@@ -1,227 +1,239 @@
 {
-    "name" : "芋道商城",
-    "appid" : "__UNI__460BC4C",
-    "description" : "基于 uni-app + Vue3 技术驱动的在线商城系统,内含诸多功能与丰富的活动,期待您的使用和反馈。",
-    "versionName" : "2.1.0",
-    "versionCode" : 183,
-    "transformPx" : false,
-    "app-plus" : {
-        "usingComponents" : true,
-        "nvueCompiler" : "uni-app",
-        "nvueStyleCompiler" : "uni-app",
-        "compilerVersion" : 3,
-        "nvueLaunchMode" : "fast",
-        "splashscreen" : {
-            "alwaysShowBeforeRender" : true,
-            "waiting" : true,
-            "autoclose" : true,
-            "delay" : 0
-        },
-        "safearea" : {
-            "bottom" : {
-                "offset" : "none"
-            }
-        },
-        "modules" : {
-            "Payment" : {},
-            "Share" : {},
-            "VideoPlayer" : {},
-            "OAuth" : {}
-        },
-        "distribute" : {
-            "android" : {
-                "permissions" : [
-                    "<uses-feature android:name=\"android.hardware.camera\"/>",
-                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
-                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
-                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
-                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
-                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
-                    "<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
-                    "<uses-permission android:name=\"android.permission.INTERNET\"/>",
-                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
-                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_SMS\"/>",
-                    "<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
-                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
-                    "<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
-                    "<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
-                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
-                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
-                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
-                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
-                    "<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
-                    "<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
-                ],
-                "minSdkVersion" : 21,
-                "schemes" : "shopro"
-            },
-            "ios" : {
-                "urlschemewhitelist" : [ "baidumap", "iosamap" ],
-                "dSYMs" : false,
-                "privacyDescription" : {
-                    "NSPhotoLibraryUsageDescription" : "需要同意访问您的相册选取图片才能完善该条目",
-                    "NSPhotoLibraryAddUsageDescription" : "需要同意访问您的相册才能保存该图片",
-                    "NSCameraUsageDescription" : "需要同意访问您的摄像头拍摄照片才能完善该条目",
-                    "NSUserTrackingUsageDescription" : "开启追踪并不会获取您在其它站点的隐私信息,该行为仅用于标识设备,保障服务安全和提升浏览体验"
-                },
-                "urltypes" : "shopro",
-                "capabilities" : {
-                    "entitlements" : {
-                        "com.apple.developer.associated-domains" : [ "applinks:shopro.sheepjs.com" ]
-                    }
-                },
-                "idfa" : true
-            },
-            "sdkConfigs" : {
-                "speech" : {
-                    "ifly" : {}
-                },
-                "ad" : {},
-                "oauth" : {
-                    "apple" : {},
-                    "weixin" : {
-                        "appid" : "wxae7a0c156da9383b",
-                        "UniversalLinks" : "https://shopro.sheepjs.com/uni-universallinks/__UNI__082C0BA/"
-                    }
-                },
-                "payment" : {
-                    "weixin" : {
-                        "__platform__" : [ "ios", "android" ],
-                        "appid" : "wxae7a0c156da9383b",
-                        "UniversalLinks" : "https://shopro.sheepjs.com/uni-universallinks/__UNI__082C0BA/"
-                    },
-                    "alipay" : {
-                        "__platform__" : [ "ios", "android" ]
-                    }
-                },
-                "share" : {
-                    "weixin" : {
-                        "appid" : "wxae7a0c156da9383b",
-                        "UniversalLinks" : "https://shopro.sheepjs.com/uni-universallinks/__UNI__082C0BA/"
-                    }
-                }
-            },
-            "orientation" : [ "portrait-primary" ],
-            "splashscreen" : {
-                "androidStyle" : "common",
-                "iosStyle" : "common",
-                "useOriginalMsgbox" : true
-            },
-            "icons" : {
-                "android" : {
-                    "hdpi" : "unpackage/res/icons/72x72.png",
-                    "xhdpi" : "unpackage/res/icons/96x96.png",
-                    "xxhdpi" : "unpackage/res/icons/144x144.png",
-                    "xxxhdpi" : "unpackage/res/icons/192x192.png"
-                },
-                "ios" : {
-                    "appstore" : "unpackage/res/icons/1024x1024.png",
-                    "ipad" : {
-                        "app" : "unpackage/res/icons/76x76.png",
-                        "app@2x" : "unpackage/res/icons/152x152.png",
-                        "notification" : "unpackage/res/icons/20x20.png",
-                        "notification@2x" : "unpackage/res/icons/40x40.png",
-                        "proapp@2x" : "unpackage/res/icons/167x167.png",
-                        "settings" : "unpackage/res/icons/29x29.png",
-                        "settings@2x" : "unpackage/res/icons/58x58.png",
-                        "spotlight" : "unpackage/res/icons/40x40.png",
-                        "spotlight@2x" : "unpackage/res/icons/80x80.png"
-                    },
-                    "iphone" : {
-                        "app@2x" : "unpackage/res/icons/120x120.png",
-                        "app@3x" : "unpackage/res/icons/180x180.png",
-                        "notification@2x" : "unpackage/res/icons/40x40.png",
-                        "notification@3x" : "unpackage/res/icons/60x60.png",
-                        "settings@2x" : "unpackage/res/icons/58x58.png",
-                        "settings@3x" : "unpackage/res/icons/87x87.png",
-                        "spotlight@2x" : "unpackage/res/icons/80x80.png",
-                        "spotlight@3x" : "unpackage/res/icons/120x120.png"
-                    }
-                }
-            }
-        }
+  "name": "芋道商城",
+  "appid": "__UNI__460BC4C",
+  "description": "基于 uni-app + Vue3 技术驱动的在线商城系统,内含诸多功能与丰富的活动,期待您的使用和反馈。",
+  "versionName": "2.1.0",
+  "versionCode": 183,
+  "transformPx": false,
+  "app-plus": {
+    "usingComponents": true,
+    "nvueCompiler": "uni-app",
+    "nvueStyleCompiler": "uni-app",
+    "compilerVersion": 3,
+    "nvueLaunchMode": "fast",
+    "splashscreen": {
+      "alwaysShowBeforeRender": true,
+      "waiting": true,
+      "autoclose": true,
+      "delay": 0
     },
-    "quickapp" : {},
-    "quickapp-native" : {
-        "icon" : "/static/logo.png",
-        "package" : "com.example.demo",
-        "features" : [
-            {
-                "name" : "system.clipboard"
-            }
-        ]
+    "safearea": {
+      "bottom": {
+        "offset": "none"
+      }
     },
-    "quickapp-webview" : {
-        "icon" : "/static/logo.png",
-        "package" : "com.example.demo",
-        "minPlatformVersion" : 1070,
-        "versionName" : "1.0.0",
-        "versionCode" : 100
+    "modules": {
+      "Payment": {},
+      "Share": {},
+      "VideoPlayer": {},
+      "OAuth": {}
     },
-    "mp-weixin" : {
-        "appid" : "wx98df718e528399d2",
-        "setting" : {
-            "urlCheck" : false,
-            "minified" : true,
-            "postcss" : true
+    "distribute": {
+      "android": {
+        "permissions": [
+          "<uses-feature android:name=\"android.hardware.camera\"/>",
+          "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+          "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+          "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+          "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+          "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+          "<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
+          "<uses-permission android:name=\"android.permission.INTERNET\"/>",
+          "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+          "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+          "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+          "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+          "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.READ_SMS\"/>",
+          "<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
+          "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+          "<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
+          "<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
+          "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+          "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+          "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
+          "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
+          "<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
+          "<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
+        ],
+        "minSdkVersion": 21,
+        "schemes": "shopro"
+      },
+      "ios": {
+        "urlschemewhitelist": [
+          "baidumap",
+          "iosamap"
+        ],
+        "dSYMs": false,
+        "privacyDescription": {
+          "NSPhotoLibraryUsageDescription": "需要同意访问您的相册选取图片才能完善该条目",
+          "NSPhotoLibraryAddUsageDescription": "需要同意访问您的相册才能保存该图片",
+          "NSCameraUsageDescription": "需要同意访问您的摄像头拍摄照片才能完善该条目",
+          "NSUserTrackingUsageDescription": "开启追踪并不会获取您在其它站点的隐私信息,该行为仅用于标识设备,保障服务安全和提升浏览体验"
         },
-        "optimization" : {
-            "subPackages" : true
+        "urltypes": "shopro",
+        "capabilities": {
+          "entitlements": {
+            "com.apple.developer.associated-domains": [
+              "applinks:shopro.sheepjs.com"
+            ]
+          }
         },
-        "plugins" : {},
-        "lazyCodeLoading" : "requiredComponents",
-        "usingComponents" : {},
-        "permission" : {},
-        "requiredPrivateInfos" : [ "chooseAddress" ]
-    },
-    "mp-alipay" : {
-        "usingComponents" : true
-    },
-    "mp-baidu" : {
-        "usingComponents" : true
-    },
-    "mp-toutiao" : {
-        "usingComponents" : true
-    },
-    "mp-jd" : {
-        "usingComponents" : true
-    },
-    "h5" : {
-        "template" : "index.html",
-        "router" : {
-            "mode" : "history",
-            "base" : "./"
+        "idfa": true
+      },
+      "sdkConfigs": {
+        "speech": {
+          "ifly": {}
         },
-        "sdkConfigs" : {
-            "maps" : {}
+        "ad": {},
+        "oauth": {
+          "apple": {},
+          "weixin": {
+            "appid": "wxae7a0c156da9383b",
+            "UniversalLinks": "https://shopro.sheepjs.com/uni-universallinks/__UNI__082C0BA/"
+          }
         },
-        "async" : {
-            "timeout" : 20000
+        "payment": {
+          "weixin": {
+            "__platform__": [
+              "ios",
+              "android"
+            ],
+            "appid": "wxae7a0c156da9383b",
+            "UniversalLinks": "https://shopro.sheepjs.com/uni-universallinks/__UNI__082C0BA/"
+          },
+          "alipay": {
+            "__platform__": [
+              "ios",
+              "android"
+            ]
+          }
         },
-        "title" : "芋道商城",
-        "optimization" : {
-            "treeShaking" : {
-                "enable" : true
-            }
+        "share": {
+          "weixin": {
+            "appid": "wxae7a0c156da9383b",
+            "UniversalLinks": "https://shopro.sheepjs.com/uni-universallinks/__UNI__082C0BA/"
+          }
+        }
+      },
+      "orientation": [
+        "portrait-primary"
+      ],
+      "splashscreen": {
+        "androidStyle": "common",
+        "iosStyle": "common",
+        "useOriginalMsgbox": true
+      },
+      "icons": {
+        "android": {
+          "hdpi": "unpackage/res/icons/72x72.png",
+          "xhdpi": "unpackage/res/icons/96x96.png",
+          "xxhdpi": "unpackage/res/icons/144x144.png",
+          "xxxhdpi": "unpackage/res/icons/192x192.png"
         },
-        "devServer" : {
-            "port" : 8383
+        "ios": {
+          "appstore": "unpackage/res/icons/1024x1024.png",
+          "ipad": {
+            "app": "unpackage/res/icons/76x76.png",
+            "app@2x": "unpackage/res/icons/152x152.png",
+            "notification": "unpackage/res/icons/20x20.png",
+            "notification@2x": "unpackage/res/icons/40x40.png",
+            "proapp@2x": "unpackage/res/icons/167x167.png",
+            "settings": "unpackage/res/icons/29x29.png",
+            "settings@2x": "unpackage/res/icons/58x58.png",
+            "spotlight": "unpackage/res/icons/40x40.png",
+            "spotlight@2x": "unpackage/res/icons/80x80.png"
+          },
+          "iphone": {
+            "app@2x": "unpackage/res/icons/120x120.png",
+            "app@3x": "unpackage/res/icons/180x180.png",
+            "notification@2x": "unpackage/res/icons/40x40.png",
+            "notification@3x": "unpackage/res/icons/60x60.png",
+            "settings@2x": "unpackage/res/icons/58x58.png",
+            "settings@3x": "unpackage/res/icons/87x87.png",
+            "spotlight@2x": "unpackage/res/icons/80x80.png",
+            "spotlight@3x": "unpackage/res/icons/120x120.png"
+          }
         }
+      }
+    }
+  },
+  "quickapp": {},
+  "quickapp-native": {
+    "icon": "/static/logo.png",
+    "package": "com.example.demo",
+    "features": [
+      {
+        "name": "system.clipboard"
+      }
+    ]
+  },
+  "quickapp-webview": {
+    "icon": "/static/logo.png",
+    "package": "com.example.demo",
+    "minPlatformVersion": 1070,
+    "versionName": "1.0.0",
+    "versionCode": 100
+  },
+  "mp-weixin": {
+    "appid": "wx63c280fe3248a3e7",
+    "setting": {
+      "urlCheck": false,
+      "minified": true,
+      "postcss": true
+    },
+    "optimization": {
+      "subPackages": true
+    },
+    "plugins": {},
+    "lazyCodeLoading": "requiredComponents",
+    "usingComponents": {},
+    "permission": {},
+    "requiredPrivateInfos": [
+      "chooseAddress"
+    ]
+  },
+  "mp-alipay": {
+    "usingComponents": true
+  },
+  "mp-baidu": {
+    "usingComponents": true
+  },
+  "mp-toutiao": {
+    "usingComponents": true
+  },
+  "mp-jd": {
+    "usingComponents": true
+  },
+  "h5": {
+    "template": "index.html",
+    "router": {
+      "mode": "hash",
+      "base": "./"
+    },
+    "sdkConfigs": {
+      "maps": {}
+    },
+    "async": {
+      "timeout": 20000
     },
-    "vueVersion" : "3",
-    "_spaceID" : "192b4892-5452-4e1d-9f09-eee1ece40639",
-    "locale" : "zh-Hans",
-    "fallbackLocale" : "zh-Hans"
+    "title": "芋道商城",
+    "optimization": {
+      "treeShaking": {
+        "enable": true
+      }
+    }
+  },
+  "vueVersion": "3",
+  "_spaceID": "192b4892-5452-4e1d-9f09-eee1ece40639",
+  "locale": "zh-Hans",
+  "fallbackLocale": "zh-Hans"
 }

+ 9 - 18
pages.json

@@ -86,8 +86,7 @@
 	],
 	"subPackages": [{
 			"root": "pages/goods",
-			"pages": [
-              {
+			"pages": [{
 					"path": "index",
 					"style": {
 						"navigationBarTitleText": "商品详情"
@@ -151,8 +150,7 @@
 		},
 		{
 			"root": "pages/order",
-			"pages": [
-              {
+			"pages": [{
 					"path": "detail",
 					"style": {
 						"navigationBarTitleText": "订单详情"
@@ -251,8 +249,7 @@
 		},
 		{
 			"root": "pages/user",
-			"pages": [
-              {
+			"pages": [{
 					"path": "info",
 					"style": {
 						"navigationBarTitleText": "我的信息"
@@ -338,8 +335,7 @@
 		},
 		{
 			"root": "pages/commission",
-			"pages": [
-              {
+			"pages": [{
 					"path": "index",
 					"style": {
 						"navigationBarTitleText": "分销"
@@ -436,8 +432,7 @@
 		},
 		{
 			"root": "pages/app",
-			"pages": [
-              {
+			"pages": [{
 				"path": "sign",
 				"style": {
 					"navigationBarTitleText": "签到中心"
@@ -452,8 +447,7 @@
 		},
 		{
 			"root": "pages/public",
-			"pages": [
-              {
+			"pages": [{
 					"path": "setting",
 					"style": {
 						"navigationBarTitleText": "系统设置"
@@ -502,8 +496,7 @@
 		},
 		{
 			"root": "pages/coupon",
-			"pages": [
-              {
+			"pages": [{
 					"path": "list",
 					"style": {
 						"navigationBarTitleText": "领券中心"
@@ -545,8 +538,7 @@
 		},
 		{
 			"root": "pages/pay",
-			"pages": [
-              {
+			"pages": [{
 					"path": "index",
 					"style": {
 						"navigationBarTitleText": "收银台"
@@ -586,8 +578,7 @@
 		},
 		{
 			"root": "pages/activity",
-			"pages": [
-              {
+			"pages": [{
 					"path": "groupon/detail",
 					"style": {
 						"navigationBarTitleText": "拼团详情"

+ 1 - 6
pages/chat/components/chatBox.vue

@@ -133,11 +133,6 @@
 </template>
 
 <script setup>
-  /**
-   * uniapp 实现虚拟列表
-   *
-   * see https://juejin.cn/post/7105280477141041183
-   */
   import { nextTick, reactive, ref, unref } from 'vue';
   import { onLoad } from '@dcloudio/uni-app';
   import sheep from '@/sheep';
@@ -170,7 +165,7 @@
 
   // 获得消息分页列表
   const getMessageList = async (pageNo = undefined) => {
-    const { data } = await KeFuApi.getMessageListPage({
+    const { data } = await KeFuApi.getKefuMessagePage({
       pageNo: pageNo || currentShowPage.value,
     });
     if (isEmpty(data.list)) {

+ 0 - 456
pages/chat/components/chatBox1.vue

@@ -1,456 +0,0 @@
-<template>
-  <view class="chat-box" :style="{ height: pageHeight + 'px' }">
-    <!--  竖向滚动区域需要设置固定 height  -->
-    <scroll-view
-      :style="{ height: pageHeight + 'px' }"
-      scroll-y="true"
-      :scroll-with-animation="false"
-      :enable-back-to-top="true"
-      :scroll-into-view="state.scrollInto"
-    >
-      <!--  消息渲染  -->
-      <view class="message-item ss-flex-col" v-for="(item, index) in chatList" :key="index">
-        <view class="ss-flex ss-row-center ss-col-center">
-          <!-- 日期 -->
-          <view v-if="item.contentType !== KeFuMessageContentTypeEnum.SYSTEM && showTime(item, index)"
-                class="date-message">
-            {{ formatDate(item.date) }}
-          </view>
-          <!-- 系统消息 -->
-          <view v-if="item.contentType === KeFuMessageContentTypeEnum.SYSTEM" class="system-message">
-            {{ item.content }}
-          </view>
-        </view>
-        <!-- 消息体渲染管理员消息和用户消息并左右展示  -->
-        <view
-          v-if="item.contentType !== KeFuMessageContentTypeEnum.SYSTEM"
-          class="ss-flex ss-col-top"
-          :class="[
-              item.senderType === UserTypeEnum.ADMIN
-                ? `ss-row-left`
-                : item.senderType === UserTypeEnum.MEMBER
-                ? `ss-row-right`
-                : '',
-            ]"
-        >
-          <!-- 客服头像 -->
-          <image
-            v-show="item.senderType === UserTypeEnum.ADMIN"
-            class="chat-avatar ss-m-r-24"
-            :src="
-                sheep.$url.cdn(item?.senderAvatar) ||
-                sheep.$url.static('/static/img/shop/chat/default.png')
-              "
-            mode="aspectFill"
-          ></image>
-
-          <!-- 发送状态 -->
-          <span
-            v-if="
-                item.senderType === UserTypeEnum.MEMBER &&
-                index == chatList.length - 1 &&
-                isSendSuccess !== 0
-              "
-            class="send-status"
-          >
-              <image
-                v-if="isSendSuccess == -1"
-                class="loading"
-                :src="sheep.$url.static('/static/img/shop/chat/loading.png')"
-                mode="aspectFill"
-              ></image>
-            <!-- <image
-              v-if="chatData.isSendSuccess == 1"
-              class="warning"
-              :src="sheep.$url.static('/static/img/shop/chat/warning.png')"
-              mode="aspectFill"
-              @click="onAgainSendMessage(item)"
-            ></image> -->
-            </span>
-
-          <!-- 内容 -->
-          <template v-if="item.contentType === KeFuMessageContentTypeEnum.TEXT">
-            <view class="message-box" :class="{'admin': item.senderType === UserTypeEnum.ADMIN}">
-              <mp-html :content="replaceEmoji(item.content)" />
-            </view>
-          </template>
-          <template v-if="item.contentType === KeFuMessageContentTypeEnum.IMAGE">
-            <view class="message-box" :class="{'admin': item.senderType === UserTypeEnum.ADMIN}" :style="{ width: '200rpx' }">
-              <su-image
-                class="message-img"
-                isPreview
-                :previewList="[sheep.$url.cdn(item.content)]"
-                :current="0"
-                :src="sheep.$url.cdn(item.content)"
-                :height="200"
-                :width="200"
-                mode="aspectFill"
-              ></su-image>
-            </view>
-          </template>
-          <template v-if="item.contentType === KeFuMessageContentTypeEnum.PRODUCT">
-            <GoodsItem
-              :goodsData="item.content.item"
-              @tap="
-                  sheep.$router.go('/pages/goods/index', {
-                    id: item.content.item.id,
-                  })
-                "
-            />
-          </template>
-          <template v-if="item.contentType === KeFuMessageContentTypeEnum.ORDER">
-            <OrderItem
-              from="msg"
-              :orderData="item.content.item"
-              @tap="
-                  sheep.$router.go('/pages/order/detail', {
-                    id: item.content.item.id,
-                  })
-                "
-            />
-          </template>
-          <!-- user头像 -->
-          <image
-            v-if="item.senderType === UserTypeEnum.MEMBER"
-            class="chat-avatar ss-m-l-24"
-            :src="sheep.$url.cdn(item?.senderAvatar) ||
-                sheep.$url.static('/static/img/shop/chat/default.png')"
-            mode="aspectFill"
-          >
-          </image>
-        </view>
-      </view>
-      <!-- 视图滚动锚点  -->
-      <view id="scrollBottom"></view>
-    </scroll-view>
-  </view>
-</template>
-
-<script setup>
-  import sheep from '@/sheep';
-  import OrderItem from '@/pages/chat/components/order.vue';
-  import GoodsItem from '@/pages/chat/components/goods.vue';
-  import { reactive, ref, unref } from 'vue';
-  import { formatDate } from '@/sheep/util';
-  import dayjs from 'dayjs';
-  import { KeFuMessageContentTypeEnum,UserTypeEnum } from './constants';
-  import { emojiList } from '@/pages/chat/emoji';
-
-  const KEFU_MESSAGE_TYPE = 'kefu_message_type'; // 客服消息类型
-  const { screenHeight, safeAreaInsets, safeArea, screenWidth } = sheep.$platform.device;
-  const pageHeight = safeArea.height - 44 - 35 - 50;
-  const state = reactive({
-    scrollInto: '',
-  });
-
-  const chatList = [
-    {
-      id: 1,
-      conversationId: 1001,
-      senderId: 1,
-      senderType: 1, // UserTypeEnum.MEMBER
-      receiverId: 2,
-      receiverType: 1, // UserTypeEnum.MEMBER
-      contentType: 1, // KeFuMessageContentTypeEnum.TEXT
-      content: "Hello, how are you?",
-      readStatus: false
-    },
-    {
-      id: 2,
-      conversationId: 1001,
-      senderId: 2,
-      senderType: 1, // UserTypeEnum.MEMBER
-      receiverId: 1,
-      receiverType: 1, // UserTypeEnum.MEMBER
-      contentType: 1, // KeFuMessageContentTypeEnum.TEXT
-      content: "I'm good, thanks! [流泪][流泪][流泪][流泪]",
-      readStatus: false
-    },
-    {
-      id: 3,
-      conversationId: 1002,
-      senderId: 3,
-      senderType: 2, // UserTypeEnum.ADMIN
-      receiverId: 4,
-      receiverType: 1, // UserTypeEnum.MEMBER
-      contentType: 2, // KeFuMessageContentTypeEnum.IMAGE
-      content: "https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg",
-      readStatus: true
-    },
-    {
-      id: 4,
-      conversationId: 1002,
-      senderId: 4,
-      senderType: 1, // UserTypeEnum.MEMBER
-      receiverId: 3,
-      receiverType: 2, // UserTypeEnum.ADMIN
-      contentType: 1, // KeFuMessageContentTypeEnum.TEXT
-      content: "This is a text message.",
-      readStatus: false
-    },
-    {
-      id: 5,
-      conversationId: 1003,
-      senderId: 5,
-      senderType: 1, // UserTypeEnum.MEMBER
-      receiverId: 6,
-      receiverType: 1, // UserTypeEnum.MEMBER
-      contentType: 3, // KeFuMessageContentTypeEnum.VOICE
-      content: "Voice content here",
-      readStatus: true
-    },
-    {
-      id: 6,
-      conversationId: 1003,
-      senderId: 6,
-      senderType: 1, // UserTypeEnum.MEMBER
-      receiverId: 5,
-      receiverType: 1, // UserTypeEnum.MEMBER
-      contentType: 1, // KeFuMessageContentTypeEnum.TEXT
-      content: "Another text message.",
-      readStatus: false
-    },
-    {
-      id: 7,
-      conversationId: 1004,
-      senderId: 7,
-      senderType: 2, // UserTypeEnum.ADMIN
-      receiverId: 8,
-      receiverType: 1, // UserTypeEnum.MEMBER
-      contentType: 1, // KeFuMessageContentTypeEnum.VIDEO
-      content: "Video content here",
-      readStatus: true
-    },
-    {
-      id: 8,
-      conversationId: 1004,
-      senderId: 8,
-      senderType: 1, // UserTypeEnum.MEMBER
-      receiverId: 7,
-      receiverType: 2, // UserTypeEnum.ADMIN
-      contentType: 5, // KeFuMessageContentTypeEnum.SYSTEM
-      content: "System message content",
-      readStatus: false
-    },
-    {
-      id: 9,
-      conversationId: 1005,
-      senderId: 9,
-      senderType: 1, // UserTypeEnum.MEMBER
-      receiverId: 10,
-      receiverType: 1, // UserTypeEnum.MEMBER
-      contentType: 10, // KeFuMessageContentTypeEnum.PRODUCT
-      content: "Product message content",
-      readStatus: true
-    },
-    {
-      id: 10,
-      conversationId: 1005,
-      senderId: 10,
-      senderType: 1, // UserTypeEnum.MEMBER
-      receiverId: 9,
-      receiverType: 1, // UserTypeEnum.MEMBER
-      contentType: 11, // KeFuMessageContentTypeEnum.ORDER
-      content: "Order message content",
-      readStatus: false
-    }
-  ];
-
-  const isSendSuccess = ref(-1)
-  //======================= 工具函数 =======================
-  /**
-   * 是否显示时间
-   * @param {*} item - 数据
-   * @param {*} index - 索引
-   */
-  const showTime = (item, index) => {
-    if (unref(chatList)[index + 1]) {
-      let dateString = dayjs(unref(chatList)[index + 1].date).fromNow();
-      return dateString !== dayjs(unref(item).date).fromNow();
-    }
-    return false;
-  };
-  // 处理表情
-  function replaceEmoji(data) {
-    let newData = data;
-    if (typeof newData !== 'object') {
-      let reg = /\[(.+?)\]/g; // [] 中括号
-      let zhEmojiName = newData.match(reg);
-      if (zhEmojiName) {
-        zhEmojiName.forEach((item) => {
-          let emojiFile = selEmojiFile(item);
-          newData = newData.replace(
-            item,
-            `<img class="chat-img" style="width: 24px;height: 24px;margin: 0 3px;" src="${sheep.$url.cdn(
-              '/static/img/chat/emoji/' + emojiFile,
-            )}"/>`,
-          );
-        });
-      }
-    }
-    return newData;
-  }
-  function selEmojiFile(name) {
-    for (let index in emojiList) {
-      if (emojiList[index].name === name) {
-        return emojiList[index].file;
-      }
-    }
-    return false;
-  }
-</script>
-
-<style scoped lang="scss">
-  .chat-box {
-    padding: 0 20rpx 0;
-
-    .loadmore-btn {
-      width: 98%;
-      height: 40px;
-      font-size: 12px;
-      color: #8c8c8c;
-
-      .loadmore-icon {
-        transform: rotate(90deg);
-      }
-    }
-
-    .message-item {
-      margin-bottom: 33rpx;
-    }
-
-    .date-message,
-    .system-message {
-      width: fit-content;
-      border-radius: 12rpx;
-      padding: 8rpx 16rpx;
-      margin-bottom: 16rpx;
-      background-color: var(--ui-BG-3);
-      color: #999;
-      font-size: 24rpx;
-    }
-
-    .chat-avatar {
-      width: 70rpx;
-      height: 70rpx;
-      border-radius: 50%;
-    }
-
-    .send-status {
-      color: #333;
-      height: 80rpx;
-      margin-right: 8rpx;
-      display: flex;
-      align-items: center;
-
-      .loading {
-        width: 32rpx;
-        height: 32rpx;
-        -webkit-animation: rotating 2s linear infinite;
-        animation: rotating 2s linear infinite;
-
-        @-webkit-keyframes rotating {
-          0% {
-            transform: rotateZ(0);
-          }
-
-          100% {
-            transform: rotateZ(360deg);
-          }
-        }
-
-        @keyframes rotating {
-          0% {
-            transform: rotateZ(0);
-          }
-
-          100% {
-            transform: rotateZ(360deg);
-          }
-        }
-      }
-
-      .warning {
-        width: 32rpx;
-        height: 32rpx;
-        color: #ff3000;
-      }
-    }
-
-    .message-box {
-      max-width: 50%;
-      font-size: 16px;
-      line-height: 20px;
-      // max-width: 500rpx;
-      white-space: normal;
-      word-break: break-all;
-      word-wrap: break-word;
-      padding: 20rpx;
-      border-radius: 10rpx;
-      color: #fff;
-      background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
-
-      &.admin {
-        background: #fff;
-        color: #333;
-      }
-
-      :deep() {
-        .imgred {
-          width: 100%;
-        }
-
-        .imgred,
-        img {
-          width: 100%;
-        }
-      }
-    }
-
-    :deep() {
-      .goods,
-      .order {
-        max-width: 500rpx;
-      }
-    }
-
-    .message-img {
-      width: 100px;
-      height: 100px;
-      border-radius: 6rpx;
-    }
-
-    .template-wrap {
-      // width: 100%;
-      padding: 20rpx 24rpx;
-      background: #fff;
-      border-radius: 10rpx;
-
-      .title {
-        font-size: 26rpx;
-        font-weight: 500;
-        color: #333;
-        margin-bottom: 29rpx;
-      }
-
-      .item {
-        font-size: 24rpx;
-        color: var(--ui-BG-Main);
-        margin-bottom: 16rpx;
-
-        &:last-of-type {
-          margin-bottom: 0;
-        }
-      }
-    }
-
-    .error-img {
-      width: 400rpx;
-      height: 400rpx;
-    }
-
-    #scrollBottom {
-      height: 120rpx;
-    }
-  }
-</style>

+ 1 - 1
pages/chat/index.vue

@@ -61,7 +61,7 @@
         contentType: KeFuMessageContentTypeEnum.TEXT,
         content: chat.msg,
       };
-      await KeFuApi.sendMessage(data);
+      await KeFuApi.sendKefuMessage(data);
       await getMessageList()
       chat.msg = '';
     } finally {

+ 0 - 678
pages/chat/index1.vue

@@ -1,678 +0,0 @@
-<template>
-  <s-layout class="chat-wrap" title="客服" navbar="inner">
-    <div class="status">
-      {{ socketState.isConnect ? customerServiceInfo.title : '网络已断开,请检查网络后刷新重试' }}
-    </div>
-    <div class="page-bg" :style="{ height: sys_navBar + 'px' }"></div>
-    <view class="chat-box" :style="{ height: pageHeight + 'px' }">
-      <scroll-view
-        :style="{ height: pageHeight + 'px' }"
-        scroll-y="true"
-        :scroll-with-animation="false"
-        :enable-back-to-top="true"
-        :scroll-into-view="chat.scrollInto"
-      >
-        <button
-          class="loadmore-btn ss-reset-button"
-          v-if="
-            chatList.length &&
-            chatHistoryPagination.lastPage > 1 &&
-            loadingMap[chatHistoryPagination.loadStatus].title
-          "
-          @click="onLoadMore"
-        >
-          {{ loadingMap[chatHistoryPagination.loadStatus].title }}
-          <i
-            class="loadmore-icon sa-m-l-6"
-            :class="loadingMap[chatHistoryPagination.loadStatus].icon"
-          ></i>
-        </button>
-        <view class="message-item ss-flex-col" v-for="(item, index) in chatList" :key="index">
-          <view class="ss-flex ss-row-center ss-col-center">
-            <!-- 日期 -->
-            <view v-if="item.from !== 'system' && showTime(item, index)" class="date-message">
-              {{ formatTime(item.date) }}
-            </view>
-            <!-- 系统消息 -->
-            <view v-if="item.from === 'system'" class="system-message">
-              {{ item.content.text }}
-            </view>
-          </view>
-          <!-- 常见问题 -->
-          <view v-if="item.mode === 'template' && item.content.list.length" class="template-wrap">
-            <view class="title">猜你想问</view>
-            <view
-              class="item"
-              v-for="(item, index) in item.content.list"
-              :key="index"
-              @click="onTemplateList(item)"
-            >
-              * {{ item.title }}
-            </view>
-          </view>
-
-          <view
-            v-if="
-              (item.from === 'customer_service' && item.mode !== 'template') ||
-              item.from === 'customer'
-            "
-            class="ss-flex ss-col-top"
-            :class="[
-              item.from === 'customer_service'
-                ? `ss-row-left`
-                : item.from === 'customer'
-                ? `ss-row-right`
-                : '',
-            ]"
-          >
-            <!-- 客服头像 -->
-            <image
-              v-show="item.from === 'customer_service'"
-              class="chat-avatar ss-m-r-24"
-              :src="
-                sheep.$url.cdn(item?.sender?.avatar) ||
-                sheep.$url.static('/static/img/shop/chat/default.png')
-              "
-              mode="aspectFill"
-            ></image>
-
-            <!-- 发送状态 -->
-            <span
-              v-if="
-                item.from === 'customer' &&
-                index == chatData.chatList.length - 1 &&
-                chatData.isSendSucces !== 0
-              "
-              class="send-status"
-            >
-              <image
-                v-if="chatData.isSendSucces == -1"
-                class="loading"
-                :src="sheep.$url.static('/static/img/shop/chat/loading.png')"
-                mode="aspectFill"
-              ></image>
-              <!-- <image
-                v-if="chatData.isSendSucces == 1"
-                class="warning"
-                :src="sheep.$url.static('/static/img/shop/chat/warning.png')"
-                mode="aspectFill"
-                @click="onAgainSendMessage(item)"
-              ></image> -->
-            </span>
-
-            <!-- 内容 -->
-            <template v-if="item.mode === 'text'">
-              <view class="message-box" :class="[item.from]">
-                <div
-                  class="message-text ss-flex ss-flex-wrap"
-                  @click="onRichtext"
-                  v-html="replaceEmoji(item.content.text)"
-                ></div>
-              </view>
-            </template>
-            <template v-if="item.mode === 'image'">
-              <view class="message-box" :class="[item.from]" :style="{ width: '200rpx' }">
-                <su-image
-                  class="message-img"
-                  isPreview
-                  :previewList="[sheep.$url.cdn(item.content.url)]"
-                  :current="0"
-                  :src="sheep.$url.cdn(item.content.url)"
-                  :height="200"
-                  :width="200"
-                  mode="aspectFill"
-                ></su-image>
-              </view>
-            </template>
-            <template v-if="item.mode === 'goods'">
-              <GoodsItem
-                :goodsData="item.content.item"
-                @tap="
-                  sheep.$router.go('/pages/goods/index', {
-                    id: item.content.item.id,
-                  })
-                "
-              />
-            </template>
-            <template v-if="item.mode === 'order'">
-              <OrderItem
-                from="msg"
-                :orderData="item.content.item"
-                @tap="
-                  sheep.$router.go('/pages/order/detail', {
-                    id: item.content.item.id,
-                  })
-                "
-              />
-            </template>
-            <!-- user头像 -->
-            <image
-              v-show="item.from === 'customer'"
-              class="chat-avatar ss-m-l-24"
-              :src="sheep.$url.cdn(customerUserInfo.avatar)"
-              mode="aspectFill"
-            >
-            </image>
-          </view>
-        </view>
-        <view id="scrollBottom"></view>
-      </scroll-view>
-    </view>
-    <su-fixed bottom>
-      <message-input v-model="chat.msg" @on-tools="onTools" @send-message="onSendMessage"></message-input>
-    </su-fixed>
-    <!--  聊天工具  -->
-    <tools-popup :show-tools="chat.showTools" :tools-mode="chat.toolsMode" @close="handleToolsClose"
-                 @on-emoji="onEmoji" @image-select="onSelect" @on-show-select="onShowSelect">
-      <message-input v-model="chat.msg" @on-tools="onTools" @send-message="onSendMessage"></message-input>
-    </tools-popup>
-
-    <SelectPopup
-      :mode="chat.selectMode"
-      :show="chat.showSelect"
-      @select="onSelect"
-      @close="chat.showSelect = false"
-    />
-  </s-layout>
-</template>
-
-<script setup>
-  import sheep from '@/sheep';
-  import { computed, reactive, toRefs } from 'vue';
-  import { onLoad } from '@dcloudio/uni-app';
-  import { emojiList } from './emoji.js';
-  import SelectPopup from './components/select-popup.vue';
-  import GoodsItem from './components/goods.vue';
-  import OrderItem from './components/order.vue';
-  import MessageInput from './components/messageInput.vue';
-  import ToolsPopup from './components/toolsPopup.vue';
-  import { useChatWebSocket } from './socket';
-  import { useWebSocket } from '@/sheep/hooks/useWebSocket';
-
-  const {
-    socketInit,
-    state: chatData,
-    socketSendMsg,
-    formatChatInput,
-    socketHistoryList,
-    onDrop,
-    onPaste,
-    getFocus,
-    // upload,
-    getUserToken,
-    // socketTest,
-    showTime,
-    formatTime,
-  } = useChatWebSocket();
-  const chatList = toRefs(chatData).chatList;
-  const customerServiceInfo = toRefs(chatData).customerServerInfo;
-  const chatHistoryPagination = toRefs(chatData).chatHistoryPagination;
-  const customerUserInfo = toRefs(chatData).customerUserInfo;
-  const socketState = toRefs(chatData).socketState;
-
-  const sys_navBar = sheep.$platform.navbar;
-  const chatConfig = computed(() => sheep.$store('app').chat);
-
-  const { screenHeight, safeAreaInsets, safeArea, screenWidth } = sheep.$platform.device;
-  const pageHeight = safeArea.height - 44 - 35 - 50;
-
-  const chatStatus = {
-    online: {
-      text: '在线',
-      colorVariate: '#46c55f',
-    },
-    offline: {
-      text: '离线',
-      colorVariate: '#b5b5b5',
-    },
-    busy: {
-      text: '忙碌',
-      colorVariate: '#ff0e1b',
-    },
-  };
-
-  // 加载更多
-  const loadingMap = {
-    loadmore: {
-      title: '查看更多',
-      icon: 'el-icon-d-arrow-left',
-    },
-    nomore: {
-      title: '没有更多了',
-      icon: '',
-    },
-    loading: {
-      title: '加载中... ',
-      icon: 'el-icon-loading',
-    },
-  };
-  const onLoadMore = () => {
-    chatHistoryPagination.value.page < chatHistoryPagination.value.lastPage && socketHistoryList();
-  };
-
-  const chat = reactive({
-    msg: '',
-    scrollInto: '',
-
-    showTools: false,
-    toolsMode: '',
-
-    showSelect: false,
-    selectMode: '',
-    chatStyle: {
-      mode: 'inner',
-      color: '#F8270F',
-      type: 'color',
-      alwaysShow: 1,
-      src: '',
-      list: {},
-    },
-  });
-
-  //======================= 聊天工具相关 =======================
-
-  function handleToolsClose() {
-    chat.showTools = false;
-    chat.toolsMode = '';
-  }
-
-  function onEmoji(item) {
-    chat.msg += item.name;
-  }
-
-  // 点击工具栏开关
-  function onTools(mode) {
-    // if (!socketState.value.isConnect) {
-    //   sheep.$helper.toast(socketState.value.tip || '您已掉线!请返回重试');
-    //   return;
-    // }
-
-    if (!chat.toolsMode || chat.toolsMode === mode) {
-      chat.showTools = !chat.showTools;
-    }
-    chat.toolsMode = mode;
-    if (!chat.showTools) {
-      chat.toolsMode = '';
-    }
-  }
-
-  function onShowSelect(mode) {
-    chat.showTools = false;
-    chat.showSelect = true;
-    chat.selectMode = mode;
-  }
-
-  async function onSelect({ type, data }) {
-    let msg = '';
-    switch (type) {
-      case 'image':
-        const { path, fullurl } = await sheep.$api.app.upload(data.tempFiles[0].path, 'default');
-        msg = {
-          from: 'customer',
-          mode: 'image',
-          date: new Date().getTime(),
-          content: {
-            url: fullurl,
-            path: path,
-          },
-        };
-        break;
-      case 'goods':
-        msg = {
-          from: 'customer',
-          mode: 'goods',
-          date: new Date().getTime(),
-          content: {
-            item: {
-              id: data.goods.id,
-              title: data.goods.title,
-              image: data.goods.image,
-              price: data.goods.price,
-              stock: data.goods.stock,
-            },
-          },
-        };
-        break;
-      case 'order':
-        msg = {
-          from: 'customer',
-          mode: 'order',
-          date: new Date().getTime(),
-          content: {
-            item: {
-              id: data.id,
-              order_sn: data.order_sn,
-              create_time: data.create_time,
-              pay_fee: data.pay_fee,
-              items: data.items.filter((item) => ({
-                goods_id: item.goods_id,
-                goods_title: item.goods_title,
-                goods_image: item.goods_image,
-                goods_price: item.goods_price,
-              })),
-              status_text: data.status_text,
-            },
-          },
-        };
-        break;
-    }
-    if (msg) {
-      socketSendMsg(msg, () => {
-        scrollBottom();
-      });
-      // scrollBottom();
-      chat.showTools = false;
-      chat.showSelect = false;
-      chat.selectMode = '';
-    }
-  }
-
-  function onAgainSendMessage(item) {
-    if (!socketState.value.isConnect) {
-      sheep.$helper.toast(socketState.value.tip || '您已掉线!请返回重试');
-      return;
-    }
-    if (!item) return;
-    const data = {
-      from: 'customer',
-      mode: 'text',
-      date: new Date().getTime(),
-      content: item.content,
-    };
-    socketSendMsg(data, () => {
-      scrollBottom();
-    });
-  }
-
-  function onSendMessage() {
-    if (!socketState.value.isConnect) {
-      sheep.$helper.toast(socketState.value.tip || '您已掉线!请返回重试');
-      return;
-    }
-    if (!chat.msg) return;
-    const data = {
-      from: 'customer',
-      mode: 'text',
-      date: new Date().getTime(),
-      content: {
-        text: chat.msg,
-      },
-    };
-    socketSendMsg(data, () => {
-      scrollBottom();
-    });
-    chat.showTools = false;
-    // scrollBottom();
-    setTimeout(() => {
-      chat.msg = '';
-    }, 100);
-  }
-
-  // 点击猜你想问
-  function onTemplateList(e) {
-    if (!socketState.value.isConnect) {
-      sheep.$helper.toast(socketState.value.tip || '您已掉线!请返回重试');
-      return;
-    }
-    const data = {
-      from: 'customer',
-      mode: 'text',
-      date: new Date().getTime(),
-      content: {
-        text: e.title,
-      },
-      customData: {
-        question_id: e.id,
-      },
-    };
-    socketSendMsg(data, () => {
-      scrollBottom();
-    });
-    // scrollBottom();
-  }
-
-  function selEmojiFile(name) {
-    for (let index in emojiList) {
-      if (emojiList[index].name === name) {
-        return emojiList[index].file;
-      }
-    }
-    return false;
-  }
-
-  function replaceEmoji(data) {
-    let newData = data;
-    if (typeof newData !== 'object') {
-      let reg = /\[(.+?)\]/g; // [] 中括号
-      let zhEmojiName = newData.match(reg);
-      if (zhEmojiName) {
-        zhEmojiName.forEach((item) => {
-          let emojiFile = selEmojiFile(item);
-          newData = newData.replace(
-            item,
-            `<img class="chat-img" style="width: 24px;height: 24px;margin: 0 3px;" src="${sheep.$url.cdn(
-              '/static/img/chat/emoji/' + emojiFile,
-            )}"/>`,
-          );
-        });
-      }
-    }
-    return newData;
-  }
-
-  function scrollBottom() {
-    let timeout = null;
-    chat.scrollInto = '';
-    clearTimeout(timeout);
-    timeout = setTimeout(() => {
-      chat.scrollInto = 'scrollBottom';
-    }, 100);
-  }
-  const websocket = useWebSocket()
-  onLoad(async () => {
-    websocket.socketInit({}, () => {
-      scrollBottom();
-    });
-  });
-</script>
-
-<style lang="scss" scoped>
-  .page-bg {
-    width: 100%;
-    position: absolute;
-    top: 0;
-    left: 0;
-    background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
-    background-size: 750rpx 100%;
-    z-index: 1;
-  }
-
-  .chat-wrap {
-    // :deep() {
-    //   .ui-navbar-box {
-    //     background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
-    //   }
-    // }
-
-    .status {
-      position: relative;
-      box-sizing: border-box;
-      z-index: 3;
-      height: 70rpx;
-      padding: 0 30rpx;
-      background: var(--ui-BG-Main-opacity-1);
-      display: flex;
-      align-items: center;
-      font-size: 30rpx;
-      font-weight: 400;
-      color: var(--ui-BG-Main);
-    }
-
-    .chat-box {
-      padding: 0 20rpx 0;
-
-      .loadmore-btn {
-        width: 98%;
-        height: 40px;
-        font-size: 12px;
-        color: #8c8c8c;
-
-        .loadmore-icon {
-          transform: rotate(90deg);
-        }
-      }
-
-      .message-item {
-        margin-bottom: 33rpx;
-      }
-
-      .date-message,
-      .system-message {
-        width: fit-content;
-        border-radius: 12rpx;
-        padding: 8rpx 16rpx;
-        margin-bottom: 16rpx;
-        background-color: var(--ui-BG-3);
-        color: #999;
-        font-size: 24rpx;
-      }
-
-      .chat-avatar {
-        width: 70rpx;
-        height: 70rpx;
-        border-radius: 50%;
-      }
-
-      .send-status {
-        color: #333;
-        height: 80rpx;
-        margin-right: 8rpx;
-        display: flex;
-        align-items: center;
-
-        .loading {
-          width: 32rpx;
-          height: 32rpx;
-          -webkit-animation: rotating 2s linear infinite;
-          animation: rotating 2s linear infinite;
-
-          @-webkit-keyframes rotating {
-            0% {
-              transform: rotateZ(0);
-            }
-
-            100% {
-              transform: rotateZ(360deg);
-            }
-          }
-
-          @keyframes rotating {
-            0% {
-              transform: rotateZ(0);
-            }
-
-            100% {
-              transform: rotateZ(360deg);
-            }
-          }
-        }
-
-        .warning {
-          width: 32rpx;
-          height: 32rpx;
-          color: #ff3000;
-        }
-      }
-
-      .message-box {
-        max-width: 50%;
-        font-size: 16px;
-        line-height: 20px;
-        // max-width: 500rpx;
-        white-space: normal;
-        word-break: break-all;
-        word-wrap: break-word;
-        padding: 20rpx;
-        border-radius: 10rpx;
-        color: #fff;
-        background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
-
-        &.customer_service {
-          background: #fff;
-          color: #333;
-        }
-
-        :deep() {
-          .imgred {
-            width: 100%;
-          }
-
-          .imgred,
-          img {
-            width: 100%;
-          }
-        }
-      }
-
-      :deep() {
-        .goods,
-        .order {
-          max-width: 500rpx;
-        }
-      }
-
-      .message-img {
-        width: 100px;
-        height: 100px;
-        border-radius: 6rpx;
-      }
-
-      .template-wrap {
-        // width: 100%;
-        padding: 20rpx 24rpx;
-        background: #fff;
-        border-radius: 10rpx;
-
-        .title {
-          font-size: 26rpx;
-          font-weight: 500;
-          color: #333;
-          margin-bottom: 29rpx;
-        }
-
-        .item {
-          font-size: 24rpx;
-          color: var(--ui-BG-Main);
-          margin-bottom: 16rpx;
-
-          &:last-of-type {
-            margin-bottom: 0;
-          }
-        }
-      }
-
-      .error-img {
-        width: 400rpx;
-        height: 400rpx;
-      }
-
-      #scrollBottom {
-        height: 120rpx;
-      }
-    }
-  }
-</style>
-<style>
-  .chat-img {
-    width: 24px;
-    height: 24px;
-    margin: 0 3px;
-  }
-
-  .full-img {
-    object-fit: cover;
-    width: 100px;
-    height: 100px;
-    border-radius: 6px;
-  }
-</style>

+ 0 - 818
pages/chat/socket.js

@@ -1,818 +0,0 @@
-import { reactive, ref, unref } from 'vue';
-import sheep from '@/sheep';
-// import chat from '@/sheep/api/chat';
-import dayjs from 'dayjs';
-import io from '@hyoga/uni-socket.io';
-import { baseUrl, websocketPath } from '@/sheep/config';
-
-export function useChatWebSocket(socketConfig) {
-  let SocketIo = null;
-
-  // chat状态数据
-  const state = reactive({
-    chatDotNum: 0, //总状态红点
-    chatList: [], //会话信息
-    customerUserInfo: {}, //用户信息
-    customerServerInfo: {
-      //客服信息
-      title: '客服已接入',
-      state: 'connecting',
-      avatar: null,
-      nickname: '',
-    },
-    socketState: {
-      isConnect: true, //是否连接成功
-      isConnecting: false, //重连中,不允许新的socket开启。
-      tip: '',
-    },
-    chatHistoryPagination: {
-      page: 0, //当前页
-      list_rows: 10, //每页条数
-      last_id: 0, //最后条ID
-      lastPage: 0, //总共多少页
-      loadStatus: 'loadmore', //loadmore-加载前的状态,loading-加载中的状态,nomore-没有更多的状态
-    },
-    templateChatList: [], //猜你想问
-
-    chatConfig: {}, // 配置信息
-
-    isSendSuccess: -1, // 是否发送成功 -1=发送中|0=发送成功|1发送失败
-  });
-
-  /**
-   * 连接初始化
-   * @param {Object} config  - 配置信息
-   * @param {Function} callBack -回调函数,有新消息接入,保持底部
-   */
-  const socketInit = (config, callBack) => {
-    state.chatConfig = config;
-    if (SocketIo && SocketIo.connected) return; // 如果socket已经连接,返回false
-    if (state.socketState.isConnecting) return; // 重连中,返回false
-
-    // 启动初始化
-    SocketIo = io(baseUrl + websocketPath, {
-      path:websocketPath,
-      query:{
-        token: getAccessToken()
-      },
-      reconnection: true, // 默认 true    是否断线重连
-      reconnectionAttempts: 5, // 默认无限次   断线尝试次数
-      reconnectionDelay: 1000, // 默认 1000,进行下一次重连的间隔。
-      reconnectionDelayMax: 5000, // 默认 5000, 重新连接等待的最长时间 默认 5000
-      randomizationFactor: 0.5, // 默认 0.5 [0-1],随机重连延迟时间
-      timeout: 20000, // 默认 20s
-      transports: ['websocket', 'polling'], // websocket | polling,
-      ...config,
-    });
-
-    // 监听连接
-    SocketIo.on('connect', async (res) => {
-      socketReset(callBack);
-      // socket连接
-      // 用户登录
-      // 顾客登录
-      console.log('socket:connect');
-    });
-    // 监听消息
-    SocketIo.on('message', (res) => {
-      if (res.error === 0) {
-        const { message, sender } = res.data;
-        state.chatList.push(formatMessage(res.data.message));
-
-        // 告诉父级页面
-        // window.parent.postMessage({
-        // 	chatDotNum: ++state.chatDotNum
-        // })
-        callBack && callBack();
-      }
-    });
-    // 监听客服接入成功
-    SocketIo.on('customer_service_access', (res) => {
-      if (res.error === 0) {
-        editCustomerServerInfo({
-          title: res.data.customer_service.name,
-          state: 'online',
-          avatar: res.data.customer_service.avatar,
-        });
-        state.chatList.push(formatMessage(res.data.message));
-        // callBack && callBack()
-      }
-    });
-    // 监听排队等待
-    SocketIo.on('waiting_queue', (res) => {
-      if (res.error === 0) {
-        editCustomerServerInfo({
-          title: res.data.title,
-          state: 'waiting',
-          avatar: '',
-        });
-        // callBack && callBack()
-      }
-    });
-    // 监听没有客服在线
-    SocketIo.on('no_customer_service', (res) => {
-      if (res.error === 0) {
-        editCustomerServerInfo({
-          title: '暂无客服在线...',
-          state: 'waiting',
-          avatar: '',
-        });
-      }
-      state.chatList.push(formatMessage(res.data.message));
-      // callBack && callBack()
-    });
-    // 监听客服上线
-    SocketIo.on('customer_service_online', (res) => {
-      if (res.error === 0) {
-        editCustomerServerInfo({
-          title: res.data.customer_service.name,
-          state: 'online',
-          avatar: res.data.customer_service.avatar,
-        });
-      }
-    });
-    // 监听客服下线
-    SocketIo.on('customer_service_offline', (res) => {
-      if (res.error === 0) {
-        editCustomerServerInfo({
-          title: res.data.customer_service.name,
-          state: 'offline',
-          avatar: res.data.customer_service.avatar,
-        });
-      }
-    });
-    // 监听客服忙碌
-    SocketIo.on('customer_service_busy', (res) => {
-      if (res.error === 0) {
-        editCustomerServerInfo({
-          title: res.data.customer_service.name,
-          state: 'busy',
-          avatar: res.data.customer_service.avatar,
-        });
-      }
-    });
-    // 监听客服断开链接
-    SocketIo.on('customer_service_break', (res) => {
-      if (res.error === 0) {
-        editCustomerServerInfo({
-          title: '客服服务结束',
-          state: 'offline',
-          avatar: '',
-        });
-        state.socketState.isConnect = false;
-        state.socketState.tip = '当前服务已结束';
-      }
-      state.chatList.push(formatMessage(res.data.message));
-      // callBack && callBack()
-    });
-    // 监听自定义错误 custom_error
-    SocketIo.on('custom_error', (error) => {
-      editCustomerServerInfo({
-        title: error.msg,
-        state: 'offline',
-        avatar: '',
-      });
-      console.log('custom_error:', error);
-    });
-    // 监听错误 error
-    SocketIo.on('error', (error) => {
-      console.log('error:', error);
-    });
-    // 重连失败 connect_error
-    SocketIo.on('connect_error', (error) => {
-      console.log('connect_error');
-    });
-    // 连接上,但无反应 connect_timeout
-    SocketIo.on('connect_timeout', (error) => {
-      console.log(error, 'connect_timeout');
-    });
-    // 服务进程销毁 disconnect
-    SocketIo.on('disconnect', (error) => {
-      console.log(error, 'disconnect');
-    });
-    // 服务重启重连上reconnect
-    SocketIo.on('reconnect', (error) => {
-      console.log(error, 'reconnect');
-    });
-    // 开始重连reconnect_attempt
-    SocketIo.on('reconnect_attempt', (error) => {
-      state.socketState.isConnect = false;
-      state.socketState.isConnecting = true;
-      editCustomerServerInfo({
-        title: `重连中,第${error}次尝试...`,
-        state: 'waiting',
-        avatar: '',
-      });
-      console.log(error, 'reconnect_attempt');
-    });
-    // 重新连接中reconnecting
-    SocketIo.on('reconnecting', (error) => {
-      console.log(error, 'reconnecting');
-    });
-    // 重新连接错误reconnect_error
-    SocketIo.on('reconnect_error', (error) => {
-      console.log('reconnect_error');
-    });
-    // 重新连接失败reconnect_failed
-    SocketIo.on('reconnect_failed', (error) => {
-      state.socketState.isConnecting = false;
-      editCustomerServerInfo({
-        title: `重连失败,请刷新重试~`,
-        state: 'waiting',
-        avatar: '',
-      });
-      console.log(error, 'reconnect_failed');
-
-      // setTimeout(() => {
-      state.isSendSucces = 1;
-      // }, 500)
-    });
-  };
-
-  // 重置socket
-  const socketReset = (callBack) => {
-    state.chatList = [];
-    state.chatHistoryList = [];
-    state.chatHistoryPagination = {
-      page: 0,
-      per_page: 10,
-      last_id: 0,
-      totalPage: 0,
-    };
-    socketConnection(callBack); // 连接
-  };
-
-  // 退出连接
-  const socketClose = () => {
-    SocketIo.emit('customer_logout', {}, (res) => {
-      console.log('socket:退出', res);
-    });
-  };
-
-  // 测试事件
-  const socketTest = () => {
-    SocketIo.emit('test', {}, (res) => {
-      console.log('test:test', res);
-    });
-  };
-
-  // 发送消息
-  const socketSendMsg = (data, sendMsgCallBack) => {
-    state.isSendSucces = -1;
-    state.chatList.push(data);
-    sendMsgCallBack && sendMsgCallBack();
-    SocketIo.emit(
-      'message',
-      {
-        message: formatInput(data),
-        ...data.customData,
-      },
-      (res) => {
-        // setTimeout(() => {
-        state.isSendSucces = res.error;
-        // }, 500)
-
-        // console.log(res, 'socket:send');
-        // sendMsgCallBack && sendMsgCallBack()
-      },
-    );
-  };
-
-  // 连接socket,存入sessionId
-  const socketConnection = (callBack) => {
-    SocketIo.emit(
-      'connection',
-      {
-        auth: 'user',
-        token: uni.getStorageSync('socketUserToken') || '',
-        session_id: uni.getStorageSync('socketSessionId') || '',
-      },
-      (res) => {
-        if (res.error === 0) {
-          socketCustomerLogin(callBack);
-          uni.setStorageSync('socketSessionId', res.data.session_id);
-          // uni.getStorageSync('socketUserToken') && socketLogin(uni.getStorageSync(
-          // 	'socketUserToken')) // 如果有用户token,绑定
-          state.customerUserInfo = res.data.chat_user;
-          state.socketState.isConnect = true;
-        } else {
-          editCustomerServerInfo({
-            title: `服务器异常!`,
-            state: 'waiting',
-            avatar: '',
-          });
-          state.socketState.isConnect = false;
-        }
-      },
-    );
-  };
-
-  // 获取token
-  const getAccessToken = () => {
-    return uni.getStorageSync('token');
-  };
-
-  // 用户登录
-  const socketLogin = (token) => {
-    SocketIo.emit(
-      'login',
-      {
-        token: token,
-      },
-      (res) => {
-        console.log(res, 'socket:login');
-        state.customerUserInfo = res.data.chat_user;
-      },
-    );
-  };
-
-  // 顾客登录
-  const socketCustomerLogin = (callBack) => {
-    SocketIo.emit(
-      'customer_login',
-      {
-        room_id: state.chatConfig.room_id,
-      },
-      (res) => {
-        state.templateChatList = res.data.questions.length ? res.data.questions : [];
-        state.chatList.push({
-          from: 'customer_service', // 用户customer右 |  顾客customer_service左 | 系统system中间
-          mode: 'template', // goods,order,image,text,system
-          date: new Date().getTime(), //时间
-          content: {
-            //内容
-            list: state.templateChatList,
-          },
-        });
-        res.error === 0 && socketHistoryList(callBack);
-      },
-    );
-  };
-
-  // 获取历史消息
-  const socketHistoryList = (historyCallBack) => {
-    state.chatHistoryPagination.loadStatus = 'loading';
-    state.chatHistoryPagination.page += 1;
-    SocketIo.emit('messages', state.chatHistoryPagination, (res) => {
-      if (res.error === 0) {
-        state.chatHistoryPagination.total = res.data.messages.total;
-        state.chatHistoryPagination.lastPage = res.data.messages.last_page;
-        state.chatHistoryPagination.page = res.data.messages.current_page;
-        res.data.messages.data.forEach((item) => {
-          item.message_type && state.chatList.unshift(formatMessage(item));
-        });
-        state.chatHistoryPagination.loadStatus =
-          state.chatHistoryPagination.page < state.chatHistoryPagination.lastPage
-            ? 'loadmore'
-            : 'nomore';
-        if (state.chatHistoryPagination.last_id == 0) {
-          state.chatHistoryPagination.last_id = res.data.messages.data.length
-            ? res.data.messages.data[0].id
-            : 0;
-        }
-        state.chatHistoryPagination.page === 1 && historyCallBack && historyCallBack();
-      }
-
-      // 历史记录之后,猜你想问
-      // state.chatList.push({
-      // 	from: 'customer_service', // 用户customer右 |  顾客customer_service左 | 系统system中间
-      // 	mode: 'template', // goods,order,image,text,system
-      // 	date: new Date().getTime(), //时间
-      // 	content: { //内容
-      // 		list: state.templateChatList
-      // 	}
-      // })
-    });
-  };
-
-  // 修改客服信息
-  const editCustomerServerInfo = (data) => {
-    state.customerServerInfo = {
-      ...state.customerServerInfo,
-      ...data,
-    };
-  };
-
-  /**
-   * ================
-   * 工具函数 ↓
-   * ===============
-   */
-
-  /**
-   * 是否显示时间
-   * @param {*} item - 数据
-   * @param {*} index - 索引
-   */
-  const showTime = (item, index) => {
-    if (unref(state.chatList)[index + 1]) {
-      let dateString = dayjs(unref(state.chatList)[index + 1].date).fromNow();
-      if (dateString === dayjs(unref(item).date).fromNow()) {
-        return false;
-      } else {
-        dateString = dayjs(unref(item).date).fromNow();
-        return true;
-      }
-    }
-    return false;
-  };
-
-  /**
-   * 格式化时间
-   * @param {*} time - 时间戳
-   */
-  const formatTime = (time) => {
-    let diffTime = new Date().getTime() - time;
-    if (diffTime > 28 * 24 * 60 * 1000) {
-      return dayjs(time).format('MM/DD HH:mm');
-    }
-    if (diffTime > 360 * 28 * 24 * 60 * 1000) {
-      return dayjs(time).format('YYYY/MM/DD HH:mm');
-    }
-    return dayjs(time).fromNow();
-  };
-
-  /**
-   * 获取焦点
-   * @param {*} virtualNode - 节点信息 ref
-   */
-  const getFocus = (virtualNode) => {
-    if (window.getSelection) {
-      let chatInput = unref(virtualNode);
-      chatInput.focus();
-      let range = window.getSelection();
-      range.selectAllChildren(chatInput);
-      range.collapseToEnd();
-    } else if (document.selection) {
-      let range = document.selection.createRange();
-      range.moveToElementText(chatInput);
-      range.collapse(false);
-      range.select();
-    }
-  };
-
-  /**
-   * 文件上传
-   * @param {Blob} file -文件数据流
-   * @return {path,fullPath}
-   */
-
-  const upload = (name, file) => {
-    return new Promise((resolve, reject) => {
-      let data = new FormData();
-      data.append('file', file, name);
-      data.append('group', 'chat');
-      ajax({
-        url: '/upload',
-        method: 'post',
-        headers: {
-          'Content-Type': 'multipart/form-data',
-        },
-        data,
-        success: function (res) {
-          resolve(res);
-        },
-        error: function (err) {
-          reject(err);
-        },
-      });
-    });
-  };
-
-  /**
-   * 粘贴到输入框
-   * @param {*} e  - 粘贴内容
-   * @param {*} uploadHttp - 上传图片地址
-   */
-  const onPaste = async (e) => {
-    let paste = e.clipboardData || window.clipboardData;
-    let filesArr = Array.from(paste.files);
-    filesArr.forEach(async (child) => {
-      if (child && child.type.includes('image')) {
-        e.preventDefault(); //阻止默认
-        let file = child;
-        const img = await readImg(file);
-        const blob = await compressImg(img, file.type);
-        const { data } = await upload(file.name, blob);
-        let image = `<img class="full-url" src='${data.fullurl}'>`;
-        document.execCommand('insertHTML', false, image);
-      } else {
-        document.execCommand('insertHTML', false, paste.getData('text'));
-      }
-    });
-  };
-
-  /**
-   * 拖拽到输入框
-   * @param {*} e  - 粘贴内容
-   * @param {*} uploadHttp - 上传图片地址
-   */
-  const onDrop = async (e) => {
-    e.preventDefault(); //阻止默认
-    let filesArr = Array.from(e.dataTransfer.files);
-    filesArr.forEach(async (child) => {
-      if (child && child.type.includes('image')) {
-        let file = child;
-        const img = await readImg(file);
-        const blob = await compressImg(img, file.type);
-        const { data } = await upload(file.name, blob);
-        let image = `<img class="full-url" src='${data.fullurl}' >`;
-        document.execCommand('insertHTML', false, image);
-      } else {
-        ElMessage({
-          message: '禁止拖拽非图片资源',
-          type: 'warning',
-        });
-      }
-    });
-  };
-
-  /**
-   * 解析富文本输入框内容
-   * @param {*}  virtualNode -节点信息
-   * @param {Function} formatInputCallBack - cb 回调
-   */
-  const formatChatInput = (virtualNode, formatInputCallBack) => {
-    let res = '';
-    let elemArr = Array.from(virtualNode.childNodes);
-    elemArr.forEach((child, index) => {
-      if (child.nodeName === '#text') {
-        //如果为文本节点
-        res += child.nodeValue;
-        if (
-          //文本节点的后面是图片,并且不是emoji,分开发送。输入框中的图片和文本表情分开。
-          elemArr[index + 1] &&
-          elemArr[index + 1].nodeName === 'IMG' &&
-          elemArr[index + 1] &&
-          elemArr[index + 1].name !== 'emoji'
-        ) {
-          const data = {
-            from: 'customer',
-            mode: 'text',
-            date: new Date().getTime(),
-            content: {
-              text: filterXSS(res),
-            },
-          };
-          formatInputCallBack && formatInputCallBack(data);
-          res = '';
-        }
-      } else if (child.nodeName === 'BR') {
-        res += '<br/>';
-      } else if (child.nodeName === 'IMG') {
-        // 有emjio 和 一般图片
-        // 图片解析后直接发送,不跟文字表情一组
-        if (child.name !== 'emoji') {
-          let srcReg = /src=[\'\']?([^\'\']*)[\'\']?/i;
-          let src = child.outerHTML.match(srcReg);
-          const data = {
-            from: 'customer',
-            mode: 'image',
-            date: new Date().getTime(),
-            content: {
-              url: src[1],
-              path: src[1].replace(/http:\/\/[^\/]*/, ''),
-            },
-          };
-          formatInputCallBack && formatInputCallBack(data);
-        } else {
-          // 非表情图片跟文字一起发送
-          res += child.outerHTML;
-        }
-      } else if (child.nodeName === 'DIV') {
-        res += `<div style='width:200px; white-space: nowrap;'>${child.outerHTML}</div>`;
-      }
-    });
-    if (res) {
-      const data = {
-        from: 'customer',
-        mode: 'text',
-        date: new Date().getTime(),
-        content: {
-          text: filterXSS(res),
-        },
-      };
-      formatInputCallBack && formatInputCallBack(data);
-    }
-    unref(virtualNode).innerHTML = '';
-  };
-
-  /**
-   * 状态回调
-   * @param {*} res -接口返回数据
-   */
-  const callBackNotice = (res) => {
-    ElNotification({
-      title: 'socket',
-      message: res.msg,
-      showClose: true,
-      type: res.error === 0 ? 'success' : 'warning',
-      duration: 1200,
-    });
-  };
-
-  /**
-   * 格式化发送信息
-   * @param {Object} message
-   * @returns  obj - 消息对象
-   */
-  const formatInput = (message) => {
-    let obj = {};
-    switch (message.mode) {
-      case 'text':
-        obj = {
-          message_type: 'text',
-          message: message.content.text,
-        };
-        break;
-      case 'image':
-        obj = {
-          message_type: 'image',
-          message: message.content.path,
-        };
-        break;
-      case 'goods':
-        obj = {
-          message_type: 'goods',
-          message: message.content.item,
-        };
-        break;
-      case 'order':
-        obj = {
-          message_type: 'order',
-          message: message.content.item,
-        };
-        break;
-      default:
-        break;
-    }
-    return obj;
-  };
-  /**
-   * 格式化接收信息
-   * @param {*} message
-   * @returns obj - 消息对象
-   */
-  const formatMessage = (message) => {
-    let obj = {};
-    switch (message.message_type) {
-      case 'system':
-        obj = {
-          from: 'system', // 用户customer左 |  顾客customer_service右 | 系统system中间
-          mode: 'system', // goods,order,image,text,system
-          date: message.create_time * 1000, //时间
-          content: {
-            //内容
-            text: message.message,
-          },
-        };
-        break;
-      case 'text':
-        obj = {
-          from: message.sender_identify,
-          mode: message.message_type,
-          date: message.create_time * 1000, //时间
-          sender: message.sender,
-          content: {
-            text: message.message,
-            messageId: message.id,
-          },
-        };
-        break;
-      case 'image':
-        obj = {
-          from: message.sender_identify,
-          mode: message.message_type,
-          date: message.create_time * 1000, //时间
-          sender: message.sender,
-          content: {
-            url: sheep.$url.cdn(message.message),
-            messageId: message.id,
-          },
-        };
-        break;
-      case 'goods':
-        obj = {
-          from: message.sender_identify,
-          mode: message.message_type,
-          date: message.create_time * 1000, //时间
-          sender: message.sender,
-          content: {
-            item: message.message,
-            messageId: message.id,
-          },
-        };
-        break;
-      case 'order':
-        obj = {
-          from: message.sender_identify,
-          mode: message.message_type,
-          date: message.create_time * 1000, //时间
-          sender: message.sender,
-          content: {
-            item: message.message,
-            messageId: message.id,
-          },
-        };
-        break;
-      default:
-        break;
-    }
-    return obj;
-  };
-
-  /**
-   * file 转换为 img
-   * @param {*} file  - file 文件
-   * @returns  img   - img标签
-   */
-  const readImg = (file) => {
-    return new Promise((resolve, reject) => {
-      const img = new Image();
-      const reader = new FileReader();
-      reader.onload = function (e) {
-        img.src = e.target.result;
-      };
-      reader.onerror = function (e) {
-        reject(e);
-      };
-      reader.readAsDataURL(file);
-      img.onload = function () {
-        resolve(img);
-      };
-      img.onerror = function (e) {
-        reject(e);
-      };
-    });
-  };
-
-  /**
-   * 压缩图片
-   *@param img -被压缩的img对象
-   * @param type -压缩后转换的文件类型
-   * @param mx -触发压缩的图片最大宽度限制
-   * @param mh -触发压缩的图片最大高度限制
-   * @returns blob - 文件流
-   */
-  const compressImg = (img, type = 'image/jpeg', mx = 1000, mh = 1000, quality = 1) => {
-    return new Promise((resolve, reject) => {
-      const canvas = document.createElement('canvas');
-      const context = canvas.getContext('2d');
-      const { width: originWidth, height: originHeight } = img;
-      // 最大尺寸限制
-      const maxWidth = mx;
-      const maxHeight = mh;
-      // 目标尺寸
-      let targetWidth = originWidth;
-      let targetHeight = originHeight;
-      if (originWidth > maxWidth || originHeight > maxHeight) {
-        if (originWidth / originHeight > 1) {
-          // 宽图片
-          targetWidth = maxWidth;
-          targetHeight = Math.round(maxWidth * (originHeight / originWidth));
-        } else {
-          // 高图片
-          targetHeight = maxHeight;
-          targetWidth = Math.round(maxHeight * (originWidth / originHeight));
-        }
-      }
-      canvas.width = targetWidth;
-      canvas.height = targetHeight;
-      context.clearRect(0, 0, targetWidth, targetHeight);
-      // 图片绘制
-      context.drawImage(img, 0, 0, targetWidth, targetHeight);
-      canvas.toBlob(
-        function (blob) {
-          resolve(blob);
-        },
-        type,
-        quality,
-      );
-    });
-  };
-
-  return {
-    compressImg,
-    readImg,
-    formatMessage,
-    formatInput,
-    callBackNotice,
-
-    socketInit,
-    socketSendMsg,
-    socketClose,
-    socketHistoryList,
-
-    getFocus,
-    formatChatInput,
-    onDrop,
-    onPaste,
-    upload,
-    state,
-
-    socketTest,
-
-    showTime,
-    formatTime,
-  };
-}

+ 2 - 2
sheep/api/promotion/kefu.js

@@ -1,7 +1,7 @@
 import request from '@/sheep/request';
 
 const KeFuApi = {
-  sendMessage: (data) => {
+  sendKefuMessage: (data) => {
     return request({
       url: '/promotion/kefu-message/send',
       method: 'POST',
@@ -15,7 +15,7 @@ const KeFuApi = {
       },
     });
   },
-  getMessageListPage: (params) => {
+  getKefuMessagePage: (params) => {
     return request({
       url: '/promotion/kefu-message/page',
       method: 'GET',