import { ref, onMounted, computed, watch, nextTick } from 'vue'; import { onLoad } from '@dcloudio/uni-app'; import useGetUserIdFromLocal from '@/hooks/user/useGetUserIdFromLocal'; import { useStore } from 'vuex'; import { flatten } from 'lodash'; export default function useInit() { const store = useStore(); const token = computed(() => store.state.user.token); const userId = useGetUserIdFromLocal(); const roleId = computed(() => store.state.role.roleId); const timeNode = computed(() => store.state.task.timeNode); const timeUnit = computed(() => store.state.task.timeUnit); const tasks = computed(() => store.state.task.tasks); const newProjectInfo = computed(() => store.state.task.newProjectInfo); const showScrollTo = computed(() => store.state.task.showScrollTo); const timeGranularity = computed(() => store.getters['task/timeGranularity']); const projectId = computed(() => store.getters['project/projectId']); const height = ref(null); const timeLine = ref(null); onLoad(options => { console.log('onLoad options: ', options); if (options.share && options.share === '1') { shareInit(options); } else { init(options); } }); /** * 当时间基准点发生变化时 * 重新根据时间和角色查询普通日常任务 * 永久日常任务不发生 改变 */ watch(timeNode, newValue => { if (newValue && roleId.value) { console.log('当时间基准点发生变化时') clearTasksData(); getGlobalData(); // 查可变日常任务 initPlanTasks(); // 处理定期任务 } }); /** * 当角色发生变化时 * 重新查询永久日常任务和普通日常任务 * 注意: 切换角色后 重新设置了时间基准点 时间基准点一定会变 * 所以监听时间基准点获取 可变日常任务即可 这里不用获取 避免重复获取 */ watch(roleId, newValue => { if (newValue) { console.log('当角色发生变化时') store.commit('task/setTimeNode', Date.now()); // 根据角色查找永久的日常任务 const params = { roleId: newValue.value, projectId: projectId.value }; store.dispatch('task/getPermanent', params); } }); /** * 当时间基准点发生变化时 * 重新根据时间和角色查询普通日常任务 * 永久日常任务不发生改变 */ watch(newProjectInfo, newValue => { console.log('当时间基准点发生变化时') if (newValue && newValue.value.projectId && newValue.value.url) { uni.$u.route('/', { u: userId.value, p: newValue.value.projectId, url: newValue.value.url }); clearTasksData(); store.commit('role/setRoleId', ''); const options = uni.$route.query; init(options); } }); onMounted(() => { const system = uni.getSystemInfoSync(); height.value = `${system.windowHeight}px`; }); /** * 初始化 * @param {object | null} options */ function init(options) { console.log('初始化init') if (!token.value) { // 不论有没有token都直接从userId获取token // token有过期时间 从本地获取可能是过期 干脆直接从userId获取 if (!options || !options.u) { uni.$ui.showToast('缺少用户信息参数'); // 参数里没有u (userId)提示 } else { store.dispatch('user/getToken', options.u); } } // 参数里有项目名称 就设置标题里的项目名称 options && options.pname && store.commit('project/setProjectName', options.pname); if (!options || !options.p) { uni.$ui.showToast('缺少项目信息参数'); // 没有项目id参数 } else { if (options.p !== uni.$storage.getStorageSync('projectId')) { console.log('切项目了'); uni.$storage.setStorageSync('roleId', ''); } // 根据项目id获取项目信息 const params = { projectId: options.p, num: 0 } getProjectById(params); // 查询医院是否填写了调查问卷 // this.handleQueryNotWrite(options.p); // 根据项目id获取成员列表 store.dispatch('role/getAllMembers', { projectId: options.p }); } } // 初始化 定期任务 async function initPlanTasks() { setPrevPlaceholderTasks(); // 向上加载空数据 setNextPlaceholderTasks(); // 向下加载空数据 await getInitTasks(); // 获取初始数据 // 滚动到对应位置 let timer = null; timer = setInterval(() => { if (showScrollTo.value) { clearInterval(timer); // nextTick(() => timeLine.setScrollPosition()); } }, 500); } // 切换了 颗粒度 || 角色时候 获取初始定期任务 function getInitTasks() { // 预加载 上下的定期任务 function preloadFn(that) { const detailId = tasks.value.findIndex(task => task.detailId); const arr = []; tasks.value.forEach(task => { if (task.detailId) { arr.push(task); } }); if (detailId !== -1) { // 只要有1个真实的任务 就预加载上下周期的任务 const { pageCount } = uni.$task; nextTick(() => { // 向上拿数据 getTasks({ timeNode: +tasks.value[detailId].planStart, queryType: 0, queryNum: pageCount }); // 向下拿数据 const nextQueryTime = +uni.$time.add(+arr[arr.length - 1].planStart, 1, timeGranularity.value); getTasks({ timeNode: nextQueryTime, queryType: 1, queryNum: pageCount }); }); } else { // 没有任务 上下显示时间刻度 // 向上加载 setPrevPlaceholderTasks(); // // 向下加载 setNextPlaceholderTasks(); } } // 根据时间基准点和角色查找定期任务 getTasks({ queryType: 0 }); // 向上获取定期任务数据 // 根据项目id获取角色列表 getTasks({ queryType: 1 }, preloadFn); // 向下获取定期任务数据 } /** * 根据时间基准点和角色查找定期任务 * @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, fn) { store.commit('task/setShowSkeleton', false); const params = generateGetTaskParam(query); uni.$catchReq.getRegularTask(params, (err, data) => { store.commit('task/setShowSkeleton', false); if (err) { // TODO: 提示错误 console.error('err: ', err); } else { store.commit('task/setShowScrollTo', true); // 有数据用数据替换刻度 // 没有数据 继续加载刻度 if (data && data.length) { replacePrevData(data, params.queryType); params.queryType === 0 ? store.commit('task/setTopEnd', false) : store.commit('task/setBottomEnd', false); } else { // TODO: 0 -> 向上 1 -> 向下 params.queryType === 0 ? setPrevPlaceholderTasks() : setNextPlaceholderTasks(); } if (tasks.value.length && fn) { fn(this); } } }); } /** * 生成getTasks所用的参数 * @param {object} query getTasks传递的参数 */ function generateGetTaskParam(query) { return { roleId: roleId.value, timeNode: query.timeNode || timeNode.value, timeUnit: query.timeUnit || timeUnit.value, queryNum: query.queryNum || 3, queryType: query.queryType, projectId: projectId.value, }; } // 设置时间轴向上的空数据 function setPrevPlaceholderTasks() { store.commit('task/setTopEnd', true); let startTime = ''; if (!tasks.value || !tasks.value.length) { startTime = Date.now(); // 没有任务就应该是时间基准点 } else { startTime = tasks[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 = +tasks.value[tasks.value.length - 1].planStart; } const initData = uni.$task.setPlaceholderTasks(startTime, false, timeGranularity.value); store.commit('task/setDownTasks', initData); } /** * 用拿到的新数据 替换 时间刻度/旧数据 * 先对比 新旧数据的 始末时间 补齐刻度 * 再遍历对比 用任务替换刻度 * @param {array} data 服务端返回的新数据 上边已经处理过空值 * @param {number} type 0 -> 向上 1->向下 */ function replacePrevData(data, type) { let oldTasks = fillPlaceholderTask({ tasks.value, data, timeGranularity.value }); // 已经上下补齐时间刻度的 // 遍历对比 用任务替换刻度 // 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({ tasks, data, timeGranularity }) { const { prev, next } = uni.$task.computeFillPlaceholderTaskCount({ tasks, data, timeGranularity }); if (prev) { const newTasks = uni.$task.setPlaceholderTasks(+tasks[0].planStart, true, timeGranularity, prev); store.commit('task/setUpTasks', newTasks); } if (next) { const newTasks = uni.$task.setPlaceholderTasks(+tasks[tasks.length - 1].planStart, false, timeGranularity, next); store.commit('task/setDownTasks', newTasks); } return tasks.value; } // 分享链接来的初始化 async function shareInit(options) { console.log('分享链接来的初始化init') const storageUser = uni.$storage.getStorageSync('user'); const user = storageUser ? JSON.parse(storageUser) : null; if (user && user.id) { await store.dispatch('user/getToken', user.id); const res = await clickShare({ code: options.shareId }); if (res && res.projectId) { let query = { ...uni.$route.query }; query = { u: user.id, p: res.projectId, }; uni.$router.push({ path: uni.$route.path, query }); console.log('query',query) init(query); } } else { uni.$ui.showToast('缺少用户信息参数,请登录'); } } /** * 点击分享连接 * @param {any} commit * @param {object} param 请求参数 */ async function clickShare(param) { try { const data = await uni.$catchReq.clickShare(param); return data; } catch (error) { uni.$ui.showToast(error.msg || '获取失败'); } } /** * 通过项目id获取项目信息 * @param {object} params 提交的参数 */ async function getProjectById(params) { try { const data = await uni.$u.api.findProjectById(params); store.commit('project/setProject', data); // 根据项目id获取角色列表 getRoles(params); } catch (error) { console.log('error: ', error || '获取项目信息失败'); } } /** * 通过项目id获取角色信息 * @param {string} projectId * @param {object} params 提交的参数 */ function getRoles(params) { uni.$catchReq.findShowRole(params, (err, data) => { if (err) { console.error('err: ', err || '获取角色信息失败'); } else { store.commit('role/setInvisibleRoles', data ? data.invisibleList : []); store.commit('role/setVisibleRoles', data ? data.visibleList : []); setInitialRoleId(data ? data.visibleList : []); } }); } // 设置 初始显示角色信息 function setInitialRoleId(visibleList) { if (!visibleList || !visibleList.length) return; const index = visibleList.findIndex(item => +item.mine === 1); const currentRole = index > 0 ? visibleList[index] : visibleList[0]; const storageRoleId = uni.$storage.getStorageSync('roleId'); const currentRoleId = storageRoleId || (currentRole ? currentRole.id : ''); store.commit('role/setRoleId', currentRoleId); // 清空storage uni.$storage.setStorageSync('roleId', ''); } // 获取可变全局任务 function getGlobalData() { const param = { roleId: roleId.value, timeNode: timeNode.value, timeUnit: timeUnit.value, projectId: projectId.value }; store.dispatch('task/getGlobal', param); } // 清除已有的任务数据 function clearTasksData() { // 清空日常任务的数据 store.commit('task/setPermanents', []); store.commit('task/setDailyTasks', []); // 清空定期任务数据 store.commit('task/clearTasks'); // 到顶的标志复位 // 到底的标志复位 store.commit('task/clearEndFlag'); } }