kuaifan 5 éve
szülő
commit
3a28e4153e

+ 5 - 1
app/Http/Controllers/IndexController.php

@@ -92,10 +92,14 @@ class IndexController extends Controller
         if (!$scale[0] && !$scale[1]) {
             $scale = [2160, 4160, -1];
         }
+        $path = "uploads/picture/" . Users::token2userid() . "/" . date("Ym") . "/";
+        if (Request::input('from') == 'chat') {
+            $path = "uploads/chat/" . Users::token2userid() . "/" . date("Ym") . "/";
+        }
         $data = Base::upload([
             "file" => Request::file('image'),
             "type" => 'image',
-            "path" => "uploads/picture/" . Users::token2userid() . "/" . date("Ym") . "/",
+            "path" => $path,
             "scale" => $scale
         ]);
         if (Base::isError($data)) {

+ 5 - 0
package-lock.json

@@ -12678,6 +12678,11 @@
                 "clipboard": "^2.0.0"
             }
         },
+        "vue-emoji-picker": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/vue-emoji-picker/-/vue-emoji-picker-1.0.1.tgz",
+            "integrity": "sha512-phisHAaSg+7xnpi7xlOxFGD46npaQXCLit2T6nAHMlEcFNT1ZUqu/NO3P5FDp6RgjP7o4ueduktnxk9ul0IS9Q=="
+        },
         "vue-hot-reload-api": {
             "version": "2.3.4",
             "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",

+ 1 - 0
package.json

@@ -35,6 +35,7 @@
         "view-design": "^4.2.0",
         "vuedraggable": "^2.23.2",
         "vue-clipboard2": "^0.3.1",
+        "vue-emoji-picker": "^1.0.1",
         "vue-kityminder-gg": "^1.2.3",
         "x-data-spreadsheet": "^1.1.2"
     }

+ 16 - 1
resources/assets/js/main/components/ImgUpload.vue

@@ -26,7 +26,7 @@
                             ref="upload"
                             accept="image/*"
                             :action="actionUrl"
-                            :data="params"
+                            :data="uploadParams"
                             :show-upload-list="false"
                             :max-size="2048"
                             :format="['jpg', 'jpeg', 'gif', 'png']"
@@ -308,6 +308,12 @@
                 type: Boolean,
                 default: false
             },
+            otherParams: {
+                type: Object,
+                default: () => {
+                    return {};
+                }
+            },
         },
         data () {
             return {
@@ -363,6 +369,15 @@
                 this.httpValue = '';
             }
         },
