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);
}
/**
* @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. 搜索消息位置
*

View File

@ -3,9 +3,9 @@
<PageTitle :title="$L('项目')"/>
<div class="list-search">
<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">
<Loading v-if="loadProjects"/>
<Loading v-if="loadProjects > 0"/>
<Icon v-else type="ios-search" />
</div>
</Input>
@ -141,7 +141,6 @@ export default {
keys: {
name: this.projectKeyValue
},
hideload: true,
}).finally(_ => {
this.projectKeyLoading--;
});

View File

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

View File

@ -14,6 +14,20 @@ export default {
return new Promise(async resolve => {
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.cacheServerUrl = await $A.IDBString("cacheServerUrl")
@ -54,21 +68,6 @@ export default {
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
dispatch("call", {
url: "users/key/client",
@ -543,7 +542,7 @@ export default {
window.__getBasicDataKey = tmpKey
//
dispatch("getProjects").catch(() => {});
dispatch("getDialogs").catch(() => {});
dispatch("getDialogAuto").catch(() => {});
dispatch("getDialogTodo", 0).catch(() => {});
dispatch("getReportUnread", 1000);
dispatch("getApproveUnread", 1000);
@ -845,20 +844,12 @@ export default {
* 清除缓存
* @param state
* @param dispatch
* @param userInfo
* @param userData
* @returns {Promise<unknown>}
*/
handleClearCache({state, dispatch}, userInfo) {
handleClearCache({state, dispatch}, userData) {
return new Promise(async resolve => {
try {
// state
state.cacheUserBasic = [];
state.cacheDialogs = [];
state.cacheProjects = [];
state.cacheColumns = [];
state.cacheTasks = [];
state.callAt = [];
// localStorage
const languageType = window.localStorage.getItem("__language:type__");
const keyboardData = window.localStorage.getItem("__keyboard:data__");
@ -869,19 +860,26 @@ export default {
window.localStorage.setItem("__theme:mode__", themeMode)
// 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 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.IDBSet("clientId", state.clientId);
await $A.IDBSet("cacheServerUrl", state.cacheServerUrl);
await $A.IDBSet("cacheProjectParameter", state.cacheProjectParameter);
await $A.IDBSet("clientId", clientId);
await $A.IDBSet("cacheServerUrl", cacheServerUrl);
await $A.IDBSet("cacheProjectParameter", cacheProjectParameter);
await $A.IDBSet("cacheLoginEmail", cacheLoginEmail);
await $A.IDBSet("cacheFileSort", cacheFileSort);
await $A.IDBSet("cacheTaskBrowse", state.cacheTaskBrowse);
await $A.IDBSet("cacheEmojis", state.cacheEmojis);
await $A.IDBSet("cacheTaskBrowse", cacheTaskBrowse);
await $A.IDBSet("cacheEmojis", cacheEmojis);
await $A.IDBSet("cacheVersion", state.cacheVersion)
// userInfo
dispatch("saveUserInfoBase", $A.isJson(userInfo) ? userInfo : state.userInfo).then(resolve);
dispatch("saveUserInfoBase", $A.isJson(userData) ? userData : userInfo).then(resolve);
} catch (e) {
resolve()
}
@ -1111,7 +1109,9 @@ export default {
}
const callData = $callData('projects', requestData, state)
//
callData.showLoad() && state.loadProjects++;
setTimeout(() => {
state.loadProjects++;
}, 2000)
dispatch("call", {
url: 'project/lists',
data: callData.get()
@ -1125,7 +1125,7 @@ export default {
console.warn(e);
reject(e)
}).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
@ -2408,7 +2436,6 @@ export default {
}
const callData = $callData('dialogs', requestData, state)
//
callData.showLoad() && state.loadDialogs++;
dispatch("call", {
url: 'dialog/lists',
data: callData.get()
@ -2426,8 +2453,6 @@ export default {
}).catch(e => {
console.warn(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

View File

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

View File

@ -11,7 +11,6 @@ function __callData(key, requestData, state) {
const callKey = key + "::" + encodeURIComponent(new URLSearchParams($.sortObject(requestData, [
'page',
'pagesize',
'hideload',
'timerange',
])).toString())
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
}