diff --git a/src/App.vue b/src/App.vue index bce60f0c..715197fe 100644 --- a/src/App.vue +++ b/src/App.vue @@ -21,7 +21,7 @@ import { useRouter } from "vue-router"; import TBackTop from "./components/app/t-backTop.vue"; import TSidebar from "./components/app/t-sidebar.vue"; -import showConfirm from "./components/func/confirm.js"; +import showDialog from "./components/func/dialog.js"; import showSnackbar from "./components/func/snackbar.js"; import TGSqlite from "./plugins/Sqlite/index.js"; import TSUserAccount from "./plugins/Sqlite/modules/userAccount.js"; @@ -247,11 +247,8 @@ async function checkUpdate(): Promise { const needUpdate = await TGSqlite.checkUpdate(); if (needUpdate && isProdEnv) { await TGLogger.Info("[App][checkUpdate] 检测到版本更新!"); - const confirm = await showConfirm({ - title: "检测到版本更新", - text: "是否更新数据库数据?(请确保成就数据已导出)", - }); - if (!confirm) { + const updateCheck = await showDialog.check("检测到版本更新", "是否更新数据库数据?"); + if (!updateCheck) { showSnackbar.error("请到设置页手动更新数据库!", 3000); return; } diff --git a/src/components/config/tc-dataDir.vue b/src/components/config/tc-dataDir.vue index c55471c0..fdb49c37 100644 --- a/src/components/config/tc-dataDir.vue +++ b/src/components/config/tc-dataDir.vue @@ -75,7 +75,7 @@ import TGSqlite from "../../plugins/Sqlite/index.js"; import { useAppStore } from "../../store/modules/app.js"; import { backUpUserData } from "../../utils/dataBS.js"; import TGShell from "../../utils/TGShell.js"; -import showConfirm from "../func/confirm.js"; +import showDialog from "../func/dialog.js"; import showSnackbar from "../func/snackbar.js"; const appStore = storeToRefs(useAppStore()); @@ -100,8 +100,8 @@ onMounted(async () => { async function confirmCUD(): Promise { const oriDir = appStore.userDir.value; - const check = await showConfirm({ title: "确认修改用户数据路径吗?" }); - if (!check) { + const changeCheck = await showDialog.check("确认修改用户数据路径吗?"); + if (!changeCheck) { showSnackbar.cancel("已取消修改"); return; } @@ -122,8 +122,8 @@ async function confirmCUD(): Promise { await TGSqlite.saveAppData("userDir", dir); await backUpUserData(dir); showSnackbar.success("已修改用户数据路径!"); - const confirm = await showConfirm({ title: "是否删除原用户数据目录?", text: "删除后不可恢复!" }); - if (confirm) { + const delCheck = await showDialog.check("是否删除原用户数据目录?"); + if (delCheck) { await remove(oriDir, { recursive: true }); showSnackbar.success("已删除原用户数据目录!"); } @@ -136,11 +136,11 @@ async function confirmCGD(): Promise { return; } const oriEmpty = appStore.gameDir.value === "未设置"; - const editConfirm = await showConfirm({ - title: oriEmpty ? "确认设置目录?" : "确认修改目录?", - text: oriEmpty ? "请选择启动器所在目录" : `当前:${appStore.gameDir.value}`, - }); - if (!editConfirm) { + const editCheck = await showDialog.check( + oriEmpty ? "确认设置游戏目录?" : "确认修改游戏目录?", + oriEmpty ? "请选择启动器所在目录" : `当前:${appStore.gameDir.value}`, + ); + if (!editCheck) { showSnackbar.cancel(oriEmpty ? "已取消设置" : "已取消修改"); return; } @@ -175,11 +175,8 @@ function isOverWeek(date: string): boolean { } async function confirmCLD(): Promise { - const check = await showConfirm({ - title: "确认清理日志文件吗?", - text: "将保留一周内的日志文件", - }); - if (!check) { + const delCheck = await showDialog.check("确认清理日志文件吗?", "将保留一周内的日志文件"); + if (!delCheck) { showSnackbar.cancel("已取消清理"); return; } diff --git a/src/components/config/tc-userBadge.vue b/src/components/config/tc-userBadge.vue index 9ce21b46..ffaa2856 100644 --- a/src/components/config/tc-userBadge.vue +++ b/src/components/config/tc-userBadge.vue @@ -112,7 +112,7 @@ import { useAppStore } from "../../store/modules/app.js"; import { useUserStore } from "../../store/modules/user.js"; import TGLogger from "../../utils/TGLogger.js"; import TGRequest from "../../web/request/TGRequest.js"; -import showConfirm from "../func/confirm.js"; +import showDialog from "../func/dialog.js"; import showGeetest from "../func/geetest.js"; import showSnackbar from "../func/snackbar.js"; @@ -139,7 +139,7 @@ const userInfo = computed(() => { }); async function tryCaptchaLogin(): Promise { - const phone = await showConfirm({ mode: "input", title: "请输入手机号", text: "+86" }); + const phone = await showDialog.input("请输入手机号", "+86"); if (!phone) { showSnackbar.cancel("已取消验证码登录"); return; @@ -152,12 +152,7 @@ async function tryCaptchaLogin(): Promise { const actionType = await tryGetCaptcha(phone); if (!actionType) return; showSnackbar.success(`已发送验证码到 ${phone}`); - const captcha = await showConfirm({ - mode: "input", - title: "请输入验证码", - text: "验证码:", - otcancel: false, - }); + const captcha = await showDialog.input("请输入验证码", "验证码:", undefined, false); if (!captcha) { showSnackbar.warn("输入验证码为空"); return; @@ -365,31 +360,28 @@ async function loadAccount(uid: string): Promise { } async function confirmRefreshUser(uid: string): Promise { - const res = await showConfirm({ title: "确认刷新用户信息吗?", text: "将会重新获取用户信息" }); - if (!res) { + const freshCheck = await showDialog.check("确认刷新用户信息吗?", "将会重新获取用户信息"); + if (!freshCheck) { showSnackbar.cancel("已取消刷新用户信息"); return; } await refreshUser(uid); if (userStore.uid.value === uid) showSnackbar.success("成功刷新用户信息"); - const confirm = await showConfirm({ title: "是否切换用户?", text: `将切换到用户${uid}` }); - if (!confirm) return; + const switchCheck = await showDialog.check("是否切换用户?", `将切换到用户${uid}`); + if (!switchCheck) return; await loadAccount(uid); } async function confirmCopyCookie(): Promise { - const res = await showConfirm({ - title: "确认复制 Cookie 吗?", - text: "将会复制当前登录的 Cookie", - }); - if (!res) { - showSnackbar.cancel("已取消复制 Cookie"); - return; - } if (!userStore.cookie.value) { showSnackbar.warn("请先登录"); return; } + const copyCheck = await showDialog.check("确认复制 Cookie 吗?", "将会复制当前登录的 Cookie"); + if (!copyCheck) { + showSnackbar.cancel("已取消复制 Cookie"); + return; + } const ckText = TSUserAccount.account.copy(userStore.cookie.value); await navigator.clipboard.writeText(ckText); showSnackbar.success("已复制 Cookie!"); @@ -447,11 +439,7 @@ async function showAccounts(): Promise { } async function addByCookie(): Promise { - const ckInput = await showConfirm({ - mode: "input", - title: "请输入cookie", - text: "Cookie:", - }); + const ckInput = await showDialog.input("请输入Cookie", "Cookie:"); if (!ckInput) { showSnackbar.cancel("已取消Cookie输入"); return; @@ -553,8 +541,8 @@ async function clearUser(user: TGApp.App.Account.User): Promise { showSnackbar.warn("当前登录用户不许删除!"); return; } - const confirm = await showConfirm({ title: "确认删除", text: "将删除账号及其游戏账号数据" }); - if (!confirm) { + const delCheck = await showDialog.check("确认删除用户吗?", "将删除账号及其游戏账号数据"); + if (!delCheck) { showSnackbar.cancel("已取消删除用户数据"); return; } diff --git a/src/components/func/confirm.ts b/src/components/func/confirm.ts deleted file mode 100644 index d97e009b..00000000 --- a/src/components/func/confirm.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file component/func/confirm.ts - * @description 封装自定义 confirm 组件,通过函数调用的方式,简化 confirm 的使用 - * @since Beta v0.3.9 - */ - -import { h, render } from "vue"; -import type { ComponentInternalInstance, VNode } from "vue"; - -import confirm from "./confirm.vue"; - -const confirmId = "tg-func-confirm"; - -/** - * @description 自定义 confirm 组件 - * @since Beta v0.3.4 - * @extends ComponentInternalInstance - * @property {Function} exposeProxy.displayBox 显示 confirm - * @return ConfirmInstance - */ -interface ConfirmInstance extends ComponentInternalInstance { - exposeProxy: { - displayBox: (props: TGApp.Component.Confirm.Params) => Promise; - }; -} - -const renderBox = (props: TGApp.Component.Confirm.Params): VNode => { - const container = document.createElement("div"); - container.id = confirmId; - const boxVNode: VNode = h(confirm, props); - render(boxVNode, container); - document.body.appendChild(container); - return boxVNode; -}; - -let confirmInstance: VNode; - -/** - * @function showConfirm - * @since Beta v0.3.9 - * @description 弹出 confirm - * @param {TGApp.Component.Confirm.Params} props confirm 的参数 - * @return {Promise} 点击确认返回 true,点击取消返回 false,点击外部返回 undefined - */ -async function showConfirm( - props: TGApp.Component.Confirm.ParamsConfirm, -): Promise; -async function showConfirm( - props: TGApp.Component.Confirm.ParamsInput, -): Promise; -async function showConfirm( - props: TGApp.Component.Confirm.Params, -): Promise; -async function showConfirm( - props: TGApp.Component.Confirm.Params, -): Promise { - if (confirmInstance !== undefined) { - const boxVue = confirmInstance.component; - return await boxVue.exposeProxy.displayBox(props); - } else { - confirmInstance = renderBox(props); - return await showConfirm(props); - } -} - -export default showConfirm; diff --git a/src/components/func/confirm.vue b/src/components/func/confirm.vue deleted file mode 100644 index e7d42e2f..00000000 --- a/src/components/func/confirm.vue +++ /dev/null @@ -1,270 +0,0 @@ - - - - diff --git a/src/components/func/dialog.ts b/src/components/func/dialog.ts new file mode 100644 index 00000000..9ed8b15a --- /dev/null +++ b/src/components/func/dialog.ts @@ -0,0 +1,113 @@ +/** + * @file component/func/dialog.ts + * @description dialog 组件封装,函数式调用 + * @since Beta v0.6.3 + */ + +import { h, render } from "vue"; +import type { ComponentInternalInstance, VNode } from "vue"; + +import dialog from "./dialog.vue"; + +const dialogId = "tg-func-dialog"; + +export type DialogParams = DialogCheckParams | DialogInputParams; +export type DialogCheckParams = { + mode: "check"; + title: string; + text?: string; + otcancel?: boolean; +}; +export type DialogInputParams = { + mode: "input"; + title: string; + text?: string; + otcancel?: boolean; + input?: string; +}; + +/** + * @description 自定义 confirm 组件 + * @since Beta v0.6.3 + * @extends ComponentInternalInstance + * @property {Function} exposeProxy.displayBox 显示 confirm + * @return DialogInstance + */ +interface DialogInstance extends ComponentInternalInstance { + exposeProxy: { + displayCheckBox: (props: DialogCheckParams) => Promise; + displayInputBox: (props: DialogInputParams) => Promise; + }; +} + +function renderBox(props: DialogParams): VNode { + const container = document.createElement("div"); + container.id = dialogId; + const boxVNode: VNode = h(dialog, props); + render(boxVNode, container); + document.body.appendChild(container); + return boxVNode; +} + +let dialogInstance: VNode; + +async function showDialogFull( + mode: "check" | "input", + title: string, + text?: string, + input?: string, + otcancel?: boolean, +): Promise { + if (mode === "check") return await showDialogCheck(title, text, otcancel); + return await showDialogInput(title, text, input, otcancel); +} + +async function showDialogCheck( + title: string, + text?: string, + otcancel?: boolean, +): Promise { + const params: DialogCheckParams = { + mode: "check", + title: title, + text: text, + otcancel: otcancel, + }; + if (dialogInstance !== undefined) { + const boxVue = dialogInstance.component; + return await boxVue.exposeProxy.displayCheckBox(params); + } else { + dialogInstance = renderBox(params); + return await showDialogCheck(title, text, otcancel); + } +} + +async function showDialogInput( + title: string, + text?: string, + input?: string, + otcancel?: boolean, +): Promise { + const params: DialogInputParams = { + mode: "input", + title: title, + text: text, + input: input, + otcancel: otcancel, + }; + if (dialogInstance !== undefined) { + const boxVue = dialogInstance.component; + return await boxVue.exposeProxy.displayInputBox(params); + } else { + dialogInstance = renderBox(params); + return await showDialogInput(title, text, input, otcancel); + } +} + +const showDialog = { + _: showDialogFull, + check: showDialogCheck, + input: showDialogInput, +}; + +export default showDialog; diff --git a/src/components/func/dialog.vue b/src/components/func/dialog.vue new file mode 100644 index 00000000..f04ed771 --- /dev/null +++ b/src/components/func/dialog.vue @@ -0,0 +1,294 @@ + + + + diff --git a/src/components/func/snackbar.ts b/src/components/func/snackbar.ts index 725e7547..3eaafd24 100644 --- a/src/components/func/snackbar.ts +++ b/src/components/func/snackbar.ts @@ -1,6 +1,6 @@ /** - * @file component func snackbar.ts - * @description 封装 vuetify 的 snackbar 组件,通过函数调用的方式,简化 snackbar 的使用 + * @file component/func/snackbar.ts + * @description snackbar 组件封装,函数式调用 * @since Beta v0.6.3 */ @@ -11,32 +11,32 @@ import snackbar from "./snackbar.vue"; const snackbarId = "tg-func-snackbar"; +export type SnackbarParams = { text: string; color: string; timeout: number }; + /** * @description 自定义 snackbar 组件 - * @since Beta v0.3.3 - * @extends ComponentInternalInstance - * @property {Function} exposeProxy.displayBox 显示 snackbar + * @since Beta v0.6.3 * @return SnackbarInstance */ interface SnackbarInstance extends ComponentInternalInstance { exposeProxy: { - displayBox: (props: TGApp.Component.Snackbar.Params) => void; + displayBox: (props: SnackbarParams) => void; }; } -const renderBox = (props: TGApp.Component.Snackbar.Params): VNode => { +function renderBox(props: SnackbarParams): VNode { const container = document.createElement("div"); container.id = snackbarId; const boxVNode: VNode = h(snackbar, props); render(boxVNode, container); document.body.appendChild(container); return boxVNode; -}; +} let snackbarInstance: VNode; function showSnackbarFull(text: string, color?: string, timeout?: number): void { - const params: TGApp.Component.Snackbar.Params = { + const params: SnackbarParams = { text: text, color: color ?? "success", timeout: timeout ?? 1500, diff --git a/src/components/func/snackbar.vue b/src/components/func/snackbar.vue index 24868ef9..9ee38c86 100644 --- a/src/components/func/snackbar.vue +++ b/src/components/func/snackbar.vue @@ -1,7 +1,7 @@