增加设置提示功能
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/AdvisoryRepositoryImpl.java b/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/AdvisoryRepositoryImpl.java
index c16ab64..7574e6f 100644
--- a/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/AdvisoryRepositoryImpl.java
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/dao/impl/AdvisoryRepositoryImpl.java
@@ -5,8 +5,10 @@
 import com.supwisdom.dlpay.framework.jpa.page.Pagination;
 import com.supwisdom.dlpay.framework.util.StringUtil;
 import com.supwisdom.dlpay.portal.bean.AdvisorySearchBean;
+import com.supwisdom.dlpay.portal.bean.PageSearchBean;
 import com.supwisdom.dlpay.portal.dao.AdvisoryRepository;
 import com.supwisdom.dlpay.portal.domain.TBAdvisory;
+import com.supwisdom.dlpay.portal.domain.TBPrompt;
 import org.hibernate.transform.Transformers;
 import org.jetbrains.annotations.NotNull;
 
@@ -43,4 +45,13 @@
     Finder f = Finder.create(sql);
     return findNative(f, Transformers.aliasToBean(TBAdvisory.class), pageno, pagesize);
   }
+
+  @NotNull
+  @Override
+  public Pagination getPromptList(@NotNull PageSearchBean bean) {
+    int pageno = bean.getPageno();
+    int pagesize = bean.getPagesize();
+    Finder f = Finder.create("select * from tb_prompt order by updatetime desc");
+    return findNative(f, Transformers.aliasToBean(TBPrompt.class), pageno, pagesize);
+  }
 }
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 9ead66d..c8ad430 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,7 +4,7 @@
 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.PageSearchBean;
 import com.supwisdom.dlpay.portal.bean.ColumnSearchBean;
 import com.supwisdom.dlpay.portal.dao.ColumnRepository;
 import com.supwisdom.dlpay.portal.domain.TBBanner;
@@ -42,7 +42,7 @@
 
   @NotNull
   @Override
