发表日期: 2021-04-27 08:55:26 浏览次数:154
邳州小程序制作【邳州企业邮箱】邳州网站外包、邳州微信商城开发、邳州网店美工、邳州淘宝设计
邳州,简称“邳”,江苏省徐州市代管县级市, [1-2] 古称良城、邳国、下邳、邳县,位于苏鲁交界,东接新沂市,西连徐州市铜山区、贾汪区,南界睢宁县,北邻山东省兰陵县。 [3] 1992年撤县设市。
邳州历史悠久,境内大墩子文化遗址距今6000年,是江苏文明最早的起源之一。境内有邳州市艾山风景名胜区、沙沟湖水杉公园、国家银杏博览园、小萝卜头纪念馆等旅游景点。邳州的城市精神是“创新、争先、开放、包容”。 [4]
邳州发展的目标是东陇海产业带重要的水陆交通枢纽、新兴工贸城市,京杭运河沿岸具有水乡特色和历史文化底蕴的生态宜居城市。
2019年7月,邳州入选国家知识产权强县工程试点县(区)。2019年,邳州位居全国综合实力百强县市第37位、经济竞争力百强第40位、全国投资潜力百强县市第18位、全国绿色发展百强县市第33位、全国科技创新百强县市第36位、全国新型城镇化质量百强县市第51位。
按照基类在模板方法下定义的流程步骤,首先需要实现检测判断用户是否满足推送每周营养计划的条件。
// Family-2.0$ vim ./Apps/Scale/Domain/SPush/Week.php <?phpclass Domain_SPush_Week extends Domain_SPushBase {
/**
* 验证用户是否满足推送的业务要求
*/
protected function varidateInfo($infoEx) {
if ($infoEx['gender'] != Domain_SInfo::GENDER_FEMALE) {
return false;
}
if ($infoEx['type'] != Domain_SInfo::TYPE_PREGNANT) {
return false;
}
... ...
if ($infoEx['expect_born_date'] <= 0 || $infoEx['expect_born_date'] < $_SERVER['REQUEST_TIME']) {
return false;
}
if ($infoEx['weight_before_born'] <= 0) {
return false;
}
return true;
}}复制代码由于推送的目标用户人群是孕妇,因此在前面判断了是否为女性,且为孕妇。中间省略部分的代码,进行了更多信息的合法性检测,避免对错误或不齐全的用户进行错误的推送。最后,还判断了预产期等数据的有效性。
接下来,就是关键的发布动态这一推送实现过程。
// Family-2.0$ vim ./Apps/Scale/Domain/SPush/Week.php
/**
* 发布动态
*/
protected function postFeed($userId, $infoEx, $toPushWeekGroupId) {
$weekth = $this->getWeekth($infoEx);
$weekCfg = DI()->config->get('push.week');
//体重与文案
$nextWeekNeedCAL = 0;
$nextWeekContent = '';
$lastWeekWeight = $this->getLastWeekWeight($userId);
if ($lastWeekWeight <= 0) {
//上周无秤重
... ...
} else {
//上周有秤重
... ...
}
//选择一个合适的食谱
$domainNutritionRecipe = new Domain_Nutrition_SRecipe();
$recipeId = $domainNutritionRecipe->extractRandomOneByCalorie($nextWeekNeedCAL);
if ($recipeId <= 0) {
return false;
}
$domainFeed = new Domain_Feed();
$postUserId = DI()->config->get('app.NPC.week_push.userId');
$typeStruct = json_encode(
array(
'content_type' => $weekCfg['content_type'],
'recipe_id' => $recipeId,
'week_num' => $weekth,
'url' => sprintf($weekCfg['jump_url'], $recipeId, $weekth),
)
);
$feedId = $domainFeed->postBaseFeed($postUserId, $toPushWeekGroupId, $nextWeekContent, 0, 0, 'web', $typeStruct);
//动态图片
if (!empty($weekCfg['pics']) && is_array($weekCfg['pics'])) {
$domainFeed->attachFeedPics($feedId, $weekCfg['pics']);
}
return true;
}复制代码上面是精简后的实现代码片段。这段代码比较有意思,因为它的过程也是有规律可循的。在最前面,先获取当前用户的周数以及相关的配置信息,随后获取用户上周的体重历史数据。根据上面的体重情况,算出CAL后,便来到了核心的部分:选择一个合适的食谱。如果这时没有合适的食谱,那么返回FALSE表示失败。如果有合适的食谱,那么就进行推送操作。这时,准备好待推送的数据后,委托给Domain_Feed动态领域业务类进行发布,并且如果有动态图片资源的话,则附上相关的图片。最终用户就可以看到类似图6-8这样的推送效果了!
Domain_SPushBase抽象蕨类有两个抽象方法,现在我们实现了其中一个,另外一个则是非常简单的。它主要的作用是用于辅助纪录对于各种推送,每个用户推送的情况,避免重复推送。因此需要一个唯一的标识来作区分。以下是每周营养计划推送中的实现代码。
// Family-2.0$ vim ./Apps/Scale/Domain/SPush/Week.php
/**
* 推送纪录类型
*/
protected function getPushRecordType($infoEx) {
return sprintf('week_%s', $this->getWeekth($infoEx));
}复制代码每周营养计划推送是固定周期的推送,让我们再来看一个触发推送的示例。例如,当准妈妈第一次使用营养称时,为了指供新人指引以及表示欢迎,可以进行一次场景推送。因为此场景推送的实现比较简单,以下是全部实现的代码片段。
// Family-2.0$ vim ./Apps/Scale/Domain/SPush/SpecialSceneWelcome.php<?phpclass Domain_SPush_SpecialSceneWelcome extends Domain_SPushBase {
protected function varidateInfo($infoEx) {
return $infoEx['type'] == Domain_SInfo::TYPE_PREGNANT;
}
protected function postFeed($userId, $infoEx, $toPushWeekGroupId) {
$specialCfg = DI()->config->get('push.special_scene.6');
$domainFeed = new Domain_Feed();
$postUserId = DI()->config->get('app.NPC.special_scene.userId');
$typeStruct = json_encode(
array(
'content_type' => 6,
'url' => $specialCfg['jump_url'],
)
);
$content = $specialCfg['content'];
$feedId = $domainFeed->postBaseFeed($postUserId, $toPushWeekGroupId, $content, 0, 0, 'web', $typeStruct);
if ($feedId > 0 && !empty($specialCfg['pics']) && is_array($specialCfg['pics'])) {
$domainFeed->attachFeedPics($feedId, $specialCfg['pics']);
}
return $feedId > 0;
}
protected function getPushRecordType($infoEx) {
return 'ss_welcome';
}}复制代码可以看到,虽然是不同的推送实现,但其实现是类似的,特别在发布动态过程中,也是先获取配置信息,委托给Domain_Feed领域业务类进行动态的发布,最后返回是否成功推送的布尔值。这样既有利于不同功能的快速开发,因为可以重用通用的功能,又可以达到风险隔离、封装变化,即各个业务线独立变化,互不干扰。我觉得,这是一种好的设计,而且事实上它也工作得非常好。
在本小节中,我们先是研究了如何收集用户上报的体重数据,接着学习了如何使用模板方法设计模式进行不同场景下的推送操作。现在,我们有了体重这一基础数据,也实现了推送功能。那么,接下来的问题是,我们该如何调度执行这些推送操作呢?显然,推送有两大类,一类是定时的推送,如每日、每周、每月推送;一类是触发的推送,如欢迎新用户。既然推送的时机随时都有可能发生,而且是属于耗时的操作,更为重要的是,不管用户是否上线使用App,都应该能为其进行推送。因此,一个不错的方案就是通过后台异步的计划任务对推送进行调度。如前面所述,我们使用了Task计划任务扩展类库。假设Task已经安装部署完毕,下面重点来看下如何实现具体的调度业务。
在开始编写计划任务之前,有一些事情是需要明确的。提前考虑到这些问题,可以避免错误的设计,同时提高开发的效率。首先,,调用上面开发好的推送接口,是通过远程接口服务调度,还是直接本地调度?其次,也是比较关键的问题,就是待消费的MQ数据从哪里来,又存在哪里?
上面第一个问题,比较容易解决,把计划任务的接口服务放在我们上面所说的Task项目中,并且通过本地的方式进行调度。因此也就不需要对外提供访问入口。注意这里的Task项目目录不是指扩展类库的Task目录。剩下第二个问题,则需要一步步编写代码实现了。例如,对于每周营养计划的推送,首先要从数据库的用户表中筛选出候选用户,然后可以把候选用户放进内存数组MQ中,最后进行消费。
Task扩展类库有一个通用的触发器,但基于我们现在特定的业务场景,由于已经可以确定使用本地调度、内存数组MQ和特定的接口服务,所以可以自定义实现更能与当前业务场景的触发器。

邳州小程序制作【邳州企业邮箱】邳州网站外包、邳州微信商城开发、邳州网店美工、邳州淘宝设计