🎉 项目基础架构完成

This commit is contained in:
li-chx 2025-04-23 17:43:14 +08:00
commit 15c0a1de0e
40 changed files with 2645 additions and 0 deletions

Binary file not shown.

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Nuxt dev/build outputs
.output
.nuxt
.nitro
.cache
dist
# Node dependencies
node_modules
# Logs
logs
*.log
# Misc
.DS_Store
.fleet
.idea
# Local env files
.env
.env.*
!.env.example
/pnpm-lock.yaml

3
.npmrc Normal file
View File

@ -0,0 +1,3 @@
# 由于使用了 @nuxtjs/tailwindcsstailwindcss 不是直接依赖,
# 需要将依赖平铺在 node_modules 中,否则 VS Code 插件不会启用语法支持
shamefully-hoist=true

0
.nuxtignore Normal file
View File

102
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,102 @@
{
"i18n-ally.localesPaths": "lang", //
"i18n-ally.sourceLanguage": "zh", //
"i18n-ally.displayLanguage": "zh", //
"i18n-ally.keystyle": "nested", // nested flat:
"i18n-ally.preferredDelimiter": "_",
"i18n-ally.sortKeys": true,
// "i18n-ally.extract.keygenStrategy": "random", // slugrandomempty
// "i18n-ally.extract.keygenStyle": "camelCase", //
"i18n-ally.enabledParsers": ["json", "js", "ts"],
"i18n-ally.keysInUse": [
"view.progress_submenu.translated_keys",
"view.progress_submenu.missing_keys",
"view.progress_submenu.empty_keys"
],
"i18n-ally.theme.annotationMissingBorder": "#d37070",
"i18n-ally.theme.annotationMissing": "#d37070",
"npm.packageManager": "pnpm",
"editor.tabSize": 2,
"files.eol": "\n",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.expand": false,
"explorer.fileNesting.patterns": {
"*.asax": "$(capture).*.cs, $(capture).*.vb",
"*.ascx": "$(capture).*.cs, $(capture).*.vb",
"*.ashx": "$(capture).*.cs, $(capture).*.vb",
"*.aspx": "$(capture).*.cs, $(capture).*.vb",
"*.bloc.dart": "$(capture).event.dart, $(capture).state.dart",
"*.c": "$(capture).h",
"*.cc": "$(capture).hpp, $(capture).h, $(capture).hxx",
"*.component.ts": "$(capture).component.html, $(capture).component.spec.ts, $(capture).component.css, $(capture).component.scss, $(capture).component.sass, $(capture).component.less",
"*.cpp": "$(capture).hpp, $(capture).h, $(capture).hxx",
"*.cs": "$(capture).*.cs",
"*.cshtml": "$(capture).cshtml.cs",
"*.csproj": "*.config, *proj.user, appsettings.*, bundleconfig.json",
"*.css": "$(capture).css.map, $(capture).*.css",
"*.cxx": "$(capture).hpp, $(capture).h, $(capture).hxx",
"*.dart": "$(capture).freezed.dart, $(capture).g.dart",
"*.ex": "$(capture).html.eex, $(capture).html.heex, $(capture).html.leex",
"*.go": "$(capture)_test.go",
"*.java": "$(capture).class",
"*.js": "$(capture).js.map, $(capture).*.js, $(capture)_*.js",
"*.jsx": "$(capture).js, $(capture).*.jsx, $(capture)_*.js, $(capture)_*.jsx",
"*.master": "$(capture).*.cs, $(capture).*.vb",
"*.module.ts": "$(capture).resolver.ts, $(capture).controller.ts, $(capture).service.ts",
"*.pubxml": "$(capture).pubxml.user",
"*.resx": "$(capture).*.resx, $(capture).designer.cs, $(capture).designer.vb",
"*.tex": "$(capture).acn, $(capture).acr, $(capture).alg, $(capture).aux, $(capture).bbl, $(capture).blg, $(capture).fdb_latexmk, $(capture).fls, $(capture).glg, $(capture).glo, $(capture).gls, $(capture).idx, $(capture).ind, $(capture).ist, $(capture).lof, $(capture).log, $(capture).lot, $(capture).out, $(capture).pdf, $(capture).synctex.gz, $(capture).toc, $(capture).xdv",
"*.ts": "$(capture).js, $(capture).d.ts.map, $(capture).*.ts, $(capture)_*.js, $(capture)_*.ts",
"*.tsx": "$(capture).ts, $(capture).*.tsx, $(capture)_*.ts, $(capture)_*.tsx",
"*.vbproj": "*.config, *proj.user, appsettings.*, bundleconfig.json",
"*.vue": "$(capture).*.ts, $(capture).*.js, $(capture).story.vue",
"*.xaml": "$(capture).xaml.cs",
"+layout.svelte": "+layout.ts,+layout.ts,+layout.js,+layout.server.ts,+layout.server.js",
"+page.svelte": "+page.server.ts,+page.server.js,+page.ts,+page.js ",
".clang-tidy": ".clang-format, .clangd, compile_commands.json",
".env": "*.env, .env.*, .envrc, env.d.ts",
".gitignore": ".gitattributes, .gitmodules, .gitmessage, .mailmap, .git-blame*",
".project": ".classpath",
"BUILD.bazel": "*.bzl, *.bazel, *.bazelrc, bazel.rc, .bazelignore, .bazelproject, WORKSPACE",
"CMakeLists.txt": "*.cmake, *.cmake.in, .cmake-format.yaml, CMakePresets.json",
"I*.cs": "$(capture).cs",
"artisan": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, playwright.config.*, postcss.config.*, puppeteer.config.*, server.php, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, webpack.mix.js, windi.config.*",
"astro.config.*": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, playwright.config.*, postcss.config.*, puppeteer.config.*, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, windi.config.*",
"cargo.toml": ".clippy.toml, .rustfmt.toml, cargo.lock, clippy.toml, cross.toml, rust-toolchain.toml, rustfmt.toml",
"composer.json": ".php*.cache, composer.lock, phpunit.xml*, psalm*.xml",
"default.nix": "shell.nix",
"deno.json*": "*.env, .env.*, .envrc, api-extractor.json, env.d.ts, import-map.json, import_map.json, jsconfig.*, tsconfig.*, tsdoc.*",
"dockerfile": ".dockerignore, docker-compose.*, dockerfile*",
"flake.nix": "flake.lock",
"gatsby-config.*": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, gatsby-browser.*, gatsby-node.*, gatsby-ssr.*, gatsby-transformer.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, playwright.config.*, postcss.config.*, puppeteer.config.*, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, windi.config.*",
"gemfile": ".ruby-version, gemfile.lock",
"go.mod": ".air*, go.sum",
"go.work": "go.work.sum",
"mix.exs": ".credo.exs, .dialyzer_ignore.exs, .formatter.exs, .iex.exs, .tool-versions, mix.lock",
"next.config.*": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, next-env.d.ts, playwright.config.*, postcss.config.*, puppeteer.config.*, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, windi.config.*",
"nuxt.config.*": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, playwright.config.*, postcss.config.*, puppeteer.config.*, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, windi.config.*",
"package.json": ".browserslist*, .circleci*, .commitlint*, .cz-config.js, .czrc, .dlint.json, .dprint.json, .editorconfig, .eslint*, .firebase*, .flowconfig, .github*, .gitlab*, .gitpod*, .huskyrc*, .jslint*, .lintstagedrc*, .markdownlint*, .node-version, .nodemon*, .npm*, .nvmrc, .pm2*, .pnp.*, .pnpm*, .prettier*, .releaserc*, .sentry*, .stackblitz*, .styleci*, .stylelint*, .tazerc*, .textlint*, .tool-versions, .travis*, .versionrc*, .vscode*, .watchman*, .xo-config*, .yamllint*, .yarnrc*, Procfile, apollo.config.*, appveyor*, azure-pipelines*, bower.json, build.config.*, commitlint*, crowdin*, dangerfile*, dlint.json, dprint.json, firebase.json, grunt*, gulp*, jenkins*, lerna*, lint-staged*, nest-cli.*, netlify*, nodemon*, nx.*, package-lock.json, package.nls*.json, phpcs.xml, pm2.*, pnpm*, prettier*, pullapprove*, pyrightconfig.json, release-tasks.sh, renovate*, rollup.config.*, stylelint*, tslint*, tsup.config.*, turbo*, typedoc*, unlighthouse*, vercel*, vetur.config.*, webpack*, workspace.json, xo.config.*, yarn*",
"pubspec.yaml": ".metadata, .packages, all_lint_rules.yaml, analysis_options.yaml, build.yaml, pubspec.lock, pubspec_overrides.yaml",
"pyproject.toml": ".pdm.toml, pdm.lock, pyproject.toml",
"quasar.conf.js": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, playwright.config.*, postcss.config.*, puppeteer.config.*, quasar.extensions.json, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, windi.config.*",
"readme*": "authors, backers*, changelog*, citation*, code_of_conduct*, codeowners, contributing*, contributors, copying, credits, governance.md, history.md, license*, maintainers, readme*, security.md, sponsors*",
"remix.config.*": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, playwright.config.*, postcss.config.*, puppeteer.config.*, remix.*, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, windi.config.*",
"rush.json": ".browserslist*, .circleci*, .commitlint*, .cz-config.js, .czrc, .dlint.json, .dprint.json, .editorconfig, .eslint*, .firebase*, .flowconfig, .github*, .gitlab*, .gitpod*, .huskyrc*, .jslint*, .lintstagedrc*, .markdownlint*, .node-version, .nodemon*, .npm*, .nvmrc, .pm2*, .pnp.*, .pnpm*, .prettier*, .releaserc*, .sentry*, .stackblitz*, .styleci*, .stylelint*, .tazerc*, .textlint*, .tool-versions, .travis*, .versionrc*, .vscode*, .watchman*, .xo-config*, .yamllint*, .yarnrc*, Procfile, apollo.config.*, appveyor*, azure-pipelines*, bower.json, build.config.*, commitlint*, crowdin*, dangerfile*, dlint.json, dprint.json, firebase.json, grunt*, gulp*, jenkins*, lerna*, lint-staged*, nest-cli.*, netlify*, nodemon*, nx.*, package-lock.json, package.nls*.json, phpcs.xml, pm2.*, pnpm*, prettier*, pullapprove*, pyrightconfig.json, release-tasks.sh, renovate*, rollup.config.*, stylelint*, tslint*, tsup.config.*, turbo*, typedoc*, unlighthouse*, vercel*, vetur.config.*, webpack*, workspace.json, xo.config.*, yarn*",
"shims.d.ts": "*.d.ts",
"svelte.config.*": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, mdsvex.config.js, playwright.config.*, postcss.config.*, puppeteer.config.*, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, windi.config.*",
"vite.config.*": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, playwright.config.*, postcss.config.*, puppeteer.config.*, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, windi.config.*",
"vue.config.*": "*.env, .babelrc*, .codecov, .cssnanorc*, .env.*, .envrc, .htmlnanorc*, .lighthouserc.*, .mocha*, .postcssrc*, .terserrc*, api-extractor.json, ava.config.*, babel.config.*, contentlayer.config.*, cssnano.config.*, cypress.*, env.d.ts, formkit.config.*, formulate.config.*, histoire.config.*, htmlnanorc.*, jasmine.*, jest.config.*, jsconfig.*, karma*, lighthouserc.*, playwright.config.*, postcss.config.*, puppeteer.config.*, svgo.config.*, tailwind.config.*, tsconfig.*, tsdoc.*, unocss.config.*, vitest.config.*, webpack.config.*, windi.config.*"
}
}

91
README.md Normal file
View File

