Browse Source

feat: 时间轴新策略

test2
xuesinan 4 years ago
parent
commit
e25218be75
  1. 3
      CHANGELOG.md
  2. 10
      components/Plugin/Plugin.vue
  3. 20
      components/TimeLine/TimeLine.vue
  4. 263
      hooks/project/useGetTasks - 副本.js
  5. 263
      hooks/project/useGetTasks.js
  6. 2
      hooks/project/useInit.js
  7. 14
      pages/project/project.vue
  8. 2
      plugins/p-deliver/p-deliver.vue
  9. 2
      plugins/p-finance/p-finance.vue
  10. 325
      store/task/mutations - 副本.js
  11. 77
      store/task/mutations.js
  12. 36
      store/task/state - 副本.js
  13. 13
      store/task/state.js

3
CHANGELOG.md

@ -1,4 +1,4 @@
# 1.0.0 (2022-02-16) # 1.0.0 (2022-02-17)
### 🌟 新功能 ### 🌟 新功能
范围|描述|commitId 范围|描述|commitId
@ -31,6 +31,7 @@
- | 获取手机唯一码 | [3f60cf8](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3f60cf8) - | 获取手机唯一码 | [3f60cf8](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3f60cf8)
- | 将时间轴改成swiper滑动 | [12384f9](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/12384f9) - | 将时间轴改成swiper滑动 | [12384f9](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/12384f9)
- | 解决时间轴日常任务不显示问题 | [c532a93](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/c532a93) - | 解决时间轴日常任务不显示问题 | [c532a93](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/c532a93)
- | 刻度模式时间轴 | [a9bc53a](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/a9bc53a)
- | 日历页首页 | [561c8e6](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/561c8e6) - | 日历页首页 | [561c8e6](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/561c8e6)
- | 日历页添加 | [1b46a91](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/1b46a91) - | 日历页添加 | [1b46a91](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/1b46a91)
- | 设置项目域名 | [1a835f1](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/1a835f1) - | 设置项目域名 | [1a835f1](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/1a835f1)

10
components/Plugin/Plugin.vue

@ -28,7 +28,7 @@
<p-domain-source-manage v-else-if="pluginId === '20'" class="p-2" /> <p-domain-source-manage v-else-if="pluginId === '20'" class="p-2" />
<p-project-version-management v-else-if="pluginId === '21'" class="p-2" /> <p-project-version-management v-else-if="pluginId === '21'" class="p-2" />
<Render <!-- <Render
v-else v-else
:task="task" :task="task"
:pluginId="pluginId" :pluginId="pluginId"
@ -36,7 +36,7 @@
:pluginTaskId="pluginTaskId" :pluginTaskId="pluginTaskId"
:businessPluginId="businessPluginId" :businessPluginId="businessPluginId"
:param="param" :param="param"
/> /> -->
<!-- #ifdef H5 --> <!-- #ifdef H5 -->
<!-- #endif --> <!-- #endif -->
</view> </view>
@ -70,9 +70,9 @@ const isMine = computed(() => store.getters['role/isMine']);
// return target.component; // return target.component;
// }); // });
if (props.pluginId === '5') { // if (props.pluginId === '5') {
store.dispatch('role/getAllMembers', { projectId: projectId.value }); // store.dispatch('role/getAllMembers', { projectId: projectId.value });
} // }
// storage // storage
async function setStorage() { async function setStorage() {

20
components/TimeLine/TimeLine.vue

@ -13,19 +13,13 @@
@scrolltoupper="handleScrollTop" @scrolltoupper="handleScrollTop"
id="scroll" id="scroll"
> >
<!-- 时间轴 -->
<!-- <u-divider bg-color="#f3f4f6" class="pt-5" fontSize="14px" v-if="topEnd">到顶啦</u-divider> -->
<TimeBox :tasks="tasks" /> <TimeBox :tasks="tasks" />
<!-- <u-divider bg-color="#f3f4f6" class="pb-5" fontSize="14px" v-if="bottomEnd">到底啦</u-divider> -->
</scroll-view> </scroll-view>
</template> </template>
<script setup> <script setup>
import { reactive, computed } from 'vue'; import { reactive, computed } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
// import Barrier from './component/Barrier.vue';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import TimeBox from './component/TimeBox.vue'; import TimeBox from './component/TimeBox.vue';
import useGetTasks from '@/hooks/project/useGetTasks'; import useGetTasks from '@/hooks/project/useGetTasks';
@ -39,18 +33,16 @@ const props = defineProps({
const store = useStore(); const store = useStore();
const getTasksHook = useGetTasks(); const getTasksHook = useGetTasks();
// 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 topEnd = computed(() => store.state.task.topEnd);
const bottomEnd = computed(() => store.state.task.bottomEnd); const bottomEnd = computed(() => store.state.task.bottomEnd);
const showSkeleton = computed(() => store.state.task.showSkeleton); const showSkeleton = computed(() => store.state.task.showSkeleton);
const timeNode = computed(() => store.state.task.timeNode); const timeNode = computed(() => store.state.task.timeNode);
const timeUnit = computed(() => store.state.task.timeUnit);
const scrollToTaskId = computed(() => store.state.task.scrollToTaskId); const scrollToTaskId = computed(() => store.state.task.scrollToTaskId);
const timeGranularity = computed(() => store.getters['task/timeGranularity']); const timeGranularity = computed(() => store.getters['task/timeGranularity']);
// const showStatus = computed(() => store.state.task.showStatus); // 120 2 const downNextPage = computed(() => store.state.task.downNextPage); //
const nextPage = computed(() => store.state.task.nextPage); //
const upNextPage = computed(() => store.state.task.upNextPage); // const upNextPage = computed(() => store.state.task.upNextPage); //
const timeLineType = computed(() => store.state.task.timeLineType); //
const emit = defineEmits(['getTasks']); const emit = defineEmits(['getTasks']);
const data = reactive({ top: 0 }); const data = reactive({ top: 0 });
@ -69,7 +61,7 @@ async function handleScrollTop() {
store.commit('task/updateTasks', props.tasks) store.commit('task/updateTasks', props.tasks)
console.warn('滚动到顶部: '); console.warn('滚动到顶部: ');
let params = { pageNum: upNextPage.value, queryType: 0 }; let params = { pageNum: upNextPage.value, queryType: 0 };
getTasksHook.renderTask(params); getTasksHook.dataRender(params);
} }
// //
@ -79,7 +71,7 @@ async function handleScrollBottom() {
store.commit('task/updateTasks', props.tasks); store.commit('task/updateTasks', props.tasks);
console.warn('滚动到底部: '); console.warn('滚动到底部: ');
let params = { pageNum: nextPage.value, queryType: 1 }; let params = { pageNum: downNextPage.value, queryType: 1 };
getTasksHook.renderTask(params); getTasksHook.dataRender(params);
} }
</script> </script>

263
hooks/project/useGetTasks - 副本.js

@ -0,0 +1,263 @@
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
};
}

263
hooks/project/useGetTasks.js

