精华内容
下载资源
问答
  •  复制下面代码到你自己要展示广告条的 Activity 的 layout 布局文件中,并放在适当的位置:      android:id="@+id/adLayout"  android:layout_width="fill_parent"  android:layout_height=...

    1、导入 SDK

    将 lerdian_SDK 文件导入到工程指定的 libs 目录。

    2、权限配置

    请将下面权限配置代码复制到 AndroidManifest.xml 文件中 :

    <uses-permission android:name="android.permission.INTERNET" />

    <uses-permission android:name="android.permission.CALL_PHONE"/>

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    <uses-permission android:name="android.permission.GET_TASKS" />

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    <uses-permission android:name="android.permission.WRITE_SMS"/>

    广告组件配置

    调用广告时请将以下配置代码复制到 AndroidManifest.xml 文件中(注:必须添加在<application></application>节点中,应用秘钥请到乐点网站后台获取):

    <meta-data

                android:name="LERDIAN_CHANNEL"

                android:value="应用秘钥" />

     <activity android:name="com.lerdian.advertisement.AdWebViewActivity" />

     

    若调用开屏广告,还需要在调用全屏广告的Activity节点中添加属性:android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

    android:screenOrientation="portrait" 

    开屏插屏广告

    启动开屏初始化时在onCreate方法中调用以下方法:

    第一个true 为显示关闭按钮 ,false为不显示关闭按钮

    第二个true 为一小时显示一次开屏广告,false为不做限制

    AdScreenManager.getInstance(this).showFullScreen(true,true);

    启动插屏初始化时在onCreate方法中调用以下方法:

    AdSpotManager.getInstance(this).showSpot(true);

    banner广告

     (1).广告条尺寸大小

        AdSize提供了6中广告尺寸大小给开发者 :

    * AdSizeManger.WRAP_CONTENT    // 自适应屏幕宽度

    * AdSizeManger.SIZE_320x50   // 手机

    * AdSizeManger.SIZE_300x250  // 手机,平板

    * AdSizeManger.SIZE_468x60   // 平板

    * AdSizeManger.SIZE_600x90   //平板

    * AdSizeManger.SIZE_728x90   // 平板

     

    (2).嵌入广告条

     

        2.1布局(适用于应用)

     

        1)配置布局文件

      复制下面代码到你自己要展示广告条的Activitylayout布局文件中,并放在适当的位置:

     

          <LinearLayout

            android:id="@+id/adLayout"

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:orientation="horizontal"

            android:layout_alignParentBottom="true"

            android:gravity="center_horizontal">

          </LinearLayout>

     

        2)将AdBannerView添加到

        在展示广告的Activity onCreat()方法中,添加如下代码:

     

        // 实例化广告条

    //True为显示关闭按钮,false为不显示关闭按钮

    AdBannerView  adView = new AdBannerView(this, AdSizeManager.WRAP_CONTENT,true);

     

        // 获取要嵌入广告条的布局

        LinearLayout adLayout=(LinearLayout)findViewById(R.id.adLayout);

     

        // 将广告条加入到布局中

        adLayout.addView(adView );

     

     

     

        2.2)悬浮式布局(适用于游戏)

     

    在展示广告的Activity onCreat()方法中,添加如下代码:

    //True为显示关闭按钮,false为不显示关闭按钮

        // 实例化 LayoutParams(重要)

     

    FrameLayout.LayoutParams layoutParams= new FrameLayout.LayoutParams( FrameLayout.LayoutParams.FILL_PARENT,

        FrameLayout.LayoutParams.WRAP_CONTENT);

     

        // 设置广告条的悬浮位置

        layoutParams.gravity = Gravity.BOTTOM ; // 这里示例为下边

     

        // 实例化广告条

    AdBannerView  adView  = new AdBannerView(this, AdSizeManager.WRAP_CONTENT,true);

     

        // 调用 Activity 的 addContentView 函数

        this.addContentView(adView, layoutParams);  

     

        (3).广告条监听接口(必写)

     

        乐点SDK 提供给有需要的开发者使用广告条监听接口,用于监听广告条的状态

     

        // 监听广告条接口

            adView.setAdListener(new AdViewListener() {

                @Override

                public void onSwitchAd(AdBannerView view) {

                    Log.i("LerdianAdDemo", "广告条切换");

                }

     

                @Override

                public void onReceivedAdFinished(AdBannerView view) {

                    Log.i("LerdianAdDemo", "请求广告成功");

                }

     

                @Override

                public void onFailedReceivedAd(AdBannerView view) {

                    Log.i("LerdianAdDemo", "广告条切换");

                }

            });

    6、混淆配置

    如果您的项目使用了 Proguard 混淆打包,为了避免 SDK 被二次混淆导致无法正常获取广告,请务必在 proguard-project.txt 中添加以下代码:

    -dontwarn com.lerdian.**
    -keep class com.lerdian.** { *; }

    并在 project.properties 中指向Android混淆文件

    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

     

     

     

    展开全文
  • 灰色系摄影影集展示广告落地页网站html模板
  • 类广告的介绍及优势

    2019-03-22 16:24:00
    展示类广告,就是一种按每千次展示计费的图片形式的广告,可以投放在博客页面和网页中,这种广告可以统称为CPM广告。展示广告当前比较成熟的两种方式:一种是Google Adsense的按点击付费,一种是常见的按展示付费。 ...

    展示类广告,就是一种按每千次展示计费的图片形式的广告,可以投放在博客页面和网页中,这种广告可以统称为CPM广告。展示广告当前比较成熟的两种方式:一种是Google Adsense的按点击付费,一种是常见的按展示付费。

           展示类广告的展现形式多种多样,包含了视频,贴片,动态网幅,交互式,插播式等等,其中视频,贴片广告较为常见,广告的优点也十分鲜明。

      1、确定到达:其它类型的展示类广告会出现在页面上,但不一定会被用户看到。而视频贴片广告中的前贴片广告则基本可以确定打开这段视频的人都会看到,因为要看视频必须先看一段贴片广告,所以基本可以以视频播放次数来估算广告被观看的次数,以观看该视频的人数、人群特征来估算广告触达的人数及人群特征。  

      2、信息传达更丰富:因为是视频广告的形式,就像电视广告一样,可以完整的讲述一个故事,生动的展示一次品牌形象,通过声音、影像等丰富的媒介来传达信息。广告内容可以更直接,透明地显现给用户,相比起用几个文字、一张图片、一段动画,都不如视频广告更有效。
      3、多种模式互动:因为都是视频广告形式,与线下电视广告是一样的,两者是互通的。

           由此可见,展示类广告已经被广泛应用,在不久的将来将会处于广告领导趋势。

    转载于:https://www.cnblogs.com/fengzifengfeng/p/10579072.html

    展开全文
  • 切记联系前文中简述的 数据表的关系 三级分类中的数据返回构造: 参照这个图片,看下面的数据结构: 这是一个难点,最主要的就是以一个好的形式将数据传递,使用 ... "1":{ # 这个数字key, 就是代表的 tb_...

    切记联系前文中简述的 数据表的关系

    三级分类中的数据返回构造:

    • 参照这个图片,看下面的数据结构:
      在这里插入图片描述

    • 这是一个难点,最主要的就是以一个好的形式将数据传递,使用

    {
        "1":{   # 这个数字key, 就是代表的 tb_channel_group 表当中的频道 
            "channels":[
            	# 这个就是一行,每个频道中包含的一级分类 
                {"id":1, "name":"手机",   "url":"http://shouji.jd.com/"},
                {"id":2, "name":"相机", "url":"http://www.itcast.cn/"}
            ],        
            "sub_cats":[
                {
                	# 这是每个一级分类对应的二级分类
                    "id":38, 
                    "name":"手机通讯", 
                    "sub_cats":[
                    	# 每个二级分类对应的三级分类信息
                        {"id":115, "name":"手机"},
                        {"id":116, "name":"游戏手机"}
                    ]
                },
                {
                    "id":39, 
                    "name":"手机配件", 
                    "sub_cats":[
                        {"id":119, "name":"手机壳"},
                        {"id":120, "name":"贴膜"}
                    ]
                }
            ]
        },
        "2":{
            "channels":[],
            "sub_cats":[]
        }
    }
    
    • 下面是具体实现的代码:
    def get_categories():
        # 查询分类数据,每个元素包含两个数据:一级分类列表。二级分类列表(里面含三级分类)
        '''
        categories={
        1: {
            channels:[{name:***, url:***}....],  # 一级分类,某些一级分类属于同一频道
            sub_cates:[sub{},....],   # 二级分类,里面是三级分类
        },
        {}, {}, {}, .....
        }
        '''
        # 1. 查询所有的频道
        channel_list = GoodsChannel.objects.order_by('group_id', "sequence")  # 前面一个排序是判断在一个频道,后面一个是判断,一个频道中 谁在前面,谁在后面排列
        categories = {}
        # 遍历频道,添加分类信息
        for channel in channel_list:
            # 判断频道是否已经存在
            if channel.group_id not in categories:
                # 不存在则新建频道
                categories[channel.group_id] = {
                    'channels': [],
                    'sub_cats': []
                }
            # 添加一级分类, 二级分类
            categories[channel.group_id]['channels'].append({'url': channel.url, 'name': channel.category.name})
            # 添加二级分类:通过一级分类的对象关联找到对应的二级和三级分类
            for sub2 in channel.category.subs.all():
            	# 这里的做法是后续的更改了。和上面的结构不一样, 直接是加入了一个 二级分类对象,它的一个属性含有三级分类对象,因为是前后端不分离开发,可以传递对象。
                sub2.sub_cats = sub2.subs.all()  # 获取二级分类对应的三级分类,动态给二级分类对象增加这个属性
                categories[channel.group_id]['sub_cats'].append(sub2)
    
        return categories
    
    • 大致思路就是这样! 注释是那么的清晰~ 希望你能理解,不懂就要多看看上节的数据表分析。

    首页广告展示:

    直接上代码:这一部分逻辑要简单很多

    def get(self, request):
            # 2. 查询所有广告分类(广告位),我们之前讲的,广告分类,因为广告有很多投放位置
            content_category_list = ContentCategory.objects.all()
            # 构造广告字典
            '''
            {广告位标识:[广告1,....]}
            '''
            contents = {}
            # 遍历广告分类,找到每个分类中需要展示的广告即可,这里也是不分离。 分离也很容易,把查出来的对象再次遍历,组成所需数据结构即可~
            for content_category in content_category_list:
                # 查询出一个广告位,对应的所有广告内容
                contents[content_category.key] = content_category.content_set.all().order_by('sequence')
    
    

    总结下来,实际上还是数据表的设计比较复杂。代码只要掌握一些技巧,知识构造数据结构。其实多写起来并不难。

    over!

    展开全文
  • 商品分类&轮播广告 因最近又被困在了OSGI技术POC,更新进度有点慢,希望大家不要怪罪哦。 上节 我们实现了登录之后前端的展示,如: 接着,我们来实现左侧分类栏目的功能。 ## 商品分类 ProductCategory 从上...

    商品分类&轮播广告

    因最近又被困在了OSGI技术POC,更新进度有点慢,希望大家不要怪罪哦。

    上节 我们实现了登录之后前端的展示,如:登录展示效果子分类

    接着,我们来实现左侧分类栏目的功能。

    ## 商品分类 ProductCategory

    从上图我们可以看出,商品的分类其实是有层级关系的,而且这种关系一般都是无限层级。在我们的实现中,为了效果的展示,我们仅仅是展示3级分类,在大多数的中小型电商系统中,三级分类完全足够应对SKU的分类。

    需求分析

    ---

    先来分析分类都包含哪些元素,以jd为例:京东分类

    • logo(logo) 有的分类文字前面会有小标
    • 分类展示主图(img_url)
    • 主标题(title)
    • 副标题/Slogan
    • 图片跳转地址(imglinkurl)-- 大多数时候我们点击分类都会分类Id跳转到固定的分类商品列表展示页面,但是在一些特殊的场景,比如我们要做一个活动,希望可以点击某一个分类的主图直接定位到活动页面,这个url就可以使用了。
    • 上级分类(parent_id)
    • 背景色(bg_color)
    • 顺序(sort)
    • 当前分类级别(type)

    开发梳理

    ---

    在上一小节,我们简单分析了一下要实现商品分类的一些points,那么我们最好在每次拿到需求【开发之前】,对需求进行拆解,然后分解开发流程,这样可以保证我们更好的理解需求,以及在开发之前发现一部分不合理的需求,并且如果需求设计不合理的话,开发人员完全有权,也有责任告知PM。大家的终极目的都是为了我们做的产品更加合理,好用,受欢迎!

    • 首次展示,仅仅读取一级分类(Root)
    • 根据一级分类查询二三级子分类

    编码实现

    ---

    查询一级分类

    Service实现

    1.在com.liferunner.service中创建service 接口ICategoryService.java, 编写查询所有一级分类的方法getAllRootCategorys,如下:

    package com.liferunner.service;
    import com.liferunner.dto.CategoryResponseDTO;
    import com.liferunner.dto.SecondSubCategoryResponseDTO;
    import java.util.List;
    /**
     * ICategoryService for : 分类service
     *
     * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
     * @since 2019/11/13
     */
    public interface ICategoryService {
        /**
         * 获取所有有效的一级分类(根节点)
         *
         * @return
         */
        List<CategoryResponseDTO> getAllRootCategorys();
    }

    2.编写实现类com.liferunner.service.ICategoryService.java

    @Service
    @Slf4j
    public class CategorySericeImpl implements ICategoryService {
        @Autowired
        private CategoryMapper categoryMapper;
        
        @Override
        public List<CategoryResponseDTO> getAllRootCategorys() {
            Example example = new Example(Category.class);
            val conditions = example.createCriteria();
            conditions.andEqualTo("type", CategoryTypeEnum.ROOT.type);
            val categoryList = this.categoryMapper.selectByExample(example);
            //声明返回对象
            List<CategoryResponseDTO> categoryResponseDTOS = new ArrayList<>();
            if (!CollectionUtils.isEmpty(categoryList)) {
                //赋值
                CategoryResponseDTO dto;
                for (Category category : categoryList) {
                    dto = new CategoryResponseDTO();
                    BeanUtils.copyProperties(category, dto);
                    categoryResponseDTOS.add(dto);
                }
            }
            return categoryResponseDTOS;
        }
    }

    上述代码很好理解,创建tk.mybatis.mapper.entity.Example,将条件传入,然后使用通用Mapper查询到type=1的一级分类,接着将查到的对象列表转换为DTO对象列表。

    Controller实现

    一般情况下,此类查询都会出现在网站的首页,因此我们来创建一个com.liferunner.api.controller.IndexController,并对外暴露一个查询一级分类的接口:

    package com.liferunner.api.controller;
    
    import com.liferunner.service.ICategoryService;
    import com.liferunner.service.IProductService;
    import com.liferunner.service.ISlideAdService;
    import com.liferunner.utils.JsonResponse;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import io.swagger.annotations.ApiParam;
    import java.util.Collections;
    import lombok.extern.slf4j.Slf4j;
    import lombok.val;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.util.CollectionUtils;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    /**
     * IndexController for : 首页controller
     *
     * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
     * @since 2019/11/12
     */
    @RestController
    @RequestMapping("/index")
    @Api(value = "首页信息controller", tags = "首页信息接口API")
    @Slf4j
    public class IndexController {
        @Autowired
        private ICategoryService categoryService;
    
        @GetMapping("/rootCategorys")
        @ApiOperation(value = "查询一级分类", notes = "查询一级分类")
        public JsonResponse findAllRootCategorys() {
            log.info("============查询一级分类==============");
            val categoryResponseDTOS = this.categoryService.getAllRootCategorys();
            if (CollectionUtils.isEmpty(categoryResponseDTOS)) {
                log.info("============未查询到任何分类==============");
                return JsonResponse.ok(Collections.EMPTY_LIST);
            }
            log.info("============一级分类查询result:{}==============", categoryResponseDTOS);
            return JsonResponse.ok(categoryResponseDTOS);
        }
    }

    Test API

    编写完成之后,我们需要对我们的代码进行测试验证,还是通过使用RestService插件来实现,当然,大家也可以通过Postman来测试。

    {
      "status": 200,
      "message": "OK",
      "data": [
        {
          "id": 1,
          "name": "烟酒",
          "type": 1,
          "parentId": 0,
          "logo": "img/cake.png",
          "slogan": "吸烟受害健康",
          "catImage": "http://www.life-runner.com/shop/category/cake.png",
          "bgColor": "#fe7a65"
        },
        {
          "id": 2,
          "name": "服装",
          "type": 1,
          "parentId": 0,
          "logo": "img/cookies.png",
          "slogan": "我选择我喜欢",
          "catImage": "http://www.life-runner.com/shop/category/cookies.png",
          "bgColor": "#f59cec"
        },
        {
          "id": 3,
          "name": "鞋帽",
          "type": 1,
          "parentId": 0,
          "logo": "img/meat.png",
          "slogan": "飞一般的感觉",
          "catImage": "http://www.life-runner.com/shop/category/meat.png",
          "bgColor": "#b474fe"
        }
      ],
      "ok": true
    }

    根据一级分类查询子分类

    因为根据一级id查询子分类的时候,我们是在同一张表中做自连接查询,因此,通用mapper已经不适合我们的使用,因此我们需要自定义mapper来实现我们的需求。

    自定义Mybatis Mapper实现

    在之前的编码中,我们都是使用的插件帮我们实现的通用Mapper,但是这种查询只能处理简单的单表CRUD,一旦我们需要SQL 包含一部分逻辑处理的时候,那就必须得自己来编写了,let's code.1.在项目mscx-shop-mapper中,创建一个新的custom package,在该目录下创建自定义mappercom.liferunner.custom.CategoryCustomMapper

    public interface CategoryCustomMapper {
        List<SecondSubCategoryResponseDTO> getSubCategorys(Integer parentId);
    }

    2.resources目录下创建目录mapper.custom,以及创建和上面的接口相同名称的XML文件mapper/custom/CategoryCustomMapper.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.liferunner.custom.CategoryCustomMapper">
        <resultMap id="subCategoryDTO" type="com.liferunner.dto.SecondSubCategoryResponseDTO">
            <id column="id" jdbcType="INTEGER" property="id"/>
            <result column="name" jdbcType="VARCHAR" property="name"/>
            <result column="type" jdbcType="INTEGER" property="type"/>
            <result column="parentId" jdbcType="INTEGER" property="parentId"/>
            <collection property="thirdSubCategoryResponseDTOList" ofType="com.liferunner.dto.ThirdSubCategoryResponseDTO">
                <id column="subId" jdbcType="INTEGER" property="subId"/>
                <result column="subName" jdbcType="VARCHAR" property="subName"/>
                <result column="subType" jdbcType="INTEGER" property="subType"/>
                <result column="subParentId" jdbcType="INTEGER" property="subParentId"/>
            </collection>
        </resultMap>
        <select id="getSubCategorys" resultMap="subCategoryDTO" parameterType="INTEGER">
            SELECT p.id as id,p.`name` as `name`,p.`type` as `type`,p.father_id as parentId,
            c.id as subId,c.`name` as subName,c.`type` as subType,c.parent_id as subParentId
            FROM category p
            LEFT JOIN category c
            ON p.id = c.parent_id
            WHERE p.parent_id = ${parentId};
        </select>
    </mapper>

    TIPS

    上述创建的package,一定要在项目的启动类com.liferunner.api.ApiApplication中修改@MapperScan(basePackages = { "com.liferunner.mapper", "com.liferunner.custom"}),如果不把我们的custom package加上,会造成扫描不到而报错。

    在上面的xml中,我们定义了两个DTO对象,分别用来处理二级和三级分类的DTO,实现如下:

    @Data
    @ToString
    public class SecondSubCategoryResponseDTO {
        /**
         * 主键
         */
        private Integer id;
    
        /**
         * 分类名称
         */
        private String name;
    
        /**
         * 分类类型
         1:一级大分类
         2:二级分类
         3:三级小分类
         */
        private Integer type;
    
        /**
         * 父id
         */
        private Integer parentId;
    
        List<ThirdSubCategoryResponseDTO> thirdSubCategoryResponseDTOList;
    }
    ---
        
    @Data
    @ToString
    public class ThirdSubCategoryResponseDTO {
        /**
         * 主键
         */
        private Integer subId;
    
        /**
         * 分类名称
         */
        private String subName;
    
        /**
         * 分类类型
         1:一级大分类
         2:二级分类
         3:三级小分类
         */
        private Integer subType;
    
        /**
         * 父id
         */
        private Integer subParentId;
    }

    Service实现

    编写完自定义mapper之后,我们就可以继续编写service了,在com.liferunner.service.ICategoryService中新增一个方法:getAllSubCategorys(parentId).如下:

    public interface ICategoryService {
        ...
        /**
         * 根据一级分类获取子分类
         *
         * @param parentId 一级分类id
         * @return 子分类list
         */
        List<SecondSubCategoryResponseDTO> getAllSubCategorys(Integer parentId);
    }

    com.liferunner.service.impl.CategorySericeImpl实现上述方法:

    @Service
    @Slf4j
    public class CategorySericeImpl implements ICategoryService {
        @Autowired
        private CategoryMapper categoryMapper;
    
        @Autowired
        private CategoryCustomMapper categoryCustomMapper;
        ...
        @Override
        @Transactional(propagation = Propagation.SUPPORTS)
        public List<SecondSubCategoryResponseDTO> getAllSubCategorys(Integer parentId) {
            return this.categoryCustomMapper.getSubCategorys(parentId);
        }
    }

    Controller实现

    @RestController
    @RequestMapping("/index")
    @Api(value = "首页信息controller", tags = "首页信息接口API")
    @Slf4j
    public class IndexController {
        @Autowired
        private ICategoryService categoryService;
        ...
        @GetMapping("/subCategorys/{parentId}")
        @ApiOperation(value = "查询子分类", notes = "根据一级分类id查询子分类")
        public JsonResponse findAllSubCategorys(
                @ApiParam(name = "parentId", value = "一级分类id", required = true)
                @PathVariable Integer parentId) {
            log.info("============查询id = {}的子分类==============", parentId);
            val categoryResponseDTOS = this.categoryService.getAllSubCategorys(parentId);
            if (CollectionUtils.isEmpty(categoryResponseDTOS)) {
                log.info("============未查询到任何分类==============");
                return JsonResponse.ok(Collections.EMPTY_LIST);
            }
            log.info("============子分类查询result:{}==============", categoryResponseDTOS);
            return JsonResponse.ok(categoryResponseDTOS);
        }
    }

    Test API

    {
      "status": 200,
      "message": "OK",
      "data": [
        {
          "id": 11,
          "name": "国产",
          "type": 2,
          "parentId": 1,
          "thirdSubCategoryResponseDTOList": [
            {
              "subId": 37,
              "subName": "中华",
              "subType": 3,
              "subParentId": 11
            },
            {
              "subId": 38,
              "subName": "冬虫夏草",
              "subType": 3,
              "subParentId": 11
            },
            {
              "subId": 39,
              "subName": "南京",
              "subType": 3,
              "subParentId": 11
            },
            {
              "subId": 40,
              "subName": "云烟",
              "subType": 3,
              "subParentId": 11
            }
          ]
        },
        {
          "id": 12,
          "name": "外烟",
          "type": 2,
          "parentId": 1,
          "thirdSubCategoryResponseDTOList": [
            {
              "subId": 44,
              "subName": "XXXXX",
              "subType": 3,
              "subParentId": 12
            },
            {
              "subId": 45,
              "subName": "RRRRR",
              "subType": 3,
              "subParentId": 12
            }
          ]
        }
      ],
      "ok": true
    }

    以上我们就已经实现了和jd类似的商品分类的功能实现。

    ## 轮播广告 SlideAD

    需求分析

    这个就是jd或者tb首先的最顶部的广告图片是一样的,每隔1秒自动切换图片。接下来我们分析一下轮播图中都包含哪些信息:Slide Images

    • 图片(img_url)是最基本的
    • 图片跳转连接(imglinkurl),这个是在我们点击这个图片的时候需要跳转到的页面
    • 有的可以直接跳转到商品详情页面
    • 有的可以直接跳转到某一分类商品列表页面
    • 轮播图的播放顺序(sort)
    • ...

    开发梳理

    直接查询出所有的有效的轮播图片,并且进行排序

    编码实现

    Service 实现

    和商品分类实现一样,在mscx-shop-service中创建com.liferunner.service.ISlideAdService并实现,代码如下:

    public interface ISlideAdService {
        /**
         * 查询所有可用广告并排序
         * @param isShow
         * @return
         */
        List<SlideAdResponseDTO> findAll(Integer isShow, String sortRanking);
    }

    @Service
    @Slf4j
    public class SlideAdServiceImpl implements ISlideAdService {
    
        // 注入mapper
        private final SlideAdsMapper slideAdsMapper;
    
        @Autowired
        public SlideAdServiceImpl(SlideAdsMapper slideAdsMapper) {
            this.slideAdsMapper = slideAdsMapper;
        }
    
        @Override
        public List<SlideAdResponseDTO> findAll(Integer isShow, String sortRanking) {
            Example example = new Example(SlideAds.class);
            //设置排序
            if (StringUtils.isBlank(sortRanking)) {
                example.orderBy("sort").asc();
            } else {
                example.orderBy("sort").desc();
            }
            val conditions = example.createCriteria();
            conditions.andEqualTo("isShow", isShow);
            val slideAdsList = this.slideAdsMapper.selectByExample(example);
            //声明返回对象
            List<SlideAdResponseDTO> slideAdResponseDTOList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(slideAdsList)) {
                //赋值
                SlideAdResponseDTO dto;
                for (SlideAds slideAds : slideAdsList) {
                    dto = new SlideAdResponseDTO();
                    BeanUtils.copyProperties(slideAds, dto);
                    slideAdResponseDTOList.add(dto);
                }
            }
            return slideAdResponseDTOList;
        }
    }

    从上述可以看到,这里我使用的是构造函数注入SlideAdsMapper,其余代码单表查询没什么特别的,根据条件查询轮播图,并返回结果,返回的对象是com.liferunner.dto.SlideAdResponseDTO列表,代码如下:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    @ApiModel(value = "轮播广告返回DTO", description = "轮播广告返回DTO")
    public class SlideAdResponseDTO{
        /**
         * 主键
         */
        private String id;
    
        /**
         * 图片地址
         */
        private String imageUrl;
    
        /**
         *  背景颜色
         */
        private String backgroundColor;
    
        /**
         * 商品id
         */
        private String productId;
    
        /**
         * 商品分类id
         */
        private String catId;
    
        /**
         * 图片跳转URL
         */
        private String imageLinkUrl;
    
        /**
         * 轮播图类型 用于判断,可以根据商品id或者分类进行页面跳转,1:商品 2:分类 3:链接url
         */
        private Integer type;
    
        /**
         * 轮播图展示顺序 轮播图展示顺序,从小到大
         */
        private Integer sort;
    
        /**
         * 是否展示 是否展示,1:展示    0:不展示
         */
        private Integer isShow;
    
        /**
         * 创建时间 创建时间
         */
        private Date createTime;
    
        /**
         * 更新时间 更新
         */
        private Date updateTime;
    }

    Controller实现

    com.liferunner.api.controller.IndexController中,新添加一个查询轮播图API,代码如下:

        @Autowired
        private ISlideAdService slideAdService;
    
        @GetMapping("/slideAds")
        @ApiOperation(value = "查询轮播广告", notes = "查询轮播广告接口")
        public JsonResponse findAllSlideList() {
            log.info("============查询所有轮播广告,isShow={},sortRanking={}=============="
                    , 1, "desc");
            val slideAdsList = this.slideAdService.findAll(1, "desc");
            if (CollectionUtils.isEmpty(slideAdsList)) {
                log.info("============未查询到任何轮播广告==============");
                return JsonResponse.ok(Collections.EMPTY_LIST);
            }
            log.info("============轮播广告查询result:{}=============="
                    , slideAdsList);
            return JsonResponse.ok(slideAdsList);
        }

    Test API

    {
      "status": 200,
      "message": "OK",
      "data": [
        {
          "id": "slide-100002",
          "imageUrl": "http://www.life-runner.com/2019/11/CpoxxF0ZmH6AeuRrAAEZviPhyQ0768.png",
          "backgroundColor": "#55be59",
          "productId": "",
          "catId": "133",
          "type": 2,
          "sort": 2,
          "isShow": 1,
          "createTime": "2019-10-11T21:33:01.000 0000",
          "updateTime": "2019-10-11T21:33:02.000 0000"
        },
        {
          "id": "slide-100003",
          "imageUrl": "http://www.life-runner.com/2019/11/CpoxxF0ZmHuAPlXvAAFe-H5_-Nw961.png",
          "backgroundColor": "#ff9801",
          "productId": "y200008",
          "catId": "",
          "type": 1,
          "sort": 1,
          "isShow": 1,
          "createTime": "2019-10-11T21:33:01.000 0000",
          "updateTime": "2019-10-11T21:33:02.000 0000"
        }
      ],
      "ok": true
    }

    福利讲解

    在我们的实现代码中,有心的同学可以看到,我使用了3种不同的Bean注入方式:

    • 属性注入
        @Autowired
        private ISlideAdService slideAdService;

    • 构造函数注入
        // 注入mapper
        private final SlideAdsMapper slideAdsMapper;
    
        @Autowired
        public SlideAdServiceImpl(SlideAdsMapper slideAdsMapper) {
            this.slideAdsMapper = slideAdsMapper;
        }

    • Lombok插件注入(本质也是构造器注入,代码会动态生成。)
    @RequiredArgsConstructor(onConstructor = @__(@Autowired))
    public class ProductServiceImpl implements IProductService {
        // RequiredArgsConstructor 构造器注入
        private final ProductCustomMapper productCustomMapper;
        private final ProductsMapper productsMapper;
        ...
    }

    那么,这几种注入都有什么区别呢?首先我们下了解一下Spring的注入是干什么的?

    Spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过Spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。

    依赖注入的另一种说法是"控制反转"。通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员, 而控制反转是指new实例工作不由我们程序员来做而是交给Spring容器来做。

    在传统的SpringMVC中,大家使用的都是XML注入,比如:

    <!--配置bean,配置后该类由spring管理--> 
    <bean name="CategorySericeImpl" class="com.liferunner.service.impl.CategorySericeImpl"> 
    <!--注入配置当前类中相应的属性--> 
    <property name="categoryMapper" ref="categoryMapper"></property> 
    </bean> 
    <bean name="categoryMapper" class="com.liferunner.mapper.CategoryMapper"></bean>

    注入之后,使用@Autowired,我们可以很方便的自动从IOC容器中查找属性,并返回。

    @Autowired的原理

    在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。

    注意事项:

    在使用@Autowired时,首先在容器中查询对应类型的bean

    如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据

    如果查询的结果不止一个,那么@Autowired会根据名称来查找。

    如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false

    source传送门

    上述三种注解方式,其实本质上还是注入的2种:set属性注入 & 构造器注入,使用方式都可以,根据个人喜好来用,本人喜欢使用lombok插件注入是因为,它将代码整合在一起,更加符合我们Spring自动注入的规范。

    源码下载

    ---

    Github 传送门
    Gitee 传送门

    下节预告

    ---

    下一节我们将继续开发我们电商的核心部分-商品列表和详情展示,在过程中使用到的任何开发组件,我都会通过专门的一节来进行介绍的,兄弟们末慌!

    gogogo!

    奔跑的人生 | 博客园 | segmentfault | spring4all | csdn | 掘金 | OSChina | 简书 | 头条 | 知乎 | 51CTO

    展开全文
  • 介绍了内容匹配广告展示广告相关技术。 本博客记录观看品牌展示广告部分的一些笔记, 绝大多数为原slide内容,只做简单的整理。 1. 基本概念 展示广告分类  按广告作用分类:品牌广告(Brand Disp
  • "模块"【网站首页广告管理】:广告展示广告数据的管理,--- ----------------------------------------------------------- 分为两张表广告分类表 和广告表 1对多的关系 分类表主要有...
  • google广告分类

    万次阅读 2012-03-28 10:44:57
    Google广告的偏好设置,根据兴趣类别和受众人口统计特点类别来展示广告,可以设置站点Adsense的出现广告的类别,Adsense的分类体系如下: 1、类别:1578,不算多,也不算少。 2、级别:一级大概是26,一般行业下...
  • 家具展示类装潢装饰行业网站织梦模板介绍: 适合做家居装饰、户外家居类企业网站使用,属于企业通用类型的模板!页面简洁简单,容易管理,DEDE内核都可以使用;附带测试数据! 家具展示类装潢装饰行业网站织梦模板...
  • 网络营销广告分类

    2020-05-31 17:42:48
    网络广告就是在网络上做的广告。通过网络广告投放平台来利用网站上的广告横幅、文本链接、多媒体...是位于网页的两侧,广告面积较大,较狭窄,能够展示较多的广告内容。 3、文本链接广告 文本链接广告是以一排文字作为
  • 接上篇,GD定义里的最后一个问题是...偏好的挖掘是基于几的用户数据:一部分是用户的静态属性的信息,例如姓名性别出生年月注册兴趣等等,这数据是由用户主动提供的,后续训练修正。还有大量的用户行为数据,包括
  • 电商除了选品,渠道,物流,发货,其实在广告投放优化才是重中之中,而一个好的信息流广告优化师更是需要经过很多实操才能做得得心应手。分享一下信息流广告到底怎么投?信息流广告投放的侧重点,一定要注意,...
  • 大广告位展示-淘淘商城

    千次阅读 热门讨论 2017-11-25 20:16:22
    展示首页返回一个逻辑视图,需要把首页大广告位的json数据传递给jsp。 @RequestMapping ( "/index" ) public String showIndex (Model model) { String adJson = contentService.getContentList(); model....
  • 广告类专业求职简历PPT模板。一份适合广告类专业大学生求职简历PPT模板,采用全图型背景图片设计,包括个人信息、专业学习经历、工作经历、设计软件技能掌握情况、设计作品展示等部分。
  • 新闻广告图片滚动展示

    千次阅读 2010-12-27 15:20:00
    在做门户网站时,首页面上经常会有新闻图片展示,下面收集两个图片展示的方式: 方法1.显示多个图片,横行滚动  JS代码如下:  <mce:script type="text/javascript"><!-- //...
  • CTR广告点击率预估

    2020-04-20 13:08:24
    展示类广告:腾讯的广点通 搜索广告:百度蜂巢 社交平台上广告:微博上广告 2、广告计费方式 CPM(cost per mile) 按照展示收费,不管用户看到广告没,只要广告每天达到一定的曝光次数,就需要给钱,广告组会给...
  • 广告类网站织梦模板

    2017-05-13 17:58:18
    广告展厅设计网站织梦模板  模板介绍: 页面简洁简单,容易管理,DEDE内核都可以使用;附带测试数据!   模板特点: 企业网站通用模板,简单便捷, 易于管理,一款值得拥有的织梦网站模板。 简洁美观...
  • 电商除了选品,渠道,物流,发货,其实在广告投放优化才是重中之重,而一个好的信息流广告优化师更是需要经过很多实操才能做得得心应手。OK,今天小编就来分享信息流广告到底怎么投?信息流广告投放的侧重点,...
  • 广告展厅设计网站织梦模板 模板介绍: 页面简洁简单,容易管理,DEDE内核都可以使用;附带测试数据! 模板特点: 企业网站通用模板,简单便捷, 易于管理,一款值得拥有的织梦网站模板。 简洁美观大方的黑白设计...
  • 展示类广告 分类广告 引导广告 电子邮件广告 二、广告收费方式 CPC (每点击成本 Cost peer Click) 结算为主,单价在3毛左右,价格浮动较大 CPA(cost peer action)(例如用户下载注册)付费,单价在0.6~4元...
  • 互联网广告形式

    2011-03-27 19:16:00
    展示类广告 2.1> 横幅广告 2.2> 富媒体广告 2.3> 视频广告 2.4> 赞助广告 3> 分类广告4> 引导广告5> 电子邮件广告 转载于:https://www.cnblogs.com/caichunsheng/archive/2011/03/27/...
  • 卫浴洁具企业网站产品展示功能介绍: 一、可视化的鼠标拖曳排版 可以方便地在网页中插入插件、拖放定位和改变插件尺寸,灵活设置插件边框风格和插件显示参数,灵活设置网页背景,网页排版完全可视化,所见即所得...
  • 电商除了选品,渠道,物流,发货,其实在广告投放优化才是重中之中,而一个好的信息流广告优化师更是需要经过很多实操才能做得得心应手。分享一下信息流广告到底怎么投?信息流广告投放的侧重点,一定要注意,...
  • 本博文将分析CMS内容管理系统的功能实现,同时借助广告位的展示来介绍解决ajax跨域请求问题的方案二:httpClient。 一、CMS内容管理系统 在后台管理内容及内容分类的系统就叫做cms系统。 1.表设计管理 思路: 1、 ...
  • 广告图一般比较大 而且只需要展示几秒时间 如果在展示时间还需要加载图片这样会让广告商觉得不爽 思路 把网络图片转成btm 用链接作为参数名进行存储,每次加载判断有没有该文件 如果为空 网络加载图片并进行缓存 ...
  • 大气品牌传播广告设计企业公司织梦模板介绍: 页面简洁简单,容易管理,DEDE5.5内核以上都可以使用;附带测试数据! 大气品牌传播广告设计企业公司织梦模板模板特点: 品牌设计,品牌传播,广告网络设计...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 815
精华内容 326
关键字:

展示类广告