create-admin-mvp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/index.d.mts +1 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +175 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +159 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/package.json +41 -0
  8. package/templates/admin-portal/ .stylelintrc.cjs +39 -0
  9. package/templates/admin-portal/.dockerignore +60 -0
  10. package/templates/admin-portal/.env +29 -0
  11. package/templates/admin-portal/.env.development +41 -0
  12. package/templates/admin-portal/.env.example +4 -0
  13. package/templates/admin-portal/.env.production +41 -0
  14. package/templates/admin-portal/.eslintrc.cjs +45 -0
  15. package/templates/admin-portal/.github/workflows/ci.yml +217 -0
  16. package/templates/admin-portal/.husky/commit-msg +11 -0
  17. package/templates/admin-portal/.husky/pre-commit +10 -0
  18. package/templates/admin-portal/.lintstagedrc.json +13 -0
  19. package/templates/admin-portal/.prettierrc.cjs +19 -0
  20. package/templates/admin-portal/.stylelintrc.cjs +35 -0
  21. package/templates/admin-portal/Dockerfile +35 -0
  22. package/templates/admin-portal/README.md +196 -0
  23. package/templates/admin-portal/commitlint.config.cjs +41 -0
  24. package/templates/admin-portal/docker-compose.yml +35 -0
  25. package/templates/admin-portal/index.html +13 -0
  26. package/templates/admin-portal/nginx.conf +45 -0
  27. package/templates/admin-portal/package-lock.json +10730 -0
  28. package/templates/admin-portal/package.json +62 -0
  29. package/templates/admin-portal/playwright-report/index.html +85 -0
  30. package/templates/admin-portal/playwright.config.ts +73 -0
  31. package/templates/admin-portal/pnpm-lock.yaml +1620 -0
  32. package/templates/admin-portal/postcss.config.cjs +56 -0
  33. package/templates/admin-portal/public/vite.svg +1 -0
  34. package/templates/admin-portal/src/App.vue +15 -0
  35. package/templates/admin-portal/src/assets/styles/main.css +36 -0
  36. package/templates/admin-portal/src/assets/vue.svg +1 -0
  37. package/templates/admin-portal/src/components/HelloWorld.vue +41 -0
  38. package/templates/admin-portal/src/layout/index.vue +23 -0
  39. package/templates/admin-portal/src/main.ts +12 -0
  40. package/templates/admin-portal/src/mock/auth.ts +26 -0
  41. package/templates/admin-portal/src/permission.ts +15 -0
  42. package/templates/admin-portal/src/router/index.ts +21 -0
  43. package/templates/admin-portal/src/style.css +79 -0
  44. package/templates/admin-portal/src/views/About.vue +15 -0
  45. package/templates/admin-portal/src/views/Home.vue +15 -0
  46. package/templates/admin-portal/src/views/login/index.vue +34 -0
  47. package/templates/admin-portal/test-results/.last-run.json +23 -0
  48. package/templates/admin-portal/test-results/results.json +882 -0
  49. package/templates/admin-portal/tests/e2e/example.spec.ts +52 -0
  50. package/templates/admin-portal/tests/unit/example.test.ts +49 -0
  51. package/templates/admin-portal/tsconfig.app.json +18 -0
  52. package/templates/admin-portal/tsconfig.json +7 -0
  53. package/templates/admin-portal/tsconfig.node.json +22 -0
  54. package/templates/admin-portal/vite.config.ts +21 -0
  55. package/templates/admin-portal/vitest.config.ts +49 -0
  56. package/templates/admin-portal/vitest.setup.ts +60 -0
