import { computed, nextTick, watch } from 'vue'; import { useStore } from 'vuex'; import { flatten } from 'lodash'; import dayjs from 'dayjs'; export default function useGetTasks() { const store = useStore(); const tasks = computed(() => store.state.task.tasks); const basicTasks = computed(() => store.state.task.basicTasks); const upBasicTasks = computed(() => store.state.task.upBasicTasks); const nextPage = computed(() => store.state.task.nextPage); // 下一页 const upNextPage = computed(() => store.state.task.upNextPage); // 下一页 // const lastPage = computed(() => store.state.task.lastPage); // 最后一页 const roleId = computed(() => store.state.role.roleId); const timeNode = computed(() => store.state.task.timeNode); const timeUnit = computed(() => store.state.task.timeUnit); const visibleRoles = computed(() => store.state.role.visibleRoles); const allTasks = computed(() => store.state.task.allTasks); const roleIndex = computed(() => store.state.role.roleIndex); const projectId = computed(() => store.getters['project/projectId']); const timeGranularity = computed(() => store.getters['task/timeGranularity']); // 初始化 定期任务 async function initPlanTasks() { await getTasks({}); // 获取初始数据 } /** * 根据时间基准点和角色查找定期任务 * @param {object} query * @param {string} query.roleId 角色id * @param {string} query.timeNode 时间基准点 默认当前 * @param {string} query.timeUnit 时间颗粒度 默认天 * @param {string} query.queryNum 查找颗粒度数量 默认3个 * @param {number} query.queryType 0向上查找 1向下查找(默认) 下查包含自己,上查不包含 */ function getTasks(query) { store.commit('task/setShowSkeleton', false); const params = { roleId: roleId.value, timeUnit: query.timeUnit || timeUnit.value, queryType: query.queryType === 0 ? 0 : 1, pageNum: query.pageNum || 1, pageSize: query.pageSize || uni.$taskConfig.pageCount } uni.$catchReq.getTaskByNum(params, (err, data) => { store.commit('task/setShowSkeleton', false); if (err) { // TODO: 提示错误 console.error('err: ', err); } else { store.commit('task/setShowScrollTo', true); if (params.queryType === 0) { // 将接口返回的数据存储到store let lists = [...upBasicTasks.value, ...data.list]; store.commit('task/setUpBasicTask', lists); store.commit('task/setUpNextPage', data.nextPage); // 下一页 } else { let lists = [...basicTasks.value, ...data.list]; store.commit('task/setBasicTask', lists); store.commit('task/setNextPage', data.nextPage); // 下一页 } // 刻度模式数据处理 renderTask(params); } }); } // 刻度模式数据处理 function renderTask(params) { params.queryType === 0 ? setPrevPlaceholderTasks() : setNextPlaceholderTasks(); tasksData(params); } /** * 刻度模式数据处理 * 大于等于15天,真实数据的时间跨度 * 或大于等于15条,真实数据的数量 * 不用重新加载数据 * @param {Object} params */ function tasksData(params) { let oldTasks = tasks.value; let realTasks = params.queryType === 0 ? upBasicTasks.value : basicTasks.value; // 下一页的值 let next = params.queryType === 0 ? upNextPage.value : nextPage.value; // 真实数据是否>=15条 || 是否>=15天 let term = tremFilter(params); if (term || next === 0) { // 过滤真实数据中在tasks时间段中的数据,并将最后的数据存储到tasksArr数组中 let tasksArr = [], taskLen = 0, lastIndex = 0; oldTasks.forEach((task, index) => { const oldArr = oldTasks.filter(item => dayjs(+item.planStart).isSame(+task.planStart, timeGranularity.value)); const arr = realTasks.filter(item => dayjs(+item.planStart).isSame(+task.planStart, timeGranularity.value)); if (arr && arr.length) { if (task.detailId) { tasksArr = [...arr]; lastIndex = index; } else { taskLen += arr.length; // 在时间刻度内的数据量 oldTasks.splice(index, 1, [...arr]); // 这里加入的数据是array类型的, [{},{},[],[],{}] } } }) // 数据与上一页最后一个数据时间节点相同 if (lastIndex) { taskLen += tasksArr.length; oldTasks.splice(lastIndex, 0, [...tasksArr]); } oldTasks = flatten(oldTasks); // 1维拍平 if (taskLen === params.pageSize) { // 如果真实任务所有数据都在tasks时间段中,则将所有任务显示,并且从最后一个真实任务的时间截止,存储到tasks中 let len = 0; oldTasks.forEach((item, index) => { if (item.id === realTasks[realTasks.length - 1].id) { len = index; } }) oldTasks = oldTasks.slice(0, len + 1); params.queryType === 0 ? store.commit('task/setUpBasicTask', []) : store.commit('task/setBasicTask', []); } else { // 只有一部分真实数据展示,展示tasks时间段加时间段内的真实数据 params.queryType === 0 ? store.commit('task/setUpBasicTask', realTasks.slice(taskLen)) : store.commit('task/setBasicTask', realTasks.slice(taskLen)); } store.commit('task/clearTasks'); params.queryType === 0 ? store.commit('task/setUpTasks', oldTasks) : store.commit('task/setDownTasks', oldTasks); } else { if (next > 0) { getTasks({pageNum: params.pageNum, queryType: params.queryType}); } } } /** * 数据筛选条件 * 大于等于15天,真实数据的时间跨度,且大于等于15条,真实数据的数量,不用重新加载数据 */ function tremFilter(params) { let time1 = 0, time2 = 0; let realTasks = basicTasks.value; if (realTasks.length > 0) { // 真实数据第一条数据加上15天后的时间 time1 = dayjs(+realTasks[0].planStart).add(params.pageSize, timeGranularity.value); // 真实数据最后一条数据的时间 time2 = dayjs(realTasks[realTasks.length - 1].planStart, timeGranularity.value); } let result1 = false, result2 = false; // 判断真实任务的时间跨度是否在15天之内 if (time1 > 0 && time2 > 0) { // 两个时间是否相等 result1 = dayjs(time1).isSame(time2, timeGranularity.value); // time1是否大于time2 result2 = dayjs(time1).isAfter(time2, timeGranularity.value); } let term1 = realTasks.length >= params.pageSize; // 大于等于15条,真实数据的数量 // 大于等于15天,真实数据的时间跨度 let term2 = result1 || result2; return term1 || term2; } /** * 用拿到的新数据 替换 时间刻度/旧数据 * 先对比 新旧数据的 始末时间 补齐刻度 * 再遍历对比 用任务替换刻度 * @param {array} data 服务端返回的新数据 上边已经处理过空值 * @param {number} type 0 -> 向上 1->向下 */ // function replacePrevData(data, type) { // const obj = { tasks: tasks.value, data, timeGranularity: timeGranularity.value }; // let oldTasks = fillPlaceholderTask(obj); // 已经上下补齐时间刻度的 // console.log('oldTasks', oldTasks) // // 遍历对比 用任务替换刻度 // // TODO: tasks越来越多 遍历越来越多 需要优化 // oldTasks.forEach((taskItem, index) => { // const arr = data.filter(dataItem => dayjs(+dataItem.planStart).isSame(+taskItem.planStart, timeGranularity.value)); // if (arr && arr.length) { // oldTasks.splice(index, 1, [...arr]); // 这里加入的数据是array类型的, [{},{},[],[],{}] // } // }); // oldTasks = flatten(oldTasks); // 1维拍平 // store.commit('task/clearTasks'); // type === 0 ? store.commit('task/setUpTasks', oldTasks) : store.commit('task/setDownTasks', oldTasks); // } /** * 超出旧数据上、下限 补齐时间刻度到新数据的起始时间颗粒度 */ // function fillPlaceholderTask(obj) { // const { prev, next } = uni.$task.computeFillPlaceholderTaskCount(obj); // if (prev) { // const newTasks = uni.$task.setPlaceholderTasks(+obj.tasks[0].planStart, true, obj.timeGranularity, prev); // store.commit('task/setUpTasks', newTasks); // } // if (next) { // const newTasks = uni.$task.setPlaceholderTasks(+obj.tasks[obj.tasks.length - 1].planStart, false, obj.timeGranularity, next); // store.commit('task/setDownTasks', newTasks); // } // return tasks.value; // } // 设置时间轴向上的空数据 function setPrevPlaceholderTasks() { store.commit('task/setTopEnd', true); let startTime = ''; if (!tasks.value || !tasks.value.length) { startTime = Date.now(); // 没有任务就应该是时间基准点 } else { startTime = tasks.value[0].planStart - 0; // 有任务就是第一个任务的计划开始时间 } const placeholderTasks = uni.$task.setPlaceholderTasks(startTime, true, timeGranularity.value); store.commit('task/setUpTasks', placeholderTasks); } // 设置时间轴向下的空数据 function setNextPlaceholderTasks() { // store.commit('task/setBottomEnd', true); let startTime = ''; if (!tasks.value || !tasks.value.length) { startTime = Date.now(); } else { startTime = dayjs(+tasks.value[tasks.value.length - 1].planStart).add(1, timeGranularity.value); } const initData = uni.$task.setPlaceholderTasks(startTime, false, timeGranularity.value); store.commit('task/setDownTasks', initData); } /** * 当日常任务发生变化时 * 将新获取到的日常任务放在allTasks里 */ watch(tasks, newValue => { // console.log('newValue----->tasks: ', tasks.value); // 添加到allTasks里 const index = visibleRoles.value.findIndex(role => role.id === roleId.value); const arr = [...allTasks.value]; arr[index].task = [...newValue]; store.commit('task/setAllTasks', arr); }); return { initPlanTasks, getTasks, renderTask }; }