| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- import { defineStore } from "pinia";
- import { ref } from "vue";
- import { ElMessage } from "element-plus";
- /** 上传占 90%,内容审核占 10% */
- const UPLOAD_PERCENT_MAX = 90;
- const AUDIT_PERCENT_MAX = 100;
- const AUDIT_ROTATE_MESSAGES = [
- "检测违规内容中...",
- "审核内容合规性...",
- "筛查敏感信息中...",
- "识别不良信息中...",
- "智能风控核验中..."
- ];
- const AUDIT_TITLE_DONE = "上传完毕,处理中...";
- const AUDIT_TITLE_SUCCESS = "上传成功";
- let uploadCreepTimer: ReturnType<typeof setInterval> | null = null;
- let auditMessageTimer: ReturnType<typeof setInterval> | null = null;
- let auditProgressTimer: ReturnType<typeof setInterval> | null = null;
- let auditMessageIndex = 0;
- let activeController: AbortController | null = null;
- function clearUploadCreepTimer() {
- if (uploadCreepTimer) {
- clearInterval(uploadCreepTimer);
- uploadCreepTimer = null;
- }
- }
- function clearAuditTimers() {
- if (auditMessageTimer) {
- clearInterval(auditMessageTimer);
- auditMessageTimer = null;
- }
- if (auditProgressTimer) {
- clearInterval(auditProgressTimer);
- auditProgressTimer = null;
- }
- }
- function clearAllTimers() {
- clearUploadCreepTimer();
- clearAuditTimers();
- }
- function clampPercent(n: number) {
- return Math.min(AUDIT_PERCENT_MAX, Math.max(0, Math.round(n)));
- }
- export const useSimpleUploadOverlayStore = defineStore("simple-upload-overlay", () => {
- const show = ref(false);
- const percent = ref(0);
- const title = ref("上传中");
- const cancelText = ref("取消上传");
- function beginUpload(opts?: { title?: string }) {
- activeController?.abort(new DOMException("已开始新的上传", "AbortError"));
- clearAllTimers();
- activeController = new AbortController();
- title.value = opts?.title ?? "上传中";
- percent.value = 0;
- show.value = true;
- auditMessageIndex = 0;
- /** OSS 未回调 progress 时缓慢推进,上限留到 85% 等待真实进度 */
- uploadCreepTimer = setInterval(() => {
- if (percent.value < 85) {
- percent.value = Math.min(85, percent.value + 1);
- }
- }, 220);
- return activeController.signal;
- }
- /** 单文件 OSS 上传进度 ratio 0~1 → 0~90% */
- function setUploadProgress(ratio: number, opts?: { skipAudit?: boolean }) {
- const r = Math.min(1, Math.max(0, Number(ratio) || 0));
- const max = opts?.skipAudit ? AUDIT_PERCENT_MAX : UPLOAD_PERCENT_MAX;
- const next = clampPercent(r * max);
- if (next > percent.value) {
- percent.value = next;
- }
- if (next >= UPLOAD_PERCENT_MAX - 1) {
- clearUploadCreepTimer();
- }
- }
- /** 多文件:第 index 个文件、共 total 个,单文件内 ratio 0~1 */
- function setMultiFileUploadProgress(fileIndex: number, totalFiles: number, ratio: number) {
- const total = Math.max(1, totalFiles);
- const idx = Math.min(Math.max(0, fileIndex), total - 1);
- const r = Math.min(1, Math.max(0, Number(ratio) || 0));
- const base = (idx / total) * UPLOAD_PERCENT_MAX;
- const span = UPLOAD_PERCENT_MAX / total;
- const next = clampPercent(base + r * span);
- if (next > percent.value) {
- percent.value = next;
- }
- if (r >= 1 && idx === total - 1) {
- clearUploadCreepTimer();
- percent.value = UPLOAD_PERCENT_MAX;
- }
- }
- /** 多文件审核阶段进度 */
- function setMultiFileAuditProgress(fileIndex: number, totalFiles: number, ratio: number) {
- const total = Math.max(1, totalFiles);
- const idx = Math.min(Math.max(0, fileIndex), total - 1);
- const r = Math.min(1, Math.max(0, Number(ratio) || 0));
- const base = UPLOAD_PERCENT_MAX + (idx / total) * (AUDIT_PERCENT_MAX - UPLOAD_PERCENT_MAX);
- const span = (AUDIT_PERCENT_MAX - UPLOAD_PERCENT_MAX) / total;
- percent.value = clampPercent(base + r * span);
- }
- function startAuditMessageRotation() {
- clearAuditTimers();
- auditMessageIndex = 0;
- title.value = AUDIT_TITLE_DONE;
- auditMessageTimer = setInterval(() => {
- title.value = AUDIT_ROTATE_MESSAGES[auditMessageIndex % AUDIT_ROTATE_MESSAGES.length];
- auditMessageIndex += 1;
- }, 1200);
- let auditP = percent.value < UPLOAD_PERCENT_MAX ? UPLOAD_PERCENT_MAX : percent.value;
- percent.value = UPLOAD_PERCENT_MAX;
- auditProgressTimer = setInterval(() => {
- if (auditP < 99) {
- auditP = Math.min(99, auditP + 0.35);
- percent.value = clampPercent(auditP);
- }
- }, 280);
- }
- /** 进入审核阶段:固定 90%,先显示「上传完毕,处理中...」再轮播审核文案 */
- function beginAuditPhase() {
- clearUploadCreepTimer();
- percent.value = UPLOAD_PERCENT_MAX;
- title.value = AUDIT_TITLE_DONE;
- setTimeout(() => {
- if (!show.value) return;
- startAuditMessageRotation();
- }, 600);
- }
- function beginAuditPhaseForBatch(fileIndex: number, totalFiles: number) {
- clearUploadCreepTimer();
- const total = Math.max(1, totalFiles);
- const idx = Math.min(Math.max(0, fileIndex), total - 1);
- const auditBase = UPLOAD_PERCENT_MAX + (idx / total) * (AUDIT_PERCENT_MAX - UPLOAD_PERCENT_MAX);
- percent.value = clampPercent(Math.max(UPLOAD_PERCENT_MAX, auditBase));
- title.value = AUDIT_TITLE_DONE;
- setTimeout(() => {
- if (!show.value) return;
- startAuditMessageRotation();
- }, 600);
- }
- function completeSuccess() {
- clearAllTimers();
- percent.value = AUDIT_PERCENT_MAX;
- title.value = AUDIT_TITLE_SUCCESS;
- }
- /** @deprecated 请用 completeSuccess */
- function bumpToComplete() {
- completeSuccess();
- }
- function dismiss() {
- clearAllTimers();
- show.value = false;
- percent.value = 0;
- title.value = "上传中";
- activeController = null;
- }
- function userCancel() {
- activeController?.abort(new DOMException("用户已取消上传", "AbortError"));
- dismiss();
- ElMessage.info("取消上传");
- }
- function getActiveAbortSignal(): AbortSignal | undefined {
- return activeController?.signal;
- }
- return {
- show,
- percent,
- title,
- cancelText,
- beginUpload,
- setUploadProgress,
- setMultiFileUploadProgress,
- setMultiFileAuditProgress,
- beginAuditPhase,
- beginAuditPhaseForBatch,
- completeSuccess,
- bumpToComplete,
- dismiss,
- userCancel,
- getActiveAbortSignal
- };
- });
|