19 Commits

Author SHA1 Message Date
2a0935b581 Merge pull request 'docs: 更新readme文档结构和内容' (#2) from dev/1.0 into main
Reviewed-on: #2
2026-01-24 09:41:36 +00:00
09e410df00 docs: 更新readme文档结构和内容
重构readme文档结构,使用更清晰的markdown格式和emoji图标
添加详细的开发调试说明和发布流程
补充构建脚本说明和版本历史记录
2026-01-24 17:40:40 +08:00
b31197a8b4 Merge pull request 'dev/1.0' (#1) from dev/1.0 into main
Reviewed-on: #1
2026-01-24 09:24:05 +00:00
Zhukj
75dfe80bde Merge remote-tracking branch 'remotes/origin/dev/1.0' into zhu-kaijiie/dev-1.0 2026-01-24 16:59:15 +08:00
Zhukj
2a1f33323c chore:修改readme.md小程序和快应用发布说明文档 2026-01-24 16:51:31 +08:00
Zhukj
b441c46993 chore:更新小程序发布说明文档 2026-01-24 11:19:53 +08:00
38ade75046 fix(diy-map): 替换cover-view为div解决z-index失效问题
移除ns-login组件中不必要的z-index设置
2026-01-24 09:20:01 +08:00
1e51abd7cd docs: 更新本地配置示例文件添加IVD数商模式配置
添加2812环境的IVD数商模式配置,并增加本地开发测试平台选项
2026-01-23 17:09:42 +08:00
0939449aa7 fix(ns-login): 修复complete-info-wrap弹窗层级问题 2026-01-23 17:09:05 +08:00
29b5cfda6f fix: 在页面加载时统一隐藏首页按钮
在多个页面的onLoad生命周期中添加this.$util.hideHomeButton()调用,确保页面加载时即隐藏首页按钮,避免显示不一致问题。同时调整category.vue中onShow的逻辑顺序。
2026-01-23 11:54:31 +08:00
ceca4e5956 fix: 在多个页面添加隐藏首页按钮功能
为统一处理首页按钮显示逻辑,在会员页、联系页和商品分类页的onShow生命周期中添加了hideHomeButton调用
2026-01-23 11:36:15 +08:00
aa9d2e64d2 feat(util): 添加隐藏微信小程序首页按钮功能
添加 hideHomeButton 方法用于在微信小程序环境中隐藏首页按钮,提升用户体验
2026-01-23 11:18:55 +08:00
e8ccb87266 feat(脚本): 增强微信小程序补丁脚本功能
- 添加新的 npm scripts 支持不同模式运行补丁脚本
- 支持命令行参数 --no-zip 和 --mode 控制 ZIP 文件生成和运行模式
- 自动复制项目配置文件到目标目录
- 更新使用说明文档
2026-01-23 10:12:30 +08:00
153c84266a chore: 更新项目配置文件和微信小程序名称
- 将项目名称从'lucky_shop'改为'mp-weixin'
- 在project.config.json中添加include数组和多个新配置项
- 启用enhance功能并添加编译相关设置
2026-01-23 09:25:58 +08:00
7ae7a1d3bd chore(uniapp): 增加拷贝文本超时检测提示功能 2026-01-17 15:30:02 +08:00
1ebb94e9e2 chore: 调整隐私协议及注册服务展示样式 2026-01-17 13:52:19 +08:00
9b53540f91 Merge branch 'dev/1.0' of http://git.aigc-quickapp.com/Uniapp/lucky_shop into dev/1.0 2026-01-16 18:11:00 +08:00
2223636184 Merge branch 'dev/1.0' of http://git.aigc-quickapp.com/Uniapp/lucky_shop into dev/1.0 2026-01-16 18:00:31 +08:00
6144dc72b8 chore:非 h5 平台 :key 不支持表达式的问题 2026-01-16 18:00:03 +08:00
16 changed files with 516 additions and 257 deletions

View File

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

View File

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

View File

@@ -6,13 +6,23 @@
/**
* 显示错误信息
* @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({
title: err?.message || err?.errMsg || err?.toString(),
title: content,
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 {*} 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 {
console.log('copyText');
uni.setClipboardData({
data: `${text}`,
success: () => {
console.error('复制成功');
success: (res) => {
clearTimeout(timeoutId);
try {
if (copySuccess) {
uni.showToast({
title: copySuccess,
icon: 'success',
duration: 2000
});
}
} catch (e) {
showError(e);
}
resolve(res);
},
fail: (err) => {
console.error('复制失败:', err);
clearTimeout(timeoutId);
try {
uni.showToast({
title: err.message || err.errMsg || copyFailed,
title: err.message || err.errMsg || copyFailed || '复制失败',
icon: 'none',
duration: 2000
});
} catch (e) {
showError(e);
}
reject(err);
}
});
} catch (err) {
clearTimeout(timeoutId);
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();
}
},
/**
* 隐藏“返回首页/小房子”按钮
* 这个函数用到页面show, onshow 的生命周期时
*/
hideHomeButton() {
// #ifdef MP-WEIXIN
wx.hideHomeButton();
// #endif
},
/**
*
* @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">
<map id="map" style="width: 100%; height:600rpx" scale="12" :markers="markerst" bindupdated="bindupdated"
: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;"
@click="handlerClick(item)" @tap="handlerClick(item)">
<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>
</view>

View File

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

View File

@@ -1,6 +1,9 @@
{
"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": {
"dart-sass": "^1.25.0",

View File

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

View File

@@ -1,19 +1,38 @@
<template>
<view style="padding: 20rpx;" :style="themeColor">
<rich-text :nodes="content"></rich-text>
<view class="view-container" :style="themeColor">
<!-- 加载状态 -->
<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>
</template>
<script>
import htmlParser from '@/common/js/html-parser';
import scroll from '@/common/js/scroll-view.js';
export default {
data() {
return {
content: '',
type: '',
uniacid:0
uniacid: 0,
loading: true
};
},
mixins: [scroll],
onLoad(option) {
this.type = option.type
this.uniacid = option.uniacid ? option.uniacid : 0
@@ -26,6 +45,7 @@ export default {
},
methods: {
getcontent() {
this.loading = true
// privacy content
var data = {
type: this.type
@@ -40,6 +60,10 @@ export default {
title: res.data.title
})
this.content = res.data.content
this.loading = false
},
fail: () => {
this.loading = false
}
});
}
@@ -47,6 +71,117 @@ export default {
};
</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>

View File

@@ -10,8 +10,7 @@
</view>
<!-- 消息列表 -->
<view v-for="(message, index) in messages" :key="`msg-${message.id || message.timestamp}-${index}`"
class="message-item" :class="[message.role, { 'first-message': index === 0 }]">
<view v-for="item in messagesWithKey" :key="item.__renderKey" class="message-item" :class="[item.role, { 'first-message': item.__index === 0 }]">
<!-- 用户消息 -->
<view v-if="message.role === 'user'" class="user-message">
@@ -392,6 +391,19 @@ export default {
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() {
// 优先读取本地缓存的会话 ID
const localConvId = this.getConversationIdFromLocal();

View File

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

View File

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

View File

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

View File

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

281
readme.md
View File

@@ -1,176 +1,147 @@
# 小程序及快应用前端源码
来源于外包提供的源代码,"0731xcx20微信小程序(1).zip"
## 1. 📋 项目说明
该项目基于 **uni-app** 开发构建,请使用 [HBuilderX](https://www.dcloud.io/hbuilderx.html) 进行代码开发及构建发布。
## 项目说明
## 2. 🛠️ 开发说明
该项目基于 uniapp 开发构建,请使用(HBuilderX)[https://www.dcloud.io/hbuilderx.html] 进行代码开发及构建发布。
- 源码基于 **Vue2** 版本
- SCSS 采用 **dart-sass** 进行编译输出
## 开发说明
## 3. 🔧 开发调试说明
1. 源码基于Vue2版本scss采用node-sass进行编译输出。
### 3.1 注意事项
- 应用访问等关键参数的配置来源于 `./common/js/config.js`
## 开发调试说明
### 3.2 本地调试
### 注意点
`.local.config.js.example` 是本地调试配置示例。
应用访问等关键参数的配置来源于 `./common/js/config.js`
拷贝 `.local.config.js.example``.local.config.js` 文件,默认开发调试模式会自动加载该文件
### 小程序调试
---
## 4. 📦 发布说明
### 4.1 小程序发布
## 发布说明
#### 4.1.1 基本操作步骤(通用版/定制化版)
### 小程序发布
基本操作步骤:
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',
//客服地址
webSocket: '{{$webSocket}}',
//本地端主动给服务器ping的时间, 0 则不开启 , 单位秒
pingInterval: 1500,
// 版本号
version: '1.0'
};
export default config;
##### 4.1.1.1 【前置准备】
1. 在项目根目录打开终端安装依赖:
```bash
npm install
```
*已有依赖可跳过此步骤*
### 快应用发布
##### 4.1.1.2 【发布构建】
1. 使用 HBuilderX 打开项目
2. 点击项目中【⚙】manifest.jion--->web配置--->运行的基础路径--->/hwappx/改编号/
"h5" : {
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : "TUHBZ-CNWKU-UHAVP-GZQ26-HNZFO-3YBF4"
}
}
},
"router" : {
"mode" : "history",
"base" : "/hwappx/2811/"
},
2. 选择菜单栏「发行」 → 「小程序-微信」→ 「发行」,等待构建完成
⚠️ **注意**:底部控制台弹出"请在微信小程序开发者工具中点击上传"后再执行下一步
3. 打开资源管理器→项目根目录,右键选择「在终端中打开」,执行命令:
```bash
npm run mp-weixin
```
4. 找到项目根目录 `/unpackage/dist/build` 下生成的 mp-weixin 压缩包
💡 **示例**`mp-weixin-2026-01-23-1769152056146.zip`
*同时该目录下会生成未压缩的 `mp-weixin` 目录*
##### 4.1.1.3 【验证与重命名】
1. 打开未压缩的 `mp-weixin` 目录,找到 `site.js` 文件,将文件内的 `uniacid` 值改为当前客户编号2812并保存
2. 打开微信开发者工具导入「mp-weixin」目录点击「编译」在开发者工具控制台验证有无报错以及能否返回对应客户的业务数据
3. 确保无误后将生成的 mp-weixin 压缩包重命名
- **定制化版**格式:`定制化-客户编号-域名-mp-weixin-当前日期-生成编号.zip`
- **通用版**无需重命名
💡 **示例**`custom-2812-xcx.aigc-quickapp.com-mp-weixin-2026-01-22-1769152056146.zip`
🚫 **禁止**:压缩包命名禁止包含 `/ \ : * ? " < > |` 等特殊字符
##### 4.1.1.4 【交付与最终发布】🔍
1. 将重命名后的文件发送给技术人员
*📌通用版直接将生成的 mp-weixin 压缩包发送给技术人员*
2. **技术人员操作流程**
- 解压压缩包
- 确认 `site.js` 中的 `uniacid` 为客户编号
- 用微信开发者工具导入解压后的代码目录
- 编译验证无误后,上传发布
---
### 4.2 快应用发布
#### 4.2.1 基本操作(通用版/定制化版)
##### 4.2.1.1 【发布构建】
1. 使用 HBuilderX 打开项目
2. 打开项目根目录的 `manifest.json` 文件,切换至可视化配置界面:
1. 依次点击「Web 配置」→「运行的基础配置」
2. 修改路径中的客户编号
3. 📌 **通用版**保留原有 `/hwappx/common/`
💡 **示例**`/hwappx/2811/`,其中 2811 为定制化版客户编号
3. 选择菜单栏「发行」 → 「自定义发行」 →「H5-xcx.aigc-quickapp.com」修改以下配置
1. **网站标题**:快应用
2. **网站域名**当前客户域名示例xcx.aigc-quickapp.com
3. 确认后点击「发行」等待构建完成
⚠️ **注意**:底部控制台弹出“项目 lucky_shop 导出Web成功路径为D:\项目文件\项目根目录\unpackage\dist\build\web”后再执行下一步
💡 **示例**`项目 lucky_shop 导出Web成功路径为D:\0.项目源码\lucky_shop\unpackage\dist\build\web`
4. 按控制台提示的路径找到 `web` 目录,将该目录下所有文件手动打包成一个 `.zip` 压缩包
*仅打包文件,不包含外层 web 目录*
##### 4.2.1.2 【重命名】
1. 按版本类型规范重命名压缩包:
- **通用版**`hwappx-common-域名-时间.zip`
💡 **示例**`hwappx-common-xcx.aigc-quickapp.com-2026-01-24.zip`
- **定制化版**`客户名称-定制化---hwappx-客户编号-域名-时间.zip`
💡 **示例**`POCT检测分析平台-定制化---hwappx-2811-xcx.aigc-quickapp.com-2026-01-24.zip`
🚫 **禁止**:压缩包命名禁止包含 `/ \ : * ? " < > |` 等特殊字符
##### 4.2.1.3 【交付与最终发布】🔍
1. 将重命名后的压缩包发送给运维人员
2. **运维人员操作流程**
1. 解压压缩包
2. 打开快应用开发者工具,导入解压后的代码目录
3. 验证代码无报错后,执行上传发布操作
---
## 5. 📝 构建脚本说明
### 5.1 可用的 npm 脚本命令
| 命令 | 说明 |
|------|------|
| `npm run mp-weixin` | 默认构建production模式包含ZIP文件 |
| `npm run mp-weixin:patch` | 只打补丁production模式不创建ZIP文件 |
| `npm run mp-weixin:dev` | 开发模式构建development模式包含ZIP文件 |
| `npm run mp-weixin:dev:patch` | 只打补丁development模式不创建ZIP文件 |
### 5.2 构建脚本功能
- 复制 `project.config.json` 和 `project.private.config.json` 文件到构建目录
- 复制 `site.js` 文件到构建目录
- 在 `vendor.js` 文件开头追加 `import site from "../site.js";` 语句
- 支持创建构建结果的 ZIP 压缩包
- 自动打开 ZIP 文件所在目录
---
## 6. 🔄 版本历史
### 6.1 v1.3
- 修复微信小程序构建脚本,支持复制 `project.config.json` 和 `project.private.config.json` 文件
- 增强构建脚本功能,添加命令行参数支持
- 在 `package.json` 中添加相关 npm 脚本命令
- 优化脚本执行逻辑,提高可靠性和灵活性
(编号可以在.local.config.js中找到需要的编号
const localDevConfig = ({
'460': { // 制氧设备平台
uniacid: 460,
domain: 'https://xcx30.5g-quickapp.com/',
},
'576-xcx30.5g': { // 活性石灰装备
uniacid: 576,
domain: 'https://xcx30.5g-quickapp.com/',
},
'2285': { // 数码喷墨墨水
uniacid: 2285,
domain: 'https://xcx.aigc-quickapp.com/',
},
'2811': { // POCT检测分析平台
uniacid: 2811,
domain: 'https://xcx6.aigc-quickapp.com/',
},
'2724': { // 生物菌肥
uniacid: 2724,
domain: 'https://xcx.aigc-quickapp.com/',
},
'2505': { // 煤矿钻机
uniacid: 2505,
domain: 'https://xcx.aigc-quickapp.com/',
},
'2777': { // 养老服务
uniacid: 2777,
domain: 'https://xcx.aigc-quickapp.com/',
},
'1': { // 开发平台
uniacid: 1,
domain: 'https://dev.aigc-quickapp.com',
},
'1-test': { // 测试平台
uniacid: 1,
domain: 'https://test.aigc-quickapp.com',
},
})['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 来兼容不同平台。
@@ -29,8 +32,6 @@ async function commonPatch(mode = 'production') {
// 根据当前脚本所在目录scripts定位到项目根目录
const cwd = path.join(__dirname, '..');
const srcSitePath = path.join(cwd, 'site.js');
const destDir = path.join(cwd, 'unpackage', 'dist', mode === 'production' ? 'build' : 'dev', 'mp-weixin');
const destSitePath = path.join(destDir, 'site.js');
@@ -47,6 +48,22 @@ async function commonPatch(mode = 'production') {
// 确保目标目录存在
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 到目标目录(覆盖)
await fsp.copyFile(srcSitePath, destSitePath);
console.log(`已拷贝: ${srcSitePath} -> ${destSitePath}`);
@@ -96,14 +113,26 @@ async function commonPatch(mode = 'production') {
}
}
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) 打补丁
await commonPatch('production');
await commonPatch(options.mode);
// await commonPatch('development');
// 2) 创建 ZIP 文件
// 2) 创建 ZIP 文件(如果未指定 --no-zip
if (!options.noZip) {
const cwd = path.join(__dirname, '..');
const sourceDir = path.join(cwd, 'unpackage', 'dist', 'build', 'mp-weixin');
const destDir = path.join(cwd, 'unpackage', 'dist', 'build');
@@ -112,6 +141,9 @@ async function main() {
// 3) 自动打开zip所在的目录
await openFileDirectory(zipFilePath);
} else {
console.log('跳过创建 ZIP 文件和打开目录');
}
}
async function exists(p) {