no message

This commit is contained in:
kuaifan 2021-06-16 22:37:28 +08:00
parent face5a943d
commit 7c6dcc3daa
16 changed files with 601 additions and 241 deletions

View File

@ -23,11 +23,6 @@ use Request;
*/
class ProjectController extends AbstractController
{
private $projectSelect = [
'projects.*',
'project_users.owner',
];
/**
* 项目列表
*
@ -38,7 +33,7 @@ class ProjectController extends AbstractController
{
$user = User::auth();
//
$list = Project::select($this->projectSelect)
$list = Project::select(Project::projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('project_users.userid', $user->userid)
->orderByDesc('projects.id')
@ -79,7 +74,7 @@ class ProjectController extends AbstractController
$taskQuery->with(['taskUser', 'taskTag'])->where('parent_id', 0);
}]);
}, 'projectUser'])
->select($this->projectSelect)
->select(project::projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('projects.id', $project_id)
->where('project_users.userid', $user->userid)
@ -419,7 +414,7 @@ class ProjectController extends AbstractController
return Base::retError('列表不存在');
}
// 项目
$project = Project::select($this->projectSelect)
$project = Project::select(project::projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('projects.id', $column->project_id)
->where('project_users.userid', $user->userid)
@ -456,7 +451,7 @@ class ProjectController extends AbstractController
return Base::retError('列表不存在');
}
// 项目
$project = Project::select($this->projectSelect)
$project = Project::select(project::projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('projects.id', $column->project_id)
->where('project_users.userid', $user->userid)
@ -471,6 +466,46 @@ class ProjectController extends AbstractController
return Base::retError('删除失败');
}
/**
* 任务列表
*
* @apiParam {String} name 任务名称(包含)
* @apiParam {Array} time 时间范围,格式:数组,如:[2020-12-12,2020-20-12]
*/
public function task__lists()
{
$user = user::auth();
//
$builder = ProjectTask::select(ProjectTask::taskSelect);
//
$name = Request::input('name');
$time = Request::input('time');
if ($name) {
$builder->where(function($query) use ($name) {
$query->where('project_tasks.name', 'like', '%,' . $name . ',%');
});
}
if (is_array($time)) {
if (Base::isDateOrTime($time[0]) && Base::isDateOrTime($time[1])) {
$between = [
Carbon::parse($time[0])->startOfDay(),
Carbon::parse($time[1])->endOfDay()
];
$builder->where(function($query) use ($between) {
$query->whereBetween('project_tasks.start_at', $between)->orWhereBetween('project_tasks.end_at', $between);
});
}
}
//
$list = $builder
->join('project_task_users', 'project_tasks.id', '=', 'project_task_users.task_id')
->where('project_task_users.userid', $user->userid)
->orderByDesc('project_tasks.id')
->paginate(Base::getPaginate(200, 100));
//
return Base::retSuccess('success', $list);
}
/**
* 获取任务
*

View File

@ -50,6 +50,11 @@ class Project extends AbstractModel
{
use SoftDeletes;
const projectSelect = [
'projects.*',
'project_users.owner',
];
protected $appends = [
'task_num',
'task_complete',
@ -295,7 +300,7 @@ class Project extends AbstractModel
*/
public static function userProject($project_id)
{
$project = Project::select([ 'projects.*', 'project_users.owner' ])
$project = Project::select(self::projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('projects.id', intval($project_id))
->where('project_users.userid', User::token2userid())

View File

@ -79,6 +79,11 @@ class ProjectTask extends AbstractModel
{
use SoftDeletes;
const taskSelect = [
'project_tasks.*',
'project_task_users.owner',
];
protected $appends = [
'file_num',
'msg_num',
@ -305,15 +310,16 @@ class ProjectTask extends AbstractModel
$task->save();
if ($owner) {
ProjectTaskUser::createInstance([
'project_id' => $task->parent_id,
'project_id' => $task->project_id,
'task_id' => $task->id,
'task_pid' => $task->parent_id ?: $task->id,
'userid' => $owner,
'owner' => 1,
])->save();
}
if ($content) {
ProjectTaskContent::createInstance([
'project_id' => $task->parent_id,
'project_id' => $task->project_id,
'task_id' => $task->id,
'content' => $content,
])->save();
@ -367,7 +373,7 @@ class ProjectTask extends AbstractModel
$row->owner = 0;
$row->save();
ProjectTaskUser::updateInsert([
'project_id' => $this->parent_id,
'project_id' => $this->project_id,
'task_id' => $this->id,
'userid' => $owner,
], [
@ -402,8 +408,9 @@ class ProjectTask extends AbstractModel
//
if (empty($this->useridInTheTask($uid))) {
ProjectTaskUser::createInstance([
'project_id' => $this->parent_id,
'project_id' => $this->project_id,
'task_id' => $this->id,
'task_pid' => $this->parent_id ?: $this->id,
'userid' => $uid,
'owner' => 0,
])->save();
@ -422,7 +429,7 @@ class ProjectTask extends AbstractModel
// 内容
if (Arr::exists($data, 'content')) {
ProjectTaskContent::updateInsert([
'project_id' => $this->parent_id,
'project_id' => $this->project_id,
'task_id' => $this->id,
], [
'content' => $data['content'],
@ -625,7 +632,7 @@ class ProjectTask extends AbstractModel
throw new ApiException('任务不存在');
}
//
$project = Project::select([ 'projects.*', 'project_users.owner' ])
$project = Project::select(Project::projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('projects.id', $task->project_id)
->where('project_users.userid', User::token2userid())

View File

@ -9,6 +9,7 @@ namespace App\Models;
* @property int $id
* @property int|null $project_id 项目ID
* @property int|null $task_id 任务ID
* @property int|null $task_pid 任务ID如果是子任务则是父级任务ID
* @property int|null $userid 成员ID
* @property int|null $owner 是否任务负责人
* @property \Illuminate\Support\Carbon|null $created_at
@ -21,6 +22,7 @@ namespace App\Models;
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereOwner($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereProjectId($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereTaskId($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereTaskPid($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereUserid($value)
* @mixin \Eloquent

View File

@ -914,6 +914,16 @@ class Base
return true;
}
/**
* 检测 日期格式 时间格式
* @param string $str 需要检测的字符串
* @return bool
*/
public static function isDateOrTime($str)
{
return self::isDate($str) || self::isTime($str);
}
/**
* 检测手机号码格式
* @param string $str 需要检测的字符串

View File

@ -18,6 +18,7 @@
"jquery": "^3.5.1",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"moment": "^2.29.1",
"node-sass": "^4.11.0",
"postcss": "^8.1.14",
"resolve-url-loader": "^4.0.0",
@ -37,6 +38,7 @@
"echarts": "^5.1.1",
"element-ui": "^2.15.2",
"tinymce": "^5.8.1",
"tui-calendar-hi": "^1.13.0-3",
"view-design-hi": "^4.6.1-1",
"vue-clipboard2": "^0.3.1",
"vue-emoji-picker": "^1.0.1",

View File

@ -4,166 +4,212 @@
<div class="calendar-head">
<div class="calendar-titbox">
<div class="calendar-title">
<h1>{{viewDay}}</h1>
<h1>{{rangeText}}</h1>
</div>
<ButtonGroup class="calendar-arrow" size="small">
<Button @click="preMonth"><Icon type="ios-arrow-back"></Icon></Button>
<Button @click="curMonth">{{$L('今天')}}</Button>
<Button @click="afterMonth"><Icon type="ios-arrow-forward"></Icon></Button>
</ButtonGroup>
<ButtonGroup class="calendar-view">
<Button @click="setView('day')" :type="calendarView == 'day' ? 'primary' : 'default'">{{$L('日')}}</Button>
<Button @click="setView('week')" :type="calendarView == 'week' ? 'primary' : 'default'">{{$L('周')}}</Button>
<Button @click="setView('month')" :type="calendarView == 'month' ? 'primary' : 'default'">{{$L('月')}}</Button>
</ButtonGroup>
</div>
</div>
<div class="calendar-box">
<ul class="head">
<li>SUN</li>
<li>MON</li>
<li>TUE</li>
<li>WED</li>
<li>THU</li>
<li>FRI</li>
<li>SAT</li>
</ul>
<ul class="days">
<li v-for="row in days">
<ul>
<li v-for="(item, key) in row" :key="key" :class="item.place">
<div class="time"><em :class="{'cur-day': item.ymd == curDay}">{{item.day}}</em></div>
</li>
</ul>
</li>
</ul>
<Calendar
ref="cal"
:view="calendarView"
:calendars="calendarLists"
:schedules="scheduleLists"
@beforeClickSchedule="onBeforeClickSchedule"
@beforeUpdateSchedule="onBeforeUpdateSchedule"/>
</div>
</div>
</template>
<script>
import 'tui-date-picker/dist/tui-date-picker.css';
import 'tui-time-picker/dist/tui-time-picker.css';
import 'tui-calendar-hi/dist/tui-calendar-hi.css'
import {mapState} from "vuex";
import Calendar from "./components/Calendar";
import moment from "moment";
const today = new Date();
const getDate = (type, start, value, operator) => {
start = new Date(start);
type = type.charAt(0).toUpperCase() + type.slice(1);
if (operator === '+') {
start[`set${type}`](start[`get${type}`]() + value);
} else {
start[`set${type}`](start[`get${type}`]() - value);
}
return start;
};
export default {
components: {Calendar},
data() {
return {
viewDay: $A.formatDate("Y-m"),
lists: [],
curDay: $A.formatDate("Y-m-d"),
curInterval: null,
rangeText: 'Calendar',
rangeTime: [],
calendarView: 'month',
scheduleLoad: 0,
scheduleList: [],
}
},
mounted() {
this.curInterval = setInterval(() => {
this.curDay = $A.formatDate("Y-m-d");
}, 60000)
this.setRenderRange();
},
destroyed() {
clearInterval(this.curInterval)
},
computed: {
...mapState(['userInfo']),
...mapState(['projectList']),
days() {
const days = this.getDateJson(new Date(this.viewDay));
let row = days[days.length - 1].day >= 7 ? 5 : 6
let array = [], tmp = [];
for (let i = 0; i < days.length; i++) {
let obj = days[i];
tmp.push(obj);
if ((i + 1) % 7 == 0) {
array.push(tmp);
tmp = [];
calendarLists() {
const {projectList} = this;
return projectList.map((project) => {
return {
id: project.id,
name: project.name,
bgColor: '#F2F3F5',
borderColor: '#F2F3F5'
}
if (array.length >= row) {
break;
}
}
return array;
});
},
scheduleLists() {
return this.scheduleList.filter(({complete_at}) => !complete_at)
}
},
watch: {
watch: {
rangeTime(time) {
this.getTask(time);
}
},
methods: {
getTask(time) {
if (this.scheduleLoad > 0) {
setTimeout(() => {
this.getTask(time)
}, 100)
return;
}
this.scheduleLoad++;
this.$store.dispatch("getTaskList", {
time
}).then(({data}) => {
this.scheduleLoad--;
data.data.some((task) => {
let schedule = {
id: task.id,
calendarId: task.project_id,
title: task.name,
category: 'allday',
start: new Date(task.start_at).toISOString(),
end: new Date(task.end_at).toISOString(),
color: "#515a6e",
bgColor: task.color || '#E3EAFD',
borderColor: task.p_color,
complete_at: task.complete_at,
preventClick: true,
isChecked: false,
};
if (task.p_name) {
schedule.priority = '<span class="priority" style="background-color:' + task.p_color + '">' + task.p_name + '</span>';
}
if (task.overdue) {
schedule.color = "#f56c6c"
schedule.bgColor = "#fef0f0"
}
let index = this.scheduleList.findIndex(({id}) => id === task.id);
if (index > -1) {
this.scheduleList.splice(index, 1, schedule)
} else {
this.scheduleList.push(schedule)
}
});
}).catch(() => {
this.scheduleLoad--;
})
},
preMonth() {
const date = new Date(this.viewDay);
date.setMonth(date.getMonth() - 1);
this.viewDay = $A.formatDate("Y-m", date)
this.$refs.cal.getInstance().prev();
this.setRenderRange()
},
curMonth() {
this.viewDay = $A.formatDate("Y-m");
this.$refs.cal.getInstance().today();
this.setRenderRange()
},
afterMonth() {
const date = new Date(this.viewDay);
date.setMonth(date.getMonth() + 1);
this.viewDay = $A.formatDate("Y-m", date)
this.$refs.cal.getInstance().next();
this.setRenderRange()
},
getDateJson(date){
const getMonths = (yy) => {
let months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
let months2 = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
let mrun = yy % 100 == 0 && yy % 400 == 0 ? true : (yy % 4 == 0);
return mrun ? months2 : months;
}
const zeroFill = (num) => {
if (num < 9) return '0' + num;
return '' + num;
}
//
let yy = date.getFullYear();
let mm = date.getMonth();
//使
let month = getMonths(yy);
//1
let begin_date = new Date(yy, mm, 1);
//
let pre_num = begin_date.getDay();
//
let const_num = 7 * 6;
//
let cur_num = month[mm];
//
let after_num = const_num - cur_num - pre_num;
//
let preyy = yy;
let premm = mm;
//-10
if (premm == 0) {
preyy -= 1;
}
//
premm = premm - 1 < 0 ? 11 : (premm - 1);
let pre_max = month[premm];
setView(view) {
this.calendarView = view;
this.setRenderRange()
},
//
let afteryy = yy;
let aftermm = mm;
if (aftermm == 11) {
afteryy += 1;
setRenderRange() {
this.$nextTick(() => {
const cal = this.$refs.cal.getInstance();
let options = cal.getOptions();
let viewName = cal.getViewName();
let html = [];
if (viewName === 'day') {
html.push(this.currentCalendarDate('YYYY.MM.DD'));
} else if (viewName === 'month' &&
(!options.month.visibleWeeksCount || options.month.visibleWeeksCount > 4)) {
html.push(this.currentCalendarDate('YYYY.MM'));
} else {
html.push(moment(cal.getDateRangeStart().getTime()).format('YYYY.MM.DD'));
html.push(' ~ ');
html.push(moment(cal.getDateRangeEnd().getTime()).format(' MM.DD'));
}
this.rangeText = html.join('');
this.rangeTime = [moment(cal.getDateRangeStart().getTime()).format('YYYY-MM-DD'), moment(cal.getDateRangeEnd().getTime()).format('YYYY-MM-DD')];
})
},
currentCalendarDate(format) {
const cal = this.$refs.cal.getInstance();
let currentDate = moment([cal.getDate().getFullYear(), cal.getDate().getMonth(), cal.getDate().getDate()]);
return currentDate.format(format);
},
onBeforeClickSchedule({type, schedule}) {
switch (type) {
case "check":
break;
case "edit":
this.$store.dispatch("openTask", schedule.id)
break;
case "delete":
break;
}
aftermm = aftermm + 1 > 11 ? 0 : (aftermm + 1);
//
let dateJson = [];
//
for (let i = pre_num; i > 0; i--) {
let obj = {year: preyy, month: premm + 1, day: (pre_max - i + 1), place: 'pre'};
obj.ymd = obj.year + '-' + zeroFill(obj.month) + '-' + zeroFill(obj.day)
dateJson.push(obj);
}
//
for (let i = 1; i <= cur_num; i++) {
let obj = {year: yy, month: mm + 1, day: i, place: 'cur'};
obj.ymd = obj.year + '-' + zeroFill(obj.month) + '-' + zeroFill(obj.day)
dateJson.push(obj);
}
//
for (let i = 1; i <= after_num; i++) {
let obj = {year: afteryy, month: aftermm + 1, day: i, place: 'after'};
obj.ymd = obj.year + '-' + zeroFill(obj.month) + '-' + zeroFill(obj.day)
dateJson.push(obj);
}
return dateJson;
},
onBeforeUpdateSchedule(res) {
console.group('onBeforeUpdateSchedule');
console.log('BeforeUpdate : ', res);
console.groupEnd();
}
}
}

View File

@ -0,0 +1,223 @@
<template>
<div ref="tuiCalendar" class="calendar-wrapper"></div>
</template>
<script>
import Calendar from 'tui-calendar-hi';
const scheduleNeedProp = [
'start',
'category'
];
export default {
name: 'Calendar',
props: {
calendars: {
type: Array,
default() {
return [];
}
},
schedules: {
type: Array,
default() {
return [];
},
validator(value) {
let notHave = false;
value.forEach(schedule => {
notHave = scheduleNeedProp.some(prop => !schedule.hasOwnProperty(prop));
});
return !notHave;
}
},
view: {
type: String,
default: 'week'
},
taskView: {
type: [Boolean, Array],
default: true
},
scheduleView: {
type: [Boolean, Array],
default: true
},
theme: {
type: Object,
default() {
return {
'common.border': '1px solid #f4f5f5',
'month.dayname.fontSize': '14px',
'month.dayname.borderLeft': '1px solid #f4f5f5',
'month.dayname.height': '50px',
};
}
},
template: {
type: Object,
default() {
return {
titlePlaceholder: function () {
return "Task Description"
}
};
}
},
week: {
type: Object,
default() {
return {};
}
},
month: {
type: Object,
default() {
return {};
}
},
useCreationPopup: {
type: Boolean,
default: true
},
useDetailPopup: {
type: Boolean,
default: true
},
timezones: {
type: Array,
default() {
return [];
}
},
disableDblClick: {
type: Boolean,
default: false
},
disableClick: {
type: Boolean,
default: false
},
isReadOnly: {
type: Boolean,
default: false
},
usageStatistics: {
type: Boolean,
default: true
}
},
data() {
return {
calendarInstance: null
}
},
watch: {
calendars(newValue) {
this.calendarInstance.setCalendars(newValue);
},
schedules() {
this.calendarInstance.clear();
this.reflectSchedules();
},
view(newValue) {
this.calendarInstance.changeView(newValue, true);
},
taskView(newValue) {
this.calendarInstance.setOptions({taskView: newValue});
},
scheduleView(newValue) {
this.calendarInstance.setOptions({scheduleView: newValue});
},
theme: {
handler(newValue) {
this.calendarInstance.setTheme(this.cloneData(newValue));
},
deep: true
},
week: {
handler(newValue) {
const silent = this.view !== 'week' && this.view !== 'day';
this.calendarInstance.setOptions({week: this.cloneData(newValue)}, silent);
},
deep: true
},
month: {
handler(newValue) {
const silent = this.view !== 'month';
this.calendarInstance.setOptions({month: this.cloneData(newValue)}, silent);
},
deep: true
},
timezones(newValue) {
this.calendarInstance.setOptions({timezones: newValue});
},
disableDblClick(newValue) {
this.calendarInstance.setOptions({disableDblClick: newValue});
},
disableClick(newValue) {
this.calendarInstance.setOptions({disableClick: newValue});
},
isReadOnly(newValue) {
this.calendarInstance.setOptions({isReadOnly: newValue});
}
},
mounted() {
this.calendarInstance = new Calendar(this.$refs.tuiCalendar, {
defaultView: this.view,
taskView: this.taskView,
scheduleView: this.scheduleView,
theme: this.theme,
template: this.template,
week: this.week,
month: this.month,
calendars: this.calendars,
useCreationPopup: this.useCreationPopup,
useDetailPopup: this.useDetailPopup,
timezones: this.timezones,
disableDblClick: this.disableDblClick,
disableClick: this.disableClick,
isReadOnly: this.isReadOnly,
usageStatistics: this.usageStatistics
});
this.addEventListeners();
this.reflectSchedules();
},
beforeDestroy() {
this.calendarInstance.off();
this.calendarInstance.destroy();
},
methods: {
cloneData(data) {
return JSON.parse(JSON.stringify(data));
},
addEventListeners() {
for (const eventName of Object.keys(this.$listeners)) {
this.calendarInstance.on(eventName, (...args) => this.$emit(eventName, ...args));
}
},
reflectSchedules() {
if (this.schedules.length > 0) {
this.invoke('createSchedules', this.schedules);
}
},
getRootElement() {
return this.$refs.tuiCalendar;
},
getInstance() {
return this.calendarInstance;
},
invoke(methodName, ...args) {
let result;
if (this.calendarInstance[methodName]) {
result = this.calendarInstance[methodName](...args);
}
return result;
}
}
};
</script>

View File

@ -46,7 +46,7 @@
</li>
</ul>
<div class="project-switch">
<div v-if="projectTablePanel && completedList.length > 0" class="project-checkbox">
<div v-if="completedCount > 0" class="project-checkbox">
<Checkbox :value="projectCompleteHide" @on-change="toggleBoolean('projectCompleteHide', $event)">{{$L('隐藏已完成')}}</Checkbox>
</div>
<div :class="['project-switch-button', !projectTablePanel ? 'menu' : '']" @click="toggleBoolean('projectTablePanel')">
@ -480,10 +480,15 @@ export default {
},
myList() {
const {searchText, userId, projectDetail} = this;
const {searchText, projectCompleteHide, userId, projectDetail} = this;
const array = [];
projectDetail.project_column.forEach(({project_task, name}) => {
project_task.some((task) => {
if (projectCompleteHide) {
if (task.complete_at) {
return false;
}
}
if (searchText) {
if (!$A.strExists(task.name, searchText) && !$A.strExists(task.desc, searchText)) {
return false;
@ -507,10 +512,15 @@ export default {
},
undoneList() {
const {searchText, projectDetail} = this;
const {searchText, projectCompleteHide, projectDetail} = this;
const array = [];
projectDetail.project_column.forEach(({project_task, name}) => {
project_task.some((task) => {
if (projectCompleteHide) {
if (task.complete_at) {
return false;
}
}
if (searchText) {
if (!$A.strExists(task.name, searchText) && !$A.strExists(task.desc, searchText)) {
return false;
@ -533,11 +543,25 @@ export default {
});
},
completedCount() {
const {projectDetail} = this;
let count = 0;
projectDetail.project_column.forEach(({project_task, name}) => {
count += project_task.filter(({complete_at}) => !!complete_at).length;
});
return count;
},
completedList() {
const {searchText, projectDetail} = this;
const {searchText, projectCompleteHide, projectDetail} = this;
const array = [];
projectDetail.project_column.forEach(({project_task, name}) => {
project_task.some((task) => {
if (projectCompleteHide) {
if (task.complete_at) {
return false;
}
}
if (searchText) {
if (!$A.strExists(task.name, searchText) && !$A.strExists(task.desc, searchText)) {
return false;

View File

@ -26,7 +26,7 @@
<i v-else-if="dialog.group_type=='task'" class="iconfont icon-avatar task">&#xe6f4;</i>
<Icon v-else class="icon-avatar" type="ios-people" />
</template>
<div v-else-if="dialog.dialog_user" class="user-avatar"><UserAvatar :userid="dialog.dialog_user.userid" :size="46" hide-icon-menu/></div>
<div v-else-if="dialog.dialog_user" class="user-avatar"><UserAvatar :userid="dialog.dialog_user.userid" :size="42" hide-icon-menu/></div>
<Icon v-else class="icon-avatar" type="md-person" />
<div class="dialog-box">
<div class="dialog-title">

View File

@ -398,6 +398,30 @@ export default {
}
},
/**
* 获取任务列表
* @param state
* @param dispatch
* @param whereData
* @returns {Promise<unknown>}
*/
getTaskList({state, dispatch}, whereData) {
return new Promise(function (resolve, reject) {
if (state.userId === 0) {
reject()
return;
}
dispatch("call", {
url: 'project/task/lists',
data: whereData,
}).then(result => {
resolve(result)
}).catch(result => {
reject(result)
});
});
},
/**
* 获取任务信息
* @param state

View File

@ -12,6 +12,21 @@ $--tooltip-font-size: 14px;
.el-dropdown-menu__item {
min-width: 100px;
line-height: 34px;
.item {
&.red {
color: #f00;
> i {
color: #f00;
}
}
&:hover {
&.red {
> i {
color: #f00;
}
}
}
}
}
.el-dropdown-menu__item--divided:before {

View File

@ -22,7 +22,7 @@
bottom: 0;
width: 100%;
height: 1px;
background-color: #f2f2f2;
background-color: #f4f5f5;
}
.main-title {
display: flex;

View File

@ -739,23 +739,12 @@
font-size: 16px;
}
}
&.red {
color: #f00;
> i {
color: #f00;
}
}
&:hover {
> i {
&.ivu-icon {
color: #66b1ff;
}
}
&.red {
> i {
color: #f00;
}
}
}
}
}

View File

@ -1,6 +1,4 @@
.page-calendar {
display: flex;
flex-direction: column;
.calendar-head {
display: flex;
align-items: flex-start;
@ -30,100 +28,79 @@
}
}
}
}
}
.calendar-box {
flex: 1;
height: 0;
display: flex;
flex-direction: column;
padding: 0 48px;
.head {
display: flex;
align-items: center;
border-bottom: 1px solid #f4f5f5;
> li {
.calendar-view {
margin-left: 36px;
flex: 1;
list-style: none;
display: flex;
align-items: center;
justify-content: center;
padding: 12px;
position: relative;
&:after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 1px;
height: 100%;
background-color: #f4f5f5;
}
&:last-child {
&:after {
display: none;
justify-content: flex-end;
> button {
&:focus {
box-shadow: none;
}
}
}
}
.days {
}
.calendar-box {
padding: 0 48px;
.calendar-wrapper {
flex: 1;
flex-shrink: 0;
display: flex;
flex-direction: column;
> li {
flex: 1;
flex-shrink: 0;
list-style: none;
display: flex;
flex-direction: column;
border-bottom: 1px solid #f4f5f5;
> ul {
flex: 1;
flex-shrink: 0;
position: relative;
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background-color: #ffffff;
z-index: 1;
}
.tui-full-calendar-popup-creation {
.tui-full-calendar-popup-section {
display: flex;
> li {
flex: 1;
flex-shrink: 0;
list-style: none;
position: relative;
display: flex;
flex-direction: column;
.time {
padding: 10px 10px 0;
> em {
font-style: normal;
display: inline-block;
border-radius: 50%;
min-height: 24px;
min-width: 24px;
line-height: 24px;
text-align: center;
&.cur-day {
background-color: #2d8cf0;
color: #ffffff;
}
}
}
&:after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 1px;
height: 100%;
background-color: #f4f5f5;
}
&:last-child {
&:after {
display: none;
}
}
&.pre,
&.after {
color: #aaaaaa;
}
justify-content: space-between;
margin-bottom: 6px;
}
.tui-full-calendar-section-title {
width: 100%;
}
.tui-full-calendar-section-start-date,
.tui-full-calendar-section-end-date {
width: 210px;
}
.tui-full-calendar-popup-location,
.tui-full-calendar-section-private,
.tui-full-calendar-section-allday,
.tui-full-calendar-section-state {
display: none;
}
}
.tui-full-calendar-popup-task {
.priority {
color: #ffffff;
padding: 2px 3px;
border-radius: 4px;
}
.tui-full-calendar-calendar-dot,
.tui-full-calendar-ic-priority {
opacity: 0;
}
}
.tui-datepicker {
.tui-calendar {
th,
td {
height: 35px;
}
.tui-calendar-prev-month.tui-calendar-date,
.tui-calendar-next-month.tui-calendar-date {
visibility: visible;
}
}
.tui-datepicker-body .tui-timepicker,
.tui-datepicker-footer .tui-timepicker {
padding: 16px 46px 16px 47px;
}
}
}

View File

@ -20,7 +20,7 @@
right: 0;
height: 100%;
width: 1px;
background-color: #f2f2f2;
background-color: #f4f5f5;
}
.messenger-search {
display: flex;
@ -83,8 +83,9 @@
list-style: none;
.user-avatar,
.icon-avatar {
width: 46px;
height: 46px;
width: 42px;
height: 42px;
margin: 2px;
flex-grow: 0;
flex-shrink: 0;
}
@ -229,12 +230,12 @@
display: flex;
align-items: center;
justify-content: center;
height: 54px;
height: 52px;
flex-shrink: 0;
border-top: 1px solid #f2f2f2;
border-top: 1px solid #f4f5f5;
> i {
cursor: pointer;
font-size: 28px;
font-size: 24px;
margin: 0 24px;
color: #aaaaaa;
opacity: 0.9;