From e926b751fbb22e20dcee1fe152292418f6c5ffd1 Mon Sep 17 00:00:00 2001 From: song Date: Thu, 6 Jan 2022 18:29:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=97=B6=E9=97=B4=E8=BD=B4=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 158 +++-- CHANGELOG.md | 13 +- apis/project.js | 17 + apis/role.js | 12 + apis/task.js | 20 + common/styles/tailwind.scss | 4 + components/Projects/ProjectItem.vue | 139 +++-- components/Roles/Roles.vue | 236 ++++++- components/Title/Title.vue | 216 ++++++- .../Title/components/CreateTask copy.vue | 466 ++++++++++++++ components/Title/components/CreateTask.vue | 583 ++++++++++++++++++ components/Title/components/ShareProject.vue | 210 +++++++ components/Upload/Upload.vue | 2 +- config/time.js | 17 + hooks/useGetOptions.js | 8 + main.js | 12 + package.json | 4 +- pages.json | 16 +- pages/index/index.vue | 175 +++--- pages/project/project.vue | 480 ++++++++++++-- store/index.js | 4 +- store/role/actions.js | 17 + store/role/getters.js | 13 + store/role/index.js | 12 + store/role/mutations.js | 39 ++ store/role/state.js | 8 + store/task/actions.js | 33 + store/task/getters.js | 23 + store/task/index.js | 12 + store/task/mutations.js | 238 +++++++ store/task/state.js | 25 + uni.scss | 2 + utils/cache.js | 235 +++++++ utils/task.js | 58 ++ 34 files changed, 3193 insertions(+), 314 deletions(-) create mode 100644 apis/project.js create mode 100644 apis/role.js create mode 100644 apis/task.js create mode 100644 components/Title/components/CreateTask copy.vue create mode 100644 components/Title/components/CreateTask.vue create mode 100644 components/Title/components/ShareProject.vue create mode 100644 config/time.js create mode 100644 hooks/useGetOptions.js create mode 100644 store/role/actions.js create mode 100644 store/role/getters.js create mode 100644 store/role/index.js create mode 100644 store/role/mutations.js create mode 100644 store/role/state.js create mode 100644 store/task/actions.js create mode 100644 store/task/getters.js create mode 100644 store/task/index.js create mode 100644 store/task/mutations.js create mode 100644 store/task/state.js create mode 100644 utils/task.js diff --git a/App.vue b/App.vue index 16aaa30..f3c747b 100644 --- a/App.vue +++ b/App.vue @@ -1,96 +1,90 @@ diff --git a/components/Title/Title.vue b/components/Title/Title.vue index 48d48ea..fb9a3f0 100644 --- a/components/Title/Title.vue +++ b/components/Title/Title.vue @@ -1,8 +1,220 @@ - - diff --git a/components/Title/components/CreateTask copy.vue b/components/Title/components/CreateTask copy.vue new file mode 100644 index 0000000..cdcd229 --- /dev/null +++ b/components/Title/components/CreateTask copy.vue @@ -0,0 +1,466 @@ + + + + + diff --git a/components/Title/components/CreateTask.vue b/components/Title/components/CreateTask.vue new file mode 100644 index 0000000..d12ac71 --- /dev/null +++ b/components/Title/components/CreateTask.vue @@ -0,0 +1,583 @@ + + + + + diff --git a/components/Title/components/ShareProject.vue b/components/Title/components/ShareProject.vue new file mode 100644 index 0000000..37b7164 --- /dev/null +++ b/components/Title/components/ShareProject.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/components/Upload/Upload.vue b/components/Upload/Upload.vue index d94d3f5..6ba08be 100644 --- a/components/Upload/Upload.vue +++ b/components/Upload/Upload.vue @@ -22,7 +22,7 @@ const handleUpload = async cur => { emit('success'); res.url && (uni.$t.domain = res.url); setTimeout(() => { - uni.navigateTo({ url: `/pages/project-webview/project-webview?u=${userId.value}&p=${res.id}&pname=${res.pname}&url=${res.url}` }); + uni.navigateTo({ url: `/pages/project/project?u=${userId.value}&p=${res.id}&pname=${res.pname}&url=${res.url}` }); }, 2000); } catch (error) { console.error('error: ', error); diff --git a/config/time.js b/config/time.js new file mode 100644 index 0000000..27e412e --- /dev/null +++ b/config/time.js @@ -0,0 +1,17 @@ +export default { + timeUnits: [ + // 时间颗粒度 + { id: 0, value: '毫秒', format: 'x', cycle: 'YY-M-D HH:mm:ss', granularity: 'millisecond' }, + { id: 1, value: '秒', format: 'x', cycle: 'YY-M-D HH:mm:ss', granularity: 'second' }, + { id: 2, value: '分', format: 'ss', cycle: 'YY-M-D HH:mm', granularity: 'minute' }, + { id: 3, value: '时', format: 'mm', cycle: 'YY-M-D HH时', granularity: 'hour' }, + { id: 4, value: '天', format: 'D日 HH:mm', cycle: 'YY-M-D', granularity: 'day' }, + { id: 5, value: '周', format: 'D日 HH:mm', cycle: '', granularity: 'week' }, + { id: 6, value: '月', format: 'D日 H:m', cycle: 'YYYY年', granularity: 'month' }, + { id: 7, value: '季度', format: '', cycle: 'YYYY年', granularity: 'quarter' }, + { id: 8, value: '年', format: 'YYYY', cycle: '', granularity: 'year' }, + { id: 9, value: '年代', format: '', cycle: '', granularity: '' }, + { id: 10, value: '世纪', format: '', cycle: '', granularity: '' }, + { id: 11, value: '千年', format: '', cycle: '', granularity: '' }, + ], +}; diff --git a/hooks/useGetOptions.js b/hooks/useGetOptions.js new file mode 100644 index 0000000..e29a528 --- /dev/null +++ b/hooks/useGetOptions.js @@ -0,0 +1,8 @@ +import qs from 'qs'; + +export default function useGetOptions(){ + const options = getCurrentPages(); + const param = options[0].$page.fullPath.split('?')[1]; + const prefixed = qs.parse(param, { ignoreQueryPrefix: true }); + return prefixed +} \ No newline at end of file diff --git a/main.js b/main.js index 6675cd9..8b06ada 100644 --- a/main.js +++ b/main.js @@ -4,6 +4,9 @@ import uView from './uni_modules/vk-uview-ui'; // 引入 uView UI import store from "./store"; import { setupHttp } from '@/utils/request.js'; import { setupTall } from '@/apis/tall.js'; +import { setupProject } from '@/apis/project.js'; +import { setupRole } from '@/apis/role.js'; +import { setupTask } from '@/apis/task.js'; import { setupWbs } from '@/apis/wbs.js' import dayjs from 'dayjs'; import 'dayjs/locale/zh-cn'; @@ -14,6 +17,8 @@ import storage from '@/utils/storage.js'; import time from '@/utils/time.js'; import ui from '@/utils/ui.js'; import upload from '@/utils/upload.js'; +import task from '@/utils/task.js'; +import timeConfig from '@/config/time'; export function createApp() { const app = createSSRApp(App) @@ -22,6 +27,9 @@ export function createApp() { app.use(store); setupHttp(app); setupTall(app); + setupProject(app); + setupRole(app); + setupTask(app); setupWbs(app); dayjs.locale('zh-cn'); @@ -32,6 +40,8 @@ export function createApp() { app.config.globalProperties.$time = time; app.config.globalProperties.$ui = ui; app.config.globalProperties.$upload = upload; + app.config.globalProperties.$task = task; + app.config.globalProperties.$timeConfig = timeConfig; uni.$cache = cache; uni.$catchReq = cacheAndRequest; @@ -39,6 +49,8 @@ export function createApp() { uni.$time = time; uni.$ui = ui; uni.$upload = upload; + uni.$task = task; + uni.$timeConfig = timeConfig; return { app diff --git a/package.json b/package.json index a6aba21..d61a6d5 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "main": "main.js", "dependencies": { "axios": "^0.24.0", - "dayjs": "^1.10.7" + "dayjs": "^1.10.7", + "lodash": "^4.17.21", + "qs": "^6.10.2" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.8.1", diff --git a/pages.json b/pages.json index 69f11f7..54acbb8 100644 --- a/pages.json +++ b/pages.json @@ -5,14 +5,14 @@ "style": { "navigationBarText": "TALL" } - } - // { - // "path": "pages/project/project", - // "style": { - // "navigationStyle": "custom", - // "navigationBarTextStyle": "white" - // } - // } + }, + { + "path": "pages/project/project", + "style": { + "navigationStyle": "custom", + "navigationBarTextStyle": "white" + } + } ], "globalStyle": { "navigationBarTextStyle": "black", diff --git a/pages/index/index.vue b/pages/index/index.vue index effe100..e39a44a 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -4,7 +4,8 @@ + @handleFindPoint="handleFindPoint" +/> @@ -18,92 +19,92 @@ diff --git a/store/index.js b/store/index.js index e8d8158..70cac9f 100644 --- a/store/index.js +++ b/store/index.js @@ -2,6 +2,8 @@ import { createStore } from 'vuex'; import user from './user/index.js'; import socket from './socket/index.js'; import project from './project/index.js'; +import role from './role/index.js'; +import task from './task/index.js'; // 不属于具体模块的 应用级的 store内容 const state = { @@ -42,5 +44,5 @@ export default createStore({ state, getters, mutations, - modules: {user, socket, project} + modules: {user, socket, project, role, task} }); diff --git a/store/role/actions.js b/store/role/actions.js new file mode 100644 index 0000000..d06ed72 --- /dev/null +++ b/store/role/actions.js @@ -0,0 +1,17 @@ +const actions = { + /** + * 根据项目id查找所有成员信息 + * @param {*} commit + * @param {object} params + */ + async getAllMembers({ commit }, params) { + try { + const data = await uni.$catchReq.queryChecker(params); + commit('setMembers', data); + } catch (error) { + uni.$ui.showToast(error.msg || '成员查询失败'); + } + }, +}; + +export default actions; diff --git a/store/role/getters.js b/store/role/getters.js new file mode 100644 index 0000000..6552b4a --- /dev/null +++ b/store/role/getters.js @@ -0,0 +1,13 @@ +const getters = { + // 是不是负责人 + isMine({ roleId, invisibleRoles, visibleRoles }) { + if (!visibleRoles || !visibleRoles.length) return false; + const visible = visibleRoles.find(visible => visible.id === roleId); + if (visible) return visible.mine; + const invisible = invisibleRoles.find(invisible => invisible.id === roleId); + if (invisible) return visible.mine; + return false; + }, +}; + +export default getters; diff --git a/store/role/index.js b/store/role/index.js new file mode 100644 index 0000000..d22f64a --- /dev/null +++ b/store/role/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import getters from './getters'; +import mutations from './mutations'; +import actions from './actions'; + +export default { + namespaced: true, + state, + getters, + mutations, + actions, +}; diff --git a/store/role/mutations.js b/store/role/mutations.js new file mode 100644 index 0000000..83bd215 --- /dev/null +++ b/store/role/mutations.js @@ -0,0 +1,39 @@ +const mutations = { + /** + * 设置不展示的角色信息 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setInvisibleRoles(state, data) { + state.invisibleRoles = data || []; + }, + + /** + * 设置展示的角色信息 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setVisibleRoles(state, data) { + state.visibleRoles = data || []; + }, + + /** + * 设置当前角色信息 + * @param {Object} state + * @param {string} roleId 当前正在展示的角色的id + */ + setRoleId(state, roleId) { + state.roleId = roleId; + }, + + /** + * 设置项目下所有成员信息 + * @param {Object} state + * @param {Array} data 服务端返回的模板数组 + */ + setMembers(state, data) { + state.members = data || []; + }, +}; + +export default mutations; diff --git a/store/role/state.js b/store/role/state.js new file mode 100644 index 0000000..1117de7 --- /dev/null +++ b/store/role/state.js @@ -0,0 +1,8 @@ +const state = { + invisibleRoles: [], // 不展示的角色信息 + visibleRoles: [], // 展示的角色信息 + roleId: '', // 当前展示查看的角色id + members: [], // 项目下所有成员 +}; + +export default state; diff --git a/store/task/actions.js b/store/task/actions.js new file mode 100644 index 0000000..2ff1f56 --- /dev/null +++ b/store/task/actions.js @@ -0,0 +1,33 @@ +const actions = { + /** + * 根据角色查找永久的日常任务 + * @param {*} commit + * @param {string} roleId 角色id + */ + getPermanent({ commit }, param) { + uni.$catchReq.getPermanent(param, (err, data) => { + if (err) { + console.error('err: ', err); + } else { + commit('setPermanents', data); + } + }); + }, + + /** + * 根据时间和角色查找日常任务 + * @param {*} commit + * @param {object} param 请求参数 roleId, timeNode, timeUnit + */ + getGlobal({ commit }, param) { + uni.$catchReq.getGlobal(param, (err, data) => { + if (err) { + console.error('err: ', err); + } else { + commit('setDailyTasks', data); + } + }); + }, +}; + +export default actions; diff --git a/store/task/getters.js b/store/task/getters.js new file mode 100644 index 0000000..756ad80 --- /dev/null +++ b/store/task/getters.js @@ -0,0 +1,23 @@ +const getters = { + // 所有的日常任务 永久 + 可变 日常任务 + globals({ dailyTasks, permanents }) { + return [...permanents, ...dailyTasks]; + }, + + unitConfig({ timeUnit }) { + const target = uni.$timeConfig.timeUnits.find(item => item.id === timeUnit); + return target; + }, + + // 计算任务开始时间的格式 + startTimeFormat(state, { unitConfig }) { + return unitConfig.format || 'D日 HH:mm'; + }, + + // 计算颗粒度 对应的 dayjs add 的单位 + timeGranularity(state, { unitConfig }) { + return unitConfig.granularity; + }, +}; + +export default getters; diff --git a/store/task/index.js b/store/task/index.js new file mode 100644 index 0000000..d22f64a --- /dev/null +++ b/store/task/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import getters from './getters'; +import mutations from './mutations'; +import actions from './actions'; + +export default { + namespaced: true, + state, + getters, + mutations, + actions, +}; diff --git a/store/task/mutations.js b/store/task/mutations.js new file mode 100644 index 0000000..01d9dd7 --- /dev/null +++ b/store/task/mutations.js @@ -0,0 +1,238 @@ +const mutations = { + /** + * 记录时间轴向上滚动的距离 + * @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 (task.id == item.id) { + flag = true; + } + }); + + if (!flag) { + arr.push(task); + } + }); + + state.tasks = [...arr]; + // state.tasks = [...state.tasks.concat(data)]; + } + }, + + /** + * 添加任务后更新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 + */ + setShowScrollTo(state, show) { + state.showScrollTo = show; + }, +}; + +export default mutations; diff --git a/store/task/state.js b/store/task/state.js new file mode 100644 index 0000000..023378d --- /dev/null +++ b/store/task/state.js @@ -0,0 +1,25 @@ +const state = { + 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, // 定期任务骨架屏 + newProjectInfo: {}, + showScrollTo: false, // 是否可以设置时间轴自动滚动的位置 +}; + +export default state; diff --git a/uni.scss b/uni.scss index d53a89f..13a36b6 100644 --- a/uni.scss +++ b/uni.scss @@ -26,12 +26,14 @@ $uni-text-color-inverse:#fff;//反色 $uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息 $uni-text-color-placeholder: #808080; $uni-text-color-disable:#c0c0c0; +$roleChoiceColor: #f59e0b; /* 背景颜色 */ $uni-bg-color:#ffffff; $uni-bg-color-grey:#f8f8f8; $uni-bg-color-hover:#f1f1f1;//点击状态颜色 $uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色 +$uni-bg-color-transparent: rgba(255, 255, 255, 0); //透明色 /* 边框颜色 */ $uni-border-color:#c8c7cc; diff --git a/utils/cache.js b/utils/cache.js index 0d03f0e..d9ed650 100644 --- a/utils/cache.js +++ b/utils/cache.js @@ -59,4 +59,239 @@ export default { uni.$storage.setStorage('projects', []); } }, + + /** + * 当前显示的角色信息 获取 + * @param {object} params + * @returns + */ + async getShowRole(projectId) { + try { + const data = await uni.$storage.getStorage(`roles_${projectId}`); + return filter.roles(JSON.parse(data)); + } catch (error) { + return null; + } + }, + + /** + * 当前显示的角色信息 存 + * @param {array} data + */ + putShowRole(projectId, data) { + try { + if (!data || !data.visibleList || !data.visibleList.length) return; // 服务端没数据不做操作 + let value = uni.$storage.getStorageSync(`roles_${projectId}`); + let locals = value ? JSON.parse(value) : null; + if (!locals || !locals.length) { + // 本地没数据 + locals = data || null; + } else { + // 本地有数据 + data.invisibleList.forEach(item => { + let invisibleListLocalData = locals.invisibleList.find(local => item.id === local.id); + if (invisibleListLocalData) { + // 有相同数据 就用新的data里的数据 + invisibleListLocalData = item; + } else { + // 没有就直接存本地 + locals.invisibleList.push(item); + } + }); + data.visibleList.forEach(item => { + let localData = locals.visibleList.find(local => item.id === local.id); + if (localData) { + // 有相同数据 就用新的data里的数据 + localData = item; + } else { + // 没有就直接存本地 + locals.visibleList.push(item); + } + }); + } + uni.$storage.setStorage(`roles_${projectId}`, locals); + } catch (error) { + console.error('error: ', error); + uni.$storage.setStorage(`roles_${projectId}`, []); + } + }, + + /** + * 定期任务 获取 + * @param {number} startTime + * @param {number} endTime + * @returns + */ + async getStorageRegularTask(params) { + try { + const data = await uni.$storage.getStorage(`plan_task_${params.projectId}_${params.roleId}`); + return filter.planTask(JSON.parse(data), params.timeNode, params.queryNum, params.timeUnit, params.queryType); + } catch (error) { + return []; + } + }, + + /** + * 定期任务 存 + * @param {array} data + */ + putStorageRegularTask(params, data) { + try { + if (!data || !data.length) return; // 服务端没数据不做操作 + let value = uni.$storage.getStorageSync(`plan_task_${params.projectId}_${params.roleId}`); + let locals = value ? JSON.parse(value) : []; + if (!locals || !locals.length) { + // 本地没数据 + locals = data || []; + } else { + // 本地有数据 + data.forEach(item => { + let localData = locals.find(local => item.id === local.id); + if (localData) { + // 有相同数据 就用新的data里的数据 + localData = item; + } else { + // 没有就直接存本地 + locals.push(item); + } + }); + } + uni.$storage.setStorage(`plan_task_${params.projectId}_${params.roleId}`, locals); + } catch (error) { + console.error('error: ', error); + uni.$storage.setStorage(`plan_task_${params.projectId}_${params.roleId}`, []); + } + }, + + /** + * 永久的日常任务 获取 + * @param {number} startTime + * @param {number} endTime + * @returns + */ + async getStoragePermanent(params) { + try { + const data = await uni.$storage.getStorage(`fixed_tasks_${params.projectId}_${params.roleId}`); + return filter.fixedTasks(JSON.parse(data)); + } catch (error) { + return []; + } + }, + + /** + * 永久的日常任务 存 + * @param {array} data + */ + putStoragePermanent(params, data) { + try { + if (!data || !data.length) return; // 服务端没数据不做操作 + let value = uni.$storage.getStorageSync(`fixed_tasks_${params.projectId}_${params.roleId}`); + let locals = value ? JSON.parse(value) : []; + if (!locals || !locals.length) { + // 本地没数据 + locals = data || []; + } else { + // 本地有数据 + data.forEach((item, index) => { + let localData = locals.find(local => item.detailId === local.detailId); + if (localData) { + // 有相同数据 就用新的data里的数据 + localData = item; + } else { + locals.splice(index, 1); + // 没有就直接存本地 + locals.push(item); + } + }); + } + uni.$storage.setStorage(`fixed_tasks_${params.projectId}_${params.roleId}`, locals); + } catch (error) { + console.error('error: ', error); + uni.$storage.setStorage(`fixed_tasks_${params.projectId}_${params.roleId}`, []); + } + }, + + /** + * 日常任务 获取 + * @param {number} timeNode + * @returns + */ + async getDailyTask(params) { + try { + const data = await uni.$storage.getStorage(`variable_tasks_${params.projectId}_${params.roleId}`); + return filter.dailyTask(JSON.parse(data), params.timeNode); + } catch (error) { + return []; + } + }, + + /** + * 日常任务 存 + * @param {array} data + */ + putDailyTask(params, data) { + try { + if (!data || !data.length) return; // 服务端没数据不做操作 + let value = uni.$storage.getStorageSync(`variable_tasks_${params.projectId}_${params.roleId}`); + let locals = value ? JSON.parse(value) : []; + if (!locals || !locals.length) { + // 本地没数据 + locals = data || []; + } else { + // 本地有数据 + data.forEach(item => { + let localData = locals.find(local => item.detailId === local.detailId); + if (localData) { + // 有相同数据 就用新的data里的数据 + localData = item; + } else { + // 没有就直接存本地 + locals.push(item); + } + }); + } + uni.$storage.setStorage(`variable_tasks_${params.projectId}_${params.roleId}`, locals); + } catch (error) { + console.error('error: ', error); + uni.$storage.setStorage(`variable_tasks_${params.projectId}_${params.roleId}`, []); + } + }, + + /** + * 插件信息 获取 + * @param {string} pluginId + * @returns + */ + async getPlugin(pluginId) { + try { + const data = await uni.$storage.getStorage(`plugin_${pluginId}`); + return filter.plugin(JSON.parse(data)); + } catch (error) { + return null; + } + }, + + /** + * 插件信息 存 + * @param {string} pluginId + * @param {object} data + */ + putPlugin(pluginId, data) { + try { + if (!data || !data.id) return; // 服务端没数据不做操作 + let value = uni.$storage.getStorageSync(`plugin_${pluginId}`); + let locals = value ? JSON.parse(value) : null; + if (!locals || !locals.length) { + // 本地没数据 + locals = data || null; + } else { + // 本地有数据 + locals = data; + } + uni.$storage.setStorage(`plugin_${pluginId}`, locals); + } catch (error) { + console.error('error: ', error); + uni.$storage.setStorage(`plugin_${pluginId}`, null); + } + }, }; diff --git a/utils/task.js b/utils/task.js new file mode 100644 index 0000000..0279c77 --- /dev/null +++ b/utils/task.js @@ -0,0 +1,58 @@ +import dayjs from 'dayjs'; + +/** + * 设置时间轴空数据 + * @param {number} startTime + * @param {boolean} isUp true 向上加载,false 向下加载 + * @param {string} timeGranularity 颗粒度 + * @param {number} pageCount 加载的颗粒度数量 默认值是10 + */ +const setPlaceholderTasks = (startTime, isUp, timeGranularity, pageCount) => { + let result = []; + pageCount = pageCount || uni.$task.pageCount; + for (let i = 0; i < pageCount; i++) { + const delta = isUp ? `-${i + 1}` - 0 : i + 1; + let item = { + id: uni.$u.guid(20, false, 10), + panel: {}, + plugins: [], + process: 4, + planStart: uni.$moment(startTime).add(delta, timeGranularity).valueOf(), + }; + // console.log('isup: ', isUp, 'result:', new Date(item.planStart).toLocaleDateString()); + + isUp ? result.unshift(item) : result.push(item); + } + return result; +}; + +/** + * 超出旧数据上、下限 补齐时间刻度到新数据的起始时间颗粒度 + * @param {object} option + * @param {array} option.tasks 旧的已有的任务书籍 + * @param {array} option.data 新拿到的任务数据 空值已经过滤过了 + * @param {string} option.timeGranularity 颗粒度 + */ +const computeFillPlaceholderTaskCount = ({ tasks, data, timeGranularity }) => { + const result = { prev: 0, next: 0 }; + // 新数据的开始时间 < 旧数据的开始时间 + // 超出了上限 补上限的时间刻度 + // 补上 新数据开始时间 到 旧数据开始时间 的刻度 + if (+data[0].planStart < +tasks[0].planStart) { + // 找出来需要补几组颗粒度 + result.prev = dayjs(+tasks[0].planStart).diff(+data[0].planStart, timeGranularity) + 1; + } + + // 新数据的结束时间 > 旧数据的结束时间 + // 超出了下线 补下限的时间刻度 + // 补上 旧数据截止时间 到 新数据截止时间 的刻度 + if (+data[data.length - 1].planStart > +tasks[tasks.length - 1].planStart) { + result.next = dayjs(+data[data.length - 1].planStart).diff(+tasks[tasks.length - 1].planStart, timeGranularity) + 1; + } + return result; +}; + +export default { + setPlaceholderTasks, + computeFillPlaceholderTaskCount +}; \ No newline at end of file