xsh_1997 2 тижнів тому
батько
коміт
7c2b1e43bb

+ 2 - 2
huimv-employment/app/.env.production

@@ -1,2 +1,2 @@
1
-# 生产环境 API 地址(部署前请修改为实际域名
2
-VUE_APP_BASE_API=https://your-api-domain.com/api/v1/mp
1
+# 生产环境 API(与开发环境一致;有正式 HTTPS 域名后再改
2
+VUE_APP_BASE_API=https://img.ifarmcloud.com/deploymentApi/api/v1/mp

+ 14 - 0
huimv-employment/app/App.vue

@@ -8,4 +8,18 @@ export default {
8 8
 
9 9
 <style lang="scss">
10 10
 @import './common/fe.scss';
11
+
12
+/* 关闭 uni-app 导航栏阴影 CDN 预加载(shadow-grey.png timeout) */
13
+/* #ifdef H5 */
14
+body::after {
15
+	content: none !important;
16
+}
17
+/* #endif */
18
+/* #ifdef MP-WEIXIN */
19
+page::after {
20
+	content: none !important;
21
+	animation: none !important;
22
+	background-image: none !important;
23
+}
24
+/* #endif */
11 25
 </style>

+ 3 - 6
huimv-employment/app/common/config.js

@@ -1,5 +1,5 @@
1
-/** 开发环境远程 API(微信小程序 / App 等直连) */
2
-const DEV_REMOTE_API = 'http://115.238.57.190:5200/api/v1/mp'
1
+/** 小程序直连 API(体验版/开发版统一;有正式 HTTPS 域名后再改 env) */
2
+const MP_API = 'https://img.ifarmcloud.com/deploymentApi/api/v1/mp'
3 3
 
4 4
 /** H5 开发走 devServer 代理,避免浏览器跨域 */
5 5
 const H5_DEV_PROXY_API = '/api/v1/mp'
@@ -9,10 +9,7 @@ function resolveBaseApi() {
9 9
 	if (process.env.UNI_PLATFORM === 'h5' && process.env.NODE_ENV !== 'production') {
10 10
 		return H5_DEV_PROXY_API
11 11
 	}
12
-	return (
13
-		process.env.VUE_APP_BASE_API ||
14
-		(process.env.NODE_ENV !== 'production' ? DEV_REMOTE_API : '')
15
-	)
12
+	return process.env.VUE_APP_BASE_API || MP_API
16 13
 }
17 14
 
18 15
 /** API 基础路径 */

+ 4 - 2
huimv-employment/app/packageA/components/chat/FeReportFloat.vue

@@ -39,7 +39,8 @@ export default {
39 39
 		initPosition() {
40 40
 			const sys = uni.getSystemInfoSync()
41 41
 			const headerH = uni.upx2px(112)
42
-			const footerH = uni.upx2px(128 + 112) + (sys.safeAreaInsets?.bottom || 0)
42
+			const insetBottom = (sys.safeAreaInsets && sys.safeAreaInsets.bottom) || 0
43
+			const footerH = uni.upx2px(128 + 112) + insetBottom
43 44
 			const floatH = uni.upx2px(88)
44 45
 			const min = headerH + uni.upx2px(24)
45 46
 			const max = sys.windowHeight - footerH - floatH - uni.upx2px(24)
@@ -49,7 +50,8 @@ export default {
49 50
 		getBounds() {
50 51
 			const sys = uni.getSystemInfoSync()
51 52
 			const headerH = uni.upx2px(112)
52
-			const footerH = uni.upx2px(128 + 112) + (sys.safeAreaInsets?.bottom || 0)
53
+			const insetBottom = (sys.safeAreaInsets && sys.safeAreaInsets.bottom) || 0
54
+			const footerH = uni.upx2px(128 + 112) + insetBottom
53 55
 			const floatH = uni.upx2px(88)
54 56
 			return {
55 57
 				min: headerH + uni.upx2px(16),

+ 35 - 17
huimv-employment/app/packageA/home/index.vue

@@ -3,20 +3,29 @@
3 3
 		<view class="index-page">
4 4
 			<view v-if="booting" class="index-boot">
5 5
 				<view class="index-boot__spinner" />
6
-				<text class="index-boot__text">加载中...</text>
6
+				<text class="index-boot__text">{{ bootText }}</text>
7 7
 			</view>
8 8
 
9 9
 			<view v-else-if="needRegister" class="index-blank" />
10 10
 
11 11
 			<view v-else-if="ready" class="index-home">
12
+				<view v-if="!homeMounted" class="index-boot">
13
+					<view class="index-boot__spinner" />
14
+					<text class="index-boot__text">正在加载工作台...</text>
15
+				</view>
12 16
 				<EnterpriseHome
13
-					v-if="viewRole === 'enterprise'"
17
+					v-else-if="viewRole === 'enterprise'"
14 18
 					ref="enterpriseHome"
15 19
 					:active="true"
16 20
 				/>
17 21
 				<WorkerHome v-else :active="true" />
18 22
 			</view>
19 23
 
24
+			<view v-else class="index-boot">
25
+				<view class="index-boot__spinner" />
26
+				<text class="index-boot__text">页面跳转中...</text>
27
+			</view>
28
+
20 29
 			<view
21 30
 				class="fe-modal-overlay"
22 31
 				:class="{ 'fe-modal-overlay--active': registerModalVisible }"
@@ -32,15 +41,6 @@
32 41
 				</view>
33 42
 			</view>
34 43
 		</view>
35
-
36
-		<hz-novice-guidance
37
-			v-if="ready && viewRole === 'enterprise'"
38
-			ref="noviceGuidance"
39
-			:base-config="homeGuideBaseConfig"
40
-			:steps="homeGuideSteps"
41
-			@finished="onHomeGuideEnded"
42
-			@skiped="onHomeGuideEnded"
43
-		/>
44 44
 	</view>
45 45
 </template>
46 46
 
@@ -49,15 +49,15 @@ import EnterpriseHome from '@/packageA/components/home/EnterpriseHome.vue'
49 49
 import WorkerHome from '@/packageA/components/home/WorkerHome.vue'
50 50
 import store from '@/common/store.js'
51 51
 import { getToken } from '@/utils/request.js'
52
-import enterpriseHomeGuide from '@/mixins/enterprise-home-guide.js'
53 52
 
54 53
 export default {
55 54
 	components: { EnterpriseHome, WorkerHome },
56
-	mixins: [enterpriseHomeGuide],
57 55
 	data() {
58 56
 		return {
59 57
 			booting: true,
58
+			bootText: '加载中...',
60 59
 			ready: false,
60
+			homeMounted: false,
61 61
 			needRegister: false,
62 62
 			registerModalVisible: false,
63 63
 			viewRole: 'enterprise'
@@ -89,7 +89,17 @@ export default {
89 89
 	},
90 90
 	methods: {
91 91
 		goLogin() {
92
-			uni.reLaunch({ url: '/packageA/auth/login' })
92
+			this.booting = true
93
+			this.bootText = '正在前往登录...'
94
+			this.ready = false
95
+			this.needRegister = false
96
+			uni.reLaunch({
97
+				url: '/packageA/auth/login',
98
+				fail: () => {
99
+					this.bootText = '跳转登录失败,请重试'
100
+					uni.showToast({ title: '跳转登录失败', icon: 'none' })
101
+				}
102
+			})
93 103
 		},
94 104
 		goRegister() {
95 105
 			this.registerModalVisible = false
@@ -103,7 +113,9 @@ export default {
103 113
 		},
104 114
 		async bootstrap() {
105 115
 			this.booting = true
116
+			this.bootText = '加载中...'
106 117
 			this.ready = false
118
+			this.homeMounted = false
107 119
 			this.needRegister = false
108 120
 			this.registerModalVisible = false
109 121
 
@@ -123,16 +135,22 @@ export default {
123 135
 				if (!info || !info.registered) {
124 136
 					this.needRegister = true
125 137
 					this.registerModalVisible = true
138
+					this.booting = false
126 139
 					return
127 140
 				}
128 141
 
129 142
 				this.ready = true
130
-				this.scheduleHomeGuide()
143
+				this.booting = false
144
+				// 先稳定首页壳子,再挂载超大工作台组件(体验版冷启动更稳)
145
+				this.$nextTick(() => {
146
+					setTimeout(() => {
147
+						if (this.ready) this.homeMounted = true
148
+					}, 50)
149
+				})
131 150
 			} catch (e) {
151
+				console.error('home bootstrap fail', e)
132 152
 				store.logout()
133 153
 				this.goLogin()
134
-			} finally {
135
-				this.booting = false
136 154
 			}
137 155
 		}
138 156
 	}

+ 16 - 6
huimv-employment/app/pages/index/index.vue

@@ -1,7 +1,7 @@
1 1
 <template>
2 2
 	<view class="index-boot">
3 3
 		<view class="index-boot__spinner" />
4
-		<text class="index-boot__text">加载中...</text>
4
+		<text class="index-boot__text">{{ bootText }}</text>
5 5
 	</view>
6 6
 </template>
7 7
 
@@ -12,13 +12,23 @@ import { getToken } from '@/utils/request.js'
12 12
  * 主包入口:仅做启动跳转,首页 UI 在分包 packageA/home,避免主包超 2M。
13 13
  */
14 14
 export default {
15
+	data() {
16
+		return {
17
+			bootText: '加载中...'
18
+		}
19
+	},
15 20
 	onLoad() {
16 21
 		const token = getToken()
17
-		if (!token) {
18
-			uni.reLaunch({ url: '/packageA/auth/login' })
19
-			return
20
-		}
21
-		uni.reLaunch({ url: '/packageA/home/index' })
22
+		const url = token ? '/packageA/home/index' : '/packageA/auth/login'
23
+		this.bootText = token ? '正在进入首页...' : '正在前往登录...'
24
+		uni.reLaunch({
25
+			url,
26
+			fail: (err) => {
27
+				console.error('entry reLaunch fail', err)
28
+				this.bootText = '打开失败,请删除小程序后重试'
29
+				uni.showToast({ title: '页面打开失败', icon: 'none' })
30
+			}
31
+		})
22 32
 	},
23 33
 	onShareAppMessage() {
24 34
 		return {

+ 54 - 1
huimv-employment/app/vue.config.js

@@ -2,7 +2,11 @@
2 2
  * H5 开发服务器配置
3 3
  * - proxy:解决浏览器跨域
4 4
  * - host 0.0.0.0 + public:局域网同事访问时 sockjs 不连 localhost
5
+ *
6
+ * 小程序:编译后去掉 uni-app 注入的 shadow-grey.png CDN 预加载(常 timeout)
5 7
  */
8
+const fs = require('fs')
9
+const path = require('path')
6 10
 const os = require('os')
7 11
 
8 12
 function getLanIp() {
@@ -20,6 +24,52 @@ function getLanIp() {
20 24
 const DEV_PORT = 8080
21 25
 const LAN_IP = getLanIp()
22 26
 
27
+/** 匹配 uni-app 注入的 dcloud CDN 阴影图 background */
28
+const DCLOUD_SHADOW_CSS_RE = /\s*background(-image)?:\s*url\(\S*?\/\/[\w.-]*?dcloud\.net\.cn\S*?\)\s*;?/gi
29
+
30
+function stripDcloudShadowCss(dir) {
31
+	if (!dir || !fs.existsSync(dir)) return
32
+	const stack = [dir]
33
+	while (stack.length) {
34
+		const cur = stack.pop()
35
+		let entries
36
+		try {
37
+			entries = fs.readdirSync(cur)
38
+		} catch (e) {
39
+			continue
40
+		}
41
+		entries.forEach((name) => {
42
+			const full = path.join(cur, name)
43
+			let stat
44
+			try {
45
+				stat = fs.statSync(full)
46
+			} catch (e) {
47
+				return
48
+			}
49
+			if (stat.isDirectory()) {
50
+				stack.push(full)
51
+				return
52
+			}
53
+			if (!/\.(wxss|css|scss)$/i.test(name)) return
54
+			try {
55
+				const raw = fs.readFileSync(full, 'utf8')
56
+				if (!DCLOUD_SHADOW_CSS_RE.test(raw)) return
57
+				DCLOUD_SHADOW_CSS_RE.lastIndex = 0
58
+				fs.writeFileSync(full, raw.replace(DCLOUD_SHADOW_CSS_RE, ''), 'utf8')
59
+			} catch (e) {}
60
+		})
61
+	}
62
+}
63
+
64
+class RemoveUniCdnShadowPlugin {
65
+	apply(compiler) {
66
+		compiler.hooks.done.tap('RemoveUniCdnShadowPlugin', () => {
67
+			const outDir = process.env.UNI_OUTPUT_DIR
68
+			if (outDir) stripDcloudShadowCss(outDir)
69
+		})
70
+	}
71
+}
72
+
23 73
 module.exports = {
24 74
 	devServer: {
25 75
 		host: '0.0.0.0',
@@ -29,10 +79,13 @@ module.exports = {
29 79
 		public: `${LAN_IP}:${DEV_PORT}`,
30 80
 		proxy: {
31 81
 			'/api': {
32
-				target: 'http://115.238.57.190:5200',
82
+				target: 'https://img.ifarmcloud.com/deploymentApi',
33 83
 				changeOrigin: true,
34 84
 				secure: false
35 85
 			}
36 86
 		}
87
+	},
88
+	configureWebpack: {
89
+		plugins: [new RemoveUniCdnShadowPlugin()]
37 90
 	}
38 91
 }