hookehuyr

fix(弹框控制): 修复未完成表单弹框状态管理问题

修复弹框状态在不同表单间切换时未正确重置的问题
添加表单code参数跟踪确保弹框状态与当前表单匹配
新增调试页面用于测试弹框状态管理功能
1 +<!DOCTYPE html>
2 +<html lang="zh-CN">
3 +<head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 + <title>弹框状态调试工具</title>
7 + <style>
8 + body {
9 + font-family: Arial, sans-serif;
10 + max-width: 800px;
11 + margin: 0 auto;
12 + padding: 20px;
13 + background-color: #f5f5f5;
14 + }
15 + .container {
16 + background: white;
17 + padding: 20px;
18 + border-radius: 8px;
19 + box-shadow: 0 2px 10px rgba(0,0,0,0.1);
20 + }
21 + h1 {
22 + color: #333;
23 + text-align: center;
24 + }
25 + .status-section {
26 + margin: 20px 0;
27 + padding: 15px;
28 + background: #f8f9fa;
29 + border-radius: 5px;
30 + border-left: 4px solid #007bff;
31 + }
32 + .button-group {
33 + display: flex;
34 + gap: 10px;
35 + margin: 20px 0;
36 + flex-wrap: wrap;
37 + }
38 + button {
39 + padding: 10px 20px;
40 + border: none;
41 + border-radius: 5px;
42 + cursor: pointer;
43 + font-size: 14px;
44 + transition: background-color 0.3s;
45 + }
46 + .btn-primary {
47 + background-color: #007bff;
48 + color: white;
49 + }
50 + .btn-primary:hover {
51 + background-color: #0056b3;
52 + }
53 + .btn-warning {
54 + background-color: #ffc107;
55 + color: #212529;
56 + }
57 + .btn-warning:hover {
58 + background-color: #e0a800;
59 + }
60 + .btn-danger {
61 + background-color: #dc3545;
62 + color: white;
63 + }
64 + .btn-danger:hover {
65 + background-color: #c82333;
66 + }
67 + .alert {
68 + padding: 10px;
69 + margin: 10px 0;
70 + border-radius: 5px;
71 + }
72 + .alert-success {
73 + background-color: #d4edda;
74 + color: #155724;
75 + border: 1px solid #c3e6cb;
76 + }
77 + .alert-info {
78 + background-color: #d1ecf1;
79 + color: #0c5460;
80 + border: 1px solid #bee5eb;
81 + }
82 + </style>
83 +</head>
84 +<body>
85 + <div class="container">
86 + <h1>未完成表单弹框调试工具</h1>
87 +
88 + <div class="alert alert-info">
89 + <strong>说明:</strong>此工具用于调试"您还未完成的表单"弹框的显示状态。如果弹框不显示,可能是因为已经显示过或者表单代码发生了变化。
90 + </div>
91 +
92 + <div class="status-section">
93 + <h3>当前状态</h3>
94 + <div id="status"></div>
95 + </div>
96 +
97 + <div class="status-section">
98 + <div id="cookies"></div>
99 + </div>
100 +
101 + <div class="button-group">
102 + <button class="btn-primary" onclick="checkStatus()">刷新状态</button>
103 + <button class="btn-warning" onclick="resetDialogState()">重置弹框状态</button>
104 + <button class="btn-danger" onclick="clearAllData()">清除所有数据</button>
105 + </div>
106 +
107 + <div id="message"></div>
108 + </div>
109 +
110 + <script>
111 + function checkStatus() {
112 + const dialogShown = sessionStorage.getItem('unfinished_form_dialog_shown');
113 + const dialogCode = sessionStorage.getItem('unfinished_form_dialog_code');
114 + const statusDiv = document.getElementById('status');
115 +
116 + statusDiv.innerHTML = `
117 + <p><strong>弹框状态:</strong> ${dialogShown === 'true' ? '已显示过' : '未显示'}</p>
118 + <p><strong>记录的表单Code:</strong> ${dialogCode || '无'}</p>
119 + <p><strong>SessionStorage弹框值:</strong> ${dialogShown || '无'}</p>
120 + <p><strong>SessionStorage代码值:</strong> ${dialogCode || '无'}</p>
121 + `;
122 +
123 + // 检查Cookie状态
124 + const cookies = document.cookie.split(';');
125 + const cookieDiv = document.getElementById('cookies');
126 + let cookieInfo = '<h3>相关Cookie信息:</h3>';
127 +
128 + if (cookies.length === 1 && cookies[0] === '') {
129 + cookieInfo += '<p>无Cookie数据</p>';
130 + } else {
131 + cookies.forEach(cookie => {
132 + const [name, value] = cookie.trim().split('=');
133 + if (name && value) {
134 + cookieInfo += `<p><strong>${name}:</strong> ${decodeURIComponent(value)}</p>`;
135 + }
136 + });
137 + }
138 +
139 + cookieDiv.innerHTML = cookieInfo;
140 + }
141 +
142 + function resetDialogState() {
143 + sessionStorage.removeItem('unfinished_form_dialog_shown');
144 + sessionStorage.removeItem('unfinished_form_dialog_code');
145 + showMessage('弹框状态已重置!现在可以重新显示弹框了。', 'success');
146 + checkStatus();
147 + }
148 +
149 + function clearAllData() {
150 + // 清除所有sessionStorage
151 + sessionStorage.clear();
152 +
153 + // 清除所有cookies(注意:只能清除当前域名下的cookies)
154 + const cookies = document.cookie.split(';');
155 + cookies.forEach(cookie => {
156 + const eqPos = cookie.indexOf('=');
157 + const name = eqPos > -1 ? cookie.substr(0, eqPos).trim() : cookie.trim();
158 + if (name) {
159 + document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/';
160 + }
161 + });
162 +
163 + showMessage('所有数据已清除!包括SessionStorage和Cookies。', 'success');
164 + checkStatus();
165 + }
166 +
167 + function showMessage(text, type) {
168 + const messageDiv = document.getElementById('message');
169 + messageDiv.innerHTML = `<div class="alert alert-${type}">${text}</div>`;
170 + setTimeout(() => {
171 + messageDiv.innerHTML = '';
172 + }, 3000);
173 + }
174 +
175 + // 页面加载时自动检查状态
176 + window.onload = function() {
177 + checkStatus();
178 + };
179 + </script>
180 +</body>
181 +</html>
...\ No newline at end of file ...\ No newline at end of file
...@@ -28,6 +28,7 @@ import { getFormSettingAPI } from "@/api/form.js"; ...@@ -28,6 +28,7 @@ import { getFormSettingAPI } from "@/api/form.js";
28 import { showDialog, showConfirmDialog } from 'vant'; 28 import { showDialog, showConfirmDialog } from 'vant';
29 // import fp3 from '@/utils/fp3'; 29 // import fp3 from '@/utils/fp3';
30 import { Updater } from '@/utils/versionUpdater'; 30 import { Updater } from '@/utils/versionUpdater';
31 +import { resetDialogState } from '@/utils/dialogControl.js';
31 32
32 // 使用 include + pinia 状态管理动态缓存页面 33 // 使用 include + pinia 状态管理动态缓存页面
33 const store = mainStore(); 34 const store = mainStore();
...@@ -63,6 +64,9 @@ const is_wx = computed(() => wxInfo().isWeiXin); ...@@ -63,6 +64,9 @@ const is_wx = computed(() => wxInfo().isWeiXin);
63 const is_iframe = computed(() => window.self !== window.top); 64 const is_iframe = computed(() => window.self !== window.top);
64 65
65 onMounted(async () => { 66 onMounted(async () => {
67 + // 重置弹框状态,确保每次访问页面时都能正常显示未完成表单弹框
68 + resetDialogState();
69 +
66 const code = getUrlParams(location.href) ? getUrlParams(location.href).code : ''; 70 const code = getUrlParams(location.href) ? getUrlParams(location.href).code : '';
67 const model = getUrlParams(location.href) ? getUrlParams(location.href).model : ''; 71 const model = getUrlParams(location.href) ? getUrlParams(location.href).model : '';
68 const data_id = getUrlParams(location.href) ? getUrlParams(location.href).data_id : ''; 72 const data_id = getUrlParams(location.href) ? getUrlParams(location.href).data_id : '';
......
1 /* 1 /*
2 * @Date: 2022-05-26 13:57:28 2 * @Date: 2022-05-26 13:57:28
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-09-10 10:26:45 4 + * @LastEditTime: 2025-09-11 17:13:53
5 * @FilePath: /data-table/src/router.js 5 * @FilePath: /data-table/src/router.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -11,7 +11,7 @@ import asyncRoutesArr from "./mock/routes" ...@@ -11,7 +11,7 @@ import asyncRoutesArr from "./mock/routes"
11 import generateRoutes from './utils/generateRoute' 11 import generateRoutes from './utils/generateRoute'
12 import { Loading } from "vant"; 12 import { Loading } from "vant";
13 import Cookies from 'js-cookie'; 13 import Cookies from 'js-cookie';
14 -import { showUnfinishedFormDialog } from '@/utils/dialogControl.js'; 14 +import { showUnfinishedFormDialog, resetDialogState } from '@/utils/dialogControl.js';
15 import { getCycleListAPI } from '@/api/cycle'; 15 import { getCycleListAPI } from '@/api/cycle';
16 16
17 // TAG: 路由配置表 17 // TAG: 路由配置表
...@@ -86,6 +86,11 @@ const checkCycleSelection = (to) => { ...@@ -86,6 +86,11 @@ const checkCycleSelection = (to) => {
86 }; 86 };
87 87
88 router.beforeEach((to, from, next) => { 88 router.beforeEach((to, from, next) => {
89 + // 当访问不同的表单时(code参数不同),重置弹框状态
90 + if (to.query.code && from.query.code && to.query.code !== from.query.code) {
91 + resetDialogState();
92 + }
93 +
89 // 使用404为中转页面,避免动态路由没有渲染出来,控制台报警告问题 94 // 使用404为中转页面,避免动态路由没有渲染出来,控制台报警告问题
90 if (to.path == '/404' && to.redirectedFrom != undefined) { 95 if (to.path == '/404' && to.redirectedFrom != undefined) {
91 // 模拟异步操作 96 // 模拟异步操作
...@@ -150,7 +155,8 @@ router.beforeEach((to, from, next) => { ...@@ -150,7 +155,8 @@ router.beforeEach((to, from, next) => {
150 // 用户选择删除,删除cookie并跳转 155 // 用户选择删除,删除cookie并跳转
151 Cookies.remove(to.query.code); 156 Cookies.remove(to.query.code);
152 next(); 157 next();
153 - } 158 + },
159 + to.query.code
154 ); 160 );
155 } else { 161 } else {
156 next(); 162 next();
...@@ -198,7 +204,8 @@ router.beforeEach((to, from, next) => { ...@@ -198,7 +204,8 @@ router.beforeEach((to, from, next) => {
198 // 用户选择删除,删除cookie并跳转 204 // 用户选择删除,删除cookie并跳转
199 Cookies.remove(to.query.code); 205 Cookies.remove(to.query.code);
200 next(); 206 next();
201 - } 207 + },
208 + to.query.code
202 ); 209 );
203 } else { 210 } else {
204 next(); 211 next();
......
1 +/*
2 + * @Date: 2025-09-10 10:54:52
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-09-11 17:13:28
5 + * @FilePath: /data-table/src/utils/dialogControl.js
6 + * @Description: 文件描述
7 + */
1 import { showConfirmDialog } from 'vant'; 8 import { showConfirmDialog } from 'vant';
2 import { styleColor } from '@/constant.js'; 9 import { styleColor } from '@/constant.js';
3 10
4 // 弹框显示状态管理 11 // 弹框显示状态管理
5 const DIALOG_SHOWN_KEY = 'unfinished_form_dialog_shown'; 12 const DIALOG_SHOWN_KEY = 'unfinished_form_dialog_shown';
13 +const DIALOG_CODE_KEY = 'unfinished_form_dialog_code';
6 14
7 /** 15 /**
8 * 检查弹框是否已经显示过 16 * 检查弹框是否已经显示过
17 + * @param {string} currentCode - 当前表单的code参数
9 * @returns {boolean} 是否已显示过 18 * @returns {boolean} 是否已显示过
10 */ 19 */
11 -export function hasDialogShown() { 20 +export function hasDialogShown(currentCode) {
12 - return sessionStorage.getItem(DIALOG_SHOWN_KEY) === 'true'; 21 + const isShown = sessionStorage.getItem(DIALOG_SHOWN_KEY) === 'true';
22 + const lastCode = sessionStorage.getItem(DIALOG_CODE_KEY);
23 +
24 + // 如果当前code与上次显示弹框的code不同,则重置状态
25 + if (currentCode && lastCode && currentCode !== lastCode) {
26 + resetDialogState();
27 + return false;
28 + }
29 +
30 + return isShown;
13 } 31 }
14 32
15 /** 33 /**
16 * 标记弹框已显示 34 * 标记弹框已显示
35 + * @param {string} currentCode - 当前表单的code参数
17 */ 36 */
18 -export function markDialogShown() { 37 +export function markDialogShown(currentCode) {
19 sessionStorage.setItem(DIALOG_SHOWN_KEY, 'true'); 38 sessionStorage.setItem(DIALOG_SHOWN_KEY, 'true');
39 + if (currentCode) {
40 + sessionStorage.setItem(DIALOG_CODE_KEY, currentCode);
41 + }
20 } 42 }
21 43
22 /** 44 /**
...@@ -24,17 +46,19 @@ export function markDialogShown() { ...@@ -24,17 +46,19 @@ export function markDialogShown() {
24 */ 46 */
25 export function resetDialogState() { 47 export function resetDialogState() {
26 sessionStorage.removeItem(DIALOG_SHOWN_KEY); 48 sessionStorage.removeItem(DIALOG_SHOWN_KEY);
49 + sessionStorage.removeItem(DIALOG_CODE_KEY);
27 } 50 }
28 51
29 /** 52 /**
30 * 显示未完成表单确认弹框(带全局控制) 53 * 显示未完成表单确认弹框(带全局控制)
31 * @param {Function} onConfirm - 确认回调 54 * @param {Function} onConfirm - 确认回调
32 * @param {Function} onCancel - 取消回调 55 * @param {Function} onCancel - 取消回调
56 + * @param {string} currentCode - 当前表单的code参数
33 * @returns {Promise|null} 如果已显示过则返回null,否则返回弹框Promise 57 * @returns {Promise|null} 如果已显示过则返回null,否则返回弹框Promise
34 */ 58 */
35 -export function showUnfinishedFormDialog(onConfirm, onCancel) { 59 +export function showUnfinishedFormDialog(onConfirm, onCancel, currentCode) {
36 // 如果已经显示过,直接执行确认回调 60 // 如果已经显示过,直接执行确认回调
37 - if (hasDialogShown()) { 61 + if (hasDialogShown(currentCode)) {
38 if (onConfirm) { 62 if (onConfirm) {
39 onConfirm(); 63 onConfirm();
40 } 64 }
...@@ -42,7 +66,7 @@ export function showUnfinishedFormDialog(onConfirm, onCancel) { ...@@ -42,7 +66,7 @@ export function showUnfinishedFormDialog(onConfirm, onCancel) {
42 } 66 }
43 67
44 // 标记为已显示 68 // 标记为已显示
45 - markDialogShown(); 69 + markDialogShown(currentCode);
46 70
47 // 显示弹框 71 // 显示弹框
48 return showConfirmDialog({ 72 return showConfirmDialog({
......
...@@ -189,7 +189,8 @@ const checkUnfinishedForm = (route) => { ...@@ -189,7 +189,8 @@ const checkUnfinishedForm = (route) => {
189 cycle_selected: '1' 189 cycle_selected: '1'
190 } 190 }
191 }); 191 });
192 - } 192 + },
193 + route.query.code
193 ); 194 );
194 } else { 195 } else {
195 // 没有未完成的表单,直接跳转 196 // 没有未完成的表单,直接跳转
......
...@@ -198,6 +198,7 @@ import { useRoute } from "vue-router"; ...@@ -198,6 +198,7 @@ import { useRoute } from "vue-router";
198 import { queryFormAPI, postVerifyPasswordAPI, getVolunteerSourceLeaderAPI } from "@/api/form.js"; 198 import { queryFormAPI, postVerifyPasswordAPI, getVolunteerSourceLeaderAPI } from "@/api/form.js";
199 import { addFormDataAPI, queryFormDataAPI, modiFormDataAPI, flowFormDataAPI } from "@/api/data.js"; 199 import { addFormDataAPI, queryFormDataAPI, modiFormDataAPI, flowFormDataAPI } from "@/api/data.js";
200 import { showSuccessToast, showFailToast, showConfirmDialog, showToast } from "vant"; 200 import { showSuccessToast, showFailToast, showConfirmDialog, showToast } from "vant";
201 +import { resetDialogState } from "@/utils/dialogControl.js";
201 import { wxInfo, getUrlParams, formatDate, prettyLog } from "@/utils/tools"; 202 import { wxInfo, getUrlParams, formatDate, prettyLog } from "@/utils/tools";
202 import { styleColor } from "@/constant.js"; 203 import { styleColor } from "@/constant.js";
203 import { sharePage } from '@/composables/useShare.js' 204 import { sharePage } from '@/composables/useShare.js'
...@@ -1067,6 +1068,8 @@ const submitStatus = ref(false); // 表单提交按钮状态 ...@@ -1067,6 +1068,8 @@ const submitStatus = ref(false); // 表单提交按钮状态
1067 const successHandle = () => { // 表单成功提交后续操作 1068 const successHandle = () => { // 表单成功提交后续操作
1068 // 删除存在cookie, 提交成功后删除 1069 // 删除存在cookie, 提交成功后删除
1069 Cookies.remove($route.query.code); 1070 Cookies.remove($route.query.code);
1071 + // 清理弹框状态,表单提交成功后重置
1072 + resetDialogState();
1070 //在 iframe 中调用父页面中定义的变量 - Doris需要自由控制 1073 //在 iframe 中调用父页面中定义的变量 - Doris需要自由控制
1071 let getChildVal = parent.parent.getChildVal; 1074 let getChildVal = parent.parent.getChildVal;
1072 if (getChildVal) { 1075 if (getChildVal) {
......