-  public Pagination getBannerList(@NotNull BannerSearchBean bean) {
+  public Pagination getBannerList(@NotNull PageSearchBean bean) {
     int pageno = bean.getPageno();
     int pagesize = bean.getPagesize();
     Finder f = Finder.create("select * from tb_banner order by ordernum ");
diff --git a/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBPrompt.java b/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBPrompt.java
new file mode 100644
index 0000000..c3790c0
--- /dev/null
+++ b/backend/src/main/java/com/supwisdom/dlpay/portal/domain/TBPrompt.java
@@ -0,0 +1,68 @@
+package com.supwisdom.dlpay.portal.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "tb_prompt")
+public class TBPrompt {
+  @Id
+  @GenericGenerator(name = "idGenerator", strategy = "uuid")
+  @GeneratedValue(generator = "idGenerator")
+  @Column(name = "id", nullable = false, length = 32)
+  private String id;
+
+  @Column(name = "title", length = 50)
+  private String title;
+
+  @Column(name = "content", length = 1000)
+  private String content;
+
+  @Column(name = "code", length = 20)
+  private String code;
+
+  @Column(name = "updatetime", length = 14)
+  private String updatetime;
+
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public String getTitle() {
+    return title;
+  }
+
+  public void setTitle(String title) {
+    this.title = title;
+  }
+
+  public String getContent() {
+    return content;
+  }
+
+  public void setContent(String content) {
+    this.content = content;
+  }
+
+  public String getCode() {
+    return code;
+  }
+
+  public void setCode(String code) {
+    this.code = code;
+  }
+
+  public String getUpdatetime() {
+    return updatetime;
+  }
+
+  public void setUpdatetime(String updatetime) {
+    this.updatetime = updatetime;
+  }
+}
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 401b4a0..0e59219 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
@@ -332,7 +332,7 @@
      */
     @RequestMapping("/advisory/list")
     fun getActivity(@RequestHeader("Authorization") auth: String?,
-                   pageno:Int,pagesize:Int): JsonResult? {
+                    pageno: Int, pagesize: Int): JsonResult? {
         try {
             val page = advisoryService.getMobileAdvisoryList(pageno, pagesize)
             return JsonResult.ok().put("data", page)
@@ -350,7 +350,7 @@
      */
     @RequestMapping("/outlets/nearby")
     fun getNearbyOutlets(@RequestHeader("Authorization") auth: String?,
-                    location:String,distance:Double): JsonResult? {
+                         location: String, distance: Double): JsonResult? {
         try {
             val data = outletsService.getNearbyOutlets(location, distance)
             return JsonResult.ok().put("data", data)
@@ -370,7 +370,7 @@
     fun getNearbyOutlets(@RequestHeader("Authorization") auth: String?): JsonResult? {
         try {
             val list = columnService.getAllBanner()
-            return JsonResult.ok().put("data",list)
+            return JsonResult.ok().put("data", list)
         } catch (e: Exception) {
             logger.error { e.message }
             if (e is PortalBusinessException) {
@@ -412,7 +412,7 @@
             }
             val refundMedicalDtl = medicalService.refundMedicalDtlInit(bean)
             val medicalDtl = medicalService.refundMedicalDtlConfirm(bean.outOrderNumber, refundMedicalDtl)
-            val map = HashMap<String,String>()
+            val map = HashMap<String, String>()
             val jsonResult = JsonResult.ok()
             if (medicalDtl.paystatus == MedicalConstant.DTL_STATUS_SUCCESS) {
                 map["refundNumber"] = medicalDtl.hisrefundno
@@ -422,7 +422,7 @@
             map["status"] = medicalDtl.paystatus
             map["transdate"] = medicalDtl.transdate
             map["transtime"] = medicalDtl.transtime
-            return jsonResult.put("data",map)
+            return jsonResult.put("data", map)
         } catch (e: Exception) {
             logger.error("系统异常", e)
             if (e is MedicineException) {
@@ -450,7 +450,7 @@
             }
             val refundMedicalDtl = medicalService.refundMedicalDtlInit(bean)
             val medicalDtl = medicalService.refundQuickPayConfirm(bean.outOrderNumber, refundMedicalDtl)
-            val map = HashMap<String,String>()
+            val map = HashMap<String, String>()
             val jsonResult = JsonResult.ok()
             if (medicalDtl.paystatus == MedicalConstant.DTL_STATUS_SUCCESS) {
                 map["refundNumber"] = medicalDtl.hisrefundno
@@ -460,7 +460,7 @@
             map["status"] = medicalDtl.paystatus
             map["transdate"] = medicalDtl.transdate
             map["transtime"] = medicalDtl.transtime
-            return jsonResult.put("data",map)
+            return jsonResult.put("data", map)
         } catch (e: Exception) {
             logger.error("系统异常", e)
             if (e is MedicineException) {
@@ -484,7 +484,7 @@
                 return JsonResult.error("token检验失败,请检查是否正确")
             }
             val medicalDtl = medicalService.queryRefundResult(bean)
-            val map = HashMap<String,String>()
+            val map = HashMap<String, String>()
             val jsonResult = JsonResult.ok()
             if (medicalDtl.paystatus == MedicalConstant.DTL_STATUS_SUCCESS) {
                 map["refundNumber"] = medicalDtl.hisrefundno
@@ -510,7 +510,7 @@
     @RequestMapping(value = ["/security/list"], method = [RequestMethod.GET])
     fun getSecretSecurityList(phone: String?): JsonResult? {
         return try {
-            val user:TBMobileUser
+            val user: TBMobileUser
             user = if (phone.isNullOrEmpty()) {
                 val p = SecurityContextHolder.getContext().authentication
                 mobileApiService.findUserById(p.name)
@@ -540,7 +540,7 @@
                     ?: return JsonResult.error("用户不存在,请注册")
             bean.uid = user.uid
             val error = secretSecurityService.checkUserSecurity(bean)
-            return JsonResult.ok().put("error",error)
+            return JsonResult.ok().put("error", error)
         } catch (e: Exception) {
             if (e is PortalBusinessException) {
                 return JsonResult.error(e.message)
@@ -597,7 +597,8 @@
                 if (!version.isNullOrEmpty()) {
                     val split = version.split("##")
                     if (split[1].toInt() > verno.toInt()) {
-                        return JsonResult.ok().put("prompt", "您当前使用的应用不是最新版本,如要升级请至应用商店更新")
+                        val updatePrompt = advisoryService.getPromptByCode("updateApp")
+                        return JsonResult.ok().put("prompt", updatePrompt.content)
                     }
                 }
                 return JsonResult.ok().put("prompt", null)
@@ -630,6 +631,20 @@
             JsonResult.error(e.message)
         }
     }
+
+    /**
+     * 获取提示信息
+     */
+    @RequestMapping(value = ["/prompt/get/{code}"], method = [RequestMethod.GET])
+    fun getPrompt(@PathVariable code: String): JsonResult? {
+        return try {
+            val prompt = advisoryService.getPromptByCode(code)
+            JsonResult.ok().put("prompt",prompt.content)
+        } catch (e: Exception) {
+            logger.error("获取提示信息异常",e)
+            JsonResult.ok().put("prompt","")
+        }
+    }
 }
 
 
@@ -802,7 +817,7 @@
         if (exsitUser != null) {
             return JsonResult.error("该银行卡号已被绑定,若您本人绑定,请先解除绑定,若非本人,请联系客服")
         }
-        val bindCardResult = userProxy.bindCard(BindCardParam().apply{
+        val bindCardResult = userProxy.bindCard(BindCardParam().apply {
             this.cardno = cardno
             this.name = name
             this.idtype = idtype
@@ -848,7 +863,7 @@
         if (user.phone.isNullOrEmpty()) {
             return JsonResult.error("手机号不存在,请注册")
         }
-        val bindCardCodeResult = userProxy.bindCardCode(user.userid!!,user.phone)
+        val bindCardCodeResult = userProxy.bindCardCode(user.userid!!, user.phone)
         if (bindCardCodeResult["retcode"] != 0) {
             logger.error { "获取绑卡验证码失败,${bindCardCodeResult["retmsg"]}" }
             return JsonResult.error("获取验证码失败,${bindCardCodeResult["retmsg"]}")
@@ -950,7 +965,7 @@
                 })
                 if (cardResponse.retcode != 0) {
                     logger.error { "查询用户[${user.userid}]卡片信息失败:${cardResponse.retmsg}" }
-                    return JsonResult.error(-1,"卡片不存在,请重新绑定")
+                    return JsonResult.error(-1, "卡片不存在,请重新绑定")
                 }
                 val card = cardResponse.card
                 if (card.signed) {
@@ -1040,7 +1055,7 @@
             this.userid = user.userid
             this.cardtype = ConstantUtil.CARDTYPE_BANKCARD
         })
-        var card:QueryCardInfo? = null
+        var card: QueryCardInfo? = null
         if (cardResponse.retcode == 0) {
             card = cardResponse.card
         }
@@ -1233,7 +1248,7 @@
         }
         val card = cardResponse.card
         val personResponse = userProxy.queryPerson(user.userid)
-        if (personResponse.retcode!= 0) {
+        if (personResponse.retcode != 0) {
             logger.error { "查询用户[${user.userid}]信息失败:${personResponse.retmsg}" }
             return JsonResult.error("查询用户信息失败,请稍后重试")
         }
@@ -1307,10 +1322,10 @@
         val p = SecurityContextHolder.getContext().authentication
         val user = mobileApiService.findUserById(p.name)
                 ?: return JsonResult.error("用户不存在,请注册")
-        if(TradeDict.STATUS_NORMAL!=user.status){
+        if (TradeDict.STATUS_NORMAL != user.status) {
             return JsonResult.error("用户状态异常")
         }
-        if(user.userid.isNullOrEmpty()){
+        if (user.userid.isNullOrEmpty()) {
             return JsonResult.error("用户未绑定身份")
         }
         val cardResponse = userProxy.queryCard(QueryCardParam().apply {
@@ -1319,10 +1334,10 @@
         })
         if (cardResponse.retcode != 0) {
             logger.error { "查询用户[${user.userid}]卡片信息失败:${cardResponse.retmsg}" }
-            return JsonResult.error(-1,"银行卡信息不存在,请重新绑定")
+            return JsonResult.error(-1, "银行卡信息不存在,请重新绑定")
         }
         if (!cardResponse.card.signed) {
-            return JsonResult.error(-1,"请先签约银行卡")
+            return JsonResult.error(-1, "请先签约银行卡")
         }
         val qrcodeResult = userProxy.qrcode(QrcodeParam().apply {
             this.uid = user.uid
@@ -1467,7 +1482,7 @@
      * 发布留言
      */
     @RequestMapping(value = ["/feedback/release"], method = [RequestMethod.POST])
-    fun releaseFeedback(@RequestBody bean: FeedbackBean,request:HttpServletRequest): JsonResult? {
+    fun releaseFeedback(@RequestBody bean: FeedbackBean, request: HttpServletRequest): JsonResult? {
         val p = SecurityContextHolder.getContext().authentication
         val user = mobileApiService.findUserById(p.name)
                 ?: return JsonResult.error("用户不存在,请注册")
@@ -1480,7 +1495,7 @@
         if (!user.userid.isNullOrEmpty()) {
             feedback.userid = user.userid
         }
-        feedbackService.saveFeedback(feedback,bean.pictures)
+        feedbackService.saveFeedback(feedback, bean.pictures)
         return JsonResult.ok()
     }
 
@@ -1488,7 +1503,7 @@
      * 查询留言列表接口
      */
     @RequestMapping(value = ["/feedback/list"], method = [RequestMethod.GET])
-    fun getFeedbackList(pagesize:Int,pageno:Int): JsonResult? {
+    fun getFeedbackList(pagesize: Int, pageno: Int): JsonResult? {
         val p = SecurityContextHolder.getContext().authentication
         val user = mobileApiService.findUserById(p.name)
                 ?: return JsonResult.error("用户不存在,请注册")
@@ -1497,27 +1512,27 @@
             this.pagesize = pagesize
             this.mobileid = user.uid
         })
-        return JsonResult.ok().put("data",data)
+        return JsonResult.ok().put("data", data)
     }
 
     /**
      * 查询单条留言详情
-    */
+     */
     @RequestMapping(value = ["/feedback/{fbid}"], method = [RequestMethod.GET])
-    fun getFeedbackDetail(@PathVariable fbid:String): JsonResult? {
+    fun getFeedbackDetail(@PathVariable fbid: String): JsonResult? {
         val p = SecurityContextHolder.getContext().authentication
         val user = mobileApiService.findUserById(p.name)
                 ?: return JsonResult.error("用户不存在,请注册")
         val feedback = feedbackService.getFeedbackDetail(fbid, user.uid)
                 ?: return JsonResult.error("未找到该条留言")
-        return JsonResult.ok().put("data",feedback)
+        return JsonResult.ok().put("data", feedback)
     }
 
     /**
      * 删除留言
      */
     @RequestMapping(value = ["/feedback/delete/{fbid}"], method = [RequestMethod.POST])
-    fun deleteFeedback(@PathVariable fbid:String): JsonResult? {
+    fun deleteFeedback(@PathVariable fbid: String): JsonResult? {
         val p = SecurityContextHolder.getContext().authentication
         val user = mobileApiService.findUserById(p.name)
                 ?: return JsonResult.error("用户不存在,请注册")
@@ -1530,8 +1545,8 @@
      * 查询用户总积分
      */
     @Suppress("UNCHECKED_CAST")
-    @RequestMapping(value = ["/point/total"],method = [RequestMethod.GET])
-    fun getTotalPoint():JsonResult?{
+    @RequestMapping(value = ["/point/total"], method = [RequestMethod.GET])
+    fun getTotalPoint(): JsonResult? {
         val p = SecurityContextHolder.getContext().authentication
         val user = mobileApiService.findUserById(p.name)
                 ?: return JsonResult.error("用户不存在,请注册")
@@ -1541,12 +1556,12 @@
                 this.cardtype = ConstantUtil.CARDTYPE_CITIZENCARD
             })
             if (cardResponse.retcode != 0) {
-                return JsonResult.ok().put("data",0)
+                return JsonResult.ok().put("data", 0)
             }
             val card = cardResponse.card
             val personResponse = userProxy.queryPerson(card.userid)
             if (personResponse.retcode != 0) {
-                return JsonResult.ok().put("data",0)
+                return JsonResult.ok().put("data", 0)
             }
             val person = personResponse.person
             val pointResponse = userProxy.getUserPoints(UserPointsParam().apply {
@@ -1559,23 +1574,23 @@
                 logger.error { "查询用户[${user.userid}]积分失败" }
                 return JsonResult.error("查询积分失败")
             }
-            val page = pointResponse["page"] as LinkedHashMap<String,Any>
-            val data = page["data"] as ArrayList<LinkedHashMap<String,Any>>
+            val page = pointResponse["page"] as LinkedHashMap<String, Any>
+            val data = page["data"] as ArrayList<LinkedHashMap<String, Any>>
             if (data.isNotEmpty()) {
-                val pointsMain = data[0]["tPointsMain"] as LinkedHashMap<String,Any>
-                return JsonResult.ok().put("data",pointsMain["points"])
+                val pointsMain = data[0]["tPointsMain"] as LinkedHashMap<String, Any>
+                return JsonResult.ok().put("data", pointsMain["points"])
             }
-            return JsonResult.ok().put("data",0)
-        }else{
-            return JsonResult.ok().put("data",0)
+            return JsonResult.ok().put("data", 0)
+        } else {
+            return JsonResult.ok().put("data", 0)
         }
     }
 
     /**
      * 查询用户积分流水
      */
-    @RequestMapping(value = ["/point/flow"],method = [RequestMethod.GET])
-    fun getTotalPoint(pageno:Int,pagesize:Int):JsonResult?{
+    @RequestMapping(value = ["/point/flow"], method = [RequestMethod.GET])
+    fun getTotalPoint(pageno: Int, pagesize: Int): JsonResult? {
         val p = SecurityContextHolder.getContext().authentication
         val user = mobileApiService.findUserById(p.name)
                 ?: return JsonResult.error("用户不存在,请注册")
@@ -1588,12 +1603,12 @@
                 this.cardtype = ConstantUtil.CARDTYPE_CITIZENCARD
             })
             if (cardResponse.retcode != 0) {
-                return JsonResult.ok().put("data",emptyResult)
+                return JsonResult.ok().put("data", emptyResult)
             }
             val card = cardResponse.card
             val personResponse = userProxy.queryPerson(card.userid)
             if (personResponse.retcode != 0) {
-                return JsonResult.ok().put("data",emptyResult)
+                return JsonResult.ok().put("data", emptyResult)
             }
             val person = personResponse.person
             val pointResponse = userProxy.getUserPoints(UserPointsParam().apply {
@@ -1606,17 +1621,17 @@
                 logger.error { "查询用户[${user.userid}]积分流水失败" }
                 return JsonResult.error("查询积分流水失败")
             }
-            return JsonResult.ok().put("data",pointResponse["page"])
-        }else{
-            return JsonResult.ok().put("data",emptyResult)
+            return JsonResult.ok().put("data", pointResponse["page"])
+        } else {
+            return JsonResult.ok().put("data", emptyResult)
         }
     }
 
     /**
      * 完成积分任务
      */
-    @RequestMapping(value = ["/point/task/{taskcode}"],method = [RequestMethod.POST])
-    fun completePointTask(@PathVariable taskcode:String):JsonResult?{
+    @RequestMapping(value = ["/point/task/{taskcode}"], method = [RequestMethod.POST])
+    fun completePointTask(@PathVariable taskcode: String): JsonResult? {
         try {
             val p = SecurityContextHolder.getContext().authentication
             val user = mobileApiService.findUserById(p.name)
@@ -1627,7 +1642,7 @@
                     logger.error { "查询用户[${user.userid}]信息失败:${personResponse.retmsg}" }
                     return JsonResult.error("查询用户信息失败,请稍后重试")
                 }
-                return userService.completePointTask(user,taskcode)
+                return userService.completePointTask(user, taskcode)
             } else {
                 return JsonResult.error("未绑定银行卡,不能获取积分")
             }
@@ -1635,7 +1650,7 @@
             if (e is PortalBusinessException) {
                 return JsonResult.error(e.message)
             }
-            logger.error("系统异常",e)
+            logger.error("系统异常", e)
             return JsonResult.error("服务器繁忙,请稍后重试")
         }
     }
@@ -1643,19 +1658,19 @@
     /**
      * 查询积分状态
      */
-    @RequestMapping(value = ["/point/taskstatus"],method = [RequestMethod.GET])
-    fun completePointTask():JsonResult?{
+    @RequestMapping(value = ["/point/taskstatus"], method = [RequestMethod.GET])
+    fun completePointTask(): JsonResult? {
         try {
             val p = SecurityContextHolder.getContext().authentication
             val user = mobileApiService.findUserById(p.name)
                     ?: return JsonResult.error("用户不存在,请注册")
             val result = userService.queryPointTaskStatus(user)
-            return JsonResult.ok().put("data",result)
+            return JsonResult.ok().put("data", result)
         } catch (e: Exception) {
             if (e is PortalBusinessException) {
                 return JsonResult.error(e.message)
             }
-            logger.error("系统异常",e)
+            logger.error("系统异常", e)
             return JsonResult.error("服务器繁忙,请稍后重试")
         }
     }
@@ -1678,7 +1693,7 @@
      * 发送邮件
      */
     @RequestMapping(value = ["/email/send"], method = [RequestMethod.POST])
-    fun sendEmail(email: String,type: String): JsonResult? {
+    fun sendEmail(email: String, type: String): JsonResult? {
         return try {
             if (!email.matches(Regex("^[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}$"))) {
                 return JsonResult.error("邮箱格式错误,请检查后再试")
@@ -1764,7 +1779,7 @@
     fun getAllSecretSecurity(): JsonResult? {
         return try {
             val data = secretSecurityService.getAllSecretSecurity()
-            JsonResult.ok().put("data",data)
+            JsonResult.ok().put("data", data)
         } catch (e: Exception) {
             if (e is PortalBusinessException) {
                 return JsonResult.error(e.message)
@@ -1857,5 +1872,5 @@
         }
     }
 
-    
+
 }
\ No newline at end of file
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 6670dca..a8745f8 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/PortalApi.kt
@@ -1,7 +1,6 @@
 package com.supwisdom.dlpay.portal
 
 import com.supwisdom.dlpay.api.bean.JsonResult
-import com.supwisdom.dlpay.api.bean.QueryUserParam
 import com.supwisdom.dlpay.api.service.UploadPicService
 import com.supwisdom.dlpay.framework.core.JwtConfig
 import com.supwisdom.dlpay.framework.core.JwtTokenUtil
@@ -284,7 +283,7 @@
      * 获取轮播图列表
      */
     @RequestMapping("/column/bannerlist")
-    fun getBannerList(bean: BannerSearchBean): JsonResult? {
+    fun getBannerList(bean: PageSearchBean): JsonResult? {
         return try {
             val page = columnService.getBannerList(bean)
             if (page.list == null || page.list.size == 0) {
@@ -603,7 +602,7 @@
      * 重置管理员密码
      */
     @RequestMapping(value = ["/operator/resetpwd/{operid}"], method = [RequestMethod.POST])
-    fun resetPassword(@PathVariable operid:String): JsonResult? {
+    fun resetPassword(@PathVariable operid: String): JsonResult? {
         return try {
             operatorDetailService.resetPassword(operid)
             JsonResult.ok()
@@ -618,7 +617,7 @@
      */
     @RequestMapping(value = ["/operator/switchstatus/{operid}"], method = [RequestMethod.POST])
     fun switchStatus(@PathVariable(value = "operid") operid: String,
-                          @RequestParam(value = "status") status: String): JsonResult? {
+                     @RequestParam(value = "status") status: String): JsonResult? {
         return try {
             val result = operatorDetailService.switchStatus(operid, status)
             JsonResult.ok().put("result", result)
@@ -644,4 +643,59 @@
             JsonResult.error("查询操作员列表失败")
         }
     }
+
+    /**
+     * 保存提示
+     */
+    @RequestMapping(value = ["/prompt/save"], method = [RequestMethod.POST])
+    fun savePrompt(@RequestBody prompt: TBPrompt): JsonResult? {
+        return try {
+            advisoryService.savePrompt(prompt)
+            JsonResult.ok()
+        } catch (e: Exception) {
+            logger.error("保存提示异常", e)
+            if (e is PortalBusinessException) {
+                return JsonResult.error(e.message)
+            }
+            JsonResult.error("保存提示失败")
+        }
+    }
+
+    /**
+     * 获取提示列表
+     */
+    @RequestMapping(value = ["/prompt/list"], method = [RequestMethod.GET])
+    fun getPromptList(bean: PageSearchBean): JsonResult? {
+        return try {
+            val page = advisoryService.getPromptList(bean)
+            if (page.list == null || page.list.size == 0) {
+                return JsonResult.ok().put("msg", "无数据")
+            }
+            JsonResult.ok().put("page", page)
+        } catch (e: Exception) {
+            logger.error("获取提示列表异常", e)
+            if (e is PortalBusinessException) {
+                return JsonResult.error(e.message)
+            }
+            JsonResult.error("获取提示列表失败")
+        }
+    }
+
+    /**
+     * 删除提示
+     */
+    @RequestMapping(value = ["/prompt/delete/{promptid}"], method = [RequestMethod.POST])
+    fun deletePrompt(@PathVariable promptid: String): JsonResult? {
+        return try {
+            advisoryService.deletePrompt(promptid)
+            JsonResult.ok()
+        } catch (e: Exception) {
+            logger.error("删除提示异常", e)
+            if (e is PortalBusinessException) {
+                return JsonResult.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/PageSearchBean.kt
similarity index 78%
rename from backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/BannerSearchBean.kt
rename to backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/PageSearchBean.kt
index 4eee697..e5d1b48 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/BannerSearchBean.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/bean/PageSearchBean.kt
@@ -1,6 +1,6 @@
 package com.supwisdom.dlpay.portal.bean
 
-class BannerSearchBean {
+class PageSearchBean {
     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/AdvisoryRepository.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/AdvisoryRepository.kt
index cfd40a2..00c611c 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/AdvisoryRepository.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/AdvisoryRepository.kt
@@ -2,8 +2,10 @@
 
 import com.supwisdom.dlpay.framework.jpa.page.Pagination
 import com.supwisdom.dlpay.portal.bean.AdvisorySearchBean
+import com.supwisdom.dlpay.portal.bean.PageSearchBean
 
 interface AdvisoryRepository {
     fun getAdvisoryList(bean: AdvisorySearchBean): Pagination
     fun getMobileAdvisoryList(pageno: Int, pagesize: Int): Pagination
+    fun getPromptList(bean: PageSearchBean): Pagination
 }
\ 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 d704e94..9da2c05 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,12 +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.PageSearchBean
 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 getBannerList(bean: PageSearchBean): Pagination
     fun getAllBanner(): List<TBBanner>
 }
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/PromptDao.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/PromptDao.kt
new file mode 100644
index 0000000..ac3b743
--- /dev/null
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/dao/PromptDao.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.dlpay.portal.dao
+
+import com.supwisdom.dlpay.portal.domain.TBPrompt
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface PromptDao : JpaRepository<TBPrompt, String> {
+    fun findByCode(code: String): TBPrompt?
+}
\ No newline at end of file
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/AdvisoryService.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/AdvisoryService.kt
index 832a6ba..5bdf8ee 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/AdvisoryService.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/AdvisoryService.kt
@@ -2,18 +2,36 @@
 
 import com.supwisdom.dlpay.framework.jpa.page.Pagination
 import com.supwisdom.dlpay.portal.bean.AdvisorySearchBean
+import com.supwisdom.dlpay.portal.bean.PageSearchBean
 import com.supwisdom.dlpay.portal.domain.TBAdvisory
+import com.supwisdom.dlpay.portal.domain.TBPrompt
 import org.springframework.transaction.annotation.Transactional
 
 interface AdvisoryService {
     @Transactional
-    fun saveAdvisory(advisory:TBAdvisory)
+    fun saveAdvisory(advisory: TBAdvisory)
+
     @Transactional
     fun getAdvisoryList(bean: AdvisorySearchBean): Pagination
+
     @Transactional
-    fun switchDisplay(advisoryid:String,value:String):String
+    fun switchDisplay(advisoryid: String, value: String): String
+
     @Transactional
-    fun deleteAdvisory(advisoryid:String)
+    fun deleteAdvisory(advisoryid: String)
+
     @Transactional
-    fun getMobileAdvisoryList(pageno:Int,pagesize:Int): Pagination
+    fun getMobileAdvisoryList(pageno: Int, pagesize: Int): Pagination
+
+    @Transactional
+    fun savePrompt(prompt: TBPrompt)
+
+    @Transactional
+    fun getPromptList(bean: PageSearchBean): Pagination
+
+    @Transactional
+    fun deletePrompt(promptid: String)
+
+    @Transactional
+    fun getPromptByCode(code: String): TBPrompt
 }
\ 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 82bd5db..89f2e56 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,7 @@
 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.PageSearchBean
 import com.supwisdom.dlpay.portal.bean.ColumnSearchBean
 import com.supwisdom.dlpay.portal.domain.TBBanner
 import com.supwisdom.dlpay.portal.domain.TBColumn
@@ -18,7 +18,7 @@
     fun getColumnList(bean: ColumnSearchBean): Pagination
 
     @Transactional
-    fun getBannerList(bean: BannerSearchBean): Pagination
+    fun getBannerList(bean: PageSearchBean): Pagination
 
     @Transactional(readOnly = true)
     fun getAllBanner():List<TBBanner>
diff --git a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/AdvisoryServiceImpl.kt b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/AdvisoryServiceImpl.kt
index 2e72d93..eb48c36 100644
--- a/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/AdvisoryServiceImpl.kt
+++ b/backend/src/main/kotlin/com/supwisdom/dlpay/portal/service/Impl/AdvisoryServiceImpl.kt
@@ -2,20 +2,26 @@
 
 import com.supwisdom.dlpay.framework.jpa.page.Pagination
 import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.mobile.exception.PortalBusinessException
 import com.supwisdom.dlpay.portal.bean.AdvisorySearchBean
+import com.supwisdom.dlpay.portal.bean.PageSearchBean
 import com.supwisdom.dlpay.portal.dao.AdvisoryDao
+import com.supwisdom.dlpay.portal.dao.PromptDao
 import com.supwisdom.dlpay.portal.domain.TBAdvisory
+import com.supwisdom.dlpay.portal.domain.TBPrompt
 import com.supwisdom.dlpay.portal.service.AdvisoryService
 import com.supwisdom.dlpay.portal.util.PortalConstant
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.stereotype.Service
 
 @Service
-class AdvisoryServiceImpl : AdvisoryService{
+class AdvisoryServiceImpl : AdvisoryService {
     @Autowired
     lateinit var systemUtilService: SystemUtilService
     @Autowired
     lateinit var advisoryDao: AdvisoryDao
+    @Autowired
+    lateinit var promptDao: PromptDao
 
     override fun saveAdvisory(advisory: TBAdvisory) {
         advisory.updatetime = systemUtilService.sysdatetime.hostdatetime
@@ -34,7 +40,7 @@
             advisory.isdisplay = value
             advisoryDao.save(advisory)
             return advisory.isdisplay
-        }else{
+        } else {
             throw RuntimeException("ID为:[${advisoryid}]的问答未找到")
         }
     }
@@ -43,12 +49,51 @@
         val optional = advisoryDao.findById(advisoryid)
         if (optional.isPresent) {
             advisoryDao.delete(optional.get())
-        }else{
+        } else {
             throw RuntimeException("ID为:[${advisoryid}]的问答未找到")
         }
     }
 
     override fun getMobileAdvisoryList(pageno: Int, pagesize: Int): Pagination {
-        return advisoryDao.getMobileAdvisoryList(pageno,pagesize)
+        return advisoryDao.getMobileAdvisoryList(pageno, pagesize)
+    }
+
+    override fun savePrompt(prompt: TBPrompt) {
+        prompt.updatetime = systemUtilService.sysdatetime.hostdatetime
+        if (prompt.id.isNullOrEmpty()) {
+            val codePrompt = promptDao.findByCode(prompt.code)
+            if (codePrompt != null) {
+                throw PortalBusinessException("已存在编号为[${prompt.code}]的提示,请更换")
+            }
+            promptDao.save(prompt)
+        } else {
+            // 修改时不能修改编号
+            val optional = promptDao.findById(prompt.id)
+            if (!optional.isPresent) {
+                throw PortalBusinessException("未找到id为[${prompt.id}]的提示,修改失败")
+            }
+            val tbPrompt = optional.get()
+            tbPrompt.title = prompt.title
+            tbPrompt.content = prompt.content
+            tbPrompt.updatetime = prompt.updatetime
+            promptDao.save(tbPrompt)
+        }
+    }
+
+    override fun getPromptList(bean: PageSearchBean): Pagination {
+        return advisoryDao.getPromptList(bean)
+    }
+
+    override fun deletePrompt(promptid: String) {
+        val optional = promptDao.findById(promptid)
+        if (!optional.isPresent) {
+            throw PortalBusinessException("未找到id为${promptid}的提示")
+        }
+        promptDao.delete(optional.get())
+    }
+
+    override fun getPromptByCode(code: String): TBPrompt {
+        return promptDao.findByCode(code)
+                ?: throw PortalBusinessException("未找到code为[${code}]的提示")
     }
 }
\ No newline at end of file
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 6985f35..7f258bc 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
@@ -3,7 +3,7 @@
 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.PageSearchBean
 import com.supwisdom.dlpay.portal.bean.ColumnSearchBean
 import com.supwisdom.dlpay.portal.dao.ArticleDao
 import com.supwisdom.dlpay.portal.dao.BannerDao
@@ -32,7 +32,7 @@
         return columnDao.getColumnList(bean)
     }
 
-    override fun getBannerList(bean: BannerSearchBean): Pagination {
+    override fun getBannerList(bean: PageSearchBean): Pagination {
         return columnDao.getBannerList(bean)
     }
 
@@ -52,11 +52,10 @@
 
     override fun deleteBanner(bannerid: String) {
         val optional = bannerDao.findById(bannerid)
-        if (optional.isPresent) {
-            bannerDao.delete(optional.get())
-        } else {
-            throw RuntimeException("为找到id为:[$bannerid]的轮播图")
+        if (!optional.isPresent) {
+            throw RuntimeException("未找到id为:[$bannerid]的轮播图")
         }
+        bannerDao.delete(optional.get())
     }
 
     override fun getAllColumnList(): List<TBColumn>? {
diff --git a/backend/src/main/resources/data-postgresql.sql b/backend/src/main/resources/data-postgresql.sql
index ee77003..56fe683 100644
--- a/backend/src/main/resources/data-postgresql.sql
+++ b/backend/src/main/resources/data-postgresql.sql
@@ -79,6 +79,11 @@
 INSERT INTO "tb_secret_security"("ssid", "createtime", "question", "sort") VALUES ('8721e26b78044749b75dc2bc19882c9f', '20210106160653', '您最熟悉的童年好友名字是?', 9);
 INSERT INTO "tb_secret_security"("ssid", "createtime", "question", "sort") VALUES ('b46cd79c01804250a2bedea089356406', '20210106160653', '您小学班主任的名字是?', 10);
 
+INSERT INTO "public"."tb_prompt"("id", "code", "content", "title", "updatetime") VALUES ('2c9cab9477d2fa1d0177d2fcd01f0001', 'rights', '1.公交乘车:普通卡9折、爱心卡、学生卡原价5折;阳光卡、老年卡每年享1500次免费乘坐。
+2.市民卡日(每月第一周的周六周日):到指定商户消费享受最低5折优惠。', '卡应用-我的权益-提示', '20210224161235');
+INSERT INTO "public"."tb_prompt"("id", "code", "content", "title", "updatetime") VALUES ('2c9cab9477d2fa1d0177d315676c0002', 'pointRules', '1.积分不得转让或买卖
+2.请正确合理使用积分', '我的积分-活动规则-提示', '20210224161249');
+INSERT INTO "public"."tb_prompt"("id", "code", "content", "title", "updatetime") VALUES ('2c9cab9477d328a70177d32c2a9b0001', 'updateApp', '您当前使用的应用不是最新版本,如要升级请至应用商店更新', 'App升级-提示', '20210224163342');
 
 
 
diff --git a/frontend/src/api/advisory.js b/frontend/src/api/advisory.js
index db9ed14..b48892f 100644
--- a/frontend/src/api/advisory.js
+++ b/frontend/src/api/advisory.js
@@ -30,3 +30,26 @@
     params: value
   })
 }
+
+export function savePrompt(data) {
+  return request({
+    url: '/prompt/save',
+    method: 'post',
+    data
+  })
+}
+
+export function getPromptList(query) {
+  return request({
+    url: '/prompt/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function deletePrompt(promptid) {
+  return request({
+    url: '/prompt/delete/' + promptid,
+    method: 'post'
+  })
+}
diff --git a/frontend/src/views/advisory/index.vue b/frontend/src/views/advisory/index.vue
index 7b24d62..3569fbb 100644
--- a/frontend/src/views/advisory/index.vue
+++ b/frontend/src/views/advisory/index.vue
@@ -1,131 +1,233 @@
 <template>
   <div class="app-container">
-    <div class="filter-container">
-      <div class="filter-item" style="margin-right:15px">问答标题</div>
-      <el-input
-        v-model="formData.title"
-        placeholder="咨询问答标题"
-        style="width: 350px;margin-right:50px"
-        class="filter-item"
-      />
-      <div class="filter-item" style="margin-right:15px">问答内容</div>
-      <el-input
-        v-model="formData.content"
-        placeholder="咨询问答内容"
-        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="!promptSet">
+      <div class="filter-container">
+        <div class="filter-item" style="margin-right:15px">问答标题</div>
+        <el-input
+          v-model="formData.title"
+          placeholder="咨询问答标题"
+          style="width: 350px;margin-right:50px"
+          class="filter-item"
+        />
+        <div class="filter-item" style="margin-right:15px">问答内容</div>
+        <el-input
+          v-model="formData.content"
+          placeholder="咨询问答内容"
+          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="addAdvisory()">
+        新增问答
       </el-button>
-    </div>
-    <el-button type="primary" icon="el-icon-circle-plus-outline" @click="addAdvisory()">
-      新增问答
-    </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="问答标题" width="150" align="center">
-        <template slot-scope="{row}">
-          <span>{{ row.title }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="问答内容" align="center">
-        <template slot-scope="{row}">
-          <span>{{ row.content }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="修改日期" align="center" width="160">
-        <template slot-scope="{row}">
-          <span>{{ dateFormat(row.updatetime) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="排序" width="80" align="center">
-        <template slot-scope="{row}">
-          <span>{{ row.ordernum }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column width="100px" label="是否展示" align="center">
-        <template slot-scope="{row}">
-          <el-switch
-            :value="row.isdisplay === '1'"
-            active-color="#13ce66"
-            inactive-color="#a7a7a7"
-            @click.native.prevent="switchDisplay(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 type="primary" icon="el-icon-edit" circle size="mini" @click="updateAdvisory(row)" />
-          </el-tooltip>
-          <el-tooltip class="item" effect="dark" content="删除" placement="bottom">
-            <el-button type="danger" icon="el-icon-delete" circle size="mini" @click="deleteAdvisory(row)" />
-          </el-tooltip>
-        </template>
-      </el-table-column>
-    </el-table>
+      <el-button type="primary" icon="el-icon-info" style="float:right" @click="setPrompt()">
+        提示设置
+      </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="问答标题" width="150" align="center">
+          <template slot-scope="{row}">
+            <span>{{ row.title }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="问答内容" align="center">
+          <template slot-scope="{row}">
+            <span>{{ row.content }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="修改日期" align="center" width="160">
+          <template slot-scope="{row}">
+            <span>{{ dateFormat(row.updatetime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="排序" width="80" align="center">
+          <template slot-scope="{row}">
+            <span>{{ row.ordernum }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column width="100px" label="是否展示" align="center">
+          <template slot-scope="{row}">
+            <el-switch
+              :value="row.isdisplay === '1'"
+              active-color="#13ce66"
+              inactive-color="#a7a7a7"
+              @click.native.prevent="switchDisplay(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 type="primary" icon="el-icon-edit" circle size="mini" @click="updateAdvisory(row)" />
+            </el-tooltip>
+            <el-tooltip class="item" effect="dark" content="删除" placement="bottom">
+              <el-button type="danger" icon="el-icon-delete" circle size="mini" @click="deleteAdvisory(row)" />
+            </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="getAdvisoryList"
-    />
-    <el-dialog
-      :title="title"
-      :visible.sync="advisoryDialogVisible"
-      width="45%"
-    >
-      <div>
-        <el-form ref="advisoryForm" :model="advisoryForm" :rules="rules" label-width="100px">
-          <el-form-item label="问答标题" prop="title" class="form-input-item">
+      <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="formData.pageno"
+        :limit.sync="formData.pagesize"
+        style="margin-top:0;"
+        @pagination="getAdvisoryList"
+      />
+      <el-dialog
+        :title="title"
+        :visible.sync="advisoryDialogVisible"
+        width="45%"
+      >
+        <div>
+          <el-form ref="advisoryForm" :model="advisoryForm" :rules="rules" label-width="100px">
+            <el-form-item label="问答标题" prop="title" class="form-input-item">
+              <el-input
+                v-model="advisoryForm.title"
+                maxlength="30"
+                show-word-limit
+                style="width:80%"
+              />
+            </el-form-item>
+            <el-form-item label="问答排序" prop="ordernum">
+              <el-input-number v-model="advisoryForm.ordernum" :min="1" style="width:40%" />
+            </el-form-item>
+            <el-form-item label="问答内容" prop="content">
+              <el-input
+                v-model="advisoryForm.content"
+                type="textarea"
+                maxlength="230"
+                :rows="8"
+                placeholder=""
+                show-word-limit
+                style="width:80%"
+              />
+            </el-form-item>
+          </el-form>
+        </div>
+        <div style="text-align:center">
+          <el-button
+            type="primary"
+            @click="saveAdvisory('advisoryForm')"
+          >保存
+          </el-button>
+          <el-button @click="advisoryDialogVisible = false">取消</el-button>
+        </div>
+      </el-dialog>
+    </div>
+
+    <div v-show="promptSet">
+      <el-button type="primary" icon="el-icon-info" @click="addPrompt()">
+        新增提示
+      </el-button>
+      <el-button type="primary" icon="el-icon-back" style="float:right" @click="promptSet=false">
+        返回
+      </el-button>
+      <el-table
+        :key="promptTableKey"
+        :data="promptList"
+        border
+        fit
+        highlight-current-row
+        style="width: 100%;margin-top:10px"
+      >
+        <el-table-column label="提示标题" 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.code }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="修改日期" align="center" width="160">
+          <template slot-scope="{row}">
+            <span>{{ dateFormat(row.updatetime) }}</span>
+          </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="updatePrompt(row)" />
+            </el-tooltip>
+            <el-tooltip class="item" effect="dark" content="删除" placement="bottom">
+              <el-button type="danger" icon="el-icon-delete" circle size="mini" @click="deletePrompt(row)" />
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="promptTotal>0"
+        :total="promptTotal"
+        :page.sync="promptFormData.pageno"
+        :limit.sync="promptFormData.pagesize"
+        style="margin-top:0;"
+        @pagination="getPromptList"
+      />
+      <el-dialog
+        :title="promptTitle"
+        :visible.sync="promptDialogVisible"
+        width="40%"
+        @close="promptDialogVisible = false"
+      >
+        <el-form ref="promptForm" style="margin:20px 0 0 35px" label-width="100px" :rules="promptRule" :model="promptForm">
+          <el-form-item label="提示标题" prop="title" class="form-input-item">
             <el-input
-              v-model="advisoryForm.title"
-              maxlength="30"
+              v-model="promptForm.title"
+              maxlength="50"
               show-word-limit
+              placeholder="请输入提示标题"
               style="width:80%"
             />
           </el-form-item>
-          <el-form-item label="问答排序" prop="ordernum">
-            <el-input-number v-model="advisoryForm.ordernum" :min="1" style="width:40%" />
-          </el-form-item>
-          <el-form-item label="问答内容" prop="content">
+          <el-form-item label="提示编号" prop="code" class="form-input-item">
             <el-input
-              v-model="advisoryForm.content"
-              type="textarea"
-              maxlength="230"
-              :rows="8"
-              placeholder=""
+              v-model="promptForm.code"
+              maxlength="20"
               show-word-limit
+              :disabled="updatePromptFlag"
+              placeholder="请输入提示编号"
+              style="width:80%"
+            />
+          </el-form-item>
+          <el-form-item label="提示内容" prop="content">
+            <el-input
+              v-model="promptForm.content"
+              type="textarea"
+              maxlength="1000"
+              :rows="8"
+              placeholder="请输入提示内容"
               style="width:80%"
             />
           </el-form-item>
         </el-form>
-      </div>
-      <div style="text-align:center">
-        <el-button
-          type="primary"
-          @click="saveAdvisory('advisoryForm')"
-        >保存
-        </el-button>
-        <el-button @click="advisoryDialogVisible = false">取消</el-button>
-      </div>
-    </el-dialog>
+        <div style="text-align:center">
+          <el-button
+            type="primary"
+            @click="savePrompt('promptForm')"
+          >保存
+          </el-button>
+          <el-button @click="promptDialogVisible = false">取消</el-button>
+        </div>
+      </el-dialog>
+    </div>
   </div>
 </template>
 <script>
@@ -133,7 +235,10 @@
   saveAdvisory,
   getAdvisoryList,
   switchDisplay,
-  deleteAdvisory
+  deleteAdvisory,
+  savePrompt,
+  getPromptList,
+  deletePrompt
 } from '@/api/advisory'
 import moment from 'moment'
 import Pagination from '@/components/Pagination'
@@ -144,6 +249,8 @@
   },
   data() {
     return {
+      promptSet: false,
+      updatePromptFlag: true,
       advisoryDialogVisible: false,
       formData: {
         title: '',
@@ -151,10 +258,17 @@
         pageno: 1,
         pagesize: 10
       },
+      promptFormData: {
+        pageno: 1,
+        pagesize: 10
+      },
       listLoading: false,
       tableKey: 0,
       list: null,
+      promptTableKey: 1,
+      promptList: null,
       total: 0,
+      promptTotal: 0,
       title: '',
       advisoryForm: {
         advisoryid: '',
@@ -162,6 +276,14 @@
         content: '',
         ordernum: 1
       },
+      promptForm: {
+        id: '',
+        title: '',
+        code: '',
+        content: ''
+      },
+      promptTitle: '新增提示',
+      promptDialogVisible: false,
       rules: {
         title: [
           { required: true, message: '请输入问答标题', trigger: 'blur' }
@@ -169,6 +291,17 @@
         content: [
           { required: true, message: '请输入问答内容', trigger: 'blur' }
         ]
+      },
+      promptRule: {
+        title: [
+          { required: true, message: '请输入提示标题', trigger: 'blur' }
+        ],
+        code: [
+          { required: true, message: '请输入提示代码', trigger: 'blur' }
+        ],
+        content: [
+          { required: true, message: '请输入提示内容', trigger: 'blur' }
+        ]
       }
     }
   },
@@ -238,6 +371,17 @@
         this.$refs[formName].clearValidate()
       })
     },
+    resetPromptForm(formName) {
+      this.promptForm = {
+        id: '',
+        title: '',
+        code: '',
+        content: ''
+      }
+      this.$nextTick(() => {
+        this.$refs[formName].clearValidate()
+      })
+    },
     updateAdvisory(row) {
       this.title = '修改问答'
       this.resetForm('advisoryForm')
@@ -286,6 +430,91 @@
         })
       }).catch(() => {
       })
+    },
+    setPrompt() {
+      this.promptFormData.pageno = 1
+      this.getPromptList()
+      this.promptSet = true
+    },
+    getPromptList() {
+      getPromptList(this.promptFormData).then(response => {
+        if (response.page) {
+          this.promptList = response.page.list
+          this.promptTotal = response.page.totalCount
+        } else {
+          this.promptList = null
+          this.promptTotal = 0
+        }
+      }).catch(error => {
+        this.$message({
+          message: error.msg || '请求异常',
+          type: 'error'
+        })
+      })
+    },
+    addPrompt() {
+      this.promptTitle = '新增提示'
+      this.resetPromptForm('promptForm')
+      this.promptDialogVisible = true
+      this.updatePromptFlag = false
+    },
+    savePrompt(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          savePrompt(this.promptForm).then(response => {
+            this.$notify({
+              title: '成功',
+              message: '保存成功!',
+              type: 'success',
+              duration: 2000
+            })
+            this.promptDialogVisible = false
+            this.getPromptList()
+          }).catch(error => {
+            this.$message({
+              message: error.msg || '请求异常',
+              type: 'error'
+            })
+          })
+        } else {
+          return false
+        }
+      })
+    },
+    updatePrompt(row) {
+      this.promptForm = {
+        id: '',
+        title: '',
+        code: '',
+        content: ''
+      }
+      this.promptTitle = '修改提示'
+      this.resetPromptForm('promptForm')
+      this.promptForm = Object.assign({}, row)
+      this.promptDialogVisible = true
+      this.updatePromptFlag = true
+    },
+    deletePrompt(row) {
+      this.$confirm('是否确认删除该提示?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        deletePrompt(row.id).then(response => {
+          this.$message({
+            type: 'success',
+            message: '删除成功!'
+          })
+          this.promptFormData.pageno = 1
+          this.getPromptList()
+        }).catch(error => {
+          this.$message({
+            message: error.msg || '请求异常',
+            type: 'error'
+          })
+        })
+      }).catch(() => {
+      })
     }
   }
 }
diff --git a/frontend/src/views/article/components/ArticleDetail.vue b/frontend/src/views/article/components/ArticleDetail.vue
index 7a6139d..fefa8f5 100644
--- a/frontend/src/views/article/components/ArticleDetail.vue
+++ b/frontend/src/views/article/components/ArticleDetail.vue
@@ -33,13 +33,10 @@
                 标题
               </MDinput>
             </el-form-item>
-            <el-form-item label="排序" prop="ordernum">
-              <el-input-number v-model="postForm.ordernum" :min="1" style="width:20%" />
-            </el-form-item>
 
             <div class="postInfo-container">
               <el-row>
-                <el-col :span="8">
+                <el-col :span="7">
                   <el-form-item label-width="100px" prop="columnid" label="所属栏目:" class="postInfo-container-item">
                     <el-select
                       v-model="postForm.columnid"
@@ -58,6 +55,11 @@
                     </el-select>
                   </el-form-item>
                 </el-col>
+                <el-col :span="8">
+                  <el-form-item label="排序" prop="ordernum" label-width="100px" class="postInfo-container-item">
+                    <el-input-number v-model="postForm.ordernum" :min="1" />
+                  </el-form-item>
+                </el-col>
               </el-row>
             </div>
           </el-col>
@@ -158,6 +160,9 @@
     fetchData(id) {
       getArticle(id).then(response => {
         this.postForm = response.article
+        if (response.article.ordernum == null) {
+          this.postForm.ordernum = undefined
+        }
         console.log(response)
 
         // set tagsview title
diff --git a/frontend/src/views/article/list.vue b/frontend/src/views/article/list.vue
index 670e682..f879a93 100644
--- a/frontend/src/views/article/list.vue
+++ b/frontend/src/views/article/list.vue
@@ -8,20 +8,19 @@
         style="width: 320px;margin-right:50px"
         class="filter-item"
       />
-      <div class="filter-item" style="margin-right:15px">发布日期</div>
-      <el-date-picker
-        v-model="releaseDate"
-        type="daterange"
-        align="left"
-        style="width:320px;margin-right:50px"
-        unlink-panels
-        range-separator="至"
-        start-placeholder="开始日期"
-        end-placeholder="结束日期"
-        value-format="yyyyMMdd"
-        :picker-options="pickerOptions"
+      <div class="filter-item" style="margin-right:15px">文章状态</div>
+      <el-select
+        v-model="formData.status"
+        style="width:200px;margin-right:50px"
         class="filter-item"
-      />
+      >
+        <el-option
+          v-for="item in statusOptions"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value"
+        />
+      </el-select>
     </div>
     <div class="filter-container">
       <div class="filter-item" style="margin-right:15px">保存日期</div>
@@ -38,19 +37,20 @@
         :picker-options="pickerOptions"
         class="filter-item"
       />
-      <div class="filter-item" style="margin-right:15px">文章状态</div>
-      <el-select
-        v-model="formData.status"
-        style="width:200px;margin-right:120px"
+      <div class="filter-item" style="margin-right:15px">发布日期</div>
+      <el-date-picker
+        v-model="releaseDate"
+        type="daterange"
+        align="left"
+        style="width:320px;margin-right:50px"
+        unlink-panels
+        range-separator="至"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期"
+        value-format="yyyyMMdd"
+        :picker-options="pickerOptions"
         class="filter-item"
-      >
-        <el-option
-          v-for="item in statusOptions"
-          :key="item.value"
-          :label="item.label"
-          :value="item.value"
-        />
-      </el-select>
+      />
 
       <el-button
         class="filter-item"
diff --git a/frontend/src/views/column/index.vue b/frontend/src/views/column/index.vue
index 68b4e95..c7cd431 100644
--- a/frontend/src/views/column/index.vue
+++ b/frontend/src/views/column/index.vue
@@ -288,7 +288,7 @@
             @click="saveBanner()"
           >保存
           </el-button>
-          <el-button @click="imageDialogVisible = fasle">取消</el-button>
+          <el-button @click="imageDialogVisible = false">取消</el-button>
         </div>
       </el-dialog>
       <el-dialog :visible.sync="dialogVisible">