51 changed files with 1539 additions and 1031 deletions
@ -1,6 +1,12 @@ |
|||
# 1.0.0 (2021-12-31) |
|||
# 1.0.0 (2022-01-04) |
|||
|
|||
### 🌟 新功能 |
|||
范围|描述|commitId |
|||
--|--|-- |
|||
- | Initial commit | 52b8f49 |
|||
- | first commit | [8dc26de](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8dc26de) |
|||
|
|||
|
|||
范围|描述|commitId |
|||
--|--|-- |
|||
- | Initial commit | [52b8f49](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/52b8f49) |
|||
|
|||
|
@ -0,0 +1,81 @@ |
|||
const apiUrl = 'https://test.tall.wiki/gateway'; // 测试
|
|||
// const apiUrl = 'https://www.tall.wiki/gateway'; // 生产
|
|||
const tall = `${apiUrl}/tall3/v3.0`; |
|||
|
|||
// 登录
|
|||
export const login = { |
|||
async index(params) { |
|||
try { |
|||
const data = await uni.$u.http.post(`${tall}/users/signin`, params); |
|||
return data; |
|||
} catch (error) { |
|||
throw new Error(error); |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
export const getToken = userId => uni.config.globalProperties.$u.get(`${tall}/users/userId`, { userId }); |
|||
|
|||
const install = (Vue, vm) => { |
|||
vm.$u.api = { ...vm.$u.api } || {}; |
|||
// 登录
|
|||
vm.$u.api.signin = params => login.index(params); |
|||
// 获取图片验证码
|
|||
vm.$u.api.getImageCode = () => vm.$u.get(`${tall}/users/code`); |
|||
// 获取短信验证码
|
|||
vm.$u.api.getSmsCode = params => vm.$u.get(`${tall}/users/smscode`, params); |
|||
// 根据userId获取token
|
|||
vm.$u.api.getToken = userId => vm.$u.get(`${tall}/users/userId`, { userId }); |
|||
// 绑定手机号
|
|||
vm.$u.api.phoneBind = (phone, smsCode) => vm.$u.http.post(`${tall}/users/binding`, { phone, smsCode }); |
|||
// 是否合并账号
|
|||
vm.$u.api.phoneMerge = (phone, isMerge) => vm.$u.http.post(`${tall}/users/merge`, { phone, isMerge }); |
|||
|
|||
// 修改用户信息
|
|||
vm.$u.api.updateUserInfo = params => vm.$u.http.post(`${tall}/users/userInfo`, params); |
|||
|
|||
// 获取项目列表
|
|||
vm.$u.api.getProjects = (startTime, endTime) => vm.$u.post(`${tall}/project/query`, { startTime, endTime }); |
|||
// 查询日历是否有小红点
|
|||
vm.$u.api.findRedPoint = (startTime, endTime) => vm.$u.post(`${tall}/project/day`, { startTime, endTime }); |
|||
// 设置项目顺序
|
|||
vm.$u.api.setProjectSort = params => vm.$u.post(`${tall}/project/setProjectSort`, params); |
|||
// 设置项目父子结构
|
|||
vm.$u.api.setProjectRelation = params => vm.$u.post(`${tall}/project/setProjectRelation`, params); |
|||
// 删除某个项目
|
|||
vm.$u.api.delProject = projectId => vm.$u.post(`${tall}/project/deleteProject`, { projectId }); |
|||
}; |
|||
|
|||
export default { |
|||
install |
|||
}; |
|||
|
|||
// export function setupTall(app) {
|
|||
// app.config.globalProperties.$u.api = { ...app.config.globalProperties.$u.api } || {};
|
|||
// // 登录
|
|||
// // app.config.globalProperties.$u.api.signin = params => login.index(params);
|
|||
// // 获取图片验证码
|
|||
// // app.config.globalProperties.$u.api.getImageCode = () => app.config.globalProperties.$u.get(`${tall}/users/code`);
|
|||
// // 获取短信验证码
|
|||
// // app.config.globalProperties.$u.api.getSmsCode = params => app.config.globalProperties.$u.get(`${tall}/users/smscode`, params);
|
|||
// // 根据userId获取token
|
|||
// const getToken = userId => app.config.globalProperties.$u.get(`${tall}/users/userId`, { userId });
|
|||
// // 绑定手机号
|
|||
// // app.config.globalProperties.$u.api.phoneBind = (phone, smsCode) => app.config.globalProperties.$u.http.post(`${tall}/users/binding`, { phone, smsCode });
|
|||
// // 是否合并账号
|
|||
// // app.config.globalProperties.$u.api.phoneMerge = (phone, isMerge) => app.config.globalProperties.$u.http.post(`${tall}/users/merge`, { phone, isMerge });
|
|||
|
|||
// // 修改用户信息
|
|||
// // app.config.globalProperties.$u.api.updateUserInfo = params => app.config.globalProperties.$u.http.post(`${tall}/users/userInfo`, params);
|
|||
|
|||
// // 获取项目列表
|
|||
// // app.config.globalProperties.$u.api.getProjects = (startTime, endTime) => app.config.globalProperties.$u.post(`${tall}/project/query`, { startTime, endTime });
|
|||
// // 查询日历是否有小红点
|
|||
// // app.config.globalProperties.$u.api.findRedPoint = (startTime, endTime) => app.config.globalProperties.$u.post(`${tall}/project/day`, { startTime, endTime });
|
|||
// // 设置项目顺序
|
|||
// // app.config.globalProperties.$u.api.setProjectSort = params => app.config.globalProperties.$u.post(`${tall}/project/setProjectSort`, params);
|
|||
// // 设置项目父子结构
|
|||
// // app.config.globalProperties.$u.api.setProjectRelation = params => app.config.globalProperties.$u.post(`${tall}/project/setProjectRelation`, params);
|
|||
// // 删除某个项目
|
|||
// // app.config.globalProperties.$u.api.delProject = projectId => app.config.globalProperties.$u.post(`${tall}/project/deleteProject`, { projectId });
|
|||
// }
|
@ -0,0 +1,7 @@ |
|||
const install = (Vue, vm) => { |
|||
vm.$u.api = { ...vm.$u.api } || {}; |
|||
// 导入wbs
|
|||
vm.$u.api.import = formData => vm.$t.chooseAndUpload(`${uni.$t.domain}/wbs`, formData); |
|||
}; |
|||
|
|||
export default { install }; |
@ -0,0 +1,60 @@ |
|||
const install = (Vue, vm) => { |
|||
Vue.prototype.$u.http.setConfig({ |
|||
baseUrl: '', |
|||
showLoading: true, // 是否显示请求中的loading
|
|||
loadingText: '玩命加载中...', |
|||
loadingTime: 800, |
|||
loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
|
|||
// 配置请求头信息
|
|||
header: { |
|||
'content-type': 'application/json;charset=UTF-8' |
|||
}, |
|||
}); |
|||
|
|||
// 请求拦截部分,如配置,每次请求前都会执行
|
|||
Vue.prototype.$u.http.interceptor.request = config => { |
|||
const token = vm.$store.state.user.token || uni.$t.storage.getStorageSync(uni.$t.app.tokenKey); |
|||
if (token) { |
|||
config.header.Authorization = `Bearer ${token}`; |
|||
} |
|||
|
|||
return config; |
|||
}; |
|||
|
|||
// 响应拦截,如配置,每次请求结束都会执行本方法
|
|||
Vue.prototype.$u.http.interceptor.response = res => { |
|||
if (res.code === 200) { |
|||
// res为服务端返回值,可能有code,result等字段
|
|||
// 这里对res.result进行返回,将会在this.$u.post(url).then(res => {})的then回调中的res的到
|
|||
// 如果配置了originalData为true,请留意这里的返回值
|
|||
return res.data; |
|||
} else if (res.code === 401) { |
|||
// 假设201为token失效,这里跳转登录
|
|||
vm.$u.toast('验证失败,请重新登录'); |
|||
setTimeout(() => { |
|||
// 此为uView的方法,详见路由相关文档
|
|||
vm.$u.route('/pages/user/login'); |
|||
}, 1500); |
|||
return false; |
|||
} else { |
|||
// 如果返回false,则会调用Promise的reject回调,
|
|||
// 并将进入this.$u.post(url).then().catch(res=>{})的catch回调中,res为服务端的返回值
|
|||
return false; |
|||
} |
|||
}; |
|||
|
|||
Vue.prototype.$u.post = (url, param = {}, header = {}) => { |
|||
return Vue.prototype.$u.http.request({ |
|||
url, |
|||
method: 'POST', |
|||
header, |
|||
data: { |
|||
param |
|||
}, |
|||
}); |
|||
}; |
|||
}; |
|||
|
|||
export default { |
|||
install |
|||
}; |
@ -0,0 +1,59 @@ |
|||
export default { |
|||
/** |
|||
* 显示toast |
|||
* @param {string} title 提示内容 |
|||
* @param {number} duration 显示时间 默认2000 |
|||
*/ |
|||
showToast(title, duration = 2000) { |
|||
return uni.showToast({ |
|||
title, |
|||
icon: 'none', |
|||
duration, |
|||
mask: true, |
|||
}); |
|||
}, |
|||
|
|||
// 隐藏toast
|
|||
hideToast() { |
|||
return uni.hideToast(); |
|||
}, |
|||
|
|||
/** |
|||
* 显示加载雪花 |
|||
* @param {string} title |
|||
*/ |
|||
showLoading(title = '玩命加载中...') { |
|||
return uni.showLoading({ |
|||
title, |
|||
mask: true, |
|||
}); |
|||
}, |
|||
|
|||
// 隐藏loading
|
|||
hideLoading() { |
|||
return uni.hideLoading(); |
|||
}, |
|||
|
|||
/** |
|||
* 显示modal弹出框 |
|||
* @param {string} title 标题 |
|||
* @param {string} content 内容 |
|||
* @param {boolean} showCancel 是否显示取消按钮 默认true |
|||
*/ |
|||
showModal(title, content, showCancel = true) { |
|||
return new Promise(function(resolve, reject) { |
|||
uni.showModal({ |
|||
title, |
|||
content, |
|||
showCancel, |
|||
success: ({ |
|||
confirm, |
|||
cancel |
|||
}) => { |
|||
confirm && resolve(); |
|||
cancel && reject(); |
|||
}, |
|||
}); |
|||
}); |
|||
}, |
|||
}; |
@ -1,23 +1,28 @@ |
|||
import App from './App' |
|||
import uView from './uni_modules/vk-uview-ui'; // 引入 uView UI
|
|||
|
|||
// #ifndef VUE3
|
|||
import Vue from 'vue' |
|||
Vue.config.productionTip = false |
|||
App.mpType = 'app' |
|||
const app = new Vue({ |
|||
...App |
|||
}) |
|||
app.$mount() |
|||
// #endif
|
|||
|
|||
// #ifdef VUE3
|
|||
import { createSSRApp } from 'vue' |
|||
export function createApp() { |
|||
const app = createSSRApp(App) |
|||
app.use(uView) // 使用 uView UI
|
|||
return { |
|||
app |
|||
} |
|||
import { createSSRApp } from 'vue'; |
|||
import App from './App'; |
|||
import uView from './uni_modules/vk-uview-ui'; // 引入 uView UI
|
|||
import store from "./store"; |
|||
import tall from '@/apis/tall.js'; |
|||
import request from '@/utils/request.js'; |
|||
// import Tall from '@/utils/tall.js';
|
|||
// import { setupHttp } from '@/utils/request.js'
|
|||
// import { setupTall } from '@/apis/tall.js'
|
|||
|
|||
export function createApp() { |
|||
const app = createSSRApp(App) |
|||
|
|||
app.use(uView); // 使用 uView UI
|
|||
app.use(store); |
|||
// app.use(request);
|
|||
// app.use(tall);
|
|||
// app.use(Tall);
|
|||
// setupHttp(app);
|
|||
// setupTall(app);
|
|||
|
|||
app.config.globalProperties.$tall = tall; |
|||
app.config.globalProperties.$request = request; |
|||
|
|||
return { |
|||
app |
|||
} |
|||
} |
|||
// #endif
|
@ -1,54 +1,54 @@ |
|||
{ |
|||
"name": "tall-4", |
|||
"version": "1.0.0", |
|||
"description": "", |
|||
"main": "main.js", |
|||
"dependencies": {}, |
|||
"devDependencies": { |
|||
"@typescript-eslint/eslint-plugin": "^5.8.1", |
|||
"@typescript-eslint/parser": "^5.8.1", |
|||
"commitizen": "^4.2.4", |
|||
"commitlint": "^16.0.1", |
|||
"conventional-changelog": "^3.1.25", |
|||
"conventional-changelog-cli": "^2.2.2", |
|||
"eslint": "^7.32.0", |
|||
"eslint-config-airbnb-base": "^15.0.0", |
|||
"eslint-plugin-import": "^2.25.3", |
|||
"eslint-plugin-prettier": "^4.0.0", |
|||
"eslint-plugin-vue": "^8.2.0", |
|||
"husky": "^7.0.4", |
|||
"lint-staged": "^12.1.4", |
|||
"prettier": "^2.5.1", |
|||
"right-pad": "^1.0.1", |
|||
"vue-cli-plugin-commitlint": "^1.0.12" |
|||
}, |
|||
"browserslist": [ |
|||
"Android >= 4", |
|||
"ios >= 8" |
|||
], |
|||
"config": { |
|||
"commitizen": { |
|||
"path": "./node_modules/vue-cli-plugin-commitlint/lib/cz" |
|||
} |
|||
}, |
|||
"husky": { |
|||
"hooks": { |
|||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS", |
|||
"pre-commit": "lint-staged" |
|||
} |
|||
}, |
|||
"lint-staged": { |
|||
"src/**/*.{js,json,css,vue}": [ |
|||
"eslint --fix", |
|||
"git add" |
|||
], |
|||
"*.js": "eslint --cache --fix" |
|||
}, |
|||
"scripts": { |
|||
"test": "echo \"Error: no test specified\" && exit 1", |
|||
"cz": "npm run log && git add . && git cz", |
|||
"log": "conventional-changelog --config ./node_modules/vue-cli-plugin-commitlint/lib/log -i CHANGELOG.md -s -r 0" |
|||
}, |
|||
"author": "", |
|||
"license": "ISC" |
|||
{ |
|||
"name": "tall-4", |
|||
"version": "1.0.0", |
|||
"description": "", |
|||
"main": "main.js", |
|||
"dependencies": {}, |
|||
"devDependencies": { |
|||
"@typescript-eslint/eslint-plugin": "^5.8.1", |
|||
"@typescript-eslint/parser": "^5.8.1", |
|||
"commitizen": "^4.2.4", |
|||
"commitlint": "^16.0.1", |
|||
"conventional-changelog": "^3.1.25", |
|||
"conventional-changelog-cli": "^2.2.2", |
|||
"eslint": "^7.32.0", |
|||
"eslint-config-airbnb-base": "^15.0.0", |
|||
"eslint-plugin-import": "^2.25.3", |
|||
"eslint-plugin-prettier": "^4.0.0", |
|||
"eslint-plugin-vue": "^8.2.0", |
|||
"husky": "^7.0.4", |
|||
"lint-staged": "^12.1.4", |
|||
"prettier": "^2.5.1", |
|||
"right-pad": "^1.0.1", |
|||
"vue-cli-plugin-commitlint": "^1.0.12" |
|||
}, |
|||
"browserslist": [ |
|||
"Android >= 4", |
|||
"ios >= 8" |
|||
], |
|||
"config": { |
|||
"commitizen": { |
|||
"path": "./node_modules/vue-cli-plugin-commitlint/lib/cz" |
|||
} |
|||
}, |
|||
"husky": { |
|||
"hooks": { |
|||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS", |
|||
"pre-commit": "lint-staged" |
|||
} |
|||
}, |
|||
"lint-staged": { |
|||
"src/**/*.{js,json,css,vue}": [ |
|||
"eslint --fix", |
|||
"git add" |
|||
], |
|||
"*.js": "eslint --cache --fix" |
|||
}, |
|||
"scripts": { |
|||
"test": "echo \"Error: no test specified\" && exit 1", |
|||
"cz": "npm run log && git add . && git cz", |
|||
"log": "conventional-changelog --config ./node_modules/vue-cli-plugin-commitlint/lib/log -i CHANGELOG.md -s -r 0" |
|||
}, |
|||
"author": "", |
|||
"license": "ISC" |
|||
} |
|||
|
@ -1,3 +0,0 @@ |
|||
const actions = {}; |
|||
|
|||
export default actions; |
@ -1,3 +0,0 @@ |
|||
const getters = {}; |
|||
|
|||
export default getters; |
@ -1,12 +0,0 @@ |
|||
import state from './state'; |
|||
import getters from './getters'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions'; |
|||
|
|||
export default { |
|||
namespaced: true, |
|||
state, |
|||
getters, |
|||
mutations, |
|||
actions, |
|||
}; |
@ -1,3 +0,0 @@ |
|||
const mutations = {}; |
|||
|
|||
export default mutations; |
@ -1,7 +0,0 @@ |
|||
const state = { |
|||
db: null, // indexedDB对象
|
|||
name: 'TALL_indexedDB', |
|||
version: 1, |
|||
}; |
|||
|
|||
export default state; |
@ -1,36 +1,44 @@ |
|||
import Vue from 'vue'; |
|||
import Vuex from 'vuex'; |
|||
import messages from './messages/index'; |
|||
import project from './project/index'; |
|||
import role from './role/index'; |
|||
import socket from './socket/index'; |
|||
import task from './task/index'; |
|||
import user from './user/index'; |
|||
|
|||
// 不属于具体模块的 应用级的 store内容
|
|||
const state = { |
|||
networkConnected: true, // 网络是否连接
|
|||
forceUseStorage: true, // 强制启用storage
|
|||
}; |
|||
|
|||
const getters = { |
|||
// 是否启用本地存储
|
|||
// 设置了强制启用本地存储 或者 没有网络连接的时候
|
|||
useStorage({ networkConnected, forceUseStorage }) { |
|||
return forceUseStorage || !networkConnected; |
|||
}, |
|||
}; |
|||
|
|||
const mutations = { |
|||
/** |
|||
* 设置网络是否连接的变量 |
|||
* @param {*} state |
|||
* @param {boolean} networkConnected |
|||
*/ |
|||
setNetworkConnected(state, networkConnected) { |
|||
state.networkConnected = networkConnected; |
|||
}, |
|||
}; |
|||
|
|||
Vue.use(Vuex); |
|||
export default new Vuex.Store({ state, getters, mutations, modules: { user, messages, socket, project, role, task } }); |
|||
import { createStore } from 'vuex'; |
|||
import user from './user/index.js'; |
|||
|
|||
// 不属于具体模块的 应用级的 store内容
|
|||
const state = { |
|||
networkConnected: true, // 网络是否连接
|
|||
forceUseStorage: true, // 强制启用storage
|
|||
systemInfo: null, // 系统设备信息
|
|||
}; |
|||
|
|||
const getters = { |
|||
// 是否启用本地存储
|
|||
// 设置了强制启用本地存储 或者 没有网络连接的时候
|
|||
useStorage({ networkConnected, forceUseStorage }) { |
|||
return forceUseStorage || !networkConnected; |
|||
}, |
|||
}; |
|||
|
|||
const mutations = { |
|||
/** |
|||
* 设置网络是否连接的变量 |
|||
* @param {*} state |
|||
* @param {boolean} networkConnected |
|||
*/ |
|||
setNetworkConnected(state, networkConnected) { |
|||
state.networkConnected = networkConnected; |
|||
}, |
|||
|
|||
/** |
|||
* 设置系统信息的数据 |
|||
* @param {object} state |
|||
* @param {object | null} data 获取到的数据 |
|||
*/ |
|||
setSystemInfo(state, data) { |
|||
state.systemInfo = data; |
|||
}, |
|||
}; |
|||
|
|||
export default createStore({ |
|||
state, |
|||
getters, |
|||
mutations, |
|||
modules: {user} |
|||
}); |
|||
|
@ -1,3 +0,0 @@ |
|||
const getters = {}; |
|||
|
|||
export default getters; |
@ -1,4 +0,0 @@ |
|||
import state from './state'; |
|||
import mutations from './mutations'; |
|||
|
|||
export default { namespaced: true, state, mutations }; |
@ -1,85 +0,0 @@ |
|||
import storage from '@/utils/storage'; |
|||
const { setStorageSync, getStorageSync, removeStorageSync } = storage; |
|||
|
|||
const mutations = { |
|||
/** |
|||
* 初始化消息栈 |
|||
* @param {object} state |
|||
* @param {string} type |
|||
* type: |
|||
* syncMessages 同步消息栈 |
|||
* faultMessages 故障消息 未处理消息栈 |
|||
* faults 所有的故障消息栈 |
|||
*/ |
|||
messagesInit(state, type) { |
|||
const messages = getStorageSync(type) ? JSON.parse(getStorageSync(type)) : []; |
|||
state[type] = messages; |
|||
}, |
|||
|
|||
/** |
|||
* 将新 消息添加到 消息栈 最前边 |
|||
* @param { object } state |
|||
* @param { object } data |
|||
* data: message, type |
|||
* message 消息对象 |
|||
* type: |
|||
* syncMessages 同步消息栈 |
|||
* faultMessages 故障消息 未处理消息栈 |
|||
* faults 所有的故障消息栈 |
|||
* game 游戏的消息 |
|||
* |
|||
* cache: boolean true 本地存储 false 不存储 |
|||
*/ |
|||
messagesAdd(state, data) { |
|||
const messages = state[data.type]; |
|||
if (messages.length > 0) { |
|||
const result = messages.find(msg => msg.id === data.message.id); |
|||
if (result) return; |
|||
} |
|||
messages.unshift(data.message); |
|||
// eslint-disable-next-line no-param-reassign
|
|||
state[data.type] = messages; |
|||
if (data.cache) { |
|||
setStorageSync(data.type, JSON.stringify(messages)); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 通过消息id移除指定 同步 消息 |
|||
* @param { object } state |
|||
* @param { object } data |
|||
* data: messageId, type |
|||
* messageId: 要移除的消息的messageId |
|||
* type: |
|||
* syncMessages 同步消息栈 |
|||
* faultMessages 故障消息 未处理消息栈 |
|||
* faults 所有的故障消息栈 |
|||
* cache: boolean true 本地存储 false 不存储 |
|||
*/ |
|||
messagesRemoveById(state, data) { |
|||
const messages = state[data.type]; |
|||
const index = messages.findIndex(msg => msg.id === data.messageId); |
|||
if (index < 0) return; |
|||
messages.splice(index, 1); |
|||
// eslint-disable-next-line no-param-reassign
|
|||
state[data.type] = messages; |
|||
if (data.cache) { |
|||
setStorageSync(data.type, JSON.stringify(messages)); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 清除指定type的消息 |
|||
* @param {any} state |
|||
* @param {object} data |
|||
* data: type, cache |
|||
*/ |
|||
messagesClear(state, data) { |
|||
state[data.type] = []; |
|||
if (data.cache) { |
|||
removeStorageSync(data.type); |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
export default mutations; |
@ -1,8 +0,0 @@ |
|||
const state = { |
|||
syncMessages: [], // 同步消息
|
|||
faultMessages: [], // 新收到的未处理的 故障消息
|
|||
faults: [], // 所有的故障消息
|
|||
game: [], // 游戏的消息
|
|||
}; |
|||
|
|||
export default state; |
@ -1,3 +0,0 @@ |
|||
const actions = {}; |
|||
|
|||
export default actions; |
@ -1,12 +0,0 @@ |
|||
const getters = { |
|||
/** |
|||
* 当前项目的id |
|||
* @param {object} project |
|||
*/ |
|||
projectId({ project }) { |
|||
uni.$t.storage.setStorageSync('projectId', project.id); |
|||
return project.id; |
|||
}, |
|||
}; |
|||
|
|||
export default getters; |
@ -1,12 +0,0 @@ |
|||
import state from './state'; |
|||
import getters from './getters'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions'; |
|||
|
|||
export default { |
|||
namespaced: true, |
|||
state, |
|||
getters, |
|||
mutations, |
|||
actions, |
|||
}; |
@ -1,43 +0,0 @@ |
|||
const mutations = { |
|||
/** |
|||
* 设置state projects书籍 |
|||
* @param {object} state |
|||
* @param {array} projects 项目列表 |
|||
*/ |
|||
setProjects(state, projects) { |
|||
if (!projects || !projects.length) { |
|||
state.projects = []; |
|||
} else { |
|||
state.projects = [...projects]; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 设置当前项目信息 |
|||
* @param { object } state |
|||
* @param { object } data |
|||
*/ |
|||
setProject(state, data) { |
|||
state.project = data || { name: '加载中...' }; |
|||
}, |
|||
|
|||
/** |
|||
* 设置当前项目名称 |
|||
* @param { object } state |
|||
* @param { string } data |
|||
*/ |
|||
setProjectName(state, data) { |
|||
state.project.name = data; |
|||
}, |
|||
|
|||
/** |
|||
* 设置小红点 |
|||
* @param { object } state |
|||
* @param { string } data |
|||
*/ |
|||
setDotList(state, data) { |
|||
state.dotList = data; |
|||
}, |
|||
}; |
|||
|
|||
export default mutations; |
@ -1,8 +0,0 @@ |
|||
/* eslint-disable */ |
|||
const state = { |
|||
project: { name: '加载中...' }, // 当前项目信息
|
|||
projects: [], // 项目列表
|
|||
dotList: [], // 小红点
|
|||
}; |
|||
|
|||
export default state; |
@ -1,17 +0,0 @@ |
|||
const actions = { |
|||
/** |
|||
* 根据项目id查找所有成员信息 |
|||
* @param {*} commit |
|||
* @param {object} params |
|||
*/ |
|||
async getAllMembers({ commit }, params) { |
|||
try { |
|||
const data = await uni.$u.api.queryChecker(params); |
|||
commit('setMembers', data); |
|||
} catch (error) { |
|||
uni.$t.ui.showToast(error.msg || '成员查询失败'); |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
export default actions; |
@ -1,13 +0,0 @@ |
|||
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; |
@ -1,12 +0,0 @@ |
|||
import state from './state'; |
|||
import getters from './getters'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions'; |
|||
|
|||
export default { |
|||
namespaced: true, |
|||
state, |
|||
getters, |
|||
mutations, |
|||
actions, |
|||
}; |
@ -1,39 +0,0 @@ |
|||
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; |
@ -1,8 +0,0 @@ |
|||
const state = { |
|||
invisibleRoles: [], // 不展示的角色信息
|
|||
visibleRoles: [], // 展示的角色信息
|
|||
roleId: '', // 当前展示查看的角色id
|
|||
members: [], // 项目下所有成员
|
|||
}; |
|||
|
|||
export default state; |
@ -1,154 +0,0 @@ |
|||
const WS_BASE_URL = process.env.VUE_APP_MSG_URL; |
|||
|
|||
let prevTime = 0; |
|||
let socketMsgQueue = []; // socket消息队列
|
|||
let sendHeartTimer = null; |
|||
|
|||
const actions = { |
|||
// 初始化socket
|
|||
initSocket({ commit, dispatch, state, rootState }) { |
|||
if (state.lockSocket) return; |
|||
const { token } = rootState.user; |
|||
if (!token) return; |
|||
commit('setLockSocket', true); |
|||
commit('setSocket', uni.connectSocket({ url: WS_BASE_URL, complete: () => {} })); |
|||
dispatch('onSocketOpen'); |
|||
dispatch('onSocketMessage'); |
|||
dispatch('onSocketClose'); |
|||
state.socket.onError(errMsg => console.error(errMsg)); |
|||
commit('setLockSocket', false); |
|||
}, |
|||
|
|||
// 监听ws打开
|
|||
onSocketOpen({ dispatch, commit, state }) { |
|||
// eslint-disable-next-line no-unused-vars
|
|||
state.socket.onOpen(res => { |
|||
// console.log('ws open: ', res);
|
|||
commit('setConnected', true); |
|||
prevTime = Date.now(); |
|||
// this.auth();
|
|||
dispatch('auth'); |
|||
for (let i = 0; i < socketMsgQueue.length; i++) { |
|||
dispatch('sendSocketMessage', socketMsgQueue[i]); |
|||
} |
|||
socketMsgQueue = []; |
|||
}); |
|||
}, |
|||
|
|||
// 监听收到的ws消息
|
|||
onSocketMessage({ dispatch, state }) { |
|||
state.socket.onMessage(res => { |
|||
// console.log('收到消息:', res);
|
|||
prevTime = Date.now(); |
|||
if (!res || !res.data || !JSON.parse(res.data)) return; |
|||
const resData = JSON.parse(res.data); |
|||
const { messageSet, ackId } = resData; |
|||
// 处理消息体对象
|
|||
messageSet.forEach(item => dispatch('handleMessagesData', item)); |
|||
ackId && dispatch('sendSocketMessage', { type: 'Ack', data: { ackId } }); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 处理收到的消息内容 |
|||
* @param {object} item 单个消息体对象 |
|||
*/ |
|||
handleMessagesData({ dispatch, commit }, item) { |
|||
const data = JSON.parse(item.data); |
|||
switch (data.type) { |
|||
case 'Sync': // 开始某个节点
|
|||
commit('messages/messagesAdd', { message: data, type: 'syncMessages' }, { root: true }); |
|||
break; |
|||
case 'taskStatus': // 任务状态修改相关消息
|
|||
commit('task/setTaskStatus', data.data, { root: true }); |
|||
break; |
|||
case 'switchoverProject': // 打开新项目消息
|
|||
commit('task/setNewProjectInfo', data.data, { root: true }); |
|||
break; |
|||
// case 'Chrome': // !收到开始游戏的消息
|
|||
// console.log('handleMessagesData', data);
|
|||
// // @ts-ignore
|
|||
// util.openGameApp({
|
|||
// type: data.data.type,
|
|||
// projectId: data.data.projectId,
|
|||
// id: data.data.recordId,
|
|||
// token: rootState.user.token,
|
|||
// });
|
|||
// break;
|
|||
// case 'Deliver': // 交付物相关消息
|
|||
// commit('messages/messagesAdd', { type: 'checkMessages', message: data }, { root: true });
|
|||
// break;
|
|||
case 'ChannelStatus': |
|||
dispatch('handleAuthMessage', data); |
|||
break; |
|||
// case 'switchoverProject': // 康复相关消息
|
|||
// dispatch('home/getProjectById', data.data.projectId, { root: true });
|
|||
// break;
|
|||
// case 'startDrill': // 康复开始训练相关消息
|
|||
// console.log('setStartDrillInfo', data.data);
|
|||
// commit('home/setStartDrillMessages', data.data, { root: true });
|
|||
// break;
|
|||
default: |
|||
break; |
|||
} |
|||
}, |
|||
|
|||
// 发送消息
|
|||
sendSocketMessage({ state }, data) { |
|||
if (state.connected) { |
|||
const msg = JSON.stringify({ toDomain: 'Server', data: JSON.stringify(data) }); |
|||
state.socket.send({ data: msg }); |
|||
} else { |
|||
socketMsgQueue.push(data); |
|||
} |
|||
}, |
|||
|
|||
// 监听关闭事件
|
|||
onSocketClose({ dispatch, commit, state }) { |
|||
// console.log('onSocketClose');
|
|||
state.socket.onClose(() => { |
|||
commit('setConnected', false); |
|||
if (sendHeartTimer) clearInterval(sendHeartTimer); |
|||
setTimeout(() => { |
|||
dispatch('initSocket'); |
|||
}, 300); |
|||
}); |
|||
}, |
|||
|
|||
// websocket发送channelId进行认证
|
|||
auth({ dispatch, rootState }) { |
|||
const { token } = rootState.user; |
|||
if (!token) return; |
|||
const data = { type: 'Auth', data: { token } }; |
|||
dispatch('sendSocketMessage', data); |
|||
}, |
|||
|
|||
// 心跳检测
|
|||
sendHeart({ dispatch, state }) { |
|||
if (sendHeartTimer) clearInterval(sendHeartTimer); |
|||
sendHeartTimer = setInterval(() => { |
|||
if (Date.now() - prevTime >= 15000) { |
|||
dispatch('sendSocketMessage', { type: 'Ping' }); |
|||
if (Date.now() - prevTime >= 20000) { |
|||
state.socket.close(); |
|||
} |
|||
} |
|||
}, 5000); |
|||
}, |
|||
|
|||
/** |
|||
* 处理auth认证返回的ChannelStatus消息 |
|||
* @param {object} data 消息内容对象 |
|||
*/ |
|||
handleAuthMessage({ commit, dispatch }, data) { |
|||
if (data.data.authed) { |
|||
dispatch('sendHeart'); |
|||
} else { |
|||
uni.$u.toast('消息系统认证失败, 请退出重新登录'); |
|||
uni.$t.removeStorageSync('anyringToken'); |
|||
commit('setSocket', null); |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
export default actions; |
@ -1,5 +0,0 @@ |
|||
import state from './state'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions'; |
|||
|
|||
export default { namespaced: true, state, mutations, actions }; |
@ -1,26 +0,0 @@ |
|||
const mutations = { |
|||
// 设置socket实例
|
|||
setSocket(state, socket) { |
|||
state.socket = socket; |
|||
}, |
|||
|
|||
/** |
|||
* 设置socket连接状态 |
|||
* @param {Object} state |
|||
* @param {boolean} connected 是否连接 true -> 连接 |
|||
*/ |
|||
setConnected(state, connected) { |
|||
state.connected = connected; |
|||
}, |
|||
|
|||
/** |
|||
* 设置连接锁 正在连接中 锁上 避免多个连接同时发出 |
|||
* @param {Object} state |
|||
* @param {boolean} lockSocket 是否正在连接的过程中 |
|||
*/ |
|||
setLockSocket(state, lockSocket) { |
|||
state.lockSocket = lockSocket; |
|||
}, |
|||
}; |
|||
|
|||
export default mutations; |
@ -1,7 +0,0 @@ |
|||
const state = { |
|||
socket: null, // websocket实例
|
|||
connected: false, // 是否处于连接状态
|
|||
lockSocket: false, // 是否正在连接状态
|
|||
}; |
|||
|
|||
export default state; |
@ -1,33 +0,0 @@ |
|||
const actions = { |
|||
/** |
|||
* 根据角色查找永久的日常任务 |
|||
* @param {*} commit |
|||
* @param {string} roleId 角色id |
|||
*/ |
|||
getPermanent({ commit }, param) { |
|||
uni.$t.$q.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.$t.$q.getGlobal(param, (err, data) => { |
|||
if (err) { |
|||
console.error('err: ', err); |
|||
} else { |
|||
commit('setDailyTasks', data); |
|||
} |
|||
}); |
|||
}, |
|||
}; |
|||
|
|||
export default actions; |
@ -1,23 +0,0 @@ |
|||
const getters = { |
|||
// 所有的日常任务 永久 + 可变 日常任务
|
|||
globals({ dailyTasks, permanents }) { |
|||
return [...permanents, ...dailyTasks]; |
|||
}, |
|||
|
|||
unitConfig({ timeUnit }) { |
|||
const target = uni.$t.timeConfig.timeUnits.find(item => item.id === timeUnit); |
|||
return target; |
|||
}, |
|||
|
|||
// 计算任务开始时间的格式
|
|||
startTimeFormat(state, { unitConfig }) { |
|||
return unitConfig.format || 'M月D日 HH:mm'; |
|||
}, |
|||
|
|||
// 计算颗粒度 对应的 dayjs add 的单位
|
|||
timeGranularity(state, { unitConfig }) { |
|||
return unitConfig.granularity; |
|||
}, |
|||
}; |
|||
|
|||
export default getters; |
@ -1,12 +0,0 @@ |
|||
import state from './state'; |
|||
import getters from './getters'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions'; |
|||
|
|||
export default { |
|||
namespaced: true, |
|||
state, |
|||
getters, |
|||
mutations, |
|||
actions, |
|||
}; |
@ -1,238 +0,0 @@ |
|||
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; |
@ -1,25 +0,0 @@ |
|||
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; |
@ -1,19 +1,22 @@ |
|||
const actions = { |
|||
/** |
|||
* 通过userId获取token |
|||
* @param {any} commit |
|||
* @param {string} userId 用户id |
|||
*/ |
|||
async getToken({ commit }, userId) { |
|||
try { |
|||
const data = await uni.$u.api.getToken(userId); |
|||
commit('setToken', data.token); |
|||
commit('setUser', data); |
|||
return data; |
|||
} catch (error) { |
|||
uni.$t.ui.showToast(error.msg || '获取个人信息失败'); |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
import util from '@/common/js/util.js'; |
|||
import { getToken } from '@/apis/tall.js'; |
|||
|
|||
const actions = { |
|||
/** |
|||
* 通过userId获取token |
|||
* @param {any} commit |
|||
* @param {string} userId 用户id |
|||
*/ |
|||
async getToken({ commit }, userId) { |
|||
try { |
|||
const data = await getToken(userId); |
|||
commit('setToken', data.token); |
|||
commit('setUser', data); |
|||
return data; |
|||
} catch (error) { |
|||
util.showToast(error.msg || '获取个人信息失败'); |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
export default actions; |
|||
|
@ -1,14 +1,14 @@ |
|||
const getters = { |
|||
// 获取用户的id
|
|||
userId({ user }) { |
|||
try { |
|||
if (!user) return ''; |
|||
return user.id; |
|||
} catch (error) { |
|||
console.warn("user's getters 获取userId失败", error); |
|||
return ''; |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
export default getters; |
|||
const getters = { |
|||
// 获取用户的id
|
|||
userId({ user }) { |
|||
try { |
|||
if (!user) return ''; |
|||
return user.id; |
|||
} catch (error) { |
|||
console.warn("user's getters 获取userId失败", error); |
|||
return ''; |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
export default getters; |
|||
|
@ -1,12 +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, |
|||
import state from './state'; |
|||
import getters from './getters'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions'; |
|||
|
|||
export default { |
|||
namespaced: true, |
|||
state, |
|||
getters, |
|||
mutations, |
|||
actions, |
|||
}; |
|||
|
@ -1,24 +1,24 @@ |
|||
const mutations = { |
|||
/** |
|||
* 设置存储token |
|||
* @param {object} state |
|||
* @param {string} token |
|||
*/ |
|||
setToken(state, token) { |
|||
state.token = token || ''; |
|||
uni.$t.storage.setStorageSync(uni.$t.app.tokenKey, token || ''); |
|||
}, |
|||
|
|||
/** |
|||
* 设置user数据 |
|||
* @param {object} state |
|||
* @param {object} user |
|||
*/ |
|||
setUser(state, user) { |
|||
if (!user) return; |
|||
state.user = { ...user }; |
|||
uni.$t.storage.setStorageSync('user', JSON.stringify(user)); |
|||
}, |
|||
}; |
|||
|
|||
export default mutations; |
|||
const mutations = { |
|||
/** |
|||
* 设置存储token |
|||
* @param {object} state |
|||
* @param {string} token |
|||
*/ |
|||
setToken(state, token) { |
|||
state.token = token || ''; |
|||
uni.$t.storage.setStorageSync(uni.$t.app.tokenKey, token || ''); |
|||
}, |
|||
|
|||
/** |
|||
* 设置user数据 |
|||
* @param {object} state |
|||
* @param {object} user |
|||
*/ |
|||
setUser(state, user) { |
|||
if (!user) return; |
|||
state.user = { ...user }; |
|||
uni.$t.storage.setStorageSync('user', JSON.stringify(user)); |
|||
}, |
|||
}; |
|||
|
|||
export default mutations; |
|||
|
@ -1,5 +1,5 @@ |
|||
const state = { |
|||
token: '', |
|||
user: null, |
|||
}; |
|||
export default state; |
|||
const state = { |
|||
token: '', |
|||
user: null, |
|||
}; |
|||
export default state; |
|||
|
@ -0,0 +1,62 @@ |
|||
export const filter = { |
|||
/** |
|||
* 过滤获取到的数据 根据开始截止时间 |
|||
* @param {object} data 缓存拿到的数据 |
|||
* @param {number} start ms |
|||
* @param {number} end ms |
|||
* @returns |
|||
*/ |
|||
projects(data, start, end) { |
|||
if (!data || !data.length) return []; |
|||
return data.filter(item => start <= +item.endTime && end >= +item.startTime); |
|||
}, |
|||
}; |
|||
|
|||
export default { |
|||
/** |
|||
* 项目列表某天的 获取 |
|||
* @param {number} startTime |
|||
* @param {number} endTime |
|||
* @returns |
|||
*/ |
|||
async getProjectsByDay(startTime, endTime) { |
|||
try { |
|||
const data = await uni.$t.storage.getStorage('projects'); |
|||
return filter.projects(JSON.parse(data), startTime, endTime); |
|||
} catch (error) { |
|||
return []; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 项目列表 存 |
|||
* @param {array} data |
|||
*/ |
|||
putProjects(data) { |
|||
try { |
|||
if (!data || !data.length) return; // 服务端没数据不做操作
|
|||
let value = uni.$t.storage.getStorageSync('projects'); |
|||
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.$t.storage.setStorage('projects', locals); |
|||
} catch (error) { |
|||
console.error('error: ', error); |
|||
uni.$t.storage.setStorage('projects', []); |
|||
} |
|||
}, |
|||
}; |
@ -0,0 +1,190 @@ |
|||
import store from '@/store/index'; |
|||
|
|||
/** |
|||
* 等待token执行api |
|||
* 没有token 就延时执行自己 直到有了token在请求 |
|||
* @param {function} requestFn 执行请求的函数 |
|||
*/ |
|||
export const waitTokenRequest = requestFn => { |
|||
if (!requestFn || typeof requestFn !== 'function') throw new Error(`requestFn must be a function`); |
|||
if (uni.$t.storage.getStorageSync(uni.$t.app.tokenKey)) { |
|||
requestFn(); |
|||
} else { |
|||
setTimeout(() => waitTokenRequest(requestFn), 10); |
|||
} |
|||
}; |
|||
|
|||
export default { |
|||
/** |
|||
* 获取项目列表 |
|||
* @param {number} startTime 起始时间 |
|||
* @param {number} endTime 截止时间 |
|||
*/ |
|||
getProjects(startTime, endTime, fn) { |
|||
let remote = false; |
|||
if (store.getters.useStorage) { |
|||
// 有缓存 且 服务端数据未返回 就先返回缓存
|
|||
uni.$t.cache |
|||
.getProjectsByDay(startTime, endTime) |
|||
.then(data => { |
|||
!remote && fn(null, data); |
|||
}) |
|||
.catch(err => !remote && fn(err)); |
|||
} |
|||
waitTokenRequest(() => { |
|||
// 拿到api数据后 再用api的数据
|
|||
uni.$u.api |
|||
.getProjects(startTime, endTime) |
|||
.then(data => { |
|||
remote = true; |
|||
fn(null, data); |
|||
// 存api到cache里
|
|||
uni.$t.cache.putProjects(data); |
|||
}) |
|||
.catch(err => fn(err)); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 通过项目id获取角色信息 |
|||
* @param {object} params 提交的参数 |
|||
*/ |
|||
findShowRole(params, fn) { |
|||
let remote = false; |
|||
// 有缓存 且 服务端数据未返回 就先返回缓存
|
|||
uni.$t.cache |
|||
.getShowRole(params.projectId) |
|||
.then(data => { |
|||
!remote && fn(null, data); |
|||
}) |
|||
.catch(err => !remote && fn(err)); |
|||
|
|||
waitTokenRequest(() => { |
|||
// 拿到api数据后 再用api的数据
|
|||
uni.$u.api |
|||
.findShowRole(params) |
|||
.then(data => { |
|||
remote = true; |
|||
fn(null, data); |
|||
// 存api到cache里
|
|||
uni.$t.cache.putShowRole(params.projectId, data); |
|||
}) |
|||
.catch(err => fn(err)); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 根据时间基准点和角色查找定期任务 |
|||
* @param {object} params 提交的参数 |
|||
*/ |
|||
getRegularTask(params, fn) { |
|||
let remote = false; |
|||
// 有缓存 且 服务端数据未返回 就先返回缓存
|
|||
uni.$t.cache |
|||
.getStorageRegularTask(params) |
|||
.then(data => { |
|||
console.log('cache data: ', data); |
|||
!remote && fn(null, data); |
|||
}) |
|||
.catch(err => !remote && fn(err)); |
|||
|
|||
waitTokenRequest(() => { |
|||
// 拿到api数据后 再用api的数据
|
|||
uni.$u.api |
|||
.getRegularTask(params) |
|||
.then(data => { |
|||
console.log('api data: ', uni.$u.deepClone(data)); |
|||
remote = true; |
|||
|
|||
fn(null, uni.$u.deepClone(data)); |
|||
// 存api到cache里
|
|||
uni.$t.cache.putStorageRegularTask(params, data); |
|||
}) |
|||
.catch(err => fn(err)); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 根据角色查找永久的日常任务 |
|||
* @param {object} params 提交的参数 |
|||
*/ |
|||
getPermanent(params, fn) { |
|||
let remote = false; |
|||
// 有缓存 且 服务端数据未返回 就先返回缓存
|
|||
uni.$t.cache |
|||
.getStoragePermanent(params) |
|||
.then(data => { |
|||
!remote && fn(null, data); |
|||
}) |
|||
.catch(err => !remote && fn(err)); |
|||
|
|||
waitTokenRequest(() => { |
|||
// 拿到api数据后 再用api的数据
|
|||
uni.$u.api |
|||
.getPermanent(params) |
|||
.then(data => { |
|||
remote = true; |
|||
fn(null, data); |
|||
// 存api到cache里
|
|||
uni.$t.cache.putStoragePermanent(params, data); |
|||
}) |
|||
.catch(err => fn(err)); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 根据时间和角色查找日常任务 |
|||
* @param {object} params 提交的参数 |
|||
*/ |
|||
getGlobal(params, fn) { |
|||
let remote = false; |
|||
// 有缓存 且 服务端数据未返回 就先返回缓存
|
|||
uni.$t.cache |
|||
.getDailyTask(params) |
|||
.then(data => { |
|||
!remote && fn(null, data); |
|||
}) |
|||
.catch(err => !remote && fn(err)); |
|||
|
|||
waitTokenRequest(() => { |
|||
// 拿到api数据后 再用api的数据
|
|||
uni.$u.api |
|||
.getGlobal(params) |
|||
.then(data => { |
|||
remote = true; |
|||
fn(null, data); |
|||
// 存api到cache里
|
|||
uni.$t.cache.putDailyTask(params, data); |
|||
}) |
|||
.catch(err => fn(err)); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 获取插件信息 |
|||
* @param {object} params 提交的参数 |
|||
*/ |
|||
getOtherPlugin(params, fn) { |
|||
let remote = false; |
|||
// 有缓存 且 服务端数据未返回 就先返回缓存
|
|||
uni.$t.cache |
|||
.getPlugin(params.pluginId) |
|||
.then(data => { |
|||
!remote && fn(null, data); |
|||
}) |
|||
.catch(err => !remote && fn(err)); |
|||
|
|||
waitTokenRequest(() => { |
|||
// 拿到api数据后 再用api的数据
|
|||
uni.$u.api |
|||
.getOtherPlugin(params) |
|||
.then(data => { |
|||
remote = true; |
|||
fn(null, data); |
|||
// 存api到cache里
|
|||
uni.$t.cache.putPlugin(params.pluginId, data); |
|||
}) |
|||
.catch(err => fn(err)); |
|||
}); |
|||
}, |
|||
}; |
@ -0,0 +1,118 @@ |
|||
const install = (Vue, vm) => { |
|||
Vue.prototype.$u.http.setConfig({ |
|||
baseUrl: '', |
|||
showLoading: true, // 是否显示请求中的loading
|
|||
loadingText: '玩命加载中...', |
|||
loadingTime: 800, |
|||
loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
|
|||
// 配置请求头信息
|
|||
header: { |
|||
'content-type': 'application/json;charset=UTF-8' |
|||
}, |
|||
}); |
|||
|
|||
// 请求拦截部分,如配置,每次请求前都会执行
|
|||
Vue.prototype.$u.http.interceptor.request = config => { |
|||
const token = vm.$store.state.user.token || uni.$t.storage.getStorageSync(uni.$t.app.tokenKey); |
|||
if (token) { |
|||
config.header.Authorization = `Bearer ${token}`; |
|||
} |
|||
|
|||
return config; |
|||
}; |
|||
|
|||
// 响应拦截,如配置,每次请求结束都会执行本方法
|
|||
Vue.prototype.$u.http.interceptor.response = res => { |
|||
if (res.code === 200) { |
|||
// res为服务端返回值,可能有code,result等字段
|
|||
// 这里对res.result进行返回,将会在this.$u.post(url).then(res => {})的then回调中的res的到
|
|||
// 如果配置了originalData为true,请留意这里的返回值
|
|||
return res.data; |
|||
} else if (res.code === 401) { |
|||
// 假设201为token失效,这里跳转登录
|
|||
vm.$u.toast('验证失败,请重新登录'); |
|||
setTimeout(() => { |
|||
// 此为uView的方法,详见路由相关文档
|
|||
vm.$u.route('/pages/user/login'); |
|||
}, 1500); |
|||
return false; |
|||
} else { |
|||
// 如果返回false,则会调用Promise的reject回调,
|
|||
// 并将进入this.$u.post(url).then().catch(res=>{})的catch回调中,res为服务端的返回值
|
|||
return false; |
|||
} |
|||
}; |
|||
|
|||
Vue.prototype.$u.post = (url, param = {}, header = {}) => { |
|||
return Vue.prototype.$u.http.request({ |
|||
url, |
|||
method: 'POST', |
|||
header, |
|||
data: { |
|||
param |
|||
}, |
|||
}); |
|||
}; |
|||
}; |
|||
|
|||
export default { |
|||
install |
|||
}; |
|||
|
|||
|
|||
// export function setupHttp(app) {
|
|||
// app.config.globalProperties.$u.http.setConfig({
|
|||
// baseUrl: '',
|
|||
// showLoading: true, // 是否显示请求中的loading
|
|||
// loadingText: '玩命加载中...',
|
|||
// loadingTime: 800,
|
|||
// loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
|
|||
// // 配置请求头信息
|
|||
// header: {
|
|||
// 'content-type': 'application/json;charset=UTF-8'
|
|||
// },
|
|||
// });
|
|||
|
|||
// // 请求拦截部分,如配置,每次请求前都会执行
|
|||
// app.config.globalProperties.$u.http.interceptor.request = config => {
|
|||
// const token = vm.$store.state.user.token || uni.$t.storage.getStorageSync(uni.$t.app.tokenKey);
|
|||
// if (token) {
|
|||
// config.header.Authorization = `Bearer ${token}`;
|
|||
// }
|
|||
|
|||
// return config;
|
|||
// };
|
|||
|
|||
// // 响应拦截,如配置,每次请求结束都会执行本方法
|
|||
// app.config.globalProperties.$u.http.interceptor.response = res => {
|
|||
// if (res.code === 200) {
|
|||
// // res为服务端返回值,可能有code,result等字段
|
|||
// // 这里对res.result进行返回,将会在this.$u.post(url).then(res => {})的then回调中的res的到
|
|||
// // 如果配置了originalData为true,请留意这里的返回值
|
|||
// return res.data;
|
|||
// } else if (res.code === 401) {
|
|||
// // 假设201为token失效,这里跳转登录
|
|||
// vm.$u.toast('验证失败,请重新登录');
|
|||
// setTimeout(() => {
|
|||
// // 此为uView的方法,详见路由相关文档
|
|||
// vm.$u.route('/pages/user/login');
|
|||
// }, 1500);
|
|||
// return false;
|
|||
// } else {
|
|||
// // 如果返回false,则会调用Promise的reject回调,
|
|||
// // 并将进入this.$u.post(url).then().catch(res=>{})的catch回调中,res为服务端的返回值
|
|||
// return false;
|
|||
// }
|
|||
// };
|
|||
|
|||
// app.config.globalProperties.$u.post = (url, param = {}, header = {}) => {
|
|||
// return app.config.globalProperties.$u.http.request({
|
|||
// url,
|
|||
// method: 'POST',
|
|||
// header,
|
|||
// data: {
|
|||
// param
|
|||
// },
|
|||
// });
|
|||
// };
|
|||
// }
|
@ -0,0 +1,112 @@ |
|||
export default { |
|||
/** |
|||
* 设置本地存储 同步 |
|||
* @param {string} key |
|||
* @param {*} data |
|||
*/ |
|||
setStorageSync(key, data) { |
|||
const value = typeof data === 'string' ? data : JSON.stringify(data); |
|||
uni.setStorageSync(key, value); |
|||
}, |
|||
|
|||
/** |
|||
* 获取本地存储的信息 根据key |
|||
* @param {string} key |
|||
* @return {string} |
|||
*/ |
|||
getStorageSync(key) { |
|||
return uni.getStorageSync(key); |
|||
}, |
|||
|
|||
/** |
|||
* 根据key移除某条数据 同步 |
|||
* @param {string} key |
|||
*/ |
|||
removeStorageSync(key) { |
|||
uni.removeStorageSync(key); |
|||
}, |
|||
|
|||
/** |
|||
* 清楚全部数据 同步 |
|||
*/ |
|||
clearStorageSync() { |
|||
uni.clearStorageSync(); |
|||
}, |
|||
|
|||
/** |
|||
* 设置本地存储 异步 |
|||
* @param {string} key |
|||
* @param {*} data |
|||
*/ |
|||
setStorage(key, data) { |
|||
uni.$t.storage.checkCapacity(); |
|||
return new Promise((resolve, reject) => { |
|||
const value = typeof data === 'string' ? data : JSON.stringify(data); |
|||
uni.setStorage({ |
|||
key, |
|||
data: value, |
|||
success() { |
|||
resolve(`数据${key}存储成功`); |
|||
}, |
|||
fail() { |
|||
reject(`数据${key}存储失败`); |
|||
}, |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 获取本地存储的信息 根据key 异步 |
|||
* @param {string} key |
|||
* @return {string} |
|||
*/ |
|||
getStorage(key) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.getStorage({ |
|||
key, |
|||
success(res) { |
|||
resolve(res.data); |
|||
}, |
|||
fail(error) { |
|||
reject(`数据${key}获取失败, error: ${error.errMsg}`); |
|||
}, |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 根据key移除某条数据 异步 |
|||
* @param {string} key |
|||
*/ |
|||
removeStorage(key) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.removeStorage({ |
|||
key, |
|||
success(res) { |
|||
resolve(res); |
|||
}, |
|||
fail(error) { |
|||
reject(`数据${key}删除失败, error: ${error}`); |
|||
}, |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 清楚全部数据 异步 |
|||
*/ |
|||
clearStorage() { |
|||
uni.clearStorage(); |
|||
}, |
|||
|
|||
// 检测local Storage容量 超出容量清空数据缓存
|
|||
checkCapacity() { |
|||
/* #ifdef H5 */ |
|||
const capacity = JSON.stringify(localStorage).length; |
|||
let max = 1024 * 1024 * 4; |
|||
if (capacity >= max) { |
|||
uni.$t.storage.clearStorage(); |
|||
} |
|||
/* #endif */ |
|||
}, |
|||
}; |
@ -0,0 +1,34 @@ |
|||
import app from '@/config/app.js'; |
|||
import cache from '@/utils/cache.js'; |
|||
import cacheAndRequest from '@/utils/cacheAndRequest.js'; |
|||
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 user from '@/config/user.js'; |
|||
import zIndex from '@/config/zIndex.js'; |
|||
|
|||
const gateway = process.env.VUE_APP_API_URL; |
|||
|
|||
const $t = { |
|||
zIndex, // 定位元素层级
|
|||
app, // app级别的相关配置
|
|||
storage, // 本地存储storage封装
|
|||
time, // 时间处理
|
|||
ui, // ui界面提示相关
|
|||
chooseAndUpload: upload.chooseAndUpload, // 选择并上传单个文件相关的封装
|
|||
domain: `${gateway}/defaultwbs`, |
|||
cache, // 本地存储相关
|
|||
$q: cacheAndRequest, |
|||
user, // 用户相关配置
|
|||
}; |
|||
|
|||
uni.$t = $t; |
|||
|
|||
const install = Vue => { |
|||
Vue.prototype.$t = $t; |
|||
}; |
|||
|
|||
export default { |
|||
install |
|||
}; |
@ -0,0 +1,366 @@ |
|||
import dayjs from 'dayjs'; |
|||
|
|||
const advancedFormat = require('dayjs/plugin/advancedFormat'); |
|||
const weekOfYear = require('dayjs/plugin/weekOfYear'); |
|||
const duration = require('dayjs/plugin/duration'); |
|||
|
|||
dayjs.extend(advancedFormat); |
|||
dayjs.extend(weekOfYear); |
|||
dayjs.extend(duration); |
|||
|
|||
/** |
|||
* 格式化数字 |
|||
* @param {*} n |
|||
*/ |
|||
const formatNumber = n => { |
|||
const str = n.toString(); |
|||
return str[1] ? str : `0${str}`; |
|||
}; |
|||
|
|||
/** |
|||
* 格式化时间 |
|||
* @param {number} beginTime |
|||
*/ |
|||
const formatTime = beginTime => { |
|||
const date = new Date(beginTime); |
|||
const year = date.getFullYear(); |
|||
const month = date.getMonth() + 1; |
|||
const day = date.getDate(); |
|||
const hour = date.getHours(); |
|||
const minute = date.getMinutes(); |
|||
const second = date.getSeconds(); |
|||
|
|||
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`; |
|||
}; |
|||
|
|||
/** |
|||
* 添加一定时间的时长 |
|||
* @param {number | date} time |
|||
* @param {number} num |
|||
* @param {string} cycle |
|||
*/ |
|||
const add = (time, num, cycle) => { |
|||
const str = dayjs(time).add(num, cycle); |
|||
return str; |
|||
}; |
|||
|
|||
/** |
|||
* 时间转换 08:00 转换成8小时0分钟 |
|||
* @param {string} time |
|||
* @returns {{hours: number, minutes: number}} |
|||
*/ |
|||
const convertTime = time => { |
|||
const arr = time.split(':'); |
|||
return { |
|||
hours: parseInt(arr[0], 10), |
|||
minutes: parseInt(arr[1], 10), |
|||
}; |
|||
}; |
|||
|
|||
/** |
|||
* 将秒 -> 分 秒 |
|||
* @param {number} seconds |
|||
*/ |
|||
const secondToMinute = seconds => { |
|||
const minute = formatNumber(Math.floor(seconds / 60)); |
|||
const second = formatNumber(parseInt(seconds % 60, 10)); |
|||
return { |
|||
minute, |
|||
second, |
|||
}; |
|||
}; |
|||
|
|||
/** |
|||
* 将时间戳 -> 时:分 |
|||
* @param {Number} timestamp 时间戳 |
|||
* @return date:2018/10/09 time: 12:59 |
|||
*/ |
|||
const setTimestampToStr = timestamp => { |
|||
const timeObj = new Date(timestamp); |
|||
const year = timeObj.getFullYear(); |
|||
const month = formatNumber(timeObj.getMonth() + 1); |
|||
const day = formatNumber(timeObj.getDate()); |
|||
const hour = formatNumber(timeObj.getHours()); |
|||
const minute = formatNumber(timeObj.getMinutes()); |
|||
const date = `${year}-${month}-${day}`; |
|||
const time = `${hour}:${minute}`; |
|||
return { |
|||
date, |
|||
time, |
|||
}; |
|||
}; |
|||
|
|||
/** |
|||
* 检测时间(ms)是不是今天 |
|||
* @param {Number} time 时间戳 |
|||
*/ |
|||
const validateTimeIsToday = time => { |
|||
const timeDate = new Date(time); |
|||
const date = new Date(); |
|||
return timeDate.getFullYear() === date.getFullYear() && timeDate.getMonth() === date.getMonth() && timeDate.getDate() === date.getDate(); |
|||
}; |
|||
|
|||
/** |
|||
* 检测两个日期是否相同 |
|||
* @param {number | date} time |
|||
* @param {number | date} value |
|||
* @param {string} cycle 传入 day 将会比较 day、 month和 year |
|||
*/ |
|||
const isSame = (time, value, cycle) => { |
|||
const str = dayjs(time).isSame(value, cycle); |
|||
return str; |
|||
}; |
|||
|
|||
/** |
|||
* 格式化开始时间 |
|||
* @param {Number} timestamp 时间戳 |
|||
* @return |
|||
* 如果是今天 -> 时:分 |
|||
* 如果不是今年 -> 年/月/日 时:分 |
|||
* 否则 *月*日 时:分 |
|||
*/ |
|||
const formatBeginTime = timestamp => { |
|||
const timeObj = new Date(timestamp); |
|||
const year = timeObj.getFullYear(); |
|||
const month = formatNumber(timeObj.getMonth() + 1); |
|||
const day = formatNumber(timeObj.getDate()); |
|||
const hour = formatNumber(timeObj.getHours()); |
|||
const minute = formatNumber(timeObj.getMinutes()); |
|||
const date = `${year}/${month}/${day}`; |
|||
const time = `${hour}:${minute}`; |
|||
const currentYear = new Date().getFullYear(); |
|||
|
|||
if (validateTimeIsToday(timestamp)) { |
|||
// 今天
|
|||
return `今天 ${time}`; |
|||
} else if (currentYear !== year) { |
|||
// 不是今年
|
|||
return `${date} ${time}`; |
|||
} else { |
|||
return `${month}月${day}日 ${time}`; |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* 格式化时长 |
|||
* @param {Number} duration 时长 |
|||
* 超过24小时( 24 * 60 * 60 * 1000 ms) 转换成天数 + 小时 + 分钟 |
|||
* 小于1分钟( 60 * 1000 ms) 转换成秒钟 |
|||
* 其余的显示分钟 |
|||
* 超过2小时( 2 * 60 * 60 * 1000 ms) 转换成小时 + 分钟数 |
|||
*/ |
|||
const formatDuration = duration => { |
|||
const minuteTime = 60 * 1000; |
|||
const hourTime = 60 * minuteTime; |
|||
const dayTime = 24 * hourTime; |
|||
const days = Math.floor(duration / dayTime); |
|||
const hours = Math.floor((duration % dayTime) / hourTime); |
|||
const minutes = Math.floor((duration % hourTime) / minuteTime); |
|||
if (duration <= 60 * 1000) { |
|||
// 小于1分钟 返回几秒
|
|||
return `${Math.floor(duration / 1000)}秒`; |
|||
} else if (duration > dayTime) { |
|||
// 大于1天
|
|||
if (minutes === 0) { |
|||
if (hours === 0) { |
|||
// 分钟数是0 和 小时数是0 返回 几天
|
|||
return `${days}天`; |
|||
} else { |
|||
// 分钟是0 小时不是0 返回 几天几小时
|
|||
return `${days}天${hours}小时`; |
|||
} |
|||
} else { |
|||
// 分钟不是0 返回几天几时几分
|
|||
return `${days}天${hours}时${minutes}分`; |
|||
} |
|||
} else if (duration > 2 * hourTime) { |
|||
// 大于2h
|
|||
if (minutes === 0) { |
|||
// 分钟是0 返回几小时
|
|||
return `${hours}小时`; |
|||
} else { |
|||
// 分钟不是0 返回几小时几分钟
|
|||
return `${hours}小时${minutes}分钟`; |
|||
} |
|||
} else { |
|||
// 其余情况 返回 几分钟
|
|||
return `${parseInt(duration / minuteTime)}分钟`; |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* 格式化时长 转换成对象格式 |
|||
* @param {Number} duration 时长 |
|||
* 超过24小时( 24 * 60 * 60 * 1000 ms) 转换成{days, hours, minutes, seconds: 0} |
|||
* 小于1分钟( 60 * 1000 ms) 转换成秒钟 { days: 0, hours: 0, minutes: 0, seconds } |
|||
* 其余的显示分钟 { days: 0, hours: 0, minutes, seconds: 0 } |
|||
* 超过2小时( 2 * 60 * 60 * 1000 ms) 转换成{ days: 0, hours, minutes, seconds: 0 } |
|||
*/ |
|||
const formatDurationToObject = duration => { |
|||
const minuteTime = 60 * 1000; |
|||
const hourTime = 60 * minuteTime; |
|||
const dayTime = 24 * hourTime; |
|||
const days = Math.floor(duration / dayTime); |
|||
const hours = Math.floor((duration % dayTime) / hourTime); |
|||
const minutes = Math.floor((duration % hourTime) / minuteTime); |
|||
const result = { |
|||
days: 0, |
|||
hours: 0, |
|||
minutes: 0, |
|||
seconds: 0, |
|||
}; |
|||
if (duration <= 60 * 1000) { |
|||
// 小于1分钟 返回几秒
|
|||
result.seconds = Math.floor(duration / 1000); |
|||
} else if (duration > dayTime) { |
|||
// 大于1天
|
|||
if (minutes === 0) { |
|||
if (hours === 0) { |
|||
// 分钟数是0 和 小时数是0 返回 几天
|
|||
result.days = days; |
|||
} else { |
|||
// 分钟是0 小时不是0 返回 几天几小时
|
|||
result.days = days; |
|||
result.hours = hours; |
|||
} |
|||
} else { |
|||
// 分钟不是0 返回几天几时几分
|
|||
result.days = days; |
|||
result.hours = hours; |
|||
result.minutes = minutes; |
|||
} |
|||
} else if (duration > 2 * hourTime) { |
|||
// 大于2h
|
|||
if (minutes === 0) { |
|||
// 分钟是0 返回几小时
|
|||
result.hours = hours; |
|||
} else { |
|||
// 分钟不是0 返回几小时几分钟
|
|||
result.hours = hours; |
|||
result.minutes = minutes; |
|||
} |
|||
} else { |
|||
// 其余情况 返回 几分钟
|
|||
result.minutes = minutes; |
|||
} |
|||
return result; |
|||
}; |
|||
|
|||
/** |
|||
* 将对象格式的时间转换成时间戳 |
|||
* @param {obj} 对象格式的时间 days, hours, minutes, seconds |
|||
* @return 时长的ms |
|||
*/ |
|||
const formatObjectTimeToMs = (days = 0, hours = 0, minutes = 0, seconds = 0) => { |
|||
return days * 24 * 60 * 60 * 1000 + hours * 60 * 60 * 1000 + minutes * 60 * 1000 + seconds * 1000; |
|||
}; |
|||
|
|||
/** |
|||
* 计算过滤 周期 |
|||
* @param {string} time 周期字符串 |
|||
* @return {string} cycle 周期英文字符串 |
|||
*/ |
|||
const computeCycle = time => { |
|||
// 加载下一个周期的任务
|
|||
let cycle = 'day'; |
|||
switch (time) { |
|||
case '天': |
|||
cycle = 'day'; |
|||
break; |
|||
case '周': |
|||
cycle = 'week'; |
|||
break; |
|||
case '月': |
|||
cycle = 'month'; |
|||
break; |
|||
default: |
|||
cycle = '日程'; |
|||
break; |
|||
} |
|||
return cycle; |
|||
}; |
|||
|
|||
/** |
|||
* 将时间按周期语义化 |
|||
* @param {string} cycle 周期 |
|||
* @param {number|string} time 时间 |
|||
*/ |
|||
const formatStartTimeToCycleTime = (cycle, time) => { |
|||
let result = ''; |
|||
const _time = dayjs(+time); |
|||
switch (cycle) { |
|||
case '天': |
|||
result = _time.format('YYYY年M月D日'); |
|||
break; |
|||
case '周': |
|||
result = _time.format('YYYY年w周'); |
|||
break; |
|||
case '月': |
|||
result = _time.format('YYYY年M月'); |
|||
break; |
|||
case '日程': |
|||
result = _time.format('YYYY年M月D日 HH:mm'); |
|||
break; |
|||
default: |
|||
result = _time.format('YYYY年M月D日'); |
|||
break; |
|||
} |
|||
return result; |
|||
}; |
|||
|
|||
/** |
|||
* 计算进行中状态剩余时间 显示数字 |
|||
* @param {number} leftTime 剩余时间ms |
|||
* @returns { num: 显示的数字, time: 演示器演示时长 } |
|||
*/ |
|||
const computeDurationText = leftTime => { |
|||
try { |
|||
if (leftTime < 0) return { num: 0, time: null }; |
|||
const { years, months, days, hours, minutes, seconds, milliseconds } = dayjs.duration(leftTime).$d; |
|||
let num = 0; |
|||
let time = 1000; |
|||
|
|||
if (years > 0) { |
|||
num = years; |
|||
time = 60 * 60 * 1000; // 按小时
|
|||
} else if (months > 0) { |
|||
num = months; |
|||
time = 60 * 60 * 1000; // 按小时
|
|||
} else if (days > 0) { |
|||
num = days; |
|||
time = 60 * 60 * 1000; // 按小时
|
|||
} else if (hours > 0) { |
|||
num = hours; |
|||
} else if (minutes > 0) { |
|||
num = minutes; |
|||
} else if (seconds > 0) { |
|||
num = seconds; |
|||
} else if (milliseconds > 0) { |
|||
num = milliseconds; |
|||
time = 16; |
|||
} else { |
|||
time = null; |
|||
} |
|||
return { num, time }; |
|||
} catch (error) { |
|||
console.log('🚀 ~ file: time.js ~ line 335 ~ computeDurationText ~ error', error); |
|||
return { num: 0, time: null }; |
|||
} |
|||
}; |
|||
|
|||
export default { |
|||
formatNumber, |
|||
formatTime, |
|||
add, |
|||
convertTime, |
|||
secondToMinute, |
|||
setTimestampToStr, |
|||
isSame, |
|||
formatBeginTime, |
|||
formatDuration, |
|||
formatDurationToObject, |
|||
formatObjectTimeToMs, |
|||
computeCycle, |
|||
formatStartTimeToCycleTime, |
|||
computeDurationText, |
|||
}; |
@ -0,0 +1,59 @@ |
|||
export default { |
|||
/** |
|||
* 显示toast |
|||
* @param {string} title 提示内容 |
|||
* @param {number} duration 显示时间 默认2000 |
|||
*/ |
|||
showToast(title, duration = 2000) { |
|||
return uni.showToast({ |
|||
title, |
|||
icon: 'none', |
|||
duration, |
|||
mask: true, |
|||
}); |
|||
}, |
|||
|
|||
// 隐藏toast
|
|||
hideToast() { |
|||
return uni.hideToast(); |
|||
}, |
|||
|
|||
/** |
|||
* 显示加载雪花 |
|||
* @param {string} title |
|||
*/ |
|||
showLoading(title = '玩命加载中...') { |
|||
return uni.showLoading({ |
|||
title, |
|||
mask: true, |
|||
}); |
|||
}, |
|||
|
|||
// 隐藏loading
|
|||
hideLoading() { |
|||
return uni.hideLoading(); |
|||
}, |
|||
|
|||
/** |
|||
* 显示modal弹出框 |
|||
* @param {string} title 标题 |
|||
* @param {string} content 内容 |
|||
* @param {boolean} showCancel 是否显示取消按钮 默认true |
|||
*/ |
|||
showModal(title, content, showCancel = true) { |
|||
return new Promise(function(resolve, reject) { |
|||
uni.showModal({ |
|||
title, |
|||
content, |
|||
showCancel, |
|||
success: ({ |
|||
confirm, |
|||
cancel |
|||
}) => { |
|||
confirm && resolve(); |
|||
cancel && reject(); |
|||
}, |
|||
}); |
|||
}); |
|||
}, |
|||
}; |
@ -0,0 +1,110 @@ |
|||
// H5选择文件
|
|||
const chooseFileH5 = (extension = ['.xls', '.xlsx']) => { |
|||
return new Promise((resolve, reject) => { |
|||
uni.chooseFile({ |
|||
count: 1, //默认100
|
|||
extension, |
|||
success(res) { |
|||
resolve(res.tempFilePaths[0]); |
|||
}, |
|||
fail() { |
|||
reject('上传失败'); |
|||
}, |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
// 微信选择文件 从客户端会话选择文件。
|
|||
const chooseFileWeixin = (extension = ['.xls', '.xlsx']) => { |
|||
return new Promise((resolve, reject) => { |
|||
wx.chooseMessageFile({ |
|||
count: 1, |
|||
extension, |
|||
type: 'file', |
|||
success(res) { |
|||
resolve(res.tempFiles[0].path); |
|||
}, |
|||
fail() { |
|||
reject('上传失败'); |
|||
}, |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
// 选择文件
|
|||
const chooseFile = (extension = ['.xls', '.xlsx']) => { |
|||
let fn = null; |
|||
/* #ifdef H5 */ |
|||
fn = chooseFileH5(extension); |
|||
/* #endif */ |
|||
|
|||
/* #ifdef MP-WEIXIN */ |
|||
fn = chooseFileWeixin(extension); |
|||
/* #endif */ |
|||
return fn; |
|||
}; |
|||
|
|||
export default { |
|||
/** |
|||
* 上传单个文件 |
|||
* @param {string} url 服务器地址 |
|||
* @param {object} formData 上传的其他字段 |
|||
* @param {array} extension 上传文件类型 扩展名数组 |
|||
* @param {string} name |
|||
* @returns |
|||
*/ |
|||
chooseAndUpload(url, formData = {}, extension = ['.xls', '.xlsx'], name = 'param') { |
|||
uni.hideLoading(); |
|||
clearTimeout(timer); |
|||
let timer = null; |
|||
return new Promise((resolve, reject) => { |
|||
const token = uni.$t.storage.getStorageSync(uni.$t.app.tokenKey); |
|||
if (!token) { |
|||
return reject('用户未登录,请登录后重试'); |
|||
} |
|||
chooseFile(extension) |
|||
.then(filePath => { |
|||
console.log('filePath: ', filePath); |
|||
if (!timer) { |
|||
timer = setTimeout(() => { |
|||
uni.$t.ui.showLoading('正在上传...'); |
|||
timer = null; |
|||
}, 800); |
|||
} |
|||
// 开始上传
|
|||
uni.uploadFile({ |
|||
url, |
|||
filePath, |
|||
name, |
|||
formData, |
|||
header: { Authorization: `Bearer ${token}` }, |
|||
success: ({ data, statusCode }) => { |
|||
clearTimeout(timer); |
|||
uni.hideLoading(); |
|||
|
|||
if (statusCode === 200 && data) { |
|||
const { code, msg } = JSON.parse(data); |
|||
if (code !== 200) { |
|||
reject(msg); |
|||
} else { |
|||
resolve(JSON.parse(data).data); |
|||
} |
|||
} else { |
|||
reject('上传失败'); |
|||
} |
|||
}, |
|||
fail: error => { |
|||
clearTimeout(timer); |
|||
uni.hideLoading(); |
|||
reject(error); |
|||
}, |
|||
}); |
|||
}) |
|||
.catch(error => { |
|||
clearTimeout(timer); |
|||
uni.hideLoading(); |
|||
reject(error); |
|||
}); |
|||
}); |
|||
}, |
|||
}; |
Loading…
Reference in new issue