增加首页轮播图可配置
diff --git a/backend/src/main/java/com/supwisdom/dlpay/framework/util/LocationUtil.java b/backend/src/main/java/com/supwisdom/dlpay/framework/util/LocationUtil.java
new file mode 100644
index 0000000..09475d9
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/framework/util/LocationUtil.java
@@ -0,0 +1,86 @@
+package com.supwisdom.dlpay.framework.util;
+
+public class LocationUtil {
+  /**
+   * 赤道半径
+   */
+  private static double EARTH_RADIUS = 6378.137;
+
+  private static double rad(double d) {
+    return d * Math.PI / 180.0;
+  }
+
+  /**
+   * Description : 通过经纬度获取距离(单位:米)
+   * Group :
+   *
+   * @param origin      出发点
+   * @param destination 目的地
+   * @return double
+   * @author honghh
+   * @date 2019/2/13 0013 15:50
+   */
+  public static double getDistance(String origin, String destination) {
+    if (origin == null) {
+      return 0;
+    }
+    if (destination == null) {
+      return 0;
+    }
+    String[] temp = origin.split(",");
+    String[] temp2 = destination.split(",");
+
+    double radLat1 = rad(Double.parseDouble(temp[1]));
+    double radLat2 = rad(Double.parseDouble(temp2[1]));
+    double a = radLat1 - radLat2;
+    double b = rad(Double.parseDouble(temp[0])) - rad(Double.parseDouble(temp2[0]));
+    double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
+        + Math.cos(radLat1) * Math.cos(radLat2)
+        * Math.pow(Math.sin(b / 2), 2)));
+    s = s * EARTH_RADIUS;
+    // 保留两位小数
+    s = Math.round(s * 100d) / 100d;
+    s = s * 1000;
+    return s;
+  }
+
+  /**
+   * Description : 通过经纬度获取距离(单位:米)
+   * Group :
+   *
+   * @param originLon      出发点经度
+   * @param originLat      出发点纬度
+   * @param destinationLon 目的地经度
+   * @param destinationLat 目的地纬度
+   * @return double
+   * @author honghh
+   * @date 2019/2/15 0015 9:14
+   */
+  public static double getDistance(String originLon, String originLat, String destinationLon, String destinationLat) {
+    if (StringUtil.isEmpty(originLon)) {
+      return 0;
+    }
+    if (StringUtil.isEmpty(originLat)) {
+      return 0;
+    }
+    if (StringUtil.isEmpty(destinationLon)) {
+      return 0;
+    }
+    if (StringUtil.isEmpty(destinationLat)) {
+      return 0;
+    }
+
+    double radLat1 = rad(Double.parseDouble(originLat));
+    double radLat2 = rad(Double.parseDouble(destinationLat));
+    double a = radLat1 - radLat2;
+    double b = rad(Double.parseDouble(originLon)) - rad(Double.parseDouble(destinationLon));
+    double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
+        + Math.cos(radLat1) * Math.cos(radLat2)
+        * Math.pow(Math.sin(b / 2), 2)));
+    s = s * EARTH_RADIUS;
+    // 保留两位小数
+    s = Math.round(s * 100d) / 100d;
+    s = s * 1000;
+    return s;
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/ColumnRepositoryImpl.java b/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/ColumnRepositoryImpl.java
index 54661d7..9ead66d 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/ColumnRepositoryImpl.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/ColumnRepositoryImpl.java
@@ -4,12 +4,16 @@
 import com.supwisdom.dlpay.framework.jpa.Finder;
 import com.supwisdom.dlpay.framework.jpa.page.Pagination;
 import com.supwisdom.dlpay.framework.util.StringUtil;
+import com.supwisdom.dlpay.portal.bean.BannerSearchBean;
 import com.supwisdom.dlpay.portal.bean.ColumnSearchBean;
 import com.supwisdom.dlpay.portal.dao.ColumnRepository;
+import com.supwisdom.dlpay.portal.domain.TBBanner;
 import com.supwisdom.dlpay.portal.domain.TBColumn;
 import org.hibernate.transform.Transformers;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.List;
+
 public class ColumnRepositoryImpl extends BaseRepository implements ColumnRepository {
   @NotNull
   @Override
@@ -35,4 +39,20 @@
     }
     return findNative(f, Transformers.aliasToBean(TBColumn.class), pageno, pagesize);
   }
+
+  @NotNull
+  @Override
+  public Pagination getBannerList(@NotNull BannerSearchBean bean) {
+    int pageno = bean.getPageno();
+    int pagesize = bean.getPagesize();
+    Finder f = Finder.create("select * from tb_banner order by ordernum ");
+    return findNative(f, Transformers.aliasToBean(TBBanner.class), pageno, pagesize);
+  }
+
+  @NotNull
+  @Override
+  public List<TBBanner> getAllBanner() {
+    Finder f = Finder.create("from TBBanner order by ordernum ");
+    return find(f);
+  }
 }
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBBanner.java b/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBBanner.java
new file mode 100644
index 0000000..64885b5
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBBanner.java
@@ -0,0 +1,77 @@
+package com.supwisdom.dlpay.portal.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "tb_banner")
+public class TBBanner {
+  @Id
+  @GenericGenerator(name = "idGenerator", strategy = "uuid")
+  @GeneratedValue(generator = "idGenerator")
+  @Column(name = "bannerid", nullable = false, length = 32)
+  private String bannerid;
+
+  @Column(name = "articleno", unique = true, nullable = false, length = 20)
+  private String articleno;
+
+  @Column(name = "ordernum")
+  private Integer ordernum;
+
+  @Column(name = "picid", length = 32)
+  private String picid;
+  @Column(name = "minpicid", length = 32)
+  private String minpicid;
+
+  @Column(name = "title", length = 50)
+  private String title;
+
+  public String getBannerid() {
+    return bannerid;
+  }
+
+  public void setBannerid(String bannerid) {
+    this.bannerid = bannerid;
+  }
+
+  public String getArticleno() {
+    return articleno;
+  }
+
+  public void setArticleno(String articleno) {
+    this.articleno = articleno;
+  }
+
+  public Integer getOrdernum() {
+    return ordernum;
+  }
+
+  public void setOrdernum(Integer ordernum) {
+    this.ordernum = ordernum;
+  }
+
+  public String getPicid() {
+    return picid;
+  }
+
+  public void setPicid(String picid) {
+    this.picid = picid;
+  }
+
+  public String getMinpicid() {
+    return minpicid;
+  }
+
+  public void setMinpicid(String minpicid) {
+    this.minpicid = minpicid;
+  }
+
+  public String getTitle() {
+    return title;
+  }
+
+  public void setTitle(String title) {
+    this.title = title;
+  }
+}
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBOutlets.java b/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBOutlets.java
index 0493441..23467b1 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBOutlets.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBOutlets.java
@@ -43,6 +43,12 @@
   @Column(name = "tel",length = 50)
   private String tel;
 