@@ -0,0 +1,56 @@
1
+ // PostCSS 配置文件
2
+ // 配置 CSS 处理工具,用于 rem 转换
3
+
4
+ module.exports = {
5
+ // 1. 插件列表
6
+ plugins: {
7
+ // 1.1 autoprefixer:自动添加浏览器前缀
8
+ // 作用:自动添加 -webkit-、-moz-、-ms- 等浏览器前缀
9
+ autoprefixer: {
10
+ // 1.1.1 覆盖率:添加浏览器前缀的覆盖范围
11
+ // > 1%:添加超过 1% 用户使用的浏览器前缀
12
+ // last 2 versions:最近 2 个版本的浏览器
13
+ overrideBrowserslist: ['> 1%', 'last 2 versions'],
14
+ },
15
+
16
+ // 1.2 postcss-pxtorem:px 转 rem
17
+ // 作用:把 px 单位自动转换为 rem 单位
18
+ 'postcss-pxtorem': {
19
+ // 1.2.1 根元素字体大小:1rem = 根元素字体大小
20
+ // 16:根元素字体大小为 16px
21
+ rootValue: 16,
22
+
23
+ // 1.2.2 单位精度:rem 的小数位数
24
+ // 6:保留 6 位小数
25
+ unitPrecision: 6,
26
+
27
+ // 1.2.3 转换规则:哪些 px 需要转换
28
+ // propList:属性列表,只转换这些属性的 px
29
+ propList: [
30
+ 'font',
31
+ 'font-size',
32
+ 'line-height',
33
+ 'letter-spacing',
34
+ ],
35
+
36
+ // 1.2.4 选择器黑名单:不转换这些选择器
37
+ // selectorBlackList:选择器列表,不转换这些选择器
38
+ selectorBlackList: [
39
+ 'body', // body 选择器不转换
40
+ 'html', // html 选择器不转换
41
+ ],
42
+
43
+ // 1.2.5 替换规则:是否替换规则而不是追加
44
+ // replace:true = 替换规则
45
+ replace: true,
46
+
47
+ // 1.2.6 媒体查询:是否在媒体查询中转换
48
+ // mediaQuery:false = 不在媒体查询中转换
49
+ mediaQuery: false,
50
+
51
+ // 1.2.7 最小像素值:小于这个值的 px 不转换
52
+ // minPixelValue:2 = 小于 2px 的不转换
53
+ minPixelValue: 2,
54
+ },
55
+ },
56
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <div id="app">
3
+ <router-view />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ </script>
9
+
10
+ <style scoped>
11
+ #app {
12
+ width: 100%;
13
+ height: 100vh;
14
+ }
15
+ </style>
@@ -0,0 +1,36 @@
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ html,
8
+ body {
9
+ width: 100%;
10
+ height: 100%;
11
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
12
+ font-size: 14px;
13
+ line-height: 1.5;
14
+ color: #333;
15
+ background-color: #fff;
16
+ }
17
+
18
+ a {
19
+ text-decoration: none;
20
+ color: inherit;
21
+ }
22
+
23
+ button {
24
+ border: none;
25
+ outline: none;
26
+ cursor: pointer;
27
+ background: none;
28
+ font-family: inherit;
29
+ }
30
+
31
+ input,
32
+ textarea {
33
+ border: none;
34
+ outline: none;
35
+ font-family: inherit;
36
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
@@ -0,0 +1,41 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+
4
+ defineProps<{ msg: string }>()
5
+
6
+ const count = ref(0)
7
+ </script>
8
+
9
+ <template>
10
+ <h1>{{ msg }}</h1>
11
+
12
+ <div class="card">
13
+ <button type="button" @click="count++">count is {{ count }}</button>
14
+ <p>
15
+ Edit
16
+ <code>components/HelloWorld.vue</code> to test HMR
17
+ </p>
18
+ </div>
19
+
20
+ <p>
21
+ Check out
22
+ <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
23
+ >create-vue</a
24
+ >, the official Vue + Vite starter
25
+ </p>
26
+ <p>
27
+ Learn more about IDE Support for Vue in the
28
+ <a
29
+ href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
30
+ target="_blank"
31
+ >Vue Docs Scaling up Guide</a
32
+ >.
33
+ </p>
34
+ <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
35
+ </template>
36
+
37
+ <style scoped>
38
+ .read-the-docs {
39
+ color: #888;
40
+ }
41
+ </style>
@@ -0,0 +1,23 @@
1
+ <!--
2
+ * @Author: xhp 837792102@qq.com
3
+ * @Date: 2026-01-18 22:15:09
4
+ * @LastEditors: xhp 837792102@qq.com
5
+ * @LastEditTime: 2026-01-18 22:15:21
6
+ * @FilePath: /admin-mvp/src/layout/index.vue
7
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
8
+ -->
9
+ <script setup lang="ts">
10
+ import router from "../router";
11
+
12
+ function logout() {
13
+ localStorage.removeItem("token");
14
+ router.push("/login");
15
+ }
16
+ </script>
17
+
18
+ <template>
19
+ <div>
20
+ <h1>Admin Layout</h1>
21
+ <button @click="logout">logout</button>
22
+ </div>
23
+ </template>
@@ -0,0 +1,12 @@
1
+ import { createApp } from 'vue'
2
+ import { createPinia } from 'pinia'
3
+ import App from './App.vue'
4
+ import router from './router'
5
+ import './assets/styles/main.css'
6
+
7
+ const app = createApp(App)
8
+
9
+ app.use(createPinia())
10
+ app.use(router)
11
+
12
+ app.mount('#app')
@@ -0,0 +1,26 @@
1
+ /*
2
+ * @Author: xhp 837792102@qq.com
3
+ * @Date: 2026-01-18 21:41:45
4
+ * @LastEditors: xhp 837792102@qq.com
5
+ * @LastEditTime: 2026-01-21 16:31:18
6
+ * @FilePath: /admin-mvp/src/mock/auth.ts
7
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
8
+ */
9
+ // 从 vite-plugin-mock 插件导入 MockMethod 类型定义
10
+ import type { MockMethod } from 'vite-plugin-mock'
11
+
12
+ // 导出一个 mock 接口配置数组
13
+ export default [
14
+ {
15
+ url: '/api/auth/login',
16
+ method: 'post',
17
+ response: ({ body }: { body: { username?: string; password?: string } }) => {
18
+ if (body?.username === 'admin' && body?.password === '123456') {
19
+ return { code: 0, data: { token: 'mock-token-admin' }, msg: 'ok' }
20
+ }
21
+ return { code: 0, data: { token: 'mock-token-guest' }, msg: 'ok' }
22
+ },
23
+ },
24
+ ] as MockMethod[]
25
+
26
+
@@ -0,0 +1,15 @@
1
+ /*
2
+ * @Author: xhp 837792102@qq.com
3
+ * @Date: 2026-01-19 12:50:30
4
+ * @LastEditors: xhp 837792102@qq.com
5
+ * @LastEditTime: 2026-01-19 12:50:45
6
+ * @FilePath: /admin-mvp/src/permission.ts
7
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
8
+ */
9
+ import router from './router'
10
+ import type { RouteLocationNormalized } from 'vue-router'
11
+
12
+ router.beforeEach((to: RouteLocationNormalized) => {
13
+ const token = localStorage.getItem('token')
14
+ if (!token && to.path !== '/login') return '/login'
15
+ })
@@ -0,0 +1,21 @@
1
+ import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
2
+
3
+ const routes: RouteRecordRaw[] = [
4
+ {
5
+ path: '/',
6
+ name: 'Home',
7
+ component: () => import('@/views/Home.vue'),
8
+ },
9
+ {
10
+ path: '/about',
11
+ name: 'About',
12
+ component: () => import('@/views/About.vue'),
13
+ },
14
+ ]
15
+
16
+ const router = createRouter({
17
+ history: createWebHistory(import.meta.env.BASE_URL),
18
+ routes,
19
+ })
20
+
21
+ export default router
@@ -0,0 +1,79 @@
1
+ :root {
2
+ font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3
+ line-height: 1.5;
4
+ font-weight: 400;
5
+
6
+ color-scheme: light dark;
7
+ color: rgba(255, 255, 255, 0.87);
8
+ background-color: #242424;
9
+
10
+ font-synthesis: none;
11
+ text-rendering: optimizeLegibility;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
15
+
16
+ a {
17
+ font-weight: 500;
18
+ color: #646cff;
19
+ text-decoration: inherit;
20
+ }
21
+ a:hover {
22
+ color: #535bf2;
23
+ }
24
+
25
+ body {
26
+ margin: 0;
27
+ display: flex;
28
+ place-items: center;
29
+ min-width: 320px;
30
+ min-height: 100vh;
31
+ }
32
+
33
+ h1 {
34
+ font-size: 3.2em;
35
+ line-height: 1.1;
36
+ }
37
+
38
+ button {
39
+ border-radius: 8px;
40
+ border: 1px solid transparent;
41
+ padding: 0.6em 1.2em;
42
+ font-size: 1em;
43
+ font-weight: 500;
44
+ font-family: inherit;
45
+ background-color: #1a1a1a;
46
+ cursor: pointer;
47
+ transition: border-color 0.25s;
48
+ }
49
+ button:hover {
50
+ border-color: #646cff;
51
+ }
52
+ button:focus,
53
+ button:focus-visible {
54
+ outline: 4px auto -webkit-focus-ring-color;
55
+ }
56
+
57
+ .card {
58
+ padding: 2em;
59
+ }
60
+
61
+ #app {
62
+ max-width: 1280px;
63
+ margin: 0 auto;
64
+ padding: 2rem;
65
+ text-align: center;
66
+ }
67
+
68
+ @media (prefers-color-scheme: light) {
69
+ :root {
70
+ color: #213547;
71
+ background-color: #ffffff;
72
+ }
73
+ a:hover {
74
+ color: #747bff;
75
+ }
76
+ button {
77
+ background-color: #f9f9f9;
78
+ }
79
+ }
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <div class="about">
3
+ <h1>About Page</h1>
4
+ <p>This is the about page.</p>
5
+ </div>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ </script>
10
+
11
+ <style scoped>
12
+ .about {
13
+ padding: 20px;
14
+ }
15
+ </style>
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <div class="home">
3
+ <h1>Home Page</h1>
4
+ <p>Welcome to the home page!</p>
5
+ </div>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ </script>
10
+
11
+ <style scoped>
12
+ .home {
13
+ padding: 20px;
14
+ }
15
+ </style>
@@ -0,0 +1,34 @@
1
+ <!--
2
+ * @Author: xhp 837792102@qq.com
3
+ * @Date: 2026-01-19 12:48:15
4
+ * @LastEditors: xhp 837792102@qq.com
5
+ * @LastEditTime: 2026-01-19 12:50:14
6
+ * @FilePath: /admin-mvp/src/views/login/index.vue
7
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
8
+ -->
9
+ <script setup lang="ts">
10
+ import { ref } from "vue";
11
+ import axios from "axios";
12
+ import router from "../../router";
13
+
14
+ const username = ref("admin");
15
+ const password = ref("123456");
16
+
17
+ async function onLogin() {
18
+ const res = await axios.post("/api/auth/login", {
19
+ username: username.value,
20
+ password: password.value,
21
+ });
22
+ localStorage.setItem("token", res.data.data.token);
23
+ router.push("/");
24
+ }
25
+ </script>
26
+
27
+ <template>
28
+ <div>
29
+ <h1>Login</h1>
30
+ <input v-model="username" placeholder="username" />
31
+ <input v-model="password" placeholder="password" type="password" />
32
+ <button @click="onLogin">login</button>
33
+ </div>
34
+ </template>
@@ -0,0 +1,23 @@
1
+ {
2
+ "status": "failed",
3
+ "failedTests": [
4
+ "a30a6eba6312f6b87ea5-fa16ec4464d78a46c0e3",
5
+ "a30a6eba6312f6b87ea5-b7b5d8f5bde06502d420",
6
+ "a30a6eba6312f6b87ea5-f8ffa1ecae4b7bbba524",
7
+ "a30a6eba6312f6b87ea5-3557a571baf50abf4052",
8
+ "a30a6eba6312f6b87ea5-882c191ec598045d8e7d",
9
+ "a30a6eba6312f6b87ea5-d3837c1e87e35186f0a8",
10
+ "a30a6eba6312f6b87ea5-2bf6908e1ce54f0bb0a5",
11
+ "a30a6eba6312f6b87ea5-95ede7b2041b5b9684ef",
12
+ "a30a6eba6312f6b87ea5-de7c7c8d622c8bb693dc",
13
+ "a30a6eba6312f6b87ea5-9d0122a9ee5226062ae1",
14
+ "a30a6eba6312f6b87ea5-f059b4fe8c0579a60336",
15
+ "a30a6eba6312f6b87ea5-5a5cbbdcbff1ff0ff143",
16
+ "a30a6eba6312f6b87ea5-144df201d3eaf6de7c31",
17
+ "a30a6eba6312f6b87ea5-2b1ad10e38a921b63db0",
18
+ "a30a6eba6312f6b87ea5-8316adf1aaa206904998",
19
+ "a30a6eba6312f6b87ea5-e29a7150aece2d7b8b58",
20
+ "a30a6eba6312f6b87ea5-8f8e04e9b23f1f70a6a5",
21
+ "a30a6eba6312f6b87ea5-558a5297e26c3cddfbf3"
22
+ ]
23
+ }