29 changed files with 1016 additions and 55 deletions
@ -0,0 +1,9 @@ |
|||||
|
<template> |
||||
|
<view class="w-full bg-gray-100 text-gray-200 text-center pt-4 pb-12">----------我也是有底线的----------</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default {}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,9 @@ |
|||||
|
<template> |
||||
|
<view>已测评</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default {}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,24 @@ |
|||||
|
<template> |
||||
|
<view class="flex flex-col"> |
||||
|
<view class="flex justify-between items-center"> |
||||
|
<text class="text-base">脑力测评</text> |
||||
|
<u-icon name="arrow-right"></u-icon> |
||||
|
</view> |
||||
|
<view class="text-sm text-gray-400 my-2"> |
||||
|
这套脑力测评工具是认知障碍诊疗专家在国际权威 认知测评量表的基础上,结合我国老年人生活背景 及多年的临床经验编写而成,每次测评包括35个 |
||||
|
问题,涵盖了各个方面的认知功能,您只需要跟随 屏幕提示回答这些问题,系统就会对您的认知水平 做一个全面评估,根据评估结果,系统将会为您量 |
||||
|
身定制一套认知训练课程。 这些问题有难有易,请您别紧张,因为老人的视力 不太好,我们建议您在平板电脑上或者在台式电脑 上操作. |
||||
|
</view> |
||||
|
<view class="flex flex-nowrap my-2"> |
||||
|
<u-button type="primary" size="mini" class="mx-0">开始测评</u-button> |
||||
|
<view class="flex-1"></view> |
||||
|
</view> |
||||
|
<text class="text-xs text-gray-300">注:每两个周可进行一次测评</text> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default {}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,127 @@ |
|||||
|
<template> |
||||
|
<!-- 时间间隔栏 --> |
||||
|
<!-- <Barrier /> --> |
||||
|
|
||||
|
<scroll-view |
||||
|
style="height: 100%" |
||||
|
:lower-threshold="100" |
||||
|
:scroll-y="true" |
||||
|
:upper-threshold="100" |
||||
|
: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> |
||||
|
// import Barrier from './component/Barrier.vue'; |
||||
|
import { mapState, mapMutations, mapGetters } from 'vuex'; |
||||
|
import { setPlaceholderTasks } from '@/utils/task'; |
||||
|
import TimeBox from './component/TimeBox.vue'; |
||||
|
|
||||
|
export default { |
||||
|
name: 'TimeLine', |
||||
|
components: { TimeBox }, |
||||
|
|
||||
|
data() { |
||||
|
return { top: 0 }; |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
...mapState('role', ['visibleRoles']), |
||||
|
...mapState('task', ['scrollTop', 'tasks', 'topEnd', 'bottomEnd', 'showSkeleton', 'timeNode', 'scrollToTaskId']), |
||||
|
...mapGetters('task', ['timeGranularity']), |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
...mapMutations('task', ['setScrollTop', 'setShrink', 'setUpTasks', 'setDownTasks', 'setScrollToTaskId']), |
||||
|
|
||||
|
// 滚动 |
||||
|
scroll(e) { |
||||
|
console.log('e: ', e); |
||||
|
this.top = e.detail.scrollTop; |
||||
|
this.setShrink(this.top > this.scrollTop); |
||||
|
this.setScrollTop(this.top); |
||||
|
}, |
||||
|
|
||||
|
// 滚动到顶部 |
||||
|
async handleScrollTop() { |
||||
|
if (!this.tasks || !this.tasks.length || this.showSkeleton) return; |
||||
|
const startTime = this.tasks[0].planStart - 0; |
||||
|
if (this.topEnd) { |
||||
|
// 没有数据时 自动加载数据 |
||||
|
console.warn('滚动到顶部没有数据时: '); |
||||
|
const addTasks = setPlaceholderTasks(startTime, true, this.timeGranularity); |
||||
|
this.setUpTasks(addTasks); |
||||
|
} else { |
||||
|
// 有数据时 |
||||
|
console.warn('滚动到顶部有数据时: '); |
||||
|
const detailId = this.tasks.findIndex(task => task.detailId); |
||||
|
const timeNode = this.tasks[detailId].planStart - 0; |
||||
|
const upQuery = { |
||||
|
timeNode, |
||||
|
queryType: 0, |
||||
|
queryNum: 6, |
||||
|
}; |
||||
|
await this.$emit('getTasks', upQuery); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 滚动到底部 |
||||
|
async handleScrollBottom() { |
||||
|
if (!this.tasks || !this.tasks.length || this.showSkeleton) return; |
||||
|
const { tasks, timeGranularity } = this; |
||||
|
const startTime = tasks[tasks.length - 1].planStart - 0; |
||||
|
if (this.bottomEnd) { |
||||
|
// 没有数据时 自动加载数据 |
||||
|
console.warn('滚动到底部没有数据时: '); |
||||
|
const addTasks = setPlaceholderTasks(startTime, false, this.timeGranularity); |
||||
|
this.setDownTasks(addTasks); |
||||
|
} else { |
||||
|
// 时间基准点=最后一个任务的开始时间+当前时间颗粒度 |
||||
|
console.warn('滚动到底部有数据时: '); |
||||
|
const arr = []; |
||||
|
this.tasks.forEach(task => { |
||||
|
if (task.detailId) { |
||||
|
arr.push(task); |
||||
|
} |
||||
|
}); |
||||
|
const nextQueryTime = +this.$t.time.add(+arr[arr.length - 1].planStart, 1, timeGranularity); |
||||
|
const downQuery = { |
||||
|
timeNode: nextQueryTime, |
||||
|
queryType: 1, |
||||
|
queryNum: 6, |
||||
|
}; |
||||
|
await this.$emit('getTasks', downQuery); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 设置自动滚动位置 |
||||
|
setScrollPosition() { |
||||
|
// 如果storage里有taskId 滚动到这个id的任务 |
||||
|
const taskId = this.$t.storage.getStorageSync('taskId'); |
||||
|
if (taskId) { |
||||
|
this.setScrollToTaskId(`a${taskId}`); |
||||
|
this.$t.storage.setStorageSync('taskId', ''); // 记录后即刻清除本地存储 |
||||
|
} else { |
||||
|
const item = this.tasks.find(task => task.detailId); |
||||
|
if (item) { |
||||
|
this.setScrollToTaskId(`a${item.id}`); |
||||
|
} else { |
||||
|
// 没有本地记录的taskId |
||||
|
// 找到当前时间基准线的任务id 记录 并滚动到当前时间基准线 |
||||
|
const task = this.tasks.find(item => this.$moment(+item.planStart).isSame(this.timeNode, this.timeGranularity)); |
||||
|
task && this.setScrollToTaskId(`a${task.id}`); // 有这个task 就记录他的id |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
@ -0,0 +1,42 @@ |
|||||
|
<!-- |
||||
|
* @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> |
||||
|
export default { |
||||
|
name: 'Barrier', |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
}; |
||||
|
</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,185 @@ |
|||||
|
<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="show"> |
||||
|
<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="maskShow" @click="closeMask"></view> |
||||
|
<!-- 新建任务弹窗 --> |
||||
|
<CreateTask |
||||
|
:startTime="startTime" |
||||
|
:endTime="endTime" |
||||
|
:task="task" |
||||
|
@showTime="showTime" |
||||
|
@closeMask="closeMask" |
||||
|
class="thirdPopup flex transition-transform" |
||||
|
v-if="createTaskShow" |
||||
|
/> |
||||
|
|
||||
|
<u-picker title="开始时间" mode="time" v-model="showStart" :params="params" @confirm="confirmStartTime"></u-picker> |
||||
|
<u-picker title="结束时间" mode="time" v-model="showEnd" :params="params" @confirm="confirmEndTime"></u-picker> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import CreateTask from '../../Title/components/CreateTask.vue'; |
||||
|
|
||||
|
export default { |
||||
|
components: { CreateTask }, |
||||
|
|
||||
|
props: { |
||||
|
task: { |
||||
|
type: Object, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
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, |
||||
|
}, |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
//操作 |
||||
|
operation() { |
||||
|
// this.$t.ui.showToast('操作'); |
||||
|
this.show = !this.show; |
||||
|
}, |
||||
|
|
||||
|
// 新建项目 |
||||
|
createTask() { |
||||
|
// 关闭 ... 弹窗 |
||||
|
this.show = false; |
||||
|
// 打开遮罩 |
||||
|
this.maskShow = true; |
||||
|
// 打开新建项目弹窗 |
||||
|
this.createTaskShow = true; |
||||
|
}, |
||||
|
|
||||
|
//点击遮罩,关闭弹窗 |
||||
|
closeMask() { |
||||
|
// 关闭遮罩 |
||||
|
this.maskShow = false; |
||||
|
// 关闭分享项目弹窗 |
||||
|
this.secondShow = false; |
||||
|
// 关闭新建项目弹窗 |
||||
|
this.createTaskShow = false; |
||||
|
}, |
||||
|
|
||||
|
showTime() { |
||||
|
this.showStart = !this.showStart; |
||||
|
}, |
||||
|
|
||||
|
// 选择开始时间 |
||||
|
confirmStartTime(e) { |
||||
|
this.startTime = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}:${e.second}`; |
||||
|
this.showEnd = true; |
||||
|
}, |
||||
|
|
||||
|
// 选择结束时间 |
||||
|
confirmEndTime(e) { |
||||
|
this.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,142 @@ |
|||||
|
<template> |
||||
|
<view class="column"> |
||||
|
<!-- 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" 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="styleType || 0" |
||||
|
v-for="plugin in row" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</u-card> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!-- 局部弹框操作栏 --> |
||||
|
<Tips /> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { mapState, mapMutations, mapGetters, mapActions } from 'vuex'; |
||||
|
import Skeleton from '@/components/Skeleton/Skeleton'; |
||||
|
import TimeStatus from './TimeStatus.vue'; |
||||
|
import TaskTools from './TaskTools.vue'; |
||||
|
|
||||
|
export default { |
||||
|
name: 'TimeBox', |
||||
|
components: { TimeStatus, Skeleton, TaskTools }, |
||||
|
|
||||
|
data() { |
||||
|
return { currentComponent: '', styleType: 0 }; |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
...mapState('role', ['roleId']), |
||||
|
...mapState('task', ['timeUnit', 'tasks', 'taskLoading', 'showSkeleton']), |
||||
|
...mapGetters('task', ['startTimeFormat']), |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
...mapActions('task', ['getGlobal']), |
||||
|
...mapMutations('task', ['setTipsContent', 'setTipsContent']), |
||||
|
|
||||
|
// 设置任务面板高度 |
||||
|
setHeight(panel) { |
||||
|
if (panel && panel.height) { |
||||
|
return panel.height + 'px'; |
||||
|
} else { |
||||
|
return 'auto'; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 点击了定期任务的面板 更新可变的日常任务 |
||||
|
* @param {number} planStart 任务计划开始时间 |
||||
|
* @param {string} taskId 任务id |
||||
|
*/ |
||||
|
onClickTask(planStart, taskId) { |
||||
|
const param = { roleId: this.roleId, timeNode: planStart, timeUnit: this.timeUnit }; |
||||
|
this.getGlobal(param); |
||||
|
this.$t.storage.setStorageSync('taskId', taskId); |
||||
|
this.$t.storage.setStorageSync('roleId', this.roleId); |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</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,231 @@ |
|||||
|
<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>{{ 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>{{ durationText }}</template> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { mapState, mapMutations } from 'vuex'; |
||||
|
|
||||
|
export default { |
||||
|
name: 'TimeStatus', |
||||
|
props: { task: { type: Object, default: () => {} } }, |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
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, |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
...mapState('task', ['tip']), |
||||
|
status() { |
||||
|
return this.task ? this.task.process : 0; |
||||
|
}, |
||||
|
taskName() { |
||||
|
return this.task ? this.task.name : ''; |
||||
|
}, |
||||
|
taskId() { |
||||
|
return this.task ? this.task.id : ''; |
||||
|
}, |
||||
|
// 图标文本颜色 |
||||
|
// 任务状态 0未开始 1进行中 2暂停中 3已完成 |
||||
|
orderStyle() { |
||||
|
let color = '#9CA3AF'; |
||||
|
let icon = 'play-right-fill'; |
||||
|
let persent = 100; |
||||
|
switch (this.status) { |
||||
|
case 1: // 进行中 |
||||
|
color = '#60A5FA'; |
||||
|
icon = ''; |
||||
|
if (+this.computeCyclePersent() > 100) { |
||||
|
persent = 96; |
||||
|
} else { |
||||
|
persent = this.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 }; |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
mounted() { |
||||
|
// TODO: 计算在不在窗口内显示 |
||||
|
const time = this.computeDurationText(); |
||||
|
this.updateDurationText(time); |
||||
|
}, |
||||
|
|
||||
|
destroyed() { |
||||
|
if (this.timer) { |
||||
|
clearInterval(this.timer); |
||||
|
this.timer = null; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
...mapMutations('task', ['setTip']), |
||||
|
|
||||
|
/** |
||||
|
* 点击了图标 修改任务状态 |
||||
|
* @param {object} event |
||||
|
*/ |
||||
|
changeStatus(process, event) { |
||||
|
if (process === 4) { |
||||
|
this.addTask(); |
||||
|
return; |
||||
|
} |
||||
|
// return false; |
||||
|
const { status, taskId, taskName, tip } = this; |
||||
|
tip.status = status; |
||||
|
tip.taskId = taskId; |
||||
|
tip.left = event.target.x; |
||||
|
tip.top = event.target.y; |
||||
|
tip.show = true; |
||||
|
tip.text = this.genetateTips(status, taskName); |
||||
|
|
||||
|
this.setTip(tip); |
||||
|
}, |
||||
|
|
||||
|
// 新建任务 |
||||
|
addTask() { |
||||
|
this.$t.ui.showToast('新建任务'); |
||||
|
}, |
||||
|
|
||||
|
// 计算圆环的弧度百分比 |
||||
|
computeCyclePersent() { |
||||
|
if (!this.task || !this.task.realStart || !this.task.planDuration) return 100; |
||||
|
const { realStart, planDuration } = this.task; |
||||
|
return (((Date.now() - +realStart) * 100) / +planDuration).toFixed(2); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 计算tip的标题内容 |
||||
|
*/ |
||||
|
genetateTips(status, content) { |
||||
|
switch (status) { |
||||
|
case 0: |
||||
|
return `确认开始任务"${content}"吗?`; |
||||
|
case 1: |
||||
|
return `请选择要执行的操作`; |
||||
|
case 2: |
||||
|
return `请选择要执行的操作`; |
||||
|
case 3: |
||||
|
return `是否要重新开始此任务`; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 计算进行中状态剩余时间 |
||||
|
// 预计结束时间 = realStart(实际开始) + planDuration(计划时长) |
||||
|
// 剩余时间 = 预计结束时间 - 当前时间 |
||||
|
// 剩余时间 = realStart + planDuration - Date.now() |
||||
|
computeDurationText() { |
||||
|
const { realStart, planDuration } = this.task; |
||||
|
const leftTime = +realStart + +planDuration - Date.now(); // 剩余时间 |
||||
|
const { num, time } = this.$t.time.computeDurationText(leftTime); |
||||
|
if (num <= 0) { |
||||
|
clearInterval(this.timer); |
||||
|
this.timer = null; |
||||
|
} |
||||
|
this.durationText = num; |
||||
|
return time; |
||||
|
}, |
||||
|
|
||||
|
updateDurationText(time) { |
||||
|
if (this.timer) { |
||||
|
clearInterval(this.timer); |
||||
|
this.timer = null; |
||||
|
} |
||||
|
if (!time) return; |
||||
|
setInterval(() => { |
||||
|
this.computeDurationText(); |
||||
|
}, 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; |
||||
|
} |
||||
|
</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 |
||||
|
--> |
||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1,13 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<Info /> |
||||
|
<EndLine /> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Info from 'components/ConfigInfo/components/Info'; |
||||
|
export default { components: { Info } }; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,9 @@ |
|||||
|
<template> |
||||
|
<view>训练归属</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default {}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,9 @@ |
|||||
|
<template> |
||||
|
<view>工具箱</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default {}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,9 @@ |
|||||
|
<template> |
||||
|
<view>扫码</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default {}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
Loading…
Reference in new issue