create-young-proj 1.4.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +32 -0
- package/package.json +1 -1
- package/template-nuxt-admin/README.md +1 -1
- package/template-nuxt-admin/nuxt.config.ts +4 -5
- package/template-nuxt-admin/package.json +0 -1
- package/template-nuxt-admin/server/plugins/env.ts +8 -0
- package/template-nuxt-admin/yarn.lock +0 -5
- package/template-nuxt-mobile/.nvmrc +1 -0
- package/{template-vue-mobile → template-nuxt-mobile}/.vscode/extensions.json +5 -3
- package/template-nuxt-mobile/.vscode/settings.json +39 -0
- package/{template-vue-mobile → template-nuxt-mobile}/Dockerfile +12 -13
- package/template-nuxt-mobile/README.md +90 -0
- package/template-nuxt-mobile/_gitignore +26 -0
- package/template-nuxt-mobile/_npmrc +2 -0
- package/template-nuxt-mobile/_nvmrc +1 -0
- package/template-nuxt-mobile/app.vue +79 -0
- package/template-nuxt-mobile/boot.mjs +17 -0
- package/template-nuxt-mobile/components/young/CodeInput.vue +72 -0
- package/template-nuxt-mobile/composables/api.ts +57 -0
- package/template-nuxt-mobile/composables/apis/get.ts +22 -0
- package/template-nuxt-mobile/composables/apis/index.ts +8 -0
- package/template-nuxt-mobile/composables/apis/post.ts +39 -0
- package/template-nuxt-mobile/composables/share.ts +22 -0
- package/template-nuxt-mobile/composables/user.ts +48 -0
- package/template-nuxt-mobile/composables/utils.ts +80 -0
- package/template-nuxt-mobile/config/.devrc +2 -0
- package/template-nuxt-mobile/env.d.ts +65 -0
- package/template-nuxt-mobile/error.vue +69 -0
- package/template-nuxt-mobile/eslint.config.js +33 -0
- package/template-nuxt-mobile/layouts/blank.vue +11 -0
- package/template-nuxt-mobile/layouts/default.vue +32 -0
- package/template-nuxt-mobile/layouts/tabbar.vue +29 -0
- package/template-nuxt-mobile/middleware/auth.global.ts +34 -0
- package/template-nuxt-mobile/nuxt.config.ts +78 -0
- package/template-nuxt-mobile/package.json +40 -0
- package/template-nuxt-mobile/pages/base/login.vue +124 -0
- package/template-nuxt-mobile/pages/base/resetPasswd.vue +84 -0
- package/template-nuxt-mobile/pages/index.vue +22 -0
- package/template-nuxt-mobile/pages/my.vue +18 -0
- package/template-nuxt-mobile/pages/sub/[id].vue +21 -0
- package/template-nuxt-mobile/public/favicon.ico +0 -0
- package/template-nuxt-mobile/public/robots.txt +2 -0
- package/template-nuxt-mobile/server/plugins/init.ts +94 -0
- package/template-nuxt-mobile/server/routes/get/env.ts +13 -0
- package/template-nuxt-mobile/server/tsconfig.json +3 -0
- package/template-nuxt-mobile/server/utils/index.ts +12 -0
- package/template-nuxt-mobile/server/utils/proxy.ts +59 -0
- package/template-nuxt-mobile/tsconfig.json +4 -0
- package/template-nuxt-mobile/typings/system.d.ts +22 -0
- package/template-nuxt-mobile/uno.config.ts +40 -0
- package/template-nuxt-mobile/utils/tool.ts +153 -0
- package/template-nuxt-mobile/yarn.lock +7737 -0
- package/template-nuxt-website/README.md +3 -1
- package/template-nuxt-website/nuxt.config.ts +4 -5
- package/template-vitepress/Dockerfile +6 -2
- package/template-vue-mobile/.vscode/base.code-snippets +0 -24
- package/template-vue-mobile/.vscode/settings.json +0 -7
- package/template-vue-mobile/README.md +0 -71
- package/template-vue-mobile/_env +0 -6
- package/template-vue-mobile/_gitignore +0 -30
- package/template-vue-mobile/boot.mjs +0 -16
- package/template-vue-mobile/build/custom-plugin.ts +0 -30
- package/template-vue-mobile/build/index.ts +0 -7
- package/template-vue-mobile/build/plugins.ts +0 -68
- package/template-vue-mobile/config/.devrc +0 -2
- package/template-vue-mobile/index.html +0 -25
- package/template-vue-mobile/nitro.config.ts +0 -19
- package/template-vue-mobile/package.json +0 -48
- package/template-vue-mobile/plugins/env.ts +0 -26
- package/template-vue-mobile/public/vite.svg +0 -1
- package/template-vue-mobile/rome.json +0 -24
- package/template-vue-mobile/routes/[...all].ts +0 -11
- package/template-vue-mobile/routes/get/env.ts +0 -25
- package/template-vue-mobile/src/App.vue +0 -29
- package/template-vue-mobile/src/auto-components.d.ts +0 -24
- package/template-vue-mobile/src/auto-imports.d.ts +0 -289
- package/template-vue-mobile/src/components/Init.vue +0 -36
- package/template-vue-mobile/src/global.d.ts +0 -7
- package/template-vue-mobile/src/hooks/useVerifyCode.ts +0 -46
- package/template-vue-mobile/src/layouts/blank.vue +0 -9
- package/template-vue-mobile/src/layouts/default.vue +0 -27
- package/template-vue-mobile/src/layouts/sub.vue +0 -20
- package/template-vue-mobile/src/main.ts +0 -35
- package/template-vue-mobile/src/modules/1-router.ts +0 -40
- package/template-vue-mobile/src/modules/2-pinia.ts +0 -10
- package/template-vue-mobile/src/modules/3-net.ts +0 -46
- package/template-vue-mobile/src/modules/4-auth.ts +0 -64
- package/template-vue-mobile/src/views/[...all_404].vue +0 -557
- package/template-vue-mobile/src/views/base/login.vue +0 -110
- package/template-vue-mobile/src/views/base/resetPasswd.vue +0 -88
- package/template-vue-mobile/src/views/index.vue +0 -18
- package/template-vue-mobile/src/views/my.vue +0 -15
- package/template-vue-mobile/src/views/sub.vue +0 -18
- package/template-vue-mobile/src/vite-env.d.ts +0 -43
- package/template-vue-mobile/tsconfig.json +0 -21
- package/template-vue-mobile/tsconfig.node.json +0 -9
- package/template-vue-mobile/unocss.config.ts +0 -47
- package/template-vue-mobile/vite.config.ts +0 -32
- package/template-vue-mobile/yarn.lock +0 -4395
- /package/{template-vue-mobile → template-nuxt-mobile}/config/.onlinerc +0 -0
- /package/{template-vue-mobile → template-nuxt-mobile}/config/.testrc +0 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
<!--
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2021-09-09 12:07:27
|
4
|
+
* @LastEditTime: 2023-11-30 10:41:19
|
5
|
+
* @Description: 重置密码 | 修改密码
|
6
|
+
-->
|
7
|
+
<script lang="ts" setup>
|
8
|
+
import type { FormInstance } from 'vant'
|
9
|
+
import { isMobile } from '@bluesyoung/utils'
|
10
|
+
|
11
|
+
definePageMeta({
|
12
|
+
title: '重置密码',
|
13
|
+
layout: 'blank',
|
14
|
+
auth: false,
|
15
|
+
})
|
16
|
+
|
17
|
+
const formRef = ref<FormInstance>()
|
18
|
+
|
19
|
+
const form = ref<ResetPasswdForm>({
|
20
|
+
tel: '',
|
21
|
+
code: '',
|
22
|
+
passwd: '',
|
23
|
+
passwd_again: '',
|
24
|
+
})
|
25
|
+
function validPasswd() {
|
26
|
+
const { passwd: p1, passwd_again: p2 } = form.value
|
27
|
+
return p1 === p2
|
28
|
+
}
|
29
|
+
const [showPass1, toggle1] = useToggle(false)
|
30
|
+
const [showPass2, toggle2] = useToggle(false)
|
31
|
+
async function sure() {
|
32
|
+
try {
|
33
|
+
await formRef.value?.validate()
|
34
|
+
await apis.post.changePassword(form.value)
|
35
|
+
showToast('修改成功,请重新登录!')
|
36
|
+
useUserStore().removeToken()
|
37
|
+
navigateTo('/base/login')
|
38
|
+
}
|
39
|
+
catch (error) {
|
40
|
+
|
41
|
+
}
|
42
|
+
}
|
43
|
+
</script>
|
44
|
+
|
45
|
+
<template>
|
46
|
+
<VanNavBar title="重置密码" safe-area-inset-bottom left-arrow @click-left="$router.back()" />
|
47
|
+
<div v-bind="$attrs" class="w-full h-full mt-10">
|
48
|
+
<VanForm ref="formRef">
|
49
|
+
<VanCellGroup inset>
|
50
|
+
<VanField
|
51
|
+
v-model.trim="form.tel" maxlength="11" placeholder="手机号" :rules="[
|
52
|
+
{ required: true, message: '请填写手机号' },
|
53
|
+
{ validator: isMobile, message: '请输入合法的手机号' },
|
54
|
+
]"
|
55
|
+
/>
|
56
|
+
<YoungCodeInput v-model.trim="form.code" :tel="form.tel" placeholder="验证码" :rules="[{ required: true, message: '请填写验证码' }]" />
|
57
|
+
|
58
|
+
<VanField
|
59
|
+
v-model.trim="form.passwd" placeholder="输入新密码" :type="showPass1 ? 'text' : 'password'" clearable
|
60
|
+
:rules="[{ required: true, message: '请填写新密码' }]"
|
61
|
+
>
|
62
|
+
<template #right-icon>
|
63
|
+
<VanIcon :name="showPass1 ? 'eye' : 'closed-eye'" @click="toggle1(!showPass1)" />
|
64
|
+
</template>
|
65
|
+
</VanField>
|
66
|
+
<VanField
|
67
|
+
v-model.trim="form.passwd_again" placeholder="再次确认新密码" :type="showPass2 ? 'text' : 'password'" :rules="[
|
68
|
+
{ required: true, message: '请确认新密码' },
|
69
|
+
{ validator: validPasswd, message: '两次输入的密码不一致' },
|
70
|
+
]"
|
71
|
+
>
|
72
|
+
<template #right-icon>
|
73
|
+
<VanIcon :name="showPass2 ? 'eye' : 'closed-eye'" @click="toggle2(!showPass2)" />
|
74
|
+
</template>
|
75
|
+
</VanField>
|
76
|
+
</VanCellGroup>
|
77
|
+
<div class="m-4">
|
78
|
+
<VanButton block type="primary" @click="sure">
|
79
|
+
确定
|
80
|
+
</VanButton>
|
81
|
+
</div>
|
82
|
+
</VanForm>
|
83
|
+
</div>
|
84
|
+
</template>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<!--
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-09-21 16:38:58
|
4
|
+
* @LastEditTime: 2023-11-29 17:16:58
|
5
|
+
* @Description:
|
6
|
+
-->
|
7
|
+
<script lang="ts" setup>
|
8
|
+
definePageMeta({
|
9
|
+
title: '首页',
|
10
|
+
layout: 'tabbar',
|
11
|
+
auth: false,
|
12
|
+
})
|
13
|
+
</script>
|
14
|
+
|
15
|
+
<template>
|
16
|
+
<div>
|
17
|
+
我是首页
|
18
|
+
<NuxtLink to="/sub/index" class="text-purple-500">
|
19
|
+
进入子页面
|
20
|
+
</NuxtLink>
|
21
|
+
</div>
|
22
|
+
</template>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<!--
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-11-29 17:16:31
|
4
|
+
* @LastEditTime: 2023-11-29 17:16:34
|
5
|
+
* @Description:
|
6
|
+
-->
|
7
|
+
<script lang="ts" setup>
|
8
|
+
definePageMeta({
|
9
|
+
title: '个人中心',
|
10
|
+
layout: 'tabbar',
|
11
|
+
})
|
12
|
+
</script>
|
13
|
+
|
14
|
+
<template>
|
15
|
+
<div>
|
16
|
+
我是个人中心
|
17
|
+
</div>
|
18
|
+
</template>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<!--
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-08-15 10:04:05
|
4
|
+
* @LastEditTime: 2023-11-29 17:30:00
|
5
|
+
* @Description:
|
6
|
+
-->
|
7
|
+
<script lang="ts" setup>
|
8
|
+
definePageMeta({
|
9
|
+
title: '子页面',
|
10
|
+
})
|
11
|
+
</script>
|
12
|
+
|
13
|
+
<template>
|
14
|
+
<div>
|
15
|
+
我是子页面📃
|
16
|
+
<div class="w-[62.5%] mx-auto mb-80px reset-img" lt-md="w-full">
|
17
|
+
params:
|
18
|
+
- id: {{ $route.params.id }}
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</template>
|
Binary file
|
@@ -0,0 +1,94 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-12-30 17:19:42
|
4
|
+
* @LastEditTime: 2023-11-29 16:34:50
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import { resolve } from 'node:path'
|
8
|
+
import { loadConfig } from 'c12'
|
9
|
+
import { useYoungLogger } from '@bluesyoung/logger'
|
10
|
+
|
11
|
+
export default defineNitroPlugin(async (nitroApp) => {
|
12
|
+
const IS_PROD = process.env.NODE_ENV !== 'development'
|
13
|
+
console.log('🚀 ~ file: init.ts:13 ~ IS_PROD:', IS_PROD)
|
14
|
+
|
15
|
+
const env = (process.env.DEPLOY_ENV as 'dev' | 'test' | 'online') || 'dev'
|
16
|
+
const { config } = await loadConfig<Record<string, any>>({
|
17
|
+
name: env,
|
18
|
+
cwd: resolve(process.cwd(), 'config'),
|
19
|
+
defaultConfig: {
|
20
|
+
// 优先读取环境变量中的版本信息(自己打的 Tag)
|
21
|
+
NUXT_PUBLIC_CURRENT_VERSION: process.env.PROJECT_VERSION || 'v0.0.1',
|
22
|
+
// 日志等级
|
23
|
+
CONSOLA_LEVEL: 3,
|
24
|
+
// 此处可以放置通用的环境变量
|
25
|
+
VITE_WECHAT_APPID: 'todo: 微信公众号appid',
|
26
|
+
VITE_VCONSOLE: false,
|
27
|
+
},
|
28
|
+
})
|
29
|
+
|
30
|
+
for (const key in config) {
|
31
|
+
if (process.env[key]) {
|
32
|
+
console.log('系统环境变量优先: ', key, ' = ', process.env[key], ' -> ', config[key], ' -> ', '覆盖')
|
33
|
+
config[key] = process.env[key]
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
process.env[key] = config[key]
|
37
|
+
}
|
38
|
+
if (!((key.indexOf('NUXT_PUBLIC_') === 0) || (key.indexOf('VITE_') === 0)))
|
39
|
+
delete config[key]
|
40
|
+
}
|
41
|
+
|
42
|
+
if (IS_PROD) {
|
43
|
+
// 格式化日志
|
44
|
+
useYoungLogger()
|
45
|
+
}
|
46
|
+
|
47
|
+
console.log('------------------------读取配置文件------------------------')
|
48
|
+
console.log(config)
|
49
|
+
console.log('-------------------------------------------------------------')
|
50
|
+
|
51
|
+
nitroApp.hooks.hook('request', (event) => {
|
52
|
+
const ua = event.node.req.headers['user-agent']
|
53
|
+
|
54
|
+
console.log('ua', ua, 'x-forwarded-for', event.node.req.headers['x-forwarded-for'], 'x-real-ip', event.node.req.headers['x-real-ip'])
|
55
|
+
})
|
56
|
+
|
57
|
+
nitroApp.hooks.hook('render:html', async (html, { event }) => {
|
58
|
+
// 设定视口高度,防止软键盘影响布局
|
59
|
+
html.bodyPrepend.push(`
|
60
|
+
<script>
|
61
|
+
const metaElement = document.querySelector('#viewportMeta');
|
62
|
+
metaElement.setAttribute('content', \`maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0,height=\${window.innerHeight}\`);
|
63
|
+
</script>
|
64
|
+
`)
|
65
|
+
|
66
|
+
// 注入环境变量
|
67
|
+
html.bodyPrepend.push(`
|
68
|
+
<!-- 注入环境变量 -->
|
69
|
+
<script>window.__YOUNG_ENV__=${JSON.stringify(config)}</script>
|
70
|
+
<!-- 更新检测,每分钟一次 -->
|
71
|
+
<script>
|
72
|
+
const YOUNG_UPDATE_TIMER = setInterval(() => {
|
73
|
+
fetch('${getFullAssetsUrl('/get/env')}')
|
74
|
+
.then((res) => res.json())
|
75
|
+
.then(({ NUXT_PUBLIC_CURRENT_VERSION }) => {
|
76
|
+
if (NUXT_PUBLIC_CURRENT_VERSION !== window.__YOUNG_ENV__.NUXT_PUBLIC_CURRENT_VERSION) {
|
77
|
+
clearInterval(YOUNG_UPDATE_TIMER);
|
78
|
+
alert('版本已更新,点击重新加载页面!');
|
79
|
+
window.location.reload();
|
80
|
+
}
|
81
|
+
});
|
82
|
+
}, 6e4);
|
83
|
+
</script>
|
84
|
+
`)
|
85
|
+
|
86
|
+
// vconsole 调试
|
87
|
+
if ((config as ImportMetaEnv).VITE_VCONSOLE) {
|
88
|
+
html.bodyAppend.push(`
|
89
|
+
<script src="https://g2021-cdn.laiyouxi.com/image/21Store/admin-img/vconsole.min.js"></script>
|
90
|
+
<script>new VConsole()</script>
|
91
|
+
`)
|
92
|
+
}
|
93
|
+
})
|
94
|
+
})
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-07-20 19:48:12
|
4
|
+
* @LastEditTime: 2023-07-21 11:18:40
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
export default defineEventHandler(async (event) => {
|
8
|
+
const envObj = {
|
9
|
+
NUXT_PUBLIC_CURRENT_VERSION: process.env.PROJECT_VERSION || 'v0.0.1',
|
10
|
+
}
|
11
|
+
|
12
|
+
return envObj
|
13
|
+
})
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-05-29 10:29:52
|
4
|
+
* @LastEditTime: 2023-11-03 15:45:17
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
export function getFullAssetsUrl(url: string) {
|
8
|
+
if (process.env.NODE_ENV === 'development' || !process.env.NUXT_APP_CDN_URL)
|
9
|
+
return url
|
10
|
+
|
11
|
+
return process.env.NUXT_APP_CDN_URL + url
|
12
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-09-27 11:22:08
|
4
|
+
* @LastEditTime: 2023-11-01 19:10:45
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import type { ServerOptions as HTTPProxyOptions } from 'http-proxy'
|
8
|
+
import ProxyModule from 'http-proxy'
|
9
|
+
import type { H3Event } from 'h3'
|
10
|
+
|
11
|
+
/**
|
12
|
+
* @param target 接口代理的具体地址
|
13
|
+
* @param defaults 代理配置
|
14
|
+
* @example
|
15
|
+
* export default defineEventHandler(async (event) => {
|
16
|
+
* const proxy = createTransparentProxy(`http://127.0.0.1:3333`);
|
17
|
+
* await proxy.handle(event);
|
18
|
+
* });
|
19
|
+
*/
|
20
|
+
export function createTransparentProxy(target: string, defaults: HTTPProxyOptions = {}) {
|
21
|
+
const proxy = ProxyModule.createProxy()
|
22
|
+
const handle = (event: H3Event, opts: HTTPProxyOptions = {}) => {
|
23
|
+
return new Promise<void>((resolve, reject) => {
|
24
|
+
proxy.web(event.node.req, event.node.res, { target, ...defaults, ...opts }, (error: any) => {
|
25
|
+
if (error.code !== 'ECONNRESET')
|
26
|
+
reject(error)
|
27
|
+
|
28
|
+
resolve()
|
29
|
+
})
|
30
|
+
})
|
31
|
+
}
|
32
|
+
return {
|
33
|
+
proxy,
|
34
|
+
handle,
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* 服务端发送的请求
|
40
|
+
*/
|
41
|
+
export function useServerFetch(event: H3Event, prefix = '/index') {
|
42
|
+
const BaseServerURL = `${process.env.VITE_BACKEND_SERVER}${prefix}` as const
|
43
|
+
|
44
|
+
return $fetch.create({
|
45
|
+
baseURL: BaseServerURL,
|
46
|
+
headers: {
|
47
|
+
'platform-source': event.context.platformSource,
|
48
|
+
'x-real-ip': event.context['x-real-ip']!,
|
49
|
+
'x-forwarded-for': event.context['x-forwarded-for']!,
|
50
|
+
},
|
51
|
+
async onRequest({ request, options }) {
|
52
|
+
const { onRequest, onResponse, onRequestError, onResponseError, ...opts } = options
|
53
|
+
console.log('🚀 ~ onRequest ~ request: %o, options: %o', request, opts)
|
54
|
+
},
|
55
|
+
async onResponse({ response }) {
|
56
|
+
console.log('🚀 ~ onResponse ~ data:', response._data)
|
57
|
+
},
|
58
|
+
})
|
59
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-11-29 17:28:36
|
4
|
+
* @LastEditTime: 2023-11-29 17:39:37
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
interface UserLoginRes {
|
8
|
+
uuid: string
|
9
|
+
nickname: string
|
10
|
+
headimgurl: string
|
11
|
+
token: string
|
12
|
+
}
|
13
|
+
|
14
|
+
interface LoginForm {
|
15
|
+
tel: string
|
16
|
+
passwd: string
|
17
|
+
}
|
18
|
+
|
19
|
+
interface ResetPasswdForm extends LoginForm {
|
20
|
+
code: string
|
21
|
+
passwd_again
|
22
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-06-15 08:59:22
|
4
|
+
* @LastEditTime: 2023-05-27 19:36:43
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import {
|
8
|
+
defineConfig,
|
9
|
+
presetAttributify,
|
10
|
+
presetIcons,
|
11
|
+
presetTypography,
|
12
|
+
presetUno,
|
13
|
+
presetWebFonts,
|
14
|
+
transformerDirectives,
|
15
|
+
transformerVariantGroup,
|
16
|
+
} from 'unocss'
|
17
|
+
|
18
|
+
export default defineConfig({
|
19
|
+
shortcuts: [],
|
20
|
+
presets: [
|
21
|
+
presetUno(),
|
22
|
+
presetAttributify(),
|
23
|
+
presetIcons({
|
24
|
+
scale: 1.2,
|
25
|
+
}),
|
26
|
+
presetTypography(),
|
27
|
+
presetWebFonts({
|
28
|
+
fonts: {
|
29
|
+
sans: 'DM Sans',
|
30
|
+
serif: 'DM Serif Display',
|
31
|
+
mono: 'DM Mono',
|
32
|
+
},
|
33
|
+
}),
|
34
|
+
],
|
35
|
+
transformers: [
|
36
|
+
// 不加 enforce 会有 bug
|
37
|
+
transformerDirectives({ enforce: 'pre' }),
|
38
|
+
transformerVariantGroup(),
|
39
|
+
],
|
40
|
+
})
|
@@ -0,0 +1,153 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-05-28 16:01:24
|
4
|
+
* @LastEditTime: 2023-11-29 17:35:36
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import { randomId } from '@bluesyoung/utils'
|
8
|
+
import { reactive } from 'vue'
|
9
|
+
import { useMediaQuery } from '@vueuse/core'
|
10
|
+
|
11
|
+
/**
|
12
|
+
* 生成数组的随机索引
|
13
|
+
*/
|
14
|
+
export function getRandomIndex(length: number) {
|
15
|
+
return Math.floor(Math.random() * length)
|
16
|
+
}
|
17
|
+
|
18
|
+
/**
|
19
|
+
* 设备唯一标识
|
20
|
+
*/
|
21
|
+
export function getUUID() {
|
22
|
+
return useLocalStorage('uuid', randomId() + randomId() + randomId() + randomId()).value
|
23
|
+
}
|
24
|
+
|
25
|
+
/**
|
26
|
+
* 微信分享
|
27
|
+
*/
|
28
|
+
export async function useWeChatShare(shareData: {
|
29
|
+
title: string
|
30
|
+
desc: string
|
31
|
+
imgUrl: string
|
32
|
+
/**
|
33
|
+
* 分享链接
|
34
|
+
* @default location.href.split('#')[0]
|
35
|
+
*/
|
36
|
+
link?: string
|
37
|
+
}) {
|
38
|
+
if (process.server)
|
39
|
+
return
|
40
|
+
|
41
|
+
/**
|
42
|
+
* 分享链接
|
43
|
+
*/
|
44
|
+
const link = shareData.link || location.href.split('#')[0]
|
45
|
+
|
46
|
+
const { jssdkShareSign } = storeToRefs(useShareStore())
|
47
|
+
|
48
|
+
if (!jssdkShareSign.value.timestamp) {
|
49
|
+
// todo: 微信签名
|
50
|
+
// const signConf = await fetch('/api/wechat/sign', {
|
51
|
+
// method: 'POST',
|
52
|
+
// body: JSON.stringify({
|
53
|
+
// wxAppId: window.__YOUNG_ENV__.VITE_WECHAT_APPID,
|
54
|
+
// url: link,
|
55
|
+
// })
|
56
|
+
// })
|
57
|
+
|
58
|
+
// jssdkShareSign.value = {
|
59
|
+
// timestamp: `${signConf.timestamp}`, // 必填,生成签名的时间戳
|
60
|
+
// nonceStr: signConf.noncestr, // 必填,生成签名的随机串
|
61
|
+
// signature: signConf.signature, // 必填,签名
|
62
|
+
// }
|
63
|
+
}
|
64
|
+
|
65
|
+
// @ts-expect-error
|
66
|
+
wx.config({
|
67
|
+
debug: window.__YOUNG_ENV__.VITE_VCONSOLE, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
|
68
|
+
appId: window.__YOUNG_ENV__.VITE_WECHAT_APPID, // 必填,公众号的唯一标识
|
69
|
+
...jssdkShareSign.value,
|
70
|
+
jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData'], // 必填,需要使用的JS接口列表
|
71
|
+
openTagList: [], // 可选,需要使用的开放标签列表,例如
|
72
|
+
})
|
73
|
+
|
74
|
+
// @ts-expect-error
|
75
|
+
wx.ready(() => {
|
76
|
+
// 需在用户可能点击分享按钮前就先调用
|
77
|
+
// @ts-expect-error
|
78
|
+
wx.updateAppMessageShareData({ link, ...shareData })
|
79
|
+
// @ts-expect-error
|
80
|
+
wx.updateTimelineShareData({ link, ...shareData })
|
81
|
+
})
|
82
|
+
}
|
83
|
+
|
84
|
+
/**
|
85
|
+
* html 转 text
|
86
|
+
*/
|
87
|
+
export function html2text(html: string) {
|
88
|
+
if (!html)
|
89
|
+
return ''
|
90
|
+
|
91
|
+
return html.toString().replace(/<[^>]+>/g, '')
|
92
|
+
}
|
93
|
+
|
94
|
+
/**
|
95
|
+
* 响应式的屏幕大小
|
96
|
+
*/
|
97
|
+
export const WindowSize = reactive({
|
98
|
+
'lt-sm': useMediaQuery('(max-width: 639.9px)'),
|
99
|
+
'sm': useMediaQuery('(min-width: 640px)'),
|
100
|
+
'lt-md': useMediaQuery('(max-width: 767.9px)'),
|
101
|
+
'md': process.server ? true : useMediaQuery('(min-width: 768px)'),
|
102
|
+
'lt-lg': useMediaQuery('(max-width: 1023.9px)'),
|
103
|
+
'lg': useMediaQuery('(min-width: 1024px)'),
|
104
|
+
'lt-xl': useMediaQuery('(max-width: 1279.9px)'),
|
105
|
+
'xl': useMediaQuery('(min-width: 1280px)'),
|
106
|
+
'lt-2xl': useMediaQuery('(max-width: 1535.9px)'),
|
107
|
+
'2xl': useMediaQuery('(min-width: 1536px)'),
|
108
|
+
})
|
109
|
+
|
110
|
+
/**
|
111
|
+
* 当前浏览器是否支持下载
|
112
|
+
*/
|
113
|
+
export function isSupportDownload() {
|
114
|
+
const NotAllowed = [/Alipay/gim, /BYTEDANCE/gim, /DINGTALK/gim, /MICROMESSENGER/gim]
|
115
|
+
|
116
|
+
return !NotAllowed.some(reg => reg.test(navigator.userAgent))
|
117
|
+
}
|
118
|
+
|
119
|
+
/**
|
120
|
+
* 页面滚动是否超过一定距离
|
121
|
+
*/
|
122
|
+
export function useScrollOver(distance = 40) {
|
123
|
+
const { y } = useScroll(!process.server ? window : null)
|
124
|
+
const scrolled = computed(() => y.value > distance)
|
125
|
+
|
126
|
+
return {
|
127
|
+
scrolled,
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* 登录校验
|
133
|
+
*/
|
134
|
+
export function checkLogin(force = true) {
|
135
|
+
const { hasLogin } = storeToRefs(useUserStore())
|
136
|
+
|
137
|
+
if (!hasLogin.value) {
|
138
|
+
if (force) {
|
139
|
+
showNotify({
|
140
|
+
message: '未登录或登录过期,请登录后再试',
|
141
|
+
type: 'danger',
|
142
|
+
})
|
143
|
+
|
144
|
+
navigateTo(`/login?redirect=${encodeURIComponent(location.href.replace(location.origin, ''))}`, {
|
145
|
+
replace: true,
|
146
|
+
})
|
147
|
+
}
|
148
|
+
return false
|
149
|
+
}
|
150
|
+
else {
|
151
|
+
return true
|
152
|
+
}
|
153
|
+
}
|