招采订阅与推送说明

招采订阅与推送 — 流程、规则与操作说明

适用版本:本站当前实现(PushServiceshop_dingyue 招采订阅、by_tender_info 招标表)
最后更新:2026-06-01

1. 功能概览

招采推送用于:当平台出现新的招标/采购信息时,按用户订阅条件(城市、标题关键词、通知渠道),向匹配用户发送短信、站内信、邮箱等通知。

模块作用
用户招采订阅用户配置「收哪些城市、哪些关键词、用什么渠道收」
招标数据采集入库、商家发布、后台发布,写入 by_tender_info
推送服务Banyan/Lib/Service/PushService.class.php 统一匹配订阅并发送
后台管理招标列表、手动按渠道补推、订阅审核列表

2. 核心数据表

2.1 招采订阅 by_shop_dingyue

招采订阅通过固定字段区分(与生活信息、商家资讯订阅共用一张表):

字段招采含义
channel_id固定 100(招采订阅)
catlist固定 tender
uid订阅用户 ID
city_id订阅城市;0 = 不限城市(全国)
province_id省份(选具体城市时有效)
sitelist城市串,招采为 城市ID,0,00,0,0
tender_keywords标题关键词,逗号/中文逗号分隔;空 = 不限关键词
channel_sms / channel_weixin / channel_msg / channel_email各渠道开关(1 开启)
audit1 已审核才参与推送;0 待审核不参与
status≥0 有效;-1 等视为无效

2.2 招标信息 by_tender_info

