Merge pull request 'dev/1.0' (#1) from dev/1.0 into main

Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
2026-01-24 09:24:05 +00:00
16 changed files with 464 additions and 239 deletions

View File

@@ -38,6 +38,10 @@ const localDevConfig = ({
uniacid: 1, uniacid: 1,
domain: 'https://test.aigc-quickapp.com', domain: 'https://test.aigc-quickapp.com',
}, },
'local-2': { // 测试平台
uniacid: 2,
domain: 'http://localhost:8050/',
},
})['2811']; // 选择要使用的环境配置 })['2811']; // 选择要使用的环境配置
export default localDevConfig; export default localDevConfig;

View File

@@ -18,6 +18,10 @@ const localDevConfig = ({
uniacid: 2811, uniacid: 2811,
domain: 'https://xcx6.aigc-quickapp.com/', domain: 'https://xcx6.aigc-quickapp.com/',
}, },
'2812': { // IVD数商模式
uniacid: 2812,
domain: 'https://xcx6.aigc-quickapp.com/',
},
'2724': { // 生物菌肥 '2724': { // 生物菌肥
uniacid: 2724, uniacid: 2724,
domain: 'https://xcx.aigc-quickapp.com/', domain: 'https://xcx.aigc-quickapp.com/',
@@ -42,6 +46,10 @@ const localDevConfig = ({
uniacid: 2, uniacid: 2,
domain: 'http://localhost:8050/', domain: 'http://localhost:8050/',
}, },
})['2811']; // 选择要使用的环境配置 'local-2-dev': { // 本地开发测试平台
uniacid: 2,
domain: 'http://localhost:8050/',
},
})['2812']; // 选择要使用的环境配置
export default localDevConfig; export default localDevConfig;

View File

