update ConnectSetting.vue
This commit is contained in:
@@ -5,9 +5,14 @@
|
|||||||
v-if="navBarStore.isShowing"
|
v-if="navBarStore.isShowing"
|
||||||
class="nav-bar"
|
class="nav-bar"
|
||||||
:title="navBarStore.title"
|
:title="navBarStore.title"
|
||||||
:left-arrow="!!navBarStore.canBack"
|
:left-arrow="!hasCustomLeft && !!navBarStore.canBack"
|
||||||
@left-click="doBack"
|
@left-click="onLeftClick"
|
||||||
>
|
>
|
||||||
|
<template v-if="hasCustomLeft" #left>
|
||||||
|
<div class="nav-extra nav-extra-left">
|
||||||
|
<component :is="navBarStore.leftRenderer" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #right>
|
<template #right>
|
||||||
<div class="nav-extra">
|
<div class="nav-extra">
|
||||||
<component :is="navBarStore.rightRenderer" v-if="navBarStore.rightRenderer" />
|
<component :is="navBarStore.rightRenderer" v-if="navBarStore.rightRenderer" />
|
||||||
@@ -80,6 +85,8 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
// ---------- 导航返回 ----------
|
// ---------- 导航返回 ----------
|
||||||
|
|
||||||
|
const hasCustomLeft = computed(() => !!navBarStore.leftRenderer);
|
||||||
|
|
||||||
function doBack(): void {
|
function doBack(): void {
|
||||||
if (navBarStore.backTo) {
|
if (navBarStore.backTo) {
|
||||||
router.push(navBarStore.backTo);
|
router.push(navBarStore.backTo);
|
||||||
@@ -89,6 +96,14 @@ function doBack(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onLeftClick(): void {
|
||||||
|
if (hasCustomLeft.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
doBack();
|
||||||
|
}
|
||||||
|
|
||||||
const navBarPadding = computed(() => {
|
const navBarPadding = computed(() => {
|
||||||
if (navBarStore.isShowing) {
|
if (navBarStore.isShowing) {
|
||||||
return `${navBarStore.height || 48}px`;
|
return `${navBarStore.height || 48}px`;
|
||||||
@@ -202,6 +217,10 @@ const contentHeight = computed(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-extra-left {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.router-view {
|
.router-view {
|
||||||
|
|||||||
@@ -393,10 +393,4 @@ function getDirectoryKey(pathSegments: string[]): string {
|
|||||||
font-size: .8125rem;
|
font-size: .8125rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.theme-dark) .page {
|
|
||||||
.go-up {
|
|
||||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .22);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,103 +1,84 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page">
|
<div class="connect-setting">
|
||||||
<section class="card">
|
<t-cell-group title="服务器连接" theme="card">
|
||||||
<div class="head">
|
<t-cell title="使用 HTTPS">
|
||||||
<p class="tag">连接配置</p>
|
<template #rightIcon>
|
||||||
<h2 class="header">服务器连接</h2>
|
<t-switch v-model="httpsEnabled" />
|
||||||
<p class="desc">这里的配置会持久化保存,缺失时应用会强制回到连接引导页。</p>
|
</template>
|
||||||
</div>
|
</t-cell>
|
||||||
|
<t-input
|
||||||
<div class="group">
|
v-model.trim="form.host"
|
||||||
<p class="label">协议</p>
|
clearable
|
||||||
<div class="protocols">
|
label="地址"
|
||||||
<t-button
|
placeholder="192.168.1.10 或 nas.local"
|
||||||
size="small"
|
/>
|
||||||
theme="primary"
|
<t-input
|
||||||
:variant="form.protocol === 'http' ? 'base' : 'outline'"
|
v-model.trim="form.port"
|
||||||
@click="setProtocol('http')"
|
clearable
|
||||||
>
|
label="端口"
|
||||||
HTTP
|
placeholder="8080"
|
||||||
</t-button>
|
type="number"
|
||||||
<t-button
|
/>
|
||||||
size="small"
|
<t-input
|
||||||
theme="primary"
|
v-model.trim="form.token"
|
||||||
:variant="form.protocol === 'https' ? 'base' : 'outline'"
|
clearable
|
||||||
@click="setProtocol('https')"
|
label="密钥"
|
||||||
>
|
placeholder="请输入访问密钥"
|
||||||
HTTPS
|
/>
|
||||||
</t-button>
|
</t-cell-group>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="group">
|
|
||||||
<p class="label">主机地址</p>
|
|
||||||
<t-input v-model="form.host" clearable placeholder="例如 192.168.1.100 或 nas.local" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="group">
|
|
||||||
<p class="label">端口</p>
|
|
||||||
<t-input v-model="form.port" clearable type="number" placeholder="例如 8080" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="group">
|
|
||||||
<p class="label">访问令牌</p>
|
|
||||||
<t-input v-model="form.token" clearable placeholder="请输入 token" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<t-button block theme="primary" @click="saveConnect">
|
|
||||||
保存连接配置
|
|
||||||
</t-button>
|
|
||||||
<t-button block variant="outline" @click="resetConnect">
|
|
||||||
清空连接配置
|
|
||||||
</t-button>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Toast } from "tdesign-mobile-vue";
|
import { Toast } from "tdesign-mobile-vue";
|
||||||
import type { ConnectProtocol, ConnectSetting } from "@/store/settingStore";
|
import { useNavBarStore } from "@/store/navBarStore";
|
||||||
|
import type { ConnectSetting } from "@/store/settingStore";
|
||||||
import { useSettingStore } from "@/store/settingStore";
|
import { useSettingStore } from "@/store/settingStore";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "ConnectSetting"
|
name: "ConnectSetting"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const navBarStore = useNavBarStore();
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
|
|
||||||
const form = reactive<ConnectSetting>({
|
// ---------- 顶部导航 ----------
|
||||||
protocol: "http",
|
|
||||||
host: "",
|
const navBarOwner = `connect-setting-${Math.random().toString(36).slice(2)}`;
|
||||||
port: "",
|
|
||||||
token: ""
|
const navBarLeftRenderer = defineComponent({
|
||||||
|
name: "connect-setting-nav-left",
|
||||||
|
setup() {
|
||||||
|
const buttonComponent = resolveComponent("t-button");
|
||||||
|
|
||||||
|
return () => h(buttonComponent, {
|
||||||
|
variant: "text",
|
||||||
|
theme: "default",
|
||||||
|
size: "small",
|
||||||
|
onClick: cancelConnect
|
||||||
|
}, () => "取消");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
const navBarRightRenderer = defineComponent({
|
||||||
() => settingStore.connect,
|
name: "connect-setting-nav-right",
|
||||||
(connect) => {
|
setup() {
|
||||||
Object.assign(form, connect);
|
const buttonComponent = resolveComponent("t-button");
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
function setProtocol(protocol: ConnectProtocol): void {
|
return () => h(buttonComponent, {
|
||||||
form.protocol = protocol;
|
variant: "text",
|
||||||
|
theme: "primary",
|
||||||
|
size: "small",
|
||||||
|
onClick: saveConnect
|
||||||
|
}, () => "保存");
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateConnect(): boolean {
|
|
||||||
const host = form.host.trim();
|
|
||||||
const port = form.port.trim();
|
|
||||||
const token = form.token.trim();
|
|
||||||
|
|
||||||
if (!host || !port || !token) {
|
|
||||||
Toast({
|
|
||||||
theme: "warning",
|
|
||||||
message: "请完整填写连接配置"
|
|
||||||
});
|
});
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
function cancelConnect(): void {
|
||||||
|
Object.assign(form, settingStore.connect);
|
||||||
|
router.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveConnect(): void {
|
function saveConnect(): void {
|
||||||
@@ -112,69 +93,57 @@ function saveConnect(): void {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetConnect(): void {
|
onMounted(() => {
|
||||||
settingStore.resetConnect();
|
navBarStore.setLeftRenderer(navBarLeftRenderer, navBarOwner);
|
||||||
Object.assign(form, settingStore.connect);
|
navBarStore.setRightRenderer(navBarRightRenderer, navBarOwner);
|
||||||
Toast({
|
|
||||||
theme: "success",
|
|
||||||
message: "连接配置已清空"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
navBarStore.clearLeft(navBarOwner);
|
||||||
|
navBarStore.clearRight(navBarOwner);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---------- 表单 ----------
|
||||||
|
|
||||||
|
const form = reactive<ConnectSetting>({
|
||||||
|
protocol: "http",
|
||||||
|
host: "",
|
||||||
|
port: "",
|
||||||
|
token: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(() => settingStore.connect, (connect) => {
|
||||||
|
Object.assign(form, connect);
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
|
const httpsEnabled = computed({
|
||||||
|
get: () => form.protocol === "https",
|
||||||
|
set: (value: boolean) => {
|
||||||
|
form.protocol = value ? "https" : "http";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function validateConnect(): boolean {
|
||||||
|
const host = form.host.trim();
|
||||||
|
const port = form.port.trim();
|
||||||
|
const token = form.token.trim();
|
||||||
|
if (!host || !port || !token) {
|
||||||
|
Toast({
|
||||||
|
theme: "warning",
|
||||||
|
message: "请完整填写连接配置"
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.page {
|
.connect-setting {
|
||||||
padding: 1rem;
|
padding-top: var(--app-nav-offset);
|
||||||
|
|
||||||
.card {
|
:deep(.t-input:last-child:after) {
|
||||||
gap: 1rem;
|
background: transparent;
|
||||||
display: flex;
|
|
||||||
padding: 1rem;
|
|
||||||
border-radius: 1rem;
|
|
||||||
flex-direction: column;
|
|
||||||
border: 1px solid var(--app-line);
|
|
||||||
background: var(--app-card);
|
|
||||||
box-shadow: 0 .35rem 1rem rgba(17, 32, 56, .05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.head,
|
|
||||||
.group {
|
|
||||||
gap: .5rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag,
|
|
||||||
.label,
|
|
||||||
.desc {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--app-sub);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag,
|
|
||||||
.label {
|
|
||||||
font-size: .875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desc {
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.protocols {
|
|
||||||
gap: .75rem;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.theme-dark) .page {
|
|
||||||
.card {
|
|
||||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -256,10 +256,4 @@ function normalizeSecondValue(value: string, fallback: number): number {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.theme-dark) .page {
|
|
||||||
.card {
|
|
||||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -84,10 +84,4 @@ const themeModeList: Array<{ label: string; value: ThemeMode }> = [
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.theme-dark) .page {
|
|
||||||
.card {
|
|
||||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page">
|
<div class="connect-setting">
|
||||||
<section class="card">
|
<section class="card">
|
||||||
<div class="head">
|
<div class="head">
|
||||||
<p class="tag">系统设置</p>
|
<p class="tag">系统设置</p>
|
||||||
@@ -42,7 +42,7 @@ function openThemeSetting(): void {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.page {
|
.connect-setting {
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
@@ -91,7 +91,7 @@ function openThemeSetting(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.theme-dark) .page {
|
:global(.theme-dark) .connect-setting {
|
||||||
.card {
|
.card {
|
||||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .2);
|
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,8 @@ const router = createRouter({
|
|||||||
navBarVisible: true,
|
navBarVisible: true,
|
||||||
navBarCanBack: true,
|
navBarCanBack: true,
|
||||||
navBarTitle: "连接配置",
|
navBarTitle: "连接配置",
|
||||||
tabBarVisible: false
|
tabBarVisible: false,
|
||||||
|
bodyBackground: "#F4F4F4"
|
||||||
},
|
},
|
||||||
component: ConnectSetting
|
component: ConnectSetting
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export const useNavBarStore = defineStore("nav-bar", () => {
|
|||||||
const height = ref(0);
|
const height = ref(0);
|
||||||
const title = ref("");
|
const title = ref("");
|
||||||
const backTo = ref<string>();
|
const backTo = ref<string>();
|
||||||
|
const leftRenderer = shallowRef<Component>();
|
||||||
|
const leftOwner = ref<string>();
|
||||||
const rightRenderer = shallowRef<Component>();
|
const rightRenderer = shallowRef<Component>();
|
||||||
const rightOwner = ref<string>();
|
const rightOwner = ref<string>();
|
||||||
|
|
||||||
@@ -34,6 +36,20 @@ export const useNavBarStore = defineStore("nav-bar", () => {
|
|||||||
title.value = value || "";
|
title.value = value || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setLeftRenderer(renderer?: Component, owner?: string): void {
|
||||||
|
leftRenderer.value = renderer;
|
||||||
|
leftOwner.value = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearLeft(owner?: string): void {
|
||||||
|
if (owner && leftOwner.value !== owner) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
leftRenderer.value = undefined;
|
||||||
|
leftOwner.value = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
function setRightRenderer(renderer?: Component, owner?: string): void {
|
function setRightRenderer(renderer?: Component, owner?: string): void {
|
||||||
rightRenderer.value = renderer;
|
rightRenderer.value = renderer;
|
||||||
rightOwner.value = owner;
|
rightOwner.value = owner;
|
||||||
@@ -52,12 +68,15 @@ export const useNavBarStore = defineStore("nav-bar", () => {
|
|||||||
height,
|
height,
|
||||||
title,
|
title,
|
||||||
backTo,
|
backTo,
|
||||||
|
leftRenderer,
|
||||||
rightRenderer,
|
rightRenderer,
|
||||||
isShowing,
|
isShowing,
|
||||||
canBack,
|
canBack,
|
||||||
setHeight,
|
setHeight,
|
||||||
setBackTo,
|
setBackTo,
|
||||||
setTitle,
|
setTitle,
|
||||||
|
setLeftRenderer,
|
||||||
|
clearLeft,
|
||||||
setRightRenderer,
|
setRightRenderer,
|
||||||
clearRight
|
clearRight
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user