no message

This commit is contained in:
kuaifan 2021-06-02 19:40:33 +08:00
parent e5e7d2d052
commit b24d1f79fa
9 changed files with 197 additions and 109 deletions

View File

@ -18,6 +18,14 @@ use Request;
*/
class ProjectController extends AbstractController
{
private $projectSelect = [
'*',
'projects.id AS id',
'projects.userid AS userid',
'projects.created_at AS created_at',
'projects.updated_at AS updated_at',
];
/**
* 项目列表
*
@ -33,7 +41,8 @@ class ProjectController extends AbstractController
$user = User::IDE($user['data']);
}
//
$list = Project::join('project_users', 'projects.id', '=', 'project_users.project_id')
$list = Project::select($this->projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('project_users.userid', $user->userid)
->orderByDesc('projects.id')
->paginate(Base::getPaginate(200, 100));
@ -62,10 +71,15 @@ class ProjectController extends AbstractController
$taskQuery->where('parent_id', 0);
}]);
}, 'projectUser'])
->select($this->projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('projects.id', $project_id)
->where('project_users.userid', $user->userid)
->first();
if ($project) {
$owner_user = $project->projectUser->where('owner', 1)->first();
$project->owner_userid = $owner_user ? $owner_user->userid : 0;
}
//
return Base::retSuccess('success', $project);
}

View File

@ -6,6 +6,7 @@ use App\Models\User;
use App\Module\Base;
use Cache;
use Captcha;
use Carbon\Carbon;
use Request;
/**
@ -87,11 +88,11 @@ class UsersController extends AbstractController
}
//
$array = [
'loginnum' => $user['loginnum'] + 1,
'lastip' => Base::getIp(),
'lastdate' => time(),
'lineip' => Base::getIp(),
'linedate' => time(),
'login_num' => $user->login_num + 1,
'last_ip' => Base::getIp(),
'last_at' => Carbon::now(),
'line_ip' => Base::getIp(),
'line_at' => Carbon::now(),
];
foreach ($array as $key => $value) {
$user->$key = $value;
@ -159,14 +160,13 @@ class UsersController extends AbstractController
"email": "admin@admin.com",
"nickname": "admin",
"userimg": "",
"loginnum": 10,
"login_num": 10,
"changepass": 0,
"lastip": "10.22.22.1",
"lastdate": 1622468661,
"lineip": "10.22.22.1",
"linedate": 1622468661,
"regip": "",
"regdate": 0,
"last_ip": "10.22.22.1",
"last_at": "2021-06-01 12:00:00",
"line_ip": "10.22.22.1",
"line_at": "2021-06-01 12:00:00",
"created_ip": "",
}
*/
public function info()

View File

@ -5,6 +5,7 @@ namespace App\Models;
use App\Module\Base;
use Cache;
use Carbon\Carbon;
/**
* Class User
@ -18,14 +19,13 @@ use Cache;
* @property string|null $userimg 头像
* @property string|null $encrypt
* @property string|null $userpass 登录密码
* @property int|null $loginnum 累计登录次数
* @property int|null $login_num 累计登录次数
* @property int|null $changepass 登录需要修改密码
* @property string|null $lastip 最后登录IP
* @property int|null $lastdate 最后登录时间
* @property string|null $lineip 最后在线IP接口
* @property int|null $linedate 最后在线时间(接口)
* @property string|null $regip 注册IP
* @property int|null $regdate 注册时间
* @property string|null $last_ip 最后登录IP
* @property \Illuminate\Support\Carbon|null $last_at 最后登录时间
* @property string|null $line_ip 最后在线IP接口
* @property \Illuminate\Support\Carbon|null $line_at 最后在线时间(接口)
* @property string|null $created_ip 注册IP
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read string $usering
@ -38,14 +38,13 @@ use Cache;
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereEncrypt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereIdentity($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLastdate($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLastip($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLinedate($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLineip($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLoginnum($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLastAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLastIp($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLineAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLineIp($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLoginNum($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereNickname($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereRegdate($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereRegip($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedIp($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserid($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserimg($value)
@ -59,7 +58,6 @@ class User extends AbstractModel
protected $hidden = [
'encrypt',
'userpass',
'created_at',
'updated_at',
];
@ -80,7 +78,7 @@ class User extends AbstractModel
*/
public function getUserimgAttribute($value)
{
return self::userimg($value);
return $value ? Base::fillUrl($value) : url('images/other/avatar.png');
}
/**
@ -129,8 +127,7 @@ class User extends AbstractModel
'encrypt' => $encrypt,
'email' => $email,
'userpass' => Base::md52($userpass, $encrypt),
'regip' => Base::getIp(),
'regdate' => time()
'created_ip' => Base::getIp(),
];
if ($other) {
$inArray = array_merge($inArray, $other);
@ -228,11 +225,11 @@ class User extends AbstractModel
$row = self::whereUserid($authInfo['userid'])->whereEmail($authInfo['email'])->whereEncrypt($authInfo['encrypt'])->first();
if ($row) {
$upArray = [];
if (Base::getIp() && $row->lineip != Base::getIp()) {
$upArray['lineip'] = Base::getIp();
if (Base::getIp() && $row->line_ip != Base::getIp()) {
$upArray['line_ip'] = Base::getIp();
}
if ($row->linedate + 30 < time()) {
$upArray['linedate'] = time();
if (Carbon::parse($row->line_at)->addSeconds(30)->lt(Carbon::now())) {
$upArray['line_at'] = Carbon::now();
}
if ($upArray) {
$row->updateInstance($upArray);
@ -333,50 +330,14 @@ class User extends AbstractModel
if (isset($_A["__static_userid2basic_" . $userid])) {
return $_A["__static_userid2basic_" . $userid];
}
$fields = ['userid', 'email', 'nickname', 'userimg'];
$fields = ['userid', 'email', 'nickname', 'userimg', 'line_at'];
$userInfo = self::whereUserid($userid)->select($fields)->first();
if ($userInfo) {
$userInfo->line_at;
}
return $_A["__static_userid2basic_" . $userid] = ($userInfo ?: []);
}
/**
* email 获取 基本信息
* @param string $email 邮箱地址
* @return self
*/
public static function email2basic(string $email)
{
global $_A;
if (empty($email)) {
return null;
}
if (isset($_A["__static_email2basic_" . $email])) {
return $_A["__static_email2basic_" . $email];
}
$fields = ['userid', 'email', 'nickname', 'userimg'];
$userInfo = self::whereEmail($email)->select($fields)->first();
return $_A["__static_email2basic_" . $email] = ($userInfo ?: []);
}
/**
* 用户头像,不存在时返回默认
* @param string $var 头像地址 会员邮箱
* @return string
*/
public static function userimg(string $var)
{
if (!Base::strExists($var, '.')) {
if (empty($var)) {
$var = "";
} else {
$userInfo = self::email2basic($var);
if ($userInfo) {
$var = $userInfo->userimg;
}
}
}
return $var ? Base::fillUrl($var) : url('images/other/avatar.png');
}
/**
* 更新首字母
* @param $userid

View File

@ -20,13 +20,14 @@ import Loading from './components/Loading.vue'
import AutoTip from './components/AutoTip.vue'
import TagInput from './components/TagInput.vue'
import TableAction from './components/TableAction.vue'
import UserAvatar from './components/UserAvatar.vue'
Vue.component('PageTitle', PageTitle);
Vue.component('Loading', Loading);
Vue.component('AutoTip', AutoTip);
Vue.component('TagInput', TagInput)
Vue.component('TableAction', TableAction);
Vue.component('UserAvatar', UserAvatar);
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {

View File

@ -0,0 +1,76 @@
<template>
<Tooltip v-if="user"
:class="['common-avatar', user.online ? 'online' : '']"
:delay="600"
:transfer="transfer"
:content="user.nickname">
<Avatar v-if="showImg" :src="user.userimg" :size="size"/>
<Avatar v-else :size="size" class="common-avatar-text">{{nickname}}</Avatar>
</Tooltip>
</template>
<script>
export default {
name: 'UserAvatar',
props: {
userid: {
type: [String, Number],
default: ''
},
size: {
type: [String, Number],
default: 'default'
},
transfer: {
type: Boolean,
default: true
},
},
data() {
return {
user: null
}
},
mounted() {
this.getData()
},
computed: {
showImg() {
const {userimg} = this.user
if (!userimg) {
return false;
}
return !$A.rightExists(userimg, '/avatar.png');
},
nickname() {
const {nickname} = this.user;
if (!nickname) {
return "D";
}
let value = nickname.substring(0, 2);
if (/^[\u4e00-\u9fa5]+$/.test(value)) {
value = value.substring(0, 1);
}
return value || 'D';
}
},
watch: {
userid() {
this.getData()
}
},
methods: {
getData() {
if (!this.userid) {
return;
}
this.$store.commit('getUserBasic', {
userid: this.userid,
success: (user) => {
this.user = user;
}
});
}
}
};
</script>

View File

@ -2,13 +2,16 @@
<div class="project-list">
<div class="project-head">
<div class="project-titbox">
<div class="project-title"> Daily Task</div>
<div class="project-subtitle">Click + New To create new list and wait for project manager card Don't Create a card by yourself to manage a good colaboration.</div>
<div class="project-title">
<h1>{{projectDetail.name}}</h1>
<div v-if="projectLoad > 0" class="project-load"><Loading/></div>
</div>
<div v-if="projectDetail.desc" class="project-subtitle">{{projectDetail.desc}}</div>
</div>
<div class="project-icobox">
<ul class="project-icons">
<li class="project-avatar online">
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
<li>
<UserAvatar :userid="projectDetail.owner_userid" :size="36"/>
</li>
<li class="project-icon" @click="addShow=true">
<Icon type="md-add" />
@ -631,9 +634,22 @@
flex: 1;
margin-bottom: 16px;
.project-title {
color: #333333;
font-size: 28px;
font-weight: 600;
display: flex;
align-items: center;
> h1 {
color: #333333;
font-size: 28px;
font-weight: 600;
}
.project-load {
display: flex;
align-items: center;
margin-left: 18px;
.common-loading {
width: 22px;
height: 22px;
}
}
}
.project-subtitle {
color: #999999;
@ -687,29 +703,6 @@
background-color: #2d8cf0;
}
}
&.project-avatar {
.ivu-avatar {
width: 36px;
height: 36px;
}
&:before {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 9px;
height: 9px;
border-radius: 50%;
background-color: #ff0000;
border: 1px solid #ffffff;
z-index: 1;
}
&.online {
&:before {
background-color: #509E76;
}
}
}
}
}
.project-switch {
@ -1015,6 +1008,7 @@
<script>
import TaskPriority from "./task-priority";
import TaskAdd from "./task-add";
import {mapState} from "vuex";
export default {
name: "ProjectList",
components: {TaskAdd, TaskPriority},
@ -1034,6 +1028,9 @@ export default {
},
mounted() {
}
},
computed: {
...mapState(['projectDetail', 'projectLoad']),
},
}
</script>

View File

@ -41,6 +41,13 @@ export default {
if (state._isJson(state.cacheProject[project_id])) {
state.projectDetail = state.cacheProject[project_id];
}
state.projectDetail.id = project_id;
//
if (state.cacheProject[project_id + "::load"]) {
return;
}
state.cacheProject[project_id + "::load"] = true;
//
state.projectLoad++;
$A.apiAjax({
url: 'project/detail',
@ -49,10 +56,14 @@ export default {
},
complete: () => {
state.projectLoad--;
state.cacheProject[project_id + "::load"] = false;
},
success: ({ret, data, msg}) => {
if (ret === 1) {
state.projectDetail = state.cacheProject[project_id] = data;
state.cacheProject[project_id] = data;
if (state.projectDetail.id == project_id) {
state.projectDetail = data;
}
} else {
$A.modalError(msg);
}

View File

@ -174,7 +174,11 @@ export default Object.assign(stateCommon, {
userToken,
projectLoad: 0,
projectDetail: {},
projectDetail: {
id: 0,
project_column: [],
project_user: []
},
cacheProject: {},
cacheUserBasic: {},

View File

@ -412,6 +412,30 @@
}
}
}
.common-avatar {
.common-avatar-text {
background-color: #87d068;
}
&:before {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 9px;
height: 9px;
border-radius: 50%;
background-color: #ff0000;
border: 1px solid #ffffff;
z-index: 1;
}
&.online {
&:before {
background-color: #509E76;
}
}
}
.common-user-transfer {
.user-input-option {
display: flex;