Bladeren bron

no message

kuaifan 5 jaren geleden
bovenliggende
commit
146fd5496e

+ 12 - 1
app/Http/Controllers/Api/ChatController.php

@@ -50,14 +50,25 @@ class ChatController extends Controller
         if (count($lists) <= 0) {
             return Base::retError('暂无对话记录');
         }
+        $hasUnset = false;
         foreach ($lists AS $key => $item) {
-            $lists[$key] = array_merge($item, Users::username2basic($item['user1'] == $user['username'] ? $item['user2'] : $item['user1']));
+            $tmpUserInfo = Users::username2basic($item['user1'] == $user['username'] ? $item['user2'] : $item['user1']);
+            if (empty($tmpUserInfo)) {
+                DB::table('chat_dialog')->where('id', $item['id'])->update(['del1' => 1, 'del2' => 1]);
+                $hasUnset = true;
+                unset($lists[$key]);
+                continue;
+            }
+            $lists[$key] = array_merge($item, $tmpUserInfo);
             $lists[$key]['lastdate'] = $item['lastdate'] ?: $item['indate'];
             $unread = 0;
             if ($item['user1'] == $user['username']) $unread+= $item['unread1'];
             if ($item['user2'] == $user['username']) $unread+= $item['unread2'];
             $lists[$key]['unread'] = $unread;
         }
+        if ($hasUnset) {
+            $lists = array_values($lists);
+        }
         return Base::retSuccess('success', $lists);
     }
 

+ 8 - 3
app/Http/Controllers/Api/ProjectController.php

@@ -449,6 +449,14 @@ class ProjectController extends Controller
             'delete' => 1,
             'deletedate' => Base::time()
         ]);
