kuaifan před 5 roky
rodič
revize
4ea384c94f

+ 17 - 2
app/Http/Controllers/Api/UsersController.php

@@ -82,6 +82,15 @@ class UsersController extends Controller
     }
 
     /**
+     * 获取基本信息
+     * @return array
+     */
+    public function basic()
+    {
+        return Base::retSuccess('success', Users::username2basic(trim(Request::input('username'))));
+    }
+
+    /**
      * 搜索会员列表
      */
     public function searchinfo()
@@ -286,10 +295,16 @@ class UsersController extends Controller
         }
         //用户名
         $username = trim(Request::input('username'));
+        if (in_array($username, ['__loadIng'])) {
+            return Base::retError('用户名包含非法字符串!');
+        }
         if (strlen($username) < 2) {
             return Base::retError('用户名不可以少于2个字符!');
-        } elseif (strlen($username) > 12) {
-            return Base::retError('用户名最多只能设置12个字符!');
+        } elseif (strlen($username) > 16) {
+            return Base::retError('用户名最多只能设置16个字符!');
+        }
+        if (!preg_match('/^[A-Za-z0-9_\x{4e00}-\x{9fa5}]+$/u', $username)) {
+            return Base::retError('用户名由2-16位数字或字母、汉字、下划线组成!');
         }
         if (Users::username2id($username) > 0) {
             return Base::retError('用户名已存在!');

+ 12 - 5
app/Module/Users.php

@@ -198,19 +198,26 @@ class Users
     /**
      * username 获取 基本信息
      * @param string $username           用户名
+     * @param bool $clearCache           清理缓存
      * @return array
      */
-    public static function username2basic($username)
+    public static function username2basic($username, $clearCache = false)
     {
         if (empty($username)) {
             return [];
         }
         $fields = ['username', 'nickname', 'userimg', 'profession'];
-        $userInfo = DBCache::table('users')->where('username', $username)->select($fields)->cacheMinutes(1)->first();
-        if ($userInfo) {
-            $userInfo['userimg'] = Users::userimg($userInfo['userimg']);
+        $builder = DBCache::table('users')->where('username', $username)->select($fields)->cacheMinutes(1);
+        if ($clearCache) {
+            $builder->removeCache()->first();
+            return [];
+        } else {
+            $userInfo = $builder->first();
+            if ($userInfo) {
+                $userInfo['userimg'] = Users::userimg($userInfo['userimg']);
+            }
+            return $userInfo ?: [];
         }
-        return $userInfo ?: [];
     }
 
     /**

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

@@ -13,12 +13,14 @@ Vue.use(ViewUI);
 Vue.use(Language);
 
 import Title from '../_components/Title.vue'
-import UseridInput from './components/UseridInput'
 import sreachTitle from '../_components/sreachTitle.vue'
+import UseridInput from './components/UseridInput'
+import UserView from './components/UserView'
 
 Vue.component('VTitle', Title);
-Vue.component('UseridInput', UseridInput);
 Vue.component('sreachTitle', sreachTitle);
+Vue.component('UseridInput', UseridInput);
+Vue.component('UserView', UserView);
 
 import TaskDetail from './components/project/task/detail'
 Vue.prototype.taskDetail = TaskDetail;

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

@@ -0,0 +1,107 @@
+<template>
+    <div class="user-view-inline">
+        <Tooltip :disabled="!nickname" :delay="delay" :transfer="transfer">
+            {{nickname || username}}
+            <div slot="content">
+                <div>用户名:{{username}}</div>
+                <div>职位/职称:{{profession || '-'}}</div>
+            </div>
+        </Tooltip>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+    .user-view-inline {
+        display: inline-block;
+    }
+</style>
+
+<script>
+    export default {
+        name: 'UserView',
+        props: {
+            username: {
+                default: ''
+            },
+            delay: {
+                type: Number,
+                default: 600
+            },
+            transfer: {
+                type: Boolean,
+                default: true
+            },
+        },
+        data() {
+            return {
+                nickname: '',
+                profession: ''
+            }
+        },
+        mounted() {
+            this.getUserData(0);
+        },
+        watch: {
+            username() {
+                this.getUserData(0);
+            }
+        },
+        methods: {
+            getUserData(num) {
+                let keyName = '__name:' + this.username.substring(0, 1) + '__';
+                let localData = $A.jsonParse(window.localStorage[keyName]);
+                if (localData.__loadIng === true) {
+                    if (num < 100) {
+                        setTimeout(() => {
+                            this.getUserData(num + 1)
+                        }, 500);
+                    }
+                    return;
+                }
+                //
+                if (typeof localData[this.username] !== "object") {
+                    localData[this.username] = {};
+                }
+                //
+                if (localData[this.username].success === true
+                    && localData[this.username].exptime > Math.round(new Date().getTime() / 1000)) {
+                    this.nickname = localData[this.username].data.nickname;
+                    this.profession = localData[this.username].data.profession;
+                    return;
+                }
+                //
+                localData.__loadIng = true;
+                $A.aAjax({
+                    url: 'users/basic',
+                    data: {
+                        username: this.username,
+                    },
+                    error: () => {
+                        localData[this.username].success = false;
+                        localData[this.username].exptime = 0;
+                        localData[this.username].data = {};
+                        localData.__loadIng = false;
+                        window.localStorage[keyName] = $A.jsonStringify(localData);
+                    },
+                    success: (res) => {
+                        if (res.ret === 1) {
+                            this.nickname = res.data.nickname;
+                            this.profession = res.data.profession;
+                            localData[this.username].success = true;
+                            localData[this.username].exptime = Math.round(new Date().getTime() / 1000) + 300;
+                            localData[this.username].data = res.data;
+                        } else {
+                            this.nickname = '';
+                            this.profession = '';
+                            localData[this.username].success = false;
+                            localData[this.username].exptime = 0;
+                            localData[this.username].data = {};
+                        }
+                        localData.__loadIng = false;
+                        window.localStorage[keyName] = $A.jsonStringify(localData);
+                    }
+                });
+            }
+        }
+    }
+</script>

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

@@ -44,6 +44,9 @@
                         <FormItem :label="$L('头像')" prop="userimg">
                             <ImgUpload v-model="formDatum.userimg"></ImgUpload>
                         </FormItem>
+                        <FormItem :label="$L('账号')">
+                            <Input v-model="userInfo.username" :disabled="true"></Input>
+                        </FormItem>
                         <FormItem :label="$L('昵称')" prop="nickname">
                             <Input v-model="formDatum.nickname"></Input>
                         </FormItem>

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

@@ -5,7 +5,7 @@
                 <div class="detail-title-box detail-icon">
                     <input v-model="detail.title" :disabled="!!loadData.title" type="text" maxlength="60" @keydown.enter="(e)=>{e.target.blur()}" @blur="handleTask('title')">
                     <div class="time">
-                        <span class="z-nick">{{detail.createuser}}</span>
+                        <span class="z-nick"><UserView :username="detail.createuser"/></span>
                         {{$L('创建于:')}}
                         <span>{{$A.formatDate("Y-m-d H:i:s", detail.indate)}}</span>
                     </div>
@@ -22,7 +22,7 @@
                     </li>
                     <li class="text-username detail-icon">
                         <span>{{$L('负责人:')}}</span>
-                        <em>{{detail.username}}</em>
+                        <em><UserView :username="detail.username"/></em>
                     </li>
                     <li v-if="followerLength(detail.follower) > 0" class="text-follower detail-icon">
                         <span>{{$L('关注者:')}}</span>