@@ -6,13 +6,23 @@
/** /**
* 显示错误信息 * 显示错误信息
* @param {Exception} err * @param {Exception} err
* @param {Boolean} useModal
*/ */
const showError = (err) => { const showError = (err, useModal = false) => {
const content = err?.message || err?.errMsg || err?.toString();
if (!useModal) {
uni.showToast({ uni.showToast({
title: err?.message || err?.errMsg || err?.toString(), title: content,
icon: 'none', icon: 'none',
duration: 2000 duration: 3000
}); });
} else {
uni.showModal({
title: '错误提示',
content,
showCancel: false,
})
}
} }
/** /**
@@ -33,43 +43,92 @@ export const makePhoneCall = (mobile) => {
} }
/** /**
* 拷贝文本 * 拷贝文本(返回 Promise
* @param {*} text * @param {*} text
* @param {*} options * @param {*} options
* @returns {Promise} 返回 Promise成功时 resolve失败时 reject
*/ */
export const copyText = (text, { copySuccess = '', copyFailed = '' } = {}) => { export const copyTextAsync = (text, { copySuccess = '', copyFailed = '' } = {}) => {
return new Promise((resolve, reject) => {
// 输入验证
if (!text && text !== '') {
const error = new Error('复制文本不能为空');
showError(error);
reject(error);
return;
}
// 超时监测
const timeoutId = setTimeout(() => {
let error = new Error('复制操作长时间无响应,请检查相关权限及配置是否正确');
// #ifdef MP-WEIXIN
error = new Error([
'复制操作长时间无响应!',
'原因:',
'1.微信平台->用户隐私保护指引->"剪贴板"功能未添加或审核未通过;',
'2.微信平台对剪贴板API调用频率有限制'
].join('\r\n'));
// #endif
showError(error, true);
reject(error);
}, 5000);
try { try {
console.log('copyText');
uni.setClipboardData({ uni.setClipboardData({
data: `${text}`, data: `${text}`,
success: () => { success: (res) => {
console.error('复制成功'); clearTimeout(timeoutId);
try { try {
if (copySuccess) {
uni.showToast({ uni.showToast({
title: copySuccess, title: copySuccess,
icon: 'success', icon: 'success',
duration: 2000 duration: 2000
}); });
}
} catch (e) { } catch (e) {
showError(e); showError(e);
} }
resolve(res);
}, },
fail: (err) => { fail: (err) => {
console.error('复制失败:', err); clearTimeout(timeoutId);
try { try {
uni.showToast({ uni.showToast({
title: err.message || err.errMsg || copyFailed, title: err.message || err.errMsg || copyFailed || '复制失败',
icon: 'none', icon: 'none',
duration: 2000 duration: 2000
}); });
} catch (e) { } catch (e) {
showError(e); showError(e);
} }
reject(err);
} }
}); });
} catch (err) { } catch (err) {
clearTimeout(timeoutId);
showError(err); showError(err);
reject(err);
} }
});
}
/**
* 拷贝文本(回调形式,兼容旧代码)
* @param {*} text
* @param {*} options
* @param {Function} callback 回调函数,接收 (success, error) 参数
*/
export const copyText = (text, options = {}, callback) => {
copyTextAsync(text, options)
.then(res => {
if (callback) callback(true, null);
})
.catch(err => {
if (callback) callback(false, err);
});
} }
/** /**

View File

@@ -843,6 +843,15 @@ export default {
uni.navigateBack(); uni.navigateBack();
} }
}, },
/**
* 隐藏“返回首页/小房子”按钮
* 这个函数用到页面show, onshow 的生命周期时
*/
hideHomeButton() {
// #ifdef MP-WEIXIN
wx.hideHomeButton();
// #endif
},
/** /**
* *
* @param val 转化时间字符串 (转化时分秒) * @param val 转化时间字符串 (转化时分秒)

View File

@@ -3,11 +3,18 @@
<view class="fui-list-group merchgroup" style="margin-top:0" v-for="(item, index) in value.list"> <view class="fui-list-group merchgroup" style="margin-top:0" v-for="(item, index) in value.list">
<map id="map" style="width: 100%; height:600rpx" scale="12" :markers="markerst" bindupdated="bindupdated" <map id="map" style="width: 100%; height:600rpx" scale="12" :markers="markerst" bindupdated="bindupdated"
:longitude="item.lng" :latitude="item.lat" show-location> :longitude="item.lng" :latitude="item.lat" show-location>
<cover-view <!-- <cover-view
style="position:absolute;right:10px;bottom:30rpx;z-index:99999;background:#4390FF;padding:5px 10px;wxcs_style_padding:10rpx 20rpx;border-radius:8rpx;color: #fff;" style="position:absolute;right:10px;bottom:30rpx;z-index:99999;background:#4390FF;padding:5px 10px;wxcs_style_padding:10rpx 20rpx;border-radius:8rpx;color: #fff;"
@click="handlerClick(item)" @tap="handlerClick(item)"> @click="handlerClick(item)" @tap="handlerClick(item)">
<cover-view style="font-size:24rpx">一键导航</cover-view> <cover-view style="font-size:24rpx">一键导航</cover-view>
</cover-view> </cover-view> -->
<!-- 使用非原生cover-view, 解决原生cover-view组件渲染机制z-index失效的问题 -->
<div
style="position:absolute;right:12rpx;bottom:48rpx;z-index:1;background:#4390FF;padding:0rpx 20rpx;border-radius:8rpx;color: #fff;"
@click="handlerClick(item)">
<span style="font-size:24rpx;color: #fff;">一键导航</span>
</div>
</map> </map>
</view> </view>

View File

@@ -104,7 +104,7 @@
}, },
"router" : { "router" : {
"mode" : "history", "mode" : "history",
"base" : "/hwappx/common/" "base" : "/hwappx/2811/"
}, },
"title" : "", "title" : "",
"devServer" : { "devServer" : {

View File

@@ -1,6 +1,9 @@
{ {
"scripts": { "scripts": {
"mp-weixin": "node scripts/mp-weixin.patch.js" "mp-weixin": "node scripts/mp-weixin.patch.js",
"mp-weixin:patch": "node scripts/mp-weixin.patch.js --no-zip",
"mp-weixin:dev": "node scripts/mp-weixin.patch.js --mode development",
"mp-weixin:dev:patch": "node scripts/mp-weixin.patch.js --mode development --no-zip"
}, },
"devDependencies": { "devDependencies": {
"dart-sass": "^1.25.0", "dart-sass": "^1.25.0",

View File

@@ -30,13 +30,13 @@ export default {
}; };
}, },
onLoad() { onLoad() {
this.$util.hideHomeButton();
//刷新多语言 //刷新多语言
this.$langConfig.refresh(); this.$langConfig.refresh();
uni.hideTabBar();
this.getDiyInfo(); this.getDiyInfo();
}, },
onShow() { onShow() {
this.$util.hideHomeButton();
if (this.$refs.category) this.$refs.category[0].pageShow(); if (this.$refs.category) this.$refs.category[0].pageShow();
}, },
onUnload() { onUnload() {

View File

@@ -1,22 +1,41 @@
<template> <template>
<view style="padding: 20rpx;" :style="themeColor"> <view class="view-container" :style="themeColor">
<rich-text :nodes="content"></rich-text> <!-- 加载状态 -->
<view v-if="loading" class="loading-state">
<view class="loading-spinner"></view>
</view>
<!-- 空状态 -->
<view v-else-if="!content" class="empty-state">
<view class="empty-icon">📄</view>
<text class="empty-title">暂无内容</text>
<text class="empty-desc">该协议内容暂未设置</text>
<button class="empty-button" @click="getcontent">重新加载</button>
</view>
<!-- 内容状态 -->
<rich-text v-else :nodes="content"></rich-text>
<to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top>
</view> </view>
</template> </template>
<script> <script>
import htmlParser from '@/common/js/html-parser'; import htmlParser from '@/common/js/html-parser';
import scroll from '@/common/js/scroll-view.js';
export default { export default {
data() { data() {
return { return {
content:'', content: '',
type:'', type: '',
uniacid:0 uniacid: 0,
loading: true
}; };
}, },
mixins: [scroll],
onLoad(option) { onLoad(option) {
this.type = option.type this.type = option.type
this.uniacid = option.uniacid?option.uniacid:0 this.uniacid = option.uniacid ? option.uniacid : 0
this.isIphoneX = this.$util.uniappIsIPhoneX() this.isIphoneX = this.$util.uniappIsIPhoneX()
this.getcontent() this.getcontent()
@@ -26,20 +45,25 @@ export default {
}, },
methods: { methods: {
getcontent() { getcontent() {
this.loading = true
// privacy content // privacy content
var data = { var data = {
type:this.type type: this.type
} }
if(this.uniacid > 0) data.uniacid = this.uniacid if (this.uniacid > 0) data.uniacid = this.uniacid
this.$api.sendRequest({ this.$api.sendRequest({
url: '/api/config/agreement', url: '/api/config/agreement',
data:data, data: data,
success: res => { success: res => {
console.log(res.data.title) console.log(res.data.title)
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title:res.data.title title: res.data.title
}) })
this.content = res.data.content this.content = res.data.content
this.loading = false
},
fail: () => {
this.loading = false
} }
}); });
} }
@@ -47,6 +71,117 @@ export default {
}; };
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
.view-container {
padding: 40rpx;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06), 0 1rpx 2rpx rgba(0, 0, 0, 0.09);
margin: 4rpx 20rpx;
// max-width: 800rpx;
margin-left: auto;
margin-right: auto;
min-height: 100vh;
position: relative;
overflow: hidden;
}
// 增强纸张纹理效果
.view-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="25" cy="25" r="0.5" fill="%23f5f5f5" opacity="0.3"/><circle cx="75" cy="75" r="0.3" fill="%23f0f0f0" opacity="0.2"/><circle cx="15" cy="85" r="0.4" fill="%23f8f8f8" opacity="0.25"/><circle cx="85" cy="15" r="0.2" fill="%23ebebeb" opacity="0.3"/><path d="M0 0L200 200M200 0L0 200" stroke="%23f2f2f2" stroke-width="0.3" fill="none" opacity="0.15"/></pattern></defs><rect width="200" height="200" fill="url(%23grain)"/></svg>');
opacity: 0.4;
pointer-events: none;
}
// 加载状态样式
.loading-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 60vh;
padding: 40rpx;
.loading-spinner {
width: 50rpx;
height: 50rpx;
border: 4rpx solid #f3f3f3;
border-top: 4rpx solid #6c8ebf;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 24rpx;
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
// 空状态样式
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 60vh;
padding: 40rpx;
text-align: center;
.empty-icon {
font-size: 120rpx;
margin-bottom: 32rpx;
opacity: 0.6;
}
.empty-title {
font-size: 32rpx;
font-weight: 600;
color: #4e5969;
margin-bottom: 16rpx;
}
.empty-desc {
font-size: 24rpx;
color: #8492a6;
margin-bottom: 40rpx;
line-height: 1.6;
}
.empty-button {
width: 200rpx;
height: 70rpx;
line-height: 70rpx;
background-color: #6c8ebf;
color: white;
border: none;
border-radius: 35rpx;
font-size: 26rpx;
font-weight: 500;
box-shadow: 0 2rpx 8rpx rgba(108, 142, 191, 0.3);
transition: all 0.3s ease;
&:hover {
background-color: #5a78a8;
transform: translateY(-2rpx);
box-shadow: 0 4rpx 12rpx rgba(108, 142, 191, 0.4);
}
}
}
::v-deep .mescroll-totop {
right: 27rpx !important;
bottom: 120rpx !important;
}
</style> </style>

View File

@@ -10,8 +10,7 @@
</view> </view>
<!-- 消息列表 --> <!-- 消息列表 -->
<view v-for="(message, index) in messages" :key="`msg-${message.id || message.timestamp}-${index}`" <view v-for="item in messagesWithKey" :key="item.__renderKey" class="message-item" :class="[item.role, { 'first-message': item.__index === 0 }]">
class="message-item" :class="[message.role, { 'first-message': index === 0 }]">
<!-- 用户消息 --> <!-- 用户消息 -->
<view v-if="message.role === 'user'" class="user-message"> <view v-if="message.role === 'user'" class="user-message">
@@ -392,6 +391,19 @@ export default {
isFetchingHistory: false isFetchingHistory: false
} }
}, },
computed: {
// 为每条消息生成兼容小程序的唯一 key
messagesWithKey() {
return this.messages.map((msg, idx) => {
const uniqueId = msg.id || msg.timestamp || idx;
return {
...msg,
__renderKey: `msg_${uniqueId}_${idx}`,
__index: idx // 保留原始索引,用于判断 first-message 等
};
});
}
},
onShow() { onShow() {
// 优先读取本地缓存的会话 ID // 优先读取本地缓存的会话 ID
const localConvId = this.getConversationIdFromLocal(); const localConvId = this.getConversationIdFromLocal();

View File

@@ -252,6 +252,7 @@ export default {
}; };
}, },
onLoad(option) { onLoad(option) {
this.$util.hideHomeButton();
this.$langConfig.refresh(); this.$langConfig.refresh();
this.$api.sendRequest({ this.$api.sendRequest({
url: '/api/member/personnel', url: '/api/member/personnel',
@@ -301,6 +302,9 @@ export default {
fail: res => { } fail: res => { }
}); });
}, },
onShow() {
this.$util.hideHomeButton();
},
methods: { methods: {
// 分享文件 // 分享文件
shareFile(file) { shareFile(file) {

View File

@@ -86,6 +86,12 @@ export default {
nsNewGift nsNewGift
}, },
mixins: [diyJs, indexJs], mixins: [diyJs, indexJs],
onLoad() {
this.$util.hideHomeButton();
},
onShow() {
this.$util.hideHomeButton();
},
methods: { methods: {
tourl(url) { tourl(url) {

View File

@@ -1,12 +1,13 @@
{ {
"description": "项目配置文件", "description": "项目配置文件",
"packOptions": { "packOptions": {
"ignore": [] "ignore": [],
"include": []
}, },
"setting": { "setting": {
"urlCheck": true, "urlCheck": true,
"es6": true, "es6": true,
"enhance": false, "enhance": true,
"postcss": true, "postcss": true,
"preloadBackgroundData": false, "preloadBackgroundData": false,
"minified": true, "minified": true,
@@ -37,7 +38,15 @@
"userConfirmedBundleSwitch": false, "userConfirmedBundleSwitch": false,
"packNpmManually": false, "packNpmManually": false,
"packNpmRelationList": [], "packNpmRelationList": [],
"minifyWXSS": true "minifyWXSS": true,
"condition": true,
"swc": false,
"disableSWC": true,
"minifyWXML": true,
"compileWorklet": true,
"localPlugins": false,
"disableUseStrict": false,
"useCompilerPlugins": false
}, },
"compileType": "miniprogram", "compileType": "miniprogram",
"libVersion": "2.16.1", "libVersion": "2.16.1",

View File

@@ -1,6 +1,6 @@
{ {
"libVersion": "3.12.0", "libVersion": "3.12.0",
"projectname": "lucky_shop", "projectname": "mp-weixin",
"condition": {}, "condition": {},
"setting": { "setting": {
"urlCheck": true, "urlCheck": true,

219
readme.md
View File

@@ -1,7 +1,5 @@
# 小程序及快应用前端源码 # 小程序及快应用前端源码
来源于外包提供的源代码,"0731xcx20微信小程序(1).zip"
## 项目说明 ## 项目说明
@@ -9,7 +7,7 @@
## 开发说明 ## 开发说明
1. 源码基于Vue2版本scss采用node-sass进行编译输出。 源码基于Vue2版本scss采用dart-sass进行编译输出。
## 开发调试说明 ## 开发调试说明
@@ -18,7 +16,7 @@
应用访问等关键参数的配置来源于 `./common/js/config.js` 应用访问等关键参数的配置来源于 `./common/js/config.js`
### 小程序调试
@@ -26,151 +24,90 @@
### 小程序发布 ### 小程序发布
基本操作步骤:
1. 使用HBuilderX打开项目
2. 选择菜单栏 "发行" -> "小程序-微信",进行发布构建
3. 然后在终端进入项目根目录,执行 `npm run mp-weixin` 手动输出构建包。例如mp-weixin-2025-10-31-1761881054836.zip改id
4. 然后将mp-weixin-2025-10-31-1761881054836发给微信开发定制客户技术人员
5. 定制客户技术人员可以修改解压后修改项目根目录下的site.js进行针对客户的信息配置然后使用微信开发者工具打开发布后的代码进行上传发布
参照:`common\js\config.js` 文件内容说明:
```js
// 发行版本,配置说明
let releaseCfg = undefined;
try {
if (site) {
releaseCfg = {
baseUrl: site.baseUrl,
imgDomain: site.baseUrl,
h5Domain: site.baseUrl,
uniacid: site.uniacid,
}
}
} catch (e) {}
// 调试版本,配置说明
const devCfg = {
// 商户ID
uniacid: 460, //825
//api请求地址
baseUrl: 'https://xcx30.5g-quickapp.com/',
// 图片域名
imgDomain: 'https://xcx30.5g-quickapp.com/',
// H5端域名
h5Domain: 'https://xcx30.5g-quickapp.com/',
// // api请求地址
// baseUrl: 'https://tsaas.liveplatform.cn/',
// // 图片域名
// imgDomain: 'https://tsaas.liveplatform.cn/',
// // H5端域名
// h5Domain: 'https://tsaas.liveplatform.cn/',
// api请求地址
// baseUrl: 'http://saas.cn/',
// // 图片域名
// imgDomain: 'http://saas.cn/',
// // H5端域名
// h5Domain: 'http://saas.cn/',
};
var config = {
/**
* 1.开发调试模式
* 去掉注释 ...devCfg;
* 注释掉 ...releaseCfg,
* 2.发行/发布模式,例如通过`HBuilder>发行>小程序微信`的时候,原理
* 然后将 `import site from "../site.js";`追加到 `unpackage\dist\build\mp-weixin\common\vendor.js` 文件内容开头部分
* 然后将 site.js 文件放到 `unpackage\dist\build\mp-weixin\` 目录下面
*/
...(releaseCfg ?? devCfg),
// 腾讯地图key #### 基本操作步骤:(通用版/定制化版)
mpKey: 'TUHBZ-CNWKU-UHAVP-GZQ26-HNZFO-3YBF4',
#### 【前置准备】
1. 在项目根目录打开终端安装依赖“npm install”已有依赖可跳过此步骤
#### 【发布构建】
2. 使用HBuilderX打开项目
3. 选择菜单栏「发行」 → 「小程序-微信」→ 「发行」,等待构建完成。(⚠️注:底部控制台弹出"请在微信小程序开发者工具中点击上传"后再执行下一步);
4. 打开资源管理器→项目根目录,右键选择「在终端中打开」,执行"npm run mp-weixin"命令并回车;
5. 找到项目根目录 /unpackage/dist/build 下生成的 mp-weixin 压缩包
💡例如mp-weixin-2026-01-23-1769152056146.zip;同时该目录下会生成未压缩的 mp-weixin 目录。
#### 【验证与重命名】
6. 打开该目录下同时生成未压缩的 mp-weixin 目录找到site.js文件将文件内的uniacid值改为当前客户编号2812并保存
7. 打开微信开发者工具导入「mp-weixin」目录点击「编译」在开发者工具控制台验证有无报错以及能否返回对应客户的业务数据
8. 确保无误后将生成的mp-weixin的压缩包重命名格式为定制化-客户编号-域名-mp-weixin-当前日期-生成编号.zip。
***(📌通用版无需重命名)***
💡例如custom-2812-xcx.aigc-quickapp.com-mp-weixin-2026-01-22-1769152056146.zip
🚫压缩包命名禁止包含 / \ : * ? " < > | 等特殊字符。
#### 【交付与最终发布】🔍🔍
9. 将重命名后的文件发送给技术人员; ***(📌通用版直接将生成的 mp-weixin 压缩包直接发送给技术人员)***
10. 技术人员操作:解压压缩包 → 确认site.js中的uniacid为客户编号 → 用微信开发者工具导入解压后的代码目录 → 编译验证无误后 → 上传发布。
//客服地址
webSocket: '{{$webSocket}}',
//本地端主动给服务器ping的时间, 0 则不开启 , 单位秒
pingInterval: 1500,
// 版本号
version: '1.0'
};
export default config;
```
### 快应用发布 ### 快应用发布
1. 使用HBuilderX打开项目
2. 点击项目中【⚙】manifest.jion--->web配置--->运行的基础路径--->/hwappx/改编号/
"h5" : {
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : "TUHBZ-CNWKU-UHAVP-GZQ26-HNZFO-3YBF4"
}
}
},
"router" : {
"mode" : "history",
"base" : "/hwappx/2811/"
},
(编号可以在.local.config.js中找到需要的编号
const localDevConfig = ({ #### 基本操作(通用版/定制化版)
'460': { // 制氧设备平台
uniacid: 460,
domain: 'https://xcx30.5g-quickapp.com/',
}, #### 【发布构建】
'576-xcx30.5g': { // 活性石灰装备 1. 使用HBuilderX打开项目
uniacid: 576,
domain: 'https://xcx30.5g-quickapp.com/', 2. 打开项目根目录的manifest.json文件切换至可视化配置界面依次点击「Web 配置」→「运行的基础配置」,修改路径中的客户编号;***(📌通用版保留原有/hwappx/common/***
},
'2285': { // 数码喷墨墨水 💡例如:/hwappx/2811/其中2811为定制化版客户编号
uniacid: 2285,
domain: 'https://xcx.aigc-quickapp.com/', 3. 选择菜单栏「发行」 → 「自定义发行」 →「H5-xcx.aigc-quickapp.com」,先修改以下配置:
}, 网站标题:快应用
'2811': { // POCT检测分析平台 网站域名当前客户域名示例xcx.aigc-quickapp.com
uniacid: 2811, 确认后点击「发行」等待构建完成。
domain: 'https://xcx6.aigc-quickapp.com/',
}, ⚠️注:底部控制台弹出“项目 lucky_shop 导出Web成功路径为D:\项目文件\项目根目录\unpackage\dist\build\web”后再执行下一步
'2724': { // 生物菌肥
uniacid: 2724, 💡例如:项目 lucky_shop 导出Web成功路径为D:\0.项目源码\lucky_shop\unpackage\dist\build\web
domain: 'https://xcx.aigc-quickapp.com/',
}, 4. 按控制台提示的路径找到web目录将该目录下所有文件手动打包成一个.zip压缩包仅打包文件不包含外层web目录
'2505': { // 煤矿钻机
uniacid: 2505, #### 【重命名】
domain: 'https://xcx.aigc-quickapp.com/', 5. 按版本类型规范重命名压缩包:
},
'2777': { // 养老服务 📌通用版hwappx-common-域名-时间.zip
uniacid: 2777, 例如: hwappx-common-xcx.aigc-quickapp.com-2026-01-24.zip
domain: 'https://xcx.aigc-quickapp.com/',
}, 📌定制化:客户名称-定制化---hwappx-客户编号-域名-时间.zip
'1': { // 开发平台 例如POCT检测分析平台-定制化---hwappx-2811-xcx.aigc-quickapp.com-2026-01-24.zip
uniacid: 1,
domain: 'https://dev.aigc-quickapp.com', 🚫压缩包命名禁止包含 / \ : * ? " < > | 等特殊字符
},
'1-test': { // 测试平台 #### 【交付与最终发布】🔍🔍
uniacid: 1, 6. 将重命名后的压缩包发送给运维人员;
domain: 'https://test.aigc-quickapp.com',
}, 7. 运维人员操作:
})['2811']; // 选择要使用的环境配置
3. 选择菜单栏 "发行" ->自定义发行--->H5-xcx.aigc-quickapp.com "快应用",网站标题为"快应用" 域名为xcx.aigc-quickapp.com 进行发布构建 ① 解压压缩包;
4. 在电脑本地文件夹里找到unpackage--->dist--->build--->h5中h5-xcx.aigc-quickapp.com--->进行手动打包例如static.zip
压缩包改id 公版--例如 hwappx-common-xcx.aigc-quickapp.com-2026-01-09.zip ② 打开快应用开发者工具,导入解压后的代码目录;
定制化--例如 POCT检测分析平台-定制化--- hwappx-2811-xcx.aigc-quickapp.com-2026-01-09.zip
5. 然后将压缩包发给开发定制客户技术人员, ③ 验证代码无报错后,执行上传发布操作。
6. 使用快应用开发者工具打开发布后的代码进行上传发布

View File

@@ -9,7 +9,10 @@
* 如果这个文件开头已经有了这行代码,则不追加 * 如果这个文件开头已经有了这行代码,则不追加
* *
* 使用: * 使用:
* node fix-wechat-miniapp.js * node fix-wechat-miniapp.js # 打补丁并创建 ZIP 文件(默认 mode=production
* node fix-wechat-miniapp.js --no-zip # 只打补丁,不创建 ZIP 文件
* node fix-wechat-miniapp.js --mode development # 使用 development 模式打补丁
* node fix-wechat-miniapp.js --mode production # 使用 production 模式打补丁(默认)
* *
* 注意: * 注意:
* - 在 Windows 上路径使用反斜杠也是可以的;脚本使用 path.join 来兼容不同平台。 * - 在 Windows 上路径使用反斜杠也是可以的;脚本使用 path.join 来兼容不同平台。
@@ -29,8 +32,6 @@ async function commonPatch(mode = 'production') {
// 根据当前脚本所在目录scripts定位到项目根目录 // 根据当前脚本所在目录scripts定位到项目根目录
const cwd = path.join(__dirname, '..'); const cwd = path.join(__dirname, '..');
const srcSitePath = path.join(cwd, 'site.js'); const srcSitePath = path.join(cwd, 'site.js');
const destDir = path.join(cwd, 'unpackage', 'dist', mode === 'production' ? 'build' : 'dev', 'mp-weixin'); const destDir = path.join(cwd, 'unpackage', 'dist', mode === 'production' ? 'build' : 'dev', 'mp-weixin');
const destSitePath = path.join(destDir, 'site.js'); const destSitePath = path.join(destDir, 'site.js');
@@ -47,6 +48,22 @@ async function commonPatch(mode = 'production') {
// 确保目标目录存在 // 确保目标目录存在
await ensureDir(destDir); await ensureDir(destDir);
// 复制 project.config.json 及 project.private.config.json 文件到 destDir 下面
const configFiles = ['project.config.json', 'project.private.config.json'];
for (const fileName of configFiles) {
const srcPath = path.join(cwd, fileName);
const destPath = path.join(destDir, fileName);
// 检查源文件是否存在
const fileExists = await exists(srcPath);
if (fileExists) {
await fsp.copyFile(srcPath, destPath);
console.log(`已拷贝: ${srcPath} -> ${destPath}`);
} else {
console.warn(`源文件不存在,跳过复制: ${srcPath}`);
}
}
// 复制 site.js 到目标目录(覆盖) // 复制 site.js 到目标目录(覆盖)
await fsp.copyFile(srcSitePath, destSitePath); await fsp.copyFile(srcSitePath, destSitePath);
console.log(`已拷贝: ${srcSitePath} -> ${destSitePath}`); console.log(`已拷贝: ${srcSitePath} -> ${destSitePath}`);
@@ -96,14 +113,26 @@ async function commonPatch(mode = 'production') {
} }
} }
async function main() { async function main() {
// 解析命令行参数
const argv = process.argv.slice(2);
const options = {
noZip: argv.includes('--no-zip'),
mode: 'production' // 默认值
};
// 解析 --mode 参数
const modeIndex = argv.indexOf('--mode');
if (modeIndex !== -1 && modeIndex + 1 < argv.length) {
options.mode = argv[modeIndex + 1];
}
// 1) 打补丁 // 1) 打补丁
await commonPatch('production'); await commonPatch(options.mode);
// await commonPatch('development'); // await commonPatch('development');
// 2) 创建 ZIP 文件 // 2) 创建 ZIP 文件(如果未指定 --no-zip
if (!options.noZip) {
const cwd = path.join(__dirname, '..'); const cwd = path.join(__dirname, '..');
const sourceDir = path.join(cwd, 'unpackage', 'dist', 'build', 'mp-weixin'); const sourceDir = path.join(cwd, 'unpackage', 'dist', 'build', 'mp-weixin');
const destDir = path.join(cwd, 'unpackage', 'dist', 'build'); const destDir = path.join(cwd, 'unpackage', 'dist', 'build');
@@ -112,6 +141,9 @@ async function main() {
// 3) 自动打开zip所在的目录 // 3) 自动打开zip所在的目录
await openFileDirectory(zipFilePath); await openFileDirectory(zipFilePath);
} else {
console.log('跳过创建 ZIP 文件和打开目录');
}
} }
async function exists(p) { async function exists(p) {