Commit eafd66ea authored by lshan's avatar lshan

Merge remote-tracking branch 'origin/main' into ls_tev

parents eea43bfc 5533e54f
src/assets/icons/confirm.png

4.04 KB | W: | H:

src/assets/icons/confirm.png

943 Bytes | W: | H:

src/assets/icons/confirm.png
src/assets/icons/confirm.png
src/assets/icons/confirm.png
src/assets/icons/confirm.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/icons/deny.png

4.46 KB | W: | H:

src/assets/icons/deny.png

1.11 KB | W: | H:

src/assets/icons/deny.png
src/assets/icons/deny.png
src/assets/icons/deny.png
src/assets/icons/deny.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -7,7 +7,7 @@
<div class="flex py-3 items-center justify-between">
<slot name="prefix" />
<div class="flex justify-between flex-1" :class="contentAlign">
<div v-if="checkIfEmpty(title)" class="title flex-shrink-0 mr-4" :class="titleColor">{{ title }}</div>
<div v-if="checkIfEmpty(title)" class="title flex-shrink-0 mr-4" :class="getClass">{{ title }}</div>
<!-- 输入框 -->
<template v-if="type === 'input'">
<input
......@@ -64,10 +64,14 @@ export default Vue.extend({
type: String,
default: 'text-text-primary'
},
<<<<<<< HEAD
leftinput: {
type: String,
default: 'text-right'
},
=======
titleClass: String,
>>>>>>> origin/main
contentAlign: {
type: String,
default: 'items-center'
......@@ -77,6 +81,11 @@ export default Vue.extend({
content: String
},
name: 'CCell',
computed: {
getClass(): string {
return `${this.titleColor || ''} ${this.titleClass || '' }`
}
},
methods: {
clickItem() {
this.$emit('click')
......
<template>
<div class="text-xs px-1 py-0.5 rounded inline-block" :class="getTagClass">
<div class="text-xs px-1.5 py-0.5 inline-block" :class="getTagClass">
{{ label }}
</div>
</template>
......@@ -17,6 +17,11 @@ export default Vue.extend({
return ['primary', 'red', 'green', 'purple', 'yellow', 'orange'].indexOf(val) > -1
}
},
tagClass: String,
round: {
type: Boolean,
default: false
},
label: {
type: String,
default: '标签'
......@@ -33,7 +38,10 @@ export default Vue.extend({
// 'tag-yellow': '#F3B200',
// 'tag-red': '#EB8282',
// 'tag-purple': '#9F82E5',
return `bg-tag-${this.color}-lighter text-tag-${this.color}`
if (typeof this.tagClass !== 'undefined' && this.tagClass !== '') {
return `${this.tagClass} ${this.round ? 'rounded-full' : 'rounded'}`
}
return `bg-tag-${this.color}-lighter text-tag-${this.color} ${this.tagClass} ${this.round ? 'rounded-full' : 'rounded'}`
}
},
methods: {
......
......@@ -12,18 +12,34 @@ export const scheduleRoutes: Array<RouteConfig> = [
children: [
{
path: 'schedule-home',
name: 'schedule-home',
name: 'ScheduleHome',
component: () => import('@/views/schedule/schedule.vue'),
meta: {
title: '协同日程'
}
},
{
path: 'test',
name: 'Test',
component: () => import('@/views/schedule/test.vue'),
path: 'schedule-detail/:id',
name: 'ScheduleDetail',
component: () => import('@/views/schedule/schedule-detail.vue'),
meta: {
title: 'Test'
title: '日程详情'
}
},
{
path: 'team',
name: 'ScheduleTeam',
component: () => import('@/views/schedule/team-frame.vue'),
meta: {
title: '所有成员'
}
},
{
path: 'team/:id',
name: 'ScheduleTeamDetail',
component: () => import('@/views/schedule/team-detail.vue'),
meta: {
title: '所有成员'
}
},
{
......
......@@ -4,6 +4,7 @@
@touchstart="touchStart"
@touchend="touchEnd"
>
<!-- 头部 -->
<div class="flex">
<div class="flex-shrink-0 w-11 text-sm flex items-center py-1.5" @click="switchShow">
<div class="">{{ month }}</div>
......@@ -12,73 +13,84 @@
class-name="h-3 w-3"
/>
</div>
<!-- 头部周几 -->
<div
v-for="(day, index) in days"
:key="index"
class="flex-1 text-sm text-text-secondary text-center py-1.5"
class="flex-1 text-sm text-text-secondary text-center py-1.5 opacity-70"
>
{{ day }}
</div>
</div>
<!-- 天展示 -->
<div class="flex text-sm">
<div class="w-11 flex-shrink-0"/>
<div class="flex-1 overflow-hidden">
<div class="col-span-7 grid grid-cols-7 m-1" :class="open ? 'min-h-12' : 'h-12'">
<!-- 缩略 -->
<!-- <template v-if="open">
</template> -->
<!-- 展开 -->
<!-- <template v-else>
</template> -->
<div class="flex-1 col-span-7 grid grid-cols-7" :class="open ? 'min-h-10' : 'h-10'">
<div
v-for="(day, index) in daysShow"
:key="index"
class="flex items-center justify-center my-0.5 h-9 relative"
:class="getDateClass(day)"
@click="selectDay(day)"
>
<span :class="day.year === selectedYear && day.month === selectedMonth && day.date === date ? 'opacity-100' : 'opacity-70'">{{ day.date }}</span>
<div
v-for="(day, index) in daysShow"
:key="index"
class="flex items-center justify-center h-9 my-1 relative"
:class="getDateClass(day)"
@click="selectDay(day)"
>
{{ day.day }}
<div
v-if="showDot(day.day)"
class="dot h-1 w-1 rounded-full bg-tag-green absolute bottom-0 left-1/2 transform -translate-x-1/2"
/>
</div>
v-if="showDot(day)"
class="dot h-1 w-1 rounded-full bg-tag-green absolute bottom-0 left-1/2 transform -translate-x-1/2"
/>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from "vue"
import Vue, { PropType } from "vue"
interface Day {
type: string,
day: number,
month: number,
year: number
year: number,
date: number,
}
type RangeDays = [Date, Date]
export default Vue.extend({
name: "Calendar",
components: {
// 'main-page': () => import('@/layout/main-page.vue'),
'app-icon': () => import('@/components/common/Icon.vue')
},
props: {
defaultDate: Date as PropType<Date>,
selectedDays: {
type: Array as PropType<Date[]>,
default() {
return []
}
},
rangeDays: {
type: Array as PropType<RangeDays[]>,
default() {
return []
}
},
select: [Date, null] as PropType<Date>
},
data() {
const daysInMonth: Array<Day> = []
const daysShow: Array<Day> = []
return {
daysInMonth,
daysShow,
currentDate: 0,
month: 0,
year: 0,
date: 0,
day: 0,
selectedYear: 0,
selectedMonth: 0,
day: 0,
days: ['日', '一', '二', '三', '四', '五', '六'],
checkedDays: [new Date(2021,8,17).getTime(), new Date(2021,8,14).getTime(), new Date(2021,8,25).getTime()],
tripDays: [new Date(2021,8,12).getTime(), new Date(2021,8,15)],
startX: 0,
open: false,
rowIndex: 0, // 缩略状态下展示的天数行
......@@ -90,34 +102,46 @@ export default Vue.extend({
}
},
created() {
// 获取年月日
this.selectedMonth = this.month = new Date().getMonth() + 1
this.selectedYear = this.year = new Date().getFullYear()
this.day = new Date().getDate()
this.currentDate = new Date().getTime()
// 获取月份天数展示
this.daysInMonth = this.getDaysInMonth(this.year, this.month - 1)
const {days, index} = this.getDaysShowInShort(this.day, this.daysInMonth)
this.daysShow = this.open ? this.daysInMonth : days
this.rowIndex = index
this.init()
},
methods: {
init() {
// 获取年月日
const currentDate = this.select || this.defaultDate || new Date()
this.selectedMonth = this.month = currentDate.getMonth() + 1
this.selectedYear = this.year = currentDate.getFullYear()
this.date = currentDate.getDate()
this.day = currentDate.getDay()
// 获取月份天数展示
this.daysInMonth = this.getDaysInMonth(this.year, this.month)
const {days, index} = this.getDaysShowInShort(this.date, this.daysInMonth)
this.daysShow = this.open ? this.daysInMonth : days
this.rowIndex = index
},
// 根据日期获取年月日
getYearMonthDay(val: Date) {
const year = val.getFullYear()
const month = val.getMonth() + 1
const date = val.getDate()
const day = val.getDay()
return { year, month, date, day}
},
// 切换显示模式
switchShow() {
this.open = !this.open
const check = this.daysInMonth.find(day => this.getTime(day.year, day.month, day.day) === this.getTime(this.selectedYear, this.selectedMonth, this.day))
const check = this.daysInMonth.find(day => this.getTime(day.year, day.month, day.date) === this.getTime(this.selectedYear, this.selectedMonth, this.date))
let day = 1
if (typeof check === 'undefined') {
this.rowIndex = 0
} else {
day = this.day
this.rowIndex = this.getRowIndex(this.day, this.daysInMonth)
day = this.date
this.rowIndex = this.getRowIndex(this.date, this.daysInMonth)
}
this.daysShow = this.open ? this.daysInMonth : this.getDaysShowInShort(day, this.daysInMonth).days
},
// 获取天数展示的index
// 获取天数展示的index
getRowIndex(day: number, daysArr: Array<Day>) {
const index = daysArr.findIndex(item => item.day === day && item.type === 'current')
const index = daysArr.findIndex(item => item.date === day && item.type === 'current')
return Math.floor( index / 7 )
},
// 缩略情况下显示的天数
......@@ -129,6 +153,7 @@ export default Vue.extend({
touchStart(e: TouchEvent) {
this.startX = e.touches[0].clientX
},
// 重新获取月份天数
getNewMonthDays(type: string) {
let newYear = 0
let newMonth = 0
......@@ -143,7 +168,21 @@ export default Vue.extend({
}
this.year = newYear
this.month = newMonth
this.daysInMonth = this.getDaysInMonth(this.year, this.month - 1)
this.daysInMonth = this.getDaysInMonth(this.year, this.month)
},
// 左右滑动 默认选中设置
setDefaultSelect() {
let day: Day
if (this.open) {
day = this.daysShow.find(item => item.date === 1 && item.type === 'current') as Day
} else {
day = this.daysShow.find(item => item.day === this.day) as Day
}
this.$emit('update:select', new Date(day.year, day.month - 1, day.date))
this.selectedYear = day.year
this.selectedMonth = day.month
this.date = day.date
this.day = day.day
},
// 触摸结束
touchEnd(e: TouchEvent) {
......@@ -164,6 +203,7 @@ export default Vue.extend({
}
this.daysShow = this.getShowDays(this.rowIndex, this.daysInMonth)
}
this.setDefaultSelect()
}
if (this.startX - end > 40) {
// 右滑
......@@ -180,20 +220,39 @@ export default Vue.extend({
}
this.daysShow = this.getShowDays(this.rowIndex, this.daysInMonth)
}
this.setDefaultSelect()
}
},
// 当前有会议的展示圆点
showDot(day: number) {
const date = this.getTime(this.year, this.month, day)
const checkIfNotTripDate = date < this.tripDays[0] || date > this.tripDays[1]
return this.checkedDays.indexOf(date) > -1 && date !== this.getTime(this.year, this.month, this.day) && checkIfNotTripDate
showDot(day: Day) {
const date = this.getTime(day.year, day.month, day.date)
const checkIfNotTripDate = this.checkIfInRangeDays(day, this.rangeDays)
const index = this.selectedDays.findIndex(day => {
const { year, month, date: newDate } = this.getYearMonthDay(day)
return this.getTime(year, month, newDate) === date
})
return index > -1 && date !== this.getTime(this.year, this.month, this.date) && !checkIfNotTripDate
},
// 查询当前日期是否在日期区间内
checkIfInRangeDays(targetDay: Day, rangeDays: Array<RangeDays>) {
const target = this.getTime(targetDay.year, targetDay.month, targetDay.date)
const index = rangeDays.findIndex(dayArr => {
const {year: startYear, month: startMonth, date: startDate} = this.getYearMonthDay(dayArr[0])
const {year: endYear, month: endMonth, date: endDate} = this.getYearMonthDay(dayArr[1])
return target >= this.getTime(startYear, startMonth, startDate) && target <= this.getTime(endYear, endMonth, endDate)
})
return index > -1
},
// 会议日期区间显示下划线
showRangeDateLine(day: Day) {
return this.checkIfInRangeDays(day, this.rangeDays)
},
// 日期样式列表
getDateClass(day: Day) {
if (day.type === 'current') {
if (this.getTime(day.year, day.month, day.day) === this.getTime(this.selectedYear, this.selectedMonth, this.day)) {
if (this.getTime(day.year, day.month, day.date) === this.getTime(this.selectedYear, this.selectedMonth, this.date)) {
return 'rounded-full bg-color-primary text-white shadow-schedule-selected'
} else if (this.getTime(this.year, this.month, day.day) >= this.tripDays[0] && this.getTime(this.year, this.month, day.day) <= this.tripDays[1] ) {
} else if (this.showRangeDateLine(day)) {
return 'text-text-secondary border-b border-schedule-line'
} else {
return 'text-text-secondary'
......@@ -204,9 +263,11 @@ export default Vue.extend({
},
// 点击选择日期
selectDay(day: Day) {
this.date = day.date
this.day = day.day
this.selectedYear = day.year
this.selectedMonth = day.month
this.$emit('update:select', new Date(day.year, day.month - 1, day.date))
switch (day.type) {
case 'pre': {
this.getNewMonthDays('pre')
......@@ -229,7 +290,7 @@ export default Vue.extend({
break
}
default: {
this.rowIndex = this.getRowIndex(day.day, this.daysInMonth)
this.rowIndex = this.getRowIndex(day.date, this.daysInMonth)
}
}
},
......@@ -259,6 +320,7 @@ export default Vue.extend({
},
// 获取月份中的天数
getDaysInMonth(year: number, month: number) {
const newMonth = month - 1
const result: Array<Day> = []
// 一年中每个月的天数
const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
......@@ -267,38 +329,53 @@ export default Vue.extend({
daysInMonth[1] = 29
}
// 当月第一天日期 周几 0-6
const firstDay = new Date(year, month, 1).getDay()
let firstDay = new Date(year, newMonth, 1).getDay()
// 获取当月一号前几天显示
for (let i = 0; i < firstDay; i++) {
result.push({
type: 'pre',
day: daysInMonth[month - 1 < 0 ? 0 : month - 1] - firstDay + 1 + i,
day: i,
year,
month: month
month: newMonth,
date: daysInMonth[newMonth - 1 < 0 ? 0 : newMonth - 1] - firstDay + 1 + i,
})
}
// 当月日期天数
for (let i = 0; i < daysInMonth[month]; i++) {
for (let i = 0; i < daysInMonth[newMonth]; i++) {
result.push({
type: 'current',
day: i + 1,
date: i + 1,
year,
month: month + 1
month: newMonth + 1,
day: firstDay
})
if (firstDay >= 6) {
firstDay = 0
} else {
firstDay++
}
// firstDay = firstDay > 6 ? 0 : firstDay++
}
// 获取当月最后一天之后显示天数
for (let i = 0; i < 6 - new Date(year, month + 1, 0).getDay(); i++) {
for (let i = 0; i < 6 - new Date(year, newMonth + 1, 0).getDay(); i++) {
result.push({
type: 'next',
day: i + 1,
date: i + 1,
year,
month: month + 2
month: newMonth + 2,
day: firstDay
})
if (firstDay >= 6) {
firstDay = 0
} else {
firstDay++
}
}
return result
},
// new Date().getTime()
getTime(year: number, month: number, day: number) {
return new Date(year, month, day).getTime()
return new Date(year, month - 1, day).getTime()
},
// 获取展示的天数
getShowDays(index: number, daysArr: Array<Day>) {
......
<template>
<div class="card flex items-center">
<div class="action flex-shrink-0 mr-2.5 flex items-start">
<div class="relative">
<div class="relative z-50 mr-1.5">
<!-- checkbox -->
<div
v-if="checkBox"
@click="handleCheck">
<div
v-show="!checked"
class="w-4 h-4 border border-schedule-timeline rounded-full"
/>
<div v-show="checked" class="">
<app-icon
icon-name="radio-checked"
class-name="w-4 h-4"
/>
</div>
</div>
<!-- 状态切换 -->
<div v-else>
<app-icon
icon-name="radio-checked"
class-name="w-4 h-4"
/>
</div>
</div>
<div class="absolute h-4 w-4 top-0 left-0 rounded-full bg-common-bg z-10" />
</div>
<div class="text-text-secondary font-light">
<div class="text-xs">{{ time }}</div>
<div class="text-xxs">{{ space }}</div>
</div>
</div>
<div class="bg-white rounded-lg px-3 py-2 flex-1 overflow-hidden" @click="handleClick">
<!-- 会议标题 -->
<div class="content flex justify-between over">
<div class="overflow-hidden">
<div class="">{{ schedule.title }}</div>
<div class="text-xs font-light truncate">{{ schedule.content }}</div>
</div>
<app-icon
icon-name="avator"
class-name="w-9 h-9 flex-shrink-0 ml-2"
/>
</div>
<!-- 其他信息 -->
<div class="text-xxs text-text-secondary font-light mt-2 flex items-center justify-between pr-3.5">
<div class="flex items-center">
<app-icon
icon-name="location-small"
class-name="w-2 mr-1.5"
/>
<div>{{ schedule.location }}</div>
</div>
<div class="flex items-center">
<app-icon
icon-name="user"
class-name="h-2.5 w-2.5 mr-4"
/>
<div class="member flex items-center">
<div class="icons flex">
<div
v-for="num of schedule.member > 3 ? 3 : schedule.member"
:key="num"
class="-ml-1.5 first:ml-none"
>
<app-icon
icon-name="avator-small"
class-name="w-4.5 h-4.5"
/>
</div>
</div>
<div class="bg-text-extreme-light rounded px-1 ml-1">+{{ schedule.member }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'ScheduleCard',
props: {
schedule: {
type: Object,
default() {
return {}
}
},
checkBox: {
type: Boolean,
default: true
},
checked: {
type: Boolean,
default: false
}
},
components: {
'app-icon': () => import('@/components/common/Icon.vue'),
},
data() {
return {
time: '8:00am',
space: '45min'
}
},
methods: {
handleCheck() {
this.$emit('check', this.schedule)
},
handleClick() {
this.$emit('click', this.schedule)
}
}
})
</script>
<template>
<div class="">
<div
v-for="(item, index) in meetings"
:key="index"
class="w-full relative pt-4">
<schedule-card
:schedule="item"
:check-box="checkBox"
:checked="checkedList.indexOf(item.id) > -1"
@check="handleCheck"
@click="handleClick"
/>
<div class="absolute w-px left-2 bg-schedule-timeline" :class="getLineClass(index)" />
</div>
</div>
</template>
<script lang="ts">
import Vue, { PropType} from 'vue'
interface Schedule {
id: number,
title: string,
content: string,
location: string,
member: number
}
const meetings: Array<Schedule> = [
{
id: 11,
title: '部门例会',
content: '讨论“上链查”的实际应用模块',
location: '峨眉山会议室',
member: 3
},
{
id: 22,
title: '部门例会',
content: '讨论“上链查”的实际应用模块',
location: '峨眉山会议室',
member: 3
},
{
id: 33,
title: '部门例会',
content: '讨论“上链查”的实际应用模块',
location: '峨眉山会议室',
member: 3
}
]
export default Vue.extend({
name: 'ScheduleLine',
props: {
scheduleList: {
type: Array as PropType<Array<Schedule>>,
default() {
return []
}
},
checkBox: {
type: Boolean,
default: false
},
checkedList: {
type: Array,
default() {
return []
}
}
},
components: {
'app-icon': () => import('@/components/common/Icon.vue'),
'schedule-card': () => import('./schedule-card.vue')
},
data() {
// const checkList: number[] = []
return {
meetings
// checkList
}
},
methods: {
getLineClass(index: number) {
if (this.meetings.length < 2) {
return ''
}
if (index === 0) {
return 'h-1/2 left-2 bottom-0'
}
if (index === this.meetings.length - 1) {
return 'h-1/2 left-2 top-0'
}
return 'h-full left-2 top-0'
},
handleCheck(schedule: Schedule) {
const list: Array<number> = JSON.parse(JSON.stringify(this.checkedList))
const index = list.findIndex(id => id === schedule.id)
if (index < 0) {
list.push(schedule.id)
} else {
list.splice(index, 1)
}
this.$emit('update:checkedList', list)
},
handleClick(schedule: Schedule) {
this.$emit('click-schedule', schedule)
}
}
})
</script>
<template>
<!-- 协同日程 -->
<main-page
left-arrow
:title="title"
@click-left="$router.go(-1)"
>
<div
slot="right"
class="h-6 w-6 flex items-center justify-end"
@click="show = true"
>
<app-icon
icon-name="dot-h"
class-name="h-1 w-5"
/>
</div>
<van-action-sheet v-model="show" :actions="actions" @select="onSelect" />
<div class="py-16 px-4">
<group-cell title="基本信息">
<c-cell
title="开始时间"
content="4月3号 14:30"
title-class="text-text-secondary text-sm"
/>
<c-cell
title="结束"
content="4月3号 15:30"
title-class="text-text-secondary text-sm"
/>
<c-cell
title="地点"
content="第一会议室"
title-class="text-text-secondary text-sm"
/>
<c-cell>
<div
slot="content"
class="w-full flex justify-between items-center"
>
<div class="text-text-secondary text-sm">负责人</div>
<app-icon
icon-name="avator"
class-name="h-6 w-6"
/>
</div>
</c-cell>
<c-cell>
<div
slot="content"
class="w-full flex justify-between items-center"
>
<div class="text-text-secondary text-sm">参与人员</div>
<div class="flex items-center">
<div class="avators flex">
<div
v-for="index of 3"
:key="index"
class="-ml-2 first:-ml-0"
>
<app-icon
icon-name="avator-small"
class-name="h-6 w-6"
/>
</div>
</div>
<div class="text-xxs bg-text-extreme-light rounded-sm text-text-secondary ml-2 px-1">+12</div>
<app-icon
icon-name="right-arrow"
class-name="w-1.5 h-2 ml-2"
/>
</div>
</div>
</c-cell>
<c-cell label="描述">
<div slot="content" class="text-sm text-text-secondary">非强制参加的公司公开日程</div>
</c-cell>
</group-cell>
<group-cell class="mt-4" title="更多信息">
<c-cell
title="属性"
title-class="text-text-secondary text-sm"
content="私有"
/>
<c-cell>
<div slot="content" class="w-full flex justify-between items-center">
<div class="title text-sm text-text-secondary">标签</div>
<c-tag round tag-class="bg-gradient-to-r from-meeting-l to-meeting-r text-white text-sm" label="会议" />
</div>
</c-cell>
<c-cell>
<div
slot="content"
class="w-full flex justify-between items-center"
>
<div class="text-text-secondary text-sm">附件</div>
<div class="flex items-center">
<div class="text-sm text-text-secondary">2</div>
<app-icon
icon-name="right-arrow"
class-name="w-1.5 h-2 ml-2"
/>
</div>
</div>
</c-cell>
</group-cell>
<!-- 评论 -->
<div class="fixed bottom-0 left-0 w-full bg-white px-4 py-2.5 flex items-center justify-between">
<div class="flex-1 bg-input-bg rounded-full px-4 py-2 text-xs text-text-secondary">添加评论</div>
<div class="text-sm ml-4">评论</div>
</div>
</div>
</main-page>
</template>
<script lang="ts">
import Vue from "vue"
import { ActionSheet } from 'vant'
Vue.use(ActionSheet)
export default Vue.extend({
name: "ScheduleDetail",
components: {
'main-page': () => import('@/layout/main-page.vue'),
'app-icon': () => import('@/components/common/Icon.vue'),
'group-cell': () => import('@/components/common/group-cell.vue'),
'c-cell': () => import('@/components/common/c-cell.vue'),
'c-tag': () => import('@/components/common/c-tag.vue')
},
data() {
return {
show: false,
actions: [
{
name: '分享我的日程',
action: 'share'
},
{
name: '管理我的日程',
action: 'manage'
},
{
name: '查看其他成员日程',
action: 'check'
}
],
title: ''
}
},
methods: {
onSelect(action: {name: string, action: string}) {
this.show = false
},
}
})
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
......@@ -2,159 +2,170 @@
<!-- 协同日程 -->
<main-page
left-arrow
:title="title"
@click-left="$router.go(-1)"
>
<div class="pt-14">
<calendar />
>
<div
v-if="!isMember"
slot="right"
class="h-6 w-6 flex items-center justify-end"
@click="show = true"
>
<app-icon
icon-name="dot-h"
class-name="h-1 w-5"
/>
</div>
<van-action-sheet v-model="show" :actions="actions" @select="onSelect" />
<div class="pt-14 pb-4">
<calendar
:selected-days="selectedDays"
:range-days="rangeDays"
:select.sync="select"
/>
<div class="px-4 mt-6 pb-16">
<div v-if="!isMember" class="tab flex relative">
<div
v-for="tab in tabs"
:key="tab.key"
class="transition-all duration-200 flex-1 py-1.5 text-center"
:class="currentKey === tab.key ? 'text-white rounded-full bg-color-primary' : ''"
@click="clickTab(tab)"
>
{{ tab.label }}
</div>
</div>
<schedule-line
class="mt-4"
:check-box="showCheckBox"
:checked-list.sync="checkedSchdules"
@click-schedule="clickSchedule"
/>
<!-- 查看成员日程时不显示操作栏 -->
<div v-if="!isMember" class="fixed bottom-0 left-0 w-full flex items-center justify-center">
<!-- 默认展示,添加日程操作 -->
<div v-show="!showCheckBox">
<app-icon
icon-name="add-btn"
class-name="h-18 w-18"
/>
</div>
<!-- 管理日程显示 -->
<div v-show="showCheckBox" class="w-full bg-common-bg">
<!-- 我的日程 -->
<div
v-show="currentKey === 'mine'"
class="flex w-full text-center"
>
<div class="flex-1 py-1.5">归档</div>
<div class="flex-1 py-1.5">删除</div>
<div class="flex-1 py-1.5" @click="complete">完成</div>
</div>
<!-- 企业日程 -->
<div
v-show="currentKey === 'company'"
class="flex w-full text-center"
>
<div class="flex-1 py-1.5">申请</div>
<div class="flex-1 py-1.5" @click="complete">完成</div>
</div>
</div>
</div>
</div>
</div>
</main-page>
</template>
<script lang="ts">
import Vue from "vue"
import Calendar from './components/calendar.vue'
import { ActionSheet } from 'vant'
Vue.use(ActionSheet)
interface Day {
type: string,
day: number
interface Schedule {
id: number,
title: string,
content: string,
location: string,
member: number
}
export default Vue.extend({
name: "Schedule",
components: {
'main-page': () => import('@/layout/main-page.vue'),
calendar: Calendar
},
created() {
this.month = new Date().getMonth() + 1
this.year = new Date().getFullYear()
this.day = new Date().getDay()
this.daysInMonth = this.getDaysInMonth(this.year, this.month - 1)
'app-icon': () => import('@/components/common/Icon.vue'),
'schedule-card': () => import('./components/schedule-card.vue'),
'schedule-line': () => import('./components/schedule-line.vue'),
'calendar': () => import('./components/calendar.vue')
},
data() {
const daysInMonth: Array<{type: string, day: number}> = []
const checkedSchdules: number[] = []
return {
daysInMonth,
month: 0,
year: 0,
day: 0,
days: ['日', '一', '二', '三', '四', '五', '六'],
checkedDays: [new Date(2021,8,17).getTime(), new Date(2021,8,14).getTime(), new Date(2021,8,25).getTime()],
tripDays: [new Date(2021,8,12).getTime(), new Date(2021,8,15)],
startX: 0
checkedSchdules,
selectedDays: [new Date('2021-08-17'), new Date('2021-08-14'), new Date('2021-08-25')],
rangeDays: [[new Date('2021-08-20'), new Date('2021-08-24')], [new Date('2021-08-31'), new Date('2021-09-01')]],
select: null,
tabs: [
{
label: '我的日程',
key: 'mine'
},
{
label: '企业日程',
key: 'company'
}
],
currentKey: 'mine',
show: false,
actions: [
{
name: '分享我的日程',
action: 'share'
},
{
name: '管理我的日程',
action: 'manage'
},
{
name: '查看其他成员日程',
action: 'check'
}
],
title: '',
isMember: false,
showCheckBox: false,
}
},
created() {
const query = this.$route.query.member
if (typeof query !== 'undefined') {
this.isMember = true
const member = JSON.parse(query as string)
this.title = member.name
}
},
methods: {
touchStart(e: TouchEvent) {
this.startX = e.touches[0].clientX
},
touchEnd(e: TouchEvent) {
const end = e.changedTouches[0].clientX
if (end - this.startX > 40) {
console.log('左滑')
const { year: preYear, month: preMonth } = this.getPreMonth(this.year, this.month)
this.year = preYear
this.month = preMonth
}
if (this.startX - end > 40) {
const { year: nextYear, month: nextMonth } = this.getNextMonth(this.year, this.month)
this.year = nextYear
this.month = nextMonth
console.log('右滑')
}
this.daysInMonth = this.getDaysInMonth(this.year, this.month - 1)
},
getTime(year: number, month: number, day: number) {
return new Date(year, month, day).getTime()
clickTab(tab: {label: string, key: string}) {
this.currentKey = tab.key
this.checkedSchdules = []
},
showDot(day: number) {
const date = this.getTime(this.year, this.month, day)
const checkIfNotTripDate = date < this.tripDays[0] || date > this.tripDays[1]
return this.checkedDays.indexOf(date) > -1 && date !== this.getTime(this.year, this.month, this.day) && checkIfNotTripDate
},
getDateClass(day: Day) {
if (day.type === 'current') {
if (this.getTime(this.year, this.month, day.day) === this.getTime(this.year, this.month, this.day)) {
return 'rounded-full bg-color-primary text-white shadow-schedule-selected'
} else if (this.getTime(this.year, this.month, day.day) >= this.tripDays[0] && this.getTime(this.year, this.month, day.day) <= this.tripDays[1] ) {
return 'text-text-secondary border-b border-schedule-line'
} else {
return 'text-text-secondary'
}
} else {
return 'text-text-extreme-light'
}
},
selectDay(day: Day) {
this.day = day.day
switch (day.type) {
case 'pre':
const { year: preYear, month: preMonth } = this.getPreMonth(this.year, this.month)
this.year = preYear
this.month = preMonth
break
case 'next':
const { year: nextYear, month: nextMonth } = this.getNextMonth(this.year, this.month)
this.year = nextYear
this.month = nextMonth
onSelect(action: {name: string, action: string}) {
this.show = false
switch(action.action) {
case 'check':
this.$router.push('/schedule/team')
break
case 'manage':
this.showCheckBox = true
}
this.daysInMonth = this.getDaysInMonth(this.year, this.month - 1)
},
getNextMonth(year: number, month: number) {
let newYear = year
let newMonth = month
if (newMonth === 12) {
newMonth = 1
newYear++
} else {
newMonth++
}
return { year: newYear, month: newMonth }
},
getPreMonth(year: number, month: number) {
let newYear = year
let newMonth = month
if (newMonth === 1) {
newMonth = 12
newYear--
} else {
newMonth--
}
return { year: newYear, month: newMonth }
complete() {
this.checkedSchdules = []
this.showCheckBox = false
},
getDaysInMonth(year: number, month: number) {
const result: Array<{type: string, day: number}> = []
// 一年中每个月的天数
const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
// 闰二月
if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
daysInMonth[1] = 29
}
// 当月第一天日期 周几 0-6
const firstDay = new Date(year, month, 1).getDay()
// 获取当月一号前几天显示
for (let i = 0; i < firstDay; i++) {
result.push({
type: 'pre',
day: daysInMonth[month] - firstDay + 1 + i
})
}
// 当月日期天数
for (let i = 0; i < daysInMonth[month]; i++) {
result.push({
type: 'current',
day: i + 1
})
}
// 获取当月最后一天之后显示天数
for (let i = 0; i < 6 - new Date(year, month + 1, 0).getDay(); i++) {
result.push({
type: 'next',
day: i + 1
})
}
return result
clickSchedule(schedule: Schedule) {
this.$router.push(`/schedule/schedule-detail/${schedule.id}`)
}
}
})
......
<template>
<!-- 团队详情 -->
<main-page left-arrow @click-left="$router.go(-1)">
<template slot="right">
<app-icon
type="png"
class-name="w-6.5 h-6.5"
:path="require('@/assets/icons/search.png')"
/>
</template>
<div class="px-4 pt-14">
<!-- 团队架构详情 -->
<team-tree
isDetail
:tree-data="[currentTeam]"
:pre-team="parentTeam.name"
@click-child="clickItem"
/>
<!-- 通讯录 -->
<div class="pb-16">
<div class="text-text-secondary py-1">成员</div>
<team-contacts
:radio="showRadio"
:checked.sync="checkedMemberId"
:contacts="contacts"
@click-member="clickMember"
/>
</div>
<!-- 底部操作 -->
<!-- <div class="py-2 px-4 bg-common-bg w-screen fixed bottom-0 left-0 z-30">
<template v-if="showRadio">
<c-button round @click="$router.push('/team/team-management')">确定</c-button>
</template>
<template v-else>
<div class="grid grid-cols-3 gap-2.5">
<c-button round @click="$router.push('/team/add-member')">添加成员</c-button>
<c-button round @click="$router.push('/team/add-department')">添加部门</c-button>
<c-button round @click="$router.push('/team/department-management')">部门设置</c-button>
</div>
</template>
</div> -->
</div>
</main-page>
</template>
<script lang="ts">
import Vue from 'vue'
import { team, contacts } from '@/DTO'
import { Member } from '@/DTO'
export default Vue.extend({
name: 'TeamDetail',
components: {
'main-page': () => import('@/layout/main-page.vue'),
'app-icon': () => import('@/components/common/Icon.vue'),
'team-tree': () => import('@/views/team/components/team-tree.vue'),
'team-contacts': () => import('@/views/team/components/team-contacts.vue'),
'c-button': () => import('@/components/common/c-button.vue')
},
created() {
this.showRadio = this.$route.query.transfer === '1'
},
data() {
let flatTeams: Array<Member> = []
let currentTeam: Member = {
id: 0,
name: ''
}
return {
title: '导航',
team,
contacts,
parentTeam: {},
currentTeam,
flatTeams,
checkedMemberId: [],
showRadio: false
// newTeams: []
}
},
methods: {
getFlatTeams(arr: Array<Member>) {
let newArr: Array<Member> = []
for (let i=0; i<arr.length; i++) {
newArr.push(arr[i])
if (arr[i].children?.length) {
newArr = newArr.concat(this.getFlatTeams(arr[i].children as Array<Member>))
}
}
return newArr
},
clickItem(val: Member) {
this.$router.push(`/schedule/team/${val.id}`)
},
addDepartment() {
console.log('添加部门')
},
clickMember(member: Member) {
this.$router.push({
path: '/schedule/schedule-home',
query: {
member: JSON.stringify(member)
}
})
},
},
watch: {
$route: {
handler() {
const id = parseInt(this.$route.params.id)
this.flatTeams = this.getFlatTeams(this.team)
this.currentTeam = this.flatTeams.find(team => team.id === id) as Member
const parentId = this.currentTeam.parentId
this.parentTeam = this.flatTeams.find(team => team.id === parentId) as Member
},
immediate: true
}
}
})
</script>
<style lang="less">
</style>
<template>
<!-- 所有成员 -->
<div class="team-frame">
<main-page left-arrow @click-left="$router.go(-1)">
<template slot="right">
<app-icon
type="png"
class-name="w-6.5 h-6.5"
:path="require('@/assets/icons/search.png')"
/>
</template>
<div class="px-4 pt-14">
<!-- 团队架构详情 -->
<team-tree
:tree-data="team"
@click-child="clickItem"
/>
<!-- 通讯录 -->
<div class="pb-16">
<div class="text-text-secondary py-1">成员</div>
<team-contacts
:radio="showRadio"
:checked.sync="checkedMemberId"
:contacts="contacts"
@click-member="clickMember"
/>
</div>
<!-- 底部操作 -->
<!-- <div class="py-2 px-4 bg-common-bg w-screen fixed bottom-0 left-0 z-30">
<template v-if="showRadio">
<c-button round @click="$router.go(-1)">确定</c-button>
</template>
<template v-else>
<div class="grid grid-cols-3 gap-2.5">
<c-button round @click="$router.push('/team/add-member')">添加成员</c-button>
<c-button round @click="$router.push('/team/add-department')">添加部门</c-button>
<c-button round @click="$router.push('/team/department-management')">部门设置</c-button>
</div>
</template>
</div> -->
</div>
</main-page>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import { team, contacts } from '@/DTO'
import { Member } from '@/DTO'
export default Vue.extend({
name: 'TeamFrame',
components: {
'main-page': () => import('@/layout/main-page.vue'),
'app-icon': () => import('@/components/common/Icon.vue'),
'team-tree': () => import('@/views/team/components/team-tree.vue'),
'team-contacts': () => import('@/views/team/components/team-contacts.vue'),
'c-button': () => import('@/components/common/c-button.vue')
},
created() {
// console.log(Mock, 'mock')
this.showRadio = this.$route.query.transfer === '1'
},
data() {
return {
title: '导航',
team,
contacts,
checkedMemberId: [],
showRadio: false
}
},
methods: {
clickMember(member: Member) {
this.$router.push({
path: '/schedule/schedule-home',
query: {
member: JSON.stringify(member)
}
})
},
clickItem(val: Member) {
// console.log(val)
if (this.showRadio) {
this.$router.push({
path: `/schedule/team/${val.id}`,
query: {
transfer: '1'
}
})
return
}
this.$router.push(`/schedule/team/${val.id}`)
}
}
})
</script>
<style lang="less">
</style>
......@@ -174,7 +174,7 @@ export default Vue.extend({
this.handleCheck(member)
return
}
this.$router.push(`/team/team-member/${member.id}`)
this.$emit('click-member', member)
},
handleCheck(member: Member) {
let arr = Array.from(this.checked)
......
......@@ -23,6 +23,7 @@
:radio="showRadio"
:checked.sync="checkedMemberId"
:contacts="contacts"
@click-member="clickMember"
/>
</div>
<!-- 底部操作 -->
......@@ -93,7 +94,10 @@ export default Vue.extend({
},
addDepartment() {
console.log('添加部门')
}
},
clickMember(member: Member) {
this.$router.push(`/team/team-member/${member.id}`)
},
},
watch: {
$route: {
......
......@@ -22,6 +22,7 @@
:radio="showRadio"
:checked.sync="checkedMemberId"
:contacts="contacts"
@click-member="clickMember"
/>
</div>
<!-- 底部操作 -->
......@@ -74,6 +75,9 @@ export default Vue.extend({
// console.log('click left')
// this.$router.go(-1)
// },
clickMember(member: Member) {
this.$router.push(`/team/team-member/${member.id}`)
},
clickItem(val: Member) {
// console.log(val)
if (this.showRadio) {
......
......@@ -45,8 +45,18 @@ module.exports = {
'tag-red-lighter': '#FAEEEE',
'tag-purple': '#9F82E5',
'tag-purple-lighter': '#F1ECFD',
// 日程
'input-bg': '#F8F8FA',
// 日程下划线
'schedule-line': '#EBAE44'
'schedule-line': '#EBAE44',
'schedule-timeline': '#D3DFE6',
// 日程类型标签渐变
'meeting-l': '#5DC2BA',
'meeting-r': '#64AAE8',
'field-l': '#FABD60',
'field-r': '#9AD8E7',
'trip-l': '#F24E72',
'trip-r': '#C855B5'
},
spacing: {
4.5: '1.08rem',
......@@ -54,6 +64,7 @@ module.exports = {
10.5: '2.625rem',
13: '3.125rem',
15: '3.75rem',
18: '4.5rem',
21.5:'5.375rem',
22.5: '5.625rem',
38: '9.5rem',
......@@ -75,6 +86,9 @@ module.exports = {
bg: '0px 2px 24px 0px #D7E7EF',
'schedule-selected': '0px 4px 6px 0px rgba(36, 55, 78, 0.51)',
'join-team': '0px 0px 10px 0px rgba(36, 55, 78, 0.35)'
},
fontSize: {
xxs: ['0.625rem', { lineHeight: '1rem' }],
}
},
screens: {
......@@ -990,7 +1004,7 @@ module.exports = {
lineHeight: ['responsive'],
listStylePosition: ['responsive'],
listStyleType: ['responsive'],
margin: ['responsive'],
margin: ['responsive', 'first'],
maxHeight: ['responsive'],
maxWidth: ['responsive'],
minHeight: ['responsive'],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment