9 changed files with 856 additions and 34 deletions
@ -0,0 +1,122 @@ |
|||
<template> |
|||
<!-- 时间间隔栏 --> |
|||
<!-- <Barrier /> --> |
|||
|
|||
<scroll-view |
|||
:lower-threshold="300" |
|||
scroll-y="true" |
|||
:upper-threshold="300" |
|||
:scroll-into-view="scrollToTaskId" |
|||
@scroll="scroll" |
|||
@scrolltolower="handleScrollBottom" |
|||
@scrolltoupper="handleScrollTop" |
|||
id="scroll" |
|||
> |
|||
<!-- 时间轴 --> |
|||
<!-- <u-divider bg-color="#f3f4f6" class="pt-5" fontSize="14px" v-if="topEnd">到顶啦</u-divider> --> |
|||
|
|||
<!-- <TimeBox /> --> |
|||
|
|||
<!-- <u-divider bg-color="#f3f4f6" class="pb-5" fontSize="14px" v-if="bottomEnd">到底啦</u-divider> --> |
|||
</scroll-view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { reactive, computed, defineEmits } from 'vue'; |
|||
import { useStore } from 'vuex'; |
|||
// import Barrier from './component/Barrier.vue'; |
|||
import dayjs from 'dayjs'; |
|||
import TimeBox from './component/TimeBox.vue'; |
|||
|
|||
const store = useStore(); |
|||
// const visibleRoles = computed(() => store.state.role.visibleRoles); |
|||
// const scrollTop = computed(() => store.state.task.scrollTop); |
|||
const tasks = computed(() => store.state.task.tasks); |
|||
const topEnd = computed(() => store.state.task.topEnd); |
|||
const bottomEnd = computed(() => store.state.task.bottomEnd); |
|||
const showSkeleton = computed(() => store.state.task.showSkeleton); |
|||
const timeNode = computed(() => store.state.task.timeNode); |
|||
const scrollToTaskId = computed(() => store.state.task.scrollToTaskId); |
|||
const timeGranularity = computed(() => store.getters['task/timeGranularity']); |
|||
const emit = defineEmits(['getTasks']); |
|||
|
|||
const data = reactive({ top: 0 }); |
|||
|
|||
// 滚动 |
|||
function scroll(e) { |
|||
data.top = e.detail.scrollTop; |
|||
store.commit('task/setShrink', data.top > data.scrollTop); |
|||
store.commit('task/setScrollTop', data.top); |
|||
} |
|||
|
|||
// 滚动到顶部 |
|||
async function handleScrollTop() { |
|||
if (!tasks.value || !tasks.value.length || showSkeleton.value) return; |
|||
const startTime = tasks.value[0].planStart - 0; |
|||
if (topEnd.value) { |
|||
// 没有数据时 自动加载数据 |
|||
console.warn('滚动到顶部没有数据时: '); |
|||
const addTasks = uni.$task.setPlaceholderTasks(startTime, true, timeGranularity.value); |
|||
store.commit('task/setUpTasks', addTasks); |
|||
} else { |
|||
// 有数据时 |
|||
console.warn('滚动到顶部有数据时: '); |
|||
const detailId = tasks.value.findIndex(task => task.detailId); |
|||
const timeNodeValue = tasks.value[detailId].planStart - 0; |
|||
const upQuery = { |
|||
timeNode: timeNodeValue, |
|||
queryType: 0, |
|||
queryNum: 6, |
|||
}; |
|||
await emit('getTasks', upQuery); |
|||
} |
|||
} |
|||
|
|||
// 滚动到底部 |
|||
async function handleScrollBottom() { |
|||
if (!tasks.value || !tasks.value.length || showSkeleton.value) return; |
|||
const startTime = tasks.value[tasks.value.length - 1].planStart - 0; |
|||
if (bottomEnd.value) { |
|||
// 没有数据时 自动加载数据 |
|||
console.warn('滚动到底部没有数据时: '); |
|||
const addTasks = uni.$task.setPlaceholderTasks(startTime, false, timeGranularity.value); |
|||
store.commit('task/setDownTasks', addTasks); |
|||
} else { |
|||
// 时间基准点=最后一个任务的开始时间+当前时间颗粒度 |
|||
console.warn('滚动到底部有数据时: '); |
|||
const arr = []; |
|||
tasks.value.forEach(task => { |
|||
if (task.detailId) { |
|||
arr.push(task); |
|||
} |
|||
}); |
|||
const nextQueryTime = +uni.$time.add(+arr[arr.length - 1].planStart, 1, timeGranularity.value); |
|||
const downQuery = { |
|||
timeNode: nextQueryTime, |
|||
queryType: 1, |
|||
queryNum: 6, |
|||
}; |
|||
await emit('getTasks', downQuery); |
|||
} |
|||
} |
|||
|
|||
// 设置自动滚动位置 |
|||
function setScrollPosition() { |
|||
// 如果storage里有taskId 滚动到这个id的任务 |
|||
const taskId = uni.$storage.getStorageSync('taskId'); |
|||
if (taskId) { |
|||
store.commit('task/setScrollToTaskId', `a${taskId}`); |
|||
uni.$storage.setStorageSync('taskId', ''); // 记录后即刻清除本地存储 |
|||
} else { |
|||
const item = tasks.value.find(task => task.detailId); |
|||
if (item) { |
|||
store.commit('task/setScrollToTaskId', `a${item.id}`); |
|||
} else { |
|||
// 没有本地记录的taskId |
|||
// 找到当前时间基准线的任务id 记录 并滚动到当前时间基准线 |
|||
const task = tasks.value.find(item => dayjs(+item.planStart).isSame(timeNode.value, timeGranularity.value)); |
|||
task && store.commit('task/setScrollToTaskId', `a${task.id}`); // 有这个task 就记录他的id |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,38 @@ |
|||
<!-- |
|||
* @Author: aBin |
|||
* @email: binbin0314@126.com |
|||
* @Date: 2021-07-19 14:22:54 |
|||
* @LastEditors: aBin |
|||
* @LastEditTime: 2021-07-20 11:46:04 |
|||
--> |
|||
<template> |
|||
<view class> |
|||
<!-- :class="{ active: cycleTasks.time.start === filter.startTime }" --> |
|||
<view class="cycle-time active"> |
|||
<!-- {{ $util.formatStartTimeToCycleTime(filter.time, cycleTasks.time.start) }} --> |
|||
2021年30周 |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
|
|||
</script> |
|||
<style scoped lang="scss"> |
|||
.cycle-time { |
|||
padding: 8rpx 16rpx; |
|||
margin-bottom: 16rpx; |
|||
background: #fafafc; |
|||
color: $uni-text-color; |
|||
font-size: 28rpx; |
|||
position: sticky; |
|||
top: -1px; |
|||
left: 0; |
|||
z-index: 99; |
|||
|
|||
&.active { |
|||
background: $uni-color-primary; |
|||
color: $uni-text-color-inverse; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,177 @@ |
|||
<template> |
|||
<view> |
|||
<view class="flex justify-between" style="min-width: 90px; position: relative"> |
|||
<u-icon custom-prefix="custom-icon" name="C-bxl-redux" size="17px"></u-icon> |
|||
<u-icon custom-prefix="custom-icon" name="attachment" size="21px"></u-icon> |
|||
<!-- <u-icon custom-prefix="custom-icon" name="moneycollect" size="20px"></u-icon> --> |
|||
<u-icon name="xuanxiang" custom-prefix="custom-icon" size="21px" @click="operation"></u-icon> |
|||
|
|||
<!-- 右上角 ... 弹窗 --> |
|||
<view class="popup border shadow-md" v-if="data.show"> |
|||
<!-- <view class="flex justify-center pb-3 border-b-1"> |
|||
<span>添加插件</span> |
|||
</view> --> |
|||
<view class="flex justify-center pb-3 border-b-1"> |
|||
<span @click="createTask">新建任务</span> |
|||
</view> |
|||
<view class="flex pt-3 justify-center"> |
|||
<span>克隆任务</span> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 遮罩 --> |
|||
<view class="mask" v-if="data.maskShow" @click="closeMask"></view> |
|||
<!-- 新建任务弹窗 --> |
|||
<CreateTask |
|||
:startTime="data.startTime" |
|||
:endTime="data.endTime" |
|||
:task="task" |
|||
:source="'regular'" |
|||
@showTime="showTime" |
|||
@closeMask="closeMask" |
|||
class="thirdPopup flex transition-transform" |
|||
v-if="data.createTaskShow" |
|||
/> |
|||
|
|||
<u-picker title="开始时间" mode="time" v-model="data.showStart" :params="data.params" @confirm="confirmStartTime"></u-picker> |
|||
<u-picker title="结束时间" mode="time" v-model="data.showEnd" :params="data.params" @confirm="confirmEndTime"></u-picker> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { defineProps, reactive } from 'vue'; |
|||
import CreateTask from '@/components/Title/components/CreateTask.vue'; |
|||
|
|||
defineProps({ task: { type: Object, default: () => {} } }); |
|||
|
|||
const data = reactive({ |
|||
show: false, // 右上角 ... 显示 |
|||
createTaskShow: false, // 新建项目显示 |
|||
secondShow: false, // 分享项目显示 |
|||
maskShow: false, // 遮罩显示 |
|||
showStart: false, |
|||
showEnd: false, |
|||
startTime: '', // 新建任务的开始时间 |
|||
endTime: '', // 新建任务的截止时间 |
|||
params: { |
|||
year: true, |
|||
month: true, |
|||
day: true, |
|||
hour: true, |
|||
minute: true, |
|||
second: true, |
|||
}, |
|||
}); |
|||
|
|||
// 操作 |
|||
function operation() { |
|||
// this.$t.ui.showToast('操作'); |
|||
data.show = !data.show; |
|||
} |
|||
|
|||
// 新建项目 |
|||
function createTask() { |
|||
// 关闭 ... 弹窗 |
|||
data.show = false; |
|||
// 打开遮罩 |
|||
data.maskShow = true; |
|||
// 打开新建项目弹窗 |
|||
data.createTaskShow = true; |
|||
} |
|||
|
|||
// 点击遮罩,关闭弹窗 |
|||
function closeMask() { |
|||
// 关闭遮罩 |
|||
data.maskShow = false; |
|||
// 关闭分享项目弹窗 |
|||
data.secondShow = false; |
|||
// 关闭新建项目弹窗 |
|||
data.createTaskShow = false; |
|||
} |
|||
|
|||
function showTime() { |
|||
data.showStart = !data.showStart; |
|||
} |
|||
|
|||
// 选择开始时间 |
|||
function confirmStartTime(e) { |
|||
data.startTime = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}:${e.second}`; |
|||
data.showEnd = true; |
|||
} |
|||
|
|||
// 选择结束时间 |
|||
function confirmEndTime(e) { |
|||
data.endTime = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}:${e.second}`; |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.mask { |
|||
width: 100%; |
|||
height: 100vh; |
|||
z-index: 21; |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
background: rgba(0, 0, 0, 0.3); |
|||
} |
|||
|
|||
.thirdPopup { |
|||
background: #ffffff; |
|||
position: fixed; |
|||
left: 50%; |
|||
top: 50%; |
|||
transform: translate(-50%, -50%); |
|||
z-index: 33; |
|||
border-radius: 5px; |
|||
width: 90%; |
|||
} |
|||
|
|||
.popup { |
|||
width: 110px; |
|||
background: #fff; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 35px; |
|||
z-index: 99; |
|||
padding: 15px 0; |
|||
color: black; |
|||
animation: opacity 1s ease-in; |
|||
} |
|||
|
|||
@keyframes opacity { |
|||
0% { |
|||
opacity: 0; |
|||
} |
|||
50% { |
|||
opacity: 0.8; |
|||
} |
|||
100% { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
::v-deep .u-slot-content { |
|||
min-width: 0; |
|||
} |
|||
::v-deep .u-dropdown__content { |
|||
min-height: 120px !important; |
|||
height: auto !important; |
|||
overflow-y: auto; |
|||
background: #fff !important; |
|||
transition: none !important; |
|||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); |
|||
} |
|||
::v-deep .u-dropdown__menu__item .u-flex { |
|||
justify-content: space-between; |
|||
width: 100%; |
|||
height: 100%; |
|||
flex-wrap: nowrap; |
|||
border: 1px solid #afbed1; |
|||
padding: 0 8px; |
|||
} |
|||
::v-deep .u-dropdown__content__mask { |
|||
display: none; |
|||
} |
|||
</style> |
@ -0,0 +1,131 @@ |
|||
<template> |
|||
<view class="column" v-finger:pinch="pinchHandler"> |
|||
<!-- v-if="tasks && tasks.length" --> |
|||
<view> |
|||
<view :key="task.id" v-for="task in tasks" :id="`a${task.id}`"> |
|||
<view class="flex"> |
|||
<!-- <TimeStatus :task="task" /> --> |
|||
<view class="flex items-center justify-between flex-1 ml-2 task-column"> |
|||
<view v-if="task.process !== 4">{{ $moment(+task.planStart).format(startTimeFormat) }}</view> |
|||
<view v-else>{{ $moment(+task.planStart).format('D日') }}</view> |
|||
|
|||
<!-- 任务功能菜单 --> |
|||
<!-- <TaskTools v-if="task.process !== 4" :task="task" /> --> |
|||
</view> |
|||
</view> |
|||
<view class="border-l-2 border-gray-300 plugin"> |
|||
<view class="h-3" v-if="task.process === 4"></view> |
|||
<view class="ml-3 overflow-hidden shadow-lg task-box"> |
|||
<u-card :show-foot="false" :show-head="false" :style="{ height: setHeight(task.panel) }" class="h-16" margin="0" v-if="showSkeleton"> |
|||
<view slot="body"> |
|||
<view> |
|||
<!-- <skeleton :banner="false" :loading="true" :row="4" animate class="mt-2 u-line-2 skeleton"></skeleton> --> |
|||
</view> |
|||
</view> |
|||
</u-card> |
|||
|
|||
<u-card |
|||
@click="onClickTask(task.planStart - 0, task.id)" |
|||
:show-foot="false" |
|||
:show-head="false" |
|||
:style="{ height: setHeight(task.panel) }" |
|||
class="h-16" |
|||
margin="0" |
|||
v-if="tasks && tasks.length && task.process !== 4 && !showSkeleton" |
|||
> |
|||
<!-- 任务面板插件 --> |
|||
<view slot="body"> |
|||
<view class="p-0 u-col-between"> |
|||
<view :key="pIndex" v-for="(row, pIndex) in task.plugins"> |
|||
<view class="grid gap-2 grid-cols-1" v-if="row.length"> |
|||
<!-- <Plugin |
|||
:class="[`row-span-${plugin.row}`, `col-span-${plugin.col}`]" |
|||
:task="task" |
|||
:key="plugin.pluginTaskId" |
|||
:plugin-task-id="plugin.pluginTaskId" |
|||
:plugin-id="plugin.pluginId" |
|||
:param="plugin.param" |
|||
:style-type="data.styleType || 0" |
|||
v-for="plugin in row" |
|||
/> --> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</u-card> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- 局部弹框操作栏 --> |
|||
<!-- <Tips /> --> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { useStore } from 'vuex'; |
|||
import { computed, reactive } from 'vue'; |
|||
import TimeStatus from './TimeStatus.vue'; |
|||
import TaskTools from './TaskTools.vue'; |
|||
|
|||
// const data = reactive({ |
|||
// currentComponent: '', |
|||
// styleType: 0, |
|||
// }); |
|||
|
|||
const store = useStore(); |
|||
const roleId = computed(() => store.state.role.roleId); |
|||
const timeUnit = computed(() => store.state.task.timeUnit); |
|||
const tasks = computed(() => store.state.task.tasks); |
|||
const showSkeleton = computed(() => store.state.task.showSkeleton); |
|||
const startTimeFormat = computed(() => store.getters['task/startTimeFormat']); |
|||
|
|||
// 设置任务面板高度 |
|||
function setHeight(panel) { |
|||
if (panel && panel.height) { |
|||
return `${panel.height}px`; |
|||
} |
|||
return 'auto'; |
|||
} |
|||
|
|||
/** |
|||
* 点击了定期任务的面板 更新可变的日常任务 |
|||
* @param {number} planStart 任务计划开始时间 |
|||
* @param {string} taskId 任务id |
|||
*/ |
|||
function onClickTask(planStart, taskId) { |
|||
const param = { roleId: roleId.value, timeNode: planStart, timeUnit: timeUnit.value }; |
|||
store.dispatch('task/getGlobal', param); |
|||
uni.$storage.setStorageSync('taskId', taskId); |
|||
uni.$storage.setStorageSync('roleId', roleId.value); |
|||
} |
|||
|
|||
function pinchHandler(evt) { |
|||
// evt.scale代表两个手指缩放的比例 |
|||
console.log(`缩放:${evt.zoom}`); |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.task-box { |
|||
border-radius: 24rpx; |
|||
} |
|||
.column { |
|||
padding: 24px 14px; |
|||
} |
|||
.task-column { |
|||
height: 33px; |
|||
} |
|||
.plugin { |
|||
margin-top: 8px; |
|||
margin-bottom: 8px; |
|||
margin-left: 15px; |
|||
} |
|||
::v-deep .ml-2 { |
|||
margin-left: 16px; |
|||
} |
|||
|
|||
::v-deep .ml-3 { |
|||
margin-left: 20px; |
|||
} |
|||
</style> |
@ -0,0 +1,316 @@ |
|||
<template> |
|||
<view class="u-font-14"> |
|||
<view |
|||
class="flex items-center justify-center rounded-full icon-column" |
|||
:style="{ color: orderStyle.color }" |
|||
@click="changeStatus(task.process, $event)" |
|||
> |
|||
<!-- 1进行中 2暂停中 3已完成 --> |
|||
<u-circle-progress |
|||
:percent="orderStyle.persent - 0" |
|||
:active-color="orderStyle.color" |
|||
bg-color="rgba(255,255,255,0)" |
|||
border-width="4" |
|||
:width="task.process !== 4 ? 66 : 50" |
|||
v-if="task.process === 1 || task.process === 2 || task.process === 3" |
|||
> |
|||
<view class="u-progress-content"> |
|||
<view class="u-progress-dot"></view> |
|||
<view class="u-progress-info"> |
|||
<u-icon :name="orderStyle.icon" v-if="orderStyle.icon" size="15px"></u-icon> |
|||
<template v-else>{{ data.durationText }}</template> |
|||
</view> |
|||
</view> |
|||
</u-circle-progress> |
|||
<!-- 0未开始 4添加任务 --> |
|||
<view class="flex items-center justify-center rounded-full progress-box" v-else :class="task.process === 4 ? 'progress-box-4' : ''"> |
|||
<view class="u-progress-content"> |
|||
<view class="u-progress-dot"></view> |
|||
<view class="u-progress-info"> |
|||
<span v-if="orderStyle.icon"> |
|||
<u-icon :name="orderStyle.icon" v-if="task.process !== 4" size="15px"></u-icon> |
|||
<u-icon :name="orderStyle.icon" v-else size="15px"></u-icon> |
|||
</span> |
|||
<template v-else>{{ data.durationText }}</template> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 遮罩 --> |
|||
<view class="mask" v-if="data.maskShow" @click="closeMask"></view> |
|||
<!-- 新建任务弹窗 --> |
|||
<CreateTask |
|||
:startTime="data.startTime" |
|||
:endTime="data.endTime" |
|||
:task="task" |
|||
:source="'regular'" |
|||
@showTime="showTime" |
|||
@closeMask="closeMask" |
|||
class="thirdPopup flex transition-transform" |
|||
v-if="data.createTaskShow" |
|||
/> |
|||
|
|||
<u-picker title="开始时间" mode="time" v-model="data.showStart" :params="data.params" @confirm="confirmStartTime"></u-picker> |
|||
<u-picker title="结束时间" mode="time" v-model="data.showEnd" :params="data.params" @confirm="confirmEndTime"></u-picker> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { reactive, onMounted, defineProps, computed } from 'vue'; |
|||
import { useStore } from 'vuex'; |
|||
import CreateTask from '../../Title/components/CreateTask.vue'; |
|||
|
|||
const props = defineProps({ task: { type: Object, default: () => {} } }); |
|||
|
|||
const data = reactive({ |
|||
time: '', |
|||
start: [{ text: '确认开始任务', color: 'blue' }], |
|||
pause: [{ text: '继续' }, { text: '重新开始任务', color: 'blue' }, { text: '结束' }], |
|||
proceed: [{ text: '暂停' }, { text: '重新开始任务', color: 'blue' }, { text: '结束' }], |
|||
again: [{ text: '重新开始任务', color: 'blue' }], |
|||
timer: null, |
|||
durationText: 0, |
|||
maskShow: false, // 遮罩显示 |
|||
createTaskShow: false, // 新建项目显示 |
|||
startTime: '', // 新建任务的开始时间 |
|||
endTime: '', // 新建任务的截止时间 |
|||
showStart: false, |
|||
showEnd: false, |
|||
params: { |
|||
year: true, |
|||
month: true, |
|||
day: true, |
|||
hour: true, |
|||
minute: true, |
|||
second: true, |
|||
}, |
|||
}); |
|||
|
|||
const store = useStore(); |
|||
const tip = computed(() => store.state.task.tip); |
|||
const status = computed(() => [props.task ? props.task.process : 0]); |
|||
const taskName = computed(() => [props.task ? props.task.name : '']); |
|||
const taskId = computed(() => [props.task ? props.task.id : '']); |
|||
|
|||
// 计算圆环的弧度百分比 |
|||
function computeCyclePersent() { |
|||
if (!props.task || !props.task.realStart || !props.task.planDuration) return 100; |
|||
const { realStart, planDuration } = props.task; |
|||
return (((Date.now() - +realStart) * 100) / +planDuration).toFixed(2); |
|||
} |
|||
|
|||
const orderStyle = computed(() => { |
|||
// 图标文本颜色 |
|||
// 任务状态 0未开始 1进行中 2暂停中 3已完成 |
|||
let color = '#9CA3AF'; |
|||
let icon = 'play-right-fill'; |
|||
let persent = 100; |
|||
switch (status.value) { |
|||
case 1: // 进行中 |
|||
color = '#60A5FA'; |
|||
icon = ''; |
|||
if (+computeCyclePersent() > 100) { |
|||
persent = 96; |
|||
} else { |
|||
persent = computeCyclePersent(); |
|||
} |
|||
break; |
|||
case 2: // 暂停中 |
|||
color = '#F87171'; |
|||
icon = 'pause'; |
|||
persent = 50; // TODO: 暂时这样 暂停状态没有计算剩余多少时间 |
|||
break; |
|||
case 3: // 已结束 |
|||
color = '#34D399'; |
|||
icon = 'checkmark'; |
|||
persent = 100; |
|||
break; |
|||
case 4: // 添加任务 |
|||
color = '#60A5FA'; |
|||
icon = 'plus'; |
|||
persent = 100; |
|||
break; |
|||
default: |
|||
// 未开始 |
|||
color = '#9CA3AF'; |
|||
icon = 'play-right'; |
|||
persent = 100; |
|||
break; |
|||
} |
|||
return { color, icon, persent }; |
|||
}); |
|||
|
|||
// unMounted(() => { |
|||
// if (data.timer) { |
|||
// clearInterval(data.timer); |
|||
// data.timer = null; |
|||
// } |
|||
// }); |
|||
|
|||
/** |
|||
* 计算tip的标题内容 |
|||
*/ |
|||
function genetateTips(type, content) { |
|||
if (type === 0) { |
|||
return `确认开始任务"${content}"吗?`; |
|||
} |
|||
if (type === 3) { |
|||
return '是否要重新开始此任务'; |
|||
} |
|||
return '请选择要执行的操作'; |
|||
} |
|||
|
|||
// 新建任务 |
|||
function addTask() { |
|||
// uni.$ui.showToast('新建任务'); |
|||
// 打开遮罩 |
|||
data.maskShow = true; |
|||
// 打开新建项目弹窗 |
|||
data.createTaskShow = true; |
|||
} |
|||
|
|||
/** |
|||
* 点击了图标 修改任务状态 |
|||
* @param {object} event |
|||
*/ |
|||
function changeStatus(process, event) { |
|||
if (process === 4) { |
|||
addTask(); |
|||
return; |
|||
} |
|||
// return false; |
|||
tip.status = status; |
|||
tip.taskId = taskId; |
|||
tip.left = event.target.x; |
|||
tip.top = event.target.y; |
|||
tip.show = true; |
|||
tip.text = genetateTips(status, taskName); |
|||
store.commit('task/setTip', tip); |
|||
} |
|||
|
|||
// 点击遮罩,关闭弹窗 |
|||
function closeMask() { |
|||
// 关闭遮罩 |
|||
data.maskShow = false; |
|||
// 关闭新建项目弹窗 |
|||
data.createTaskShow = false; |
|||
} |
|||
|
|||
function showTime(type) { |
|||
if (type === 1) { |
|||
data.showStart = !data.showStart; |
|||
} else { |
|||
data.showEnd = !data.showEnd; |
|||
} |
|||
} |
|||
|
|||
// 选择开始时间 |
|||
function confirmStartTime(e) { |
|||
data.startTime = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}:${e.second}`; |
|||
data.showEnd = true; |
|||
} |
|||
|
|||
// 选择结束时间 |
|||
function confirmEndTime(e) { |
|||
data.endTime = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}:${e.second}`; |
|||
} |
|||
|
|||
// 计算进行中状态剩余时间 |
|||
// 预计结束时间 = realStart(实际开始) + planDuration(计划时长) |
|||
// 剩余时间 = 预计结束时间 - 当前时间 |
|||
// 剩余时间 = realStart + planDuration - Date.now() |
|||
function computeDurationText() { |
|||
const { realStart, planDuration } = props.task; |
|||
const leftTime = +realStart + +planDuration - Date.now(); // 剩余时间 |
|||
const { num, time } = uni.$time.computeDurationText(leftTime); |
|||
if (num <= 0) { |
|||
clearInterval(data.timer); |
|||
data.timer = null; |
|||
} |
|||
data.durationText = num; |
|||
return time; |
|||
} |
|||
|
|||
function updateDurationText(time) { |
|||
if (data.timer) { |
|||
clearInterval(data.timer); |
|||
data.timer = null; |
|||
} |
|||
if (!time) return; |
|||
setInterval(() => { |
|||
computeDurationText(); |
|||
}, time); |
|||
} |
|||
|
|||
onMounted(() => { |
|||
// TODO: 计算在不在窗口内显示 |
|||
const time = computeDurationText(); |
|||
updateDurationText(time); |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.icon-column { |
|||
height: 33px; |
|||
width: 33px; |
|||
} |
|||
.one { |
|||
height: 33px; |
|||
width: 33px; |
|||
} |
|||
|
|||
.progress-box { |
|||
background: rgba(255, 255, 255, 0); |
|||
width: 33px; |
|||
height: 33px; |
|||
border: 2px solid #9ca3af; |
|||
} |
|||
|
|||
.progress-box-4 { |
|||
width: 25px; |
|||
height: 25px; |
|||
border: 2px solid #60a5fa; |
|||
} |
|||
|
|||
.mask { |
|||
width: 100%; |
|||
height: 100vh; |
|||
z-index: 21; |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
background: rgba(0, 0, 0, 0.3); |
|||
} |
|||
|
|||
.thirdPopup { |
|||
background: #ffffff; |
|||
position: fixed; |
|||
left: 50%; |
|||
top: 50%; |
|||
transform: translate(-50%, -50%); |
|||
z-index: 33; |
|||
border-radius: 5px; |
|||
width: 90%; |
|||
} |
|||
|
|||
::v-deep .u-dropdown__content { |
|||
min-height: 120px !important; |
|||
height: auto !important; |
|||
overflow-y: auto; |
|||
background: #fff !important; |
|||
transition: none !important; |
|||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); |
|||
} |
|||
::v-deep .u-dropdown__menu__item .u-flex { |
|||
justify-content: space-between; |
|||
width: 100%; |
|||
height: 100%; |
|||
flex-wrap: nowrap; |
|||
border: 1px solid #afbed1; |
|||
padding: 0 8px; |
|||
} |
|||
::v-deep .u-dropdown__content__mask { |
|||
display: none; |
|||
} |
|||
</style> |
@ -0,0 +1,7 @@ |
|||
<!-- |
|||
* @Author: aBin |
|||
* @email: binbin0314@126.com |
|||
* @Date: 2021-07-19 15:40:02 |
|||
* @LastEditors: aBin |
|||
* @LastEditTime: 2021-07-19 15:40:03 |
|||
--> |
Loading…
Reference in new issue