Bläddra i källkod

用户头像文字化

kuaifan 5 år sedan
förälder
incheckning
c04baff310

+ 1 - 1
package.json

@@ -1,5 +1,5 @@
 {
-    "version": "1.4.24",
+    "version": "1.4.25",
     "name": "wookteam",
     "private": true,
     "scripts": {

+ 2 - 0
resources/assets/js/main/app.js

@@ -16,12 +16,14 @@ import Title from '../_components/Title.vue'
 import sreachTitle from '../_components/sreachTitle.vue'
 import UserInput from './components/UserInput'
 import UserView from './components/UserView'
+import UserImg from './components/UserImg'
 import WLoading from './components/WLoading'
 
 Vue.component('VTitle', Title);
 Vue.component('sreachTitle', sreachTitle);
 Vue.component('UserInput', UserInput);
 Vue.component('UserView', UserView);
+Vue.component('UserImg', UserImg);
 Vue.component('WLoading', WLoading);
 
 import TaskDetail from './components/project/task/detail'

+ 22 - 38
resources/assets/js/main/components/FullCalendar/components/body.vue

@@ -25,7 +25,7 @@
                                      :style="`background-color: ${showCard == event.id ? (event.selectedColor||'#C7E6FD') : (event.color||'#C7E6FD')}`"
                                      @click="eventClick(event,$event)">
                                     <img class="avatar" v-if="event.avatar" :src="event.avatar" @error="($set(event, 'avatar', null))"/>
-                                    <span v-else :class="`icon icon${event.id%4}`">{{event.name}}</span>
+                                    <span v-else class="icon" :style="iconStyle(event.name)">{{event.name}}</span>
                                     <p class="info" v-html="isBegin(event, day.date, day.weekDay)"></p>
                                     <div id="card" :class="cardClass" v-if="$slots['body-card'] && event && showCard == event.id" @click.stop>
                                         <slot name="body-card"></slot>
@@ -64,7 +64,7 @@
                                  v-if="isTheday(item.date, event.start) && isInTime(time, event.start)"
                                  @click="eventClick(event,$event)">
                                 <img class="avatar" v-if="event.avatar" :src="event.avatar" @error="($set(event, 'avatar', null))"/>
-                                <span v-else :class="`icon icon${event.id%4}`">{{event.name}}</span>
+                                <span v-else class="icon" :style="iconStyle(event.name)">{{event.name}}</span>
                                 <p class="info" v-html="event.title"></p>
                                 <div id="card" :class="cardClass" v-if="$slots['body-card'] && event && showCard == event.id" @click.stop>
                                     <slot name="body-card"></slot>
@@ -335,6 +335,22 @@
                     this.cardClass += ' ' + 'bottom-card'
                 }
             },
+            isEmojiPrefix(text) {
+                return /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(text);
+            },
+            iconStyle(name) {
+                const style = {
+                    backgroundColor: '#A0D7F1'
+                };
+                if (name) {
+                    let bgColor = '';
+                    for (let i = 0; i < name.length; i++) {
+                        bgColor += parseInt(name[i].charCodeAt(0), 10).toString(16);
+                    }
+                    style.backgroundColor = '#' + bgColor.slice(1, 4);
+                }
+                return style;
+            }
         }
     }
 </script>
@@ -486,22 +502,6 @@
                                         text-align: center;
                                         color: #fff;
                                         display: inline-block;
-
-                                        &.icon0 {
-                                            background: #27BA9C;
-                                        }
-
-                                        &.icon1 {
-                                            background: #5272FF;
-                                        }
-
-                                        &.icon2 {
-                                            background: #FFCC36;
-                                        }
-
-                                        &.icon3 {
-                                            background: #FF7062;
-                                        }
                                     }
 
                                     .info {
@@ -554,14 +554,14 @@
                                     }
 
                                     &.selected {
-                                        .info {
+                                        /*.info {
                                             color: #fff;
                                             font-weight: normal;
                                         }
 
                                         .icon {
                                             background-color: transparent !important;
-                                        }
+                                        }*/
                                     }
                                 }
 
@@ -698,22 +698,6 @@
                             display: inline-block;
                             padding: 0 2px;
                             overflow: hidden;