字段说明
tender_id主键
type1=采集 2=商家发布 3=平台/后台发布
status1=已发布 才可推送;0 草稿;-1 删除
city_id / city_name地区(采集时尽力解析)
title标题
content / content_summary正文与摘要(关键词匹配会查标题+摘要+正文
is_tuisong_sms各渠道是否已推送及推送时间

3. 推送方式(两种)

flowchart TB
    subgraph 数据来源
        A1[采集入库 TenderCollectService]
        A2[商家发布 Merchant/Distributors Tender]
        A3[后台发布 Backstage Tenderinfo publish]
    end

    subgraph 自动推送
        B[PushService::triggerAutoPush]
        C[pushTender 四渠道: sms/weixin/msg/email]
    end

    subgraph 手动推送
        D[后台 tenderinfo/index 点击推送链接]
        E[pushTender 单渠道]
    end

    A1 --> B
    A2 --> B
    A3 --> B
    B --> C

    D --> E

3.1 自动推送(默认)

触发时机(招标 status=1 且入库/发布成功后):

场景代码位置
采集新增一条TenderCollectService 入库成功后 triggerTenderAutoPush
商家后台发布Merchant/TenderAction::createstatus=1
公司手机后台发布Distributors/TenderAction::createstatus=1
后台新建且已发布Backstage/TenderinfoAction::create
后台点击「发布」Backstage/TenderinfoAction::publish(单条/批量)

行为

  • 调用 PushService::autoPushTender($tender_id)
  • 一次尝试四个渠道:smsweixinmsgemail
  • 每个用户只走其订阅里勾选的渠道(见下文匹配规则)
  • 无匹配订阅人:静默结束,写日志 [TenderAutoPush],不弹错给操作者
  • 有匹配人但全部发送失败:记日志,不阻断采集/发布主流程

3.2 手动推送(运营补推)

入口:后台 → 招标信息管理 → 列表操作列

链接方法渠道
短信推送tenderinfo/sms仅短信
微信推送tenderinfo/weixin仅微信
站内信推送tenderinfo/msg仅站内信
邮箱推送tenderinfo/email仅邮箱

行为

  • 同样走 PushService::pushTender
  • 若无匹配订阅用户,页面报错:「没有匹配该城市/关键词的订阅用户」
  • 推送成功会更新 is_tuisong_* 标记与时间

4. 订阅匹配规则(推送前筛人)

实现类:PushService::buildTenderRecipients()

4.1 订阅记录前置条件

同时满足才进入候选列表:

  • channel_id = 100
  • catlist = 'tender'
  • status >= 0
  • audit = 1(待审核订阅不会收到推送)
  • 对应 uidusers 表存在

4.2 城市匹配

订阅 city_id招标 city_id是否匹配
0(不限城市)任意
具体城市 A0(未识别)
具体城市 A同 ID A
滁州市来安县等下属区县✅(区县通过 area 表反查所属 city_id,归入地级市)
滁州市合肥等其他市

说明:

  • 订阅「不限城市」:接收全国招标(仍受关键词约束)。
  • 招标未标城市:对所有已选具体城市的订阅都视为可匹配(与「不限城市」订阅一起参与关键词筛选)。

4.3 关键词匹配(标题 + 摘要 + 正文)

  • 读取订阅字段 tender_keywords
  • 留空:不限制关键词,该订阅对所有通过城市筛选的招标均可收通知
  • 有内容:将 ;、空格等规范为英文逗号后拆分,任意一个词在招标 titlecontent_summarycontent 任一字段中出现即匹配(不区分大小写)

示例:

  • 关键词:保安,物业,安保
  • 标题:滁州市某某保安服务项目招标公告 → ✅(含「保安」)
  • 标题:某某项目采购公告、正文含「物业」 → ✅

4.4 渠道分配

通过城市+关键词后,total 计数 +1,再按本次推送请求的渠道列表与用户订阅开关分配:

渠道订阅字段额外条件
短信channel_sms=1用户有手机号;短信额度等见 PushService 配额逻辑
微信channel_weixin=1招采微信推送当前为占位,返回「未实现招采微信推送」
站内信channel_msg=1写入 msg
邮箱channel_email=1用户有邮箱

自动推送一次请求包含四渠道;用户只会收到自己勾选且满足条件的渠道。


5. 用户订阅 — 操作流程

5.1 手机端(Wap)

路径:我的 → 订阅设置 → 招采订阅(或 shopdingyue/settingssubscribe_type=tender

  1. 所在城市:可选具体城市,或选 「不限城市(全国)」
  2. 标题关键词:如 保安, 物业, 安保留空表示不限
  3. 通知方式:至少勾选一种(短信需先购买短信余额)
  4. 提交 → 写入/更新 shop_dingyue

控制器:Banyan/Lib/Action/User/ShopdingyueAction.class.phphandleTenderSubscribe()

5.2 电脑端商家会员(Members)

路径:商家中心 → 招采订阅shopdingyue/basesubscribe_type=tender

字段与规则与 Wap 相同。控制器:Members/ShopdingyueAction.class.php

5.3 订阅去重与更新

同一用户、同一 city_id、同一 tender_keywords 视为一条订阅;再次提交则更新渠道开关,不重复插多条。

5.4 订阅数量限制

若后台配置了 shop_dingyue_set.count_number,超过上限的新订阅可能 audit=0 待审核,审核通过前不会参与推送


6. 后台运营 — 操作流程

6.1 招标信息管理

路径:后台 → 招标信息管理(Backstage/Tenderinfo

  • 列表查看采集/商家/平台招标
  • 编辑、发布、下架、删除
  • 手动推送:短信 / 微信 / 站内 / 邮箱(见 3.2)
  • 已推送渠道会显示推送时间,避免重复点(仍可通过未推送渠道补推)

6.2 招采订阅审核列表

路径:后台 → 订阅相关 → 招标采购订阅列表Shopdingyue/tenderlist

  • 筛选 channel_id=100catlist=tender
  • 查看用户、城市(city_id=0 显示「不限城市」)、关键词、渠道、审核状态

6.3 采集任务

路径:后台 → 招标采集(Tendercollect

  • 配置采集源、手动/定时采集
  • 每新增一条已发布招标 → 自动触发招采推送(无订阅匹配则仅写日志)

7. 招标数据来源与 city_id

来源type发布状态自动推送
采集1入库时 status=1
商家2创建时 status=1
后台3创建/发布 status=1

采集时 city_id 来源(TenderCollectService::deriveTenderFields):

  1. 接口字段 areaname / areacode 映射
  2. 标题中提取「XX市/县/区」
  3. city 表名称精确匹配得到 city_id

若解析为县/区 ID,推送匹配时会尝试归入对应地级市,以便「滁州市」订阅能收到下属区县招标。


8. 日志与排查

8.1 自动推送日志

  • 关键字:[TenderAutoPush]
  • 位置:ThinkPHP 日志(如 Runtime/Logs/
  • 内容:tender_id、成功与否、说明信息

8.2 手动推送失败常见原因

提示原因
没有匹配该城市/关键词的订阅用户audit=1 订阅通过城市+标题关键词筛选
仅已发布的招标信息可推送status≠1
推送失败:所有渠道均未成功发送有匹配人但短信/邮箱等发送失败
微信相关招采微信渠道未实现,可改用站内/邮箱/短信

8.3 排查清单(以用户「滁州 + 保安,物业,安保」为例)

  1. 后台 tenderlist 确认该用户订阅 audit=1,渠道已勾选
  2. 打开待推招标,看 city_id 是否为滁州或下属县(或 0)
  3. 看招标 标题/摘要/正文 是否包含保安/物业/安保之一
  4. 站内信/邮箱:用户资料是否完整
  5. 短信:是否购买短信、余额是否足够

9. 相关代码文件索引

文件说明
Banyan/Lib/Service/PushService.class.php招采推送核心:匹配、发送、自动推送入口
Banyan/Lib/Service/TenderCollectService.class.php采集入库 + 自动推送触发
Banyan/Lib/Action/User/ShopdingyueAction.class.phpWap 招采订阅
Banyan/Lib/Action/Members/ShopdingyueAction.class.phpPC 商家招采订阅
Banyan/Lib/Action/Backstage/TenderinfoAction.class.php后台招标 + 手动推送 + 发布自动推送
Banyan/Lib/Action/Merchant/TenderAction.class.php商家招采发布 + 自动推送
Banyan/Lib/Action/Distributors/TenderAction.class.php公司手机后台招采发布 + 自动推送
Banyan/Lib/Action/Backstage/ShopdingyueAction.class.php招采订阅审核列表
themes/default/User/shopdingyue/settings.htmlWap 招采订阅表单
themes/default/Members/shopdingyue/base.htmlPC 招采订阅表单
themes/default/Backstage/tenderinfo/index.html手动推送入口

10. 规则速查表

项目规则
谁可收推送shop_dingyue 招采订阅且 audit=1
城市city_id=0 全国;否则市/县匹配及区县归市
关键词标题+摘要+正文;空=不限
何时自动推采集新增、商家发布、后台发布成功
何时手动推后台列表点渠道链接
微信招采暂未实现
重复推送自动推送不查历史;手动推送会更新 is_tuisong_* 标记

11. 修订记录

日期说明
2026-06-01增加自动推送;城市可选全国、区县归市;关键词匹配标题+摘要+正文;后台 fw 页增加说明
copyright 2013-2113 www.baoanfuwu.cn All Rights Reserved 保安服务网版权所有
皖ICP备2021016109号-1