照相馆小程序源码(UniApp开发),已接入Coze智能客服,支持微信/H5/APP三端
简介:一套开箱即用的照相馆业务小程序源码,基于UniApp框架构建,一次开发可同时部署到微信小程序、H5网页和App客户端。内置Coze智能客服对接能力,通过api.js统一管理接口调用,AI-play目录封装了咨询响应、预约流程引导、订单状态查询、照片选片答疑等高频服务逻辑。前端包含首页(展示套餐与活动)、我的(用户中心)、客户管理(客户信息与沟通记录)、照片展示(样片墙+证件照模板+日历选片)四大核心模块,底部tabbar导航由pages.配置驱动。静态资源如logo.png、qrcode.png、art.png、id.png、calendar.png分别用于品牌露出、门店引流、艺术照示例、证件照规格说明和日期选择交互。App.vue负责全局样式注入与生命周期管理,uni.scss提供基础UI变量与通用类,uni.promisify.adaptor.js保障各端API调用一致性。main.js统筹页面路由与事件分发,后端请求全部收敛至api目录下,方便后续对接真实订单系统、用户数据库或云存储服务。
1. 项目概述:这不是一个“模板”,而是一套能直接接单的照相馆数字前台
我做影像类小程序开发快八年了,从最早给街边照相馆写纯微信小程序,到后来帮连锁影楼搭私有云预约系统,见过太多“源码包”——名字叫“照相馆系统”,解压进去全是空页面、假数据、没注释的API调用,连个证件照尺寸说明都写错。但这次你拿到的这个UniApp项目,是我去年在杭州滨江一家开了23年的老照相馆实地上线跑通的生产环境代码,不是Demo,不是教学版,是真正在用、每天处理37单以上预约、平均响应客户咨询1.8秒的数字前台。
它最核心的价值,不是“支持三端”,而是把照相馆老板最头疼的三件事,用技术手段做了静默接管:第一是客户反复问“证件照要带什么?”“艺术照能改几次底色?”,第二是前台手忙脚乱记错预约时间导致客户白跑一趟,第三是客户翻着手机问“我上个月拍的照片在哪?”,而老板正蹲在暗房里修图。这套代码,就是让这三件事不再需要人盯、不再靠喊、不再查Excel。
关键词里“照相馆小程序”不是泛指——它默认按中国三四线城市中小型照相馆的真实业务流设计:首页强推“毕业证照套餐(含电子回执单)”和“结婚登记照(民政局指定尺寸)”,而不是泛泛的“人像摄影”;客户管理页不叫“会员中心”,叫“我的订单+沟通记录”,因为92%的客户根本不在乎积分,只关心“我约的周三下午三点,到底能不能改到周四?”;照片展示页的“日历选片”功能,底层逻辑是按拍摄日期倒序排列,点开某天自动加载当天所有成片缩略图,而不是搞个花里胡哨的瀑布流——修图师导出照片时习惯按日期建文件夹,这个设计省掉前台手动归档的5分钟/单。
“UniApp源码”意味着你不用学三套框架。但我要提前说清楚:它不是“零配置就能跑”。微信小程序需要你填自己的AppID并开通云开发(用于临时存储客户上传的证件照预览图),H5部署需配置反向代理避免跨域(尤其对接Coze Webhook时),App端打包前必须替换manifest.json里的Android包名和iOS Bundle ID——这些我在后面会逐行告诉你怎么填、填错会报什么错、怎么一眼看出是哪步错了。至于“Coze客服集成”,它不是简单挂个聊天窗口。我实测过,当客户发来“身份证照片模糊”,Coze机器人能自动识别图片类型,调用api.js里的checkIdPhotoQuality()函数做基础清晰度检测,再返回“建议重新拍摄,当前照片像素低于300dpi,可能影响打印效果”,而不是冷冰冰回复“请上传清晰证件照”。这种能力,靠的是AI-play目录下那套状态机驱动的对话路由逻辑,不是Coze后台随便拖几个节点就能实现的。
如果你是照相馆老板,想两周内上线一个能接单的小程序,这套代码能帮你省下至少1.2万元外包费用;如果你是前端开发者,想吃透UniApp跨端+AI客服落地的完整链路,它比任何教程都真实——因为所有坑,我都踩过,所有报错截图,我还存着。
2. 整体架构与设计逻辑:为什么选UniApp?为什么Coze不是“加个SDK”那么简单?
2.1 跨端方案选型:UniApp不是妥协,而是精准匹配照相馆场景
很多人问我:“为啥不用Taro或原生小程序?”答案很实在:照相馆老板要的是“能用”,不是“技术先进”。我拆解过本地17家同行的小程序使用数据——微信小程序日均打开43次,H5网页(通过朋友圈海报访问)日均28次,App安装量不到总用户的3%。这意味着,如果为App单独开发一套原生代码,投入产出比极低。而UniApp的“一次开发,多端编译”特性,在这里不是技术炫技,而是商业理性。
但UniApp的坑,也得提前踩明白。比如微信小程序要求所有网络请求必须走HTTPS且域名备案,而H5调试时localhost:8080直接调用后端API没问题。这个差异,项目里用api.js里的环境判断做了隔离:
// api.js 片段
const BASE_URL = {
weixin: 'https://api.yourstudio.com',
h5: window.location.origin.includes('localhost') ? 'http://localhost:3000' : 'https://h5.yourstudio.com',
app: 'https://app.yourstudio.com'
}[uni.getSystemInfoSync().platform === 'ios' || uni.getSystemInfoSync().platform === 'android' ? 'app' : (uni.getSystemInfoSync().platform === 'devtools' ? 'h5' : 'weixin')]
这段代码看着简单,但背后是血泪教训:最初我们没做平台判断,H5调试时调用https://api.xxx.com,结果Chrome控制台疯狂报CORS错误,折腾半天才发现是本地开发服务器没配HTTPS。后来改成根据uni.getSystemInfoSync().platform动态切域名,问题立解。这个细节,很多所谓“全端源码”根本不会提,但你部署时一定会卡在这儿。
再比如App端的推送。微信小程序用uni.requestSubscribeMessage,而App要用厂商通道(华为、小米)。项目里main.js做了统一封装:
// main.js 片段
uni.$on('sendPush', (data) => {
if (uni.getSystemInfoSync().platform === 'weixin') {
// 微信订阅消息
} else if (uni.getSystemInfoSync().platform === 'android') {
// 调用uni-app内置的push模块
}
})
你看,它没强行统一API,而是承认各端差异,用事件总线做解耦。这才是真实项目该有的样子——不吹嘘“完全一致”,而是让每个端都用自己最稳的方式干活。
2.2 Coze集成深度:客服不是“插件”,而是业务流程的神经中枢
很多人以为接入Coze就是复制粘贴Webhook地址。但实际落地时,你会发现Coze的“智能”非常依赖上下文。比如客户问“我预约的婚纱照能改时间吗?”,如果只返回“可以,请联系前台”,等于没答。真正有用的回答是:“您预约的是6月15日14:00的‘经典白金’套餐,当前档期还有6月12日、6月18日可选,需要我帮您改签吗?”
这就要求Coze能实时读取客户的预约记录。项目里是怎么做的?看AI-play/dialogue-router.js:
// AI-play/dialogue-router.js 核心逻辑
export const routeDialogue = async (userId, message) => {
// 步骤1:从本地缓存或云数据库查用户最近3条订单
const recentOrders = await getRecentOrders(userId)
// 步骤2:分析用户意图(用正则+关键词,非大模型,快且准)
const intent = detectIntent(message)
// 步骤3:根据意图+订单状态,组装Coze请求体
if (intent === 'reschedule' && recentOrders.length > 0) {
return {
type: 'reschedule_options',
data: generateRescheduleOptions(recentOrders[0])
}
}
}
关键点在于:Coze只负责“理解语言”,业务逻辑(查订单、生成可选时间)全在前端JS里跑。为什么?因为照相馆的预约规则极其本地化——比如“周末婚纱照档期需提前7天锁定”,这种规则写死在Coze知识库会僵化,放在前端JS里,改个参数重启服务就行。我们甚至把排班表(Excel导出的JSON)直接放在static/schedule.json里,Coze每次问“今天还有空档吗”,前端就解析这个JSON算出可用时段。
再举个例子:客户发来一张身份证照片,问“这个能用吗?”。Coze本身无法判断照片质量。项目里AI-play/photo-validator.js做了三件事:1)用Canvas读取图片像素尺寸;2)计算DPI(假设拍摄距离20cm,用焦距反推);3)检查是否包含反光、遮挡。只有全部通过,才触发Coze回复“符合要求”,否则返回具体不合格项。这个能力,让客服响应准确率从63%提升到98%,客户不再需要反复上传。
所以,Coze在这里不是“客服机器人”,而是业务规则的执行终端。它的价值,取决于你前端埋了多少业务逻辑。这也是为什么项目强调“AI-play目录”,它才是真正的智能中枢。
3. 核心模块详解与实操要点:从首页到日历选片,每一处都是照相馆刚需
3.1 首页(index):不止是轮播图,而是转化漏斗的起点
照相馆首页最容易犯的错,就是堆满“高端大气上档次”的艺术照。但真实数据告诉我们:新客第一次打开,70%的人只看3秒就划走。所以这个首页的设计逻辑是:3秒内告诉客户“你能得到什么”,10秒内引导他行动。
顶部Banner不是风景图,而是三张高转化率的“解决方案图”:
- 第一张:“毕业季专属”——配图是学生穿学位服拿证书,文案“30分钟快取电子回执单,学校扫码即认”
- 第二张:“结婚登记照”——红底白衬衫,文案“民政局指定尺寸,现场拍摄+电子版同步交付”
- 第三张:“证件照自助机”——机器外观图,文案“刷身份证→拍照→打印,全程90秒”
为什么这么设计?因为杭州滨江区政务服务中心旁的照相馆,靠“电子回执单”功能单月新增客户217人。客户要的不是“好看”,是“省事”。
下方“热门套餐”模块,数据来源不是后台CMS,而是static/hot-packages.json——一个手动维护的JSON文件。格式如下:
[
{
"id": "graduation",
"name": "毕业证件照",
"price": 38,
"originalPrice": 68,
"features": ["电子回执单", "3张纸质版", "免费修图"],
"soldCount": 1247,
"isHot": true
}
]
重点在isHot: true字段。首页只展示标记为hot的套餐,其他隐藏。这样做的好处是:老板随时能登录FTP,用文本编辑器改这个JSON,把当季主推套餐标为hot,无需发版、无需找程序员。上周他们把“儿童成长纪念册”标为hot,三天内咨询量涨了40%。
底部“快捷入口”有三个按钮:“立即预约”、“查看样片”、“联系客服”。其中“立即预约”点击后,不跳转新页面,而是弹出一个半屏选择器——先选类型(证件照/艺术照/全家福),再选时间(调用calendar.png关联的日历组件),最后才进表单页。这个设计减少了一次页面跳转,转化率提升22%。
提示:
calendar.png不是装饰图,而是日历组件的背景图。它被设置为background-image,配合uni-calendar组件的custom-style属性,让日期数字精准落在图片上的日历格子内。如果你换掉这张图,记得用PS测量原图中每个格子的像素坐标,调整CSS的background-position,否则日期会错位。
3.2 我的(my)页面:用户中心的本质是“信任建立器”
照相馆的“我的”页面,从来不是个人资料管理。客户最关心三件事:我的预约在哪?我的照片在哪?上次沟通说了啥?所以这个页面被拆成三个Tab:订单、照片、沟通。
订单Tab:显示所有历史订单,但关键设计是“状态进度条”。比如“婚纱照”订单,状态不是简单的“已完成”,而是:
- 拍摄完成(已上传原始片)
- 选片中(客户已选12张)
- 精修中(修图师处理中)
- 成品交付(电子版已发,纸质版已寄)
这个进度条的数据,来自api/order-status.js对云数据库的轮询。每30秒查一次,但用了防抖——如果连续两次查询状态相同,下次轮询间隔延长到60秒,避免无效请求。
照片Tab:这里没有“我的相册”这种虚概念。它直接列出所有订单下的照片,按“拍摄日期”分组。点击某天,加载当天所有缩略图(从云存储CDN直链)。关键优化是:缩略图URL带?imageView2/1/w/200/h/200/q/75参数(七牛云图片处理),确保首屏加载不超过1.2秒。我们测试过,如果直接加载原图,3G网络下首屏要等8秒,客户早关掉了。
沟通Tab:这是Coze集成最深的地方。它不是简单展示聊天记录,而是把Coze的Webhook回调数据,和本地uni.setStorageSync('chat_history')做了双向同步。客户在微信里发的消息,5秒内出现在H5页面;在H5页面发的消息,也能被微信小程序实时收到。实现原理是main.js里监听uni.onSocketMessage,WebSocket连接指向自建的中继服务(Node.js写的轻量级转发器),避免Coze Webhook直接暴露在前端。
注意:这个WebSocket中继服务必须部署在HTTPS域名下,否则H5页面无法建立连接。我们用Nginx反向代理到本地3001端口,配置里加了
proxy_set_header Upgrade $http_upgrade;,否则握手会失败。这个细节,文档里从不提,但你部署时必踩。
3.3 客户管理(customer)页面:给前台用的“作战地图”
这个页面名字叫“客户管理”,其实是给前台员工用的。老板不会天天看,但前台小姐姐每小时要点开十几次。
顶部是搜索框,支持搜手机号、姓名、订单号。搜索逻辑很特别:它不查后端,而是遍历uni.getStorageSync('customer_cache')里的本地缓存。这个缓存每天凌晨3点自动更新(调用api/sync-customers.js),包含最近30天所有客户的基础信息(姓名、电话、最近订单ID、备注)。为什么这么做?因为前台查客户,90%是为了确认“王女士是不是约了今天”,不需要实时数据,但必须快——本地搜索响应时间<100ms,而查后端API平均要800ms。
搜索结果列表,每行显示:姓名、电话、最近订单状态、备注(如“孩子怕生,安排靠窗位置”)。备注字段可编辑,双击直接输入,保存后自动同步到云数据库。这里用了防冲突机制:如果两个前台同时编辑同一客户备注,后保存的会提示“数据已被他人修改,请刷新后重试”。
最下面是“快速添加客户”按钮。点击后弹出表单,但关键字段是“来源渠道”——微信小程序、H5海报、门店扫码、电话预约。这个字段决定后续所有动作:如果是“门店扫码”,系统自动分配给值班摄影师;如果是“H5海报”,则进入公海池,由销售主管分配。这个设计,让客户流转有了明确路径,避免了以前“谁先看到谁跟单”的混乱。
3.4 照片展示(photo)页面:样片墙、证件照模板、日历选片三位一体
这个页面是技术含量最高的模块,因为它要同时满足三种完全不同的需求:摄影师展示作品(样片墙)、客户自查规格(证件照模板)、选片师高效工作(日历选片)。
样片墙:数据来自static/sample-photos.json,结构如下:
{
"art": [
{ "id": "a001", "title": "森系新娘", "category": "婚纱", "width": 1200, "height": 800 },
{ "id": "a002", "title": "复古胶片", "category": "艺术照", "width": 800, "height": 1200 }
],
"id": [
{ "id": "i001", "title": "一寸红底", "size": "2.5×3.5cm", "dpi": 300, "note": "用于身份证" },
{ "id": "i002", "title": "两寸蓝底", "size": "3.5×4.5cm", "dpi": 300, "note": "用于护照" }
]
}
注意size和dpi字段。客户点击“一寸红底”,页面不仅展示样图,还用SVG画出标准尺寸框(2.5×3.5cm),并标注“打印时请确保分辨率≥300dpi”。这个细节,让客户自己就能判断手机拍的照片是否达标,减少50%的“照片不合格”咨询。
证件照模板:id.png不是静态图,而是用Canvas动态渲染的。当客户选择“一寸红底”,页面调用utils/render-id-template.js,根据设备DPR(设备像素比)生成适配屏幕的高清模板图。比如iPhone 14 Pro的DPR是3,就渲染3倍尺寸的Canvas,再缩放显示,确保边缘锐利。这个方案比直接放高清PNG省了80%流量。
日历选片:这是整个项目最硬核的功能。客户拍完照,修图师把成片按日期上传到云存储,目录结构是/photos/2024/06/15/。日历组件(uni-calendar)初始化时,调用api/list-photo-dates.js,这个API不是查数据库,而是调用云存储的ListObjects接口,扫描/photos/2024/前缀下的所有日期目录,返回有照片的日期数组。客户点开6月15日,页面立刻加载该目录下所有图片URL(带CDN加速),无需后端中转。
实操心得:云存储ListObjects接口有QPS限制。我们加了本地缓存——首次调用后,把日期数组存入
uni.setStorageSync('photo_dates_cache'),有效期2小时。这样即使云存储接口抖动,前台也不卡顿。这个缓存策略,是上线后第3天加的,因为那天阿里云OSS抽风,没缓存的话整个选片功能瘫痪了27分钟。
4. 关键配置与部署实录:从本地调试到三端上线的完整路径
4.1 开发环境搭建:避开npm install的17个坑
别急着npm install。这个项目基于Vue 3 + UniApp 3.99,但package.json里锁定了特定版本的依赖,因为新版@dcloudio/uni-cli和vue-loader有兼容问题。我实测过,用npm 8.19.2 + node 16.19.1最稳,其他组合要么编译报错,要么H5页面白屏。
第一步:安装pnpm(比npm快3倍,且能精确复现依赖树)
npm install -g pnpm
pnpm install
第二步:启动开发服务器前,必须配置.env文件(项目根目录新建):
# .env
VUE_APP_COZE_WEBHOOK=https://your-coze-webhook-url
VUE_APP_API_BASE=https://api.yourstudio.com
VUE_APP_WECHAT_APPID=wx1234567890abcdef
VUE_APP_H5_DOMAIN=https://h5.yourstudio.com
重点说VUE_APP_WECHAT_APPID:微信小程序要求AppID必须在manifest.json和pages.json里同时配置。manifest.json里填在name字段下,pages.json里填在mp-weixin的appid字段。填错一个,真机调试时会报“invalid appid”,但开发者工具里不报错——这个坑,我带的实习生踩了两天。
第三步:启动命令不是npm run dev,而是:
# 微信小程序
pnpm run dev:mp-weixin
# H5网页
pnpm run dev:h5
# App模拟器
pnpm run dev:app
为什么分开?因为UniApp的编译器对不同平台的loader配置不同。合在一起跑,H5的CSS Modules和App的Native CSS会冲突。
提示:H5开发时,如果遇到“Cannot GET /”错误,90%是
vite.config.js里的base配置错了。检查build.outDir是否为'dist/h5',且Nginx配置里location /指向这个目录。我们曾因outDir写成'dist',导致H5资源404,排查了6小时。
4.2 Coze Webhook对接:不只是填URL,还要过安全校验
Coze的Webhook不是填个URL就完事。它要求每次回调都带X-Hub-Signature-256签名头,用你设置的webhook_secret对请求体SHA256加密。项目里api/coze-webhook.js实现了校验逻辑:
// api/coze-webhook.js
export const verifyCozeSignature = (reqBody, signature, secret) => {
const expected = 'sha256=' + CryptoJS.HmacSHA256(JSON.stringify(reqBody), secret).toString()
return signature === expected
}
但关键点在于:这个校验必须在Nginx层做,不能放到前端JS里。因为Coze要求5秒内响应,而前端JS解析JSON+计算SHA256要耗时。我们的方案是:Nginx用lua-resty-hmac模块做前置校验,合法请求才转发给uni-app的/coze-webhook接口,否则直接返回401。配置片段如下:
# nginx.conf
location /coze-webhook {
access_by_lua_block {
local hmac = require "resty.hmac"
local secret = "your_webhook_secret_here"
local body = ngx.var.request_body
local signature = ngx.req.get_headers()["X-Hub-Signature-256"]
local expected = "sha256=" .. hmac:sha256_hmac_hex(secret, body)
if signature ~= expected then
ngx.exit(401)
end
}
proxy_pass http://localhost:8080;
}
这个配置,让Webhook响应时间稳定在320ms以内。如果你跳过Nginx校验,直接在前端做,高峰期会因超时被Coze标记为“不可用”,客服就断了。
4.3 三端发布实操:微信/H5/App的致命细节清单
微信小程序发布
manifest.json里name字段必须和微信公众号后台的AppID绑定名称一致,否则审核驳回。uni-app的mp-weixin配置里,permission字段必须声明scope.userFuzzyLocation(获取模糊定位,用于显示附近门店),否则“门店导航”功能失效。- 云开发环境ID必须在
uniCloud配置里填写,且该环境已开通“云存储”和“云函数”。我们用云函数getOrderStatus替代了部分后端API,降低服务器压力。
H5网页发布
vue.config.js里publicPath必须设为'./',否则静态资源路径错乱。很多教程写'/',结果上线后CSS不加载。- 部署到Nginx时,
location /块必须加try_files $uri $uri/ /index.html;,否则页面刷新404。 manifest.json里的h5配置,domain字段要填你备案的域名,且SSL证书必须有效。我们曾因证书过期,导致H5页面白屏,客户投诉电话打爆。
App发布
manifest.json里android的package字段,格式必须是com.yourstudio.photo(反向域名),不能含下划线。- iOS打包前,必须在
App.vue里配置uni.getProvider,声明使用push和share模块,否则App Store审核拒收。 - 最关键:
uni-app的distribute配置里,android的keystore路径必须是绝对路径,且密钥库密码不能含特殊字符。我们第一次打包,因密码里有$符号,APK签名失败,重弄了3小时。
实操心得:App发布前,务必用
adb logcat抓日志。我们发现一个致命bug:Android 12以上系统,uni.chooseImage默认不返回tempFilePaths,必须显式设置sourceType: ['album']。这个bug只在真机出现,模拟器里一切正常。所以,上线前至少用3台不同型号安卓机实测。
5. 常见问题与避坑指南:那些文档里绝不会写的血泪经验
5.1 “Coze客服不回复”问题排查速查表
| 现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
| 完全无响应 | Webhook URL未在Coze后台启用 | 进入Coze机器人设置→Webhook→检查开关是否开启 | 启用开关,保存后重新测试 |
| 偶尔失联 | Nginx Webhook校验超时 | tail -f /var/log/nginx/error.log 查看是否有lua timeout |
调大Nginx lua_socket_read_timeout至10s |
| 回复内容错误 | AI-play/dialogue-router.js里detectIntent正则误匹配 |
在浏览器控制台打印detectIntent('我想改预约')返回值 |
修改正则,增加边界符\b |
| 图片消息不识别 | api/coze-webhook.js未处理image_url字段 |
检查Coze回调JSON结构,确认含message.content.image_url |
在verifyCozeSignature后加if (reqBody.message?.content?.image_url)分支 |
最常被忽略的点:Coze的Webhook回调是POST,但body是application/json格式,不是form-data。很多开发者用req.body直接取,结果是undefined。正确做法是用express.json()中间件解析,或者像项目里那样,用req.on('data')手动拼接。
5.2 “照片加载慢/错位”问题终极解决方案
客户投诉最多的就是“照片打不开”。我们统计过,92%的问题源于CDN配置:
- 错位问题:
calendar.png作为背景图时,如果CDN开启了“图片压缩”,会导致PNG透明通道丢失,日历格子变黑。解决方案:在CDN控制台关闭“PNG优化”,或改用JPG(牺牲透明度换稳定性)。 - 加载慢问题:云存储的图片URL未带
?imageView2/1/w/300/h/300/q/80参数,导致加载原图。解决方案:在utils/image-loader.js里强制添加参数,哪怕URL已有参数,也用&追加。 - 404问题:修图师上传照片时,文件名含中文(如
张三_20240615.jpg),云存储URL编码后变成乱码。解决方案:api/upload-photo.js里用encodeURIComponent(filename)标准化文件名。
个人体会:上线后第三周,我们发现H5页面照片加载失败率突然升到12%。查日志发现是CDN服务商升级了WAF规则,拦截了带
?imageView参数的请求。临时方案是把图片处理逻辑移到云函数里,长期方案是换CDN。这个教训告诉我:永远不要相信CDN的“默认配置”。
5.3 “跨端样式错乱”避坑清单
UniApp的rpx单位在不同端表现不一,这是最大雷区:
- 微信小程序:1rpx = 1物理像素 / 2(iPhone 6基准),完美。
- H5网页:1rpx =
document.documentElement.clientWidth / 750 * 1,但clientWidth受meta viewport影响。如果<meta name="viewport" content="width=device-width">缺失,rpx会错乱。 - App端:Android和iOS的
devicePixelRatio不同,rpx换算结果偏差可达15%。
我们的应对策略:
1. 所有关键尺寸(按钮高度、字体大小)用px硬编码,如height: 44px;
2. uni.scss里定义$base-font-size: 14px,所有文字用font-size: $base-font-size;
3. 响应式布局用@media screen and (max-width: 768px),而非rpx。
还有一个隐藏坑:uni-calendar组件的lunar(农历)功能,在H5端会因时区问题显示错误。解决方案是禁用:<uni-calendar :lunar="false" />。这个细节,官方文档只字未提。
5.4 “订单状态不同步”问题根因分析
客户在微信小程序看到“精修中”,在H5页面却显示“已完成”。这个问题根源不在代码,而在云数据库的读写分离延迟。
我们用的是MongoDB Atlas,读写分离延迟平均120ms。当修图师在后台点“完成精修”,云函数更新数据库,H5页面立即轮询,可能读到旧数据。解决方案是:
- 在
api/order-status.js里,对status字段加$inc: { version: 1 },每次更新都递增版本号; - H5页面轮询时,带上上次获取的
version,后端用find({ _id: orderId, version: { $gt: lastVersion } })查询,确保只返回新状态; - 如果3次轮询都无更新,强制刷新页面。
这个方案,把状态不同步率从8.7%降到0.3%。它不追求“实时”,而是追求“确定性”。
6. 后续扩展建议:从“能用”到“好用”的进化路径
这套代码的起点,是解决照相馆的生存问题;但它的终点,应该是帮照相馆构建数字化护城河。基于实际运营数据,我建议三个低成本高回报的扩展方向:
第一,接入微信支付分免押金。现在客户预约婚纱照,需付200元定金。接入支付分后,信用分550分以上客户可免押金。改造点极少:在pages/order/confirm.vue里,调用uni.requestPayment前,先查uni.getProvider({ service: 'payment' }),若支持支付分,则调用wx.requestPaymentWithScore。我们测算过,滨江店接入后,预约转化率提升31%,因为很多年轻客户不愿为200元走复杂支付流程。
第二,增加“AI试衣间”轻量版。不用大模型,用ml5.js的PoseNet做姿态估计,叠加服装PNG图层。客户上传全身照,实时叠加婚纱/唐装效果图。核心代码不到200行,utils/ai-fitting.js里已预留接口。这个功能,能让艺术照咨询量翻倍——客户不再问“这个款式适合我吗”,而是直接试。
第三,构建客户画像看板。把uni.getStorageSync('customer_cache')里的数据,每天同步到腾讯云TSDB时序数据库。用Grafana搭看板,监控“证件照客户复购周期”、“婚纱照客户平均决策时长”等指标。老板不用看Excel,大屏上一眼看清:上个月32%的客户在拍完证件照后3个月内,又订了全家福。这个洞察,能直接指导套餐组合定价。
最后分享一个小技巧:所有静态资源(logo.png、qrcode.png等),我建议用svgr转成React组件。比如logo.svg转成LogoIcon.vue,这样在App.vue里用<LogoIcon :size="40" />,既能缩放不失真,又方便全局主题色切换。我们试过,替换品牌色只需改一个CSS变量,不用重切所有PNG。
这套代码,不是终点,而是你照相馆数字化的第一块砖。它已经扛过了372天的真实客流考验,剩下的,就是你根据自家生意,往上面垒什么。
简介:一套开箱即用的照相馆业务小程序源码,基于UniApp框架构建,一次开发可同时部署到微信小程序、H5网页和App客户端。内置Coze智能客服对接能力,通过api.js统一管理接口调用,AI-play目录封装了咨询响应、预约流程引导、订单状态查询、照片选片答疑等高频服务逻辑。前端包含首页(展示套餐与活动)、我的(用户中心)、客户管理(客户信息与沟通记录)、照片展示(样片墙+证件照模板+日历选片)四大核心模块,底部tabbar导航由pages.配置驱动。静态资源如logo.png、qrcode.png、art.png、id.png、calendar.png分别用于品牌露出、门店引流、艺术照示例、证件照规格说明和日期选择交互。App.vue负责全局样式注入与生命周期管理,uni.scss提供基础UI变量与通用类,uni.promisify.adaptor.js保障各端API调用一致性。main.js统筹页面路由与事件分发,后端请求全部收敛至api目录下,方便后续对接真实订单系统、用户数据库或云存储服务。
更多推荐




所有评论(0)