@ -0,0 +1,91 @@
# TDesign Vue + Nuxt Starter
> [!NOTE]
> Nuxt 4 即将发布,此模板的维护重心将会转向 Nuxt 4请留意官方的 [Nuxt 3 -> 4 迁移说明](https://nuxt.com/docs/getting-started/upgrade#migrating-to-nuxt-4)。Nuxt 3 版本的模板将会移动到 [`nuxt3`](https://github.com/AnotiaWang/tdesign-vue-nuxt-starter/tree/nuxt3) 分支。
![](https://s21.ax1x.com/2024/06/15/pkwSjC6.png)
本模板仓库使用 [Nuxt 3](https://nuxt.com/docs/getting-started/introduction) (Vue 3) 和 [TDesign Vue Next](https://tdesign.tencent.com/vue-next) 组件库。
除此之外,还使用了以下依赖:
- [Tailwind CSS](https://tailwindcss.com/)
- [Nuxt Color Mode](https://color-mode.nuxtjs.org/): 深色/浅色模式
- ESLint + Prettier: 代码风格检查 + 美化
- [unplugin-auto-import 和 unplugin-vue-components](https://unplugin.unjs.io): 自动导入 TDesign Vue Next 的组件以实现 [tree shaking](https://en.wikipedia.org/wiki/Tree_shaking)
- pnpm v9
## 快速使用本模板
```bash
# 使用 main 分支
npx -y nuxi init -t gh:AnotiaWang/tdesign-vue-nuxt-starter <项目名>
# 如要继续使用 Nuxt 3 版本,请使用 `nuxt3` 分支
npx -y nuxi init -t gh:AnotiaWang/tdesign-vue-nuxt-starter#nuxt3 <项目名>
```
## 目录结构
```
.
├── app # 前端相关
│ ├── components # 全局组件
│ ├── hooks # 自定义 hooks
│ ├── layouts # Nuxt 布局
│ ├── pages # 页面,每个 SFC 代表一个页面,可用文件夹嵌套
│ └── types # TypeScript 类型定义,目前包含了 unplugin 自动生成的类型
├── node_modules
├── public # 静态资源
│ └── styles
└── server # 后端相关
```
## 自定义主题
TDesign 支持 [自定义主题](https://tdesign.tencent.com/vue-next/custom-theme)。按照以下步骤修改主题:
1. 在文档页面,点击页面底部的刷子图标,进入主题编辑器。调整完想要的效果后,点击下载按钮,保存 CSS 文件到本地。
2. 将 CSS 文件移动到 `public/styles` 文件夹下,并命名为 `tdesign-theme-{name}.css`,其中 `name` 是你给主题取的名字。
3. 在 `hooks/useTheme.ts` 中,修改:
```ts
type Theme = 'default' | 'test' // 添加/修改成你自己的主题名
```
如有需要,可以配置 defineStore 部分中的 `theme` 变量为你想要的初始主题,默认为 `default`
然后就可以在代码中调用了:
```ts
const theme = useThemeStore()
theme.setTheme('default')
```
## Setup
```bash
pnpm install
```
## Development Server
Start the development server on `http://localhost:3000`:
```bash
pnpm dev
```
## Production
Build the application for production:
```bash
pnpm build
```
Locally preview production build:
```bash
pnpm preview
```

19
app/app.vue Normal file
View File

@ -0,0 +1,19 @@
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
<script setup lang="ts">
const colorMode = useColorMode();
onMounted(() => {
watchEffect(() => {
if (colorMode.value === 'dark') {
document.documentElement.setAttribute('theme-mode', 'dark');
} else {
document.documentElement.removeAttribute('theme-mode');
}
});
});
</script>

View File

@ -0,0 +1,40 @@
<script setup lang="ts">
import type { TableProps, TableRowData } from 'tdesign-vue-next';
const emit = defineEmits(['pageChange', 'onRowClick']);
const data = defineModel<unknown>('data');
const columns = defineModel<TableProps['columns']>('columns');
const loading = defineModel<boolean>('loading');
const pagination = defineModel<TableProps['pagination']>('pagination');
async function onPageChange(pageInfo: { current: number; pageSize: number }) {
console.log('Page change');
console.log(pageInfo);
emit('pageChange', pageInfo);
}
function onRowClick(x: any) {
emit('onRowClick', x);
}
function onSelectChange() {
console.log('Select change');
}
</script>
<template>
<t-table
row-key="index"
:data="data as TableRowData[]"
:columns="columns"
:pagination="pagination"
:table-layout="'auto'"
:bordered="true"
:stripe="true"
:lazy-load="true"
:loading="loading"
@page-change="onPageChange"
@select-change="onSelectChange"
@row-click="onRowClick"
>
</t-table>
</template>

31
app/hooks/useTheme.ts Normal file
View File

@ -0,0 +1,31 @@
type Theme = 'default' | 'test' | 'self';
const themeStorageKey = 'tdesign-vue-next-theme';
export const useThemeStore = defineStore('theme', () => {
const theme = ref<Theme>('default');
const setTheme = (_theme: Theme) => {
theme.value = _theme;
};
onMounted(() => {
const storageValue = localStorage.getItem(themeStorageKey);
if (storageValue) theme.value = storageValue as Theme;
const styleElement = document.createElement('link');
watch(theme, () => {
localStorage.setItem(themeStorageKey, theme.value);
styleElement.type = 'text/css';
styleElement.rel = 'stylesheet';
styleElement.href = `/styles/tdesign-theme-${theme.value}.css?t=${Date.now()}`;
if (styleElement.parentElement === document.head) {
document.head.removeChild(styleElement);
}
document.head.appendChild(styleElement);
});
});
return { theme, setTheme };
});

7
app/layouts/default.vue Normal file
View File

@ -0,0 +1,7 @@
<template>
<div
class="w-screen h-screen bg-white dark:bg-black dark:text-white transition-all"
>
<slot />
</div>
</template>

259
app/pages/base/index.vue Normal file
View File

@ -0,0 +1,259 @@
<script setup lang="ts">
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindConfig from '~/tailwind.config';
import type { Config } from 'tailwindcss';
import { useWindowSize } from '@vueuse/core';
const theme = useThemeStore();
const config = resolveConfig(tailwindConfig as Config);
const { collapsed, manualCollapsed } = storeToRefs(useSystemStore());
const lg = parseFloat(
config.theme.screens.lg.substring(0, config.theme.screens.lg.length - 2),
);
const modeName = ref('sunny');
// watch()
// computed(())
watch(useWindowSize().width, (val) => {
console.log(val);
console.log(collapsed.value);
console.log(manualCollapsed.value);
setCollapsed(val);
});
function setCollapsed(val: number) {
if ((val > lg && !collapsed.value) || (val < lg && collapsed.value)) {
manualCollapsed.value = false;
return;
}
if (val > lg && collapsed.value) {
if (manualCollapsed.value) return;
collapsed.value = false;
} else if (val < lg && !collapsed.value) {
if (manualCollapsed.value) return;
collapsed.value = true;
}
}
function changeCollapsed() {
collapsed.value = !collapsed.value;
manualCollapsed.value = true;
}
const { currentPage } = storeToRefs(useSystemStore());
function changeMode() {
const x = useColorMode();
console.log(x.preference);
console.log(x.value);
if (x.preference === 'light') {
x.preference = 'dark';
modeName.value = 'moon';
} else if (x.preference === 'dark') {
x.preference = 'sepia';
modeName.value = 'tea';
} else {
x.preference = 'light';
modeName.value = 'sunny';
}
}
function changeTheme() {
console.log(theme.theme);
if (theme.theme === 'default') {
theme.setTheme('test');
} else if (theme.theme === 'test') {
theme.setTheme('self');
} else if (theme.theme === 'self') {
theme.setTheme('default');
}
}
function backToLogin() {
const router = useRouter();
router.push('/login');
}
watch(currentPage, (val) => {
const router = useRouter();
router.push('/base/' + val);
});
async function sendTest() {
try {
// const response = await $fetch('/api/login/test', {
// method: 'GET',
// });
$fetch('/api/file/test', { method: 'GET' }).catch(() => {
console.log('error');
$fetch('/api/login/login', {
method: 'POST',
body: {
username: 'admin',
password: 'password',
},
}).then(async () => {
const result = await $fetch('/api/file/test', { method: 'GET' });
console.log(result);
});
});
// const response = await $fetch('/api/login/login', {
// method: 'POST',
// body: {
// username: 'admin',
// password: 'password',
// },
// });
// console.log(response);
} catch (err) {
console.log(err);
}
}
onMounted(() => setCollapsed(useWindowSize().width.value));
</script>
<template>
<t-layout class="h-full">
<t-header>
<t-head-menu value="item1" height="120px">
<span class="text-xl">李晨鑫 Web 实验</span>
<template #operations>
<a @click="changeMode">
<t-icon class="t-menu__operations-icon" :name="modeName" />
</a>
<a @click="changeTheme">
<t-icon class="t-menu__operations-icon" name="fill-color" />
</a>
<a @click="backToLogin">
<t-icon class="t-menu__operations-icon" name="rollback" />
</a>
<t-button @click="sendTest" />
</template>
<!-- <template #logo>-->
<!-- <img-->
<!-- width="136"-->
<!-- class="logo"-->
<!-- src="https://www.tencent.com/img/index/menu_logo_hover.png"-->
<!-- alt="logo"-->
<!-- />-->
<!-- </template>-->
<!-- <t-menu-item value="item1"> 已选内容 </t-menu-item>-->
<!-- <t-menu-item value="item2"> 菜单内容一 </t-menu-item>-->
<!-- <t-menu-item value="item3"> 菜单内容二 </t-menu-item>-->
<!-- <t-menu-item value="item4" :disabled="true"> 菜单内容三 </t-menu-item>-->
<!-- <template #operations>-->
<!-- <a href="javascript:;"-->
<!-- ><t-icon class="t-menu__operations-icon" name="search"-->
<!-- /></a>-->
<!-- <a href="javascript:;"-->
<!-- ><t-icon class="t-menu__operations-icon" name="notification-filled"-->
<!-- /></a>-->
<!-- <a href="javascript:;"-->
<!-- ><t-icon class="t-menu__operations-icon" name="index"-->
<!-- /></a>-->
<!-- </template>-->
</t-head-menu>
</t-header>
<t-layout :class="{ collapsed: collapsed, 'non-collapsed': !collapsed }">
<t-aside class="border-t border-gray-100 dark:border-gray-700">
<t-menu
v-model="currentPage"
theme="light"
value="dashboard"
height="550px"
:collapsed="collapsed"
>
<t-menu-item value="home">
<template #icon>
<t-icon name="home" />
</template>
首页
</t-menu-item>
<t-submenu value="resource" title="功能菜单">
<template #icon>
<t-icon name="server" />
</template>
<t-menu-item value="peopleManage">
<span>用户管理</span>
</t-menu-item>
<t-menu-item value="fileManage">
<span>文件管理</span>
</t-menu-item>
</t-submenu>
<t-menu-item value="root">
<template #icon>
<t-icon name="root-list" />
</template>
导航三
</t-menu-item>
<t-menu-item value="control-platform">
<template #icon>
<t-icon name="control-platform" />
</template>
导航四
</t-menu-item>
<t-menu-item value="precise-monitor">
<template #icon>
<t-icon name="precise-monitor" />
</template>
导航五
</t-menu-item>
<t-menu-item value="mail">
<template #icon>
<t-icon name="mail" />
</template>
导航六
</t-menu-item>
<t-menu-item value="user-circle">
<template #icon>
<t-icon name="user-circle" />
</template>
导航七
</t-menu-item>
<t-menu-item value="play-circle">
<template #icon>
<t-icon name="play-circle" />
</template>
导航八
</t-menu-item>
<t-menu-item value="edit1">
<template #icon>
<t-icon name="edit-1" />
</template>
导航九
</t-menu-item>
<template #operations>
<t-button
class="t-demo-collapse-btn"
variant="text"
shape="square"
@click="changeCollapsed"
>
<template #icon>
<t-icon name="view-list" />
</template>
</t-button>
</template>
</t-menu>
</t-aside>
<t-layout>
<t-content class="overflow-auto">
<NuxtPage />
</t-content>
<t-footer class="m-auto">
Copyright @ 2019-{{ new Date().getFullYear() }} Tencent. All Rights
Reserved
</t-footer>
</t-layout>
</t-layout>
</t-layout>
</template>
<style scoped lang="less">
.collapsed {
:deep(.t-layout__sider) {
@apply w-20;
}
}
.non-collapsed {
:deep(.t-layout__sider) {
@apply w-60;
}
}
</style>

View File

@ -0,0 +1,30 @@
<script setup lang="ts">
const x = ref();
</script>
<template>
<div class="p-6">
<div class="flex md:flex-row flex-col">
<div class="flex-[1] m-2 max-h-80">
<div class="flex flex-row md:flex-col justify-center">
<span class="text-2xl ml-auto mr-auto md:mt-6 mt-20 mb-6"
>欢迎 {{ useUserStore().userName }}
</span>
<t-image
src="/avatar.jpg"
alt="头像"
shape="circle"
:fit="'contain'"
class="max-h-80 max-w-80 m-auto"
/>
</div>
</div>
<div class="flex-[2] m-2">
<t-calendar> </t-calendar>
</div>
</div>
</div>
</template>
<style scoped lang="less"></style>

View File

@ -0,0 +1,87 @@
<script setup lang="tsx">
import SuperTable from '~/components/SuperTable.vue';
import type { TableProps } from 'tdesign-vue-next';
const pagination = ref<TableProps['pagination']>({
defaultPageSize: 10,
total: 100,
defaultCurrent: 1,
});
const columns = ref<TableProps['columns']>([
{
colKey: 'index',
title: '序号',
},
{
colKey: 'date',
title: '日期',
},
{
colKey: 'name',
title: '姓名',
},
{
colKey: 'province',
title: '省份',
},
{
colKey: 'city',
title: '市区',
},
{
colKey: 'address',
title: '地址',
},
{
colKey: '',
title: '邮编',
},
{
colKey: 'operator',
title: '操作',
cell: (_, { row }) => (
<div>
<t-button onClick={() => editUser(row)}>编辑</t-button>
<t-button onClick={() => deleteUser(row)}>删除</t-button>
</div>
),
},
]);
const data = ref([]);
for (let i = 0; i < 30; i++) {
data.value.push({
index: i + 1,
date: '2023-10-01',
name: 'John Doe',
province: 'Province A',
city: 'City A',
address: 'Address A',
postalCode: '123456',
} as never);
}
function editUser(row: never) {}
function deleteUser(row: never) {}
</script>
<template>
<div class="p-6">
<div class="flex justify-between p-4">
<t-button>新增</t-button>
<t-input placeholder="搜索" clearable class="max-w-60">
<template #suffixIcon>
<search-icon :style="{ cursor: 'pointer' }" />
</template>
</t-input>
</div>
<super-table
:data="data"
:columns="columns"
:loading="false"
:pagination="pagination"
></super-table>
</div>
</template>
<style scoped lang="less"></style>

69
app/pages/index.vue Normal file
View File

@ -0,0 +1,69 @@
<template>
<div class="flex flex-col items-center px-4 py-10 gap-y-8 h-full">
<h1 class="text-[26px]">Nuxt & TDesign Vue Next</h1>
<div class="space-x-2">
<TButton
ghost
@click="
$colorMode.preference =
$colorMode.preference === 'light' ? 'dark' : 'light'
"
>
<template #icon>
<TIcon
class="mr-1"
:name="$colorMode.preference === 'light' ? 'heart' : 'heart-filled'"
/>
当前主题{{ $colorMode.preference === 'light' ? 'Light' : 'Dark' }}
</template>
</TButton>
</div>
<div class="flex items-center gap-x-4">
<TButton @click="theme.setTheme('default')">默认主题</TButton>
<TButton @click="theme.setTheme('test')">主题 1</TButton>
<TButton @click="theme.setTheme('self')">主题 2</TButton>
</div>
<div class="grid grid-cols-2 sm:flex flex-row items-center gap-2">
<TButton>按钮示例</TButton>
<TButton theme="warning" loading>按钮示例</TButton>
<TButton theme="danger" disabled>按钮示例</TButton>
<TButton theme="success" variant="outline">按钮示例</TButton>
</div>
<div class="flex flex-col sm:flex-row items-center gap-4">
<!-- tag-name TagName 写法都可以 -->
<t-switch v-model="isLoading" class="flex-none" size="large">
<template #label> 加载中 </template>
</t-switch>
<TTagInput v-model="tags" drag-sort clearable>
<template #label> 你喜欢的前端框架 </template>
</TTagInput>
</div>
<TAlert :theme="alertTheme" close>{{ date }}</TAlert>
</div>
</template>
<script setup lang="ts">
const theme = useThemeStore();
const tags = ref(['Vue', 'React', 'Angular']);
const isLoading = ref(true);
const alertTheme = ref<'success' | 'warning' | 'error' | 'info'>('success');
let date: Date;
onMounted(() => {
date = new Date();
setInterval(() => {
isLoading.value = !isLoading.value;
if (alertTheme.value === 'success') {
alertTheme.value = 'warning';
} else if (alertTheme.value === 'warning') {
alertTheme.value = 'error';
} else if (alertTheme.value === 'error') {
alertTheme.value = 'info';
} else {
alertTheme.value = 'success';
}
}, 2000);
});
</script>

View File

@ -0,0 +1,74 @@
<script setup lang="ts">
import { PageType } from '~/stores/login';
const store = useLoginStore();
const { currentType, loginForm } = storeToRefs(store);
</script>
<template>
<div class="w-full">
<div
class="flex md:flex-row items-center md:justify-center w-full flex-col gap-4"
>
<div class="flex flex-col items-center gap-4">
<button class="w-56 h-10 bg-qqColor text-white rounded-md"
><img class="max-h-7 inline" src="/QQ.png" alt="QQ logo" />
<span class="text-white">QQ登录</span>
</button>
<button class="w-56 h-10 bg-wechatColor rounded-md"
><img
class="max-h-7 inline"
src="public/微信.png"
alt="wechat logo"
/>
<span class="text-white">微信登录</span>
</button>
<button class="w-56 h-10 bg-alipayColor rounded-md"
><img
class="max-h-7 inline"
src="public/支付,支付宝.png"
alt="alipay logo"
/>
<span class="text-black">支付宝登录</span>
</button>
</div>
<div
class="relative hidden md:flex flex-col items-center gap-4 w-2/5 max-w-24 select-none"
>
<div class="w-1 h-44 bg-gray-200"></div>
<div
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full border-4 border-gray-200 w-10 h-10 bg-loginBG"
>
<span
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-1"
>or
</span>
</div>
</div>
<div class="flex flex-col items-center gap-4 mt-3 md:mt-0">
<TInput
v-model="loginForm.username"
class="w-56"
placeholder="请输入用户名"
/>
<TInput
v-model="loginForm.password"
class="w-56"
type="password"
placeholder="请输入密码"
/>
<TButton class="w-56" @click="store.login">登录</TButton>
</div>
</div>
<div
class="flex flex-row items-center bg-gray-600 w-full h-10 justify-around rounded-b-md mt-4"
>
<button class="text-white" @click="currentType = PageType.register"
>注册
</button>
<button class="text-white" @click="currentType = PageType.reset"
>忘记密码
</button>
</div>
</div>
</template>

View File

@ -0,0 +1,140 @@
<script setup lang="ts">
import type {
FormProps,
UploadInstanceFunctions,
FormInstanceFunctions,
} from 'tdesign-vue-next';
import type { IAPIResponse } from '~/utils/APIResponse';
const store = useLoginStore();
const { registerForm, currentType } = storeToRefs(store);
const rules: FormProps['rules'] = {
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ email: true, message: '请输入邮箱', trigger: 'change' },
],
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
passwordRepeat: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{
validator: (val) => val === registerForm.value.password,
message: '两次输入密码不一致',
trigger: 'change',
},
],
birth: [{ required: true, message: '请输入出生日期', trigger: 'change' }],
};
const uploadImage = ref<UploadInstanceFunctions>();
const formInstance = ref<FormInstanceFunctions>();
async function submitForm() {
console.log(formInstance.value);
if (!formInstance.value) return;
const result = await formInstance.value.validate();
if (typeof result === 'boolean' && result) {
formInstance.value.submit();
}
}
</script>
<template>
<div class="w-full">
<div class="flex md:flex-row flex-col items-center gap-4 justify-around">
<div class="flex flex-col items-center gap-4 max-w-96">
<t-form
ref="formInstance"
:label-width="10"
:data="registerForm"
:rules="rules"
@submit="() => store.register()"
>
<t-form-item name="email">
<TInput v-model="registerForm.email" placeholder="请输入邮箱" />
</t-form-item>
<t-form-item name="username">
<TInput
v-model="registerForm.username"
placeholder="请输入用户名"
/>
</t-form-item>
<t-form-item name="password">
<TInput
v-model="registerForm.password"
placeholder="请输入密码"
type="password"
/>
</t-form-item>
<t-form-item name="passwordRepeat">
<TInput
v-model="registerForm.passwordRepeat"
placeholder="请再次输入密码"
type="password"
/>
</t-form-item>
<t-form-item name="birth">
<TDatePicker
v-model="registerForm.birth"
placeholder="请输入出生日期"
/>
</t-form-item>
</t-form>
</div>
<TUpload
ref="uploadImage"
action="/api/file/uploadAvatar"
class="set-width-length bg-white bg-opacity-70"
theme="custom"
accept="image/*"
:draggable="true"
:format-response="
(res) => {
res = res as IAPIResponse<string>;
if (res.code === 200) {
registerForm.avatarURL = res.data;
return { url: res.data };
}
return { fail: res.message };
}
"
>
<div v-if="registerForm.avatarURL" class="aspect-square h-full">
<t-image
:src="registerForm.avatarURL"
class="w-40 h-40 object-cover rounded-md"
fit="contain"
/>
</div>
<div v-else>
<span class="text-blue-400"> 点击上传头像</span>
<span> / 拖拽到此区域 </span>
</div>
</TUpload>
</div>
<div
class="flex flex-row items-center bg-gray-600 w-full h-10 justify-around rounded-b-md mt-4"
>
<button class="text-white" @click="submitForm">注册用户</button>
<button class="text-white" @click="currentType = PageType.login"
>返回登录
</button>
</div>
</div>
</template>
<style scoped lang="less">
:deep(.t-upload__dragger),
.set-width-length {
@apply w-64;
@apply h-40;
@apply p-0;
@apply border-0;
}
// {
// @apply w-40;
// @apply h-40;
//}
:deep(.t-date-picker) {
@apply w-full;
}
</style>

View File

@ -0,0 +1,47 @@
<script setup lang="ts">
const store = useLoginStore();
const { currentType } = storeToRefs(store);
</script>
<template>
<div class="w-full">
<div
class="flex md:flex-row items-center md:justify-center w-full flex-col gap-4"
>
<div class="flex flex-col items-center gap-4">
<!-- <TInput class="w-56" placeholder="请输入邮箱" />-->
<!-- <TButton class="w-56">发送验证码</TButton>-->
<!-- <TInput class="w-56" placeholder="请输入验证码" />-->
<!-- <TInput class="w-56" type="password" placeholder="请输入新密码" />-->
<!-- <TButton class="w-56">确认</TButton>-->
<TInput class="w-56" placeholder="用户名" />
<TInput class="w-56" placeholder="旧密码" />
</div>
<div
class="hidden md:flex flex-col items-center gap-4 w-2/5 max-w-24 select-none"
>
<div class="w-1 h-44 bg-gray-200"></div>
<!-- <div-->
<!-- class="hidden absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full border-4 border-gray-200 w-10 h-10 bg-loginBG"-->
<!-- >-->
<!--&lt;!&ndash; <span&ndash;&gt;-->
<!--&lt;!&ndash; class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-1"&ndash;&gt;-->
<!--&lt;!&ndash; >or&ndash;&gt;-->
<!--&lt;!&ndash; </span>&ndash;&gt;-->
<!-- </div>-->
</div>
<div class="flex flex-col items-center gap-4">
<TInput class="w-56" placeholder="新密码" />
<TInput class="w-56" placeholder="确认新密码" />
</div>
</div>
<div
class="flex flex-row items-center bg-gray-600 w-full h-10 justify-around rounded-b-md mt-4"
>
<button class="text-white" @click="store.register()">修改密码</button>
<button class="text-white" @click="currentType = PageType.login"
>返回登录
</button>
</div>
</div>
</template>

32
app/pages/login/index.vue Normal file
View File

@ -0,0 +1,32 @@
<script setup lang="ts">
import LoginPart from '~/pages/login/components/LoginPart.vue';
import RegisterPart from '~/pages/login/components/RegisterPart.vue';
import ResetPart from '~/pages/login/components/ResetPart.vue';
import { PageType } from '~/stores/login';
const store = useLoginStore();
const { currentType } = storeToRefs(store);
// watch(currentType, (val) => {
// console.log(val);
// });
onMounted(() => {
// useThemeStore().setTheme('test');
// useThemeStore().setTheme('self');
});
</script>
<template>
<div
class="flex justify-center items-center min-h-screen bg-[url('public/fll.jpg')] bg-cover bg-no-repeat bg-fixed bg-center"
>
<div
class="flex flex-col items-center justify-center gap-4 w-3/5 md:w-4/5 max-w-2xl bg-loginBG pt-4 rounded-md bg-opacity-30 dark:bg-darkLoginBG dark:bg-opacity-40"
>
<h1 class="text-3xl font-bold">{{ store.getTypeName }}</h1>
<LoginPart v-if="currentType === PageType.login" />
<register-part v-else-if="currentType === PageType.register" />
<reset-part v-else-if="currentType === PageType.reset" />
</div>
</div>
</template>

82
app/stores/login.ts Normal file
View File

@ -0,0 +1,82 @@
interface RegisterData {
email: string;
username: string;
password: string;
passwordRepeat: string;
birth: string;
avatarURL: string;
}
interface LoginData {
username: string;
password: string;
}
interface resetData {
username: string;
oldPassword: string;
password: string;
passwordRepeat: string;
}
export enum PageType {
'login',
'register',
'reset',
}
export interface LoginStore {
loginForm: LoginData;
registerForm: RegisterData;
resetForm: resetData;
currentType: PageType;
}
export const useLoginStore = defineStore('Login', {
state: (): LoginStore => ({
loginForm: { username: '', password: '' },
registerForm: {
email: '',
username: '',
password: '',
passwordRepeat: '',
birth: '',
avatarURL: '',
},
resetForm: {
username: '',
oldPassword: '',
password: '',
passwordRepeat: '',
},
currentType: PageType.login,
}),
actions: {
async login() {
console.log(this.loginForm);
const router = useRouter();
await router.push('/base/home');
},
async register() {
console.log(this.registerForm);
},
async reset() {
console.log(this.resetForm);
},
},
getters: {
getTypeName: (state) => {
switch (state.currentType) {
case PageType.login:
return '登录';
case PageType.register:
return '注册';
case PageType.reset:
return '重置密码';
default:
console.log('未知');
return '未知';
}
},
},
});

12
app/stores/system.ts Normal file
View File

@ -0,0 +1,12 @@
export interface SystemStore {
currentPage: string;
collapsed: boolean;
manualCollapsed: boolean;
}
export const useSystemStore = defineStore('System', {
state: (): SystemStore => ({
currentPage: 'dashboard',
collapsed: false,
manualCollapsed: false,
}),
});

14
app/stores/user.ts Normal file
View File

@ -0,0 +1,14 @@
export interface UserState {
userId: string;
userName: string;
userEmail: string;
userAvatar: string;
}
export const useUserStore = defineStore('User', {
state: (): UserState => ({
userId: '',
userName: '李晨鑫',
userEmail: '',
userAvatar: '',
}),
});

52
app/tailwind.config.js Normal file
View File

@ -0,0 +1,52 @@
// tailwind config file
import plugin from 'tailwindcss/plugin';
export default {
mode: 'jit',
darkMode: 'class',
theme: {
extend: {
colors: {
wechatColor: '#79b542',
qqColor: '#2f85c4',
alipayColor: '#e9ebea',
loginBG: '#f2f2f2',
darkLoginBG: '#1a1a1a',
},
letterSpacing: {
doublewidest: '.2em',
},
},
screens: {
sm: '640px',
md: '800px',
lg: '1000px',
xl: '1280px',
'2xl': '1536px',
},
},
plugins: [
plugin(function ({ addUtilities }) {
addUtilities({
'.scrollbar-hide': {
/* IE and Edge */
'-ms-overflow-style': 'none',
/* Firefox */
'scrollbar-width': 'none',
/* Safari and Chrome */
'&::-webkit-scrollbar': {
display: 'none',
},
},
});
}),
],
content: [
'./app.vue',
'./components/**/*.{vue,js,ts}',
'./layouts/**/*.vue',
'./pages/**/*.vue',
],
};

151
app/types/auto-imports.d.ts vendored Normal file
View File

@ -0,0 +1,151 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
const APIResponse: typeof import('../utils/APIResponse')['APIResponse']
const ApolloError: (typeof import('@apollo/client/core'))['ApolloError']
const EffectScope: (typeof import('vue'))['EffectScope']
const NetworkStatus: (typeof import('@apollo/client/core'))['NetworkStatus']
const PageType: typeof import('../stores/login')['PageType']
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
const computed: (typeof import('vue'))['computed']
const createApp: (typeof import('vue'))['createApp']
const createPinia: typeof import('pinia')['createPinia']
const customRef: (typeof import('vue'))['customRef']
const defineAsyncComponent: (typeof import('vue'))['defineAsyncComponent']
const defineComponent: (typeof import('vue'))['defineComponent']
const defineStore: typeof import('pinia')['defineStore']
const effectScope: (typeof import('vue'))['effectScope']
const getActivePinia: typeof import('pinia')['getActivePinia']
const getCurrentInstance: (typeof import('vue'))['getCurrentInstance']
const getCurrentScope: (typeof import('vue'))['getCurrentScope']
const h: (typeof import('vue'))['h']
const inject: (typeof import('vue'))['inject']
const isProxy: (typeof import('vue'))['isProxy']
const isReactive: (typeof import('vue'))['isReactive']
const isReadonly: (typeof import('vue'))['isReadonly']
const isRef: (typeof import('vue'))['isRef']
const mapActions: typeof import('pinia')['mapActions']
const mapGetters: typeof import('pinia')['mapGetters']
const mapState: typeof import('pinia')['mapState']
const mapStores: typeof import('pinia')['mapStores']
const mapWritableState: typeof import('pinia')['mapWritableState']
const markRaw: (typeof import('vue'))['markRaw']
const nextTick: (typeof import('vue'))['nextTick']
const onActivated: (typeof import('vue'))['onActivated']
const onAddToFavorites: (typeof import('@dcloudio/uni-app'))['onAddToFavorites']
const onBackPress: (typeof import('@dcloudio/uni-app'))['onBackPress']
const onBeforeMount: (typeof import('vue'))['onBeforeMount']
const onBeforeUnmount: (typeof import('vue'))['onBeforeUnmount']
const onBeforeUpdate: (typeof import('vue'))['onBeforeUpdate']
const onDeactivated: (typeof import('vue'))['onDeactivated']
const onError: (typeof import('@dcloudio/uni-app'))['onError']
const onErrorCaptured: (typeof import('vue'))['onErrorCaptured']
const onHide: (typeof import('@dcloudio/uni-app'))['onHide']
const onLaunch: (typeof import('@dcloudio/uni-app'))['onLaunch']
const onLoad: (typeof import('@dcloudio/uni-app'))['onLoad']
const onMounted: (typeof import('vue'))['onMounted']
const onNavigationBarButtonTap: (typeof import('@dcloudio/uni-app'))['onNavigationBarButtonTap']
const onNavigationBarSearchInputChanged: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputChanged']
const onNavigationBarSearchInputClicked: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputClicked']
const onNavigationBarSearchInputConfirmed: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputConfirmed']
const onNavigationBarSearchInputFocusChanged: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputFocusChanged']
const onPageNotFound: (typeof import('@dcloudio/uni-app'))['onPageNotFound']
const onPageScroll: (typeof import('@dcloudio/uni-app'))['onPageScroll']
const onPullDownRefresh: (typeof import('@dcloudio/uni-app'))['onPullDownRefresh']
const onReachBottom: (typeof import('@dcloudio/uni-app'))['onReachBottom']
const onReady: (typeof import('@dcloudio/uni-app'))['onReady']
const onRenderTracked: (typeof import('vue'))['onRenderTracked']
const onRenderTriggered: (typeof import('vue'))['onRenderTriggered']
const onResize: (typeof import('@dcloudio/uni-app'))['onResize']
const onScopeDispose: (typeof import('vue'))['onScopeDispose']
const onServerPrefetch: (typeof import('vue'))['onServerPrefetch']
const onShareAppMessage: (typeof import('@dcloudio/uni-app'))['onShareAppMessage']
const onShareTimeline: (typeof import('@dcloudio/uni-app'))['onShareTimeline']
const onShow: (typeof import('@dcloudio/uni-app'))['onShow']
const onTabItemTap: (typeof import('@dcloudio/uni-app'))['onTabItemTap']
const onThemeChange: (typeof import('@dcloudio/uni-app'))['onThemeChange']
const onUnhandledRejection: (typeof import('@dcloudio/uni-app'))['onUnhandledRejection']
const onUnload: (typeof import('@dcloudio/uni-app'))['onUnload']
const onUnmounted: (typeof import('vue'))['onUnmounted']
const onUpdated: (typeof import('vue'))['onUpdated']
const produce: (typeof import('immer'))['produce']
const provide: (typeof import('vue'))['provide']
const reactive: (typeof import('vue'))['reactive']
const readonly: (typeof import('vue'))['readonly']
const ref: (typeof import('vue'))['ref']
const resolveComponent: (typeof import('vue'))['resolveComponent']
const setActivePinia: typeof import('pinia')['setActivePinia']
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
const shallowReactive: (typeof import('vue'))['shallowReactive']
const shallowReadonly: (typeof import('vue'))['shallowReadonly']
const shallowRef: (typeof import('vue'))['shallowRef']
const storeToRefs: typeof import('pinia')['storeToRefs']
const toRaw: (typeof import('vue'))['toRaw']
const toRef: (typeof import('vue'))['toRef']
const toRefs: (typeof import('vue'))['toRefs']
const toValue: (typeof import('vue'))['toValue']
const triggerRef: (typeof import('vue'))['triggerRef']
const unref: (typeof import('vue'))['unref']
const useApolloClient: (typeof import('@vue/apollo-composable'))['useApolloClient']
const useAttrs: (typeof import('vue'))['useAttrs']
const useCssModule: (typeof import('vue'))['useCssModule']
const useCssVars: (typeof import('vue'))['useCssVars']
const useLazyQuery: (typeof import('@vue/apollo-composable'))['useLazyQuery']
const useLoginStore: typeof import('../stores/login')['useLoginStore']
const useMutation: (typeof import('@vue/apollo-composable'))['useMutation']
const useQuery: (typeof import('@vue/apollo-composable'))['useQuery']
const useSlots: (typeof import('vue'))['useSlots']
const useSystemStore: typeof import('../stores/system')['useSystemStore']
const useThemeStore: typeof import('../hooks/useTheme')['useThemeStore']
const useUserStore: typeof import('../stores/user')['useUserStore']
const watch: (typeof import('vue'))['watch']
const watchEffect: (typeof import('vue'))['watchEffect']
const watchPostEffect: (typeof import('vue'))['watchPostEffect']
const watchSyncEffect: (typeof import('vue'))['watchSyncEffect']
}
// for type re-export
declare global {
// @ts-ignore
export type { PageType, LoginStore } from '../stores/login'
import('../stores/login')
// @ts-ignore
export type { SystemStore } from '../stores/system'
import('../stores/system')
// @ts-ignore
export type { UserState } from '../stores/user'
import('../stores/user')
// @ts-ignore
export type { APIResponse, IAPIResponse } from '../utils/APIResponse'
import('../utils/APIResponse')
}
// for vue template auto import
import { UnwrapRef } from 'vue'
declare module 'vue' {
interface GlobalComponents {}
interface ComponentCustomProperties {
readonly APIResponse: UnwrapRef<typeof import('../utils/APIResponse')['APIResponse']>
readonly PageType: UnwrapRef<typeof import('../stores/login')['PageType']>
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>
readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>
readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>
readonly mapStores: UnwrapRef<typeof import('pinia')['mapStores']>
readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']>
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
readonly useLoginStore: UnwrapRef<typeof import('../stores/login')['useLoginStore']>
readonly useSystemStore: UnwrapRef<typeof import('../stores/system')['useSystemStore']>
readonly useThemeStore: UnwrapRef<typeof import('../hooks/useTheme')['useThemeStore']>
readonly useUserStore: UnwrapRef<typeof import('../stores/user')['useUserStore']>
}
}

14
app/types/components.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

10
app/utils/APIResponse.ts Normal file
View File

@ -0,0 +1,10 @@
export interface IAPIResponse<T> {
code: number;
message: string;
data: T;
}
export class APIResponse<T> implements IAPIResponse<T> {
code: number = 200;
message: string = '';
data: T = undefined as T;
}

7
eslint.config.mjs Normal file
View File

@ -0,0 +1,7 @@
// @ts-check
import withNuxt from './.nuxt/eslint.config.mjs';
// @ts-ignore
import configPrettier from 'eslint-config-prettier';
import pluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
export default withNuxt(pluginPrettierRecommended, configPrettier);

80
nuxt.config.ts Normal file
View File

@ -0,0 +1,80 @@
import Components from 'unplugin-vue-components/vite';
import AutoImport from 'unplugin-auto-import/vite';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
'@pinia/nuxt', // '@nuxtjs/robots',
'@nuxtjs/tailwindcss',
'@nuxtjs/color-mode', // '@nuxtjs/sitemap',
'@nuxt/eslint',
'@tdesign-vue-next/nuxt', // '@nuxt/content',
'@nuxt/scripts',
],
build: {
transpile: ['tdesign-vue-next'],
},
plugins: [],
tailwindcss: {
configPath: './app/tailwind.config.js',
exposeConfig: true,
viewer: true,
},
colorMode: {
preference: 'system',
dataValue: 'theme',
classSuffix: '',
},
// Sitemap module configuration: https://nuxtseo.com/site-config/getting-started/how-it-works
// site: {
// url: 'https://tdesign-vue-nuxt-starter.ataw.top', // FIXME: Your website URL
// },
nitro: {
compressPublicAssets: { brotli: true, gzip: true },
},
vite: {
vue: {
script: {
defineModel: true,
propsDestructure: true,
},
},
plugins: [
Components({
dts: 'types/components.d.ts',
resolvers: [],
}),
AutoImport({
imports: ['pinia'],
dts: 'types/auto-imports.d.ts',
dirs: ['hooks/**', 'stores', 'constants', 'utils/**', 'layouts'],
vueTemplate: true,
resolvers: [],
}),
],
server: {
proxy: {
'/api': {
target: 'http://localhost:8080', // 替换为你的 API 服务器地址
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
},
future: {
// 启用 Nuxt 4 功能前瞻
compatibilityVersion: 4,
},
compatibilityDate: '2024-07-19',
});

48
package.json Normal file
View File

@ -0,0 +1,48 @@
{
"name": "tdesign-vue-nuxt-starter",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
},
"devDependencies": {
"@tdesign-vue-next/nuxt": "^0.1.5",
"@types/node": "^22.14.1",
"eslint": "^9.24.0",
"eslint-config-prettier": "^10.1.2",
"eslint-plugin-prettier": "^5.2.6",
"less": "^4.3.0"
},
"dependencies": {
"@nuxt/content": "3.4.0",
"@nuxt/devtools": "2.3.0",
"@nuxt/eslint": "1.2.0",
"@nuxt/scripts": "0.11.2",
"@nuxtjs/color-mode": "^3.5.2",
"@nuxtjs/robots": "^5.2.9",
"@nuxtjs/sitemap": "7.2.9",
"@nuxtjs/tailwindcss": "^6.13.2",
"@pinia/nuxt": "^0.10.1",
"@unhead/vue": "^2.0.5",
"nuxt": "^3.16.2",
"pinia": "^3.0.2",
"tdesign-vue-next": "^1.11.5",
"unplugin-auto-import": "^19.1.2",
"unplugin-vue-components": "^28.4.1"
},
"packageManager": "pnpm@10.9.0",
"pnpm": {
"onlyBuiltDependencies": [
"@parcel/watcher",
"better-sqlite3",
"esbuild"
],
"ignoredBuiltDependencies": [
"unrs-resolver"
]
}
}

9
prettier.config.cjs Normal file
View File

@ -0,0 +1,9 @@
module.exports = {
semi: true,
vueIndentScriptAndStyle: true,
singleQuote: true,
trailingComma: 'all',
proseWrap: 'never',
htmlWhitespaceSensitivity: 'strict',
endOfLine: 'auto',
};

BIN
public/QQ.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
public/avatar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 KiB

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/fll.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 MiB

View File

@ -0,0 +1,377 @@
:root,:root[theme-mode="light"] {
--td-brand-color-1: #f2f3ff;
--td-brand-color-2: #d9e1ff;
--td-brand-color-3: #b5c7ff;
--td-brand-color-4: #8eabff;
--td-brand-color-5: #618dff;
--td-brand-color-6: #366ef4;
--td-brand-color-7: #0052d9;
--td-brand-color-8: #003cab;
--td-brand-color-9: #002a7c;
--td-brand-color-10: #001a57;
--td-brand-color-light: var(--td-brand-color-1);
--td-brand-color-focus: var(--td-brand-color-2);
--td-brand-color-disabled: var(--td-brand-color-3);
--td-brand-color-hover: var(--td-brand-color-6);
--td-brand-color: var(--td-brand-color-7);
--td-brand-color-active: var(--td-brand-color-8);
--td-error-color-1: #fff0ed;
--td-error-color-2: #ffd8d2;
--td-error-color-3: #ffb9b0;
--td-error-color-4: #ff9285;
--td-error-color-5: #f6685d;
--td-error-color-6: #d54941;
--td-error-color-7: #ad352f;
--td-error-color-8: #881f1c;
--td-error-color-9: #68070a;
--td-error-color-10: #490002;
--td-error-color: var(--td-error-color-6);
--td-error-color-hover: var(--td-error-color-5);
--td-error-color-focus: var(--td-error-color-2);
--td-error-color-active: var(--td-error-color-7);
--td-error-color-disabled: var(--td-error-color-3);
--td-error-color-light: var(--td-error-color-1);
--td-success-color-1: #e3f9e9;
--td-success-color-2: #c6f3d7;
--td-success-color-3: #92dab2;
--td-success-color-4: #56c08d;
--td-success-color-5: #2ba471;
--td-success-color-6: #008858;
--td-success-color-7: #006c45;
--td-success-color-8: #005334;
--td-success-color-9: #003b23;
--td-success-color-10: #002515;
--td-success-color: var(--td-success-color-5);
--td-success-color-hover: var(--td-success-color-4);
--td-success-color-focus: var(--td-success-color-2);
--td-success-color-active: var(--td-success-color-6);
--td-success-color-disabled: var(--td-success-color-3);
--td-success-color-light: var(--td-success-color-1);
--td-warning-color-1: #fff1e9;
--td-warning-color-2: #ffd9c2;
--td-warning-color-3: #ffb98c;
--td-warning-color-4: #fa9550;
--td-warning-color-5: #e37318;
--td-warning-color-6: #be5a00;
--td-warning-color-7: #954500;
--td-warning-color-8: #713300;
--td-warning-color-9: #532300;
--td-warning-color-10: #3b1700;
--td-warning-color: var(--td-warning-color-5);
--td-warning-color-hover: var(--td-warning-color-4);
--td-warning-color-focus: var(--td-warning-color-2);
--td-warning-color-active: var(--td-warning-color-6);
--td-warning-color-disabled: var(--td-warning-color-3);
--td-warning-color-light: var(--td-warning-color-1);
--td-gray-color-1: #f3f3f3;
--td-gray-color-2: #eee;
--td-gray-color-3: #e7e7e7;
--td-gray-color-4: #dcdcdc;
--td-gray-color-5: #c5c5c5;
--td-gray-color-6: #a6a6a6;
--td-gray-color-7: #8b8b8b;
--td-gray-color-8: #777;
--td-gray-color-9: #5e5e5e;
--td-gray-color-10: #4b4b4b;
--td-gray-color-11: #383838;
--td-gray-color-12: #2c2c2c;
--td-gray-color-13: #242424;
--td-gray-color-14: #181818;
--td-bg-color-page: var(--td-gray-color-2);
--td-bg-color-container: #fff;
--td-bg-color-container-hover: var(--td-gray-color-1);
--td-bg-color-container-active: var(--td-gray-color-3);
--td-bg-color-container-select: #fff;
--td-bg-color-secondarycontainer: var(--td-gray-color-1);
--td-bg-color-secondarycontainer-hover: var(--td-gray-color-2);
--td-bg-color-secondarycontainer-active: var(--td-gray-color-4);
--td-bg-color-component: var(--td-gray-color-3);
--td-bg-color-component-hover: var(--td-gray-color-4);
--td-bg-color-component-active: var(--td-gray-color-6);
--td-bg-color-secondarycomponent: var(--td-gray-color-4);
--td-bg-color-secondarycomponent-hover: var(--td-gray-color-5);
--td-bg-color-secondarycomponent-active: var(--td-gray-color-6);
--td-bg-color-component-disabled: var(--td-gray-color-2);
--td-component-stroke: var(--td-gray-color-3);
--td-component-border: var(--td-gray-color-4);
--td-font-white-1: rgba(255, 255, 255, 1);
--td-font-white-2: rgba(255, 255, 255, 0.55);
--td-font-white-3: rgba(255, 255, 255, 0.35);
--td-font-white-4: rgba(255, 255, 255, 0.22);
--td-font-gray-1: rgba(0, 0, 0, 0.9);
--td-font-gray-2: rgba(0, 0, 0, 0.6);
--td-font-gray-3: rgba(0, 0, 0, 0.4);
--td-font-gray-4: rgba(0, 0, 0, 0.26);
--td-table-shadow-color: rgba(0, 0, 0, 8%);
--td-scrollbar-color: rgba(0, 0, 0, 10%);
--td-scrollbar-hover-color: rgba(0, 0, 0, 30%);
--td-scroll-track-color: #fff;
--td-bg-color-specialcomponent: #fff;
--td-border-level-1-color: var(--td-gray-color-3);
--td-border-level-2-color: var(--td-gray-color-4);
--td-shadow-inset-top: inset 0 0.5px 0 #dcdcdc;
--td-shadow-inset-right: inset 0.5px 0 0 #dcdcdc;
--td-shadow-inset-bottom: inset 0 -0.5px 0 #dcdcdc;
--td-shadow-inset-left: inset -0.5px 0 0 #dcdcdc;
--td-mask-active: rgba(0, 0, 0, 0.6);
--td-mask-disabled: rgba(255, 255, 255, 0.6);
/* 字体配置 */
--td-font-family: PingFang SC, Microsoft YaHei, Arial Regular;
--td-font-family-medium: PingFang SC, Microsoft YaHei, Arial Medium;
--td-font-size-link-small: 12px;
--td-font-size-link-medium: 14px;
--td-font-size-link-large: 16px;
--td-font-size-mark-small: 12px;
--td-font-size-mark-medium: 14px;
--td-font-size-body-small: 12px;
--td-font-size-body-medium: 14px;
--td-font-size-body-large: 16px;
--td-font-size-title-small: 14px;
--td-font-size-title-medium: 16px;
--td-font-size-title-large: 20px;
--td-font-size-headline-small: 24px;
--td-font-size-headline-medium: 28px;
--td-font-size-headline-large: 36px;
--td-font-size-display-medium: 48px;
--td-font-size-display-large: 64px;
--td-line-height-common: 8px;
--td-line-height-link-small: calc( var(--td-font-size-link-small) + var(--td-line-height-common) );
--td-line-height-link-medium: calc( var(--td-font-size-link-medium) + var(--td-line-height-common) );
--td-line-height-link-large: calc( var(--td-font-size-link-large) + var(--td-line-height-common) );
--td-line-height-mark-small: calc( var(--td-font-size-mark-small) + var(--td-line-height-common) );
--td-line-height-mark-medium: calc( var(--td-font-size-mark-medium) + var(--td-line-height-common) );
--td-line-height-body-small: calc( var(--td-font-size-body-small) + var(--td-line-height-common) );
--td-line-height-body-medium: calc( var(--td-font-size-body-medium) + var(--td-line-height-common) );
--td-line-height-body-large: calc( var(--td-font-size-body-large) + var(--td-line-height-common) );
--td-line-height-title-small: calc( var(--td-font-size-title-small) + var(--td-line-height-common) );
--td-line-height-title-medium: calc( var(--td-font-size-title-medium) + var(--td-line-height-common) );
--td-line-height-title-large: calc( var(--td-font-size-title-medium) + var(--td-line-height-common) );
--td-line-height-headline-small: calc( var(--td-font-size-headline-small) + var(--td-line-height-common) );
--td-line-height-headline-medium: calc( var(--td-font-size-headline-medium) + var(--td-line-height-common) );
--td-line-height-headline-large: calc( var(--td-font-size-headline-large) + var(--td-line-height-common) );
--td-line-height-display-medium: calc( var(--td-font-size-display-medium) + var(--td-line-height-common) );
--td-line-height-display-large: calc( var(--td-font-size-display-large) + var(--td-line-height-common) );
--td-font-link-small: var(--td-font-size-link-small) / var(--td-line-height-link-small) var(--td-font-family);
--td-font-link-medium: var(--td-font-size-link-medium) / var(--td-line-height-link-medium) var(--td-font-family);
--td-font-link-large: var(--td-font-size-link-large) / var(--td-line-height-link-large) var(--td-font-family);
--td-font-mark-small: 600 var(--td-font-size-mark-small) / var(--td-line-height-mark-small) var(--td-font-family);
--td-font-mark-medium: 600 var(--td-font-size-mark-medium) / var(--td-line-height-mark-medium) var(--td-font-family);
--td-font-body-small: var(--td-font-size-body-small) / var(--td-line-height-body-small) var(--td-font-family);
--td-font-body-medium: var(--td-font-size-body-medium) / var(--td-line-height-body-medium) var(--td-font-family);
--td-font-body-large: var(--td-font-size-body-large) / var(--td-line-height-body-large) var(--td-font-family);
--td-font-title-small: var(--td-font-size-title-small) / var(--td-line-height-title-small) var(--td-font-family);
--td-font-title-medium: var(--td-font-size-title-medium) / var(--td-line-height-title-medium) var(--td-font-family);
--td-font-title-large: var(--td-font-size-title-large) / var(--td-line-height-title-large) var(--td-font-family);
--td-font-headline-small: var(--td-font-size-headline-small) / var(--td-line-height-headline-small) var(--td-font-family);
--td-font-headline-medium: var(--td-font-size-headline-medium) / var(--td-line-height-headline-medium) var(--td-font-family);
--td-font-headline-large: var(--td-font-size-headline-large) / var(--td-line-height-headline-large) var(--td-font-family);
--td-font-display-medium: var(--td-font-size-display-medium) / var(--td-line-height-display-medium) var(--td-font-family);
--td-font-display-large: var(--td-font-size-display-large) / var(--td-line-height-display-large) var(--td-font-family);
/* 字体颜色 */
--td-text-color-primary: var(--td-font-gray-1);
--td-text-color-secondary: var(--td-font-gray-2);
--td-text-color-placeholder: var(--td-font-gray-3);
--td-text-color-disabled: var(--td-font-gray-4);
--td-text-color-anti: #fff;
--td-text-color-brand: var(--td-brand-color);
--td-text-color-link: var(--td-brand-color);
/* end 字体配置 */ /* 圆角配置 */
--td-radius-small: 2px;
--td-radius-default: 3px;
--td-radius-medium: 6px;
--td-radius-large: 9px;
--td-radius-extraLarge: 12px;
--td-radius-round: 999px;
--td-radius-circle: 50%;
/* end 圆角配置 */ /* 阴影配置 */
--td-shadow-1: 0 1px 10px rgba(0, 0, 0, 0.05), 0 4px 5px rgba(0, 0, 0, 0.08), 0 2px 4px -1px rgba(0, 0, 0, 0.12);
--td-shadow-2: 0 3px 14px 2px rgba(0, 0, 0, 0.05), 0 8px 10px 1px rgba(0, 0, 0, 0.06), 0 5px 5px -3px rgba(0, 0, 0, 0.1);
--td-shadow-3: 0 6px 30px 5px rgba(0, 0, 0, 0.05), 0 16px 24px 2px rgba(0, 0, 0, 0.04), 0 8px 10px -5px rgba(0, 0, 0, 0.08);
/* end 阴影配置 */ /* 尺寸配置 */
--td-size-1: 2px;
--td-size-2: 4px;
--td-size-3: 6px;
--td-size-4: 8px;
--td-size-5: 12px;
--td-size-6: 16px;
--td-size-7: 20px;
--td-size-8: 24px;
--td-size-9: 28px;
--td-size-10: 32px;
--td-size-11: 36px;
--td-size-12: 40px;
--td-size-13: 48px;
--td-size-14: 56px;
--td-size-15: 64px;
--td-size-16: 72px;
--td-comp-size-xxxs: var(--td-size-6);
--td-comp-size-xxs: var(--td-size-7);
--td-comp-size-xs: var(--td-size-8);
--td-comp-size-s: var(--td-size-9);
--td-comp-size-m: var(--td-size-10);
--td-comp-size-l: var(--td-size-11);
--td-comp-size-xl: var(--td-size-12);
--td-comp-size-xxl: var(--td-size-13);
--td-comp-size-xxxl: var(--td-size-14);
--td-comp-size-xxxxl: var(--td-size-15);
--td-comp-size-xxxxxl: var(--td-size-16);
--td-pop-padding-s: var(--td-size-2);
--td-pop-padding-m: var(--td-size-3);
--td-pop-padding-l: var(--td-size-4);
--td-pop-padding-xl: var(--td-size-5);
--td-pop-padding-xxl: var(--td-size-6);
--td-comp-paddingLR-xxs: var(--td-size-1);
--td-comp-paddingLR-xs: var(--td-size-2);
--td-comp-paddingLR-s: var(--td-size-4);
--td-comp-paddingLR-m: var(--td-size-5);
--td-comp-paddingLR-l: var(--td-size-6);
--td-comp-paddingLR-xl: var(--td-size-8);
--td-comp-paddingLR-xxl: var(--td-size-10);
--td-comp-paddingTB-xxs: var(--td-size-1);
--td-comp-paddingTB-xs: var(--td-size-2);
--td-comp-paddingTB-s: var(--td-size-4);
--td-comp-paddingTB-m: var(--td-size-5);
--td-comp-paddingTB-l: var(--td-size-6);
--td-comp-paddingTB-xl: var(--td-size-8);
--td-comp-paddingTB-xxl: var(--td-size-10);
--td-comp-margin-xxs: var(--td-size-1);
--td-comp-margin-xs: var(--td-size-2);
--td-comp-margin-s: var(--td-size-4);
--td-comp-margin-m: var(--td-size-5);
--td-comp-margin-l: var(--td-size-6);
--td-comp-margin-xl: var(--td-size-7);
--td-comp-margin-xxl: var(--td-size-8);
--td-comp-margin-xxxl: var(--td-size-10);
--td-comp-margin-xxxxl: var(--td-size-12);
/* end 尺寸配置 */
}
:root[theme-mode="dark"] {
--brand-main: var(--td-brand-color);
--td-brand-color-1: #1b2f51;
--td-brand-color-2: #173463;
--td-brand-color-3: #143975;
--td-brand-color-4: #103d88;
--td-brand-color-5: #0d429a;
--td-brand-color-6: #054bbe;
--td-brand-color-7: #2667d4;
--td-brand-color-8: #4582e6;
--td-brand-color-9: #699ef5;
--td-brand-color-10: #96bbf8;
--td-brand-color-light: var(--td-brand-color-1);
--td-brand-color-focus: var(--td-brand-color-2);
--td-brand-color-disabled: var(--td-brand-color-3);
--td-brand-color-hover: var(--td-brand-color-7);
--td-brand-color: var(--td-brand-color-8);
--td-brand-color-active: var(--td-brand-color-9);
--td-warning-color-1: #4f2a1d;
--td-warning-color-2: #582f21;
--td-warning-color-3: #733c23;
--td-warning-color-4: #a75d2b;
--td-warning-color-5: #cf6e2d;
--td-warning-color-6: #dc7633;
--td-warning-color-7: #e8935c;
--td-warning-color-8: #ecbf91;
--td-warning-color-9: #eed7bf;
--td-warning-color-10: #f3e9dc;
--td-warning-color: var(--td-warning-color-5);
--td-warning-color-hover: var(--td-warning-color-4);
--td-warning-color-focus: var(--td-warning-color-2);
--td-warning-color-active: var(--td-warning-color-6);
--td-warning-color-disabled: var(--td-warning-color-3);
--td-warning-color-light: var(--td-warning-color-1);
--td-error-color-1: #472324;
--td-error-color-2: #5e2a2d;
--td-error-color-3: #703439;
--td-error-color-4: #83383e;
--td-error-color-5: #a03f46;
--td-error-color-6: #c64751;
--td-error-color-7: #de6670;
--td-error-color-8: #ec888e;
--td-error-color-9: #edb1b6;
--td-error-color-10: #eeced0;
--td-error-color: var(--td-error-color-6);
--td-error-color-hover: var(--td-error-color-5);
--td-error-color-focus: var(--td-error-color-2);
--td-error-color-active: var(--td-error-color-7);
--td-error-color-disabled: var(--td-error-color-3);
--td-error-color-light: var(--td-error-color-1);
--td-success-color-1: #193a2a;
--td-success-color-2: #1a4230;
--td-success-color-3: #17533d;
--td-success-color-4: #0d7a55;
--td-success-color-5: #059465;
--td-success-color-6: #43af8a;
--td-success-color-7: #46bf96;
--td-success-color-8: #80d2b6;
--td-success-color-9: #b4e1d3;
--td-success-color-10: #deede8;
--td-success-color: var(--td-success-color-5);
--td-success-color-hover: var(--td-success-color-4);
--td-success-color-focus: var(--td-success-color-2);
--td-success-color-active: var(--td-success-color-6);
--td-success-color-disabled: var(--td-success-color-3);
--td-success-color-light: var(--td-success-color-1);
--td-gray-color-1: #f3f3f3;
--td-gray-color-2: #eee;
--td-gray-color-3: #e7e7e7;
--td-gray-color-4: #dcdcdc;
--td-gray-color-5: #c5c5c5;
--td-gray-color-6: #a6a6a6;
--td-gray-color-7: #8b8b8b;
--td-gray-color-8: #777;
--td-gray-color-9: #5e5e5e;
--td-gray-color-10: #4b4b4b;
--td-gray-color-11: #383838;
--td-gray-color-12: #2c2c2c;
--td-gray-color-13: #242424;
--td-gray-color-14: #181818;
--td-bg-color-page: var(--td-gray-color-14);
--td-bg-color-container: var(--td-gray-color-13);
--td-bg-color-container-hover: var(--td-gray-color-12);
--td-bg-color-container-active: var(--td-gray-color-10);
--td-bg-color-container-select: var(--td-gray-color-9);
--td-bg-color-secondarycontainer: var(--td-gray-color-12);
--td-bg-color-secondarycontainer-hover: var(--td-gray-color-11);
--td-bg-color-secondarycontainer-active: var(--td-gray-color-9);
--td-bg-color-component: var(--td-gray-color-11);
--td-bg-color-component-hover: var(--td-gray-color-10);
--td-bg-color-component-active: var(--td-gray-color-9);
--td-bg-color-secondarycomponent: var(--td-gray-color-10);
--td-bg-color-secondarycomponent-hover: var(--td-gray-color-9);
--td-bg-color-secondarycomponent-active: var(--td-gray-color-8);
--td-bg-color-component-disabled: var(--td-gray-color-12);
--td-component-stroke: var(--td-gray-color-11);
--td-component-border: var(--td-gray-color-9);
--td-font-white-1: rgba(255, 255, 255, 0.9);
--td-font-white-2: rgba(255, 255, 255, 0.55);
--td-font-white-3: rgba(255, 255, 255, 0.35);
--td-font-white-4: rgba(255, 255, 255, 0.22);
--td-font-gray-1: rgba(0, 0, 0, 0.9);
--td-font-gray-2: rgba(0, 0, 0, 0.6);
--td-font-gray-3: rgba(0, 0, 0, 0.4);
--td-font-gray-4: rgba(0, 0, 0, 0.26);
--td-text-color-primary: var(--td-font-white-1);
--td-text-color-secondary: var(--td-font-white-2);
--td-text-color-placeholder: var(--td-font-white-3);
--td-text-color-disabled: var(--td-font-white-4);
--td-text-color-anti: #fff;
--td-text-color-brand: var(--td-brand-color);
--td-text-color-link: var(--td-brand-color);
--td-shadow-1: 0 4px 6px rgba(0, 0, 0, 0.06), 0 1px 10px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.12);
--td-shadow-2: 0 8px 10px rgba(0, 0, 0, 0.12), 0 3px 14px rgba(0, 0, 0, 0.10), 0 5px 5px rgba(0, 0, 0, 0.16);
--td-shadow-3: 0 16px 24px rgba(0, 0, 0, 0.14), 0 6px 30px rgba(0, 0, 0, 0.12), 0 8px 10px rgba(0, 0, 0, 0.20);
--td-shadow-inset-top: inset 0 0.5px 0 #5e5e5e;
--td-shadow-inset-right: inset 0.5px 0 0 #5e5e5e;
--td-shadow-inset-bottom: inset 0 -0.5px 0 #5e5e5e;
--td-shadow-inset-left: inset -0.5px 0 0 #5e5e5e;
--td-table-shadow-color: rgba(0, 0, 0, 55%);
--td-scrollbar-color: rgba(255, 255, 255, 10%);
--td-scrollbar-hover-color: rgba(255, 255, 255, 30%);
--td-scroll-track-color: #333;
--td-bg-color-specialcomponent: transparent;
--td-border-level-1-color: var(--td-gray-color-11);
--td-border-level-2-color: var(--td-gray-color-9);
--td-mask-active: rgba(0, 0, 0, 0.4);
--td-mask-disabled: rgba(0, 0, 0, 0.6);
}

View File

@ -0,0 +1,268 @@
:root,:root[theme-mode="light"] {
--brand-main: var(--td-brand-color-6);
--td-brand-color-light: var(--td-brand-color-1);
--td-brand-color-focus: var(--td-brand-color-2);
--td-brand-color-disabled: var(--td-brand-color-3);
--td-brand-color-hover: var(--td-brand-color-5);
--td-brand-color: var(--td-brand-color-6);
--td-brand-color-active: var(--td-brand-color-7);
--td-brand-color-1: #f0f3ff;
--td-brand-color-2: #d6e2ff;
--td-brand-color-3: #afc9ff;
--td-brand-color-4: #81adff;
--td-brand-color-5: #4a90ff;
--td-brand-color-6: #007aff;
--td-brand-color-7: #005ac3;
--td-brand-color-8: #004396;
--td-brand-color-9: #002e6c;
--td-brand-color-10: #001e4b;
--td-warning-color-1: #fff4ec;
--td-warning-color-2: #ffe5d0;
--td-warning-color-3: #ffd0a7;
--td-warning-color-4: #ffb36c;
--td-warning-color-5: #fc9830;
--td-warning-color-6: #d07502;
--td-warning-color-7: #a35900;
--td-warning-color-8: #774000;
--td-warning-color-9: #512900;
--td-warning-color-10: #341900;
--td-warning-color: var(--td-warning-color-5);
--td-warning-color-hover: var(--td-warning-color-4);
--td-warning-color-focus: var(--td-warning-color-2);
--td-warning-color-active: var(--td-warning-color-6);
--td-warning-color-disabled: var(--td-warning-color-3);
--td-warning-color-light: var(--td-warning-color-1);
--td-error-color-1: #fff0ed;
--td-error-color-2: #ffd8d3;
--td-error-color-3: #ffb8b1;
--td-error-color-4: #ff928b;
--td-error-color-5: #ff5f5a;
--td-error-color-6: #f24444;
--td-error-color-7: #b6272a;
--td-error-color-8: #8f1018;
--td-error-color-9: #6b0009;
--td-error-color-10: #490004;
--td-error-color: var(--td-error-color-6);
--td-error-color-hover: var(--td-error-color-5);
--td-error-color-focus: var(--td-error-color-2);
--td-error-color-active: var(--td-error-color-7);
--td-error-color-disabled: var(--td-error-color-3);
--td-error-color-light: var(--td-error-color-1);
--td-success-color-1: #e1f9ec;
--td-success-color-2: #c4f2dd;
--td-success-color-3: #8edbbc;
--td-success-color-4: #06ba8e;
--td-success-color-5: #14a47d;
--td-success-color-6: #008765;
--td-success-color-7: #006c50;
--td-success-color-8: #00523c;
--td-success-color-9: #003b2a;
--td-success-color-10: #002519;
--td-success-color: var(--td-success-color-5);
--td-success-color-hover: var(--td-success-color-4);
--td-success-color-focus: var(--td-success-color-2);
--td-success-color-active: var(--td-success-color-6);
--td-success-color-disabled: var(--td-success-color-3);
--td-success-color-light: var(--td-success-color-1);
--td-gray-color-1: #f3f3f4;
--td-gray-color-2: #edeef0;
--td-gray-color-3: #e7e8eb;
--td-gray-color-4: #dbdde1;
--td-gray-color-5: #c3c6cd;
--td-gray-color-6: #a0a6b1;
--td-gray-color-7: #818b99;
--td-gray-color-8: #697686;
--td-gray-color-9: #535e6a;
--td-gray-color-10: #424b55;
--td-gray-color-11: #323941;
--td-gray-color-12: #272c33;
--td-gray-color-13: #20242a;
--td-gray-color-14: #15181c;
--td-bg-color-container: #fff;
--td-bg-color-container-select: #fff;
--td-bg-color-page: var(--td-gray-color-2);
--td-bg-color-container-hover: var(--td-gray-color-1);
--td-bg-color-container-active: var(--td-gray-color-3);
--td-bg-color-secondarycontainer: var(--td-gray-color-1);
--td-bg-color-secondarycontainer-hover: var(--td-gray-color-2);
--td-bg-color-secondarycontainer-active: var(--td-gray-color-4);
--td-bg-color-component: var(--td-gray-color-3);
--td-bg-color-component-hover: var(--td-gray-color-4);
--td-bg-color-component-active: var(--td-gray-color-6);
--td-bg-color-component-disabled: var(--td-gray-color-2);
--td-component-stroke: var(--td-gray-color-3);
--td-component-border: var(--td-gray-color-4);
--td-font-white-1: #ffffff;
--td-font-white-2: rgba(255, 255, 255, 0.55);
--td-font-white-3: rgba(255, 255, 255, 0.35);
--td-font-white-4: rgba(255, 255, 255, 0.22);
--td-font-gray-1: rgba(0, 0, 0, 0.9);
--td-font-gray-2: rgba(0, 0, 0, 0.6);
--td-font-gray-3: rgba(0, 0, 0, 0.4);
--td-font-gray-4: rgba(0, 0, 0, 0.26);
--td-brand-color-light-hover: var(--td-brand-color-2);
--td-warning-color-light-hover: var(--td-warning-color-2);
--td-error-color-light-hover: var(--td-error-color-2);
--td-success-color-light-hover: var(--td-success-color-2);
--td-bg-color-secondarycomponent: var(--td-gray-color-4);
--td-bg-color-secondarycomponent-hover: var(--td-gray-color-5);
--td-bg-color-secondarycomponent-active: var(--td-gray-color-6);
--td-table-shadow-color: rgba(0, 0, 0, 8%);
--td-scrollbar-color: rgba(0, 0, 0, 10%);
--td-scrollbar-hover-color: rgba(0, 0, 0, 30%);
--td-scroll-track-color: #fff;
--td-bg-color-specialcomponent: #fff;
--td-border-level-1-color: var(--td-gray-color-3);
--td-border-level-2-color: var(--td-gray-color-4);
--td-shadow-inset-top: inset 0 0.5px 0 #dcdcdc;
--td-shadow-inset-right: inset 0.5px 0 0 #dcdcdc;
--td-shadow-inset-bottom: inset 0 -0.5px 0 #dcdcdc;
--td-shadow-inset-left: inset -0.5px 0 0 #dcdcdc;
--td-mask-active: rgba(0, 0, 0, 0.6);
--td-mask-disabled: rgba(255, 255, 255, 0.6);
}
:root[theme-mode="dark"] {
--brand-main: var(--td-brand-color-6);
--td-brand-color-light: var(--td-brand-color-1);
--td-brand-color-focus: var(--td-brand-color-2);
--td-brand-color-disabled: var(--td-brand-color-3);
--td-brand-color-hover: var(--td-brand-color-5);
--td-brand-color: var(--td-brand-color-6);
--td-brand-color-active: var(--td-brand-color-7);
--td-brand-color-1: #4a90ff20;
--td-brand-color-2: #002e6c;
--td-brand-color-3: #004396;
--td-brand-color-4: #005ac3;
--td-brand-color-5: #007aff;
--td-brand-color-6: #4a90ff;
--td-brand-color-7: #81adff;
--td-brand-color-8: #afc9ff;
--td-brand-color-9: #d6e2ff;
--td-brand-color-10: #f0f3ff;
--td-warning-color-1: #4f2a1d;
--td-warning-color-2: #582f21;
--td-warning-color-3: #733c23;
--td-warning-color-4: #a75d2b;
--td-warning-color-5: #cf6e2d;
--td-warning-color-6: #dc7633;
--td-warning-color-7: #e8935c;
--td-warning-color-8: #ecbf91;
--td-warning-color-9: #eed7bf;
--td-warning-color-10: #f3e9dc;
--td-error-color-1: #472324;
--td-error-color-2: #5e2a2d;
--td-error-color-3: #703439;
--td-error-color-4: #83383e;
--td-error-color-5: #a03f46;
--td-error-color-6: #c64751;
--td-error-color-7: #de6670;
--td-error-color-8: #ec888e;
--td-error-color-9: #edb1b6;
--td-error-color-10: #eeced0;
--td-success-color-1: #193a2a;
--td-success-color-2: #1a4230;
--td-success-color-3: #17533d;
--td-success-color-4: #0d7a55;
--td-success-color-5: #059465;
--td-success-color-6: #43af8a;
--td-success-color-7: #46bf96;
--td-success-color-8: #80d2b6;
--td-success-color-9: #b4e1d3;
--td-success-color-10: #deede8;
--td-gray-color-1: #f3f3f3;
--td-gray-color-2: #eee;
--td-gray-color-3: #e7e7e7;
--td-gray-color-4: #dcdcdc;
--td-gray-color-5: #c5c5c5;
--td-gray-color-6: #a6a6a6;
--td-gray-color-7: #8b8b8b;
--td-gray-color-8: #777;
--td-gray-color-9: #5e5e5e;
--td-gray-color-10: #4b4b4b;
--td-gray-color-11: #383838;
--td-gray-color-12: #2c2c2c;
--td-gray-color-13: #242424;
--td-gray-color-14: #181818;
--td-bg-color-page: var(--td-gray-color-14);
--td-bg-color-container: var(--td-gray-color-13);
--td-bg-color-container-hover: var(--td-gray-color-12);
--td-bg-color-container-active: var(--td-gray-color-10);
--td-bg-color-container-select: var(--td-gray-color-9);
--td-bg-color-secondarycontainer: var(--td-gray-color-12);
--td-bg-color-secondarycontainer-hover: var(--td-gray-color-11);
--td-bg-color-secondarycontainer-active: var(--td-gray-color-9);
--td-bg-color-component: var(--td-gray-color-11);
--td-bg-color-component-hover: var(--td-gray-color-10);
--td-bg-color-component-active: var(--td-gray-color-9);
--td-bg-color-component-disabled: var(--td-gray-color-12);
--td-component-stroke: var(--td-gray-color-11);
--td-component-border: var(--td-gray-color-9);
--td-font-white-1: rgba(255, 255, 255, 0.9);
--td-font-white-2: rgba(255, 255, 255, 0.55);
--td-font-white-3: rgba(255, 255, 255, 0.35);
--td-font-white-4: rgba(255, 255, 255, 0.22);
--td-font-gray-1: rgba(0, 0, 0, 0.9);
--td-font-gray-2: rgba(0, 0, 0, 0.6);
--td-font-gray-3: rgba(0, 0, 0, 0.4);
--td-font-gray-4: rgba(0, 0, 0, 0.26);
--td-gray-color-1: #f3f3f3;
--td-gray-color-2: #eee;
--td-gray-color-3: #e7e7e7;
--td-gray-color-4: #dcdcdc;
--td-gray-color-5: #c5c5c5;
--td-gray-color-6: #a6a6a6;
--td-gray-color-7: #8b8b8b;
--td-gray-color-8: #777;
--td-gray-color-9: #5e5e5e;
--td-gray-color-10: #4b4b4b;
--td-gray-color-11: #383838;
--td-gray-color-12: #2c2c2c;
--td-gray-color-13: #242424;
--td-gray-color-14: #181818;
--td-bg-color-page: var(--td-gray-color-14);
--td-bg-color-container: var(--td-gray-color-13);
--td-bg-color-container-hover: var(--td-gray-color-12);
--td-bg-color-container-active: var(--td-gray-color-10);
--td-bg-color-container-select: var(--td-gray-color-9);
--td-bg-color-secondarycontainer: var(--td-gray-color-12);
--td-bg-color-secondarycontainer-hover: var(--td-gray-color-11);
--td-bg-color-secondarycontainer-active: var(--td-gray-color-9);
--td-bg-color-component: var(--td-gray-color-11);
--td-bg-color-component-hover: var(--td-gray-color-10);
--td-bg-color-component-active: var(--td-gray-color-9);
--td-bg-color-secondarycomponent: var(--td-gray-color-10);
--td-bg-color-secondarycomponent-hover: var(--td-gray-color-9);
--td-bg-color-secondarycomponent-active: var(--td-gray-color-8);
--td-bg-color-component-disabled: var(--td-gray-color-12);
--td-component-stroke: var(--td-gray-color-11);
--td-component-border: var(--td-gray-color-9);
--td-font-white-1: rgba(255, 255, 255, 0.9);
--td-font-white-2: rgba(255, 255, 255, 0.55);
--td-font-white-3: rgba(255, 255, 255, 0.35);
--td-font-white-4: rgba(255, 255, 255, 0.22);
--td-font-gray-1: rgba(0, 0, 0, 0.9);
--td-font-gray-2: rgba(0, 0, 0, 0.6);
--td-font-gray-3: rgba(0, 0, 0, 0.4);
--td-font-gray-4: rgba(0, 0, 0, 0.26);
--td-text-color-primary: var(--td-font-white-1);
--td-text-color-secondary: var(--td-font-white-2);
--td-text-color-placeholder: var(--td-font-white-3);
--td-text-color-disabled: var(--td-font-white-4);
--td-text-color-anti: #fff;
--td-text-color-brand: var(--td-brand-color);
--td-text-color-link: var(--td-brand-color);
--td-table-shadow-color: rgba(0, 0, 0, 55%);
--td-scrollbar-color: rgba(255, 255, 255, 10%);
--td-scrollbar-hover-color: rgba(255, 255, 255, 30%);
--td-scroll-track-color: #333;
--td-bg-color-specialcomponent: #fff;
--td-border-level-1-color: var(--td-gray-color-11);
--td-border-level-2-color: var(--td-gray-color-9);
--td-mask-active: rgba(0, 0, 0, 0.4);
--td-mask-disabled: rgba(0, 0, 0, 0.6);
--td-shadow-inset-top: inset 0 0.5px 0 #5e5e5e;
--td-shadow-inset-right: inset 0.5px 0 0 #5e5e5e;
--td-shadow-inset-bottom: inset 0 -0.5px 0 #5e5e5e;
--td-shadow-inset-left: inset -0.5px 0 0 #5e5e5e;
}

View File

@ -0,0 +1,459 @@
:root,:root[theme-mode="light"] {
--brand-main: var(--td-brand-color-5);
--td-brand-color-light: var(--td-brand-color-1);
--td-brand-color-focus: var(--td-brand-color-2);
--td-brand-color-disabled: var(--td-brand-color-3);
--td-brand-color-hover: var(--td-brand-color-4);
--td-brand-color: var(--td-brand-color-5);
--td-brand-color-active: var(--td-brand-color-6);
--td-brand-color-1: #fff0f6;
--td-brand-color-2: #ffd8eb;
--td-brand-color-3: #ffafda;
--td-brand-color-4: #ff7aca;
--td-brand-color-5: #ef45b3;
--td-brand-color-6: #cb2a96;
--td-brand-color-7: #a61379;
--td-brand-color-8: #83005e;
--td-brand-color-9: #620044;
--td-brand-color-10: #44002e;
--td-warning-color-1: #fef3e6;
--td-warning-color-2: #f9e0c7;
--td-warning-color-3: #f7c797;
--td-warning-color-4: #f2995f;
--td-warning-color-5: #ed7b2f;
--td-warning-color-6: #d35a21;
--td-warning-color-7: #ba431b;
--td-warning-color-8: #9e3610;
--td-warning-color-9: #842b0b;
--td-warning-color-10: #5a1907;
--td-warning-color: var(--td-warning-color-5);
--td-warning-color-hover: var(--td-warning-color-4);
--td-warning-color-focus: var(--td-warning-color-2);
--td-warning-color-active: var(--td-warning-color-6);
--td-warning-color-disabled: var(--td-warning-color-3);
--td-warning-color-light: var(--td-warning-color-1);
--td-error-color-1: #fdecee;
--td-error-color-2: #f9d7d9;
--td-error-color-3: #f8b9be;
--td-error-color-4: #f78d94;
--td-error-color-5: #f36d78;
--td-error-color-6: #e34d59;
--td-error-color-7: #c9353f;
--td-error-color-8: #b11f26;
--td-error-color-9: #951114;
--td-error-color-10: #680506;
--td-error-color: var(--td-error-color-6);
--td-error-color-hover: var(--td-error-color-5);
--td-error-color-focus: var(--td-error-color-2);
--td-error-color-active: var(--td-error-color-7);
--td-error-color-disabled: var(--td-error-color-3);
--td-error-color-light: var(--td-error-color-1);
--td-success-color-1: #e8f8f2;
--td-success-color-2: #bcebdc;
--td-success-color-3: #85dbbe;
--td-success-color-4: #48c79c;
--td-success-color-5: #00a870;
--td-success-color-6: #078d5c;
--td-success-color-7: #067945;
--td-success-color-8: #056334;
--td-success-color-9: #044f2a;
--td-success-color-10: #033017;
--td-success-color: var(--td-success-color-5);
--td-success-color-hover: var(--td-success-color-4);
--td-success-color-focus: var(--td-success-color-2);
--td-success-color-active: var(--td-success-color-6);
--td-success-color-disabled: var(--td-success-color-3);
--td-success-color-light: var(--td-success-color-1);
--td-gray-color-1: #f3f3f3;
--td-gray-color-2: #eee;
--td-gray-color-3: #e7e7e7;
--td-gray-color-4: #dcdcdc;
--td-gray-color-5: #c5c5c5;
--td-gray-color-6: #a6a6a6;
--td-gray-color-7: #8b8b8b;
--td-gray-color-8: #777;
--td-gray-color-9: #5e5e5e;
--td-gray-color-10: #4b4b4b;
--td-gray-color-11: #383838;
--td-gray-color-12: #2c2c2c;
--td-gray-color-13: #242424;
--td-gray-color-14: #181818;
--td-bg-color-container: #fff;
--td-bg-color-container-select: #fff;
--td-bg-color-page: var(--td-gray-color-2);
--td-bg-color-container-hover: var(--td-gray-color-1);
--td-bg-color-container-active: var(--td-gray-color-3);
--td-bg-color-secondarycontainer: var(--td-gray-color-1);
--td-bg-color-secondarycontainer-hover: var(--td-gray-color-2);
--td-bg-color-secondarycontainer-active: var(--td-gray-color-4);
--td-bg-color-component: var(--td-gray-color-3);
--td-bg-color-component-hover: var(--td-gray-color-4);
--td-bg-color-component-active: var(--td-gray-color-6);
--td-bg-color-component-disabled: var(--td-gray-color-2);
--td-component-stroke: var(--td-gray-color-3);
--td-component-border: var(--td-gray-color-4);
--td-font-white-1: #ffffff;
--td-font-white-2: rgba(255, 255, 255, 0.55);
--td-font-white-3: rgba(255, 255, 255, 0.35);
--td-font-white-4: rgba(255, 255, 255, 0.22);
--td-font-gray-1: rgba(0, 0, 0, 0.9);
--td-font-gray-2: rgba(0, 0, 0, 0.6);
--td-font-gray-3: rgba(0, 0, 0, 0.4);
--td-font-gray-4: rgba(0, 0, 0, 0.26);
--td-table-shadow-color: rgba(0, 0, 0, 8%);
--td-scrollbar-color: rgba(0, 0, 0, 10%);
--td-scrollbar-hover-color: rgba(0, 0, 0, 30%);
--td-scroll-track-color: #fff;
--td-bg-color-specialcomponent: #fff;
--td-border-level-1-color: var(--td-gray-color-3);
--td-border-level-2-color: var(--td-gray-color-4);
--td-shadow-inset-top: inset 0 0.5px 0 #dcdcdc;
--td-shadow-inset-right: inset 0.5px 0 0 #dcdcdc;
--td-shadow-inset-bottom: inset 0 -0.5px 0 #dcdcdc;
--td-shadow-inset-left: inset -0.5px 0 0 #dcdcdc;
--td-mask-active: rgba(0, 0, 0, 0.6);
--td-mask-disabled: rgba(255, 255, 255, 0.6);
/* 字体配置 */
--td-font-family: PingFang SC, Microsoft YaHei, Arial Regular;
--td-font-family-medium: PingFang SC, Microsoft YaHei, Arial Medium;
--td-font-size-link-small: 13px;
--td-font-size-link-medium: 15px;
--td-font-size-link-large: 17px;
--td-font-size-mark-small: 13px;
--td-font-size-mark-medium: 15px;
--td-font-size-body-small: 13px;
--td-font-size-body-medium: 15px;
--td-font-size-body-large: 17px;
--td-font-size-title-small: 15px;
--td-font-size-title-medium: 17px;
--td-font-size-title-large: 21px;
--td-font-size-headline-small: 25px;
--td-font-size-headline-medium: 29px;
--td-font-size-headline-large: 37px;
--td-font-size-display-medium: 49px;
--td-font-size-display-large: 65px;
--td-line-height-common: 8px;
--td-line-height-link-small: calc( var(--td-font-size-link-small) + var(--td-line-height-common) );
--td-line-height-link-medium: calc( var(--td-font-size-link-medium) + var(--td-line-height-common) );
--td-line-height-link-large: calc( var(--td-font-size-link-large) + var(--td-line-height-common) );
--td-line-height-mark-small: calc( var(--td-font-size-mark-small) + var(--td-line-height-common) );
--td-line-height-mark-medium: calc( var(--td-font-size-mark-medium) + var(--td-line-height-common) );
--td-line-height-body-small: calc( var(--td-font-size-body-small) + var(--td-line-height-common) );
--td-line-height-body-medium: calc( var(--td-font-size-body-medium) + var(--td-line-height-common) );
--td-line-height-body-large: calc( var(--td-font-size-body-large) + var(--td-line-height-common) );
--td-line-height-title-small: calc( var(--td-font-size-title-small) + var(--td-line-height-common) );
--td-line-height-title-medium: calc( var(--td-font-size-title-medium) + var(--td-line-height-common) );
--td-line-height-title-large: calc( var(--td-font-size-title-medium) + var(--td-line-height-common) );
--td-line-height-headline-small: calc( var(--td-font-size-headline-small) + var(--td-line-height-common) );
--td-line-height-headline-medium: calc( var(--td-font-size-headline-medium) + var(--td-line-height-common) );
--td-line-height-headline-large: calc( var(--td-font-size-headline-large) + var(--td-line-height-common) );
--td-line-height-display-medium: calc( var(--td-font-size-display-medium) + var(--td-line-height-common) );
--td-line-height-display-large: calc( var(--td-font-size-display-large) + var(--td-line-height-common) );
--td-font-link-small: var(--td-font-size-link-small) / var(--td-line-height-link-small) var(--td-font-family);
--td-font-link-medium: var(--td-font-size-link-medium) / var(--td-line-height-link-medium) var(--td-font-family);
--td-font-link-large: var(--td-font-size-link-large) / var(--td-line-height-link-large) var(--td-font-family);
--td-font-mark-small: 600 var(--td-font-size-mark-small) / var(--td-line-height-mark-small) var(--td-font-family);
--td-font-mark-medium: 600 var(--td-font-size-mark-medium) / var(--td-line-height-mark-medium) var(--td-font-family);
--td-font-body-small: var(--td-font-size-body-small) / var(--td-line-height-body-small) var(--td-font-family);
--td-font-body-medium: var(--td-font-size-body-medium) / var(--td-line-height-body-medium) var(--td-font-family);
--td-font-body-large: var(--td-font-size-body-large) / var(--td-line-height-body-large) var(--td-font-family);
--td-font-title-small: var(--td-font-size-title-small) / var(--td-line-height-title-small) var(--td-font-family);
--td-font-title-medium: var(--td-font-size-title-medium) / var(--td-line-height-title-medium) var(--td-font-family);
--td-font-title-large: var(--td-font-size-title-large) / var(--td-line-height-title-large) var(--td-font-family);
--td-font-headline-small: var(--td-font-size-headline-small) / var(--td-line-height-headline-small) var(--td-font-family);
--td-font-headline-medium: var(--td-font-size-headline-medium) / var(--td-line-height-headline-medium) var(--td-font-family);
--td-font-headline-large: var(--td-font-size-headline-large) / var(--td-line-height-headline-large) var(--td-font-family);
--td-font-display-medium: var(--td-font-size-display-medium) / var(--td-line-height-display-medium) var(--td-font-family);
--td-font-display-large: var(--td-font-size-display-large) / var(--td-line-height-display-large) var(--td-font-family);
/* 字体颜色 */
--td-text-color-primary: var(--td-font-gray-1);
--td-text-color-secondary: var(--td-font-gray-2);
--td-text-color-placeholder: var(--td-font-gray-3);
--td-text-color-disabled: var(--td-font-gray-4);
--td-text-color-anti: #fff;
--td-text-color-brand: var(--td-brand-color);
--td-text-color-link: var(--td-brand-color);
/* end 字体配置 */ /* 圆角配置 */
--td-radius-small: 0px;
--td-radius-default: 0px;
--td-radius-medium: 0px;
--td-radius-large: 0px;
--td-radius-extraLarge: 0px;
--td-radius-round: 999px;
--td-radius-circle: 50%;
/* end 圆角配置 *//* 阴影配置 */
--td-shadow-1: 0 5px 20px rgba(0, 0, 0, 0.08),0 5px 8px rgba(0, 0, 0, 0.12),0 5px 10px -1px rgba(0, 0, 0, 0.18);
--td-shadow-2: 0 7px 23px 2px rgba(0, 0, 0, 0.09),0 12px 17px 1px rgba(0, 0, 0, 0.1),0 8px 14px -4px rgba(0, 0, 0, 0.18);
--td-shadow-3: 0 11px 37px 5px rgba(0, 0, 0, 0.1),0 21px 31px 2px rgba(0, 0, 0, 0.12),0 14px 20px -6px rgba(0, 0, 0, 0.16);
/* end 阴影配置 *//* 尺寸配置 */
--td-size-1: 2px;
--td-size-2: 4px;
--td-size-3: 6px;
--td-size-4: 8px;
--td-size-5: 12px;
--td-size-6: 16px;
--td-size-7: 20px;
--td-size-8: 24px;
--td-size-9: 28px;
--td-size-10: 32px;
--td-size-11: 36px;
--td-size-12: 40px;
--td-size-13: 48px;
--td-size-14: 56px;
--td-size-15: 64px;
--td-size-16: 72px;
--td-comp-size-xxxs: var(--td-size-6);
--td-comp-size-xxs: var(--td-size-7);
--td-comp-size-xs: var(--td-size-8);
--td-comp-size-s: var(--td-size-9);
--td-comp-size-m: var(--td-size-10);
--td-comp-size-l: var(--td-size-11);
--td-comp-size-xl: var(--td-size-12);
--td-comp-size-xxl: var(--td-size-13);
--td-comp-size-xxxl: var(--td-size-14);
--td-comp-size-xxxxl: var(--td-size-15);
--td-comp-size-xxxxxl: var(--td-size-16);
--td-pop-padding-s: var(--td-size-2);
--td-pop-padding-m: var(--td-size-3);
--td-pop-padding-l: var(--td-size-4);
--td-pop-padding-xl: var(--td-size-5);
--td-pop-padding-xxl: var(--td-size-6);
--td-comp-paddingLR-xxs: var(--td-size-1);
--td-comp-paddingLR-xs: var(--td-size-2);
--td-comp-paddingLR-s: var(--td-size-4);
--td-comp-paddingLR-m: var(--td-size-5);
--td-comp-paddingLR-l: var(--td-size-6);
--td-comp-paddingLR-xl: var(--td-size-8);
--td-comp-paddingLR-xxl: var(--td-size-10);
--td-comp-paddingTB-xxs: var(--td-size-1);
--td-comp-paddingTB-xs: var(--td-size-2);
--td-comp-paddingTB-s: var(--td-size-4);
--td-comp-paddingTB-m: var(--td-size-5);
--td-comp-paddingTB-l: var(--td-size-6);
--td-comp-paddingTB-xl: var(--td-size-8);
--td-comp-paddingTB-xxl: var(--td-size-10);
--td-comp-margin-xxs: var(--td-size-1);
--td-comp-margin-xs: var(--td-size-2);
--td-comp-margin-s: var(--td-size-4);
--td-comp-margin-m: var(--td-size-5);
--td-comp-margin-l: var(--td-size-6);
--td-comp-margin-xl: var(--td-size-7);
--td-comp-margin-xxl: var(--td-size-8);
--td-comp-margin-xxxl: var(--td-size-10);
--td-comp-margin-xxxxl: var(--td-size-12);
/* end 尺寸配置 */
}
:root[theme-mode="dark"] {
--brand-main: var(--td-brand-color-6);
--td-brand-color-light: var(--td-brand-color-1);
--td-brand-color-focus: var(--td-brand-color-2);
--td-brand-color-disabled: var(--td-brand-color-3);
--td-brand-color-hover: var(--td-brand-color-5);
--td-brand-color: var(--td-brand-color-6);
--td-brand-color-active: var(--td-brand-color-7);
--td-brand-color-1: #ef45b320;
--td-brand-color-2: #620044;
--td-brand-color-3: #83005e;
--td-brand-color-4: #a61379;
--td-brand-color-5: #cb2a96;
--td-brand-color-6: #ef45b3;
--td-brand-color-7: #ff7aca;
--td-brand-color-8: #ffafda;
--td-brand-color-9: #ffd8eb;
--td-brand-color-10: #fff0f6;
--td-warning-color-1: #4f2a1d;
--td-warning-color-2: #582f21;
--td-warning-color-3: #733c23;
--td-warning-color-4: #a75d2b;
--td-warning-color-5: #cf6e2d;
--td-warning-color-6: #dc7633;
--td-warning-color-7: #e8935c;
--td-warning-color-8: #ecbf91;
--td-warning-color-9: #eed7bf;
--td-warning-color-10: #f3e9dc;
--td-error-color-1: #472324;
--td-error-color-2: #5e2a2d;
--td-error-color-3: #703439;
--td-error-color-4: #83383e;
--td-error-color-5: #a03f46;
--td-error-color-6: #c64751;
--td-error-color-7: #de6670;
--td-error-color-8: #ec888e;
--td-error-color-9: #edb1b6;
--td-error-color-10: #eeced0;
--td-success-color-1: #193a2a;
--td-success-color-2: #1a4230;
--td-success-color-3: #17533d;
--td-success-color-4: #0d7a55;
--td-success-color-5: #059465;
--td-success-color-6: #43af8a;
--td-success-color-7: #46bf96;
--td-success-color-8: #80d2b6;
--td-success-color-9: #b4e1d3;
--td-success-color-10: #deede8;
--td-gray-color-1: #f3f3f3;
--td-gray-color-2: #eee;
--td-gray-color-3: #e7e7e7;
--td-gray-color-4: #dcdcdc;
--td-gray-color-5: #c5c5c5;
--td-gray-color-6: #a6a6a6;
--td-gray-color-7: #8b8b8b;
--td-gray-color-8: #777;
--td-gray-color-9: #5e5e5e;
--td-gray-color-10: #4b4b4b;
--td-gray-color-11: #383838;
--td-gray-color-12: #2c2c2c;
--td-gray-color-13: #242424;
--td-gray-color-14: #181818;
--td-bg-color-page: var(--td-gray-color-14);
--td-bg-color-container: var(--td-gray-color-13);
--td-bg-color-container-hover: var(--td-gray-color-12);
--td-bg-color-container-active: var(--td-gray-color-10);
--td-bg-color-container-select: var(--td-gray-color-9);
--td-bg-color-secondarycontainer: var(--td-gray-color-12);
--td-bg-color-secondarycontainer-hover: var(--td-gray-color-11);
--td-bg-color-secondarycontainer-active: var(--td-gray-color-9);
--td-bg-color-component: var(--td-gray-color-11);
--td-bg-color-component-hover: var(--td-gray-color-10);
--td-bg-color-component-active: var(--td-gray-color-9);
--td-bg-color-component-disabled: var(--td-gray-color-12);
--td-component-stroke: var(--td-gray-color-11);
--td-component-border: var(--td-gray-color-9);
--td-font-white-1: rgba(255, 255, 255, 0.9);
--td-font-white-2: rgba(255, 255, 255, 0.55);
--td-font-white-3: rgba(255, 255, 255, 0.35);
--td-font-white-4: rgba(255, 255, 255, 0.22);
--td-font-gray-1: rgba(0, 0, 0, 0.9);
--td-font-gray-2: rgba(0, 0, 0, 0.6);
--td-font-gray-3: rgba(0, 0, 0, 0.4);
--td-font-gray-4: rgba(0, 0, 0, 0.26);
--td-gray-color-1: #f3f3f3;
--td-gray-color-2: #eee;
--td-gray-color-3: #e7e7e7;
--td-gray-color-4: #dcdcdc;
--td-gray-color-5: #c5c5c5;
--td-gray-color-6: #a6a6a6;
--td-gray-color-7: #8b8b8b;
--td-gray-color-8: #777;
--td-gray-color-9: #5e5e5e;
--td-gray-color-10: #4b4b4b;
--td-gray-color-11: #383838;
--td-gray-color-12: #2c2c2c;
--td-gray-color-13: #242424;
--td-gray-color-14: #181818;
--td-bg-color-page: var(--td-gray-color-14);
--td-bg-color-container: var(--td-gray-color-13);
--td-bg-color-container-hover: var(--td-gray-color-12);
--td-bg-color-container-active: var(--td-gray-color-10);
--td-bg-color-container-select: var(--td-gray-color-9);
--td-bg-color-secondarycontainer: var(--td-gray-color-12);
--td-bg-color-secondarycontainer-hover: var(--td-gray-color-11);
--td-bg-color-secondarycontainer-active: var(--td-gray-color-9);
--td-bg-color-component: var(--td-gray-color-11);
--td-bg-color-component-hover: var(--td-gray-color-10);
--td-bg-color-component-active: var(--td-gray-color-9);
--td-bg-color-secondarycomponent: var(--td-gray-color-10);
--td-bg-color-secondarycomponent-hover: var(--td-gray-color-9);
--td-bg-color-secondarycomponent-active: var(--td-gray-color-8);
--td-bg-color-component-disabled: var(--td-gray-color-12);
--td-component-stroke: var(--td-gray-color-11);
--td-component-border: var(--td-gray-color-9);
--td-font-white-1: rgba(255, 255, 255, 0.9);
--td-font-white-2: rgba(255, 255, 255, 0.55);
--td-font-white-3: rgba(255, 255, 255, 0.35);
--td-font-white-4: rgba(255, 255, 255, 0.22);
--td-font-gray-1: rgba(0, 0, 0, 0.9);
--td-font-gray-2: rgba(0, 0, 0, 0.6);
--td-font-gray-3: rgba(0, 0, 0, 0.4);
--td-font-gray-4: rgba(0, 0, 0, 0.26);
--td-text-color-primary: var(--td-font-white-1);
--td-text-color-secondary: var(--td-font-white-2);
--td-text-color-placeholder: var(--td-font-white-3);
--td-text-color-disabled: var(--td-font-white-4);
--td-text-color-anti: #fff;
--td-text-color-brand: var(--td-brand-color);
--td-text-color-link: var(--td-brand-color);
--td-table-shadow-color: rgba(0, 0, 0, 55%);
--td-scrollbar-color: rgba(255, 255, 255, 10%);
--td-scrollbar-hover-color: rgba(255, 255, 255, 30%);
--td-scroll-track-color: #333;
--td-bg-color-specialcomponent: transparent;
--td-border-level-1-color: var(--td-gray-color-11);
--td-border-level-2-color: var(--td-gray-color-9);
--td-mask-active: rgba(0, 0, 0, 0.4);
--td-mask-disabled: rgba(0, 0, 0, 0.6);
--td-shadow-inset-top: inset 0 0.5px 0 #5e5e5e;
--td-shadow-inset-right: inset 0.5px 0 0 #5e5e5e;
--td-shadow-inset-bottom: inset 0 -0.5px 0 #5e5e5e;
--td-shadow-inset-left: inset -0.5px 0 0 #5e5e5e;
/* 圆角配置 */
--td-radius-small: 2px;
--td-radius-default: 3px;
--td-radius-medium: 6px;
--td-radius-large: 9px;
--td-radius-extraLarge: 12px;
--td-radius-round: 999px;
--td-radius-circle: 50%;
/* end 圆角配置 *//* 阴影配置 */
--td-shadow-1: 0 1px 10px rgba(0, 0, 0, 0.05), 0 4px 5px rgba(0, 0, 0, 0.08), 0 2px 4px -1px rgba(0, 0, 0, 0.12);
--td-shadow-2: 0 3px 14px 2px rgba(0, 0, 0, 0.05), 0 8px 10px 1px rgba(0, 0, 0, 0.06), 0 5px 5px -3px rgba(0, 0, 0, 0.1);
--td-shadow-3: 0 6px 30px 5px rgba(0, 0, 0, 0.05), 0 16px 24px 2px rgba(0, 0, 0, 0.04), 0 8px 10px -5px rgba(0, 0, 0, 0.08);
/* end 阴影配置 *//* 尺寸配置 */
--td-size-1: 2px;
--td-size-2: 4px;
--td-size-3: 6px;
--td-size-4: 8px;
--td-size-5: 12px;
--td-size-6: 16px;
--td-size-7: 20px;
--td-size-8: 24px;
--td-size-9: 28px;
--td-size-10: 32px;
--td-size-11: 36px;
--td-size-12: 40px;
--td-size-13: 48px;
--td-size-14: 56px;
--td-size-15: 64px;
--td-size-16: 72px;
--td-comp-size-xxxs: var(--td-size-6);
--td-comp-size-xxs: var(--td-size-7);
--td-comp-size-xs: var(--td-size-8);
--td-comp-size-s: var(--td-size-9);
--td-comp-size-m: var(--td-size-10);
--td-comp-size-l: var(--td-size-11);
--td-comp-size-xl: var(--td-size-12);
--td-comp-size-xxl: var(--td-size-13);
--td-comp-size-xxxl: var(--td-size-14);
--td-comp-size-xxxxl: var(--td-size-15);
--td-comp-size-xxxxxl: var(--td-size-16);
--td-pop-padding-s: var(--td-size-2);
--td-pop-padding-m: var(--td-size-3);
--td-pop-padding-l: var(--td-size-4);
--td-pop-padding-xl: var(--td-size-5);
--td-pop-padding-xxl: var(--td-size-6);
--td-comp-paddingLR-xxs: var(--td-size-1);
--td-comp-paddingLR-xs: var(--td-size-2);
--td-comp-paddingLR-s: var(--td-size-4);
--td-comp-paddingLR-m: var(--td-size-5);
--td-comp-paddingLR-l: var(--td-size-6);
--td-comp-paddingLR-xl: var(--td-size-8);
--td-comp-paddingLR-xxl: var(--td-size-10);
--td-comp-paddingTB-xxs: var(--td-size-1);
--td-comp-paddingTB-xs: var(--td-size-2);
--td-comp-paddingTB-s: var(--td-size-4);
--td-comp-paddingTB-m: var(--td-size-5);
--td-comp-paddingTB-l: var(--td-size-6);
--td-comp-paddingTB-xl: var(--td-size-8);
--td-comp-paddingTB-xxl: var(--td-size-10);
--td-comp-margin-xxs: var(--td-size-1);
--td-comp-margin-xs: var(--td-size-2);
--td-comp-margin-s: var(--td-size-4);
--td-comp-margin-m: var(--td-size-5);
--td-comp-margin-l: var(--td-size-6);
--td-comp-margin-xl: var(--td-size-7);
--td-comp-margin-xxl: var(--td-size-8);
--td-comp-margin-xxxl: var(--td-size-10);
--td-comp-margin-xxxxl: var(--td-size-12);
/* end 尺寸配置 */
}

BIN
public/微信.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
public/支付,支付宝.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

3
server/tsconfig.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "../.nuxt/tsconfig.server.json"
}

4
tsconfig.json Normal file
View File

@ -0,0 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}