-
-                            &.icon0 {
-                                background: #27BA9C;
-                            }
-
-                            &.icon1 {
-                                background: #5272FF;
-                            }
-
-                            &.icon2 {
-                                background: #FFCC36;
-                            }
-
-                            &.icon3 {
-                                background: #FF7062;
-                            }
                         }
 
                         .info {
@@ -766,7 +750,7 @@
                         }
 
                         &.selected {
-                            .info {
+                            /*.info {
                                 color: #fff;
                                 font-weight: normal;
                             }
@@ -774,7 +758,7 @@
                             // background-color: #5272FF !important;
                             .icon {
                                 background-color: transparent !important;
-                            }
+                            }*/
                         }
                     }
 

+ 117 - 0
resources/assets/js/main/components/UserImg.vue

@@ -0,0 +1,117 @@
+<template>
+    <div class="userimg-container" @click="onClick">
+        <template v-if="this.isJson(info)">
+            <img v-if="isShowImg(userImg)&&!imgError" class="userimg-container-img" :src="userImg" @error="imgError=true"/>
+            <div v-else class="userimg-container-box" :style="textStyle">
+                <div class="usertext-container-text">{{userName}}</div>
+            </div>
+        </template>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+    .userimg-container {
+        display: inline-block;
+        max-width: 100%;
+        max-height: 100%;
+        position: relative;
+        overflow: hidden;
+        .userimg-container-img {
+            width: 100%;
+            height: 100%;
+            display: table;
+        }
+        .userimg-container-box {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            font-weight: 400;
+            color: #ffffff;
+
+            .usertext-container-text {
+                flex: 1;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+            }
+        }
+    }
+</style>
+<script>
+    export default {
+        name: 'UserImg',
+        props: {
+            info: {
+                default: {} //{username, nickname, userimg}
+            },
+            size: {
+
+            }
+        },
+        data() {
+            return {
+                imgError: false,
+            }
+        },
+        computed: {
+            textStyle() {
+                const style = {
+                    backgroundColor: '#A0D7F1'
+                };
+                const {size} = this;
+                if (size) {
+                    style.fontSize = /^\d+$/.test(size) ? (size + 'px') : size;
+                }
+                const {username} = this.info;
+                if (username) {
+                    let bgColor = '';
+                    for (let i = 0; i < username.length; i++) {
+                        bgColor += parseInt(username[i].charCodeAt(0), 10).toString(16);
+                    }
+                    style.backgroundColor = '#' + bgColor.slice(1, 4);
+                }
+                return style;
+            },
+
+            userName() {
+                if (!this.isJson(this.info)) {
+                    return '';
+                }
+                let name = this.info.send_username || this.info.username;
+                if (this.info.nickname && !this.isEmojiPrefix(this.info.nickname)) {
+                    name = this.info.nickname;
+                }
+                return (name + " ").substring(0, 1).toLocaleUpperCase();
+            },
+
+            userImg() {
+                if (!this.isJson(this.info)) {
+                    return '';
+                }
+                return this.info.send_userimg || this.info.userimg;
+            },
+        },
+        methods: {
+            isJson(obj) {
+                return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && typeof obj.length == "undefined";
+            },
+
+            isShowImg(url) {
+                return !!(url && !$A.rightExists(url, 'images/other/avatar.png'));
+            },
+
+            isEmojiPrefix(text) {
+                return /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(text);
+            },
+
+            onClick(e) {
+                this.$emit('click', e);
+            }
+        }
+    }
+</script>

+ 7 - 7
resources/assets/js/main/components/UserInput.vue

@@ -15,11 +15,11 @@
 
         <transition name="fade">
             <div
-                    v-show="!disabled && visible"
-                    ref="popper"
-                    class="user-id-input-body"
-                    :data-transfer="transfer"
-                    v-transfer-dom>
+                v-show="!disabled && visible"
+                ref="popper"
+                class="user-id-input-body"
+                :data-transfer="transfer"
+                v-transfer-dom>
                 <Table highlight-row
                        v-if="searchShow"
                        size="small"
