perf: 优化缓存数据

This commit is contained in:
kuaifan 2023-12-28 17:44:17 +08:00
parent 8a7e80fe86
commit ccb31a81f8
6 changed files with 172 additions and 52 deletions

View File

@ -544,6 +544,47 @@ class DialogController extends AbstractController
return Base::retSuccess('success', $data); return Base::retSuccess('success', $data);
} }
/**
* @api {get} api/dialog/msg/latest 11. 获取最新消息列表
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName msg__latest
*
* @apiParam {Number} [latest_id] 此消息ID之后的数据
*
* @apiParam {Number} [page] 当前页,默认:1
* @apiParam {Number} [pagesize] 每页显示数量,默认:50,最大:100
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function msg__latest()
{
$user = User::auth();
//
$latest_id = intval(Request::input('latest_id'));
//
$builder = WebSocketDialogMsg::select([
'web_socket_dialog_msgs.*',
'read.mention',
'read.read_at',
])->join('web_socket_dialog_msg_reads as read', 'read.msg_id', '=', 'web_socket_dialog_msgs.id')
->where('read.userid', $user->userid);
//
if ($latest_id > 0) {
$builder->where('read.msg_id', '>', $latest_id);
}
//
$data = $builder->orderByDesc('read.msg_id')->paginate(Base::getPaginate(100, 50));
if ($data->isEmpty()) {
return Base::retError('empty');
}
return Base::retSuccess('success', $data);
}
/** /**
* @api {get} api/dialog/msg/search 12. 搜索消息位置 * @api {get} api/dialog/msg/search 12. 搜索消息位置
* *

View File

@ -3,9 +3,9 @@
<PageTitle :title="$L('项目')"/> <PageTitle :title="$L('项目')"/>
<div class="list-search"> <div class="list-search">
<div class="search-wrapper"> <div class="search-wrapper">
<Input v-model="projectKeyValue" :placeholder="$L(loadProjects ? '更新中...' : '搜索项目')" clearable> <Input v-model="projectKeyValue" :placeholder="$L(loadProjects > 0 ? '更新中...' : '搜索项目')" clearable>
<div class="search-pre" slot="prefix"> <div class="search-pre" slot="prefix">
<Loading v-if="loadProjects"/> <Loading v-if="loadProjects > 0"/>
<Icon v-else type="ios-search" /> <Icon v-else type="ios-search" />
</div> </div>
</Input> </Input>
@ -141,7 +141,6 @@ export default {
keys: { keys: {
name: this.projectKeyValue name: this.projectKeyValue
}, },
hideload: true,
}).finally(_ => { }).finally(_ => {
this.projectKeyLoading--; this.projectKeyLoading--;
}); });

View File

@ -9,11 +9,11 @@
v-if="tabActive==='dialog'" v-if="tabActive==='dialog'"
v-model="dialogSearchKey" v-model="dialogSearchKey"
ref="searchInput" ref="searchInput"
:placeholder="$L(loadDialogs ? '更新中...' : '搜索消息')" :placeholder="$L(loadDialogs > 0 ? '更新中...' : '搜索消息')"
@on-keydown="onKeydown" @on-keydown="onKeydown"
clearable> clearable>
<div class="search-pre" slot="prefix"> <div class="search-pre" slot="prefix">
<Loading v-if="loadDialogs || dialogSearchLoad > 0"/> <Loading v-if="loadDialogs > 0 || dialogSearchLoad > 0"/>
<Icon v-else type="ios-search" /> <Icon v-else type="ios-search" />
</div> </div>
</Input> </Input>
@ -225,6 +225,7 @@ export default {
directives: {longpress}, directives: {longpress},
data() { data() {
return { return {
firstLoad: true,
activeNum: 0, activeNum: 0,
tabActive: 'dialog', tabActive: 'dialog',
@ -286,7 +287,9 @@ export default {
}, },
activated() { activated() {
this.updateDialogs(1000); this.updateDialogs(this.firstLoad ? 0 : 1000);
this.firstLoad = false;
//
this.$nextTick(_ => this.activeNum++) this.$nextTick(_ => this.activeNum++)
// //
if ($A.isEEUiApp) { if ($A.isEEUiApp) {
@ -1039,7 +1042,7 @@ export default {
if (timeout > -1) { if (timeout > -1) {
this.__updateDialogs = setTimeout(_ => { this.__updateDialogs = setTimeout(_ => {
if (this.tabActive === 'dialog') { if (this.tabActive === 'dialog') {
this.$store.dispatch("getDialogs", {hideload: true}).catch(() => {}); this.$store.dispatch("getDialogAuto").catch(() => {});
} }
}, timeout) }, timeout)
} }

View File

@ -14,6 +14,20 @@ export default {
return new Promise(async resolve => { return new Promise(async resolve => {
let action = null let action = null
// 清理缓存
const clearCache = await $A.IDBString("clearCache")
if (clearCache) {
if (clearCache === "handle") {
action = "handleClearCache"
}
await $A.IDBRemove("clearCache")
await $A.IDBRemove("cacheVersion")
}
const cacheVersion = await $A.IDBString("cacheVersion")
if (cacheVersion !== state.cacheVersion) {
await dispatch("handleClearCache")
}
// 读取缓存 // 读取缓存
state.clientId = await $A.IDBString("clientId") state.clientId = await $A.IDBString("clientId")
state.cacheServerUrl = await $A.IDBString("cacheServerUrl") state.cacheServerUrl = await $A.IDBString("cacheServerUrl")
@ -54,21 +68,6 @@ export default {
await $A.IDBSet("clientId", state.clientId) await $A.IDBSet("clientId", state.clientId)
} }
// 清理缓存
const clearCache = await $A.IDBString("clearCache")
if (clearCache) {
if (clearCache === "handle") {
action = "handleClearCache"
}
await $A.IDBRemove("clearCache")
await $A.IDBRemove("cacheVersion")
}
const cacheVersion = await $A.IDBString("cacheVersion")
if (cacheVersion !== "v2") {
await dispatch("handleClearCache")
await $A.IDBSet("cacheVersion", "v2")
}
// 获取apiKey // 获取apiKey
dispatch("call", { dispatch("call", {
url: "users/key/client", url: "users/key/client",
@ -543,7 +542,7 @@ export default {
window.__getBasicDataKey = tmpKey window.__getBasicDataKey = tmpKey
// //
dispatch("getProjects").catch(() => {}); dispatch("getProjects").catch(() => {});
dispatch("getDialogs").catch(() => {}); dispatch("getDialogAuto").catch(() => {});
dispatch("getDialogTodo", 0).catch(() => {}); dispatch("getDialogTodo", 0).catch(() => {});
dispatch("getReportUnread", 1000); dispatch("getReportUnread", 1000);
dispatch("getApproveUnread", 1000); dispatch("getApproveUnread", 1000);
@ -845,20 +844,12 @@ export default {
* 清除缓存 * 清除缓存
* @param state * @param state
* @param dispatch * @param dispatch
* @param userInfo * @param userData
* @returns {Promise<unknown>} * @returns {Promise<unknown>}
*/ */
handleClearCache({state, dispatch}, userInfo) { handleClearCache({state, dispatch}, userData) {
return new Promise(async resolve => { return new Promise(async resolve => {
try { try {
// state
state.cacheUserBasic = [];
state.cacheDialogs = [];
state.cacheProjects = [];
state.cacheColumns = [];
state.cacheTasks = [];
state.callAt = [];
// localStorage // localStorage
const languageType = window.localStorage.getItem("__language:type__"); const languageType = window.localStorage.getItem("__language:type__");
const keyboardData = window.localStorage.getItem("__keyboard:data__"); const keyboardData = window.localStorage.getItem("__keyboard:data__");
@ -869,19 +860,26 @@ export default {
window.localStorage.setItem("__theme:mode__", themeMode) window.localStorage.setItem("__theme:mode__", themeMode)
// localForage // localForage
const clientId = await $A.IDBString("clientId")
const cacheServerUrl = await $A.IDBString("cacheServerUrl")
const cacheProjectParameter = await $A.IDBArray("cacheProjectParameter")
const cacheLoginEmail = await $A.IDBString("cacheLoginEmail"); const cacheLoginEmail = await $A.IDBString("cacheLoginEmail");
const cacheFileSort = await $A.IDBJson("cacheFileSort"); const cacheFileSort = await $A.IDBJson("cacheFileSort");
const cacheTaskBrowse = await $A.IDBArray("cacheTaskBrowse")
const cacheEmojis = await $A.IDBArray("cacheEmojis")
const userInfo = await $A.IDBJson("userInfo")
await $A.IDBClear(); await $A.IDBClear();
await $A.IDBSet("clientId", state.clientId); await $A.IDBSet("clientId", clientId);
await $A.IDBSet("cacheServerUrl", state.cacheServerUrl); await $A.IDBSet("cacheServerUrl", cacheServerUrl);
await $A.IDBSet("cacheProjectParameter", state.cacheProjectParameter); await $A.IDBSet("cacheProjectParameter", cacheProjectParameter);
await $A.IDBSet("cacheLoginEmail", cacheLoginEmail); await $A.IDBSet("cacheLoginEmail", cacheLoginEmail);
await $A.IDBSet("cacheFileSort", cacheFileSort); await $A.IDBSet("cacheFileSort", cacheFileSort);
await $A.IDBSet("cacheTaskBrowse", state.cacheTaskBrowse); await $A.IDBSet("cacheTaskBrowse", cacheTaskBrowse);
await $A.IDBSet("cacheEmojis", state.cacheEmojis); await $A.IDBSet("cacheEmojis", cacheEmojis);
await $A.IDBSet("cacheVersion", state.cacheVersion)
// userInfo // userInfo
dispatch("saveUserInfoBase", $A.isJson(userInfo) ? userInfo : state.userInfo).then(resolve); dispatch("saveUserInfoBase", $A.isJson(userData) ? userData : userInfo).then(resolve);
} catch (e) { } catch (e) {
resolve() resolve()
} }
@ -1111,7 +1109,9 @@ export default {
} }
const callData = $callData('projects', requestData, state) const callData = $callData('projects', requestData, state)
// //
callData.showLoad() && state.loadProjects++; setTimeout(() => {
state.loadProjects++;
}, 2000)
dispatch("call", { dispatch("call", {
url: 'project/lists', url: 'project/lists',
data: callData.get() data: callData.get()
@ -1125,7 +1125,7 @@ export default {
console.warn(e); console.warn(e);
reject(e) reject(e)
}).finally(_ => { }).finally(_ => {
callData.showLoad() && state.loadProjects--; state.loadProjects--;
}); });
}); });
}, },
@ -2382,6 +2382,34 @@ export default {
} }
}, },
/**
* 获取会话列表避免重复获取
* @param state
* @param dispatch
* @returns {Promise<unknown>}
*/
getDialogAuto({state, dispatch}) {
return new Promise(function (resolve, reject) {
if (state.loadDialogAuto) {
reject({msg: 'Loading'});
return
}
setTimeout(_ => {
state.loadDialogs++;
}, 2000)
state.loadDialogAuto = true
dispatch("getDialogs")
.then(resolve)
.catch(reject)
.finally(_ => {
state.loadDialogs--;
state.loadDialogAuto = false
})
//
dispatch("getDialogLatestMsgs").catch(() => {})
})
},
/** /**
* 获取会话列表 * 获取会话列表
* @param state * @param state
@ -2408,7 +2436,6 @@ export default {
} }
const callData = $callData('dialogs', requestData, state) const callData = $callData('dialogs', requestData, state)
// //
callData.showLoad() && state.loadDialogs++;
dispatch("call", { dispatch("call", {
url: 'dialog/lists', url: 'dialog/lists',
data: callData.get() data: callData.get()
@ -2426,8 +2453,6 @@ export default {
}).catch(e => { }).catch(e => {
console.warn(e); console.warn(e);
reject(e) reject(e)
}).finally(_ => {
callData.showLoad() && state.loadDialogs--;
}); });
}); });
}, },
@ -2901,6 +2926,61 @@ export default {
}); });
}, },
/**
* 获取最新消息
* @param state
* @param dispatch
* @param requestData
* @returns {Promise<unknown>}
*/
getDialogLatestMsgs({state, dispatch}, requestData = {}) {
return new Promise(function (resolve, reject) {
if (state.userId === 0) {
reject({msg: 'Parameter error'});
return;
}
if (!$A.isJson(requestData)) {
requestData = {}
}
if (typeof requestData.page === "undefined") {
requestData.page = 1
}
if (typeof requestData.pagesize === "undefined") {
requestData.pagesize = 20
}
if (typeof requestData.latest_id === "undefined") {
requestData.latest_id = state.loadDialogLatestId
}
//
dispatch("call", {
url: 'dialog/msg/latest',
data: requestData,
}).then(({data}) => {
const list = data.data
if (list.length === 0) {
resolve()
return
}
//
const lastId = list[list.length - 1].id;
const lastNotExist = state.dialogMsgs.findIndex(({id}) => id == lastId) === -1
if (requestData.page === 1) {
state.loadDialogLatestId = list[0].id
}
dispatch("saveDialogMsg", list);
//
if (data.next_page_url && data.current_page < 5 && lastNotExist) {
requestData.page++
dispatch("getDialogLatestMsgs", requestData).then(resolve).catch(reject)
} else {
resolve()
}
}).catch(e => {
reject(e)
});
})
},
/** /**
* 发送已阅消息 * 发送已阅消息
* @param state * @param state

View File

@ -6,6 +6,9 @@ export default {
// 客户端ID希望不变的除非清除浏览器缓存或者卸载应用 // 客户端ID希望不变的除非清除浏览器缓存或者卸载应用
clientId: "", clientId: "",
// 缓存版本号(如果想升级后清除客户端缓存则修改此参数值)
cacheVersion: "v3",
// 窗口是否激活 // 窗口是否激活
windowActive: true, windowActive: true,
@ -52,6 +55,8 @@ export default {
loadUserBasic: false, loadUserBasic: false,
loadProjects: 0, loadProjects: 0,
loadDialogs: 0, loadDialogs: 0,
loadDialogAuto: false,
loadDialogLatestId: 0,
floatSpinnerTimer: [], floatSpinnerTimer: [],
floatSpinnerLoad: 0, floatSpinnerLoad: 0,
touchBackInProgress: false, touchBackInProgress: false,

View File

@ -11,7 +11,6 @@ function __callData(key, requestData, state) {
const callKey = key + "::" + encodeURIComponent(new URLSearchParams($.sortObject(requestData, [ const callKey = key + "::" + encodeURIComponent(new URLSearchParams($.sortObject(requestData, [
'page', 'page',
'pagesize', 'pagesize',
'hideload',
'timerange', 'timerange',
])).toString()) ])).toString())
const callData = state.callAt.find(item => item.key === callKey) || {} const callData = state.callAt.find(item => item.key === callKey) || {}
@ -61,13 +60,6 @@ function __callData(key, requestData, state) {
}) })
} }
/**
* @returns {boolean}
*/
this.showLoad = () => {
return !requestData.hideload
}
return this return this
} }