+        computed: {
+            uploadParams() {
+                if (Object.keys(this.otherParams).length > 0) {
+                    return Object.assign(this.params, this.otherParams);
+                } else {
+                    return this.params;
+                }
+            }
+        },
         methods: {
             handleCallback(file) {
                 if (this.type === 'callback') {

+ 26 - 0
resources/assets/js/main/components/WHeader.vue

@@ -106,10 +106,36 @@
         </WDrawer>
         <WDrawer v-model="chatDrawerShow" :closable="false" maxWidth="1080">
             <chat-index></chat-index>
+            <div class="w-header-chat-close" @click="chatDrawerShow=false">
+                <Icon type="ios-close" />
+            </div>
         </WDrawer>
     </div>
 </template>
 
+<style lang="scss">
+    .w-header-chat-close {
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        z-index: 1;
+        color: #ffffff;
+        font-size: 32px;
+        width: 68px;
+        height: 58px;
+        line-height: 58px;
+        text-align: center;
+        cursor: pointer;
+        > i {
+            transition: all 0.2s;
+        }
+        &:hover {
+            > i {
+                transform: scale(1.12) rotate(90deg);
+            }
+        }
+    }
+</style>
 <style lang="scss" scoped>
     .w-header {
         z-index: 15;

+ 117 - 13
resources/assets/js/main/components/chat/Index.vue

@@ -69,8 +69,26 @@
                 <textarea ref="textarea" class="manage-input" v-model="messageText" placeholder="请输入要发送的消息" @keydown="messageSend($event)"></textarea>
             </div>
             <div class="manage-quick">
-                <Button type="primary" size="small">表情</Button>
-                <Button type="warning" size="small">清除聊天记录</Button>
+                <emoji-picker @emoji="messageInsertText" :search="messageEmojiSearch">
+                    <div slot="emoji-invoker" slot-scope="{ events: { click: clickEvent } }" @click.stop="clickEvent">
+                        <Icon class="quick-item" type="ios-happy-outline"  />
+                    </div>
+                    <div slot="emoji-picker" slot-scope="{ emojis, insert, display }">
+                        <div class="emoji-box">
+                            <Input class="emoji-input" placeholder="搜索" v-model="messageEmojiSearch" prefix="ios-search"/>
+                            <div>
+                                <div v-for="(emojiGroup, category) in emojis" :key="category">
+                                    <h5>{{ category }}</h5>
+                                    <div class="emojis">
+                                        <span v-for="(emoji, emojiName) in emojiGroup" :key="emojiName" @click="insert(emoji)" :title="emojiName">{{ emoji }}</span>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </emoji-picker>
+                <Icon class="quick-item" type="ios-photos-outline" @click="$refs.messageUpload.handleClick()"/>
+                <img-upload ref="messageUpload" class="message-upload" type="callback" @on-callback="messageInsertImage" num="3" :otherParams="{from:'chat'}"></img-upload>
             </div>
         </div>
 
@@ -323,7 +341,7 @@
                     font-size: 14px;
                     box-sizing: border-box;
                     padding: 0;
-                    margin: 38px 8px 6px;
+                    margin: 38px 10px 6px;
                     border: 0;
                     line-height: 20px;
                     box-shadow: none;
@@ -350,10 +368,59 @@
                 right: 0;
                 bottom: 79px;
                 padding: 8px;
-                > button,
-                .quick-button {
-                    font-size: 12px;
-                    margin-right: 4px;
+                display: flex;
+                align-items: center;
+                .quick-item {
+                    color: #444444;
+                    font-size: 24px;
+                    margin-right: 12px;
+                }
+                .emoji-box {
+                    position: absolute;
+                    left: 0;
+                    bottom: 40px;
+                    max-height: 320px;
+                    width: 100%;
+                    overflow: auto;
+                    background-color: #ffffff;
+                    padding: 12px;
+                    border-bottom: 1px solid #efefef;
+                    .emoji-input {
+                        margin: 6px 0;
+                    }
+                    h5 {
+                        padding: 0;
+                        margin: 8px 0 0 0;
+                        color: #b1b1b1;
+                        text-transform: uppercase;
+                        font-size: 14px;
+                        cursor: default;
+                        font-weight: normal;
+                    }
+                    .emojis {
+                        display: flex;
+                        flex-wrap: wrap;
+                        justify-content: space-between;
+                        &:after {
+                            content: "";
+                            flex: auto;
+                        }
+                        span {
+                            padding: 2px 4px;
+                            cursor: pointer;
+                            font-size: 22px;
+                            &:hover {
+                                background: #ececec;
+                                cursor: pointer;
+                            }
+                        }
+                    }
+                }
+                .message-upload {
+                    display: none;
+                    width: 0;
+                    height: 0;
+                    overflow: hidden;
                 }
             }
             @media screen and (max-width: 768px) {
@@ -368,9 +435,9 @@
                 }
                 .manage-quick {
                     bottom: 54px;
-                    > button,
-                    .quick-button {
-                        margin-right: 2px;
+                    .quick-item {
+                        font-size: 24px;
+                        margin-right: 8px;
                     }
                 }
             }
@@ -378,12 +445,15 @@
     }
 </style>
 <script>
+    import EmojiPicker from 'vue-emoji-picker'
     import DrawerTabsContainer from "../DrawerTabsContainer";
     import ScrollerY from "../../../_components/ScrollerY";
     import ChatMessage from "./message";
+    import ImgUpload from "../ImgUpload";
+
     export default {
         name: 'ChatIndex',
-        components: {ChatMessage, ScrollerY, DrawerTabsContainer},
+        components: {ImgUpload, ChatMessage, EmojiPicker, ScrollerY, DrawerTabsContainer},
         data () {
             return {
                 loadIng: 0,
@@ -405,6 +475,7 @@
                 messageText: '',
                 messageLists: [],
                 messageNoDataText: '',
+                messageEmojiSearch: '',
             }
         },
 
@@ -461,6 +532,11 @@
                 if (val === 'team' && this.teamReady == false) {
                     this.teamReady = true;
                     this.getTeamLists();
+                } else if (val === 'dialog') {
+                    this.autoBottom = true;
+                    this.$nextTick(() => {
+                        this.messageBottomGo();
+                    });
                 }
             },
             dialogTarget: {
@@ -478,9 +554,9 @@
                     if ($A.formatDate('Ymd') === $A.formatDate('Ymd', v)) {
                         string = $A.formatDate('H:i', v)
                     } else if ($A.formatDate('Y') === $A.formatDate('Y', v)) {
-                        string = $A.formatDate('m-d H:i', v)
+                        string = $A.formatDate('m-d', v)
                     } else {
-                        string = $A.formatDate('Y-m-d H:i', v)
+                        string = $A.formatDate('Y-m-d', v)
                     }
                 }
                 return string || '';
@@ -640,6 +716,34 @@
                 });
             },
 
+            messageInsertText(emoji) {
+                this.messageText+= emoji;
+            },
+
+            messageInsertImage(lists) {
+                for (let i = 0; i < lists.length; i++) {
+                    let item = lists[i];
+                    if (typeof item === 'object' && typeof item.url === "string") {
+                        let data = {
+                            type: 'image',
+                            username: this.userInfo.username,
+                            userimg: this.userInfo.userimg,
+                            indate: Math.round(new Date().getTime() / 1000),
+                            url: item.url
+                        };
+                        $A.WS.sendTo('user', this.dialogTarget.username, data, (res) => {
+                            this.$set(data, res.status === 1 ? 'id' : 'error', res.message)
+                        });
+                        //
+                        this.openDialog(this.dialogTarget, {
+                            lasttext: '[图片]',
+                            lastdate: data.indate
+                        });
+                        this.addMessageData(data, true);
+                    }
+                }
+            },
+
             addMessageData(data, animation = false) {
                 data.self = data.username === this.userInfo.username;
                 let sikp = false;

+ 4 - 4
resources/assets/js/main/components/chat/message.vue

@@ -169,8 +169,8 @@
         display: inline-block;
         text-decoration: none;
         .item-image-view {
-            max-width: 320px;
-            max-height: 320px;
+            max-width: 220px;
+            max-height: 220px;
             border-radius: 6px;
         }
     }
@@ -210,9 +210,9 @@
                     if ($A.formatDate('Ymd') === $A.formatDate('Ymd', v)) {
                         string = $A.formatDate('H:i', v)
                     } else if ($A.formatDate('Y') === $A.formatDate('Y', v)) {
-                        string = $A.formatDate('m-d H:i', v)
+                        string = $A.formatDate('m-d', v)
                     } else {
-                        string = $A.formatDate('Y-m-d H:i', v)
+                        string = $A.formatDate('Y-m-d', v)
                     }
                 }
                 return string ? '(' + string + ')' : '';