+        DB::table('project_task')->where('projectid', $projectDetail['id'])->update([
+            'delete' => 1,
+            'deletedate' => Base::time()
+        ]);
+        DB::table('project_files')->where('projectid', $projectDetail['id'])->update([
+            'delete' => 1,
+            'deletedate' => Base::time()
+        ]);
         DB::table('project_log')->insert([
             'type' => '日志',
             'projectid' => $projectDetail['id'],
@@ -1079,7 +1087,6 @@ class ProjectController extends Controller
             $whereArray[] = ['project_task.createuser', '=', $user['username']];
             if ($projectid > 0) {
                 $whereArray[] = ['project_lists.id', '=', $projectid];
-                $whereArray[] = ['project_lists.delete', '=', 0];
             }
             if (trim(Request::input('username'))) {
                 $whereArray[] = ['project_task.username', '=', trim(Request::input('username'))];
@@ -1087,7 +1094,6 @@ class ProjectController extends Controller
         } else if (intval(Request::input('attention')) === 1) {
             if ($projectid > 0) {
                 $whereArray[] = ['project_lists.id', '=', $projectid];
-                $whereArray[] = ['project_lists.delete', '=', 0];
             }
             if (trim(Request::input('username'))) {
                 $whereArray[] = ['project_task.username', '=', trim(Request::input('username'))];
@@ -1095,7 +1101,6 @@ class ProjectController extends Controller
         } else {
             if ($projectid > 0) {
                 $whereArray[] = ['project_lists.id', '=', $projectid];
-                $whereArray[] = ['project_lists.delete', '=', 0];
                 if (trim(Request::input('username'))) {
                     $whereArray[] = ['project_task.username', '=', trim(Request::input('username'))];
                 }

+ 1 - 1
app/Module/Chat.php

@@ -195,7 +195,7 @@ class Chat
         if (!is_array($array)) {
             $array = [];
         }
-        //messageType来自客户端(前端->后端):refresh/unread/read/roger/user/info/team
+        //messageType来自客户端(前端->后端):refresh/unread/read/roger/user/info/team/docs
         //messageType来自服务端(后端->前端):error/open/kick/user/back/unread
         if (!isset($array['messageType'])) $array['messageType'] = '';  //消息类型
         if (!isset($array['messageId'])) $array['messageId'] = '';      //消息ID(用于back给客户端)

+ 25 - 0
app/Services/WebSocketService.php

@@ -292,6 +292,31 @@ class WebSocketService implements WebSocketHandlerInterface
                     Task::deliver($pushTask);
                 }
                 break;
+
+            /**
+             * 知识库协作
+             */
+            case 'docs':
+                $back['message'] = [];
+                if ($data['body']['type'] === 'enter') {
+                    $sid = intval($data['body']['sid']);
+                    if ($sid > 0) {
+                        $array = Base::json2array(Cache::get("docs::" . $sid));
+                        if ($array) {
+                            foreach ($array AS $uname => $vbody) {
+                                if (intval($vbody['indate']) + 10 < time()) {
+                                    unset($array[$uname]);
+                                }
+                            }
+                        }
+                        $array[$data['body']['username']] = $data['body'];
+                        Cache::put("docs::" . $sid, Base::array2json($array), 30);
+                        //
+                        ksort($array);
+                        $back['message'] = array_values($array);
+                    }
+                }
+                break;
         }
         if ($data['messageId']) {
             $pushLists = [];

+ 4 - 3
resources/assets/js/main/main.js

@@ -704,9 +704,10 @@ import '../../sass/main.scss';
              * - unread: 未读信息总数量
              * - read: 已读会员信息
              * - roger: 收到信息回执
-             * - user: 指定target
-             * - update: 指定target
+             * - user: 发送消息,指定target
+             * - info: 发送消息(不保存),指定target
              * - team: 团队会员
+             * - docs: 知识库
              * @param target            发送目标
              * @param body              发送内容(对象或数组)
              * @param callback          发送回调
@@ -749,7 +750,7 @@ import '../../sass/main.scss';
                     }
                     return this;
                 }
-                if (['refresh', 'unread', 'read', 'roger', 'user', 'info', 'team'].indexOf(messageType) === -1) {
+                if (['refresh', 'unread', 'read', 'roger', 'user', 'info', 'team', 'docs'].indexOf(messageType) === -1) {
                     this.__log("[WS] Wrong message messageType: " + messageType);
                     typeof callback === "function" && callback({status: 0, message: '错误的消息类型: ' + messageType});
                     return this;

+ 88 - 1
resources/assets/js/main/pages/docs/edit.vue

@@ -10,6 +10,16 @@
                 <!--<div class="header-menu" @click="handleClick('share')"><Icon type="md-share" /></div>
                 <div class="header-menu" @click="handleClick('view')"><Icon type="md-eye" /></div>-->
                 <div class="header-menu" @click="handleClick('history')"><Icon type="md-time" /></div>
+                <Poptip class="header-menu synch">
+                    <Icon type="md-contacts" :title="$L('正在协作会员')"/><em v-if="synchUsers.length > 0">{{synchUsers.length}}</em>
+                    <ul class="synch-lists" slot="content">
+                        <li class="title">{{$L('正在协作会员')}}:</li>
+                        <li v-for="item in synchUsersS">
+                            <img class="synch-userimg" :src="item.userimg"/>
+                            <user-view class="synch-username" placement="right" :username="item.username"/>
+                        </li>
+                    </ul>
+                </Poptip>
                 <div class="header-title">{{docDetail.title}}</div>
                 <div v-if="docDetail.type=='mind'" class="header-hint">{{$L('选中节点,按enter键添加子节点,tab键添加同级节点')}}</div>
                 <Button :disabled="(disabledBtn || loadIng > 0) && hid == 0" class="header-button" size="small" type="primary" @click="handleClick('save')">{{$L('保存')}}</Button>
@@ -122,11 +132,41 @@
                     .ivu-icon {
                         font-size: 16px;
                     }
+                    &.synch {
+                        em {
+                            padding-left: 2px;
+                        }
+                    }
                     &:hover,
                     &.active {
                         color: #fff;
                         background: #059DFD;
                     }
+                    .synch-lists {
+                        max-height: 500px;
+                        overflow: auto;
+                        li {
+                            display: flex;
+                            align-items: center;
+                            padding: 6px 0;
+                            border-bottom: 1px dashed #eeeeee;
+                            &.title {
+                                font-size: 14px;
+                                font-weight: 600;
+                                color: #333333;
+                            }
+                            .synch-userimg {
+                                width: 24px;
+                                height: 24px;
+                                border-radius: 50%;
+                            }
+                            .synch-username {
+                                padding-left: 8px;
+                                font-size: 14px;
+                                color: #555555;
+                            }
+                        }
+                    }
                 }
                 .header-title {
                     flex: 1;
@@ -198,6 +238,12 @@
                 historyColumns: [],
                 historyLists: [],
                 historyNoDataText: "",
+
+                userInfo: {},
+
+                routeName: '',
+                synergyNum: 0,
+                synchUsers: [],
             }
         },
         created() {
@@ -256,10 +302,16 @@
             }];
         },
         mounted() {
-
+            this.routeName = this.$route.name;
+            this.userInfo = $A.getUserInfo((res, isLogin) => {
+                if (this.userInfo.id != res.id) {
+                    this.userInfo = res;
+                }
+            }, false);
         },
         activated() {
             this.refreshSid();
+            this.synergy();
         },
         deactivated() {
             this.docDrawerShow = false;
@@ -350,9 +402,44 @@
         computed: {
             disabledBtn() {
                 return this.bakContent == $A.jsonStringify(this.docContent);
+            },
+            synchUsersS() {
+                let temp = Math.round(new Date().getTime() / 1000);
+                return this.synchUsers.filter(item => {
+                    return item.indate + 10 > temp;
+                });
             }
         },
         methods: {
+            synergy() {
+                if (this.routeName !== this.$route.name) {
+                    let tmpNum = this.synergyNum;
+                    setTimeout(() => {
+                        if (tmpNum === this.synergyNum) {
+                            this.synergyNum++;
+                            this.synergy();
+                        }
+                    }, 5000);
+                    return;
+                }
+                $A.WSOB.sendTo('docs', null, {
+                    type: 'enter',
+                    sid: this.sid,
+                    username: this.userInfo.username,
+                    userimg: this.userInfo.userimg,
+                    indate: Math.round(new Date().getTime() / 1000),
+                }, (res) => {
+                    this.synchUsers = res.status === 1 ? res.message : [];
+                    let tmpNum = this.synergyNum;
+                    setTimeout(() => {
+                        if (tmpNum === this.synergyNum) {
+                            this.synergyNum++;
+                            this.synergy();
+                        }
+                    }, 5000);
+                });
+            },
+
             refreshSid() {
                 this.sid = this.$route.params.sid;
                 if (typeof this.$route.params.other === "object") {

File diff suppressed because it is too large
+ 870 - 0
resources/assets/statics/public/css/fonts/ionicons.svg


BIN
resources/assets/statics/public/css/fonts/ionicons.ttf


BIN
resources/assets/statics/public/css/fonts/ionicons.woff


BIN
resources/assets/statics/public/css/fonts/ionicons.woff2


File diff suppressed because it is too large
+ 1 - 0
resources/assets/statics/public/css/iview.css


File diff suppressed because it is too large
+ 7 - 0
resources/assets/statics/public/js/bootstrap.min.js


File diff suppressed because it is too large
+ 2 - 0
resources/assets/statics/public/js/jquery.min.js


+ 23 - 1
resources/lang/en/general.js

@@ -9,7 +9,7 @@ export default {
     "确定": "Determine",
     "自定义地址": "Custom address",
     "关闭": "Shut down",
-    "完成": "Carry out",
+    "完成": "Complete",
     "查看图片": "View image",
     "上传失败": "Upload failed",
     "文件 % 上传失败 %": "File upload failed%%",
@@ -398,4 +398,26 @@ export default {
     "你确定设置管理员的操作吗?": "Are you sure to set the administrator's action?",
     "您的管理员身份已被撤销。": "Your administrator status has been revoked.",
     "恭喜您成为管理员。": "Congratulations on becoming an administrator.",
+    "表情": "Emoji",
+    "语音聊天": "Voice chat",
+    "视频聊天": "Video chat",
+    "正在视频通话...": "On a video call...",
+    "正在语音通话...": "On a voice call...",
+    "对方:": "Person: ",
+    "当前浏览器不支持音视频通话!": "Current browser does not support audio/video calls!",
+    "浏览器不支持音视频通话!": "The browser does not support audio and video calls!",
+    "呼叫失败!": "Call failed!",
+    "视频通话": "Video call",
+    "语音通话": "Voice call",
+    "对方:拒绝接听": "Person: Refuse to answer",
+    "邀请视频通话...": "Invite video calls...",
+    "邀请语音通话...": "Inviting voice calls...",
+    "拒绝": "Refused",
+    "接受": "Accept",
+    "通话时长:%": "Length of call: %",
+    "音视频通话": "Audio video call",
+    "开启": "Open",
+    "[语音通话]": "[Voice call]",
+    "[视频通话]": "[Video call]",
+    "正在协作会员": "Collaborating member",
 }

+ 3 - 0
resources/lang/en/general.php

@@ -118,4 +118,7 @@ return [
     "项目流程最多不能超过%个!" => "The maximum number of project flows should not exceed %!",
     "列表最多不能超过%个!" => "No more than % lists!",
     "当前环境禁止修改!" => "No changes to the current environment!",
+    "[语音通话]" => "[Voice call]",
+    "[视频通话]" => "[Video call]",
+    "发送内容长度已超出最大限制!" => "The content length has exceeded the maximum limit!",
 ];

+ 3 - 3
resources/views/main.blade.php

@@ -11,9 +11,9 @@
     <meta name="csrf-token" content="{{ csrf_token() }}">
     <title>{{ config('app.name', 'WebPage') }}</title>
     <link rel="stylesheet" type="text/css" href="{{ mix('css/app.css') }}"/>
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/view-design@4.2.0/dist/styles/iview.css">
-    <script src="//cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
-    <script src="//cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/js/bootstrap.min.js"></script>
+    <link rel="stylesheet" href="{{ mix('css/iview.css') }}">
+    <script src="{{ mix('js/jquery.min.js') }}"></script>
+    <script src="{{ mix('js/bootstrap.min.js') }}"></script>
     <script>
         window.csrfToken = { csrfToken : "{{ csrf_token() }}" };
         window.webSocketConfig = { URL: "{{ env('LARAVELS_PROXY_URL') }}" };