fix(APP): 记录页删除也改为5秒倒计时双重确认
- records.vue 删除记录从 uni.showModal 改为自定义倒计时确认弹窗 - 取消逻辑由 Vue 控制,杜绝原生弹窗取消失效
This commit is contained in:
@ -48,6 +48,19 @@
|
|||||||
<text class="empty-text">暂无历史记录</text>
|
<text class="empty-text">暂无历史记录</text>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 🛡️ 双重确认删除(5 秒倒计时防误触) -->
|
||||||
|
<view v-if="confirmDlg.visible" class="dlg-overlay" @tap="confirmDlgCancel">
|
||||||
|
<view class="dlg-box" @tap.stop>
|
||||||
|
<text class="dlg-title">{{ confirmDlg.title }}</text>
|
||||||
|
<text class="dlg-content">{{ confirmDlg.content }}</text>
|
||||||
|
<text class="dlg-tip">⚠️ 请再次确认:倒计时结束点击「确认删除」才会生效</text>
|
||||||
|
<view class="dlg-btns">
|
||||||
|
<button class="dlg-btn dlg-cancel" @tap="confirmDlgCancel">取消</button>
|
||||||
|
<button class="dlg-btn dlg-danger" @tap="confirmDlgConfirm">{{ confirmLabel('删除') }}</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -62,6 +75,11 @@ export default {
|
|||||||
task: null,
|
task: null,
|
||||||
records: [],
|
records: [],
|
||||||
currentUser: null,
|
currentUser: null,
|
||||||
|
// 🛡️ 双重确认删除(5 秒倒计时防误触)
|
||||||
|
confirmDlg: { visible: false, title: "", content: "", target: null },
|
||||||
|
confirming: "",
|
||||||
|
confirmCount: 5,
|
||||||
|
confirmTimer: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -86,6 +104,8 @@ export default {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 🚀 页面卸载:清理确认倒计时定时器
|
||||||
|
onUnload() { this.clearConfirm(); },
|
||||||
methods: {
|
methods: {
|
||||||
loadCurrentUser() {
|
loadCurrentUser() {
|
||||||
try {
|
try {
|
||||||
@ -144,23 +164,69 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
confirmDelete(rec) {
|
confirmDelete(rec) {
|
||||||
uni.showModal({
|
this.openConfirmDlg({ title: "删除记录", content: "确定删除这条记录吗?删除后不可恢复。", target: rec });
|
||||||
title: "删除记录",
|
},
|
||||||
content: "确定删除这条记录吗?",
|
// ═══ 双重确认倒计时(防误触) ═══
|
||||||
confirmColor: "#dc2626",
|
openConfirmDlg({ title, content, target }) {
|
||||||
success: async (res) => {
|
this.clearConfirm();
|
||||||
if (res.confirm) {
|
this.confirmDlg = { visible: true, title, content, target };
|
||||||
try {
|
this.confirming = "dlg";
|
||||||
await request({ url: `/records/${rec.id}`, method: "DELETE" });
|
this.confirmCount = 5;
|
||||||
uni.showToast({ title: "已删除", icon: "success" });
|
this.confirmTimer = setInterval(() => {
|
||||||
this.records = this.records.filter((r) => r.id !== rec.id);
|
this.confirmCount -= 1;
|
||||||
} catch {
|
if (this.confirmCount <= 0) clearInterval(this.confirmTimer);
|
||||||
uni.showToast({ title: "删除失败", icon: "none" });
|
}, 1000);
|
||||||
}
|
},
|
||||||
}
|
clearConfirm() {
|
||||||
},
|
if (this.confirmTimer) clearInterval(this.confirmTimer);
|
||||||
|
this.confirmTimer = null;
|
||||||
|
this.confirming = "";
|
||||||
|
this.confirmCount = 5;
|
||||||
|
},
|
||||||
|
confirmLabel(baseText) {
|
||||||
|
if (this.confirming === "dlg") return this.confirmCount > 0 ? `再次确认 (${this.confirmCount}s)` : "确认删除";
|
||||||
|
return baseText;
|
||||||
|
},
|
||||||
|
confirmDlgConfirm() {
|
||||||
|
this.confirmBtn(() => {
|
||||||
|
const rec = this.confirmDlg.target;
|
||||||
|
this.confirmDlg.visible = false;
|
||||||
|
this.confirmDlg.target = null;
|
||||||
|
if (rec) this.deleteRecord(rec);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
confirmDlgCancel() {
|
||||||
|
this.clearConfirm();
|
||||||
|
this.confirmDlg.visible = false;
|
||||||
|
this.confirmDlg.target = null;
|
||||||
|
},
|
||||||
|
confirmBtn(doAction) {
|
||||||
|
if (this.confirming === "dlg") {
|
||||||
|
if (this.confirmCount <= 0) {
|
||||||
|
this.clearConfirm();
|
||||||
|
doAction();
|
||||||
|
} else {
|
||||||
|
this.clearConfirm();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.clearConfirm();
|
||||||
|
this.confirming = "dlg";
|
||||||
|
this.confirmCount = 5;
|
||||||
|
this.confirmTimer = setInterval(() => {
|
||||||
|
this.confirmCount -= 1;
|
||||||
|
if (this.confirmCount <= 0) clearInterval(this.confirmTimer);
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
async deleteRecord(rec) {
|
||||||
|
try {
|
||||||
|
await request({ url: `/records/${rec.id}`, method: "DELETE" });
|
||||||
|
uni.showToast({ title: "已删除", icon: "success" });
|
||||||
|
this.records = this.records.filter((r) => r.id !== rec.id);
|
||||||
|
} catch {
|
||||||
|
uni.showToast({ title: "删除失败", icon: "none" });
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -194,4 +260,16 @@ export default {
|
|||||||
.empty-timeline { display: flex; flex-direction: column; align-items: center; padding-top: 60px; }
|
.empty-timeline { display: flex; flex-direction: column; align-items: center; padding-top: 60px; }
|
||||||
.empty-icon { font-size: 48px; margin-bottom: 8px; }
|
.empty-icon { font-size: 48px; margin-bottom: 8px; }
|
||||||
.empty-text { font-size: 14px; color: #9ca3af; }
|
.empty-text { font-size: 14px; color: #9ca3af; }
|
||||||
|
|
||||||
|
/* 双重确认弹窗 */
|
||||||
|
.dlg-overlay { position: fixed; inset: 0; z-index: 999; background: rgba(0,0,0,0.45); display: flex; align-items: center; justify-content: center; }
|
||||||
|
.dlg-box { width: 80%; max-width: 360px; background: #fff; border-radius: 16px; padding: 28px 20px 20px; box-sizing: border-box; }
|
||||||
|
.dlg-title { display: block; text-align: center; font-size: 17px; font-weight: 700; color: #1f2937; }
|
||||||
|
.dlg-content { display: block; text-align: center; font-size: 14px; color: #6b7280; margin-top: 10px; line-height: 1.5; }
|
||||||
|
.dlg-tip { display: block; text-align: center; font-size: 12px; color: #b45309; background: #fffbeb; border: 1px solid #fcd34d; border-radius: 8px; padding: 6px 10px; margin: 12px 0 0; line-height: 1.4; }
|
||||||
|
.dlg-btns { display: flex; gap: 12px; margin-top: 20px; }
|
||||||
|
.dlg-btn { flex: 1; height: 42px; line-height: 42px; border-radius: 10px; font-size: 15px; font-weight: 600; text-align: center; box-sizing: border-box; padding: 0; margin: 0; }
|
||||||
|
.dlg-btn::after { border: none; }
|
||||||
|
.dlg-cancel { background: #f3f4f6; color: #6b7280; }
|
||||||
|
.dlg-danger { background: #dc2626; color: #fff; }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user