编辑冲突检测 (#351)

This commit is contained in:
王晓聪 2024-07-17 14:00:11 +08:00 committed by GitHub
parent 05414b1386
commit 0db3b22ecf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 51 additions and 49 deletions

View File

@ -70,7 +70,7 @@ export class SurveyHistoryService {
'operator.sessionId': { $ne: sessionId }, 'operator.sessionId': { $ne: sessionId },
}, },
order: { createDate: 'DESC' }, order: { createDate: 'DESC' },
take: 100, take: 1,
select: ['createDate', 'operator', 'type', '_id'], select: ['createDate', 'operator', 'type', '_id'],
}); });

View File

@ -18,6 +18,7 @@ import { onMounted, ref, onUnmounted } from 'vue'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import type { Action } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss' import 'element-plus/theme-chalk/src/message.scss'
import LeftMenu from '@/management/components/LeftMenu.vue' import LeftMenu from '@/management/components/LeftMenu.vue'
@ -31,44 +32,40 @@ const router = useRouter()
const route = useRoute() const route = useRoute()
const authCheckInterval = ref<any>(null) const authCheckInterval = ref<any>(null)
const showConfirmBox = () => { const showConfirmBox = () => {
const token = store.state.user.userInfo.token ElMessageBox.alert('登录状态已失效,请重新登陆。', '提示', {
ElMessageBox.alert('登录状态已失效,请刷新同步。页面将展示最新保存的内容。', '提示', {
confirmButtonText: '确认', confirmButtonText: '确认',
callback: () => { showClose: false,
axios.get('/auth/statuscheck', { callback: (action: Action) => {
headers: { if (action === 'confirm') {
'Authorization': `Bearer ${token}` axios.get('/auth/statuscheck')
} .then((response) => {
}) if (response.data.expired) {
.then((response) => { store.dispatch('user/logout').then(() => {
if (response.data.expired) { router.replace({name: 'login'}); //
store.dispatch('user/logout').then(() => { })
router.replace({name: 'login'}); // } else {
location.reload(); //
}
}) })
} else { .catch((error) => {
location.reload(); // console.log("error: " + error);
store.dispatch('user/logout').then(() => {
router.replace({name: 'login'});
})
});
} }
})
.catch((error) => {
console.log("error: " + error);
ElMessage.error(error.message || '请求失败');
});
} }
}); });
} }
const checkAuth = () => { const checkAuth = () => {
const token = store.state.user.userInfo.token axios.get('/auth/statuscheck').then((response) => {
axios.get('/auth/statuscheck', {
headers: {
'Authorization': `Bearer ${token}`
}
}).then((response) => {
if (response.data.expired) { if (response.data.expired) {
clearInterval(authCheckInterval.value);
authCheckInterval.value = null
showConfirmBox(); showConfirmBox();
} }
}).catch((error) => { }).catch((error) => {
console.log("erro:" + error) console.log("erro:" + error)
ElMessage.error(error)
}); });
} }
onMounted(async () => { onMounted(async () => {
@ -77,6 +74,9 @@ onMounted(async () => {
try { try {
await store.dispatch('edit/init') await store.dispatch('edit/init')
await initShowLogicEngine(store.state.edit.schema.logicConf.showLogicConf || {}) await initShowLogicEngine(store.state.edit.schema.logicConf.showLogicConf || {})
// 30
authCheckInterval.value = setInterval(() => checkAuth(), 1000);
} catch (err: any) { } catch (err: any) {
ElMessage.error(err.message) ElMessage.error(err.message)
@ -84,13 +84,10 @@ onMounted(async () => {
router.replace({ name: 'survey' }) router.replace({ name: 'survey' })
}, 1000) }, 1000)
} }
// 30
authCheckInterval.value = setInterval(() => {
checkAuth()
}, 30 * 60 * 1000);
}) })
onUnmounted(() => { onUnmounted(() => {
clearInterval(authCheckInterval.value); clearInterval(authCheckInterval.value);
authCheckInterval.value = null
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -7,7 +7,7 @@
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox, type Action } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss' import 'element-plus/theme-chalk/src/message.scss'
import { publishSurvey, saveSurvey, getConflictHistory } from '@/management/api/survey' import { publishSurvey, saveSurvey, getConflictHistory } from '@/management/api/survey'
import { showLogicEngine } from '@/management/hooks/useShowLogicEngine' import { showLogicEngine } from '@/management/hooks/useShowLogicEngine'
@ -35,14 +35,12 @@ const updateLogicConf = () => {
const checkConflict = async (surveyid:string) => { const checkConflict = async (surveyid:string) => {
try { try {
const dailyHis = await getConflictHistory({surveyId: surveyid, historyType: 'dailyHis', sessionId: sessionStorage.getItem('sessionUUID')}) const dailyHis = await getConflictHistory({surveyId: surveyid, historyType: 'dailyHis', sessionId: sessionStorage.getItem('sessionUUID')})
console.log(dailyHis)
if (dailyHis.data.length > 0) { if (dailyHis.data.length > 0) {
const lastHis = dailyHis.data.at(0) const lastHis = dailyHis.data.at(0)
if (Date.now() - lastHis.createDate > 2 * 60 * 1000) { if (Date.now() - lastHis.createDate > 2 * 60 * 1000) {
return [false, ''] return [false, '']
} else {
return [true, lastHis.operator.username]
} }
return [true, lastHis.operator.username]
} }
} catch (error) { } catch (error) {
console.log(error) console.log(error)
@ -62,15 +60,19 @@ const onSave = async () => {
if (conflictName == store.state.user.userInfo.username) { if (conflictName == store.state.user.userInfo.username) {
ElMessageBox.alert('当前问卷已在其它页面开启编辑,刷新以获取最新内容。', '提示', { ElMessageBox.alert('当前问卷已在其它页面开启编辑,刷新以获取最新内容。', '提示', {
confirmButtonText: '确认', confirmButtonText: '确认',
callback: () => { callback: (action: Action) => {
location.reload(); if (action === 'confirm') {
store.dispatch('edit/getSchemaFromRemote')
}
} }
}); });
} else { } else {
ElMessageBox.alert(`当前问卷2分钟内由${conflictName}编辑,刷新以获取最新内容。`, '提示', { ElMessageBox.alert(`当前问卷2分钟内由${conflictName}编辑,刷新以获取最新内容。`, '提示', {
confirmButtonText: '确认', confirmButtonText: '确认',
callback: () => { callback: (action: Action) => {
location.reload(); if (action === 'confirm') {
store.dispatch('edit/getSchemaFromRemote')
}
} }
}); });
} }

View File

@ -17,9 +17,9 @@
import { ref, computed, nextTick, watch, onMounted } from 'vue' import { ref, computed, nextTick, watch, onMounted } from 'vue'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import { get as _get } from 'lodash-es' import { get as _get } from 'lodash-es'
import { v4 as uuidv4 } from 'uuid' import { nanoid } from 'nanoid'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox, type Action } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss' import 'element-plus/theme-chalk/src/message.scss'
import { saveSurvey } from '@/management/api/survey' import { saveSurvey } from '@/management/api/survey'
@ -43,20 +43,19 @@ const store = useStore()
onMounted(() => { onMounted(() => {
if (!sessionStorage.getItem('sessionUUID')) { if (!sessionStorage.getItem('sessionUUID')) {
sessionStorage.setItem('sessionUUID', uuidv4()); sessionStorage.setItem('sessionUUID', nanoid());
} }
}) })
const checkConflict = async (surveyid: string) => { const checkConflict = async (surveyid: string) => {
try { try {
const dailyHis = await getConflictHistory({surveyId: surveyid, historyType: 'dailyHis', sessionId: sessionStorage.getItem('sessionUUID')}) const dailyHis = await getConflictHistory({surveyId: surveyid, historyType: 'dailyHis', sessionId: sessionStorage.getItem('sessionUUID')})
//sconsole.log(dailyHis)
if (dailyHis.data.length > 0) { if (dailyHis.data.length > 0) {
const lastHis = dailyHis.data.at(0) const lastHis = dailyHis.data.at(0)
if (Date.now() - lastHis.createDate > 2 * 60 * 1000) { if (Date.now() - lastHis.createDate > 2 * 60 * 1000) {
return [false, ''] return [false, '']
} else {
return [true, lastHis.operator.username]
} }
return [true, lastHis.operator.username]
} }
}catch (error) { }catch (error) {
console.log(error) console.log(error)
@ -79,15 +78,19 @@ const onSave = async () => {
if (conflictName == store.state.user.userInfo.username) { if (conflictName == store.state.user.userInfo.username) {
ElMessageBox.alert('当前问卷已在其它页面开启编辑,刷新以获取最新内容。', '提示', { ElMessageBox.alert('当前问卷已在其它页面开启编辑,刷新以获取最新内容。', '提示', {
confirmButtonText: '确认', confirmButtonText: '确认',
callback: () => { callback: (action: Action) => {
location.reload(); if (action === 'confirm') {
store.dispatch('edit/getSchemaFromRemote')
}
} }
}); });
} else { } else {
ElMessageBox.alert(`当前问卷2分钟内由${conflictName}编辑,刷新以获取最新内容。`, '提示', { ElMessageBox.alert(`当前问卷2分钟内由${conflictName}编辑,刷新以获取最新内容。`, '提示', {
confirmButtonText: '确认', confirmButtonText: '确认',
callback: () => { callback: (action: Action) => {
location.reload(); if (action === 'confirm') {
store.dispatch('edit/getSchemaFromRemote')
}
} }
}); });
} }