feat: watch UI empty shell (3-page swiper, mascot, sessions, settings, detail, input)
This commit is contained in:
@@ -1,3 +1,12 @@
|
|||||||
|
# DSHWatch(手表端 / Vela 快应用)
|
||||||
|
|
||||||
|
跟随 DeepSeek Harness 的 DSHWatch 手表客户端外壳(UI 空壳阶段)。
|
||||||
|
|
||||||
|
- 三页左右滑动(会话 / 主页吉祥物 / 设置),底部长条+小点指示器。
|
||||||
|
- 吉祥物图取自 dsh-whale-widget 的 DSniang。
|
||||||
|
- 页面:pages/index、pages/detail、pages/input、pages/settings。
|
||||||
|
- 数据通道:后续接入 @system.interconnect(与手机 APP 通信)。
|
||||||
|
|
||||||
## 快速上手
|
## 快速上手
|
||||||
|
|
||||||
### 1. 开发
|
### 1. 开发
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
onCreate() {
|
onCreate() {
|
||||||
console.log("app created")
|
console.log('DSHWatch app created')
|
||||||
},
|
},
|
||||||
onDestroy() {
|
onDestroy() {
|
||||||
console.log("app destroyed")
|
console.log('DSHWatch app destroyed')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// DSHWatch bridge stub (empty-shell UI phase)
|
||||||
|
// 真正的 interconnect 逻辑后续接入。这里先留一个数据/回调占位,方便页面引用。
|
||||||
|
|
||||||
|
const listeners = []
|
||||||
|
|
||||||
|
function setStatus(text) {
|
||||||
|
// 空壳:后续改为广播给页面
|
||||||
|
listeners.forEach((fn) => fn && fn(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
function connect() {
|
||||||
|
// 空壳
|
||||||
|
setStatus('未连接')
|
||||||
|
}
|
||||||
|
|
||||||
|
export { connect, setStatus }
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 456 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 250 KiB |
+13
-14
@@ -1,31 +1,30 @@
|
|||||||
{
|
{
|
||||||
"package": "com.application.watch.demo",
|
"package": "com.dshwatch.app",
|
||||||
"name": "DSHWatch",
|
"name": "DSHWatch",
|
||||||
"versionName": "1.0.0",
|
"versionName": "0.1.0",
|
||||||
"versionCode": 1,
|
"versionCode": 1,
|
||||||
"minPlatformVersion": 1000,
|
"minPlatformVersion": 1200,
|
||||||
"icon": "/common/logo.png",
|
"icon": "/common/logo.png",
|
||||||
|
"simulationVersion": "default",
|
||||||
"deviceTypeList": [
|
"deviceTypeList": [
|
||||||
"watch"
|
"watch"
|
||||||
],
|
],
|
||||||
"features": [
|
"features": [
|
||||||
{
|
{ "name": "system.router" },
|
||||||
"name": "system.router"
|
{ "name": "system.interconnect" }
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"logLevel": "log",
|
"logLevel": "log",
|
||||||
"designWidth": "device-width"
|
"designWidth": 480
|
||||||
},
|
},
|
||||||
"router": {
|
"router": {
|
||||||
"entry": "pages/index",
|
"entry": "pages/index",
|
||||||
"pages": {
|
"pages": {
|
||||||
"pages/index": {
|
"pages/index": { "component": "index" },
|
||||||
"component": "index"
|
"pages/detail": { "component": "detail" },
|
||||||
},
|
"pages/input": { "component": "input" },
|
||||||
"pages/detail": {
|
"pages/settings": { "component": "settings" }
|
||||||
"component": "detail"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"minAPILevel": 1
|
||||||
}
|
}
|
||||||
+110
-7
@@ -1,26 +1,129 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="demo-page">
|
<div class="page">
|
||||||
<text class="title">{{ text }}</text>
|
<text class="title">会话详情 / 状态</text>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<text class="card-label">当前会话</text>
|
||||||
|
<text class="card-value">{{activeSession}}</text>
|
||||||
|
<text class="card-label">状态</text>
|
||||||
|
<text class="card-value">{{statusText}}</text>
|
||||||
|
<text class="card-label">模型</text>
|
||||||
|
<text class="card-value">{{model}}</text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<text class="title">最近事件</text>
|
||||||
|
<div class="event-list">
|
||||||
|
<div class="event-row" for="{{events}}" tid="{{$index}}">
|
||||||
|
<text class="event-text">{{$item}}</text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<text class="hint" if="{{!events.length}}">暂无事件</text>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
<input class="btn" type="button" value="输入" onclick="openInput" />
|
||||||
|
<input class="btn btn-ghost" type="button" value="返回" onclick="goBack" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import router from '@system.router'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
private: {
|
private: {
|
||||||
text: "欢迎打开详情页"
|
activeSession: 'demo-1',
|
||||||
|
statusText: '未连接',
|
||||||
|
model: 'deepseek-chat',
|
||||||
|
events: []
|
||||||
|
},
|
||||||
|
onInit() {
|
||||||
|
// 空壳:后续从 index 页/全局状态传入
|
||||||
|
},
|
||||||
|
openInput() {
|
||||||
|
router.push({ uri: '/pages/input' })
|
||||||
|
},
|
||||||
|
goBack() {
|
||||||
|
router.back()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.demo-page {
|
.page {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
padding: 12px;
|
||||||
align-items: center;
|
box-sizing: border-box;
|
||||||
|
background-color: #0b1220;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 20px;
|
color: #e6f0ff;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background-color: #152238;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-label {
|
||||||
|
color: #8fa4c9;
|
||||||
|
font-size: 13px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-value {
|
||||||
|
color: #dbe8ff;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-list {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-row {
|
||||||
|
padding: 6px 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #152238;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-text {
|
||||||
|
color: #b7c8e8;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
color: #6b7a99;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
flex-direction: row;
|
||||||
|
margin-top: 16px;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 110px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 20px;
|
||||||
|
background-color: #33b4ff;
|
||||||
|
color: #08131f;
|
||||||
|
font-size: 16px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-ghost {
|
||||||
|
background-color: #1c2c47;
|
||||||
|
color: #dbe8ff;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+254
-22
@@ -1,48 +1,280 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="demo-page">
|
<div class="page">
|
||||||
<text class="title">{{ $t("a.b") }},欢迎打开{{ title }}</text>
|
<swiper class="swiper" ref="swiper" index="{{currentIndex}}" indicator="false" loop="false"
|
||||||
<!-- 点击跳转详情页 -->
|
previousmargin="14px" nextmargin="14px" onchange="onSwipeChange">
|
||||||
<input class="btn" type="button" value="跳转到详情页" onclick="routeDetail" />
|
<!-- 左页:会话 -->
|
||||||
|
<div class="page-item left-page">
|
||||||
|
<text class="page-title">会话</text>
|
||||||
|
<div class="session-list">
|
||||||
|
<div class="session-row" for="{{sessions}}" tid="{{$item.sessionId}}" onclick="selectSession({{$index}})">
|
||||||
|
<text class="session-title">{{$item.title}}</text>
|
||||||
|
<text class="session-dot" if="{{$item.running}}">●</text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<text class="page-hint" if="{{!sessions.length}}">暂无会话</text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 中页:主页 / 吉祥物 -->
|
||||||
|
<div class="page-item center-page">
|
||||||
|
<image class="mascot" src="/common/dsniang.png" onclick="openDetail" />
|
||||||
|
<text class="status-text">{{statusText}}</text>
|
||||||
|
<text class="session-hint">{{activeTitle}}</text>
|
||||||
|
<div class="center-actions">
|
||||||
|
<input class="btn" type="button" value="输入" onclick="openInput" />
|
||||||
|
<input class="btn btn-ghost" type="button" value="详情" onclick="openDetail" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右页:设置 -->
|
||||||
|
<div class="page-item right-page">
|
||||||
|
<text class="page-title">设置</text>
|
||||||
|
<text class="setting-label">服务器</text>
|
||||||
|
<input class="setting-input" type="text" value="{{settings.serverUrl}}" onchange="onServerChange" />
|
||||||
|
<text class="setting-label">用户ID</text>
|
||||||
|
<input class="setting-input" type="text" value="{{settings.userId}}" onchange="onUserChange" />
|
||||||
|
<text class="setting-label">Token</text>
|
||||||
|
<input class="setting-input" type="password" value="{{settings.token}}" onchange="onTokenChange" />
|
||||||
|
<text class="conn-text">{{connText}}</text>
|
||||||
|
<input class="btn" type="button" value="连接状态" onclick="refreshConn" />
|
||||||
|
<input class="btn btn-ghost" type="button" value="更多设置" onclick="openSettings" />
|
||||||
|
</div>
|
||||||
|
</swiper>
|
||||||
|
|
||||||
|
<div class="dots">
|
||||||
|
<div class="dot {{currentIndex == 0 ? 'dot-active' : ''}}"></div>
|
||||||
|
<div class="dot {{currentIndex == 1 ? 'dot-active' : ''}}"></div>
|
||||||
|
<div class="dot {{currentIndex == 2 ? 'dot-active' : ''}}"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import router from "@system.router"
|
import router from '@system.router'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// 页面级组件的数据模型,影响传入数据的覆盖机制:private内定义的属性不允许被覆盖
|
|
||||||
private: {
|
private: {
|
||||||
title: "示例页面"
|
currentIndex: 1,
|
||||||
|
sessions: [
|
||||||
|
{ sessionId: 'demo-1', title: '原型演示会话', running: false },
|
||||||
|
{ sessionId: 'demo-2', title: 'UI 对齐中', running: true },
|
||||||
|
{ sessionId: 'demo-3', title: '待接入 Harness', running: false }
|
||||||
|
],
|
||||||
|
statusText: '未连接',
|
||||||
|
activeTitle: '会话 demo-1',
|
||||||
|
settings: {
|
||||||
|
serverUrl: 'ws://127.0.0.1:8787',
|
||||||
|
userId: '',
|
||||||
|
token: ''
|
||||||
|
},
|
||||||
|
connText: '手机/手表未连接'
|
||||||
},
|
},
|
||||||
|
|
||||||
routeDetail() {
|
onInit() {
|
||||||
// 跳转到应用内的某个页面,router用法详见:文档->接口->页面路由
|
// 空壳:暂无逻辑
|
||||||
router.push({
|
},
|
||||||
uri: "/pages/detail"
|
|
||||||
})
|
onReady() {
|
||||||
|
// 空壳:后续在此初始化 interconnect
|
||||||
|
this.refreshConn()
|
||||||
|
},
|
||||||
|
|
||||||
|
onSwipeChange(e) {
|
||||||
|
if (e && typeof e.index === 'number') {
|
||||||
|
this.currentIndex = e.index
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
goTo(index) {
|
||||||
|
this.currentIndex = index
|
||||||
|
if (this.$refs && this.$refs.swiper && this.$refs.swiper.swipeTo) {
|
||||||
|
this.$refs.swiper.swipeTo({ index })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
selectSession(index) {
|
||||||
|
const item = this.sessions[index]
|
||||||
|
if (item) {
|
||||||
|
this.activeTitle = '会话 ' + item.title
|
||||||
|
this.goTo(1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
openDetail() {
|
||||||
|
router.push({ uri: '/pages/detail' })
|
||||||
|
},
|
||||||
|
|
||||||
|
openInput() {
|
||||||
|
router.push({ uri: '/pages/input' })
|
||||||
|
},
|
||||||
|
|
||||||
|
openSettings() {
|
||||||
|
router.push({ uri: '/pages/settings' })
|
||||||
|
},
|
||||||
|
|
||||||
|
onServerChange(e) { this.settings.serverUrl = e && e.value || '' },
|
||||||
|
onUserChange(e) { this.settings.userId = e && e.value || '' },
|
||||||
|
onTokenChange(e) { this.settings.token = e && e.value || '' },
|
||||||
|
|
||||||
|
refreshConn() {
|
||||||
|
// 空壳:后续通过 interconnect getReadyState 获取真实连接状态
|
||||||
|
this.connText = '手机/手表未连接'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.demo-page {
|
.page {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #0b1220;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper {
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
indicator-size: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-item {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-page,
|
||||||
|
.right-page {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-page {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.page-title {
|
||||||
font-size: 20px;
|
color: #e6f0ff;
|
||||||
text-align: center;
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-hint {
|
||||||
|
color: #6b7a99;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-list {
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-row {
|
||||||
|
width: 100%;
|
||||||
|
height: 44px;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #152238;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-title {
|
||||||
|
color: #dbe8ff;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-dot {
|
||||||
|
color: #33b4ff;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mascot {
|
||||||
|
width: 180px;
|
||||||
|
height: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
color: #e6f0ff;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-hint {
|
||||||
|
color: #7d8fb0;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-actions {
|
||||||
|
flex-direction: row;
|
||||||
|
margin-top: 18px;
|
||||||
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
width: 200px;
|
width: 100px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-top: 20px;
|
border-radius: 20px;
|
||||||
border-radius: 5px;
|
background-color: #33b4ff;
|
||||||
background-color: #09ba07;
|
color: #08131f;
|
||||||
font-size: 20px;
|
font-size: 16px;
|
||||||
color: #ffffff;
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ghost {
|
||||||
|
background-color: #1c2c47;
|
||||||
|
color: #dbe8ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-label {
|
||||||
|
color: #8fa4c9;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-input {
|
||||||
|
width: 100%;
|
||||||
|
height: 38px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #152238;
|
||||||
|
color: #e6f0ff;
|
||||||
|
font-size: 15px;
|
||||||
|
padding: 0 8px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conn-text {
|
||||||
|
color: #6b7a99;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dots {
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 14px;
|
||||||
|
margin-top: 4px;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: rgba(255, 255, 255, 0.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-active {
|
||||||
|
width: 22px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #33b4ff;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page">
|
||||||
|
<text class="title">输入指令</text>
|
||||||
|
<input class="text-input" type="text" value="{{text}}" placeholder="输入内容..." onchange="onTextChange" />
|
||||||
|
<div class="quick-list">
|
||||||
|
<div class="quick-row" for="{{quick}}" tid="{{$index}}" onclick="sendQuick({{$index}})">
|
||||||
|
<text class="quick-text">{{$item}}</text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="actions">
|
||||||
|
<input class="btn" type="button" value="发送" onclick="sendText" />
|
||||||
|
<input class="btn btn-ghost" type="button" value="返回" onclick="goBack" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import router from '@system.router'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
private: {
|
||||||
|
text: '',
|
||||||
|
quick: ['查看今日任务', '总结当前进度', '停止当前任务']
|
||||||
|
},
|
||||||
|
onTextChange(e) {
|
||||||
|
this.text = e && e.value || ''
|
||||||
|
},
|
||||||
|
sendQuick(index) {
|
||||||
|
const item = this.quick[index]
|
||||||
|
// 空壳:后续通过 interconnect 发给手机/服务器
|
||||||
|
console.log('quick send', item)
|
||||||
|
this.text = item
|
||||||
|
},
|
||||||
|
sendText() {
|
||||||
|
// 空壳:后续通过 interconnect 发送
|
||||||
|
console.log('send text', this.text)
|
||||||
|
},
|
||||||
|
goBack() {
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.page {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #0b1220;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #e6f0ff;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-input {
|
||||||
|
width: 100%;
|
||||||
|
height: 64px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background-color: #152238;
|
||||||
|
color: #e6f0ff;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 0 10px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-list {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-row {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #152238;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-text {
|
||||||
|
color: #b7c8e8;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
flex-direction: row;
|
||||||
|
margin-top: 16px;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 110px;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 22px;
|
||||||
|
background-color: #33b4ff;
|
||||||
|
color: #08131f;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ghost {
|
||||||
|
background-color: #1c2c47;
|
||||||
|
color: #dbe8ff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page">
|
||||||
|
<text class="title">设置</text>
|
||||||
|
<text class="label">服务器地址</text>
|
||||||
|
<input class="input" type="text" value="{{serverUrl}}" onchange="onServerChange" />
|
||||||
|
<text class="label">用户ID</text>
|
||||||
|
<input class="input" type="text" value="{{userId}}" onchange="onUserChange" />
|
||||||
|
<text class="label">Token</text>
|
||||||
|
<input class="input" type="password" value="{{token}}" onchange="onTokenChange" />
|
||||||
|
<text class="label">连接模式</text>
|
||||||
|
<text class="mode">{{mode}}</text>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
<input class="btn" type="button" value="保存(空壳)" onclick="save" />
|
||||||
|
<input class="btn btn-ghost" type="button" value="返回" onclick="goBack" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import router from '@system.router'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
private: {
|
||||||
|
serverUrl: 'ws://127.0.0.1:8787',
|
||||||
|
userId: '',
|
||||||
|
token: '',
|
||||||
|
mode: 'relay(服务器中转)'
|
||||||
|
},
|
||||||
|
onServerChange(e) { this.serverUrl = e && e.value || '' },
|
||||||
|
onUserChange(e) { this.userId = e && e.value || '' },
|
||||||
|
onTokenChange(e) { this.token = e && e.value || '' },
|
||||||
|
save() {
|
||||||
|
// 空壳:后续持久化并与 index 页同步
|
||||||
|
console.log('save settings', this.serverUrl, this.userId)
|
||||||
|
},
|
||||||
|
goBack() {
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.page {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #0b1220;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #e6f0ff;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #8fa4c9;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
width: 100%;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #152238;
|
||||||
|
color: #e6f0ff;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 0 10px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode {
|
||||||
|
color: #b7c8e8;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
flex-direction: row;
|
||||||
|
margin-top: 18px;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 130px;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 22px;
|
||||||
|
background-color: #33b4ff;
|
||||||
|
color: #08131f;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ghost {
|
||||||
|
background-color: #1c2c47;
|
||||||
|
color: #dbe8ff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user