简介:本资源为Discuz点微同城30.0全功能插件套件,面向基于Discuz平台构建本地生活服务类网站的开发者与运营方,提供覆盖同城分类信息、招聘、房产、婚恋、拼团、优惠抢购、小程序对接等20余核心业务场景的一站式扩展能力。压缩包含2000个文件,主体为4117个PHP后端逻辑文件、1987个HTM/HTML前端模板、2033个PNG及437个JPG/GIF图片资源、613个JS交互脚本与256个CSS样式文件,辅以WXSS/WXML等微信小程序适配文件,整体体积72.68MB,结构完整、模块解耦清晰,可直接部署升级。已有1403人学习下载,适用于需快速搭建高定制化同城服务平台的技术团队。用户可获得全部47个官方插件源码(含疫情地图、子站点、电话本、红包系统等稀缺模块),以及H5与小程序双端兼容的前端资源、标准化接口调用示例和weui.css等UI基础支持,显著降低二次开发门槛。
1. Discuz 点微同城 30.0 全套插件(47个)不是“一键安装包”,而是 H5 与小程序双端协同的本地化服务系统底座
Discuz 点微同城 30.0 全套插件(含 47 个独立功能模块)本质是一套深度耦合 Discuz! X3.4+ 核心的本地生活服务扩展体系,其 H5 前端并非简单响应式页面,而是基于 WeUI.css 规范构建、适配微信内嵌 WebView 的轻量级单页应用;其小程序前端也非独立生态,而是严格遵循微信小程序基础库 2.25.2+ 要求、通过wx.request与 Discuz 后端 RESTful 接口通信的原生方案。这套插件组合解决的是社区型平台从论坛向“附近服务”转型时最痛的三个断层:用户身份无法跨 H5/小程序复用、商家入驻流程在两端不一致、订单状态在不同入口下不同步。它适合已有 Discuz! X3.4 或 X3.5 站点、且已备案主体具备微信小程序认证资质的技术团队——不是买来就能跑的成品商城,而是需要你亲手把discuz_plugin_dianwei_tongcheng目录注入/source/plugin/、逐个启用并配置 API Token 的可定制服务中台。如果你正被“小程序备案备注信息怎么填”卡住,或发现“打包为app连接不了”,说明你还没完成这套插件最关键的后端网关对齐。
2. 拆解点微同城 30.0 插件架构:47 个模块如何分工支撑 H5 与小程序双端能力
点微同城 30.0 的 47 个插件并非平铺罗列,而是按职责划分为 5 类核心能力层,每类都直接影响 H5 页面渲染逻辑与小程序 API 调用路径。理解这个分层,是避免“H5 游戏逆向”式盲目修改的前提。
2.1 基础支撑层(12 个插件):决定 H5 是否能加载、小程序能否获取用户定位
这类插件提供底层通信协议与权限桥接,例如dwtc_api(统一 API 网关)、dwtc_wxauth(微信授权中间件)、dwtc_location(地理位置服务封装)。它们直接修改 Discuz 的common.inc.php加载链,并在 H5 端注入weui.css+weui.min.js,在小程序端暴露wx.getLocation()封装方法。关键动作是:启用dwtc_wxauth后,H5 页面必须在<head>中引入https://res.wx.qq.com/open/js/jweixin-1.6.0.js,并在onLoad阶段调用wx.config();小程序则需在app.js的onLaunch中执行wx.login()并将 code 传给dwtc_api接口/api/wx/login。
提示:若 H5 页面在微信内打开时提示“config:invalid signature”,不是签名算法错,而是
dwtc_wxauth插件未正确读取 Discuz 后台「站点 URL」设置——必须与公众号 JS 安全域名完全一致(含 http/https 协议),且不能带端口。
2.1.1 dwtc_api 插件的 3 个必调参数:控制 H5 与小程序数据一致性
dwtc_api是整套系统的神经中枢,其后台配置页有 3 个影响双端行为的关键字段:
| 参数名 | 默认值 | H5 端影响 | 小程序端影响 | 修改建议 |
|---|---|---|---|---|
api_domain | 空 | H5 发起 AJAX 请求的基础域名,若填https://api.example.com,所有$.get('/v1/shop')实际请求https://api.example.com/v1/shop | 小程序wx.request({url: '/v1/shop'})会自动拼接此域名,必须与小程序服务器域名白名单一致 | 填写与 Discuz 主站同域的二级域名(如api.bbs.example.com),避免跨域拦截 |
token_expire | 7200 | H5 登录态 JWT Token 过期时间(秒),过期后跳转/member.php?mod=logging&action=login | 小程序wx.setStorageSync('token', ...)存储的 token 有效期,超时后wx.request返回 401 | 生产环境建议设为 3600,配合小程序wx.checkSession()定期刷新 |
h5_redirect_url | /plugin.php?id=dwtc_h5:index | H5 用户点击“立即下单”后跳转的落地页路径,该路径由dwtc_h5插件提供路由 | 小程序wx.navigateTo({url: '/pages/order/index'})仅跳转本地页面,此参数不影响小程序 | 若需 H5 订单页支持微信支付,此处必须指向含wx.config初始化的页面 |
2.2 业务功能层(23 个插件):H5 与小程序共用同一套数据模型,但渲染逻辑分离
这类插件实现具体业务,如dwtc_shop(商家管理)、dwtc_order(订单中心)、dwtc_coupon(优惠券)。它们共享 Discuz 的pre_dwtc_*数据表,但前端呈现方式截然不同:H5 使用 jQuery + Handlebars 模板(位于/template/default/dwtc/),小程序使用 WXML + WXSS(位于/plugin/dwtc_xxx/template/)。以dwtc_shop为例,H5 列表页通过$.get('/plugin.php?id=dwtc_shop:api&op=list')获取 JSON,小程序则调用wx.request({url: '/api/shop/list'})—— 接口返回结构完全相同,但 H5 侧需手动处理weui-flex布局,小程序侧直接绑定wx:for。
2.2.1 H5 端 weui.css 的 2 处必须覆盖的样式冲突
WeUI.css 在 Discuz 默认模板中常与common.css冲突,导致按钮圆角失效、列表间距错乱。必须在 H5 页面<head>中追加以下 CSS 覆盖:
<style> /* 修复 WeUI 按钮在 Discuz 表单中的高度塌陷 */ .weui-btn { line-height: 1.5; padding: 0.8em 1.2em; } /* 修复 WeUI 列表项在 Discuz 评论区内的边距溢出 */ .weui-cells__title { margin-top: 0.5em; margin-bottom: 0.3em; } </style>这段代码需硬编码在dwtc_h5插件的index.htm模板中,不能依赖外部 CSS 文件——因为 Discuz 的template缓存机制会导致weui.css加载顺序不可控。
2.3 小程序专用层(8 个插件):补足原生能力,解决“uniapp开发h5嵌入微信公众号中获取定位”的兼容问题
这部分插件专为小程序设计,如dwtc_wxpay(微信支付封装)、dwtc_wxmap(高德地图 SDK 桥接)、dwtc_wxshare(自定义分享卡片)。它们不提供 H5 功能,但其 PHP 后端逻辑(如生成支付 prepay_id)被 H5 和小程序共同调用。典型场景是:H5 页面调用微信 JS-SDK 发起支付,而小程序调用wx.requestPayment(),两者均需先请求dwtc_wxpay的/api/wxpay/create接口获取签名参数。
注意:
dwtc_wxmap插件要求 Discuz 后台填写高德 Web 服务 API Key,且 H5 端需在index.htm中引入<script src="https://webapi.amap.com/maps?v=1.4.15&key=YOUR_KEY"></script>;小程序端则无需引入,由插件自动注入wx.openLocation()调用逻辑。
3. H5 与小程序前端部署实操:从本地调试到线上发布的关键步骤
部署不是复制粘贴文件,而是建立三重校验链:Discuz 后端接口可访问 → H5 页面能正确初始化 WeUI 组件 → 小程序能稳定调用wx.request。任何一环断裂都会导致“websocket运行到h5可以连接,打包为app连接不了”这类现象。
3.1 H5 前端最小可运行命令:用 PHP 内置服务器验证基础链路
不要直接扔进生产环境 Nginx,先用 PHP 内置服务快速验证。进入 Discuz 根目录,执行:
php -S localhost:8000 -t ./source/plugin/dwtc_h5/ ./source/plugin/dwtc_h5/router.php此命令启动一个仅服务于dwtc_h5插件的轻量服务器,router.php是自定义路由文件,内容如下:
<?php // source/plugin/dwtc_h5/router.php if (preg_match('/\.(?:png|jpg|jpeg|gif|css|js|woff|woff2|ttf|eot)$/', $_SERVER["REQUEST_URI"])) { return false; // 静态资源直接返回 } else { // 所有 PHP 请求转发给 index.php include __DIR__ . '/index.php'; }访问http://localhost:8000/,若看到 WeUI 风格的首页且控制台无Failed to load resource: net::ERR_CONNECTION_REFUSED错误,说明 H5 静态资源与 PHP 路由通路正常。
3.1.1 H5 页面调试必备的 3 个 Chrome DevTools 技巧
- Network 标签页过滤
xhr:检查plugin.php?id=dwtc_api:...请求是否返回 200,响应体是否含{"code":0,"data":{...}}结构; - Application 标签页查看
localStorage:确认dwtc_token字段存在且未过期(exp时间戳大于当前时间); - Console 执行
weui.alert('test'):验证 WeUI.js 是否成功加载,若报错weui is not defined,说明weui.min.js路径错误或被 Discuz 的common.js覆盖。
3.2 小程序前端构建:避开uniapp开发h5嵌入微信公众号中获取定位的常见陷阱
点微同城 30.0 小程序前端是原生开发,非 UniApp 封装。构建前必须完成三项配置:
在
project.config.json中添加libVersion:"libVersion": "2.25.2",此版本号必须与
dwtc_wxauth插件声明的最低基础库一致,否则wx.getLocation()会静默失败。在
app.js的onLaunch中强制校验登录态:App({ onLaunch() { wx.checkSession({ success: () => { /* session 有效,直接拉取用户信息 */ }, fail: () => { // session 失效,重新登录 wx.login({ success: res => { wx.request({ url: 'https://your-discuz.com/plugin.php?id=dwtc_api:wxlogin', method: 'POST', data: { code: res.code }, success: r => { wx.setStorageSync('token', r.data.token); } }); } }); } }); } });在
pages/index/index.js中处理onPullDownRefresh时的 token 自动续期:Page({ onPullDownRefresh() { const token = wx.getStorageSync('token'); if (Date.now() / 1000 > JSON.parse(atob(token.split('.')[1])).exp) { // token 过期,触发重新登录流程 this.onLoad(); } else { // 正常刷新数据 this.loadList(); } } });
提示:若小程序
wx.request返回request:fail ssl hand shake error,不是证书问题,而是dwtc_api插件的api_domain配置了 HTTP 协议——微信小程序强制 HTTPS,必须改为https://开头。
4. 双端联调排错:定位“H5 能连 WebSocket,打包为 APP 连不了”的根本原因
当 H5 在微信内运行正常,但打包成 APP 后网络请求全部失败,问题几乎 100% 出在客户端网络栈与 Discuz 后端的 TLS 协商层面,而非代码逻辑。点微同城 30.0 的 47 个插件中,只有dwtc_api和dwtc_wxpay涉及 HTTPS 请求,因此排查必须聚焦在这两个插件的 SSL 配置。
4.1 Discuz 后端 SSL 配置的 3 个致命细节
很多团队以为只要 Nginx 配置了 HTTPS 就万事大吉,却忽略了 Discuz 自身对 HTTPS 的感知逻辑:
config/config_global.php中$_config['cookie']['domain']必须为空或精确匹配:
若填'.example.com',H5 在https://m.example.com下可读 cookie,但 APP 内 WebView 访问https://api.example.com时因 domain 不匹配无法携带 cookie,导致dwtc_api接口返回 401。正确做法是留空,让 Discuz 自动根据$_SERVER['HTTP_HOST']设置。source/class/discuz/discuz_application.php第 123 行必须强制识别 HTTPS:
默认 Discuz 依赖$_SERVER['HTTPS']判断协议,但某些负载均衡器(如阿里云 SLB)会将 HTTPS 流量转为 HTTP 到后端,此时$_SERVER['HTTPS']为空。需在此处插入:if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on'; }dwtc_api插件的api_domain必须与 APP WebView 的loadUrl协议严格一致:
若 APP 使用https://m.example.com加载 H5,api_domain却配置为http://api.example.com,Android WebView 会因混合内容(Mixed Content)策略阻止请求。必须统一为https://api.example.com,且该域名需有合法 SSL 证书(Let's Encrypt 证书需包含api.example.comSAN 条目)。
4.1.1 APP 内 WebView 调试的终极方案:抓包定位 SSL 握手失败点
Android APP 内 WebView 的网络请求无法用 Chrome DevTools 查看,必须用抓包工具。推荐方案:
- PC 端 Wireshark + 手机代理:手机 WiFi 设置代理指向 PC 的 IP 和端口(如 8888),Wireshark 过滤
tls.handshake.type == 1,观察 Client Hello 后是否有 Server Hello; - 若无 Server Hello:说明服务器未响应 TLS 握手,检查 Nginx 的
ssl_protocols TLSv1.2 TLSv1.3;是否启用,旧版 OpenSSL 可能不支持 TLSv1.3; - 若有 Server Hello 但后续失败:检查证书链是否完整,用
openssl s_client -connect api.example.com:443 -showcerts验证。
4.2 小程序端wx.request超时的 2 种真实场景与对应参数调整
小程序wx.request默认超时 60 秒,但在点微同城场景下常需更精细控制:
| 场景 | 表现 | 根本原因 | 解决方案 |
|---|---|---|---|
dwtc_shop:list接口耗时 >60s | 小程序白屏,控制台报request:fail timeout | 商家数据量过大,Discuz 查询未加索引 | 在dwtc_shop插件的model/shop.php中,为pre_dwtc_shop表的status和cityid字段添加复合索引:ALTER TABLE pre_dwtc_shop ADD INDEX idx_status_city (status, cityid); |
dwtc_order:create接口偶发超时 | H5 下单成功,小程序下单失败 | dwtc_wxpay插件调用高德 API 获取配送距离时网络抖动 | 在小程序pages/order/create.js中,为wx.request显式设置timeout: 15000:wx.request({ url: '/api/order/create', timeout: 15000, ... }) |
注意:
timeout参数只在基础库 2.10.0+ 支持,低于此版本需降级处理——在fail回调中判断errMsg是否含timeout字符串,然后重试一次。
5. 进阶技巧:用 Discuz 模板机制动态注入小程序所需的数据预加载脚本
点微同城 30.0 的 H5 页面常需在onLoad时立即获取用户位置,但wx.getLocation()是异步的,导致页面闪动。最佳实践是利用 Discuz 的模板变量,在 PHP 层就完成地理围栏计算,将结果直接注入 HTML。
5.1 在dwtc_h5/index.htm中嵌入预计算的商圈数据
修改dwtc_h5插件的模板文件,找到<body>开始处,插入:
<script> // Discuz 模板变量,由 PHP 后端计算得出 const PRELOAD商圈 = {$dwtc_preload商圈|default:'[]'}; const USER_LOCATION = {$dwtc_user_location|default:'null'}; </script>对应地,在dwtc_h5/index.php中,于include template('dwtc_h5/index');前添加:
// 根据用户 IP 或 cookie 中的 last_location,查询最近 3 个商圈 $ip = $_SERVER['REMOTE_ADDR']; $商圈数据 = DB::fetch_all("SELECT id,name,lng,lat FROM ".DB::table('dwtc_business_district')." WHERE distance < 5000 ORDER BY distance LIMIT 3"); $商圈JSON = json_encode($商圈数据); // 注入模板变量 $tpl->assign('dwtc_preload商圈', $商圈JSON); // 若用户已授权位置,则直接注入 if ($user_location = dwtc_get_user_location()) { $tpl->assign('dwtc_user_location', json_encode($user_location)); } else { $tpl->assign('dwtc_user_location', 'null'); }这样,H5 页面加载时PRELOAD商圈已是可用数组,无需等待wx.getLocation(),大幅提升首屏体验。而小程序端仍走标准wx.getLocation()流程,保持精度——双端策略差异,恰是点微同城 30.0 插件体系的设计哲学:H5 重速度与兼容性,小程序重精度与原生能力。
本文还有配套的精品资源,点击获取