@ -5,11 +5,12 @@ import dayjs from 'dayjs';
export default function useGetTasks() { export default function useGetTasks() {
const store = useStore(); const store = useStore();
const tasks = computed(() => store.state.task.tasks); const tasks = computed(() => store.state.task.tasks);
const basicTasks = computed(() => store.state.task.basicTasks); const timeLineType = computed(() => store.state.task.timeLineType); // 时间轴模式
const upBasicTasks = computed(() => store.state.task.upBasicTasks); const realTasks = computed(() => store.state.task.realTasks); // 真实任务
const nextPage = computed(() => store.state.task.nextPage); // 下一页 const downNextPage = computed(() => store.state.task.downNextPage); // 下一页
const upNextPage = computed(() => store.state.task.upNextPage); // 下一页 const upNextPage = computed(() => store.state.task.upNextPage); // 下一页
// const lastPage = computed(() => store.state.task.lastPage); // 最后一页 const currUpTimeNode = computed(() => store.state.task.currUpTimeNode); // 当前查询的时间
const currDownTimeNode = computed(() => store.state.task.currDownTimeNode); // 当前查询的时间
const roleId = computed(() => store.state.role.roleId); const roleId = computed(() => store.state.role.roleId);
const timeNode = computed(() => store.state.task.timeNode); const timeNode = computed(() => store.state.task.timeNode);
const timeUnit = computed(() => store.state.task.timeUnit); const timeUnit = computed(() => store.state.task.timeUnit);
@ -32,11 +33,10 @@ export default function useGetTasks() {
function generateGetTaskParam(query) { function generateGetTaskParam(query) {
return { return {
roleId: roleId.value, roleId: roleId.value,
timeNode: query.timeNode || timeNode.value,
timeUnit: query.timeUnit || timeUnit.value, timeUnit: query.timeUnit || timeUnit.value,
queryNum: query.queryNum || 3, queryType: query.queryType === 0 ? 0 : 1,
queryType: query.queryType, pageNum: query.pageNum || 1,
projectId: projectId.value, pageSize: query.pageSize || uni.$taskConfig.pageCount
}; };
} }
@ -51,15 +51,8 @@ export default function useGetTasks() {
*/ */
function getTasks(query) { function getTasks(query) {
store.commit('task/setShowSkeleton', false); store.commit('task/setShowSkeleton', false);
// const params = generateGetTaskParam(query);
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
}
const params = generateGetTaskParam(query);
uni.$catchReq.getTaskByNum(params, (err, data) => { uni.$catchReq.getTaskByNum(params, (err, data) => {
store.commit('task/setShowSkeleton', false); store.commit('task/setShowSkeleton', false);
if (err) { if (err) {
@ -68,27 +61,70 @@ export default function useGetTasks() {
} else { } else {
store.commit('task/setShowScrollTo', true); store.commit('task/setShowScrollTo', true);
params.queryType === 0 ? store.commit('task/setUpRealTasks', data.list) : store.commit('task/setDownRealTasks', data.list);
params.queryType === 0 ? store.commit('task/setUpNextPage', data.nextPage) : store.commit('task/setDownNextPage', data.nextPage); // 下一页
// 数据处理
dataRender(params);
}
});
}
function dataRender(params) {
timeLineType.value === 1 ? renderScaleTask(params) : renderConTask(params);
}
async function renderConTask(params) {
let nextPage = params.queryType === 0 ? upNextPage.value : downNextPage.value; // 下一页的值
let showTasks = tasks.value;
let centerData = await showTaskId(params, showTasks, realTasks.value) || [];
if (centerData.length < 15 && nextPage > 0) {
getTasks({pageNum: nextPage, queryType: params.queryType});
} else {
if (params.queryType === 0) { if (params.queryType === 0) {
// 将接口返回的数据存储到store showTasks = [...centerData, ...showTasks];
let lists = [...upBasicTasks.value, ...data.list];
store.commit('task/setUpBasicTask', lists);
store.commit('task/setUpNextPage', data.nextPage); // 下一页
} else { } else {
let lists = [...basicTasks.value, ...data.list]; showTasks = [...showTasks, ...centerData];
store.commit('task/setBasicTask', lists); }
store.commit('task/setNextPage', data.nextPage); // 下一页
} }
// 刻度模式数据处理 if (showTasks.length < 15 && nextPage === 0 && params.queryType === 1) {
renderTask(params); getTasks({pageNum: 1, queryType: 0});
} }
});
store.commit('task/clearTasks');
params.queryType === 0 ? store.commit('task/setUpTasks', showTasks) : store.commit('task/setDownTasks', showTasks);
} }
// 刻度模式数据处理 // 刻度模式数据处理
function renderTask(params) { async function renderScaleTask(params) {
params.queryType === 0 ? setPrevPlaceholderTasks() : setNextPlaceholderTasks(); params.queryType === 0 ? setPrevPlaceholderTasks() : setNextPlaceholderTasks();
tasksData(params); let centerData = await showTaskId(params, tasks.value, realTasks.value) || [];
tasksData(params, centerData, realTasks.value);
}
// 已显示的任务第一个id和最后一个id
function showTaskId(params, showTasks, realTasks) {
const firstDetailIndex = showTasks.findIndex(task => task.detailId);
const firstId = firstDetailIndex === -1 ? 0 : showTasks[firstDetailIndex].id;
let lastDetailIndex = -1;
showTasks.forEach((item, index) => {
if (item.detailId) {
lastDetailIndex = index;
}
})
const lastId = lastDetailIndex === -1 ? 0 : showTasks[lastDetailIndex].id;
let centerData = params.queryType === 0 ? [] : realTasks.slice(0, params.pageSize);
realTasks.forEach((item, index) => {
if (params.queryType === 1 && item.id === lastId) {
centerData = realTasks.slice(index + 1, index + 1 + params.pageSize) || [];
} else if (params.queryType === 0 && item.id === firstId) {
centerData = realTasks.slice(index - params.pageSize, index) || [];
}
})
return centerData;
} }
/** /**
@ -98,138 +134,89 @@ export default function useGetTasks() {
* 不用重新加载数据 * 不用重新加载数据
* @param {Object} params * @param {Object} params
*/ */
function tasksData(params) { function tasksData(params, centerData, realTasks) {
let oldTasks = tasks.value; let param = generateGetTaskParam(params);
let realTasks = params.queryType === 0 ? upBasicTasks.value : basicTasks.value; let showTasks = tasks.value; // 显示的数据
// 下一页的值 let nextPage = param.queryType === 0 ? upNextPage.value : downNextPage.value; // 下一页的值
let next = params.queryType === 0 ? upNextPage.value : nextPage.value;
// 真实数据是否>=15条 || 是否>=15天 // 判断条件
let term = tremFilter(params); let isAccordTerm1 = false, isAccordTerm2 = false;
if (centerData.length > 0) {
// 1.数据数量>=15条
isAccordTerm1 = centerData.length >= param.pageSize;
if (term || next === 0) { // 2.数据最后一条数据时间>=当前查询的时间
// 过滤真实数据中在tasks时间段中的数据,并将最后的数据存储到tasksArr数组中 if (param.queryType === 0) {
let tasksArr = [], taskLen = 0, lastIndex = 0; let firstData = dayjs(centerData[0].planStart).add(param.pageSize, timeGranularity.value);
oldTasks.forEach((task, index) => { isAccordTerm2 = dayjs(+firstData).isBefore(+currUpTimeNode.value, timeGranularity.value) || dayjs(+firstData).isSame(+currUpTimeNode.value, timeGranularity.value);
const oldArr = oldTasks.filter(item => dayjs(+item.planStart).isSame(+task.planStart, timeGranularity.value)); } else {
const arr = realTasks.filter(item => dayjs(+item.planStart).isSame(+task.planStart, timeGranularity.value)); let lastData = dayjs(centerData[centerData.length - 1].planStart).subtract(param.pageSize, timeGranularity.value);
isAccordTerm2 = dayjs(+lastData).isAfter(+currDownTimeNode.value, timeGranularity.value) || dayjs(+lastData).isSame(+currDownTimeNode.value, timeGranularity.value);
}
}
// 3.下一页===0
// 不需要添加新数据
if (!isAccordTerm1 && !isAccordTerm2 && nextPage > 0) {
getTasks({pageNum: nextPage, queryType: param.queryType});
} else {
let tasksArr = [], isReplace = false, firstIndex = -1, selctedIndex = -1, replaceTime = 0;
showTasks.forEach((task, index) => {
const arr = centerData.filter(item => dayjs(+item.planStart).isSame(+task.planStart, timeGranularity.value));
if (arr && arr.length) { if (arr && arr.length) {
if (task.detailId) { if (task.detailId) {
// 新数据与旧数据时间有重叠
if (param.queryType === 1) {
selctedIndex = index;
tasksArr = [...arr]; tasksArr = [...arr];
lastIndex = index;
} else { } else {
taskLen += arr.length; // 在时间刻度内的数据量 firstIndex = showTasks.findIndex(data => dayjs(+data.planStart).isSame(+task.planStart, timeGranularity.value));
oldTasks.splice(index, 1, [...arr]); // 这里加入的数据是array类型的, [{},{},[],[],{}]
} }
} else {
showTasks.splice(index, 1, [...arr]);
} }
})
// 数据与上一页最后一个数据时间节点相同
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); if (selctedIndex) {
params.queryType === 0 ? store.commit('task/setUpBasicTask', []) : store.commit('task/setBasicTask', []); showTasks.splice(selctedIndex + 1, 0, [...tasksArr])
} else {
// 只有一部分真实数据展示,展示tasks时间段加时间段内的真实数据
params.queryType === 0 ? store.commit('task/setUpBasicTask', realTasks.slice(taskLen)) : store.commit('task/setBasicTask', realTasks.slice(taskLen));
} }
store.commit('task/clearTasks'); if (firstIndex) {
params.queryType === 0 ? store.commit('task/setUpTasks', oldTasks) : store.commit('task/setDownTasks', oldTasks); showTasks.splice(firstIndex, 0, [...tasksArr])
} else {
if (next > 0) {
getTasks({pageNum: params.pageNum, queryType: params.queryType});
} }
showTasks.forEach((task, index) => {
const arr = centerData.filter(item => dayjs(+item.planStart).isSame(+task.planStart, timeGranularity.value));
if (arr && arr.length) {
if (!task.detailId) { // 新数据与旧数据时间有重叠
showTasks.splice(index, 1, [...arr]); // 这里加入的数据是array类型的, [{},{},[],[],{}]
} }
} }
})
/** showTasks = flatten(showTasks); // 1维拍平
* 数据筛选条件
* 大于等于15天真实数据的时间跨度且大于等于15条真实数据的数量不用重新加载数据
*/
function tremFilter(params) {
let time1 = 0, time2 = 0;
let realTasks = basicTasks.value;
if (realTasks.length > 0) { if (isAccordTerm1 && !isAccordTerm2) {
// 真实数据第一条数据加上15天后的时间 let len = 0;
time1 = dayjs(+realTasks[0].planStart).add(params.pageSize, timeGranularity.value); let data = param.queryType === 0 ? centerData[0] : centerData[centerData.length - 1];
// 真实数据最后一条数据的时间 showTasks.forEach((item, index) => {
time2 = dayjs(realTasks[realTasks.length - 1].planStart, timeGranularity.value); if (item.id === data.id) {
len = index;
} }
})
let result1 = false, result2 = false; showTasks = param.queryType === 0 ? showTasks.slice(len) : showTasks.slice(0, len + 1);
// 判断真实任务的时间跨度是否在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条,真实数据的数量 if (showTasks.length > 80) {
// 大于等于15天,真实数据的时间跨度 showTasks = param.queryType === 0 ? showTasks.slice(0, 80) : showTasks.slice(showTasks.length - 80);
let term2 = result1 || result2; }
return term1 || term2;
} }
/** store.commit('task/clearTasks');
* 用拿到的新数据 替换 时间刻度/旧数据 param.queryType === 0 ? store.commit('task/setUpTasks', showTasks) : store.commit('task/setDownTasks', showTasks);
* 先对比 新旧数据的 始末时间 补齐刻度 }
* 再遍历对比 用任务替换刻度
* @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() { function setPrevPlaceholderTasks() {
@ -241,6 +228,7 @@ export default function useGetTasks() {
startTime = tasks.value[0].planStart - 0; // 有任务就是第一个任务的计划开始时间 startTime = tasks.value[0].planStart - 0; // 有任务就是第一个任务的计划开始时间
} }
const placeholderTasks = uni.$task.setPlaceholderTasks(startTime, true, timeGranularity.value); const placeholderTasks = uni.$task.setPlaceholderTasks(startTime, true, timeGranularity.value);
store.commit('task/setCurrUpTimeNode', startTime);
store.commit('task/setUpTasks', placeholderTasks); store.commit('task/setUpTasks', placeholderTasks);
} }
@ -251,9 +239,10 @@ export default function useGetTasks() {
if (!tasks.value || !tasks.value.length) { if (!tasks.value || !tasks.value.length) {
startTime = Date.now(); startTime = Date.now();
} else { } else {
startTime = dayjs(+tasks.value[tasks.value.length - 1].planStart).add(1, timeGranularity.value); startTime = dayjs(+tasks.value[tasks.value.length - 1].planStart).add(1, timeGranularity.value).valueOf();
} }
const initData = uni.$task.setPlaceholderTasks(startTime, false, timeGranularity.value); const initData = uni.$task.setPlaceholderTasks(startTime, false, timeGranularity.value);
store.commit('task/setCurrDownTimeNode', startTime);
store.commit('task/setDownTasks', initData); store.commit('task/setDownTasks', initData);
} }
@ -273,6 +262,6 @@ export default function useGetTasks() {
return { return {
initPlanTasks, initPlanTasks,
getTasks, getTasks,
renderTask dataRender
}; };
} }

2
hooks/project/useInit.js

@ -94,7 +94,7 @@ export default function useInit() {
// 根据项目id获取角色列表 // 根据项目id获取角色列表
getRoles(params); getRoles(params);
// 根据项目id获取成员列表 // 根据项目id获取成员列表
store.dispatch('role/getAllMembers', { projectId: options.p }); // store.dispatch('role/getAllMembers', { projectId: options.p });
} }
} }

14
pages/project/project.vue

@ -27,6 +27,8 @@
<!-- TODO: DEBUG: --> <!-- TODO: DEBUG: -->
<!-- <u-button @click="$store.commit('setTheme', 'theme-test')">测试切换主题</u-button> --> <!-- <u-button @click="$store.commit('setTheme', 'theme-test')">测试切换主题</u-button> -->
</view> </view>
<u-button style="position: fixed; bottom: 100px;" @click="changeModal">{{timeLineType === 1 ? '切换到任务模式' : '切换到时间轴模式'}}</u-button>
</theme> </theme>
</template> </template>
@ -54,6 +56,7 @@ const allTasks = computed(() => store.state.task.allTasks); // 所有任务
const globals = computed(() => store.getters['task/globals']); // + const globals = computed(() => store.getters['task/globals']); // +
const timeGranularity = computed(() => store.getters['task/timeGranularity']); // dayjs add const timeGranularity = computed(() => store.getters['task/timeGranularity']); // dayjs add
const height = ref(null); // const height = ref(null); //
const timeLineType = computed(() => store.state.task.timeLineType); //
onMounted(() => { onMounted(() => {
const system = uni.getSystemInfoSync(); const system = uni.getSystemInfoSync();
@ -217,6 +220,17 @@ function setScrollPosition() {
} }
} }
} }
function changeModal() {
store.commit('task/clearTasks'); //
store.commit('task/clearRealTasks'); //
store.commit('task/setUpNextPage', 1);
store.commit('task/setDownNextPage', 1);
store.commit('task/setTimeLineType', timeLineType.value === 1 ? 2 : 1);
let params = { pageNum: 1 };
getTasksHook.getTasks(params);
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

2
plugins/p-deliver/p-deliver.vue

@ -41,5 +41,5 @@ async function getDeliverData() {
} }
} }
getDeliverData(); // getDeliverData();
</script> </script>

2
plugins/p-finance/p-finance.vue

@ -52,7 +52,7 @@ async function getFinanceByTaskData() {
} }
} }
getFinanceByTaskData(); // getFinanceByTaskData();
// //
function openFinance() { function openFinance() {

325
store/task/mutations - 副本.js

@ -0,0 +1,325 @@
const mutations = {
/**
* 设置真实任务数据
* @param {Object} state
* @param {Object} data
*/
setBasicTask(state, data) {
state.basicTasks = [...data];
},
/**
* 设置向上真实任务数据
* @param {Object} state
* @param {Object} data
*/
setUpBasicTask(state, data) {
state.upBasicTasks = [...data];
},
/**
* 设置当前展示的状态
* @param {Object} state
* @param {Object} data 120个数据全部展示 2只展示一部分数据
*/
// setShowStatus(state, data) {
// state.showStatus = data;
// },
/**
* 下一页页数
* @param {Object} state
* @param {Object} data
*/
setNextPage(state, data) {
state.nextPage = data;
},
/**
* 向上下一页页数
* @param {Object} state
* @param {Object} data
*/
setUpNextPage(state, data) {
state.upNextPage = data;
},
/**
* 总共页数
* @param {Object} state
* @param {Object} data
*/
setLastPage(state, data) {
state.lastPage = data;
},
/**
* 向上总共页数
* @param {Object} state
* @param {Object} data
*/
setUpLastPage(state, data) {
state.upLastPage = data;
},
/**
* 记录时间轴向上滚动的距离
* @param { object } state
* @param { number } num
*/
setScrollTop(state, num) {
state.scrollTop = num;
},
/**
* 记录时间轴向上滚动的距离
* @param { object } state
* @param {string} taskId
*/
setScrollToTaskId(state, taskId) {
state.scrollToTaskId = taskId;
},
/**
* 设置日常任务当前是否应该处于收缩状态
* @param { object } state
* @param { boolean } data
*/
setShrink(state, data) {
state.isShrink = data;
},
/**
* 设置tip的值
* @param {object} state
* @param {object} data
*/
setTip(state, data) {
if (!data) return;
state.tip = { ...data };
},
/**
* 是否显示tips
* @param { object } state
* @param { boolean } show
*/
setTipShow(state, show) {
state.tip.show = show;
},
/**
* 是否显示tips
* @param { object } state
* @param { number } status
*/
setStatus(state, status) {
state.tip.status = status;
},
/**
* 设置时间基准点
* @param { object } state
* @param { number } data
*/
setTimeNode(state, data) {
state.timeNode = data;
},
/**
* 设置时间颗粒度
* @param { object } state
* @param { number } data
*/
setTimeUnit(state, data) {
state.timeUnit = data;
},
/**
* 设置向上查到的定期任务数据
* @param {Object} state
* @param {Array} data 服务端返回的模板数组
*/
setUpTasks(state, data) {
if (!state.tasks.length) {
state.tasks = [...data]; // 原来没有数据
} else {
state.tasks = [...data, ...state.tasks];
let arr = [],
flag = false;
state.tasks.forEach(task => {
arr.forEach(item => {
if (task.id == item.id) {
flag = true;
}
});
if (!flag) {
arr.push(task);
}
});
state.tasks = [...arr];
// state.tasks = [...data.concat(state.tasks)];
}
},
/**
* 设置向下查到的定期任务数据
* @param {Object} state
* @param {Array} data 服务端返回的模板数组
*/
setDownTasks(state, data) {
if (!state.tasks && !state.tasks.length) {
state.tasks = [...data];
} else {
state.tasks = [...state.tasks, ...data];
let arr = [], flag = false;
state.tasks.forEach(task => {
arr.forEach(item => {
if (item.id === task.id) {
flag = true;
}
});
if (!flag) {
arr.push(task);
}
});
state.tasks = [...arr];
}
},
/**
* 添加任务后更新tasks
* @param {Object} state
* @param {Array} data 新添加的task
*/
updateTasks(state, data) {
state.tasks = [...data];
},
/**
* 设置添加任务的位置
* @param {*} state
* @param {*} data
*/
setAddPosition(state, data) {
console.log('data: ', data);
},
/**
* 设置日常任务数据
* @param {Object} state
* @param {Array} data 服务端返回的模板数组
*/
setDailyTasks(state, data) {
state.dailyTasks = data || [];
},
/**
* 设置永久固定任务
* @param {object} state
* @param {array} tasks 服务端查询到的永久日常任务书籍
*/
setPermanents(state, tasks) {
state.permanents = tasks || [];
},
/**
* 设置时间轴是否继续向上查任务
* @param {Object} state
* @param {Boolean} show
*/
setTopEnd(state, show) {
state.topEnd = show;
},
/**
* 设置时间轴是否继续向下查任务
* @param {Object} state
* @param {Boolean} show
*/
setBottomEnd(state, show) {
state.bottomEnd = show;
},
// 清空标志位 如切换角色等使用
clearEndFlag(state) {
state.topEnd = false;
state.bottomEnd = false;
},
// 清空定期任务
clearTasks(state) {
state.tasks = [];
},
/**
* 收到消息设置任务状态
* @param {Object} state
* @param {Array} data 服务端返回的模板数组
*/
setTaskStatus(state, data) {
const item = state.tasks.find(i => i.id === data.id);
item.process = data.taskStatus;
},
/**
* 收到打开新项目消息状态
* @param {Object} state
* @param {Array} data 服务端返回的模板数组
*/
setNewProjectInfo(state, data) {
state.newProjectInfo = data;
},
/**
* 设置骨架屏是否显示
* @param {Object} state
* @param {Boolean} show
*/
setShowSkeleton(state, show) {
state.showSkeleton = show;
},
/**
* 设置日常任务骨架屏是否显示
* @param {Object} state
* @param {Boolean} show
*/
setShowGlobalSkeleton(state, show) {
state.showGlobalSkeleton = show;
},
/**
* 设置永久的日常任务是否加载过
* @param {Object} state
* @param {Boolean} show
*/
setHasPermanent(state, show) {
state.hasPermanent = show;
},
/**
* 是否设置时间轴自动滚动的位置
* @param {Object} state
* @param {Boolean} show
*/
setShowScrollTo(state, show) {
state.showScrollTo = show;
},
/**
* 设置所有任务数据
* @param {Object} state
* @param {Array} data 服务端返回的模板数组
*/
setAllTasks(state, data) {
state.allTasks = data || [];
},
};
export default mutations;

77
store/task/mutations.js

@ -1,38 +1,38 @@
const mutations = { const mutations = {
/** /**
* 设置真实任务数据 * 时间轴模式
* @param {Object} state * @param {Object} state
* @param {Object} data * @param {Object} data
*/ */
setBasicTask(state, data) { setTimeLineType(state, data) {
state.basicTasks = [...data]; state.timeLineType = data;
}, },
/** /**
* 设置向上真实任务数据 * 设置真实任务数据
* @param {Object} state * @param {Object} state
* @param {Object} data * @param {Object} data
*/ */
setUpBasicTask(state, data) { setUpRealTasks(state, data) {
state.upBasicTasks = [...data]; state.realTasks = [...data, ...state.realTasks];
}, },
/** /**
* 设置当前展示的状态 * 设置真实任务数据
* @param {Object} state * @param {Object} state
* @param {Object} data 120个数据全部展示 2只展示一部分数据 * @param {Object} data
*/ */
// setShowStatus(state, data) { setDownRealTasks(state, data) {
// state.showStatus = data; state.realTasks = [...state.realTasks, ...data];
// }, },
/** /**
* 下一页页数 * 下一页页数
* @param {Object} state * @param {Object} state
* @param {Object} data * @param {Object} data
*/ */
setNextPage(state, data) { setDownNextPage(state, data) {
state.nextPage = data; state.downNextPage = data;
}, },
/** /**
@ -44,24 +44,6 @@ const mutations = {
state.upNextPage = data; state.upNextPage = data;
}, },
/**
* 总共页数
* @param {Object} state
* @param {Object} data
*/
setLastPage(state, data) {
state.lastPage = data;
},
/**
* 向上总共页数
* @param {Object} state
* @param {Object} data
*/
setUpLastPage(state, data) {
state.upLastPage = data;
},
/** /**
* 记录时间轴向上滚动的距离 * 记录时间轴向上滚动的距离
* @param { object } state * @param { object } state
@ -126,6 +108,24 @@ const mutations = {
state.timeNode = data; state.timeNode = data;
}, },
/**
* 设置当前查询的时间基准点
* @param { object } state
* @param { number } data
*/
setCurrUpTimeNode(state, data) {
state.currUpTimeNode = data;
},
/**
* 设置当前查询的时间基准点
* @param { object } state
* @param { number } data
*/
setCurrDownTimeNode(state, data) {
state.currDownTimeNode = data;
},
/** /**
* 设置时间颗粒度 * 设置时间颗粒度
* @param { object } state * @param { object } state
@ -257,6 +257,21 @@ const mutations = {
state.tasks = []; state.tasks = [];
}, },
// 清空真实任务数据
clearRealTasks(state) {
state.realTasks = [];
},
// 清空刻度模式数据
// clearScaleTasks(state) {
// state.scaleTasks = [];
// },
// 清空任务模式数据
// clearConTasks(state) {
// state.conTasks = [];
// },
/** /**
* 收到消息设置任务状态 * 收到消息设置任务状态
* @param {Object} state * @param {Object} state

36
store/task/state - 副本.js

@ -0,0 +1,36 @@
const state = {
basicTasks: [], // 接口返回的任务列表
upBasicTasks: [], // 接口返回的任务列表 - 向上
// showStatus: 0, // 1、20个数据全部展示 2、只展示一部分数据
nextPage: 1, // 下一页查询的页数
lastPage: 0, // 全部页数
upNextPage: 1, // 向上查页数
upLastPage: 0, // 向上查 最后一页
scrollTop: 0,
scrollToTaskId: '', // 时间轴自动滚动的位置
isShrink: false, // true: 收起, false:展开
tip: {
taskId: '', // 当前正在修改状态的任务的id
show: false,
status: 0, // 所点击任务的当前状态码
text: '',
left: 0, // 鼠标点击位置距离左边的距离
top: 0, // 鼠标点击位置距离上边的距离
},
timeNode: new Date().getTime(), // 时间基准点
timeUnit: 4, // 时间颗粒度
topEnd: false, // 时间轴向上查任务到顶了
bottomEnd: false, // 时间轴向下查任务到底了
permanents: [], // 永久日常任务
dailyTasks: [], // 日常任务
tasks: [], // 所有的定期任务
showSkeleton: false, // 定期任务骨架屏
showGlobalSkeleton: false, // 日常任务骨架屏
newProjectInfo: {},
showScrollTo: false, // 是否可以设置时间轴自动滚动的位置
allTasks: [], // 所有任务
hasPermanent: false, // 永久的日常任务是否加载过
};
export default state;

13
store/task/state.js

@ -1,11 +1,12 @@
const state = { const state = {
basicTasks: [], // 接口返回的任务列表 realTasks: [], // 真实任务
upBasicTasks: [], // 接口返回的任务列表 - 向上 // scaleTasks: [], // 刻度模式任务
// showStatus: 0, // 1、20个数据全部展示 2、只展示一部分数据 // conTasks: [], // 任务模式任务
nextPage: 1, // 下一页查询的页数 currUpTimeNode: new Date().getTime(), // 当前查询的时间基准点
lastPage: 0, // 全部页数 currDownTimeNode: new Date().getTime(), // 当前查询的时间基准点
timeLineType: 1, // 时间轴模式 1 刻度模式 2 任务模式
downNextPage: 1, // 下一页查询的页数
upNextPage: 1, // 向上查页数 upNextPage: 1, // 向上查页数
upLastPage: 0, // 向上查 最后一页
scrollTop: 0, scrollTop: 0,
scrollToTaskId: '', // 时间轴自动滚动的位置 scrollToTaskId: '', // 时间轴自动滚动的位置
isShrink: false, // true: 收起, false:展开 isShrink: false, // true: 收起, false:展开

Loading…
Cancel
Save