@@ -263,7 +263,7 @@
                                 this.noDataText = this.$L("数据加载失败!");
                             },
                             success: (res) => {
-                                if (res.ret === 1 && res.data.total > 0) {
+                                if (res.ret === 1 && $A.count(res.data) > 0) {
                                     let tmpData = res.data[0];
                                     if (this.multiple) {
                                         this.addMultipleLists(tmpData);
@@ -495,7 +495,7 @@
         mounted() {
             this.updatePopper();
             //
-            if ($A.runNum(this.value) > 0) {
+            if ($A.count(this.value) > 0) {
                 this.userName = this.value;
             }
             if (this.multiple) {

+ 11 - 0
resources/assets/js/main/components/UserView.vue

@@ -34,6 +34,9 @@
             placement: {
                 default: 'bottom'
             },
+            info: {
+                default: null
+            },
         },
         data() {
             return {
@@ -52,6 +55,10 @@
             },
         },
         methods: {
+            isJson(obj) {
+                return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && typeof obj.length == "undefined";
+            },
+
             popperShow() {
                 this.getUserData(30)
             },
@@ -67,6 +74,10 @@
                     }
                     this.loadIng = false;
                     this.$emit("on-result", data);
+                    //
+                    if (this.isJson(this.info)) {
+                        this.$set(this.info, 'nickname', this.nickname);
+                    }
                 }, cacheTime);
             }
         }

+ 15 - 9
resources/assets/js/main/components/chat/Index.vue

@@ -3,7 +3,7 @@
         <!--左边选项-->
         <ul class="chat-menu">
             <li class="self">
-                <img :src="userInfo.userimg" onerror="this.src=window.location.origin+'/images/other/avatar.png'">
+                <UserImg :info="userInfo" class="avatar"/>
             </li>
             <li :class="{active:chatTap=='dialog'}" @click="[chatTap='dialog',chatTam='dialog']">
                 <Icon type="md-text" />
@@ -26,7 +26,7 @@
                         :class="{active:dialog.username==dialogTarget.username}"
                         :data-id="dialog.id"
                         @click="openDialog(dialog)">
-                        <img :src="dialog.userimg" onerror="this.src=window.location.origin+'/images/other/avatar.png'">
+                        <UserImg :info="dialog" class="avatar"/>
                         <div class="user-msg-box">
                             <div class="user-msg-title">
                                 <span><user-view :username="dialog.username" placement="right" @on-result="userViewResult(dialog, $event)"/></span>
@@ -53,7 +53,7 @@
                         <div class="team-label">{{key}}</div>
                         <ul>
                             <li v-for="(item, index) in teamListsS(lists)" :key="index" @click="openDialog(item, true)">
-                                <img :src="item.userimg" onerror="this.src=window.location.origin+'/images/other/avatar.png'">
+                                <UserImg :info="item" class="avatar"/>
                                 <div class="team-username">{{item.nickname||item.username}}</div>
                             </li>
                         </ul>
@@ -155,6 +155,8 @@
         .chat-notice-userimg {
             width: 42px;
             height: 42px;
+            font-size: 20px;
+            line-height: 42px;
             border-radius: 4px;
         }
         .ivu-notice-with-desc {
@@ -228,9 +230,10 @@
                 cursor: pointer;
                 &.self {
                     cursor: default;
-                    img {
+                    .avatar {
                         width: 36px;
                         height: 36px;
+                        font-size: 20px;
                         border-radius: 3px;
                     }
                 }
@@ -319,9 +322,10 @@
                                     height: 100%;
                                 }
                             }
-                            img {
+                            .avatar {
                                 width: 42px;
                                 height: 42px;
+                                font-size: 20px;
                                 border-radius: 4px;
                             }
                             .user-msg-box {
@@ -431,9 +435,10 @@
                                     align-items: center;
                                     height: 52px;
                                     cursor: pointer;
-                                    img {
+                                    .avatar {
                                         width: 30px;
                                         height: 30px;
+                                        font-size: 16px;
                                         border-radius: 3px;
                                     }
                                     .team-username {
@@ -754,9 +759,10 @@
                     margin: 6px 0;
                     font-size: 24px;
                     &.self {
-                        img {
+                        .avatar {
                             width: 32px;
                             height: 32px;
+                            font-size: 18px;
                         }
                     }
                 }
@@ -962,7 +968,7 @@
                                             }
                                         }
                                     }, [
-                                        h('img', {class: 'chat-notice-userimg', attrs: {src: body.userimg}}),
+                                        h('UserImg', {class: 'chat-notice-userimg', props: {info: body}}),
                                         h('div', {class: 'ivu-notice-with-desc'}, [
                                             h('div', {class: 'ivu-notice-title'}, [
                                                 h('UserView', {props: {username: body.username}})
@@ -1692,7 +1698,7 @@
                                 return h('div', {
                                     class: 'chat-notice-box',
                                 }, [
-                                    h('img', {class: 'chat-notice-userimg', attrs: {src: body.userimg}}),
+                                    h('UserImg', {class: 'chat-notice-userimg', props: {info: body}}),
                                     h('div', {class: 'ivu-notice-with-desc'}, [
                                         h('div', {class: 'ivu-notice-title'}, [
                                             h('UserView', {props: {username: username}})

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

@@ -9,10 +9,10 @@
                 </div>
                 <div class="item-right">
                     <div class="item-username" @click="clickUser">
-                        <em class="item-name"><user-view :username="info.username" placement="left"/></em>
+                        <em class="item-name"><user-view :username="userName" :info="info" placement="left"/></em>
                         <em v-if="info.indate" class="item-date">{{formatCDate(info.indate)}}</em>
                     </div>
-                    <div class="item-text" :class="{'text-error':info.error}">
+                    <div class="item-text" :class="{'text-emoji':textIsEmoji(info.text), 'text-error':info.error}">
                         <div class="item-text-view">{{textMsg(info.text)}}</div>
                     </div>
                     <template v-if="info.type==='taskB'">
@@ -26,17 +26,17 @@
                         <span>{{$L('通话时长:%', formatSecond(info.other.second))}}</span>
                     </div>
                 </div>
-                <img class="item-userimg" @click="clickUser" :src="info.userimg" onerror="this.src=window.location.origin+'/images/other/avatar.png'"/>
+                <UserImg :info="info" @click="clickUser" class="item-userimg"/>
             </div>
             <div v-else-if="info.self===false" class="list-item">
-                <img class="item-userimg" @click="clickUser" :src="info.userimg" onerror="this.src=window.location.origin+'/images/other/avatar.png'"/>
+                <UserImg :info="info" @click="clickUser" class="item-userimg"/>
                 <div class="item-left">
                     <div class="item-username" @click="clickUser">
-                        <em class="item-name"><user-view :username="info.username" placement="right"/></em>
+                        <em class="item-name"><user-view :username="userName" :info="info" placement="right"/></em>
                         <em v-if="info.__usertag" class="item-tag">{{info.__usertag}}</em>
                         <em v-if="info.indate" class="item-date">{{formatCDate(info.indate)}}</em>
                     </div>
-                    <div class="item-text" :class="{'text-error':info.error}">
+                    <div class="item-text" :class="{'text-emoji':textIsEmoji(info.text), 'text-error':info.error}">
                         <div class="item-text-view">{{textMsg(info.text)}}</div>
                     </div>
                     <template v-if="info.type==='taskB'">
@@ -61,20 +61,20 @@
                 </div>
                 <div class="item-right">
                     <div class="item-username" @click="clickUser">
-                        <em class="item-name"><user-view :username="info.username" placement="left"/></em>
+                        <em class="item-name"><user-view :username="userName" :info="info" placement="left"/></em>
                         <em v-if="info.indate" class="item-date">{{formatCDate(info.indate)}}</em>
                     </div>
                     <a class="item-image" :href="info.url" target="_blank">
                         <img class="item-image-view" :src="info.url"/>
                     </a>
                 </div>
-                <img class="item-userimg" @click="clickUser" :src="info.userimg" onerror="this.src=window.location.origin+'/images/other/avatar.png'"/>
+                <UserImg :info="info" @click="clickUser" class="item-userimg"/>
             </div>
             <div v-else-if="info.self===false" class="list-item">
-                <img class="item-userimg" @click="clickUser" :src="info.userimg" onerror="this.src=window.location.origin+'/images/other/avatar.png'"/>
+                <UserImg :info="info" @click="clickUser" class="item-userimg"/>
                 <div class="item-left">
                     <div class="item-username" @click="clickUser">
-                        <em class="item-name"><user-view :username="info.username" placement="right"/></em>
+                        <em class="item-name"><user-view :username="userName" :info="info" placement="right"/></em>
                         <em v-if="info.__usertag" class="item-tag">{{info.__usertag}}</em>
                         <em v-if="info.indate" class="item-date">{{formatCDate(info.indate)}}</em>
                     </div>
@@ -154,6 +154,7 @@
             margin-left: 8px;
             margin-right: 8px;
             border-radius: 3px;
+            font-size: 20px;
         }
         .item-error {
             cursor: pointer;
@@ -182,6 +183,13 @@
         background-color: #ffffff;
         max-height: 580px;
         overflow: auto;
+        &.text-emoji {
+            background-color: transparent;
+            .item-text-view {
+                font-size: 52px;
+                line-height: normal;
+            }
+        }
         &.text-error {
             box-shadow: 0 0 4px 0 #ffa1a1;
         }
@@ -262,11 +270,25 @@
 
         },
 
+        computed: {
+            userName() {
+                return this.info.send_username || this.info.username;
+            },
+
+            userImg() {
+                return this.info.send_userimg || this.info.userimg;
+            },
+        },
+
         methods: {
             textMsg(text) {
                 return (text + "").replace(/\n/, '<br/>');
             },
 
+            textIsEmoji(text) {
+                return text.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "_") === "_";
+            },
+
             formatCDate(v) {
                 let string = '';
                 if ($A.runNum(v) > 0) {

+ 9 - 9
resources/assets/js/main/components/docs/users.vue

@@ -54,16 +54,16 @@
                 "minWidth": 60,
                 "maxWidth": 100,
                 render: (h, params) => {
-                    return h('img', {
-                        style: {
-                            width: "32px",
-                            height: "32px",
-                            verticalAlign: "middle",
-                            objectFit: "cover",
-                            borderRadius: "50%"
+                    return h('UserImg', {
+                        props: {
+                            info: params.row,
                         },
-                        attrs: {
-                            src: params.row.userimg
+                        style: {
+                            width: "30px",
+                            height: "30px",
+                            fontSize: "16px",
+                            lineHeight: "30px",
+                            borderRadius: "15px",
                         },
                     });
                 }

+ 27 - 15
resources/assets/js/main/components/project/task/add.vue

@@ -22,16 +22,18 @@
                 <Tooltip :content="$L('不重要不紧急')" placement="bottom" transfer><div @click="addLevel=4" class="enter-module-icon p4"><Icon v-if="addLevel=='4'" type="md-checkmark" /></div></Tooltip>
                 <div class="enter-module-flex"></div>
                 <Poptip placement="bottom" @on-popper-show="nameTipDisabled=true" @on-popper-hide="nameTipDisabled=false" transfer>
-                    <Tooltip :content="`${$L('负责人')}: ${addUsername||$L('自己')}`" placement="bottom" :disabled="nameTipDisabled">
+                    <Tooltip placement="bottom" :disabled="nameTipDisabled">
                         <div class="enter-module-icon user">
-                            <img v-if="addUserimg" @error="addUserimg=''" :src="addUserimg"/>
-                            <Icon v-else type="md-person" />
+                            <UserImg :info="addUserInfo" class="avatar"/>
+                        </div>
+                        <div slot="content">
+                            {{$L('负责人')}}: <UserView :username="addUserInfo.username"/>
                         </div>
                     </Tooltip>
                     <div slot="content">
                         <div style="width:240px">
                             {{$L('选择负责人')}}
-                            <UserInput v-model="addUsername" :projectid="projectid" @change="changeUser" :placeholder="$L('留空默认: 自己')" style="margin:5px 0 3px"></UserInput>
+                            <UserInput v-model="addUserInfo.username" :projectid="projectid" @change="changeUser" :placeholder="$L('留空默认: 自己')" style="margin:5px 0 3px"></UserInput>
                         </div>
                     </div>
                 </Poptip>
@@ -123,16 +125,16 @@
                         background-color: #84A83B;
                     }
                     &.user {
-                        background-color: #98CD75;
-                        border-radius: 50%;
                         width: 24px;
                         height: 24px;
                         margin-left: 10px;
                         margin-right: 10px;
-                        img {
-                            width: 100%;
-                            height: 100%;
-                            border-radius: 50%;
+                        .avatar {
+                            width: 24px;
+                            height: 24px;
+                            font-size: 14px;
+                            line-height: 24px;
+                            border-radius: 12px;
                         }
                         i {
                             line-height: 24px;
@@ -212,17 +214,27 @@
 
                 addText: '',
                 addLevel: 2,
-                addUsername: '',
-
-                addUserimg: '',
+                addUserInfo: {},
                 addFocus: false,
 
                 nameTipDisabled: false,
+
+                userInfo: {},
             }
         },
+        mounted() {
+            this.userInfo = $A.getUserInfo((res, isLogin) => {
+                this.userInfo = res;
+            }, false);
+            this.addUserInfo = $A.cloneData(this.userInfo);
+        },
         methods: {
             changeUser(user) {
-                this.addUserimg = user.userimg;
+                if (typeof user.username === "undefined") {
+                    this.addUserInfo = $A.cloneData(this.userInfo);
+                } else {
+                    this.addUserInfo = user;
+                }
             },
             dropAdd(name) {
                 if (name == 'insertbottom') {
@@ -242,7 +254,7 @@
                         labelid: this.labelid,
                         title: addText,
                         level: this.addLevel,
-                        username: this.addUsername,
+                        username: this.addUserInfo.username,
                         insertbottom: insertbottom ? 1 : 0,
                     },
                     complete: () => {

+ 23 - 2
resources/assets/js/main/components/project/task/files.vue

@@ -127,16 +127,37 @@
                             },
                         });
                     }
-                    return h('img', {
+                    let imgRender = h('img', {
                         style: {
                             width: "28px",
                             height: "28px",
-                            verticalAlign: "middle",
+                            display: "table"
                         },
                         attrs: {
                             src: params.row.thumb
                         },
                     });
+                    if (['jpg', 'jpeg', 'png', 'gif'].indexOf(params.row.ext) !== -1) {
+                        return h('Tooltip', {
+                            props: {
+                                transfer: true,
+                                delay: 600,
+                                maxWidth: 600
+                            },
+                        }, [imgRender, h('div', {slot: 'content'}, [h('img', {
+                            style: {
+                                maxWidth: "360px",
+                                maxHeight: "360px",
+                                display: "table",
+                                margin: "3px 0"
+                            },
+                            attrs: {
+                                src: params.row.path
+                            },
+                        })])]);
+                    } else {
+                        return imgRender;
+                    }
                 }
             });
             columns.push({

+ 7 - 5
resources/assets/js/main/components/project/task/logs.vue

@@ -8,7 +8,7 @@
                         <Timeline>
                             <TimelineItem v-for="(item, index) in items.lists" :key="index">
                                 <div slot="dot" class="logs-dot">
-                                    <img :src="item.userimg" @click="openChat(item.username)"/>
+                                    <UserImg :info="item" class="avatar"/>
                                 </div>
                                 <div class="log-summary">
                                     <span class="log-creator" @click="openChat(item.username)"><UserView :username="item.username"/></span>
@@ -80,10 +80,12 @@
                     width: 18px;
                     height: 18px;
                     margin-left: 10px;
-                    img {
-                        width: 100%;
-                        height: 100%;
-                        border-radius: 50%;
+                    .avatar {
+                        width: 18px;
+                        height: 18px;
+                        font-size: 12px;
+                        line-height: 18px;
+                        border-radius: 14px;
                         overflow: hidden;
                     }
                 }

+ 10 - 2
resources/assets/js/main/components/project/todo/calendar.vue

@@ -165,7 +165,7 @@
                 }else if (taskData.level === 4) {
                     color = 'rgba(121, 170, 28, 0.7)';
                 }
-                return {
+                let data = {
                     "id": taskData.id,
                     "start": $A.formatDate('Y-m-d H:i:s', startdate),
                     "end": $A.formatDate('Y-m-d H:i:s', enddate),
@@ -174,7 +174,15 @@
                     "avatar": taskData.userimg,
                     "name": taskData.nickname || taskData.username
                 };
-            }
+                if (this.isShowImg(taskData.userimg)) {
+                    data.avatar = taskData.userimg;
+                }
+                return data;
+            },
+
+            isShowImg(url) {
+                return !!(url && !$A.rightExists(url, 'images/other/avatar.png'));
+            },
         }
     }
 </script>

+ 9 - 9
resources/assets/js/main/components/project/users.vue

@@ -54,16 +54,16 @@
                 "minWidth": 60,
                 "maxWidth": 100,
                 render: (h, params) => {
-                    return h('img', {
-                        style: {
-                            width: "32px",
-                            height: "32px",
-                            verticalAlign: "middle",
-                            objectFit: "cover",
-                            borderRadius: "50%"
+                    return h('UserImg', {
+                        props: {
+                            info: params.row,
                         },
-                        attrs: {
-                            src: params.row.userimg
+                        style: {
+                            width: "30px",
+                            height: "30px",
+                            fontSize: "16px",
+                            lineHeight: "30px",
+                            borderRadius: "15px",
                         },
                     });
                 }

+ 7 - 4
resources/assets/js/main/pages/docs/edit.vue

@@ -25,8 +25,8 @@
                     <ul class="synch-lists" slot="content">
                         <li class="title">{{$L('正在协作会员')}}:</li>
                         <li v-for="(item, key) in synchUsersS" :key="key" @click="handleSynch(item.username)">
-                            <img class="synch-userimg" :src="item.userimg"/>
-                            <user-view class="synch-username" placement="right" :username="item.username"/>
+                            <UserImg :info="item" class="synch-userimg"/>
+                            <UserView class="synch-username" placement="right" :username="item.username"/>
                             <span v-if="item.username==userInfo.username" class="synch-self">{{$L('自己')}}</span>
                         </li>
                     </ul>
@@ -241,7 +241,9 @@
                             .synch-userimg {
                                 width: 24px;
                                 height: 24px;
-                                border-radius: 50%;
+                                font-size: 14px;
+                                line-height: 24px;
+                                border-radius: 12px;
                             }
                             .synch-self {
                                 padding: 1px 3px;
@@ -591,7 +593,7 @@
             },
             synchUsersS() {
                 return this.synchUsers.filter(item => {
-                    return item.indate + 10 > this.timeValue;
+                    return item.indate + 20 > this.timeValue;
                 });
             },
             isLock() {
@@ -624,6 +626,7 @@
                         $A.WSOB.sendTo('docs', null, {
                             type: enter === true ? 'enter' : 'refresh',
                             sid: this.sid,
+                            nickname: this.userInfo.nickname,
                             username: this.userInfo.username,
                             userimg: this.userInfo.userimg,
                             indate: Math.round(new Date().getTime() / 1000),

+ 9 - 6
resources/assets/js/main/pages/project/panel.vue

@@ -70,7 +70,9 @@
                                         <div v-if="task.overdue" class="task-status">{{$L('已超期')}}</div>
                                         <div v-else-if="task.complete" class="task-status">{{$L('已完成')}}</div>
                                         <div v-else class="task-status">{{$L('未完成')}}</div>
-                                        <Tooltip class="task-userimg" :content="task.nickname || task.username" transfer><img :src="task.userimg"/></Tooltip>
+                                        <Tooltip class="task-userimg" :content="task.nickname || task.username" transfer>
+                                            <UserImg :info="task" class="avatar"/>
+                                        </Tooltip>
                                     </div>
                                 </div>
                             </div>
@@ -296,11 +298,12 @@
                                     .task-userimg {
                                         width: 26px;
                                         height: 26px;
-                                        img {
-                                            object-fit: cover;
-                                            width: 100%;
-                                            height: 100%;
-                                            border-radius: 50%;
+                                        .avatar {
+                                            width: 26px;
+                                            height: 26px;
+                                            font-size: 14px;
+                                            line-height: 26px;
+                                            border-radius: 13px;
                                         }
                                     }
                                 }

+ 9 - 9
resources/assets/js/main/pages/team.vue

@@ -124,16 +124,16 @@
                 "minWidth": 60,
                 "maxWidth": 100,
                 render: (h, params) => {
-                    return h('img', {
-                        style: {
-                            width: "32px",
-                            height: "32px",
-                            verticalAlign: "middle",
-                            objectFit: "cover",
-                            borderRadius: "50%"
+                    return h('UserImg', {
+                        props: {
+                            info: params.row,
                         },
-                        attrs: {
-                            src: params.row.userimg
+                        style: {
+                            width: "30px",
+                            height: "30px",
+                            fontSize: "16px",
+                            lineHeight: "30px",
+                            borderRadius: "15px",
                         },
                     });
                 }