+  @Column(name = "isopen",length = 1)
+  private String isopen;
+
+  @Transient
+  private double distance;
+
   public String getId() {
     return id;
   }
@@ -122,4 +128,20 @@
   public void setCreatetime(String createtime) {
     this.createtime = createtime;
   }
+
+  public String getIsopen() {
+    return isopen;
+  }
+
+  public void setIsopen(String isopen) {
+    this.isopen = isopen;
+  }
+
+  public double getDistance() {
+    return distance;
+  }
+
+  public void setDistance(double distance) {
+    this.distance = distance;
+  }
 }
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java b/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java
index 0e2d14f..2c4d18f 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/util/PortalConstant.java
@@ -13,6 +13,7 @@
   public static final String SYSPARA_OUTLETS_CURRENTNO = "outlets.currentno";
   public static final String SYSPARA_PORTAL_APPID = "portal.appid";
   public static final String SYSPARA_PORTAL_SECRET = "portal.secret";
+  public static final String SYSPARA_PORTAL_AMAPKEY = "portal.amapkey";
 
   public static final String ARTICLE_STATUS_SAVE = "save";
   public static final String ARTICLE_STATUS_PASS = "pass";
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
index f9a7808..22b08fc 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
@@ -1,9 +1,6 @@
 package com.supwisdom.dlpay.mobile
 
-import com.supwisdom.dlpay.agent.citizencard.YnrccUtil
-import com.supwisdom.dlpay.agent.service.CitizencardPayService
 import com.supwisdom.dlpay.api.bean.*
-import com.supwisdom.dlpay.api.service.QRCodeService
 import com.supwisdom.dlpay.api.service.UploadPicService
 import com.supwisdom.dlpay.api.service.UserService
 import com.supwisdom.dlpay.api.util.MobileNumberCheck
@@ -22,10 +19,7 @@
 import com.supwisdom.dlpay.paysdk.proxy.UserProxy
 import com.supwisdom.dlpay.portal.bean.FeedbackSearchBean
 import com.supwisdom.dlpay.portal.domain.TBFeedback
-import com.supwisdom.dlpay.portal.service.AdvisoryService
-import com.supwisdom.dlpay.portal.service.ArticleService
-import com.supwisdom.dlpay.portal.service.ColumnService
-import com.supwisdom.dlpay.portal.service.FeedbackService
+import com.supwisdom.dlpay.portal.service.*
 import com.supwisdom.dlpay.portal.util.PortalConstant
 import com.supwisdom.dlpay.system.service.DictionaryProxy
 import com.supwisdom.dlpay.util.ConstantUtil
@@ -72,6 +66,8 @@
     lateinit var userProxy: UserProxy
     @Autowired
     lateinit var advisoryService: AdvisoryService
+    @Autowired
+    lateinit var outletsService: OutletsService
     val logger = KotlinLogging.logger { }
 
     @RequestMapping("/time")
@@ -336,6 +332,41 @@
         }
     }
 
+    /**
+     * 获取附近网点
+     */
+    @RequestMapping("/outlets/nearby")
+    fun getNearbyOutlets(@RequestHeader("Authorization") auth: String?,
+                    location:String,distance:Double): JsonResult? {
+        try {
+            val data = outletsService.getNearbyOutlets(location, distance)
+            return JsonResult.ok().put("data", data)
+        } catch (e: Exception) {
+            logger.error { e.message }
+            if (e is PortalBusinessException) {
+                return JsonResult.error(e.message)
+            }
+            return JsonResult.error("服务器繁忙,请稍后重试")
+        }
+    }
+
+    /**
+     * 获取热门活动轮播图
+     */
+    @RequestMapping("/column/banner")
+    fun getNearbyOutlets(@RequestHeader("Authorization") auth: String?): JsonResult? {
+        try {
+            val list = columnService.getAllBanner()
+            return JsonResult.ok().put("data",list)
+        } catch (e: Exception) {
+            logger.error { e.message }
+            if (e is PortalBusinessException) {
+                return JsonResult.error(e.message)
+            }
+            return JsonResult.error("服务器繁忙,请稍后重试")
+        }
+    }
+
     fun judgeLoginMode(auth: String?): String {
         var mode = "tourist"
         if (auth != null) {
@@ -364,14 +395,10 @@
     @Autowired
     lateinit var dictionaryProxy: DictionaryProxy
     @Autowired
-    lateinit var citizencardPayService: CitizencardPayService
-    @Autowired
     lateinit var apiJwtRepository: ApiJwtRepository
     @Autowired
     lateinit var jwtConfig: JwtConfig
     @Autowired
-    lateinit var qrcodeService: QRCodeService
-    @Autowired
     lateinit var uploadPicService: UploadPicService
     @Autowired
     lateinit var feedbackService: FeedbackService
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
index f4bd861..26ddab6 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
@@ -74,9 +74,11 @@
             val oper = operatorDetailService.findByOperid(p.name)
             val data = HashMap<String, String>()
             val url = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_IMAGE_URLPUSH)
+            val mapKey = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_PORTAL_AMAPKEY)
             data["name"] = oper.opername
             data["roles"] = "admin"
             data["url"] = url
+            data["mapkey"] = mapKey
             JsonResult.ok().put("data", data)
         } catch (e: Exception) {
             logger.error { e.message }
@@ -221,6 +223,23 @@
         }
     }
 
+    /**
+     * 获取轮播图列表
+     */
+    @RequestMapping("/column/bannerlist")
+    fun getBannerList(bean: BannerSearchBean): JsonResult? {
+        return try {
+            val page = columnService.getBannerList(bean)
+            if (page.list == null || page.list.size == 0) {
+                return JsonResult.ok().put("msg", "无数据")
+            }
+            return JsonResult.ok().put("page", page)
+        } catch (e: Exception) {
+            logger.error { e.message }
+            JsonResult.error("查询轮播图列表异常")
+        }
+    }
+
     @RequestMapping(value = ["/column/save"], method = [RequestMethod.POST])
     fun saveColumn(@RequestBody column: TBColumn): JsonResult? {
         return try {
@@ -240,6 +259,38 @@
         }
     }
 
+    /**
+     * 保存轮播图设置
+     */
+    @RequestMapping(value = ["/column/savebanner"], method = [RequestMethod.POST])
+    fun saveBanner(@RequestBody banner: TBBanner): JsonResult? {
+        return try {
+            val msg = columnService.saveBanner(banner)
+            return if (StringUtil.isEmpty(msg)) {
+                JsonResult.ok()
+            } else {
+                JsonResult.error(msg)
+            }
+        } catch (e: Exception) {
+            logger.error { e.message }
+            JsonResult.error("保存轮播图异常")
+        }
+    }
+
+    /**
+     * 删除轮播图
+     */
+    @RequestMapping(value = ["/column/deletebanner/{bannerid}"], method = [RequestMethod.POST])
+    fun deleteBanner(@PathVariable bannerid: String): JsonResult? {
+        return try {
+            columnService.deleteBanner(bannerid)
+            JsonResult.ok()
+        } catch (e: Exception) {
+            logger.error { e.message }
+            JsonResult.error("删除轮播图异常")
+        }
+    }
+
     @RequestMapping(value = ["/article/save"], method = [RequestMethod.POST])
     fun saveArticle(@RequestBody article: TBArticle): JsonResult? {
         return try {
@@ -425,4 +476,19 @@
             JsonResult.error("查询网点列表异常")
         }
     }
