@roki-h5/create-roki-app 0.1.0 → 0.1.2
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/index.js +16 -1
- package/package.json +1 -1
- package/templates/h5/config/env/.env.development +7 -0
- package/templates/h5/config/env/.env.development.local +2 -0
- package/templates/h5/config/env/.env.production +9 -0
- package/templates/h5/config/env/.env.test +9 -0
- package/templates/h5/config/env.ts +10 -0
- package/templates/h5/index.html +1 -1
- package/templates/h5/node_modules/.bin/autoprefixer +17 -0
- package/templates/h5/node_modules/.bin/browserslist +17 -0
- package/templates/h5/node_modules/.bin/tsc +17 -0
- package/templates/h5/node_modules/.bin/tsserver +17 -0
- package/templates/h5/node_modules/.bin/vite +17 -0
- package/templates/h5/node_modules/.bin/vue-tsc +17 -0
- package/templates/h5/node_modules/.vite/deps/_metadata.json +43 -0
- package/templates/h5/node_modules/.vite/deps/axios.js +3370 -0
- package/templates/h5/node_modules/.vite/deps/axios.js.map +7 -0
- package/templates/h5/node_modules/.vite/deps/chunk-CVVHEZGK.js +162 -0
- package/templates/h5/node_modules/.vite/deps/chunk-CVVHEZGK.js.map +7 -0
- package/templates/h5/node_modules/.vite/deps/chunk-HFUUWO4F.js +13072 -0
- package/templates/h5/node_modules/.vite/deps/chunk-HFUUWO4F.js.map +7 -0
- package/templates/h5/node_modules/.vite/deps/chunk-PZ5AY32C.js +9 -0
- package/templates/h5/node_modules/.vite/deps/chunk-PZ5AY32C.js.map +7 -0
- package/templates/h5/node_modules/.vite/deps/package.json +3 -0
- package/templates/h5/node_modules/.vite/deps/pinia.js +1561 -0
- package/templates/h5/node_modules/.vite/deps/pinia.js.map +7 -0
- package/templates/h5/node_modules/.vite/deps/vue-router.js +2241 -0
- package/templates/h5/node_modules/.vite/deps/vue-router.js.map +7 -0
- package/templates/h5/node_modules/.vite/deps/vue.js +347 -0
- package/templates/h5/node_modules/.vite/deps/vue.js.map +7 -0
- package/templates/h5/node_modules/.vue-global-types/vue_3.5_0_0_0.d.ts +118 -0
- package/templates/h5/package.json +9 -6
- package/templates/h5/scripts/version.js +38 -0
- package/templates/h5/src/App.vue +29 -0
- package/templates/h5/src/api/index.ts +4 -0
- package/templates/h5/src/api/nativeApi.ts +72 -0
- package/templates/h5/src/api/request.ts +2 -1
- package/templates/h5/src/api/welcome.ts +24 -0
- package/templates/h5/src/assets/images/home/img-device.png +0 -0
- package/templates/h5/src/assets/images/home/logo-free.png +0 -0
- package/templates/h5/src/assets/images/logo.png +0 -0
- package/templates/h5/src/components/WelcomeInfo.vue +90 -0
- package/templates/h5/src/router/index.ts +1 -1
- package/templates/h5/src/stores/index.ts +96 -1
- package/templates/h5/src/utils/appInfo.ts +86 -0
- package/templates/h5/src/utils/browser.ts +26 -0
- package/templates/h5/src/utils/buildInfo.ts +3 -0
- package/templates/h5/src/utils/greeting.ts +38 -0
- package/templates/h5/src/views/home/index.vue +12 -11
- package/templates/h5/src/vite-env.d.ts +26 -0
- package/templates/h5/tsconfig.json +3 -2
- package/templates/h5/vite.config.ts +56 -11
- package/templates/h5/.env.development +0 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { storeToRefs } from 'pinia'
|
|
4
|
+
import logoSrc from '@/assets/images/home/logo-free.png'
|
|
5
|
+
import deviceImg from '@/assets/images/home/img-device.png'
|
|
6
|
+
import { useAppStore } from '@/stores'
|
|
7
|
+
|
|
8
|
+
const { welcomeCopy } = storeToRefs(useAppStore())
|
|
9
|
+
|
|
10
|
+
const prefixText = computed(() => {
|
|
11
|
+
const prefix = welcomeCopy.value?.prefix
|
|
12
|
+
return prefix && String(prefix).trim() ? String(prefix).trim() : ''
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const speechText = computed(() => {
|
|
16
|
+
const speech = welcomeCopy.value?.speech
|
|
17
|
+
return speech && String(speech).trim() ? String(speech).trim() : ''
|
|
18
|
+
})
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<section class="welcome-info">
|
|
23
|
+
<div class="welcome-info__left">
|
|
24
|
+
<img class="welcome-info__logo" :src="logoSrc" alt="ROKI" />
|
|
25
|
+
<h3 v-if="prefixText" class="welcome-info__prefix">{{ prefixText }}</h3>
|
|
26
|
+
<p v-if="speechText" class="welcome-info__speech">{{ speechText }}</p>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div class="welcome-info__right">
|
|
30
|
+
<img class="welcome-info__device" :src="deviceImg" alt="" />
|
|
31
|
+
</div>
|
|
32
|
+
</section>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<style scoped>
|
|
36
|
+
.welcome-info {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: space-between;
|
|
40
|
+
column-gap: 16px;
|
|
41
|
+
margin-bottom: 24px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.welcome-info__left {
|
|
45
|
+
min-width: 0;
|
|
46
|
+
padding-top: 6px;
|
|
47
|
+
margin-left: 32px;
|
|
48
|
+
line-height: 1.5;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.welcome-info__logo {
|
|
52
|
+
display: block;
|
|
53
|
+
position: relative;
|
|
54
|
+
top: 0;
|
|
55
|
+
right: 4px;
|
|
56
|
+
width: 68px;
|
|
57
|
+
height: 68px;
|
|
58
|
+
border-radius: 14px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.welcome-info__prefix {
|
|
62
|
+
margin: 8px 0 4px;
|
|
63
|
+
background: linear-gradient(90deg, #005da7 0%, #f87b4d 50%);
|
|
64
|
+
-webkit-background-clip: text;
|
|
65
|
+
background-clip: text;
|
|
66
|
+
color: transparent;
|
|
67
|
+
font-size: 20px;
|
|
68
|
+
font-weight: 400;
|
|
69
|
+
line-height: 1.4;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.welcome-info__speech {
|
|
73
|
+
margin: 0;
|
|
74
|
+
color: rgba(0, 0, 0, 0.8);
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
line-height: 1.5;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.welcome-info__right {
|
|
80
|
+
position: relative;
|
|
81
|
+
flex-shrink: 0;
|
|
82
|
+
width: 200px;
|
|
83
|
+
height: 200px;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.welcome-info__device {
|
|
87
|
+
display: block;
|
|
88
|
+
width: 100%;
|
|
89
|
+
}
|
|
90
|
+
</style>
|
|
@@ -1,15 +1,110 @@
|
|
|
1
1
|
import { ref } from 'vue'
|
|
2
2
|
import { defineStore } from 'pinia'
|
|
3
|
+
import { getWelcomeMessage, type WelcomeMessageData } from '@/api/welcome'
|
|
4
|
+
|
|
5
|
+
function formatRequestDate(date = new Date()) {
|
|
6
|
+
const pad = (n: number) => String(n).padStart(2, '0')
|
|
7
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** 可通过 updateState 批量更新的字段 */
|
|
11
|
+
export interface AppStateUpdates {
|
|
12
|
+
terminal?: string
|
|
13
|
+
accessToken?: string
|
|
14
|
+
familyId?: string
|
|
15
|
+
deviceType?: string
|
|
16
|
+
deviceCategory?: string
|
|
17
|
+
deviceName?: string
|
|
18
|
+
deviceId?: string
|
|
19
|
+
deviceGuid?: string
|
|
20
|
+
userId?: string
|
|
21
|
+
}
|
|
3
22
|
|
|
4
23
|
export const useAppStore = defineStore('app', () => {
|
|
5
|
-
|
|
24
|
+
/** 应用展示名,可在启动时由接口或配置覆盖 */
|
|
25
|
+
const appName = ref('Roki H5')
|
|
26
|
+
const terminal = ref('android')
|
|
27
|
+
const deviceName = ref('燃气热水器·HT808-16')
|
|
28
|
+
const familyId = ref('')
|
|
29
|
+
const deviceId = ref('HT80888a68d0fb812')
|
|
30
|
+
const deviceGuid = ref('HT80888a68d0fb812')
|
|
31
|
+
const deviceType = ref('HT808')
|
|
32
|
+
const deviceCategory = ref('RRSQ')
|
|
33
|
+
const userId = ref('3243300064')
|
|
34
|
+
|
|
35
|
+
/** 开发联调用 token,生产环境由 App 注入覆盖 */
|
|
36
|
+
const accessToken = ref(
|
|
37
|
+
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDI5Mjg0ODAsInVzZXJJZCI6MzI0MzMwMDA2NCwianRpIjoiMDI3ZjhiMGMtYmU5MS00NzA2LWI3ZDUtOGI5OTJlMjA0MzQ2IiwiY2xpZW50X2lkIjoicm9raV9jbGllbnQifQ.aW0hKvcv-k_4PocYNVWiml7IB15jZIcn24eXZFZCSz4',
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
/** `/rest/ops/ai/welcome` 的 data:prefix / speech */
|
|
41
|
+
const welcomeCopy = ref<WelcomeMessageData>({})
|
|
42
|
+
|
|
43
|
+
function setAppName(name: string) {
|
|
44
|
+
appName.value = name
|
|
45
|
+
}
|
|
6
46
|
|
|
7
47
|
function setAccessToken(token: string) {
|
|
8
48
|
accessToken.value = token
|
|
9
49
|
}
|
|
10
50
|
|
|
51
|
+
function resetWelcomeCopy() {
|
|
52
|
+
welcomeCopy.value = {}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function loadWelcomeMessage(params: Record<string, unknown> = {}) {
|
|
56
|
+
try {
|
|
57
|
+
const res = await getWelcomeMessage({
|
|
58
|
+
date: formatRequestDate(),
|
|
59
|
+
...params,
|
|
60
|
+
})
|
|
61
|
+
welcomeCopy.value = res?.data ?? {}
|
|
62
|
+
} catch (e) {
|
|
63
|
+
welcomeCopy.value = {}
|
|
64
|
+
if (import.meta.env.DEV) {
|
|
65
|
+
console.warn('[App] loadWelcomeMessage failed', e)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function updateState(updates: AppStateUpdates) {
|
|
71
|
+
const stateRefs = {
|
|
72
|
+
terminal,
|
|
73
|
+
accessToken,
|
|
74
|
+
familyId,
|
|
75
|
+
deviceType,
|
|
76
|
+
deviceCategory,
|
|
77
|
+
deviceName,
|
|
78
|
+
deviceId,
|
|
79
|
+
deviceGuid,
|
|
80
|
+
userId,
|
|
81
|
+
} as const
|
|
82
|
+
|
|
83
|
+
Object.entries(updates).forEach(([key, value]) => {
|
|
84
|
+
if (key in stateRefs) {
|
|
85
|
+
stateRefs[key as keyof typeof stateRefs].value = value as never
|
|
86
|
+
} else if (import.meta.env.DEV) {
|
|
87
|
+
console.warn(`[App] updateState: unknown key "${key}"`)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
11
92
|
return {
|
|
93
|
+
appName,
|
|
94
|
+
terminal,
|
|
95
|
+
deviceName,
|
|
96
|
+
familyId,
|
|
97
|
+
deviceId,
|
|
98
|
+
deviceGuid,
|
|
99
|
+
deviceType,
|
|
100
|
+
deviceCategory,
|
|
101
|
+
userId,
|
|
12
102
|
accessToken,
|
|
103
|
+
welcomeCopy,
|
|
104
|
+
setAppName,
|
|
13
105
|
setAccessToken,
|
|
106
|
+
resetWelcomeCopy,
|
|
107
|
+
loadWelcomeMessage,
|
|
108
|
+
updateState,
|
|
14
109
|
}
|
|
15
110
|
})
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useAppStore } from '@/stores'
|
|
2
|
+
|
|
3
|
+
export interface AppDeviceInfo {
|
|
4
|
+
deviceId?: string
|
|
5
|
+
deviceName?: string
|
|
6
|
+
deviceType?: string
|
|
7
|
+
deviceCategory?: string
|
|
8
|
+
familyId?: string
|
|
9
|
+
userId?: string
|
|
10
|
+
terminal?: string
|
|
11
|
+
accessToken?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function patchAppStoreFromInfo(rawInfo: unknown) {
|
|
15
|
+
if (!rawInfo) return null
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const info =
|
|
19
|
+
typeof rawInfo === 'string'
|
|
20
|
+
? (JSON.parse(rawInfo) as AppDeviceInfo)
|
|
21
|
+
: (rawInfo as AppDeviceInfo)
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
deviceId,
|
|
25
|
+
deviceName,
|
|
26
|
+
deviceType,
|
|
27
|
+
deviceCategory,
|
|
28
|
+
familyId,
|
|
29
|
+
userId,
|
|
30
|
+
terminal,
|
|
31
|
+
accessToken,
|
|
32
|
+
} = info
|
|
33
|
+
|
|
34
|
+
const appStore = useAppStore()
|
|
35
|
+
const prevGuid = String(appStore.deviceGuid ?? '').trim()
|
|
36
|
+
const nextGuid = String(deviceId ?? '').trim()
|
|
37
|
+
|
|
38
|
+
appStore.updateState({
|
|
39
|
+
deviceId,
|
|
40
|
+
deviceName,
|
|
41
|
+
deviceGuid: deviceId,
|
|
42
|
+
deviceType,
|
|
43
|
+
deviceCategory,
|
|
44
|
+
familyId,
|
|
45
|
+
userId,
|
|
46
|
+
terminal,
|
|
47
|
+
accessToken,
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
if (nextGuid && nextGuid !== prevGuid) {
|
|
51
|
+
appStore.resetWelcomeCopy()
|
|
52
|
+
void appStore.loadWelcomeMessage()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return info
|
|
56
|
+
} catch (e) {
|
|
57
|
+
console.warn('[appInfo] 设备信息解析失败', e)
|
|
58
|
+
return null
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** 从混合 App 原生桥获取设备信息并写入 store */
|
|
63
|
+
export async function getAppData() {
|
|
64
|
+
let info: unknown = null
|
|
65
|
+
|
|
66
|
+
if (
|
|
67
|
+
window.nativeInterface &&
|
|
68
|
+
typeof window.nativeInterface.getDeviceInfo === 'function'
|
|
69
|
+
) {
|
|
70
|
+
info = await Promise.resolve(window.nativeInterface.getDeviceInfo())
|
|
71
|
+
if (import.meta.env.DEV) {
|
|
72
|
+
console.log('[appInfo] 安卓/鸿蒙数据获取成功', info)
|
|
73
|
+
}
|
|
74
|
+
} else if (window.getDeviceInfo) {
|
|
75
|
+
const raw = window.getDeviceInfo
|
|
76
|
+
info = await Promise.resolve(
|
|
77
|
+
typeof raw === 'function' ? raw() : raw,
|
|
78
|
+
)
|
|
79
|
+
if (import.meta.env.DEV) {
|
|
80
|
+
console.log('[appInfo] iOS 数据获取成功', info)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!info) return null
|
|
85
|
+
return patchAppStoreFromInfo(info)
|
|
86
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** 轻量 UA 判断,供 JsBridge / nativeApi 区分 iOS 与 Android */
|
|
2
|
+
function getUa() {
|
|
3
|
+
return typeof navigator !== 'undefined' && navigator.userAgent
|
|
4
|
+
? navigator.userAgent
|
|
5
|
+
: ''
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const ua = getUa()
|
|
9
|
+
|
|
10
|
+
const android = /Android/i.test(ua)
|
|
11
|
+
const iPhone = /iPhone/i.test(ua) && !/iPod/i.test(ua)
|
|
12
|
+
const iPod = /iPod/i.test(ua)
|
|
13
|
+
const iPad =
|
|
14
|
+
/iPad/i.test(ua) ||
|
|
15
|
+
(typeof navigator !== 'undefined' &&
|
|
16
|
+
navigator.platform === 'MacIntel' &&
|
|
17
|
+
Number(navigator.maxTouchPoints) > 1)
|
|
18
|
+
|
|
19
|
+
export const browser = {
|
|
20
|
+
versions: {
|
|
21
|
+
android,
|
|
22
|
+
iPhone,
|
|
23
|
+
iPad,
|
|
24
|
+
iPod,
|
|
25
|
+
},
|
|
26
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** 时段及问候语 与后端 getGreeting 枚举一致 前端兜底方案 避免接口请求失败时展示不正确 */
|
|
2
|
+
export const TIME_PERIOD_GREETINGS = [
|
|
3
|
+
'早上好',
|
|
4
|
+
'中午好',
|
|
5
|
+
'下午好',
|
|
6
|
+
'傍晚好',
|
|
7
|
+
'夜深了',
|
|
8
|
+
] as const
|
|
9
|
+
|
|
10
|
+
export function getGreetingByTime(dateTime = new Date()) {
|
|
11
|
+
const hours = dateTime.getHours()
|
|
12
|
+
const minutes = dateTime.getMinutes()
|
|
13
|
+
const totalMinutes = hours * 60 + minutes
|
|
14
|
+
|
|
15
|
+
if (totalMinutes >= 5 * 60 + 1 && totalMinutes <= 10 * 60) return '早上好'
|
|
16
|
+
if (totalMinutes >= 10 * 60 + 1 && totalMinutes <= 14 * 60) return '中午好'
|
|
17
|
+
if (totalMinutes >= 14 * 60 + 1 && totalMinutes <= 17 * 60) return '下午好'
|
|
18
|
+
if (totalMinutes >= 17 * 60 + 1 && totalMinutes <= 22 * 60) return '傍晚好'
|
|
19
|
+
return '夜深了'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function extractTimePeriodGreeting(text: string) {
|
|
23
|
+
const t = String(text ?? '').trim()
|
|
24
|
+
if (!t) return ''
|
|
25
|
+
if (t === '深夜了' || t.includes('深夜')) return '夜深了'
|
|
26
|
+
return TIME_PERIOD_GREETINGS.find((greeting) => t === greeting) ?? ''
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** 解析首页问候 prefix:无接口数据或时段不一致时以本地时间为准 */
|
|
30
|
+
export function resolveWelcomePrefix(apiPrefix?: string, dateTime = new Date()) {
|
|
31
|
+
const localGreeting = getGreetingByTime(dateTime)
|
|
32
|
+
const trimmed = String(apiPrefix ?? '').trim()
|
|
33
|
+
if (!trimmed) return localGreeting
|
|
34
|
+
|
|
35
|
+
const apiGreeting = extractTimePeriodGreeting(trimmed)
|
|
36
|
+
if (apiGreeting && apiGreeting !== localGreeting) return localGreeting
|
|
37
|
+
return trimmed
|
|
38
|
+
}
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import WelcomeInfo from '@/components/WelcomeInfo.vue'
|
|
3
|
+
import { nativeApi } from '@/api/nativeApi'
|
|
4
|
+
|
|
5
|
+
const appTitle = import.meta.env.VITE_APP_TITLE
|
|
6
|
+
|
|
2
7
|
function onBack() {
|
|
3
8
|
history.back()
|
|
4
9
|
}
|
|
5
10
|
|
|
6
11
|
function onMore() {
|
|
7
|
-
|
|
12
|
+
void nativeApi.skipDeviceMore('5.0')
|
|
8
13
|
}
|
|
9
14
|
</script>
|
|
10
15
|
|
|
11
16
|
<template>
|
|
12
17
|
<div class="page home-page">
|
|
13
|
-
<RokiNavBar title="
|
|
18
|
+
<RokiNavBar :title="appTitle" @click-left="onBack">
|
|
14
19
|
<template #right>
|
|
15
20
|
<span
|
|
16
21
|
role="button"
|
|
@@ -18,14 +23,17 @@ function onMore() {
|
|
|
18
23
|
class="home-page__more"
|
|
19
24
|
aria-label="更多"
|
|
20
25
|
@click.stop="onMore"
|
|
26
|
+
@keydown.enter.prevent="onMore"
|
|
27
|
+
@keydown.space.prevent="onMore"
|
|
21
28
|
>
|
|
22
29
|
⋯
|
|
23
30
|
</span>
|
|
24
31
|
</template>
|
|
25
32
|
</RokiNavBar>
|
|
26
33
|
|
|
34
|
+
<WelcomeInfo />
|
|
35
|
+
|
|
27
36
|
<main class="home-page__content">
|
|
28
|
-
<p class="home-page__tip">向下滚动,导航栏背景会从透明渐变为白色。</p>
|
|
29
37
|
<div class="home-page__spacer" />
|
|
30
38
|
</main>
|
|
31
39
|
</div>
|
|
@@ -33,14 +41,7 @@ function onMore() {
|
|
|
33
41
|
|
|
34
42
|
<style scoped>
|
|
35
43
|
.home-page__content {
|
|
36
|
-
padding:
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.home-page__tip {
|
|
40
|
-
margin: 0;
|
|
41
|
-
font-size: 14px;
|
|
42
|
-
color: rgba(0, 0, 0, 0.6);
|
|
43
|
-
line-height: 1.6;
|
|
44
|
+
padding: 0 18px 24px;
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
.home-page__more {
|
|
@@ -1,9 +1,35 @@
|
|
|
1
1
|
/// <reference types="vite/client" />
|
|
2
2
|
|
|
3
|
+
declare module '*.png' {
|
|
4
|
+
const src: string
|
|
5
|
+
export default src
|
|
6
|
+
}
|
|
7
|
+
|
|
3
8
|
interface ImportMetaEnv {
|
|
9
|
+
readonly VITE_ENV: string
|
|
10
|
+
readonly VITE_APP_TITLE: string
|
|
4
11
|
readonly VITE_BASE_API: string
|
|
12
|
+
readonly VITE_NORMALDEVICE_BASE_API: string
|
|
13
|
+
readonly VITE_PUBLIC_BASE?: string
|
|
5
14
|
}
|
|
6
15
|
|
|
7
16
|
interface ImportMeta {
|
|
8
17
|
readonly env: ImportMetaEnv
|
|
9
18
|
}
|
|
19
|
+
|
|
20
|
+
interface WebViewJavascriptBridge {
|
|
21
|
+
callHandler: (
|
|
22
|
+
handlerName: string,
|
|
23
|
+
params: Record<string, unknown>,
|
|
24
|
+
callback: (responseData: unknown) => void,
|
|
25
|
+
) => void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface Window {
|
|
29
|
+
WebViewJavascriptBridge?: WebViewJavascriptBridge
|
|
30
|
+
WVJBCallbacks?: Array<(bridge: WebViewJavascriptBridge) => void>
|
|
31
|
+
nativeInterface?: {
|
|
32
|
+
getDeviceInfo?: () => unknown
|
|
33
|
+
}
|
|
34
|
+
getDeviceInfo?: (() => unknown) | unknown
|
|
35
|
+
}
|
|
@@ -1,19 +1,64 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
1
2
|
import path from 'node:path'
|
|
2
3
|
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import { defineConfig } from 'vite'
|
|
4
|
+
import { defineConfig, loadEnv } from 'vite'
|
|
4
5
|
import vue from '@vitejs/plugin-vue'
|
|
5
6
|
|
|
6
7
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
8
|
+
const monorepoUiDir = path.resolve(__dirname, '../../../ui')
|
|
9
|
+
const isMonorepoDev = fs.existsSync(path.join(monorepoUiDir, 'package.json'))
|
|
7
10
|
|
|
8
|
-
export default defineConfig({
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
export default defineConfig(({ mode }) => {
|
|
12
|
+
const env = loadEnv(mode, path.resolve(__dirname, 'config/env'), '')
|
|
13
|
+
|
|
14
|
+
const rawPublicBase = (env.VITE_PUBLIC_BASE ?? '').trim()
|
|
15
|
+
const base =
|
|
16
|
+
mode === 'development'
|
|
17
|
+
? '/'
|
|
18
|
+
: rawPublicBase === './' || rawPublicBase === '.'
|
|
19
|
+
? './'
|
|
20
|
+
: rawPublicBase
|
|
21
|
+
? rawPublicBase.endsWith('/')
|
|
22
|
+
? rawPublicBase
|
|
23
|
+
: `${rawPublicBase}/`
|
|
24
|
+
: './'
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
plugins: [vue()],
|
|
28
|
+
envDir: path.resolve(__dirname, 'config/env'),
|
|
29
|
+
resolve: {
|
|
30
|
+
alias: [
|
|
31
|
+
{ find: '@', replacement: path.resolve(__dirname, 'src') },
|
|
32
|
+
{ find: '@config', replacement: path.resolve(__dirname, 'config') },
|
|
33
|
+
...(isMonorepoDev
|
|
34
|
+
? [
|
|
35
|
+
{
|
|
36
|
+
find: '@roki-h5/ui/style.css',
|
|
37
|
+
replacement: path.resolve(
|
|
38
|
+
monorepoUiDir,
|
|
39
|
+
'src/styles/base.css',
|
|
40
|
+
),
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
find: '@roki-h5/ui',
|
|
44
|
+
replacement: path.resolve(monorepoUiDir, 'src/index.ts'),
|
|
45
|
+
},
|
|
46
|
+
]
|
|
47
|
+
: []),
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
base,
|
|
51
|
+
server: {
|
|
52
|
+
host: true,
|
|
53
|
+
port: 5174,
|
|
54
|
+
cors: true,
|
|
55
|
+
proxy: {
|
|
56
|
+
'/api': {
|
|
57
|
+
target: 'https://api-test.myroki.com',
|
|
58
|
+
changeOrigin: true,
|
|
59
|
+
rewrite: (p) => p.replace(/^\/api/, ''),
|
|
60
|
+
},
|
|
61
|
+
},
|
|
13
62
|
},
|
|
14
|
-
}
|
|
15
|
-
server: {
|
|
16
|
-
host: true,
|
|
17
|
-
port: 5173,
|
|
18
|
-
},
|
|
63
|
+
}
|
|
19
64
|
})
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VITE_BASE_API=
|