create-pubinfo 2.0.15 → 2.1.1
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.
- package/dist/cli.js +11 -11
- package/dist/{helper-DqTpncdb.js → helper-BzE6iSZN.js} +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/templates/pubinfo-app/package.json.hbs +1 -0
- package/templates/pubinfo-app/src/layouts/index.vue +4 -0
- package/templates/pubinfo-app/src/main.ts.hbs +2 -0
- package/templates/pubinfo-app/src/modules/captcha.ts +8 -0
- package/templates/pubinfo-app/src/views/system/login/components/PasswordLogin.vue +14 -31
- package/templates/pubinfo-app/src/views/system/login/composables.ts +5 -21
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as validateInput, n as readPackageJSON, r as run, t as bootstrop } from "./helper-
|
|
2
|
+
import { a as validateInput, n as readPackageJSON, r as run, t as bootstrop } from "./helper-BzE6iSZN.js";
|
|
3
3
|
import { checkbox, confirm, input, select } from "@inquirer/prompts";
|
|
4
|
+
import { logger } from "@pubinfo/shared";
|
|
4
5
|
import { Command } from "commander";
|
|
5
|
-
import consola from "consola";
|
|
6
6
|
import { resolve } from "node:path";
|
|
7
7
|
import process from "node:process";
|
|
8
8
|
import { existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
@@ -51,7 +51,7 @@ async function download(options) {
|
|
|
51
51
|
});
|
|
52
52
|
} catch (error) {
|
|
53
53
|
if (error.message.includes(REMOTE_URL)) error.message = error.message.replace(REMOTE_URL, "[REMOTE_URL]");
|
|
54
|
-
|
|
54
|
+
logger.error(`下载失败: ${error.message}`);
|
|
55
55
|
process.exit(1);
|
|
56
56
|
} finally {
|
|
57
57
|
finish();
|
|
@@ -67,7 +67,7 @@ function loading() {
|
|
|
67
67
|
return () => {
|
|
68
68
|
const { green, yellow } = colors;
|
|
69
69
|
spinner.stop();
|
|
70
|
-
|
|
70
|
+
logger.success(`${green("下载完成, 用时")} ${yellow(`${Date.now() - startTime}`)} ${green("ms.")}`);
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -91,7 +91,7 @@ async function fetchData() {
|
|
|
91
91
|
return { version: await fetchVersion() };
|
|
92
92
|
} catch (error) {
|
|
93
93
|
if (error.message.includes(REMOTE_URL)) error.message = error.message.replace(REMOTE_URL, "[REMOTE_URL]");
|
|
94
|
-
|
|
94
|
+
logger.error(`网络连接异常: ${error.message}`);
|
|
95
95
|
process.exit(1);
|
|
96
96
|
} finally {
|
|
97
97
|
spinner.stop();
|
|
@@ -121,13 +121,13 @@ async function writeJSON(path, json) {
|
|
|
121
121
|
*/
|
|
122
122
|
function rewriteFile(path, fn) {
|
|
123
123
|
if (!existsSync(path)) {
|
|
124
|
-
|
|
124
|
+
logger.error(`RewriteFile fail: ${path} does not exist`);
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
try {
|
|
128
128
|
writeFileSync(path, fn(readFileSync(path, { encoding: "utf-8" })));
|
|
129
129
|
} catch (error) {
|
|
130
|
-
|
|
130
|
+
logger.error(`RewriteFile fail: ${error}`);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -155,7 +155,7 @@ async function writeMetaJSON(metaDir, options) {
|
|
|
155
155
|
});
|
|
156
156
|
await writeJSON(path, json);
|
|
157
157
|
} catch (error) {
|
|
158
|
-
|
|
158
|
+
logger.error(`初始化 metadata 失败: ${error}`);
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
/**
|
|
@@ -164,7 +164,7 @@ async function writeMetaJSON(metaDir, options) {
|
|
|
164
164
|
function writeApps(appsDir, options) {
|
|
165
165
|
const { key, apps = [], openapi } = options;
|
|
166
166
|
if (!existsSync(appsDir)) {
|
|
167
|
-
|
|
167
|
+
logger.error(`初始化 apps 失败: ${appsDir} 不存在`);
|
|
168
168
|
return;
|
|
169
169
|
}
|
|
170
170
|
try {
|
|
@@ -184,7 +184,7 @@ function writeApps(appsDir, options) {
|
|
|
184
184
|
});
|
|
185
185
|
});
|
|
186
186
|
} catch (error) {
|
|
187
|
-
|
|
187
|
+
logger.error(`初始化 apps 失败: ${error}`);
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
|
|
@@ -247,7 +247,7 @@ async function main() {
|
|
|
247
247
|
}
|
|
248
248
|
await run(pkg.version);
|
|
249
249
|
} catch (error) {
|
|
250
|
-
|
|
250
|
+
logger.error(error);
|
|
251
251
|
}
|
|
252
252
|
});
|
|
253
253
|
program.parse();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { checkbox, confirm, input, select } from "@inquirer/prompts";
|
|
2
|
-
import
|
|
2
|
+
import { logger } from "@pubinfo/shared";
|
|
3
3
|
import { dirname, posix, relative, resolve, sep } from "node:path";
|
|
4
4
|
import process, { cwd } from "node:process";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -75,7 +75,7 @@ async function generate(options) {
|
|
|
75
75
|
const newPath = resolve(targetDir, newName || oldName);
|
|
76
76
|
if (existsSync(oldPath)) renameSync(oldPath, newPath);
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
logger.success(`${colors.green("项目模板初始化完成.")}`);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
//#endregion
|
|
@@ -128,7 +128,7 @@ async function interaction() {
|
|
|
128
128
|
});
|
|
129
129
|
return answer;
|
|
130
130
|
} catch {
|
|
131
|
-
|
|
131
|
+
logger.fail("操作终止");
|
|
132
132
|
process.exit(1);
|
|
133
133
|
}
|
|
134
134
|
}
|
|
@@ -147,7 +147,7 @@ async function run(version$1) {
|
|
|
147
147
|
var package_default = {
|
|
148
148
|
name: "create-pubinfo",
|
|
149
149
|
type: "module",
|
|
150
|
-
version: "2.
|
|
150
|
+
version: "2.1.1",
|
|
151
151
|
description: "初始化项目框架",
|
|
152
152
|
author: "Werheng <werheng.zhang@gmail.com>",
|
|
153
153
|
license: "MIT",
|
|
@@ -170,11 +170,11 @@ var package_default = {
|
|
|
170
170
|
},
|
|
171
171
|
dependencies: {
|
|
172
172
|
"@inquirer/prompts": "catalog:node",
|
|
173
|
+
"@pubinfo/shared": "workspace:*",
|
|
173
174
|
"ansi-colors": "catalog:node",
|
|
174
175
|
"cfonts": "catalog:node",
|
|
175
176
|
"commander": "catalog:node",
|
|
176
177
|
"confbox": "catalog:node",
|
|
177
|
-
"consola": "catalog:browser",
|
|
178
178
|
"fs-extra": "catalog:node",
|
|
179
179
|
"giget": "catalog:node",
|
|
180
180
|
"node-plop": "catalog:node",
|
package/dist/index.d.ts
CHANGED
|
@@ -97,11 +97,11 @@ declare function readPackageJSON(): {
|
|
|
97
97
|
};
|
|
98
98
|
dependencies: {
|
|
99
99
|
"@inquirer/prompts": string;
|
|
100
|
+
"@pubinfo/shared": string;
|
|
100
101
|
"ansi-colors": string;
|
|
101
102
|
cfonts: string;
|
|
102
103
|
commander: string;
|
|
103
104
|
confbox: string;
|
|
104
|
-
consola: string;
|
|
105
105
|
"fs-extra": string;
|
|
106
106
|
giget: string;
|
|
107
107
|
"node-plop": string;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as interaction, n as readPackageJSON, o as generate, r as run, s as copyTemplate } from "./helper-
|
|
1
|
+
import { i as interaction, n as readPackageJSON, o as generate, r as run, s as copyTemplate } from "./helper-BzE6iSZN.js";
|
|
2
2
|
|
|
3
3
|
export { copyTemplate, generate, interaction, readPackageJSON, run };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-pubinfo",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.1.1",
|
|
5
5
|
"description": "初始化项目框架",
|
|
6
6
|
"author": "Werheng <werheng.zhang@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"cfonts": "^3.3.0",
|
|
31
31
|
"commander": "^14.0.0",
|
|
32
32
|
"confbox": "^0.2.2",
|
|
33
|
-
"consola": "^3.4.2",
|
|
34
33
|
"fs-extra": "^11.3.0",
|
|
35
34
|
"giget": "^2.0.0",
|
|
36
35
|
"node-plop": "0.32.2",
|
|
37
36
|
"ofetch": "^1.4.1",
|
|
38
37
|
"ora": "^8.2.0",
|
|
39
38
|
"rimraf": "^6.0.1",
|
|
40
|
-
"semver": "^7.7.2"
|
|
39
|
+
"semver": "^7.7.2",
|
|
40
|
+
"@pubinfo/shared": "2.1.1"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^24.0.10"
|
|
@@ -2,6 +2,7 @@ import { createPubinfo } from 'pubinfo';
|
|
|
2
2
|
import { auth, basic } from './api/request';
|
|
3
3
|
import App from './App.vue';
|
|
4
4
|
import { setupAuth } from './modules/auth';
|
|
5
|
+
import { setupCaptcha } from './modules/captcha';
|
|
5
6
|
{{#if rbac}}
|
|
6
7
|
import { setupRbac } from './modules/rbac';
|
|
7
8
|
{{/if}}
|
|
@@ -19,6 +20,7 @@ createPubinfo({
|
|
|
19
20
|
},
|
|
20
21
|
modules: [
|
|
21
22
|
setupAuth(),
|
|
23
|
+
setupCaptcha(),
|
|
22
24
|
{{#if rbac}}
|
|
23
25
|
setupRbac(),
|
|
24
26
|
{{/if}}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
|
|
3
3
|
import type { UnwrapRef } from 'vue';
|
|
4
|
+
import { PubinfoVerifyInput } from '@pubinfo/module-captcha';
|
|
4
5
|
import { useToggle } from '@vueuse/core';
|
|
5
6
|
import { message, Modal } from 'ant-design-vue';
|
|
6
|
-
import { RESPONSE_CODE } from 'pubinfo';
|
|
7
|
-
import {
|
|
8
|
-
import { useCaptchas, useFocusElement } from '../composables';
|
|
7
|
+
import { RESPONSE_CODE, useUserStore } from 'pubinfo';
|
|
8
|
+
import { useFocusElement } from '../composables';
|
|
9
9
|
import Useragreement from './Useragreement.vue';
|
|
10
10
|
|
|
11
11
|
defineOptions({
|
|
@@ -32,19 +32,20 @@ function isHttpError(error: unknown): error is HttpError {
|
|
|
32
32
|
return (error as HttpError).code !== undefined;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
const pubinfoVerifyInputRef = ref<InstanceType<typeof PubinfoVerifyInput> | null>(null);
|
|
35
36
|
const userStore = useUserStore();
|
|
36
|
-
const { send, captcha, captchaHash } = useCaptchas();
|
|
37
37
|
const router = useRouter();
|
|
38
38
|
const route = useRoute();
|
|
39
39
|
const { focusElementDataId } = useFocusElement();
|
|
40
40
|
|
|
41
41
|
const loginForm = ref<FormInstance | null>(null);
|
|
42
|
-
const formState: UnwrapRef<FormState> = reactive({
|
|
42
|
+
const formState: UnwrapRef<FormState & { captchaType?: string }> = reactive({
|
|
43
43
|
account: '',
|
|
44
44
|
password: '',
|
|
45
45
|
captchas: '',
|
|
46
46
|
checked: true,
|
|
47
|
-
captchaHash,
|
|
47
|
+
captchaHash: '',
|
|
48
|
+
captchaType: '',
|
|
48
49
|
});
|
|
49
50
|
|
|
50
51
|
const rules: Record<string, Rule[]> = {
|
|
@@ -53,6 +54,10 @@ const rules: Record<string, Rule[]> = {
|
|
|
53
54
|
captchas: [{ required: true, whitespace: true, message: '请输入验证码' }],
|
|
54
55
|
};
|
|
55
56
|
|
|
57
|
+
function getCaptchaHash(hash: string) {
|
|
58
|
+
formState.captchaHash = hash;
|
|
59
|
+
}
|
|
60
|
+
|
|
56
61
|
const [loading, setLoading] = useToggle(false);
|
|
57
62
|
|
|
58
63
|
async function onSubmit() {
|
|
@@ -62,7 +67,7 @@ async function onSubmit() {
|
|
|
62
67
|
setLoading(true);
|
|
63
68
|
try {
|
|
64
69
|
await loginForm.value?.validate();
|
|
65
|
-
await userStore.
|
|
70
|
+
await userStore.signIn(formState);
|
|
66
71
|
message.success('登录成功');
|
|
67
72
|
router.push(route.query.redirect?.toString() ?? '/');
|
|
68
73
|
}
|
|
@@ -73,7 +78,7 @@ async function onSubmit() {
|
|
|
73
78
|
case RESPONSE_CODE.LOGINNAME_PASSWORD_WRONG:
|
|
74
79
|
case RESPONSE_CODE.CODE_OVERTIME:
|
|
75
80
|
case RESPONSE_CODE.CODE_WRONG:
|
|
76
|
-
|
|
81
|
+
pubinfoVerifyInputRef.value?.refresh();
|
|
77
82
|
break;
|
|
78
83
|
case RESPONSE_CODE.CHANGE_INIT_PASSWORD:
|
|
79
84
|
case RESPONSE_CODE.PASSWORD_EXPIRED:
|
|
@@ -142,33 +147,11 @@ function createChangePasswordModal(msg: string, token: string) {
|
|
|
142
147
|
</a-input-password>
|
|
143
148
|
</a-form-item>
|
|
144
149
|
<a-form-item name="captchas">
|
|
145
|
-
<
|
|
146
|
-
v-model:value="formState.captchas"
|
|
147
|
-
size="large"
|
|
148
|
-
allow-clear
|
|
149
|
-
placeholder="请输入验证码"
|
|
150
|
-
data-id="captchas"
|
|
151
|
-
>
|
|
152
|
-
<template #prefix>
|
|
153
|
-
<PubinfoIcon v-if="focusElementDataId === 'captchas'" name="i-solar-shield-check-bold" color="#1578FF" />
|
|
154
|
-
<PubinfoIcon v-else name="i-solar-shield-check-broken" color="#AFB0B2" />
|
|
155
|
-
</template>
|
|
156
|
-
<template #addonAfter>
|
|
157
|
-
<div
|
|
158
|
-
w-100px
|
|
159
|
-
h-38px
|
|
160
|
-
cursor-pointer
|
|
161
|
-
@click="send"
|
|
162
|
-
>
|
|
163
|
-
<img :src="captcha">
|
|
164
|
-
</div>
|
|
165
|
-
</template>
|
|
166
|
-
</a-input>
|
|
150
|
+
<PubinfoVerifyInput ref="pubinfoVerifyInputRef" v-model="formState.captchas" size="large" @get-captcha-hash="getCaptchaHash" />
|
|
167
151
|
</a-form-item>
|
|
168
152
|
<a-form-item>
|
|
169
153
|
<Useragreement v-model:checked="formState.checked" />
|
|
170
154
|
</a-form-item>
|
|
171
|
-
<!-- 登录 -->
|
|
172
155
|
<a-form-item>
|
|
173
156
|
<div w-full h-48px>
|
|
174
157
|
<a-button
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Component, MaybeRef } from 'vue';
|
|
2
|
+
import { LoginWithFourA } from '@pubinfo/module-auth';
|
|
2
3
|
import { useActiveElement } from '@vueuse/core';
|
|
3
|
-
import { useRequest } from 'alova/client';
|
|
4
|
-
import { getAuthLoginValidCode } from '@/api/modules/auth';
|
|
5
4
|
|
|
6
5
|
interface LoginTabs {
|
|
7
6
|
title: string
|
|
@@ -18,6 +17,10 @@ export function useLoginTabs() {
|
|
|
18
17
|
title: '手机号登录',
|
|
19
18
|
component: defineAsyncComponent(() => import('./components/LoginWithPhone.vue')),
|
|
20
19
|
},
|
|
20
|
+
{
|
|
21
|
+
title: '4A登录',
|
|
22
|
+
component: LoginWithFourA,
|
|
23
|
+
},
|
|
21
24
|
];
|
|
22
25
|
const initialTab = ref(0);
|
|
23
26
|
|
|
@@ -31,25 +34,6 @@ export function useLoginTabs() {
|
|
|
31
34
|
};
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
export function useCaptchas() {
|
|
35
|
-
const { send, onSuccess } = useRequest(getAuthLoginValidCode({ size: '100x40' }));
|
|
36
|
-
const captcha = ref('');
|
|
37
|
-
const captchaHash = ref('');
|
|
38
|
-
|
|
39
|
-
onSuccess(({ data }) => {
|
|
40
|
-
const { key, plaintext } = data.data!;
|
|
41
|
-
|
|
42
|
-
const imgUrl = `data:image/png;base64,${plaintext}`;
|
|
43
|
-
captcha.value = imgUrl;
|
|
44
|
-
captchaHash.value = key!;
|
|
45
|
-
});
|
|
46
|
-
return {
|
|
47
|
-
send,
|
|
48
|
-
captcha,
|
|
49
|
-
captchaHash,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
37
|
export function useFocusElement() {
|
|
54
38
|
const activeElement = useActiveElement();
|
|
55
39
|
const focusElementDataId = computed(() =>
|