+
+    /**
+     * 是否开启网点
+     */
+    @RequestMapping(value = ["/outlets/switchopen/{outletsno}"], method = [RequestMethod.POST])
+    fun switchOutletsOpen(@PathVariable(value = "outletsno") outletsno: String,
+                              @RequestParam(value = "value") value: String): JsonResult? {
+        return try {
+            val result = outletsService.switchOpen(outletsno, value)
+            JsonResult.ok().put("result", result)
+        } catch (e: Exception) {
+            logger.error { e.message }
+            JsonResult.error("切换网点是否开启异常")
+        }
+    }
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/BannerSearchBean.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/BannerSearchBean.kt
new file mode 100644
index 0000000..4eee697
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/BannerSearchBean.kt
@@ -0,0 +1,6 @@
+package com.supwisdom.dlpay.portal.bean
+
+class BannerSearchBean {
+    var pageno: Int = 0
+    var pagesize: Int = 10
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/BannerDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/BannerDao.kt
new file mode 100644
index 0000000..5602676
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/BannerDao.kt
@@ -0,0 +1,9 @@
+package com.supwisdom.dlpay.portal.dao
+
+import com.supwisdom.dlpay.portal.domain.TBBanner
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface BannerDao : JpaRepository<TBBanner, String>, ArticleRepository {
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/ColumnRepository.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/ColumnRepository.kt
index 4a3c44f..d704e94 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/ColumnRepository.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/ColumnRepository.kt
@@ -1,8 +1,12 @@
 package com.supwisdom.dlpay.portal.dao
 
 import com.supwisdom.dlpay.framework.jpa.page.Pagination
+import com.supwisdom.dlpay.portal.bean.BannerSearchBean
 import com.supwisdom.dlpay.portal.bean.ColumnSearchBean
+import com.supwisdom.dlpay.portal.domain.TBBanner
 
 interface ColumnRepository {
     fun getColumnList(bean: ColumnSearchBean): Pagination
+    fun getBannerList(bean: BannerSearchBean): Pagination
+    fun getAllBanner(): List<TBBanner>
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsDao.kt
index 55c66cd..8eab5ac 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsDao.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/OutletsDao.kt
@@ -6,5 +6,6 @@
 
 @Repository
 interface OutletsDao :JpaRepository<TBOutlets,String>,OutletsRepository{
-
+    fun getByOutletsno(outletsno:String):TBOutlets?
+    fun getByIsopen(isopen:String):List<TBOutlets>?
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/ColumnService.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/ColumnService.kt
index 563faf7..82bd5db 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/ColumnService.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/ColumnService.kt
@@ -1,7 +1,9 @@
 package com.supwisdom.dlpay.portal.service
 
 import com.supwisdom.dlpay.framework.jpa.page.Pagination
+import com.supwisdom.dlpay.portal.bean.BannerSearchBean
 import com.supwisdom.dlpay.portal.bean.ColumnSearchBean
+import com.supwisdom.dlpay.portal.domain.TBBanner
 import com.supwisdom.dlpay.portal.domain.TBColumn
 import org.springframework.transaction.annotation.Transactional
 
@@ -10,9 +12,21 @@
     fun saveColumn(column: TBColumn): String?
 
     @Transactional
+    fun saveBanner(banner: TBBanner): String?
+
+    @Transactional
     fun getColumnList(bean: ColumnSearchBean): Pagination
 
     @Transactional
+    fun getBannerList(bean: BannerSearchBean): Pagination
+
+    @Transactional(readOnly = true)
+    fun getAllBanner():List<TBBanner>
+
+    @Transactional
+    fun deleteBanner(bannerid: String)
+
+    @Transactional
     fun getAllColumnList(): List<TBColumn>?
 
     @Transactional
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/ColumnServiceImpl.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/ColumnServiceImpl.kt
index 59ae3bc..787fb15 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/ColumnServiceImpl.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/ColumnServiceImpl.kt
@@ -1,12 +1,18 @@
 package com.supwisdom.dlpay.portal.service.Impl
 
 import com.supwisdom.dlpay.framework.jpa.page.Pagination
+import com.supwisdom.dlpay.framework.service.SystemUtilService
 import com.supwisdom.dlpay.framework.util.StringUtil
+import com.supwisdom.dlpay.portal.bean.BannerSearchBean
 import com.supwisdom.dlpay.portal.bean.ColumnSearchBean
+import com.supwisdom.dlpay.portal.dao.ArticleDao
+import com.supwisdom.dlpay.portal.dao.BannerDao
 import com.supwisdom.dlpay.portal.dao.ColumnDao
+import com.supwisdom.dlpay.portal.domain.TBBanner
 import com.supwisdom.dlpay.portal.domain.TBColumn
 import com.supwisdom.dlpay.portal.service.ColumnService
 import com.supwisdom.dlpay.portal.util.PortalConstant
+import mu.KotlinLogging
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.stereotype.Service
 
@@ -14,11 +20,45 @@
 class ColumnServiceImpl : ColumnService {
     @Autowired
     lateinit var columnDao: ColumnDao
+    @Autowired
+    lateinit var articleDao: ArticleDao
+    @Autowired
+    lateinit var bannerDao: BannerDao
+    @Autowired
+    lateinit var systemUtilService: SystemUtilService
+    val logger = KotlinLogging.logger { }
 
     override fun getColumnList(bean: ColumnSearchBean): Pagination {
         return columnDao.getColumnList(bean)
     }
 
+    override fun getBannerList(bean: BannerSearchBean): Pagination {
+        return columnDao.getBannerList(bean)
+    }
+
+    override fun getAllBanner(): List<TBBanner> {
+        val url = systemUtilService.getBusinessValue(PortalConstant.SYSPARA_IMAGE_URLPUSH)
+        if (StringUtil.isEmpty(url)) {
+            logger.error { "图片服务器地址未配置" }
+            return emptyList()
+        }
+        val list = columnDao.getAllBanner()
+        list.forEach {
+            it.picid = url + "/" + it.picid
+            it.minpicid = url + "/" + it.minpicid
+        }
+        return list
+    }
+
+    override fun deleteBanner(bannerid: String) {
+        val optional = bannerDao.findById(bannerid)
+        if (optional.isPresent) {
+            bannerDao.delete(optional.get())
+        } else {
+            throw RuntimeException("为找到id为:[$bannerid]的轮播图")
+        }
+    }
+
     override fun getAllColumnList(): List<TBColumn>? {
         return columnDao.findAll()
     }
@@ -54,4 +94,18 @@
         columnDao.save(column)
         return null
     }
+
+    override fun saveBanner(banner: TBBanner): String? {
+        val article = articleDao.findByArticlenoAndIsdelete(banner.articleno, PortalConstant.NO)
+                ?: return "未找到编号为:[${banner.articleno}]的文章,请检查编号是否正确"
+        if (article.status != PortalConstant.ARTICLE_STATUS_RELEASED) {
+            return "文章状态异常,请确认该文章已发布"
+        }
+        if (article.isdisplay == PortalConstant.NO) {
+            return "该文章已设置为不展示,请修改后再操作"
+        }
+        banner.title = article.title
+        bannerDao.save(banner)
+        return null
+    }
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/OutletsServiceImpl.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/OutletsServiceImpl.kt
index 84b47ae..53734ef 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/OutletsServiceImpl.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/OutletsServiceImpl.kt
@@ -3,6 +3,7 @@
 import com.supwisdom.dlpay.framework.dao.BusinessparaDao
 import com.supwisdom.dlpay.framework.jpa.page.Pagination
 import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.LocationUtil
 import com.supwisdom.dlpay.framework.util.StringUtil
 import com.supwisdom.dlpay.portal.bean.OutletsSearchBean
 import com.supwisdom.dlpay.portal.dao.OutletsDao
@@ -11,6 +12,7 @@
 import com.supwisdom.dlpay.portal.util.PortalConstant
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.stereotype.Service
+import java.util.stream.Collectors
 
 @Service
 class OutletsServiceImpl : OutletsService {
@@ -30,6 +32,7 @@
             businessparaDao.save(currentNoBusiness)
             outlets.createtime = systemUtilService.sysdatetime.hostdatetime
             outlets.outletsno = String.format("%06d", currentNo)
+            outlets.isopen = PortalConstant.YES
         }
         outletsDao.save(outlets)
     }
@@ -37,4 +40,24 @@
     override fun getOutletsList(bean: OutletsSearchBean): Pagination {
         return outletsDao.getOutletsList(bean)
     }
+
+    override fun switchOpen(outletsno: String, value: String): String {
+        val outlets = outletsDao.getByOutletsno(outletsno)
+                ?: throw RuntimeException("未找到编号为:[${outletsno}]的网点")
+        outlets.isopen = value
+        outletsDao.save(outlets)
+        return value
+    }
+
+    override fun getNearbyOutlets(location: String, distance: Double): List<TBOutlets>? {
+        val outletsList = outletsDao.getByIsopen(PortalConstant.YES)
+        if (outletsList == null || outletsList.isEmpty()) {
+            return emptyList()
+        }
+        return outletsList.stream().filter {
+            val countDistance = LocationUtil.getDistance(location, it.location)
+            it.distance = countDistance
+            countDistance <= distance
+        }.collect(Collectors.toList())
+    }
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/OutletsService.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/OutletsService.kt
index 927daf1..7b8cb50 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/OutletsService.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/OutletsService.kt
@@ -10,4 +10,8 @@
     fun saveOutlets(outlets: TBOutlets)
     @Transactional
     fun getOutletsList(bean: OutletsSearchBean): Pagination
+    @Transactional
+    fun switchOpen(outletsno: String,value:String): String
+    @Transactional
+    fun getNearbyOutlets(location: String,distance:Double): List<TBOutlets>?
 }
\ No newline at end of file
diff --git a/backend/src/main/resources/data-postgresql.sql b/backend/src/main/resources/data-postgresql.sql
index 755e49b..397d46f 100644
--- a/backend/src/main/resources/data-postgresql.sql
+++ b/backend/src/main/resources/data-postgresql.sql
@@ -20,6 +20,7 @@
 INSERT INTO "tb_businesspara"("parakey", "paraval", "tenantid") VALUES ('aes.cfb.totp.offset', '20', '{tenantid}');
 INSERT INTO "tb_businesspara"("parakey", "paraval", "tenantid") VALUES ('aes.cfb.rootkey', 'Vbb1syh8U1+CdLmTVGdtDiVvKBQ81n4GmgBEO/ohSbU=', '{tenantid}');
 INSERT INTO "tb_businesspara"("parakey", "paraval", "tenantid") VALUES ('aes.cfb.iv', '55b6f5b3287c535f8274b99354676d0e', '{tenantid}');
+INSERT INTO "tb_businesspara"("parakey", "paraval", "tenantid") VALUES ('portal.amapkey', 'd69cdfdc1711fc7c318eb7e1a0664976', '{tenantid}');
 
 INSERT INTO "tb_column"("columnid", "isleaf", "name", "needreview", "parentid", "code", "ispublic", "publishable", "ordernum") VALUES ('2c9cab947451988c017451a737b10000', '0', '线上活动', '0', '', 'OnlineActivities', '1', '1', 12);
 INSERT INTO "tb_column"("columnid", "isleaf", "name", "needreview", "parentid", "code", "ispublic", "publishable", "ordernum") VALUES ('2c9cab947451988c017451b280870001', '0', '线下活动', '0', '', 'OfflineActivities', '1', '1', 13);
diff --git a/frontend/src/api/column.js b/frontend/src/api/column.js
index 32616b6..fcd048c 100644
--- a/frontend/src/api/column.js
+++ b/frontend/src/api/column.js
@@ -8,6 +8,14 @@
   })
 }
 
+export function getBannerList(query) {
+  return request({
+    url: '/column/bannerlist',
+    method: 'get',
+    params: query
+  })
+}
+
 export function getAllColumn() {
   return request({
     url: '/column/all',
@@ -22,3 +30,18 @@
     data
   })
 }
+
+export function saveBanner(data) {
+  return request({
+    url: '/column/savebanner',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteBanner(bannerid) {
+  return request({
+    url: '/column/deletebanner/' + bannerid,
+    method: 'post'
+  })
+}
diff --git a/frontend/src/api/outlets.js b/frontend/src/api/outlets.js
index d8323e7..247e78c 100644
--- a/frontend/src/api/outlets.js
+++ b/frontend/src/api/outlets.js
@@ -16,3 +16,11 @@
   })
 }
 
+export function switchOpen(outletsno, value) {
+  return request({
+    url: '/outlets/switchopen/' + outletsno,
+    method: 'post',
+    params: value
+  })
+}
+
diff --git a/frontend/src/components/AMap/index.vue b/frontend/src/components/AMap/index.vue
index 1c1a996..be98a89 100644
--- a/frontend/src/components/AMap/index.vue
+++ b/frontend/src/components/AMap/index.vue
@@ -11,16 +11,18 @@
 
 <script>
 import remoteLoad from '@/utils/remoteLoad.js'
-import { MapKey, MapCityName } from '@/utils/remoteLoad.js'
+import { MapCityName } from '@/utils/remoteLoad.js'
+import user from '@/store/modules/user'
 export default {
-  props: ['lat', 'lng'],
+  props: { 'lat': { type: String, default: '' }, 'lng': { type: String, default: '' }},
   data() {
     return {
       searchKey: '',
       placeSearch: null,
       dragStatus: false,
       AMapUI: null,
-      AMap: null
+      AMap: null,
+      mapkey: ''
     }
   },
   watch: {
@@ -32,11 +34,12 @@
   },
   async created() {
   // 已载入高德地图API,则直接初始化地图
+    this.mapkey = user.state.mapkey
     if (window.AMap && window.AMapUI) {
       this.initMap()
       // 未载入高德地图API,则先载入API再初始化
     } else {
-      await remoteLoad(`http://webapi.amap.com/maps?v=1.4.15&key=${MapKey}`)
+      await remoteLoad('http://webapi.amap.com/maps?v=1.4.15&key=' + this.mapkey)
       await remoteLoad('http://webapi.amap.com/ui/1.0/main.js')
       this.initMap()
     }
diff --git a/frontend/src/store/modules/user.js b/frontend/src/store/modules/user.js
index b8348bf..6e7c117 100644
--- a/frontend/src/store/modules/user.js
+++ b/frontend/src/store/modules/user.js
@@ -29,6 +29,9 @@
   },
   SET_URL: (state, url) => {
     state.url = url
+  },
+  SET_MAPKEY: (state, mapkey) => {
+    state.mapkey = mapkey
   }
 }
 
@@ -57,10 +60,11 @@
           reject('认证失败,请稍后重试')
         }
 
-        const { name, roles, url } = data
+        const { name, roles, url, mapkey } = data
         commit('SET_ROLES', roles)
         commit('SET_NAME', name)
         commit('SET_URL', url + '/')
+        commit('SET_MAPKEY', mapkey)
         resolve(data)
       }).catch(error => {
         reject(error)
@@ -75,6 +79,7 @@
         commit('SET_TOKEN', '')
         commit('SET_ROLES', [])
         commit('SET_URL', '')
+        commit('SET_MAPKEY', '')
         removeToken()
         resetRouter()
 
@@ -95,6 +100,7 @@
       commit('SET_TOKEN', '')
       commit('SET_ROLES', [])
       commit('SET_URL', '')
+      commit('SET_MAPKEY', '')
       removeToken()
       resolve()
     })
diff --git a/frontend/src/views/column/index.vue b/frontend/src/views/column/index.vue
index 42e1e7d..599b4c4 100644
--- a/frontend/src/views/column/index.vue
+++ b/frontend/src/views/column/index.vue
@@ -1,199 +1,313 @@
 <template>
   <div class="app-container">
-    <div class="filter-container">
-      <div class="filter-item" style="margin-right:15px">栏目名称</div>
-      <el-input
-        v-model="formData.name"
-        placeholder="输入栏目名称"
-        style="width: 350px;margin-right:50px"
-        class="filter-item"
-      />
-      <div class="filter-item" style="margin-right:15px">栏目CODE</div>
-      <el-input
-        v-model="formData.code"
-        placeholder="输入栏目CODE"
-        style="width: 350px;margin-right:50px"
-        class="filter-item"
-      />
-      <el-button
-        class="filter-item"
-        type="primary"
-        icon="el-icon-search"
-        @click="handleFilter()"
-      >
-        搜索
+    <div v-show="!imageSet">
+      <div class="filter-container">
+        <div class="filter-item" style="margin-right:15px">栏目名称</div>
+        <el-input
+          v-model="formData.name"
+          placeholder="输入栏目名称"
+          style="width: 350px;margin-right:50px"
+          class="filter-item"
+        />
+        <div class="filter-item" style="margin-right:15px">栏目CODE</div>
+        <el-input
+          v-model="formData.code"
+          placeholder="输入栏目CODE"
+          style="width: 350px;margin-right:50px"
+          class="filter-item"
+        />
+        <el-button
+          class="filter-item"
+          type="primary"
+          icon="el-icon-search"
+          @click="handleFilter()"
+        >
+          搜索
+        </el-button>
+      </div>
+      <el-button type="primary" icon="el-icon-circle-plus-outline" @click="addColumn()">
+        新增栏目
       </el-button>
-    </div>
-    <el-button type="primary" icon="el-icon-circle-plus-outline" @click="addColumn()">
-      新增栏目
-    </el-button>
-    <el-table
-      :key="tableKey"
-      v-loading="listLoading"
-      :data="list"
-      border
-      fit
-      highlight-current-row
-      style="width: 100%;margin-top:10px"
-    >
-      <el-table-column label="上级栏目">
-        <template slot-scope="{row}">
-          <span>{{ row.parentname }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="栏目CODE" align="center">
-        <template slot-scope="{row}">
-          <span>{{ row.code }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="栏目名称" align="center">
-        <template slot-scope="{row}">
-          <span>{{ row.name }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="序号" align="center" width="70">
-        <template slot-scope="{row}">
-          <span>{{ row.ordernum }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="是否公开" width="100" align="center">
-        <template slot-scope="{row}">
-          <i
-            v-if="row.ispublic==='1'"
-            style="color:#67C23A;font-size:20px"
-            class="el-icon-circle-check"
-          />
-          <i
-            v-else
-            style="color:#F56C6C;font-size:20px"
-            class="el-icon-circle-close"
-          />
-        </template>
-      </el-table-column>
-      <el-table-column label="是否要审核" width="100" align="center">
-        <template slot-scope="{row}">
-          <i
-            v-if="row.needreview==='1'"
-            style="color:#67C23A;font-size:20px"
-            class="el-icon-circle-check"
-          />
-          <i
-            v-else
-            style="color:#F56C6C;font-size:20px"
-            class="el-icon-circle-close"
-          />
-        </template>
-      </el-table-column>
-      <el-table-column label="是否能发布" width="100" align="center">
-        <template slot-scope="{row}">
-          <i
-            v-if="row.publishable==='1'"
-            style="color:#67C23A;font-size:20px"
-            class="el-icon-circle-check"
-          />
-          <i
-            v-else
-            style="color:#F56C6C;font-size:20px"
-            class="el-icon-circle-close"
-          />
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" align="center" width="180">
-        <template slot-scope="{row}">
-          <el-tooltip class="item" effect="dark" content="修改" placement="bottom">
-            <el-button type="primary" icon="el-icon-edit" circle size="mini" @click="updateColumn(row)" />
-          </el-tooltip>
-          <el-tooltip v-if="row.isleaf==='0'" class="item" effect="dark" content="添加子栏目" placement="bottom">
-            <el-button type="primary" size="mini" @click="addSubColumn(row)">添加子栏目</el-button>
-          </el-tooltip>
-        </template>
-      </el-table-column>
-    </el-table>
+      <el-button type="primary" icon="el-icon-picture" style="float:right" @click="setImage()">
+        热门活动图片设置
+      </el-button>
+      <el-table
+        :key="tableKey"
+        v-loading="listLoading"
+        :data="list"
+        border
+        fit
+        highlight-current-row
+        style="width: 100%;margin-top:10px"
+      >
+        <el-table-column label="上级栏目">
+          <template slot-scope="{row}">
+            <span>{{ row.parentname }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="栏目CODE" align="center">
+          <template slot-scope="{row}">
+            <span>{{ row.code }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="栏目名称" align="center">
+          <template slot-scope="{row}">
+            <span>{{ row.name }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="序号" align="center" width="70">
+          <template slot-scope="{row}">
+            <span>{{ row.ordernum }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="是否公开" width="100" align="center">
+          <template slot-scope="{row}">
+            <i
+              v-if="row.ispublic==='1'"
+              style="color:#67C23A;font-size:20px"
+              class="el-icon-circle-check"
+            />
+            <i
+              v-else
+              style="color:#F56C6C;font-size:20px"
+              class="el-icon-circle-close"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="是否要审核" width="100" align="center">
+          <template slot-scope="{row}">
+            <i
+              v-if="row.needreview==='1'"
+              style="color:#67C23A;font-size:20px"
+              class="el-icon-circle-check"
+            />
+            <i
+              v-else
+              style="color:#F56C6C;font-size:20px"
+              class="el-icon-circle-close"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="是否能发布" width="100" align="center">
+          <template slot-scope="{row}">
+            <i
+              v-if="row.publishable==='1'"
+              style="color:#67C23A;font-size:20px"
+              class="el-icon-circle-check"
+            />
+            <i
+              v-else
+              style="color:#F56C6C;font-size:20px"
+              class="el-icon-circle-close"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" width="180">
+          <template slot-scope="{row}">
+            <el-tooltip class="item" effect="dark" content="修改" placement="bottom">
+              <el-button type="primary" icon="el-icon-edit" circle size="mini" @click="updateColumn(row)" />
+            </el-tooltip>
+            <el-tooltip v-if="row.isleaf==='0'" class="item" effect="dark" content="添加子栏目" placement="bottom">
+              <el-button type="primary" size="mini" @click="addSubColumn(row)">添加子栏目</el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
 
-    <pagination
-      v-show="total>0"
-      :total="total"
-      :page.sync="formData.pageno"
-      :limit.sync="formData.pagesize"
-      style="margin-top:0;"
-      @pagination="getColumnList"
-    />
-    <el-dialog
-      :title="title"
-      :visible.sync="columnDialogVisible"
-      width="30%"
-    >
-      <div>
-        <el-form ref="columnForm" :model="columnForm" :rules="rules" label-width="100px">
-          <el-form-item label="栏目名称" prop="name" class="form-input-item">
+      <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="formData.pageno"
+        :limit.sync="formData.pagesize"
+        style="margin-top:0;"
+        @pagination="getColumnList"
+      />
+      <el-dialog
+        :title="title"
+        :visible.sync="columnDialogVisible"
+        width="30%"
+      >
+        <div>
+          <el-form ref="columnForm" :model="columnForm" :rules="rules" label-width="100px">
+            <el-form-item label="栏目名称" prop="name" class="form-input-item">
+              <el-input
+                v-model="columnForm.name"
+                maxlength="30"
+                show-word-limit
+                style="width:80%"
+              />
+            </el-form-item>
+            <el-form-item label="栏目CODE" prop="code" class="form-input-item">
+              <el-input
+                v-model="columnForm.code"
+                maxlength="30"
+                show-word-limit
+                style="width:80%"
+                placeholder="只能由字母或数字组成"
+              />
+            </el-form-item>
+            <el-form-item label="是否公开" prop="ispublic">
+              <el-select
+                v-model="columnForm.ispublic"
+                style="width:80%"
+                placeholder="游客只能浏览公开内容"
+              >
+                <el-option label="是" value="1" />
+                <el-option label="否" value="0" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="是否要审核" prop="needreview">
+              <el-select
+                v-model="columnForm.needreview"
+                style="width:80%"
+                placeholder="栏目下文章审核后才能发布"
+              >
+                <el-option label="是" value="1" />
+                <el-option label="否" value="0" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="是否能发布" prop="publishable">
+              <el-select
+                v-model="columnForm.publishable"
+                style="width:80%"
+                placeholder="该栏目下不能发布文章"
+              >
+                <el-option label="是" value="1" />
+                <el-option label="否" value="0" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="栏目排序" prop="ordernum">
+              <el-input v-model="columnForm.ordernum" style="width:80%" />
+            </el-form-item>
+          </el-form>
+        </div>
+        <div style="text-align:center">
+          <el-button
+            type="primary"
+            @click="saveColumn('columnForm')"
+          >保存
+          </el-button>
+          <el-button @click="columnDialogVisible = false">取消</el-button>
+        </div>
+      </el-dialog>
+    </div>
+
+    <div v-show="imageSet">
+      <el-button type="primary" icon="el-icon-picture" @click="addImage()">
+        新增图片
+      </el-button>
+      <el-button type="primary" icon="el-icon-back" style="float:right" @click="imageSet=false">
+        返回
+      </el-button>
+      <el-table
+        :key="bannerTableKey"
+        :data="bannerList"
+        border
+        fit
+        highlight-current-row
+        style="width: 100%;margin-top:10px"
+      >
+        <el-table-column label="轮播图片">
+          <template slot-scope="{row}">
+            <el-image :src="imageUrl+row.picid">
+              <div slot="error">
+                <i size="medium" class="el-icon-picture-outline" />
+              </div>
+            </el-image>
+          </template>
+        </el-table-column>
+        <el-table-column label="文章标题" width="300" align="center">
+          <template slot-scope="{row}">
+            <span>{{ row.title }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="文章编号" width="150" align="center">
+          <template slot-scope="{row}">
+            <span>{{ row.articleno }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="排序" width="100" align="center">
+          <template slot-scope="{row}">
+            <span>{{ row.ordernum }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" width="200">
+          <template slot-scope="{row}">
+            <el-tooltip class="item" effect="dark" content="修改" placement="bottom">
+              <el-button type="primary" icon="el-icon-edit" circle size="mini" @click="updateBanner(row)" />
+            </el-tooltip>
+            <el-tooltip class="item" effect="dark" content="删除" placement="bottom">
+              <el-button type="danger" icon="el-icon-delete" circle size="mini" @click="deleteBanner(row)" />
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="bannerTotal>0"
+        :total="bannerTotal"
+        :page.sync="bannerFormData.pageno"
+        :limit.sync="bannerFormData.pagesize"
+        style="margin-top:0;"
+        @pagination="getBannerList"
+      />
+      <el-dialog
+        :title="uploadImageTitle"
+        :visible.sync="imageDialogVisible"
+        width="40%"
+        @close="closeImageDialog()"
+      >
+        <el-upload
+          :class="{'disable':uploadDisable}"
+          class="banner-image-upload"
+          action="#"
+          :http-request="uploadImage"
+          list-type="picture-card"
+          :file-list="fileList"
+          :before-upload="handleBeforeUpload"
+          :on-error="handleError"
+          :on-preview="handlePictureCardPreview"
+          :on-remove="handleRemove"
+        >
+          <i class="el-icon-plus" />
+        </el-upload>
+        <el-form ref="bannerForm" style="margin:20px 0 0 35px" :model="bannerForm">
+          <el-form-item label="跳转文章">
             <el-input
-              v-model="columnForm.name"
-              maxlength="30"
-              show-word-limit
-              style="width:80%"
+              v-model="bannerForm.articleno"
+              style="width:50%"
+              placeholder="请输入文章编号"
             />
           </el-form-item>
-          <el-form-item label="栏目CODE" prop="code" class="form-input-item">
-            <el-input
-              v-model="columnForm.code"
-              maxlength="30"
-              show-word-limit
-              style="width:80%"
-              placeholder="只能由字母或数字组成"
-            />
-          </el-form-item>
-          <el-form-item label="是否公开" prop="ispublic">
-            <el-select
-              v-model="columnForm.ispublic"
-              style="width:80%"
-              placeholder="游客只能浏览公开内容"
-            >
-              <el-option label="是" value="1" />
-              <el-option label="否" value="0" />
-            </el-select>
-          </el-form-item>
-          <el-form-item label="是否要审核" prop="needreview">
-            <el-select
-              v-model="columnForm.needreview"
-              style="width:80%"
-              placeholder="栏目下文章审核后才能发布"
-            >
-              <el-option label="是" value="1" />
-              <el-option label="否" value="0" />
-            </el-select>
-          </el-form-item>
-          <el-form-item label="是否能发布" prop="publishable">
-            <el-select
-              v-model="columnForm.publishable"
-              style="width:80%"
-              placeholder="该栏目下不能发布文章"
-            >
-              <el-option label="是" value="1" />
-              <el-option label="否" value="0" />
-            </el-select>
-          </el-form-item>
-          <el-form-item label="栏目排序" prop="ordernum">
-            <el-input v-model="columnForm.ordernum" style="width:80%" />
+          <el-form-item label="轮播排序">
+            <el-input-number v-model="bannerForm.ordernum" :min="1" style="width:50%" />
           </el-form-item>
         </el-form>
-      </div>
-      <div style="text-align:center">
-        <el-button
-          type="primary"
-          @click="saveColumn('columnForm')"
-        >保存
-        </el-button>
-        <el-button @click="columnDialogVisible = false">取消</el-button>
-      </div>
-    </el-dialog>
+        <div style="text-align:center">
+          <el-button
+            type="primary"
+            @click="saveBanner()"
+          >保存
+          </el-button>
+          <el-button @click="imageDialogVisible = fasle">取消</el-button>
+        </div>
+      </el-dialog>
+      <el-dialog :visible.sync="dialogVisible">
+        <img width="100%" :src="dialogImageUrl" alt="">
+      </el-dialog>
+    </div>
   </div>
 </template>
 <script>
 import {
   getColumnList,
-  saveColumnList
+  saveColumnList,
+  saveBanner,
+  getBannerList,
+  deleteBanner
 } from '@/api/column'
 import Pagination from '@/components/Pagination'
+import user from '@/store/modules/user'
+import { uploadImage } from '@/api/article'
 export default {
   name: 'Column',
   components: {
@@ -207,11 +321,26 @@
         pageno: 1,
         pagesize: 10
       },
+      bannerFormData: {
+        pageno: 1,
+        pagesize: 10
+      },
       listLoading: false,
       tableKey: 0,
       list: null,
+      bannerTableKey: 1,
+      bannerList: null,
       total: 0,
+      bannerTotal: 0,
       title: '',
+      uploadImageTitle: '',
+      currentImage: {
+        picid: '',
+        minpicid: ''
+      },
+      fileList: [{ url: '' }],
+      imageSet: false,
+      imageUrl: '',
       columnForm: {
         columnid: '',
         name: '',
@@ -222,7 +351,18 @@
         parentid: '',
         ordernum: null
       },
+      bannerForm: {
+        bannerid: '',
+        picid: '',
+        minpicid: '',
+        articleno: '',
+        ordernum: null
+      },
+      dialogImageUrl: '',
+      dialogVisible: false,
+      uploadDisable: false,
       columnDialogVisible: false,
+      imageDialogVisible: false,
       rules: {
         name: [
           { required: true, message: '请输入栏目名称', trigger: 'blur' }
@@ -247,6 +387,7 @@
     }
   },
   created() {
+    this.imageUrl = user.state.url
     this.getColumnList()
   },
   methods: {
@@ -269,6 +410,22 @@
         this.listLoading = false
       })
     },
+    getBannerList() {
+      getBannerList(this.bannerFormData).then(response => {
+        if (response.page) {
+          this.bannerList = response.page.list
+          this.bannerTotal = response.page.totalCount
+        } else {
+          this.bannerList = null
+          this.bannerTotal = 0
+        }
+      }).catch(error => {
+        this.$message({
+          message: error.msg || '请求异常',
+          type: 'error'
+        })
+      })
+    },
     handleFilter() {
       this.formData.pageno = 1
       this.getColumnList()
@@ -327,6 +484,131 @@
       this.$nextTick(() => {
         this.$refs[formName].clearValidate()
       })
+    },
+    setImage() {
+      this.bannerFormData.pageno = 1
+      this.getBannerList()
+      this.imageSet = true
+    },
+    addImage() {
+      this.uploadImageTitle = '新增图片'
+      this.fileList = []
+      this.uploadDisable = false
+      this.imageDialogVisible = true
+      this.bannerForm = {
+        bannerid: '',
+        picid: '',
+        minpicid: '',
+        articleno: '',
+        ordernum: null
+      }
+    },
+    updateBanner(row) {
+      this.fileList = [{ url: this.imageUrl + row.picid }]
+      this.uploadDisable = true
+      this.uploadImageTitle = '修改图片'
+      this.bannerForm = {
+        bannerid: '',
+        picid: '',
+        minpicid: '',
+        articleno: '',
+        ordernum: null
+      }
+      this.bannerForm = Object.assign({}, row)
+      this.imageDialogVisible = true
+    },
+    deleteBanner(row) {
+      this.$confirm('是否确认删除该图片?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        deleteBanner(row.bannerid).then(response => {
+          this.$message({
+            type: 'success',
+            message: '删除成功!'
+          })
+          this.getBannerList()
+        }).catch(error => {
+          this.$message({
+            message: error.msg || '请求异常',
+            type: 'error'
+          })
+          this.listLoading = false
+        })
+      }).catch(() => {
+      })
+    },
+    uploadImage(uploader) {
+      const params = new FormData()
+      params.append('file', uploader.file)
+      uploadImage(params).then(response => {
+        uploader.onSuccess(response)
+        this.handleSuccess(response.data)
+      }).catch(error => {
+        console.log(error)
+        this.$message({
+          message: error.msg || '图片上传失败',
+          type: 'error'
+        })
+        this.listLoading = false
+      })
+    },
+    handleRemove(file, fileList) {
+      this.uploadDisable = false
+      this.bannerForm.picid = ''
+      this.bannerForm.minpicid = ''
+    },
+    handlePictureCardPreview(file) {
+      this.dialogImageUrl = file.url
+      this.dialogVisible = true
+    },
+    handleBeforeUpload() {
+      this.uploadDisable = true
+    },
+    handleSuccess(response) {
+      this.bannerForm.picid = response.picid
+      this.bannerForm.minpicid = response.minpicid
+    },
+    handleError() {
+      this.bannerForm.picid = ''
+      this.bannerForm.minpicid = ''
+      this.uploadDisable = false
+    },
+    closeImageDialog() {
+      this.imageDialogVisible = false
+      this.fileList = []
+    },
+    saveBanner() {
+      if (this.bannerForm.picid === '' || this.bannerForm.minpicid === '') {
+        this.$message({
+          message: '请先选择图片,如果图片上传失败,请重新上传后再试',
+          type: 'error'
+        })
+        return
+      }
+      if (this.bannerForm.articleno === '') {
+        this.$message({
+          message: '请输入文章编号',
+          type: 'error'
+        })
+        return
+      }
+      saveBanner(this.bannerForm).then(response => {
+        this.$notify({
+          title: '成功',
+          message: '保存成功!',
+          type: 'success',
+          duration: 2000
+        })
+        this.imageDialogVisible = false
+        this.getBannerList()
+      }).catch(error => {
+        this.$message({
+          message: error.msg || '请求异常',
+          type: 'error'
+        })
+      })
     }
   }
 }
@@ -336,5 +618,20 @@
   .el-input__inner{
     padding-right: 50px;
   }
+.disable .el-upload--picture-card {
+    display: none;
+}
+.banner-image-upload .el-upload-list__item{
+    width: 432px;
+    height: 102px;
+}
+.banner-image-upload .el-upload--picture-card{
+    width: 432px;
+    height: 102px;
+    line-height: 102px;
+}
 
+.banner-image-upload{
+  text-align: center;
+}
 </style>
diff --git a/frontend/src/views/outlets/index.vue b/frontend/src/views/outlets/index.vue
index bd4a2f7..4376941 100644
--- a/frontend/src/views/outlets/index.vue
+++ b/frontend/src/views/outlets/index.vue
@@ -36,7 +36,7 @@
       highlight-current-row
       style="width: 100%;margin-top:10px"
     >
-      <el-table-column label="网点编号" width="100">
+      <el-table-column label="网点编号" width="80">
         <template slot-scope="{row}">
           <span>{{ row.outletsno }}</span>
         </template>
@@ -66,20 +66,20 @@
           <span>{{ row.location }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="状态" align="center" width="100">
+      <el-table-column label="是否开启" align="center" width="100">
         <template slot-scope="{row}">
-          <el-tag v-if="row.isdelete==='1'" type="danger" size="medium">已删除</el-tag>
-          <el-tag v-else-if="row.replystatus==='0'" size="medium">待回复</el-tag>
-          <el-tag v-else type="success" size="medium">已回复</el-tag>
+          <el-switch
+            :value="row.isopen === '1'"
+            active-color="#13ce66"
+            inactive-color="#a7a7a7"
+            @click.native.prevent="switchOpen(row)"
+          />
         </template>
       </el-table-column>
       <el-table-column label="操作" align="center" width="100">
         <template slot-scope="{row}">
-          <el-tooltip class="item" effect="dark" content="查看详情" placement="bottom">
-            <el-button icon="el-icon-search" circle size="mini" @click="openDetailDialog(row)" />
-          </el-tooltip>
-          <el-tooltip v-if="row.isdelete==='0'" class="item" effect="dark" content="回复" placement="bottom">
-            <el-button type="primary" icon="el-icon-edit" circle size="mini" @click="openReplyDialog(row)" />
+          <el-tooltip class="item" effect="dark" content="修改" placement="bottom">
+            <el-button type="primary" icon="el-icon-edit" circle size="mini" @click="updateOutlets(row)" />
           </el-tooltip>
         </template>
       </el-table-column>
@@ -188,13 +188,16 @@
 import mapDrag from '@/components/AMap/index.vue'
 import {
   saveOutlets,
+  switchOpen,
   getOutletsList
 } from '@/api/outlets'
 import moment from 'moment'
+import Pagination from '@/components/Pagination'
 export default {
   name: 'Outlets',
   components: {
-    mapDrag
+    mapDrag,
+    Pagination
   },
   data() {
     var validateTime = (rule, value, callback) => {
@@ -260,6 +263,9 @@
       }
     }
   },
+  created() {
+    this.getOutletsList()
+  },
   methods: {
     getOutletsList() {
       this.listLoading = true
@@ -309,6 +315,16 @@
       this.resetForm('outletsForm')
       this.outletsDialogVisible = true
     },
+    updateOutlets(row) {
+      this.title = '修改网点'
+      this.resetForm('outletsForm')
+      this.outletsForm = Object.assign({}, row)
+      var time = []
+      time[0] = this.outletsForm.starttime
+      time[1] = this.outletsForm.endtime
+      this.businessTime = time
+      this.outletsDialogVisible = true
+    },
     resetForm(formName) {
       this.outletsForm = {
         outletsid: '',
@@ -320,11 +336,27 @@
         location: '',
         address: ''
       }
+      this.businessTime = null
       this.mapshow = false
       this.$nextTick(() => {
         this.$refs[formName].clearValidate()
       })
     },
+    switchOpen(row) {
+      switchOpen(row.outletsno, { value: row.isopen === '1' ? '0' : '1' }).then(response => {
+        this.$message({
+          type: 'success',
+          message: '操作成功!'
+        })
+        row.isopen = response.result
+      }).catch(error => {
+        this.$message({
+          message: error.msg || '请求异常',
+          type: 'error'
+        })
+        this.listLoading = false
+      })
+    },
     saveOutlets(formName) {
       this.$refs[formName].validate((valid) => {
         if (valid) {
@@ -341,6 +373,7 @@
               duration: 2000
             })
             this.outletsDialogVisible = false
+            this.getOutletsList()
           }).catch(error => {
             this.$message({
               message: error.msg || '请求异常',