update config frontend

This commit is contained in:
bridge
2026-01-01 17:42:07 +08:00
parent 5d69334b13
commit 3837e3eafa
7 changed files with 154 additions and 143 deletions

View File

@@ -114,17 +114,20 @@ watch(() => props.visible, (val) => {
.system-menu {
background: #1a1a1a;
width: 820px;
height: 620px;
width: 95vw;
height: 90vh;
max-width: 1920px;
/* 动态基准字号最小16px正常为视口短边的2%最大28px */
font-size: clamp(16px, 2vmin, 28px);
border: 1px solid #333;
border-radius: 8px;
border-radius: 0.5em;
display: flex;
flex-direction: column;
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
box-shadow: 0 0.5em 1.5em rgba(0,0,0,0.5);
}
.menu-header {
padding: 16px;
padding: 1em;
border-bottom: 1px solid #333;
display: flex;
justify-content: space-between;
@@ -133,7 +136,7 @@ watch(() => props.visible, (val) => {
.menu-header h2 {
margin: 0;
font-size: 18px;
font-size: 1.2em;
color: #ddd;
}
@@ -141,8 +144,9 @@ watch(() => props.visible, (val) => {
background: none;
border: none;
color: #999;
font-size: 24px;
font-size: 1.5em;
cursor: pointer;
padding: 0 0.5em;
}
.menu-tabs {
@@ -152,12 +156,13 @@ watch(() => props.visible, (val) => {
.menu-tabs button {
flex: 1;
padding: 12px;
padding: 0.8em;
background: #222;
border: none;
color: #888;
cursor: pointer;
transition: all 0.2s;
font-size: 1em;
}
.menu-tabs button:hover {
@@ -167,12 +172,12 @@ watch(() => props.visible, (val) => {
.menu-tabs button.active {
background: #1a1a1a;
color: #fff;
border-bottom: 2px solid #4a9eff;
border-bottom: 0.15em solid #4a9eff;
}
.menu-content {
flex: 1;
padding: 20px;
padding: 1.5em;
overflow-y: auto;
}
</style>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import type { AvatarDetail, EffectEntity } from '@/types/core';
import { formatHp, formatAge } from '@/utils/formatters/number';
import { formatHp } from '@/utils/formatters/number';
import StatItem from './components/StatItem.vue';
import EntityRow from './components/EntityRow.vue';
import RelationRow from './components/RelationRow.vue';
@@ -98,7 +98,7 @@ async function handleClearObjective() {
label="宗门"
:value="data.sect?.name || '散修'"
:sub-value="data.sect?.rank"
:on-click="data.sect ? () => jumpToSect(data.sect.id) : undefined"
:on-click="data.sect ? () => jumpToSect(data.sect!.id) : undefined"
/>
<StatItem

View File

@@ -206,7 +206,7 @@ onMounted(() => {
<n-form label-placement="left" label-width="80">
<n-form-item label="姓名">
<div class="name-inputs">
<n-input v-model:value="createForm.surname" placeholder="姓" style="width: 80px" />
<n-input v-model:value="createForm.surname" placeholder="姓" style="width: 6em" />
<n-input v-model:value="createForm.given_name" placeholder="名" style="flex: 1" />
</div>
</n-form-item>
@@ -218,7 +218,7 @@ onMounted(() => {
</n-form-item>
<n-form-item label="年龄">
<n-slider v-model:value="createForm.age" :min="16" :max="100" :step="1" />
<span style="margin-left: 10px; width: 50px">{{ createForm.age }}</span>
<span style="margin-left: 0.8em; width: 4em">{{ createForm.age }}</span>
</n-form-item>
<n-form-item label="初始境界">
<n-select v-model:value="createForm.level" :options="realmOptions" placeholder="选择初始境界" />
@@ -261,13 +261,13 @@ onMounted(() => {
:options="avatarOptions"
placeholder="选择角色"
filterable
style="width: 160px"
style="width: 12em"
/>
<n-select
v-model:value="rel.relation"
:options="relationOptions"
placeholder="关系"
style="width: 100px"
style="width: 8em"
/>
<n-button @click="removeRelation(index)" circle size="small" type="error">-</n-button>
</div>
@@ -311,37 +311,37 @@ onMounted(() => {
.loading {
text-align: center;
color: #888;
padding: 40px;
padding: 3em;
}
.create-layout {
display: flex;
gap: 20px;
gap: 1.5em;
height: 100%;
}
.form-column {
flex: 1;
min-width: 320px;
min-width: 20em;
}
.avatar-column {
width: 300px;
width: 20em;
display: flex;
flex-direction: column;
gap: 12px;
gap: 0.8em;
}
.name-inputs {
display: flex;
gap: 10px;
gap: 0.8em;
}
.avatar-preview {
width: 100%;
height: 220px;
height: 15em;
border: 1px solid #444;
border-radius: 4px;
border-radius: 0.3em;
display: flex;
align-items: center;
justify-content: center;
@@ -357,27 +357,27 @@ onMounted(() => {
.no-avatar {
color: #666;
font-size: 12px;
font-size: 0.85em;
}
.avatar-grid {
flex: 1;
overflow-y: auto;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
grid-auto-rows: 80px;
gap: 8px;
padding: 6px;
grid-template-columns: repeat(auto-fill, minmax(4em, 1fr));
grid-auto-rows: 5em;
gap: 0.5em;
padding: 0.4em;
border: 1px solid #333;
border-radius: 4px;
min-height: 220px;
border-radius: 0.3em;
min-height: 15em;
}
.avatar-option {
width: 100%;
height: 100%;
border: 2px solid transparent;
border-radius: 6px;
border-radius: 0.4em;
overflow: hidden;
cursor: pointer;
background: #111;
@@ -400,20 +400,20 @@ onMounted(() => {
width: 100%;
height: 100%;
object-fit: contain;
padding: 2px;
padding: 0.15em;
}
.no-avatars {
grid-column: span 4;
text-align: center;
color: #666;
font-size: 12px;
font-size: 0.85em;
}
.appearance-slider {
display: flex;
align-items: center;
gap: 12px;
gap: 0.8em;
flex: 1;
min-width: 0;
}
@@ -424,7 +424,7 @@ onMounted(() => {
}
.appearance-slider span {
width: 32px;
width: 2.5em;
text-align: right;
color: #ddd;
}
@@ -433,16 +433,16 @@ onMounted(() => {
width: 100%;
display: flex;
flex-direction: column;
gap: 8px;
gap: 0.6em;
}
.relation-row {
display: flex;
gap: 8px;
gap: 0.6em;
align-items: center;
}
.actions {
margin-top: 20px;
margin-top: 1.5em;
}
</style>

View File

@@ -86,27 +86,27 @@ onMounted(() => {
}
.search-bar {
margin-bottom: 15px;
margin-bottom: 1em;
}
.loading {
text-align: center;
color: #888;
padding: 40px;
padding: 3em;
}
.empty {
text-align: center;
color: #666;
padding: 40px;
padding: 3em;
}
.avatar-item {
background: #222;
border: 1px solid #333;
padding: 12px;
margin-bottom: 10px;
border-radius: 4px;
padding: 0.8em;
margin-bottom: 0.8em;
border-radius: 0.3em;
display: flex;
justify-content: space-between;
align-items: center;
@@ -122,12 +122,12 @@ onMounted(() => {
.avatar-info .name {
color: #fff;
font-weight: bold;
font-size: 14px;
font-size: 1em;
}
.avatar-info .details {
color: #888;
font-size: 12px;
margin-top: 4px;
font-size: 0.85em;
margin-top: 0.3em;
}
</style>

View File

@@ -271,6 +271,9 @@ onMounted(() => {
<p>
您的 API Key 仅保存在您的本地电脑配置文件中 (`static/local_config.yml`)由本地运行的游戏后端直接与模型厂商通信本游戏 (Cultivation World Simulator) 是完全开源的程序绝不会将您的 Key 上传至任何第三方服务器也请注意不要把local_config.yml文件分享给任何人
</p>
<p>
使用token会产生费用请自行评估使用成本
</p>
</div>
</div>
@@ -286,31 +289,31 @@ onMounted(() => {
.llm-panel {
height: 100%;
overflow-y: auto;
padding: 0 10px;
padding: 0 0.8em;
}
.loading {
text-align: center;
color: #888;
padding: 40px;
padding: 3em;
}
.section {
margin-bottom: 24px;
margin-bottom: 1.5em;
}
.section-title {
font-size: 14px;
font-size: 1em;
font-weight: bold;
color: #ddd;
margin-bottom: 12px;
border-left: 3px solid #4a9eff;
padding-left: 8px;
margin-bottom: 0.8em;
border-left: 0.2em solid #4a9eff;
padding-left: 0.5em;
}
.preset-buttons {
display: flex;
gap: 10px;
gap: 0.8em;
flex-wrap: wrap;
}
@@ -318,11 +321,11 @@ onMounted(() => {
background: #333;
border: 1px solid #444;
color: #ccc;
padding: 6px 12px;
border-radius: 4px;
padding: 0.4em 0.8em;
border-radius: 0.3em;
cursor: pointer;
transition: all 0.2s;
font-size: 12px;
font-size: 0.85em;
}
.preset-btn:hover {
@@ -332,20 +335,20 @@ onMounted(() => {
}
.form-item {
margin-bottom: 16px;
margin-bottom: 1.2em;
}
.form-item label {
display: block;
font-size: 13px;
font-size: 0.9em;
color: #bbb;
margin-bottom: 6px;
margin-bottom: 0.4em;
}
.form-item .desc {
font-size: 11px;
font-size: 0.8em;
color: #666;
margin-bottom: 6px;
margin-bottom: 0.4em;
}
.input-field {
@@ -353,10 +356,10 @@ onMounted(() => {
background: #222;
border: 1px solid #444;
color: #ddd;
padding: 8px 10px;
border-radius: 4px;
padding: 0.6em 0.8em;
border-radius: 0.3em;
font-family: monospace;
font-size: 13px;
font-size: 0.9em;
}
.input-field:focus {
@@ -369,16 +372,16 @@ onMounted(() => {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 6px;
margin-bottom: 0.4em;
}
.help-btn {
background: none;
border: 1px solid #444;
color: #888;
font-size: 11px;
padding: 2px 8px;
border-radius: 10px;
font-size: 0.8em;
padding: 0.2em 0.6em;
border-radius: 1em;
cursor: pointer;
transition: all 0.2s;
}
@@ -392,7 +395,7 @@ onMounted(() => {
.mode-options.horizontal {
display: flex;
flex-direction: row;
gap: 10px;
gap: 0.8em;
}
.mode-options.horizontal .mode-radio {
@@ -400,15 +403,15 @@ onMounted(() => {
flex-direction: column;
align-items: center;
text-align: center;
padding: 12px 6px;
padding: 0.8em 0.4em;
}
.mode-radio {
display: flex;
background: #222;
border: 1px solid #333;
padding: 10px;
border-radius: 4px;
padding: 0.8em;
border-radius: 0.3em;
cursor: pointer;
transition: all 0.2s;
}
@@ -432,14 +435,14 @@ onMounted(() => {
.radio-label {
color: #ddd;
font-size: 13px;
font-size: 0.9em;
font-weight: bold;
margin-bottom: 4px;
margin-bottom: 0.3em;
}
.radio-desc {
color: #777;
font-size: 11px;
font-size: 0.8em;
line-height: 1.3;
}
@@ -460,18 +463,19 @@ onMounted(() => {
.modal-content {
background: #0f1115;
border: 1px solid #333;
border-radius: 12px;
width: 700px;
border-radius: 0.8em;
width: 50em;
max-width: 90vw;
max-height: 90vh;
display: flex;
flex-direction: column;
box-shadow: 0 20px 50px rgba(0,0,0,0.7);
box-shadow: 0 1.5em 3em rgba(0,0,0,0.7);
overflow: hidden;
font-size: 1rem; /* 重置 modal 内部字体,避免过大,或者保留继承 */
}
.modal-header {
padding: 20px 24px;
padding: 1.2em 1.5em;
border-bottom: 1px solid #222;
display: flex;
justify-content: space-between;
@@ -481,22 +485,22 @@ onMounted(() => {
.modal-header h3 {
margin: 0;
font-size: 18px;
font-size: 1.2em;
color: #fff;
display: flex;
align-items: center;
gap: 8px;
gap: 0.5em;
}
.modal-header h3::before {
content: "?";
display: inline-flex;
width: 20px;
height: 20px;
width: 1.4em;
height: 1.4em;
border: 1px solid #00e0b0;
color: #00e0b0;
border-radius: 50%;
font-size: 14px;
font-size: 0.9em;
align-items: center;
justify-content: center;
}
@@ -505,7 +509,7 @@ onMounted(() => {
background: none;
border: none;
color: #666;
font-size: 24px;
font-size: 1.5em;
cursor: pointer;
transition: color 0.2s;
}
@@ -517,48 +521,48 @@ onMounted(() => {
.modal-body {
flex: 1;
overflow-y: auto;
padding: 24px;
padding: 1.5em;
color: #aaa;
}
.help-section {
margin-bottom: 30px;
margin-bottom: 2em;
}
.help-section h4 {
color: #6da; /* 类似截图中的青绿色 */
font-size: 16px;
margin: 0 0 12px 0;
color: #6da;
font-size: 1.1em;
margin: 0 0 0.8em 0;
}
.help-section p {
line-height: 1.6;
margin: 0 0 10px 0;
font-size: 14px;
margin: 0 0 0.6em 0;
font-size: 0.95em;
}
.model-cards {
display: flex;
gap: 12px;
margin-top: 12px;
gap: 0.8em;
margin-top: 0.8em;
}
.card {
flex: 1;
background: #16181d;
border: 1px solid #333;
border-radius: 8px;
padding: 12px;
border-radius: 0.5em;
padding: 0.8em;
}
.card h5 {
color: #8a9eff;
margin: 0 0 8px 0;
font-size: 14px;
margin: 0 0 0.5em 0;
font-size: 0.95em;
}
.card p {
font-size: 12px;
font-size: 0.85em;
color: #777;
margin: 0;
}
@@ -566,13 +570,13 @@ onMounted(() => {
.code-block {
background: #111;
border: 1px solid #2a2a2a;
border-radius: 8px;
padding: 16px;
border-radius: 0.5em;
padding: 1em;
font-family: monospace;
}
.code-block p {
margin-bottom: 8px;
margin-bottom: 0.5em;
}
.code-block p:last-child {
@@ -585,8 +589,8 @@ onMounted(() => {
.code-block code {
background: #333;
padding: 2px 6px;
border-radius: 4px;
padding: 0.1em 0.4em;
border-radius: 0.2em;
color: #ff79c6;
}
@@ -596,7 +600,7 @@ onMounted(() => {
margin: 0;
background: #16181d;
border: 1px solid #333;
border-radius: 8px;
border-radius: 0.5em;
}
.link-list li {
@@ -610,10 +614,10 @@ onMounted(() => {
.link-list a {
display: flex;
justify-content: space-between;
padding: 12px 16px;
padding: 0.8em 1em;
color: #ddd;
text-decoration: none;
font-size: 14px;
font-size: 0.95em;
transition: background 0.2s;
}
@@ -627,19 +631,19 @@ onMounted(() => {
}
.modal-footer {
padding: 16px 24px;
padding: 1em 1.5em;
border-top: 1px solid #222;
background: #0f1115;
}
.confirm-btn {
width: 100%;
background: #0099cc; /* 类似截图中的蓝色按钮 */
background: #0099cc;
color: white;
border: none;
padding: 12px;
border-radius: 6px;
font-size: 16px;
padding: 0.8em;
border-radius: 0.4em;
font-size: 1em;
font-weight: bold;
cursor: pointer;
transition: background 0.2s;
@@ -652,16 +656,16 @@ onMounted(() => {
.action-bar {
display: flex;
justify-content: flex-end;
padding-bottom: 20px;
padding-bottom: 1.5em;
}
.save-btn {
background: #2a8a4a;
color: #fff;
border: none;
padding: 10px 24px;
border-radius: 4px;
font-size: 14px;
padding: 0.7em 1.5em;
border-radius: 0.3em;
font-size: 0.95em;
cursor: pointer;
transition: background 0.2s;
}

View File

@@ -112,14 +112,14 @@ onMounted(() => {
.save-panel {
align-items: center;
padding-top: 40px;
padding-top: 3em;
}
.new-save-card {
width: 200px;
height: 150px;
width: 15em;
height: 11em;
border: 2px dashed #444;
border-radius: 8px;
border-radius: 0.5em;
display: flex;
flex-direction: column;
align-items: center;
@@ -127,7 +127,7 @@ onMounted(() => {
cursor: pointer;
transition: all 0.2s;
color: #888;
margin-bottom: 40px;
margin-bottom: 3em;
}
.new-save-card:hover {
@@ -137,22 +137,22 @@ onMounted(() => {
}
.new-save-card .icon {
font-size: 40px;
margin-bottom: 10px;
font-size: 3em;
margin-bottom: 0.2em;
}
.new-save-card .sub {
font-size: 12px;
font-size: 0.85em;
color: #666;
margin-top: 5px;
margin-top: 0.4em;
}
.save-item {
background: #222;
border: 1px solid #333;
padding: 12px;
margin-bottom: 10px;
border-radius: 4px;
padding: 0.8em;
margin-bottom: 0.8em;
border-radius: 0.3em;
display: flex;
justify-content: space-between;
align-items: center;
@@ -162,8 +162,9 @@ onMounted(() => {
}
.save-panel .save-item {
cursor: default; /* 存档模式下列表仅展示,不可点击加载 */
width: 600px;
cursor: default;
width: 100%;
max-width: 45em;
}
.save-item:hover {
@@ -174,18 +175,18 @@ onMounted(() => {
.save-info .save-time {
color: #fff;
font-weight: bold;
font-size: 14px;
font-size: 1em;
}
.save-info .game-time {
color: #4a9eff;
font-size: 13px;
margin: 4px 0;
font-size: 0.9em;
margin: 0.3em 0;
}
.save-info .filename {
color: #666;
font-size: 12px;
font-size: 0.85em;
font-family: monospace;
}
@@ -193,14 +194,15 @@ onMounted(() => {
background: #333;
color: #ddd;
border: 1px solid #444;
padding: 6px 16px;
border-radius: 4px;
padding: 0.4em 1em;
border-radius: 0.3em;
font-size: 0.9em;
}
.loading, .empty {
text-align: center;
color: #888;
padding: 40px;
padding: 3em;
width: 100%;
}
</style>

View File

@@ -1,9 +1,9 @@
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { gameApi } from '../api/game';
import type { AvatarDetail, RegionDetail, HoverLine } from '../types/core';
import type { AvatarDetail, RegionDetail, SectDetail, HoverLine } from '../types/core';
export type SelectionType = 'avatar' | 'region';
export type SelectionType = 'avatar' | 'region' | 'sect';
export interface Selection {
type: SelectionType;
@@ -16,7 +16,7 @@ export const useUiStore = defineStore('ui', () => {
const selectedTarget = ref<Selection | null>(null);
// 详情数据 (可能为空,或正在加载)
const detailData = ref<AvatarDetail | RegionDetail | null>(null);
const detailData = ref<AvatarDetail | RegionDetail | SectDetail | null>(null);
const isLoadingDetail = ref(false);
const detailError = ref<string | null>(null);