jionsoft

无论是开发app还是网站,可能都需要一个广告功能,比如我们常见的在首页有个轮播广告,里面会轮播显示多个图片。还有比如一个新闻门户网站 很常见的 banner横幅广告,还有js特效广告等。本篇说说在abp(5.9)中如何实现广告模块。

源码地址:https://gitee.com/bxjg1987/abp 基于abp一代5.9版
在线演示:http://git.weilaikj.cn/  账号密码 admin  123qwe

广告位

它代表某个页面上,某个位置,比如:首页顶部用来放轮播广告那个位置。再比如:新闻列表页右侧广告位。广告位有个名字属性,还有尺寸相关的属性

广告控件

它是在页面用来展示广告的页面组件定义,比如:图片轮播控件。再比如:静态图片展示控件。

这里的控件只是定义某个控件,在数据库表中就是一条记录,定义了控件名、控件类型(轮播、静态图、普通文本)、控件参数等属性。前端可以根据这些数据来定义界面。因为可能有不同的前端,就算同样是pc网站前端,我也无法限制你将来用什么样的形式来展现一个轮播图片的控件。所以我只能把后台定义的轮播图片控件的相关参数给你,至于如何使用这些参数来显示轮播控件,只能由你来实现了。

广告

它就表示一个广告,这就代表广告主将来要投放的广告。比如客户提供的一张图片。它有广告标题、广告类型(是图片?文本?一段html?一段js?)广告内容(比如是图片类型广告,则它存储图片的url)、URL(点击广告时要跳转到哪去)

广告发布记录

它是上面3个概念的多对多关系的建立,它是一条广告发布记录。什么时候,发布哪个广告,使用什么样的控件,发布到哪几个广告位。如:有个图片广告 要显示到 首页轮播控件中,同时显示到新闻列表页右侧,用静态图片广告控件展示

广告 与 广告发布记录 合并

目前没有这样处理,不过可以说说思路。广告、广告位、广告控件,最后通过广告发布记录将它们多对多关联,这样的设计非常灵活。但是也相对复杂。可以考虑将广告和广告发布记录合并,这样就没那么灵活了,比如同一个广告要同时发布到多个广告位(首页和列表页和内容页,甚至是多个栏目的不同位置都有同时显示某个广告)。或者同一个广告要用不同的控件展示时。合并这俩概念要实现前面说的这种需求,就需要将同一个广告多次发布,其实本质上就是两个广告,只是广告内容一样

cms模块中的广告源码简述

首先在CMS/BXJG.CMS.Core/Ad中建立上面各概念对应的实体类:广告位(AdPositionEntity)、广告控件(AdControlEntity)、广告(AdEntity)、广告发布记录(AdRecordEntity)等实体

然后在CMS/BXJG.CMS.EFCore/EFMaps中建立相应的ef映射文件 xxMap.cs

然后在CMS/BXJG.CMS.Application/Ad中建立应用服务接口及实现,当然还有对应的dto对象。这里需要注意,系统管理员需要在管理后台对广告进行管理,比如定义广告位、对广告的增、删、改、查、发布、撤销等操作。网站或app或小程序前台展示广告时则是不需要用户登录的,匿名用户应该也可以看到这些广告。所以这里将 分别定义后台和前端对广告的处理对应的接口,而不是定义在同一个接口中。具体来说IBXJGCMSFrontAdRecordAppService是专门给前端用的接口,里面只包含对广告的查询功能。IBXJGCMSAdAppService则是给后台对广告进行管理的接口,里面包含对广告的增、删、改、查、发布撤销等,不过写文章时此接口和实现还没有做。

下面按abp的套路定义权限和菜单

到此cms模块中的广告功能基本定义完成。

如何集成到主程序

上面大致说了下cms模块中的广告功能相关源码。在我们的项目中模块与主程序尽量独立。CMS是我们定义的一个内容管理模块,广告只是下面一个功能。源码中的ZLJ.XXX是我们的主程序。这个主程序会来集成不同的模块,广告模块就是其中之一。你也可以在你的abp项目中来单独引入这个广告模块,只是目前这个模块没有发布成nuget包。

下面说说如何在我们主程序中使用cms模块中的广告功能

在ZLJ.EntityFrameworkCore/EntityFrameworkCore/ZLJDbContext中定义广告相关实体的 DbSet

public virtual DbSet<AdEntity> BXJGCMSAds { get; set; }
public virtual DbSet<AdControlEntity> BXJGCMSAdControls { get; set; }
public virtual DbSet<AdPositionEntity> BXJGCMSAdPositions { get; set; }
public virtual DbSet<AdRecordEntity> BXJGCMSAdRecords { get; set; }

此时进入api页面可以看到广告服务接口https://git.weilaikj.cn/swagger/index.html,可以测试了。(打开页面,Ctrl + F搜索"BXJGCMSFrontAdRecord")

在主程序中集成模块时,手动在主程序的DbContext中定义DbSet比较繁琐,网上有动态向DbContext加入DbSet的方法,著名的微信库Senparc的SCF应该就是那种方式,不过我还不会。还有一个原因,有时候我们需要主程序在集成模块注册DbSet时提供实体泛型参数,手动方式最直观。(动态DbSet应该也可以指定实体泛型参数)

由于广告模块足够简单,它不需要引用主程序的某些概念,也没有考虑给模块调用方提供扩展广告、广告位、广告控件等的能力,因此在主程序集成广告功能就很简单。如果将来考虑允许模块调用方通过继承的方式,来为广告添加更多自定义属性,可以考虑在广告相关的应用服务中,将广告(AdEntity)变成泛型的。将来由模块调用方来提供一个继承至AdEntity的子类

另一种情况是模块内部需要引用主程序的提供的一些概念时,比如 AdEntity中需要引用主程序中的XXX类,作为导航属性,那么AdEntity本身就需要定义成泛型的AdEntity<xxx>,这样模块内部就不要直接依赖主程序的某个类,而是由将来主程序调用时指定

这里说的两种情况后续会专门写一篇来介绍,目前shop文件夹中相关源码已有体现。

前端处理

通过IBXJGCMSFrontAdRecordAppService接口,前端页面可以获取当前发布的广告信息,里面包含了广告位、广告控件、广告、发布相关属性,前端可以根据这些数据*控制前端广告的展示。这部分功能模块没有也很难提供。

结束

这里简单介绍了下项目中设计的abp cms模块中的广告功能,这个设计参考了部分cms系统,目前只有个骨架,后续会逐步完善。目前项目中类似的模块还有几个,没来得及写说明。后续再补充吧。希望找到热爱abp的朋友,一个做模块,互相分享,因为我们可能在做一样的功能,没必要重复劳动。

目前的目标是开发常用,简单、实用,不考虑扩展性的模块,将来逐步实现扩展性  

 

相关文章: