瀏覽代碼

消息实体建立;获取方法增加。结算页参加活动修改;用户中心修改。

dongbw 8 年之前
父節點
當前提交
42cbb5631e
共有 40 個文件被更改,包括 2636 次插入599 次删除
  1. 54 0
      donate-console/src/main/java/com/uas/console/donate/controller/MessageController.java
  2. 1 1
      donate-console/src/main/java/com/uas/console/donate/dao/ActivityDao.java
  3. 15 0
      donate-console/src/main/java/com/uas/console/donate/dao/MessageDao.java
  4. 15 0
      donate-console/src/main/java/com/uas/console/donate/dao/MessageDetailDao.java
  5. 1 1
      donate-console/src/main/java/com/uas/console/donate/dao/UserDao.java
  6. 239 0
      donate-console/src/main/java/com/uas/console/donate/model/Message.java
  7. 149 0
      donate-console/src/main/java/com/uas/console/donate/model/MessageDetail.java
  8. 28 0
      donate-console/src/main/java/com/uas/console/donate/service/MessageService.java
  9. 74 0
      donate-console/src/main/java/com/uas/console/donate/service/impl/MessageServiceImpl.java
  10. 5 4
      donate-console/src/main/webapp/WEB-INF/views/index.html
  11. 5 0
      donate-console/src/main/webapp/resources/css/base.css
  12. 386 2
      donate-console/src/main/webapp/resources/js/index/app.js
  13. 19 0
      donate-console/src/main/webapp/resources/js/index/services/Message.js
  14. 1 12
      donate-console/src/main/webapp/resources/view/activity/activity_launch.html
  15. 48 0
      donate-console/src/main/webapp/resources/view/message/message_detail.html
  16. 306 9
      donate-console/src/main/webapp/resources/view/message/message_edit.html
  17. 404 9
      donate-console/src/main/webapp/resources/view/message/message_list.html
  18. 174 0
      donate-console/src/main/webapp/resources/view/message/select_receiver_role.html
  19. 20 0
      donate-console/src/main/webapp/resources/view/message/timing_modal.html
  20. 2 2
      donate-console/src/main/webapp/resources/view/project/project_launch_2.html
  21. 4 8
      donate-console/src/main/webapp/resources/view/user/organization_detail.html
  22. 1 7
      donate-console/src/main/webapp/resources/view/user/organization_list.html
  23. 38 0
      donate-service/src/main/java/com/uas/service/donate/controller/MessageSendController.java
  24. 24 12
      donate-service/src/main/java/com/uas/service/donate/controller/UserController.java
  25. 15 0
      donate-service/src/main/java/com/uas/service/donate/dao/MessageDao.java
  26. 22 0
      donate-service/src/main/java/com/uas/service/donate/dao/MessageDetailDao.java
  27. 1 1
      donate-service/src/main/java/com/uas/service/donate/dao/ProjectDao.java
  28. 67 0
      donate-service/src/main/java/com/uas/service/donate/event/ProjectPublishEvent.java
  29. 31 0
      donate-service/src/main/java/com/uas/service/donate/listener/PublishListener.java
  30. 239 0
      donate-service/src/main/java/com/uas/service/donate/model/Message.java
  31. 149 0
      donate-service/src/main/java/com/uas/service/donate/model/MessageDetail.java
  32. 0 483
      donate-service/src/main/java/com/uas/service/donate/model/Organization.java
  33. 0 1
      donate-service/src/main/java/com/uas/service/donate/service/MessageService.java
  34. 19 6
      donate-service/src/main/java/com/uas/service/donate/service/UserService.java
  35. 0 1
      donate-service/src/main/java/com/uas/service/donate/service/impl/ProjectServiceImpl.java
  36. 46 7
      donate-service/src/main/java/com/uas/service/donate/service/impl/UserServiceImpl.java
  37. 24 17
      donate-service/src/main/webapp/resources/js/project/app.js
  38. 2 2
      donate-service/src/main/webapp/resources/js/user/controllers/UserCtrl.js
  39. 1 1
      donate-service/src/main/webapp/resources/view/project/donationsOver.html
  40. 7 13
      donate-service/src/main/webapp/resources/view/user/user_center.html

+ 54 - 0
donate-console/src/main/java/com/uas/console/donate/controller/MessageController.java

@@ -0,0 +1,54 @@
+package com.uas.console.donate.controller;
+
+import com.uas.console.donate.model.Message;
+import com.uas.console.donate.model.SearchFilter;
+import com.uas.console.donate.service.MessageService;
+import com.uas.platform.core.model.PageInfo;
+import com.uas.platform.core.model.PageParams;
+import com.uas.platform.core.util.serializer.FlexJsonUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 消息相关
+ * Created by dongbw
+ *
+ */
+@RestController
+@RequestMapping("/message")
+public class MessageController {
+
+    /**
+     * DAO
+     */
+    @Autowired
+    private MessageService messageService;
+
+    /**
+     * 获取所有消息
+     * @param pageParams 分页参数
+     * @param searchFilter 查找filter
+     * @return
+     */
+    @ResponseBody
+    @RequestMapping(value= "/getAll", method = RequestMethod.GET)
+    public Page<Message> getAllMessages(PageParams pageParams, String searchFilter){
+        PageInfo pageInfo = new PageInfo(pageParams);
+        SearchFilter filter = FlexJsonUtils.fromJson(searchFilter, SearchFilter.class);
+        return messageService.getAllMessages(pageInfo, filter);
+    }
+
+    /**
+     * 获取消息详情
+     * @param id 消息id
+     * @return 消息详情
+     */
+    @ResponseBody
+    @RequestMapping(value= "/detail/{id}", method = RequestMethod.GET)
+    public Message getDetailById(@PathVariable("id") Long id){
+        return messageService.getDetailById(id);
+    }
+
+
+}

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/dao/ActivityDao.java

@@ -13,7 +13,7 @@ import java.util.Date;
 import java.util.List;
 
 @Repository
-public interface ActivityDao extends JpaRepository<Activity,Long>,JpaSpecificationExecutor<Activity> {
+public interface ActivityDao extends JpaRepository<Activity, Long>, JpaSpecificationExecutor<Activity> {
     /**
      * 找出当前活动中的最大优先级
      * @return

+ 15 - 0
donate-console/src/main/java/com/uas/console/donate/dao/MessageDao.java

@@ -0,0 +1,15 @@
+package com.uas.console.donate.dao;
+
+import com.uas.console.donate.model.Message;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by dongbw
+ * 17/12/26 17:43.
+ */
+@Repository
+public interface MessageDao extends JpaRepository<Message, Long>, JpaSpecificationExecutor<Message>{
+
+}

+ 15 - 0
donate-console/src/main/java/com/uas/console/donate/dao/MessageDetailDao.java

@@ -0,0 +1,15 @@
+package com.uas.console.donate.dao;
+
+import com.uas.console.donate.model.MessageDetail;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by dongbw
+ * 17/12/26 17:46.
+ */
+@Repository
+public interface MessageDetailDao extends JpaRepository<MessageDetail, Long>, JpaSpecificationExecutor<MessageDetail>{
+
+}

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/dao/UserDao.java

@@ -8,7 +8,7 @@ import org.springframework.stereotype.Repository;
 import java.util.List;
 
 @Repository
-public interface UserDao extends JpaRepository<User,Long>,JpaSpecificationExecutor<User>{
+public interface UserDao extends JpaRepository<User,Long>, JpaSpecificationExecutor<User>{
 
     List<User> findByType(String type);
 }

+ 239 - 0
donate-console/src/main/java/com/uas/console/donate/model/Message.java

@@ -0,0 +1,239 @@
+package com.uas.console.donate.model;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ *  消息通知表
+ *
+ */
+@Entity
+@Table(name = "donate$message")
+public class Message implements Serializable {
+
+    /**
+     * 序号
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "dm_id")
+    private Long id;
+
+    /**
+     * 发布用户UU
+     */
+    @Column(name = "dm_useruu")
+    private Long userUU;
+
+    /**
+     * 发布用户
+     */
+    @OneToOne(cascade = CascadeType.REFRESH)
+    @JoinColumn(name = "dm_useruu", insertable = false, updatable = false)
+    private User user;
+
+    /**
+     * 提交时间
+     */
+    @Column(name = "dm_date")
+    private Date date;
+
+    /**
+     * 发布时间
+     */
+    @Column(name = "dm_publishdate")
+    private Date publishDate;
+
+    /**
+     * 消息标题
+     */
+    @Column(name = "dm_title")
+    private String title;
+
+    /**
+     * 消息正文
+     */
+    @Column(name = "dm_context")
+    private String context;
+
+    /**
+     * 消息类型(群体消息、私有消息)
+     */
+    @Column(name = "dm_type")
+    private String type;
+
+    /**
+     * 来源表
+     */
+    @Column(name = "dm_table")
+    private String table;
+
+    /**
+     * 来源id
+     */
+    @Column(name = "dm_sourceid")
+    private Long sourceId;
+
+    /**
+     * 单据链接
+     */
+    @Column(name = "dm_url")
+    private String url;
+
+    /**
+     * 消息明细
+     */
+    @OneToMany(mappedBy = "message", cascade = CascadeType.REFRESH)
+    @OrderBy("dmd_id DESC")
+    private Set<MessageDetail> messageDetails;
+
+    /**
+     * 接收对象
+     */
+    @Column(name = "dm_receiver")
+    private String receiver;
+
+    /**
+     * 阅读人数
+     */
+    @Column(name = "dm_readernum")
+    private Integer readerNum;
+
+    /**
+     * 消息接收人数
+     */
+    @Column(name = "dm_receivernum")
+    private Integer receiverNum;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getUserUU() {
+        return userUU;
+    }
+
+    public void setUserUU(Long userUU) {
+        this.userUU = userUU;
+    }
+
+    public User getUser() {
+        return user;
+    }
+
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public Date getPublishDate() {
+        return publishDate;
+    }
+
+    public void setPublishDate(Date publishDate) {
+        this.publishDate = publishDate;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getContext() {
+        return context;
+    }
+
+    public void setContext(String context) {
+        this.context = context;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getTable() {
+        return table;
+    }
+
+    public void setTable(String table) {
+        this.table = table;
+    }
+
+    public Long getSourceId() {
+        return sourceId;
+    }
+
+    public void setSourceId(Long sourceId) {
+        this.sourceId = sourceId;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    @JsonIgnore
+    @JSONField(serialize = false)
+    public Set<MessageDetail> getNoticeDetails() {
+        return messageDetails;
+    }
+
+    public void setNoticeDetails(Set<MessageDetail> noticeDetails) {
+        this.messageDetails = noticeDetails;
+    }
+
+    public String getReceiver() {
+        return receiver;
+    }
+
+    public void setReceiver(String receiver) {
+        this.receiver = receiver;
+    }
+
+    public Integer getReaderNum() {
+        return readerNum;
+    }
+
+    public void setReaderNum(Integer readerNum) {
+        this.readerNum = readerNum;
+    }
+
+    public Integer getReceiverNum() {
+        return this.receiverNum;
+    }
+
+    public void setReceiverNum(Integer receiverNum) {
+        this.receiverNum = receiverNum;
+    }
+}

+ 149 - 0
donate-console/src/main/java/com/uas/console/donate/model/MessageDetail.java

@@ -0,0 +1,149 @@
+package com.uas.console.donate.model;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 消息明细表
+ *
+ */
+@Entity
+@Table(name = "donate$messagedetail")
+public class MessageDetail implements Serializable{
+
+    /**
+     * 序号
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "dmd_id")
+    private Long id;
+
+    /**
+     * 接收人UU
+     */
+    @Column(name = "dmd_receiveuseruu")
+    private Long receiveUserUU;
+
+    /**
+     * 关联接收人
+     */
+    @OneToOne
+    @JoinColumn(name = "dmd_receiveuseruu", insertable = false, updatable = false)
+    private User receiveUser;
+
+    /**
+     * 阅读时间
+     */
+    @Column(name = "dmd_readdate")
+    private Date readDate;
+
+    /**
+     * 阅读状态 0未读,1已读
+     */
+    @Column(name = "dmd_readstatus")
+    private Short readStatus;
+
+    /**
+     * 获取状态 0未获取,1已获取
+     */
+    @Column(name = "dmd_status")
+    private Short status;
+
+    /**
+     * 推送状态 0未推送,1已推送
+     */
+    @Column(name = "dmd_pushstatus")
+    private Short pushStatus;
+
+    /**
+     * 统计状态 0未统计,1已统计
+     */
+    @Column(name = "dmd_totalstatus")
+    private Short totalStatus;
+
+    /**
+     * 消息主表
+     */
+    @ManyToOne(cascade = CascadeType.ALL)
+    @JoinColumn(name = "dmd_dmid", nullable = false)
+    private Message message;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getReceiveUserUU() {
+        return receiveUserUU;
+    }
+
+    public void setReceiveUserUU(Long receiveUserUU) {
+        this.receiveUserUU = receiveUserUU;
+    }
+
+    public User getReceiveUser() {
+        return receiveUser;
+    }
+
+    public void setReceiveUser(User receiveUser) {
+        this.receiveUser = receiveUser;
+    }
+
+    public Date getReadDate() {
+        return readDate;
+    }
+
+    public void setReadDate(Date readDate) {
+        this.readDate = readDate;
+    }
+
+    public Short getReadStatus() {
+        return readStatus;
+    }
+
+    public void setReadStatus(Short readStatus) {
+        this.readStatus = readStatus;
+    }
+
+    public Short getStatus() {
+        return status;
+    }
+
+    public void setStatus(Short status) {
+        this.status = status;
+    }
+
+    public Short getPushStatus() {
+        return pushStatus;
+    }
+
+    public void setPushStatus(Short pushStatus) {
+        this.pushStatus = pushStatus;
+    }
+
+    public Short getTotalStatus() {
+        return totalStatus;
+    }
+
+    public void setTotalStatus(Short totalStatus) {
+        this.totalStatus = totalStatus;
+    }
+
+    public Message getNotice() {
+        return message;
+    }
+
+    public void setNotice(Message notice) {
+        this.message = notice;
+    }
+}

+ 28 - 0
donate-console/src/main/java/com/uas/console/donate/service/MessageService.java

@@ -0,0 +1,28 @@
+package com.uas.console.donate.service;
+
+import com.uas.console.donate.model.Message;
+import com.uas.console.donate.model.SearchFilter;
+import com.uas.platform.core.model.PageInfo;
+import org.springframework.data.domain.Page;
+
+/**
+ * Created by dongbw
+ * 17/12/26 17:46.
+ */
+
+public interface MessageService {
+    /**
+     * 获取所有消息
+     * @param pageInfo 分页参数
+     * @param filter 查找filter
+     * @return 消息Page
+     */
+    Page<Message> getAllMessages(PageInfo pageInfo, SearchFilter filter);
+
+    /**
+     * 获取详情
+     * @param id 消息id
+     * @return 消息实体
+     */
+    Message getDetailById(Long id);
+}

+ 74 - 0
donate-console/src/main/java/com/uas/console/donate/service/impl/MessageServiceImpl.java

@@ -0,0 +1,74 @@
+package com.uas.console.donate.service.impl;
+
+import com.uas.console.donate.dao.MessageDao;
+import com.uas.console.donate.dao.MessageDetailDao;
+import com.uas.console.donate.model.Message;
+import com.uas.console.donate.model.SearchFilter;
+import com.uas.console.donate.service.MessageService;
+import com.uas.platform.core.model.PageInfo;
+import com.uas.platform.core.persistence.criteria.PredicateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+/**
+ * Created by dongbw
+ * 17/12/26 17:47.
+ */
+@Service
+public class MessageServiceImpl implements MessageService {
+
+    @Autowired
+    private MessageDao messageDao;
+
+    @Autowired
+    private MessageDetailDao messageDetailDao;
+
+    /**
+     * 获取所有消息
+     *
+     * @param pageInfo 分页参数
+     * @param filter   查找filter
+     * @return 消息Page
+     */
+    @Override
+    public Page<Message> getAllMessages(final PageInfo pageInfo, final SearchFilter filter) {
+        return messageDao.findAll(new Specification<Message>() {
+            public Predicate toPredicate(Root<Message> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
+                if (null != filter) {
+                    String keyword = filter.getKeyword();
+                    if (StringUtils.hasText(keyword)) {
+                        pageInfo.expression(PredicateUtils.or(PredicateUtils.like("title", keyword, false),
+                                PredicateUtils.like("context", keyword, false),
+                                PredicateUtils.like("type", keyword, false),
+                                PredicateUtils.like("user.name", keyword, false)));
+                    }
+                    // 根据其实时间过滤
+                    if (null != filter.getFromDate()) {
+                        pageInfo.expression(PredicateUtils.gte("publishDate", filter.getFromDate(), false));
+                    }
+                }
+                query.where(pageInfo.getPredicates(root, query, builder));
+                return null;
+            }
+        }, pageInfo);
+    }
+
+    /**
+     * 获取详情
+     *
+     * @param id 消息id
+     * @return 消息实体
+     */
+    @Override
+    public Message getDetailById(Long id) {
+        return messageDao.findOne(id);
+    }
+}

+ 5 - 4
donate-console/src/main/webapp/WEB-INF/views/index.html

@@ -112,8 +112,9 @@
                         <i class="fa fa-angle-left pull-right"></i>
                     </a>
                     <ul class="treeview-menu">
-                        <li ng-class="{'active' : thief == 'new'}"><a >编辑消息</a></li>
-                        <li ng-class="{'active' : thief == 'list'}"><a >消息列表</a></li>
+                        <!-- TODO 暂时隐藏,稍后完善 -->
+                        <!--<li ng-class="{'active' : thief == 'new'}"><a ui-sref="editMessage">编辑消息</a></li>-->
+                        <li ng-class="{'active' : thief == 'list'}"><a ui-sref="messageList">消息列表</a></li>
                     </ul>
                 </li>
                 <li class="treeview" ng-class="{'active' : tree == 'manage'}" id="front">
@@ -122,8 +123,8 @@
                     </a>
                     <ul class="treeview-menu">
                         <li><a href="http://10.10.101.23:20010/carousels/donate" target="_blank">Banner设置(PC)</a></li>
-                        <li><a href="http://10.10.101.23:20010/carousels/donate" target="_blank">Banner设置(IM)</a></li>
-                        <li ng-class="{'active' : thief == 'banner'}"><a >内容框背景设置</a></li>
+                        <li><a href="http://10.10.101.23:20010/carousels/donate-app" target="_blank">Banner设置(IM)</a></li>
+                        <!--<li ng-class="{'active' : thief == 'banner'}"><a >内容框背景设置</a></li>-->
                     </ul>
                 </li>
                 <li class="jpress_block"></li>

+ 5 - 0
donate-console/src/main/webapp/resources/css/base.css

@@ -293,4 +293,9 @@ div.active-time ul.dropdown-menu span.btn-group.pull-left>button.btn:first-child
 div.active-time ul.dropdown-menu span.btn-group.pull-left>button.btn:nth-child(2){
 	border-bottom-left-radius: 3px;
 	border-top-left-radius: 3px;
+}
+
+/* 富文本编辑框ul ol 显示 */
+.introduce .note-editable ol,.introduce .note-editable ul{
+	padding-left: 20px;
 }

+ 386 - 2
donate-console/src/main/webapp/resources/js/index/app.js

@@ -2,9 +2,9 @@
  * index
  *
  */
-define([ 'angularAMD', 'ui.router', 'ui-bootstrap', 'ngLocal', 'ngTable', 'file-upload', 'common/directives', 'common/services', 'toaster', 'ngSanitize', 'services/Project', 'services/Activity', 'services/Organization', 'ui-form', 'services/User'], function(angularAMD) {
+define([ 'angularAMD', 'ui.router', 'ui-bootstrap', 'ngLocal', 'ngTable', 'file-upload', 'common/directives', 'common/services', 'toaster', 'ngSanitize', 'services/Project', 'services/Activity', 'services/Organization', 'ui-form', 'services/User', 'services/Message'], function(angularAMD) {
 	'use strict';
-	var app = angular.module('myApp', [ 'ui.router', 'ui.bootstrap', 'ng.local', 'ngTable', 'angularFileUpload', 'common.directives', 'common.services', 'toaster', 'ngSanitize', 'ProjectService', 'ActivityService', 'OrganizationService', 'ui.form', 'UserService']);
+	var app = angular.module('myApp', [ 'ui.router', 'ui.bootstrap', 'ng.local', 'ngTable', 'angularFileUpload', 'common.directives', 'common.services', 'toaster', 'ngSanitize', 'ProjectService', 'ActivityService', 'OrganizationService', 'ui.form', 'UserService', 'MessageService']);
         app.init = function() {
 		angularAMD.bootstrap(app);
 	};
@@ -141,9 +141,35 @@ define([ 'angularAMD', 'ui.router', 'ui-bootstrap', 'ngLocal', 'ngTable', 'file-
             title : '用户列表',
             templateUrl : 'static/view/user/user_list.html',
             controller : 'UserListCtrl'
+        }).state("editMessage", {
+            url : '/message/new',
+            title : '编辑消息',
+            templateUrl : 'static/view/message/message_edit.html',
+            controller : 'MessageNewCtrl'
+        }).state("messageList", {
+            url : '/message/list',
+            title : '消息列表',
+            templateUrl : 'static/view/message/message_list.html',
+            controller : 'MessageListCtrl'
         });
 	}]);
 
+    // 富文本编辑器配置
+    var editorConfig = {
+        dialogsInBody: true,
+        lang: 'zh-CN',
+        toolbar:[
+            ['edit',['undo','redo']],
+            ['style',['bold','italic','underline','clear' ]],
+            ['para',['ul','ol','paragraph']],
+            ['style', ['style']],
+            ['color',['color']],
+            ['table', ['table']],
+            ['insert', ['link', 'picture', 'hr']],
+            ['view', ['fullscreen', 'codeview']]
+        ]
+    };
+
     // html转义
     var htmlEncode = function(sHtml) {
         return sHtml.replace(/[<>&"]/g,function(c){return {'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;'}[c];});
@@ -1412,6 +1438,7 @@ define([ 'angularAMD', 'ui.router', 'ui-bootstrap', 'ngLocal', 'ngTable', 'file-
         BaseService.scrollBackToTop();
         $rootScope.tree = 'project';
         $rootScope.thief = 'new';
+        $scope.editorConfig = editorConfig;
         // 默认捐助领域
         $scope.defaultAreas = ['疾病援助', '扶贫/救灾', '教育/助学' , '环境/动物保护', '其他'];
 
@@ -2373,6 +2400,7 @@ define([ 'angularAMD', 'ui.router', 'ui-bootstrap', 'ngLocal', 'ngTable', 'file-
         $rootScope.tree = 'activity';
         $rootScope.thief = 'new';
         $scope.loading = true;
+        $scope.editorConfig = editorConfig;
         $scope.activity = {
             awards:[],
             projects: []
@@ -3250,5 +3278,361 @@ define([ 'angularAMD', 'ui.router', 'ui-bootstrap', 'ngLocal', 'ngTable', 'file-
             };
         }]);
 
+    /**
+     * 新增消息
+     */
+    app.controller('MessageNewCtrl', ['$scope', 'BaseService', 'toaster', 'Message', '$http', '$upload', '$rootScope', '$modal',
+        function($scope, BaseService, toaster, Message, $http, $upload, $rootScope, $modal) {
+            BaseService.scrollBackToTop();
+            $rootScope.tree = 'message';
+            $rootScope.thief = 'new';
+            $scope.loading = true;
+            $scope.editorConfig = editorConfig;
+
+            $scope.message = {};
+            // 默认按角色类型发送
+            $scope.ifPersonal = 0;
+
+            // 日期选择
+            $scope.openDatePicker = function ($event, item, openParam) {
+                $event.preventDefault();
+                $event.stopPropagation();
+                item[openParam] = !item[openParam];
+            };
+
+            /**
+             * 选择接收对象
+             */
+            $scope.selectReceiver = function (ifPersonal) {
+                if (ifPersonal === 1) {
+                    // 指定用户模态框
+
+                } else {
+                    // 按角色类型模态框
+                    $modal.open({
+                        animation: true,
+                        size: 'lg',
+                        templateUrl: 'static/view/message/select_receiver_role.html',
+                        controller: 'RoleReceiverChooseCtrl',
+                        // resolve: {
+                        //     message: function () {
+                        //         return $scope.message;
+                        //     }
+                        // }
+                    }).result.then(function (data) {
+                        //TODO 选择接收对象
+                    }, function () {
+
+                    });
+                }
+            };
+
+            /**
+             * 删除接受对象
+             */
+            $scope.deleteReceiver = function() {
+
+            };
+
+            // 获取用户列表
+            var getUsers= function() {
+            };
+            getUsers();
+
+            // 搜索项目
+            $scope.onSearch = function() {
+                getUsers();
+            };
+
+            // 添加选中
+            $scope.addSelected = function() {
+                var i = 0;
+                for (i; i< $scope.projects.length; i++) {
+                    var project = $scope.projects[i];
+                    if (project.checked) {
+                        project.checked = false;
+                        if (angular.isUndefined($scope.selectedProjects)) {
+                            $scope.selectedProjects = [];
+                        }
+                        $scope.selectedProjects.push(project);
+                        $scope.projects.splice(i, 1);
+                        i = i-1;
+                    }
+                }
+            };
+
+            // 删除选中
+            $scope.deleteSelected = function() {
+                var i = 0;
+                for (i; i< $scope.selectedProjects.length; i++) {
+                    var project = $scope.selectedProjects[i];
+                    if (project.checked) {
+                        project.checked = false;
+                        $scope.projects.push(project);
+                        $scope.selectedProjects.splice(i, 1);
+                        i = i -1;
+                    }
+                }
+            };
+
+            // 取消
+            $scope.cancelSelected = function() {
+                $scope.projects = angular.copy($scope.tempProjects);
+                $scope.selectedProjects = angular.copy($scope.tempSelectedProjects);
+            };
+
+            // 保存
+            $scope.saveSelected = function() {
+                $scope.tempProjects = angular.copy($scope.projects);
+                $scope.tempSelectedProjects = angular.copy($scope.selectedProjects);
+            };
+
+            //TODO 奖品图片上传(修改编辑器图片上传可参考)
+            $scope.uploadPrizeImg = function(award, index) {
+                $scope.loading = true;
+                var files = award.prizeImgs, file = files && files.length > 0 ? files[0] : null;
+                $upload.upload({
+                    url: 'activity/upload/prizeImg',
+                    method: 'POST',
+                    file: file
+                }).success(function (data) {
+                    $scope.awards[index].img = data.path;
+                    $scope.loading = false;
+                }).error(function (data) {
+                    $scope.loading = false;
+                    // toaster.pop('error', '错误', data);
+                });
+            };
+
+            //TODO 发布通知
+            $scope.publishMessage = function(invalid) {
+                if (invalid == true) {
+                    $scope.submited = true;
+                    BaseService.scrollBackToTop();
+                    return;
+                }
+                $scope.loading = true;
+                var projectList = [];
+                angular.forEach($scope.selectedProjects, function (project) {
+                    projectList.push(project);
+                });
+                $scope.activity.projects = projectList;
+                $scope.activity.awards = $scope.awards;
+                var url;
+                if (type) {
+                    url = 'activity/submit';
+                } else {
+                    url = 'activity/save';
+                }
+                var data = new FormData();
+                data.append('actImg', $scope.actImg);
+                data.append('banner', $scope.banner);
+                // data.append('award1', $scope.award1);
+                // data.append('award2', $scope.award2);
+                // data.append('award3', $scope.award3);
+                // data.append('award4', $scope.award4);
+                data.append('jsonStr', JSON.stringify($scope.activity));
+                $http({
+                    headers: {
+                        'Content-Type': undefined
+                    },
+                    method: 'POST',
+                    processData: false,
+                    async: false,
+                    url: url,
+                    data: data
+                }).success(function (data) {
+                    if (type) {
+                        toaster.pop('success', '发布成功');
+                    } else {
+                        toaster.pop('success', '保存成功');
+                    }
+                    $scope.loading = false;
+                    window.location.hash = '#/activity';
+                }).error(function (data) {
+                    $scope.loadingShow = false;
+                    toaster.pop('error', '出现错误,操作失败');
+                });
+                // }
+            }
+
+        }]);
+
+    /**
+     * 选择接收对象
+     */
+    app.controller('RoleReceiverChooseCtrl', ['$scope', 'BaseService', 'toaster', 'Message', '$http', '$upload', '$rootScope', '$modal', 'ngTableParams',
+        function($scope, BaseService, toaster, Message, $http, $upload, $rootScope, $modal, ngTableParams) {
+            $scope.loading = true;
+            $scope.active = 'personal';
+            $scope.orgs = [];
+            $scope.checkedAll = false;
+
+            /**
+             * 修改用户类型
+             * @param value 类型
+             */
+            $scope.setActive = function(value) {
+                if ($scope.active !== value) {
+                    $scope.active = value;
+                    if ($scope.userParams.page === 1) {
+                        $scope.userParams.reload();
+                    } else {
+                        $scope.userParams.page(1);
+                    }
+                }
+            };
+
+            /**
+             * 全选
+             */
+            $scope.checkAll = function() {
+                $scope.checkedAll = !$scope.checkedAll;
+                angular.forEach($scope.orgs, function(org) {
+                    org.checked = $scope.checkedAll;
+                });
+            };
+
+            /**
+             * 根据数据类型获取用户列表
+             */
+            $scope.loading = false;
+        }]);
+
+    /**
+     * 消息列表
+     */
+    app.controller('MessageListCtrl', ['$scope', '$rootScope', 'toaster', 'ngTableParams', 'BaseService', 'Message', '$modal',
+        function ($scope, $rootScope, toaster, ngTableParams, BaseService, Message, $modal) {
+            BaseService.scrollBackToTop();
+            $rootScope.tree = 'message';
+            $rootScope.thief = 'list';
+
+            $scope.keyword = '';
+
+            $scope.fromDate = null;
+            // 设置时间过滤
+            $scope.setTime = function(type) {
+                var fromDate = new Date();
+                switch (type) {
+                    // 最近6小时
+                    case '6' :
+                        fromDate.setHours(fromDate.getHours() - 6) ;
+                        $scope.fromDate = fromDate;
+                        break;
+                    // 最近24小时
+                    case '24' :
+                        fromDate.setDate(fromDate.getDate() - 1) ;
+                        $scope.fromDate = fromDate;
+                        break;
+                    // 最近3天
+                    case '3' :
+                        fromDate.setDate(fromDate.getDate() - 3) ;
+                        $scope.fromDate = fromDate;
+                        break;
+                    // 最近7天
+                    case '7' :
+                        fromDate.setDate(fromDate.getDate() - 7) ;
+                        $scope.fromDate = fromDate;
+                        break;
+                }
+                $scope.messageParams.reload();
+            };
+
+            $scope.reload = function() {
+                if ($scope.messageParams.page() == 1)
+                    $scope.messageParams.reload();
+                else
+                    $scope.messageParams.page(1);
+            };
+
+            $scope.messageParams = new ngTableParams({
+                page: 1,
+                count: 10,
+                sorting: {
+                    'id': 'desc'
+                }
+            }, {
+                total: 0,
+                counts: [],
+                getData: function ($defer, params) {
+                    $scope.loading = true;
+                    var pageParams = params.url();
+                    var realActive = {};
+                    pageParams.searchFilter = { // 筛选条件
+                        keyword: $scope.keyword,
+                        fromDate : null !== $scope.fromDate ? $scope.fromDate.getTime(): null,
+                    };
+                    Message.getAll.call(null, BaseService.parseParams(pageParams), function (page) {
+                        $scope.loading = false;
+                        if (page) {
+                            params.total(page.totalElements);
+                            $defer.resolve(page.content);
+                            // $scope.keywordXls = angular.copy($scope.keyword); // 保存当前取值的关键词  做导出时需要的字段
+                        }
+                    }, function (response) {
+                        $scope.loading = false;
+                        toaster.pop('error', '数据加载失败', response.data);
+                    });
+                }
+            });
+
+            $scope.onSearch = function () {
+                if ($scope.messageParams.page() == 1)
+                    $scope.messageParams.reload();
+                else
+                    $scope.messageParams.page(1);
+            };
+
+            // 弹出详情页模态框
+            $scope.showDetail = function (message) {
+                var modalInstance = $modal.open({
+                    templateUrl: 'static/view/message/message_detail.html',
+                    controller: 'MessageDetailCtrl',
+                    size: 'lg',
+                    resolve: {
+                        message: function () {
+                            return message;
+                        }
+                    }
+                });
+
+                modalInstance.result.then(function(data){
+                    $scope.messageParams.reload();
+                }, function(){
+
+                });
+
+            };
+
+
+        }]);
+
+    /**
+     * 消息详情框
+     */
+    app.controller('MessageDetailCtrl', ['$scope', 'Message', 'toaster', '$modalInstance', 'BaseService', 'message',
+        function($scope, Message, toaster, $modalInstance, BaseService, message, $modal) {
+
+            $scope.message = message;
+
+            $scope.cancel= function() {
+                $modalInstance.dismiss();
+            };
+
+            $scope.delete = function(id) {
+                Message.delete({id: id}, {}, function(data) {
+                    if (data.success) {
+                        toaster.pop('success', data.success);
+                        $modalInstance.close(data);
+                    }
+                    if (data.error) {
+                        toaster.pop('error', data.error);
+                    }
+                });
+            };
+        }]);
+
+
     return app;
 });

+ 19 - 0
donate-console/src/main/webapp/resources/js/index/services/Message.js

@@ -0,0 +1,19 @@
+define ([ 'ngResource' ], function() {
+    angular.module('MessageService', ['ngResource'])
+        .factory('Message', ['$resource', function ($resource) {
+        return $resource ('message', {}, {
+            getAll : {
+                url: 'message/getAll',
+                method: 'GET'
+            },
+            // 获取消息详情
+            getDetailById: {
+                url: 'message/detail/:id',
+                method: 'GET',
+                params: {
+                    id: 'id'
+                }
+            }
+        });
+    }]);
+});

+ 1 - 12
donate-console/src/main/webapp/resources/view/activity/activity_launch.html

@@ -627,17 +627,6 @@
         -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6);
         box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6);
     }
-
-    /* datepicker 今天按钮隐藏,清除按钮样式修改 */
-    div.active-time ul.dropdown-menu span.btn-group.pull-left>button.btn:first-child{
-        display: none;
-    }
-
-    div.active-time ul.dropdown-menu span.btn-group.pull-left>button.btn:nth-child(2){
-        border-bottom-left-radius: 3px;
-        border-top-left-radius: 3px;
-    }
-
 </style>
 <!-- loading start -->
 <div class="loading in" ng-class="{'in': loading}"><i></i></div>
@@ -712,7 +701,7 @@
                     <div class="form-group clearfix">
                         <label class="control-label fl">活动介绍</label>
                         <div class="fl introduce">
-                            <summernote lang="zh-CN" ng-model="activity.summary" height="300px" maxlength="3500">
+                            <summernote lang="zh-CN" ng-model="activity.summary" height="300px" config="editorConfig" maxlength="3500">
                             </summernote>
                         </div>
                         <span class="error" ng-show="submited && !activity.summary">*请填写活动介绍</span>

+ 48 - 0
donate-console/src/main/webapp/resources/view/message/message_detail.html

@@ -0,0 +1,48 @@
+<!--右侧内容部分-->
+<aside class="content-right">
+    <!--<div class="container">-->
+    <div class="right-header clearfix">
+        <div class="fl"><span>{{message.title}}</span></div>
+        <div class="fr close">&times;</div>
+    </div>
+    <div class="right-nav"><span class="active">信息详情</span></div>
+    <!--信息详情-->
+    <div class="right-list show">
+        <div class="list-message">
+            <div class="list-body clearfix">
+                <div class="msg-list fl">
+                    <span class="fl">发送时间</span>
+                    <span class="fl">{{message.publishDate | date: 'yyyy-MM-dd HH:mm:ss'}}</span>
+                </div>
+                <div class="msg-list fl">
+                    <span class="fl">发送人</span>
+                    <span class="fl">{{message.user.name}}</span>
+                </div>
+                <div class="msg-list fl">
+                    <span class="fl">接收对象</span>
+                    <span class="fl count">{{message.receiver}}</span>
+                </div>
+            </div>
+        </div>
+        <div class="list-message">
+            <div class="list-header">
+                <span>具体内容</span>
+            </div>
+            <div class="list-body">
+                <div class="message-list">
+                    <div class="txt">
+                        <span ng-bind-html="message.context"></span>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--</div>-->
+</aside>
+<script>
+    $('.right-nav').on('click', 'span', function () {
+        var index = $(this).index();
+        $(this).addClass('active').siblings().removeClass('active');
+        $('.right-list').eq(index).addClass('show').siblings().removeClass('show');
+    });
+</script>

+ 306 - 9
donate-console/src/main/webapp/resources/view/message/message_edit.html

@@ -1,10 +1,307 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <title>Title</title>
-</head>
-<body>
+<style>
+    body{
+        font-family: "Microsoft Yahei", "微软雅黑";
+        box-sizing: border-box;
+    }
+    .clearfix {
+        clear: both;
+    }
+    .content-header{
+        padding-left: 22px;
+    }
+    .content .box-show{
+        position: relative;
+        margin-top: 4px;
+        padding-left: 22px;
+        border-radius: 3px;
+        background: #ffffff;
+        margin-bottom: 20px;
+        width: 100%;
+        height: 620px;
+        border: 1px solid #dcdcdc;
+        box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+    }
+    .content-setting{
+        margin-top: 24px;
+    }
+    .content-setting .form-group{
+        margin-bottom: 14px;
+        height: 30px;
+        line-height: 30px;
+    }
+    .content-setting .form-group label{
+        margin: 0 22px 0 14px;
+        font-family: 'SimHei'!important;
+        width: 60px;
+        font-size: 14px;
+        font-weight: normal;
+        color: #8da8b8;
+    }
+    .content-setting .form-group input{
+        margin-right: 15px;
+        width: 780px;
+        height: 30px;
+        font-size: 14px;
+        color: #323232;
+        border-radius: 0;
+    }
+    .content-setting .edit {
+        position: relative;
+        width: 780px;
+        height: 30px;
+    }
 
-</body>
-</html>
+    .content-setting .edit div.choose{
+        position: absolute;
+        top: 4px;
+        left: 10px;
+        width: 110px;
+        height: 22px;
+        line-height: 22px;
+        text-align: center;
+        background: #3c8dbc;
+        border-radius: 30px;
+        cursor: pointer;
+    }
+    .content-setting .edit div.choose span{
+        margin-right: 10px;
+        font-family: 'SimHei'!important;
+        font-size: 12px;
+        color: #fff;
+    }
+    .content-setting .edit div.choose i{
+        font-size: 16px;
+        color: #fff;
+    }
+    .introduce {
+        width: 780px;
+        height: 380px;
+    }
+    .introduce .intro-header {
+        /*position: relative;*/
+        width: 100%;
+        height: 54px;
+        line-height: 54px;
+        background: -webkit-linear-gradient(top, #fff 0%,#dadada 100%);
+        background: -o-linear-gradient(top, #fff 0%,#dadada 100%);
+        background: -ms-linear-gradient(top, #fff 0%,#dadada 100%);
+        background: linear-gradient(to bottom, #fff 0%,#dadada 100%);
+        border: 1px solid #ccc;
+        border-bottom: none;
+    }
+    .introduce .intro-header span{
+        font-size: 16px;
+        color: #323232;
+    }
+    .introduce .intro-header span img{
+        margin-left: 30px;
+    }
+    .introduce .intro-header span em{
+        margin-left: 8px;
+        font-size: 16px;
+        color: #323232;
+        font-style: normal;
+    }
+    .introduce .intro-header span input{
+        position: absolute;
+        top: 119px;
+        left: 338px;
+        width: 65px;
+        outline: none;
+        opacity: 0;
+    }
+    .introduce textarea{
+        width: 780px;
+        height: 325px;
+        border: 1px solid #ccc;
+        border-top: none;
+        border-radius: 0;
+    }
+    .introduce .button{
+        margin-top: 30px;
+    }
+    .introduce .button a{
+        display: inline-block ;
+        width: 140px;
+        height: 34px;
+        line-height: 34px;
+        text-align: center;
+        font-size: 16px;
+        font-family: 'SimHei'!important;
+        border-radius: 3px;
+    }
+    .introduce .button a:first-child {
+        margin-right: 26px;
+        color: #fff;
+        background: #3c8dbc;
+    }
+    .introduce .button a:last-child {
+        color: #787878;
+        background: #fff;
+        border: 1px solid #dcdcdc;
+    }
+    /*定时发送弹出框*/
+    .modal-open .modal {
+        width: 100%;
+        height: 100%;
+    }
+    .modal-open .modal .modal-dialog{
+        width: 450px;
+        height: 180px;
+    }
+    .setting{
+        margin: 0 auto;
+        width: 450px;
+        height: 180px;
+        text-align: center;
+    }
+    .setting .header{
+        padding: 0 20px;
+        width: 100%;
+        height: 44px;
+        line-height: 44px;
+        background: #eeeeee;
+    }
+    .setting .header p{
+        font-size: 16px;
+        color: #323232;
+    }
+    .setting .header .close{
+        font-size: 38px;
+    }
+    .setting .body{
+        width: 100%;
+        height: 80px;
+        padding: 0 20px;
+        text-align: left;
+    }
+    .setting .body .form-group{
+        padding-top: 20px;
+        height: 30px;
+        line-height: 30px;
+    }
+    .setting .body .form-group label{
+        margin-right: 22px;
+        font-family: 'SimHei'!important;
+        font-size: 14px;
+        font-weight: normal;
+        color: #8da8b8;
+    }
+    .setting .body .form-group input{
+        width: 200px;
+        height: 30px;
+        border-radius: 0;
+    }
+    .setting .footer{
+        padding-top: 10px;
+        width: 100%;
+        height: 50px;
+        background: #f4f4f4;
+    }
+    .setting .footer a{
+        display: inline-block;
+        height: 30px;
+        line-height: 30px;
+        font-size: 16px;
+        text-align: center;
+        border-radius: 3px;
+        letter-spacing: 10px;
+    }
+    .setting .footer a:first-child{
+        margin-right: 10px;
+        width: 120px;
+        color: #fff;
+        background: #3c8dbc;
+    }
+    .setting .footer a:last-child{
+        width: 80px;
+        color: #959595;
+        background: #fff;
+        border: 1px solid #dcdcdc;
+    }
+
+    /* 富文本编辑器input大小控制 */
+    div.fl.introduce input{
+       width: 80%;
+    }
+</style>
+<div class="wrapper">
+    <!--主体内容-->
+    <div class="content-wrapper" style="min-height: 924px;; z-index: 50;">
+        <section class="content-header clearfix">
+            <h1>编辑消息</h1>
+        </section>
+        <!-- Main content -->
+        <section class="content">
+            <form name="messageForm">
+                <div class="box-show">
+                    <div class="content-setting">
+                        <div class="form-group clearfix">
+                            <label class="control-label fl">接收对象</label>
+                            <div class="edit fl">
+                                <select class="form-control input-sm jp-width120" ng-model="ifPersonal">
+                                    <option value="0">按角色类型</option>
+                                    <option value="1">指定用户</option>
+                                </select>
+                            </div>
+                            <!--<div class="edit fl">-->
+                                <!--<input style="cursor: pointer;" type="text" class="form-control" id="chooseReceiver" ng-click="selectReceiver()" placeholder="点击选择接受对象" readonly/>-->
+                                <!--<div ng-if="message.receiver" class="choose"><span ng-click="selectReceiver()" ng-bind="message.receiver" title="重新选择"></span><i class="fa fa-close" ng-click="deleteReceiver()" title="删除"></i></div>-->
+                            <!--</div>-->
+                        </div>
+                        <div class="form-group clearfix">
+                            <label class="control-label fl">&nbsp;</label>
+                            <span style="cursor: pointer; color: #5078cb;" ng-click="selectReceiver(ifPersonal)"><i class="fa fa-plus-square"></i>选择接收对象</span>
+                        </div>
+                        <div class="form-group clearfix">
+                            <label class="control-label fl">主题</label>
+                            <input type="text" ng-model="message.title" class="form-control fl" placeholder="请填写消息主题" required/>
+                        </div>
+                        <div class="form-group clearfix">
+                            <label class="control-label fl">消息内容</label>
+                            <div class="fl introduce">
+                                <div class="fl introduce">
+                                    <summernote lang="zh-CN" ng-model="message.context" height="300px" maxlength="3500" config="editorConfig">
+                                    </summernote>
+                                </div>
+                                <span class="error" ng-show="submited && !message.context">*请填写消息内容</span>
+                                <div class="button"><a ng-click="publishMessage(messageForm.$invalid)">发布</a><a data-toggle="modal" data-target="#setting">定时发送</a></div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </form>
+        </section>
+    </div>
+</div>
+<!--定时发送弹出框-->
+<div class="modal setting" role="dialog" id="setting">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header header">
+                <p class="fl">设置发送时间</p>
+                <div class="close fr" data-dismiss="modal">&times;</div>
+            </div>
+            <div class="modal-body body">
+                <div class="form-group clearfix">
+                    <label class="control-label fl">发布时间</label>
+                    <input type="text" ng-model="message.publishDate" readonly style="float:left"
+                           class="date-choose f1 form-control" placeholder="发布时间"
+                           datepicker-popup="yyyy-MM-dd HH:mm:ss" is-open="message.$publishTimeOpened"
+                           current-text="今天" clear-text="清除" close-text="关闭"
+                           datepicker-options="{formatDayTitle: 'yyyy年M月', formatMonth: 'M月', showWeeks: false}"
+                           ng-click="openDatePicker($event, message, '$startTimeOpened')"
+                           ng-class="{'showEmpty' : submited && !message.publishDate}">
+                </div>
+            </div>
+            <div class="modal-footer footer text-right">
+                <a ng-click="publishMessage(messageForm.$invalid)">确认</a><a data-dismiss="modal">取消</a>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+    $('#chooseReceiver').on('click', function () {
+        $('.chooseUser').toggle();
+    });
+</script>

+ 404 - 9
donate-console/src/main/webapp/resources/view/message/message_list.html

@@ -1,10 +1,405 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <title>Title</title>
-</head>
-<body>
+<style>
+    body{
+        font-family: "Microsoft Yahei", "微软雅黑";
+        box-sizing: border-box;
+    }
+    .clearfix {
+        clear: both;
+    }
+    .skin-blue .content-wrapper .content-header{
+        margin-left: 7px;
+        padding-top: 22px;
+    }
+    .skin-blue .content-wrapper .content-header .content-row {
+        margin-top: 20px;
+        margin-bottom: -10px;
+    }
+    .content-header .form-horizontal{
+        float: right;
+    }
+    .content .boxes {
+        position: relative;
+        margin-top: 4px;
+        border-radius: 3px;
+        background: #ffffff;
+        margin-bottom: 20px;
+        width: 100%;
+        height: 700px;
+        border: 1px solid #dcdcdc;
+        box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+    }
+    .content .boxes-body table{
+        width: 100%;
+        max-width: 100%;
+    }
+    .content .boxes-body table tr{
+        text-align: center;
+        vertical-align: middle ;
+    }
+    .content .boxes-body table tr td:nth-child(2){
+        text-align: left;
+    }
+    .content .boxes-body table thead{
+        height: 40px;
+        line-height: 40px;
+        text-align: center;
+    }
+    .content .boxes-body table thead tr{
+        border-bottom: 1px solid #dcdcdc;
+    }
+    .content .boxes-body table thead tr td{
+        font-size: 14px;
+        color: #8c8c8c;
+        font-weight: bold;
+    }
+    .content .boxes-body table tbody{
+        height: 655px;
+    }
+    .content .boxes-body table tbody tr{
+        height: 60px;
+        vertical-align: middle;
+        cursor: pointer;
+    }
+    .content .boxes-body table tbody tr:nth-child(even){
+        background: #f7f7f7;
+    }
+    .content .boxes-body table tbody tr:hover{
+        background: #f1f5ff;
+    }
+    .content .boxes-body table tbody tr td{
+        padding-top: 6px;
+        font-size: 14px;
+        color: #323232;
+    }
+    .content .boxes-body table tbody tr td div.name{
+        position: relative;
+        width: 220px;
+    }
+    .content .boxes-body table tbody tr td div.name p {
+        font-size: 14px;
+        font-weight: bold;
+        color: #323232;
+    }
+    .content .boxes-body table tbody tr td div.name:hover p{
+        text-decoration: underline;
+    }
+    .content .boxes-body table tbody tr td div.name div.handle{
+        display: none;
+    }
+    .content .boxes-body table tbody tr:hover td div.name div.handle{
+        margin-top: 5px;
+        display: block;
+    }
+    .content .boxes-body table tbody tr td div.name div.set-time{
+        position: absolute;
+        top: 2px;
+        right: -45px;
+        width: 38px;
+        height: 16px;
+        line-height: 16px;
+        font-family: 'SimHei'!important;
+        font-size: 11px;
+        text-align: center;
+        color: #fff;
+        background: #3c8dbc;
+        border-radius: 10px;
+        display: none;
+    }
+    .content .boxes-body table tbody tr:hover td div.name div.set-time{
+        display: block;
+    }
+    .content .boxes-body table tbody tr td div.name span{
+        margin-right: 25px;
+        font-size: 14px;
+        color: #367bcf;
+        cursor: pointer;
+    }
+    .content .boxes-body table tbody tr td div.name span:last-child {
+        margin-right: 0;
+    }
+    /*右侧内容部分*/
+    .content-right{
+        margin-top: 50px;
+        position: absolute;
+        top: 0;
+        right: 0;
+        /*width: 50%;*/
+        width: 905px;
+        height: 624px;
+        background: #fff;
+        z-index: 100;
+        /*box-shadow: -5px 2px 2px #f0f0f0;*/
+        /*-moz-box-shadow: -5px 2px 2px #f0f0f0;*/
+        /*-o-box-shadow: -5px 2px 2px #f0f0f0;*/
+        /*-webkit-box-shadow: -5px 2px 2px #f0f0f0 ;*/
+    }
+    .right-header{
+        padding: 0 25px;
+        width: 100%;
+        height: 64px;
+        line-height: 64px;
+    }
+    .right-header span{
+        margin-right: 17px;
+        font-size: 24px;
+        color: #333;
+    }
+    .right-header a{
+        font-size: 14px;
+        color: #1a6eb5;
+    }
+    .right-header .close{
+        font-size: 40px;
+    }
+    .right-nav{
+        margin-bottom: 14px;
+        width: 100%;
+        height: 34px;
+        line-height: 34px;
+        background: #e8f0f7;
+    }
+    .right-nav span{
+        margin-right: 50px;
+        padding-bottom: 5px;
+        font-size: 14px;
+        color: #333333;
+        cursor: pointer;
+    }
+    .right-nav span:first-child{
+        margin-left: -73px;
+    }
+    .right-nav span:hover,.right-nav span.active{
+        border-bottom: 2px solid #3c8dbc;
+    }
+    .content-right .right-list{
+        width: 100%;
+    }
+    .content-right .right-list table{
+        margin-top: 20px;
+        width: 100%;
+        table-layout: fixed ;
+    }
 
-</body>
-</html>
+    .content-right .right-list table thead{
+        width: 100%;
+        height: 40px;
+        line-height: 40px;
+        border: 1px solid #dcdcdc;
+    }
+    .content-right .right-list table thead tr{
+        border: 1px solid #dcdcdc;
+    }
+    .content-right .right-list table thead th{
+        font-size: 14px;
+        color: #8c8c8c;
+        text-align: center;
+    }
+    .content-right .right-list table thead th:nth-child(2){
+        text-align: left;
+    }
+    .content-right .right-list table tbody tr{
+        height: 60px;
+        cursor: pointer;
+    }
+    .content-right .right-list table tbody tr:nth-child(even){
+        background: #f7f7f7;
+    }
+    .content-right .right-list table tbody tr:hover{
+        background: #f1f5ff;
+    }
+    .content-right .right-list table tbody tr td{
+        font-size: 14px;
+        color: #333;
+        text-align: center;
+    }
+    .content-right .right-list table tbody tr td:nth-child(2) {
+        /*font-weight: bold;*/
+        text-align: left;
+    }
+    .content-right .right-list table tbody tr td:nth-child(3) {
+        padding-right: 20px;
+        text-align: right;
+    }
+
+    .right-list .list-message{
+        padding: 0 20px 0 25px;
+    }
+    .right-list .list-header{
+        position: relative;
+        width: 100%;
+        height: 43px;
+        text-align: left;
+        border-bottom: 1px solid #dcdcdc;
+    }
+    .right-list .list-header:first-child {
+        margin-top: -10px;
+    }
+    .right-list .list-header span{
+        margin-left: 15px;
+        font-size: 15px;
+        color: #000;
+    }
+    .right-list .list-header span:before {
+        content: '';
+        position: absolute;
+        top: 13px;
+        left: 0;
+        width: 4px;
+        height: 16px;
+        background: #626262;
+    }
+    .right-list .list-body{
+        margin-top: 17px;
+    }
+    .right-list .list-body .msg-list{
+        margin-bottom: 20px;
+        overflow: hidden;
+    }
+    .right-list .list-body .msg-list.msg-lists {
+        border-bottom: 1px solid #dcdcdc;
+    }
+    .right-list .list-body .msg-list span:first-child{
+        margin-right: 20px;
+        width: 70px;
+        font-family: 'SimHei'!important ;
+        font-size: 14px;
+        color: #8da8b8;
+    }
+    .right-list .list-body .msg-list span:last-child{
+        width: 240px;
+        font-size: 14px;
+        color: #323232;
+    }
+    /*信息详情*/
+    .right-list .list-body .msg-list span.count{
+        font-size: 14px;
+        font-weight: bold;
+        color: #3c8dbc;
+    }
+    .right-list .list-body .message-list .txt{
+        margin-bottom: 20px;
+    }
+    .right-list .list-body .message-list p{
+        font-size: 14px;
+        color: #323232;
+        line-height: 21px;
+        text-indent: 2em;
+    }
+    .right-list .list-body .message-list ul>li{
+        font-size: 14px;
+        color: #323232;
+        line-height: 21px;
+        list-style: none;
+    }
+    .right-list .list-body .message-list .photo{
+        position: relative;
+        width: 400px;
+        height: 220px;
+        line-height: 220px;
+        text-align: center;
+        font-size: 14px;
+        color: #878787;
+        background: #e5e5e5;
+    }
+    .right-list .list-body .message-list .photo input{
+        position: absolute ;
+        top: 0;
+        left: 0;
+        width: 400px;
+        height: 220px;
+        outline: none;
+        opacity: 0;
+    }
+    .show{
+        display: block;
+    }
+    .box-show{
+        display: none;
+    }
+    .modal-footer {
+        padding: 10px;
+    }
+</style>
+<div class="wrapper">
+    <!--主体内容-->
+    <div class="content-wrapper" style="min-height: 924px;; z-index: 50;">
+        <section class="content-header clearfix">
+            <h1>消息列表</h1>
+            <div class="row content-row clearfix">
+                <div class="jp-left">
+                    <select class="form-control input-sm jp-width120" name="action" ng-model="time" ng-change="setTime(time)" ng-init="time ='全部时段'">
+                        <option ng-value="'全部时段'">全部时段</option>
+                        <option ng-value="'6'">最近6小时</option>
+                        <option ng-value="'24'">最近24小时</option>
+                        <option ng-value="'3'">最近3天</option>
+                        <option ng-value="'7'">最近7天</option>
+                    </select>
+                </div>
+                <div class="input-group input-group-sm pull-right">
+                    <input id="post-search-input" class="form-control" type="search" ng-search="onSearch()" placeholder="请输入关键词">&nbsp;&nbsp;
+                    <input id="search-submit" class="btn btn-default btn-sm" ng-click="onSearch()" type="button" value="搜索">
+                </div>
+            </div>
+        </section>
+        <!-- Main content -->
+        <section class="content">
+            <div class="box-show show">
+                <div class="boxes">
+                    <div class="boxes-body">
+                        <table class="" style="word-break:break-all" ng-table="messageParams">
+                            <thead>
+                            <tr>
+                                <td width="45"></td>
+                                <td width="300">消息主题</td>
+                                <td width="100">发布时间</td>
+                                <td width="160">接收对象</td>
+                                <td width="90">阅读情况</td>
+                                <td width="90">发送人</td>
+                                <td width="400"></td>
+                            </tr>
+                            </thead>
+                            <tbody ng-if="messageParams.total() == 0">
+                            <tr>
+                                <td colspan="7">
+                                    <div class="section noSearch">
+                                        <div class="img">
+                                            <img src="static/images/noSearch.png" alt=""/>
+                                        </div>
+                                        <div class="txt">
+                                            <p>未找到相关记录</p>
+                                        </div>
+                                    </div>
+                                </td>
+                            </tr>
+                            </tbody>
+                            <tbody ng-repeat="message in $data">
+                            <tr ng-click="showDetail(message)" title="点击查看详情">
+                                <td></td>
+                                <td>
+                                    <div class="name">
+                                        <p>{{message.title}}</p>
+                                        <!--<div class="handle"><span>删除</span></div>-->
+                                        <!--<div class="set-time" ng-click="setPublishTime()">定时</div>-->
+                                    </div>
+                                </td>
+                                <td>{{message.publishDate | date: 'yyyy-MM-dd HH:mm:ss'}}</td>
+                                <td>{{message.receiver || '部分用户'}}({{message.receiverNum || 0 | number}}人)</td>
+                                <td>{{message.readerNum || 0 | number}}</td>
+                                <td>{{message.user.name}}</td>
+                                <td></td>
+                            </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </section>
+    </div>
+</div>
+<script>
+    $('.right-nav').on('click', 'span', function () {
+        var index = $(this).index();
+        $(this).addClass('active').siblings().removeClass('active');
+        $('.right-list').eq(index).addClass('show').siblings().removeClass('show');
+    });
+</script>

+ 174 - 0
donate-console/src/main/webapp/resources/view/message/select_receiver_role.html

@@ -0,0 +1,174 @@
+<!-- 按角色类型指定接收消息用户 -->
+<style>
+    /*接收对象选择框*/
+
+    /*.content-setting .edit input:focus + .chooseUser{*/
+    /*display: block;*/
+    /*}*/
+    .chooseUser{
+        position: absolute;
+        top: 30px;
+        left: 15px;
+        width: 500px;
+        height: 400px;
+        -moz-box-shadow: 2px 2px 5px #b0b0b0;
+        -o-box-shadow: 2px 2px 5px #b0b0b0;
+        -webkit-box-shadow: 2px 2px 5px #b0b0b0;
+        box-shadow: 2px 2px 5px #b0b0b0;
+        border: 1px solid #dcdcdc;
+        background: #fff;
+        /*display: none;*/
+    }
+    .chooseUser .search{
+        padding-left: 18px;
+        margin: 12px 0 20px 0;
+        width: 429px;
+        height: 30px;
+        line-height: 30px;
+        position: relative;
+    }
+    .chooseUser .search input{
+        width: 100%;
+        height: 30px;
+        border-radius: 0;
+    }
+    .chooseUser .search button{
+        position: absolute;
+        top: 0;
+        right: -60px;
+        margin-left: 13px;
+        font-size: 14px;
+        color: #1b71c9;
+        border: none;
+        background: none;
+    }
+    .chooseUser .choose-body {
+        overflow: hidden;
+        padding-left: 18px;
+    }
+    .chooseUser .choose-body .left{
+        margin-right: 10px;
+    }
+    .chooseUser .choose-body .left ul li{
+        margin-bottom: 13px;
+        width: 140px;
+        height: 30px;
+        line-height: 30px;
+        list-style: none;
+    }
+    .chooseUser .choose-body .left ul li:hover,.chooseUser .choose-body .left ul li.active{
+        background: #e5e5e5;
+    }
+    .chooseUser .choose-body .left ul li a{
+        padding-left: 8px;
+        display: inline-block;
+        width: 140px;
+        height: 30px;
+        font-size: 16px;
+        color: #323232;
+    }
+    .chooseUser .choose-body .right{
+        padding-left: 10px;
+        width: 260px;
+        height: 270px;
+        overflow-y: auto;
+        border-left: 1px solid #dcdcdc;
+        border-right: 1px solid #dcdcdc;
+    }
+    .chooseUser .choose-body .right .list-item{
+        margin-bottom: 14px;
+        padding-left: 10px;
+        width: 230px;
+        height: 30px;
+        line-height: 30px;
+    }
+    .chooseUser .choose-body .right .list-item:hover, .chooseUser .choose-body .right .list-item.active{
+        background: #e5e5e5;
+    }
+    .chooseUser .choose-body .right .list-item input{
+        margin-top: 8px;
+        margin-right: 16px;
+        width: 14px;
+        height: 14px;
+        /*display: none;*/
+    }
+    /*.chooseUser .choose-body .right .list-item span{*/
+    /*display: inline-block;*/
+    /*width: 14px;*/
+    /*height: 14px;*/
+    /*background: url(static/images/radio.png) no-repeat center center;*/
+    /*}*/
+    .chooseUser .choose-body .right .list-item label{
+        margin-left: 0;
+        font-family: 'SimHei'!important;
+        font-size: 16px;
+        color: #323232;
+        width: 165px;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        overflow: hidden;
+    }
+    .chooseUser .choose-footer{
+        padding-right: 22px;
+        margin-top: 18px;
+        height: 48px;
+        width: 100%;
+        line-height: 48px;
+        background: #eee;
+    }
+    .chooseUser .choose-footer span{
+        margin-right: 30px;
+        font-size: 16px;
+        font-family: 'SimHei'!important;
+        color: #323232;
+    }
+    .chooseUser .choose-footer span b{
+        font-size: 16px;
+        color: #3c8dbc;
+    }
+    .chooseUser .choose-footer a{
+        display: inline-block;
+        width: 120px;
+        height: 30px;
+        line-height: 30px;
+        text-align: center;
+        font-size: 16px;
+        color: #fff;
+        background: #3c8dbc;
+        border-radius: 3px;
+        letter-spacing: 10px;
+    }
+</style>
+<!-- loading start -->
+<div class="loading" ng-class="{'in': loading}"><i></i></div>
+<!-- loading end -->
+<div class="chooseUser">
+    <div class="search">
+        <input type="text" ng-model="keyword" ng-change="onSearch()" placeholder="请输入关键字" class="form-control">
+    </div>
+    <div class="choose-body">
+        <div class="left fl">
+            <ul>
+                <li ng-class="{'active' : active == 'personal'}"><a ng-click="setActive('personal')">个人用户</a></li>
+                <li ng-class="{'active' : active == 'public'}"><a ng-click="setActive('public')">公募机构</a></li>
+                <li ng-class="{'active' : active == 'non-public'}"><a ng-click="setActive('non-public')">非公募机构</a></li>
+                <li ng-class="{'active' : active == 'admin'}"><a ng-click="setActive('admin')">管理员</a></li>
+            </ul>
+        </div>
+        <div class="right fl" ng-if="orgs.length != 0">
+            <div class="list-item clearfix">
+                <span ng-click="checkAll()">
+                    <input type="checkbox" ng-checked="checkedAll" class="fl"><span></span><label class="fl">选择全部</label>
+                </span>
+            </div>
+            <div class="list-item clearfix" ng-repeat="org in orgs">
+                <span ng-click="checkOne(org)">
+                    <input type="checkbox" ng-checked="org.checked" class="fl"><span></span><label class="fl">{{org.name}}</label>
+                </span>
+            </div>
+        </div>
+    </div>
+    <div class="choose-footer text-right">
+        <a ng-click="ensure()">确认</a>
+    </div>
+</div>

+ 20 - 0
donate-console/src/main/webapp/resources/view/message/timing_modal.html

@@ -0,0 +1,20 @@
+<!--定时发送弹出框-->
+<div class="modal setting" role="dialog" id="setting">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header header">
+                <p class="fl">设置发送时间</p>
+                <div class="close fr" data-dismiss="modal">&times;</div>
+            </div>
+            <div class="modal-body body">
+                <div class="form-group clearfix">
+                    <label for="" class="control-label fl">活动时间</label>
+                    <input type="date" class="fl form-control">
+                </div>
+            </div>
+            <div class="modal-footer footer text-right">
+                <a href="">保存</a><a href="">取消</a>
+            </div>
+        </div>
+    </div>
+</div>

+ 2 - 2
donate-console/src/main/webapp/resources/view/project/project_launch_2.html

@@ -727,8 +727,8 @@
                             <div class="list-item clearfix">
                                 <span class="fl">项目介绍</span>
                                 <div class="fl simple">
-                                    <summernote lang="zh-CN" ng-model="project.introduction" height="300px"
-                                                             ng-class="{'showEmpty': submited && project.introduction == null}">
+                                    <summernote lang="zh-CN" ng-model="project.introduction" height="300px" config="editorConfig" maxlength="3500"
+                                                ng-class="{'showEmpty': submited && project.introduction == null}">
                                         请填写介绍
                                     </summernote>
 

+ 4 - 8
donate-console/src/main/webapp/resources/view/user/organization_detail.html

@@ -52,21 +52,17 @@
                 </div>
                 <div class="msg-list fl">
                     <span class="fl">主要领域</span>
-                    <span ng-if="org.majorArea == 1">环保/保护动物</span>
-                    <span ng-if="org.majorArea == 2">疾病救助</span>
-                    <span ng-if="org.majorArea == 3">扶贫/救灾</span>
-                    <span ng-if="org.majorArea == 4">教育/助学</span>
-                    <span ng-if="org.majorArea != 1 && org.majorArea != 2 && org.majorArea != 3 && org.majorArea != 4">其他</span>
+                    <span ng-bind="org.majorArea"></span>
                 </div>
                 <div class="msg-list fl">
                     <span class="fl">年募捐款</span>
-                    <span class="fl" ng-bind="org.yearDonationAmount"></span>
+                    <span class="fl" ng-bind="org.yearDonationAmount || 0 | number:2"></span>
                 </div>
                 <div class="msg-list fl">
                     <span class="fl">机构规模</span>
                     <span class="fl">
-                        {{org.fullTimePopulation + org.partTimePopulation + org.voluntaryPopulation | number}}
-                        ({{org.fullTimePopulation | number}}/{{org.partTimePopulation | number}}/ {{org.voluntaryPopulation | number}})
+                        {{org.fullTimePopulation || 0 + org.partTimePopulation || 0 + org.voluntaryPopulation || 0 | number}}
+                        ({{org.fullTimePopulation|| 0 | number}}/{{org.partTimePopulation || 0 | number}}/ {{org.voluntaryPopulation || 0 | number}})
                     </span>
                 </div>
                 <div class="msg-list fl">

+ 1 - 7
donate-console/src/main/webapp/resources/view/user/organization_list.html

@@ -318,8 +318,7 @@
     /*}*/
     /*未审核-机构信息*/
     .right-list .list-footer{
-        margin: 0 auto;
-        margin-top: 50px;
+        margin: 50px auto 30px auto;
         width: 100%;
         text-align: center;
     }
@@ -506,11 +505,6 @@
             </div>
             <div class="jp-left">
                 <select class="form-control input-sm jp-width120" ng-model="selectedArea" ng-change="reload()"  ng-options="area for area in areas" ng-init="selectedArea = '全部'">
-                    <!--<option value="1">环保/保护动物</option>-->
-                    <!--<option value="2">疾病救助</option>-->
-                    <!--<option value="3">扶贫/救灾</option>-->
-                    <!--<option value="4">教育/助学</option>-->
-                    <!--<option value="5">其他</option>-->
                 </select>
             </div>
         </div>

+ 38 - 0
donate-service/src/main/java/com/uas/service/donate/controller/MessageSendController.java

@@ -0,0 +1,38 @@
+package com.uas.service.donate.controller;
+
+
+import com.uas.service.donate.service.MessageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 发送消息提醒
+ * Created by dongbw
+ * 17/09/28 17:23.
+ */
+@Controller
+@RequestMapping("/message")
+public class MessageSendController {
+
+    @Autowired
+    private MessageService messageService;
+
+    /**
+     * 发送邮件接口
+     */
+    public ResponseEntity<String> sendMail(String receivedMail, Map<String, Object> model) {
+        return messageService.sendMail(receivedMail, model);
+    }
+
+    /**
+     * 发送短信接口
+     */
+    public ResponseEntity<String> sendMessage(String receiverTel, List<Object> obj) {
+        return messageService.sendMessage(receiverTel, obj);
+    }
+}

+ 24 - 12
donate-service/src/main/java/com/uas/service/donate/controller/UserController.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.uas.platform.core.model.PageInfo;
 import com.uas.platform.core.model.PageParams;
 import com.uas.service.donate.model.ActivityRecode;
+import com.uas.service.donate.model.MessageDetail;
 import com.uas.service.donate.model.ProjectRecode;
 import com.uas.service.donate.model.SearchFilter;
 import com.uas.service.donate.service.UserService;
@@ -72,18 +73,29 @@ public class UserController {
         return userService.getJoinedActivityRecords(pageInfo, filter);
     }
 
-//    // TODO message
-//    @RequestMapping(value = "/getMessage", method = RequestMethod.GET)
-//    @ResponseBody
-//    public Page<Message> getMessage () {
-//        return new ModelMap("userUU", userService.getMessage());
-//    }
-//
-//    @RequestMapping(value = "/getUnreadMessageNum", method = RequestMethod.GET)
-//    @ResponseBody
-//    public ModelMap getUnreadMessageNum () {
-//        return new ModelMap("unreadMessage", userService.getUnreadMessageNum());
-//    }
+    /**
+     * 获取收到的消息
+     * @param params 分页参数
+     * @param searchFilter 查找filter
+     * @return 用户分页
+     */
+    @RequestMapping(value = "/getMessage", method = RequestMethod.GET)
+    @ResponseBody
+    public Page<MessageDetail> getMessage(PageParams params, String searchFilter) {
+        PageInfo pageInfo = new PageInfo(params);
+        SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
+        return userService.getMessage(pageInfo, filter);
+    }
+
+    /**
+     * 获取未读消息数量
+     * @return 消息数量map
+     */
+    @RequestMapping(value = "/getUnreadMessageNum", method = RequestMethod.GET)
+    @ResponseBody
+    public ModelMap getUnreadMessageNum() {
+        return new ModelMap("unreadMessage", userService.getUnreadMessageNum());
+    }
 
 
 }

+ 15 - 0
donate-service/src/main/java/com/uas/service/donate/dao/MessageDao.java

@@ -0,0 +1,15 @@
+package com.uas.service.donate.dao;
+
+import com.uas.service.donate.model.Message;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by dongbw
+ * 17/12/26 17:43.
+ */
+@Repository
+public interface MessageDao extends JpaRepository<Message, Long>, JpaSpecificationExecutor<Message>{
+
+}

+ 22 - 0
donate-service/src/main/java/com/uas/service/donate/dao/MessageDetailDao.java

@@ -0,0 +1,22 @@
+package com.uas.service.donate.dao;
+
+import com.uas.service.donate.model.MessageDetail;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+import java.util.List;
+
+/**
+ * Created by dongbw
+ * 17/12/26 17:46.
+ */
+public interface MessageDetailDao extends JpaRepository<MessageDetail, Long>, JpaSpecificationExecutor<MessageDetail>{
+
+    /**
+     * 根据userUU和阅读状态查找消息
+     * @param userUU  用户uu
+     * @param readStatus 阅读状态
+     * @return 消息list
+     */
+    List<MessageDetail> findByReceiveUserUUAndReadStatus(Long userUU, Short readStatus);
+}

+ 1 - 1
donate-service/src/main/java/com/uas/service/donate/dao/ProjectDao.java

@@ -14,7 +14,7 @@ import org.springframework.stereotype.Repository;
 import java.util.List;
 
 @Repository
-public interface ProjectDao extends JpaRepository<Project,Long>,JpaSpecificationExecutor<Project>,PagingAndSortingRepository<Project, Long> {
+public interface ProjectDao extends JpaRepository<Project, Long>, JpaSpecificationExecutor<Project>, PagingAndSortingRepository<Project, Long> {
 
     //获取所有进行中中和已结束的项目
     @Query("from Project p where now()>=p.startTime and p.status=1 and p.publish=2 order by p.startTime desc")

+ 67 - 0
donate-service/src/main/java/com/uas/service/donate/event/ProjectPublishEvent.java

@@ -0,0 +1,67 @@
+package com.uas.service.donate.event;
+
+import com.uas.service.donate.model.MessageDetail;
+import com.uas.service.donate.model.Project;
+
+import java.util.List;
+
+/**
+ * 发布项目时时生成消息事件
+ * Created by dongbw
+ *
+ */
+public class ProjectPublishEvent extends PublishEvent<MessageDetail, Project> {
+
+	/**
+	 *
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public ProjectPublishEvent(List<Project> savedList) {
+        super(savedList);
+    }
+
+    /**
+     * 生成对应消息记录
+     *
+     * @param project 项目
+     * @return
+     */
+    @Override
+	public MessageDetail release(Project project) {
+        //TODO 新项目发布时,产生消息
+//        Long emUU = orderAll.getUserUU();
+//        String emName = "操作员";
+//        if (null != orderAll.getUser()) {
+//            emName = orderAll.getUser().getUserName();
+//        }
+//        Long enUU = orderAll.getEnUU();
+//        Date date = new Date();
+//        String codeValue = orderAll.getCode();
+//        String from = "B2B";
+//        if (orderAll.getErpId() != null) { // erp传到平台的单据,包含erpId字段记录来源
+//            from = "ERP";
+//        }
+//        String type = "新增采购订单";
+//        String title = "B2B商务提醒";
+//        Short toVendor = Constant.YES;
+//        Short isReply = Constant.NO;
+//        String category = "sale";  // 对接收方来说,该单据类型
+//        String table = "purc$orders";
+//        Long sourceId = orderAll.getId();
+//        String url = "#/sale/order/" + orderAll.getId();
+//        Short orderStatus = orderAll.getStatus();
+//        String context = orderAll.getEnterprise().getEnName() + "的" + emName + "给您发送了一张新的采购单(" + codeValue + ")!";
+//        PagingRelease release = new PagingRelease(emUU, emName, enUU, date, codeValue, from, title, context, type, isReply, category, table, sourceId, orderStatus, toVendor, url);
+//        Long vendUU = orderAll.getVendUU();
+//        Long vendUserUU = orderAll.getVendUserUU();
+//        if (null == vendUserUU) {
+//            vendUserUU = 1L;
+//        }
+//        String vendUserName = orderAll.getVenduser();
+//        PagingReleaseDetail releaseDetail = new PagingReleaseDetail(vendUU, vendUserUU, vendUserName);
+//        releaseDetail.setPagingRelease(release);
+//        return releaseDetail;
+        return null;
+    }
+}

+ 31 - 0
donate-service/src/main/java/com/uas/service/donate/listener/PublishListener.java

@@ -0,0 +1,31 @@
+package com.uas.service.donate.listener;
+
+import com.uas.service.donate.event.ProjectPublishEvent;
+import com.uas.service.donate.event.PublishEvent;
+import com.uas.service.donate.model.MessageDetail;
+import org.springframework.context.ApplicationListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 监听发布事件<br>
+ * 产生消息
+ * 
+ */
+@Component
+public class PublishListener implements ApplicationListener<PublishEvent<?, ?>> {
+
+
+	@SuppressWarnings("unchecked")
+	@Async
+	@Override
+	public void onApplicationEvent(final PublishEvent<?, ?> event) {
+		 if (event instanceof ProjectPublishEvent) {
+		 	// TODO 事件触发监听器产生消息
+			 List<MessageDetail> messageDetailList = ((ProjectPublishEvent) event).release();
+		 }
+	}
+
+}

+ 239 - 0
donate-service/src/main/java/com/uas/service/donate/model/Message.java

@@ -0,0 +1,239 @@
+package com.uas.service.donate.model;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ *  消息通知表
+ *
+ */
+@Entity
+@Table(name = "donate$message")
+public class Message implements Serializable {
+
+    /**
+     * 序号
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "dm_id")
+    private Long id;
+
+    /**
+     * 发布用户UU
+     */
+    @Column(name = "dm_useruu")
+    private Long userUU;
+
+    /**
+     * 发布用户
+     */
+    @OneToOne(cascade = CascadeType.REFRESH)
+    @JoinColumn(name = "dm_useruu", insertable = false, updatable = false)
+    private User user;
+
+    /**
+     * 提交时间
+     */
+    @Column(name = "dm_date")
+    private Date date;
+
+    /**
+     * 发布时间
+     */
+    @Column(name = "dm_publishdate")
+    private Date publishDate;
+
+    /**
+     * 消息标题
+     */
+    @Column(name = "dm_title")
+    private String title;
+
+    /**
+     * 消息正文
+     */
+    @Column(name = "dm_context")
+    private String context;
+
+    /**
+     * 消息类型
+     */
+    @Column(name = "dm_type")
+    private String type;
+
+    /**
+     * 来源表
+     */
+    @Column(name = "dm_table")
+    private String table;
+
+    /**
+     * 来源id
+     */
+    @Column(name = "dm_sourceid")
+    private Long sourceId;
+
+    /**
+     * 单据链接
+     */
+    @Column(name = "dm_url")
+    private String url;
+
+    /**
+     * 消息明细
+     */
+    @OneToMany(mappedBy = "message", cascade = CascadeType.REFRESH)
+    @OrderBy("dmd_id DESC")
+    private Set<MessageDetail> messageDetails;
+
+    /**
+     * 接收对象
+     */
+    @Column(name = "dm_receiver")
+    private String receiver;
+
+    /**
+     * 阅读人数
+     */
+    @Column(name = "dm_readernum")
+    private Integer readerNum;
+
+    /**
+     * 消息接收人数
+     */
+    @Column(name = "dm_receivernum")
+    private Integer receiverNum;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getUserUU() {
+        return userUU;
+    }
+
+    public void setUserUU(Long userUU) {
+        this.userUU = userUU;
+    }
+
+    public User getUser() {
+        return user;
+    }
+
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public Date getPublishDate() {
+        return publishDate;
+    }
+
+    public void setPublishDate(Date publishDate) {
+        this.publishDate = publishDate;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getContext() {
+        return context;
+    }
+
+    public void setContext(String context) {
+        this.context = context;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getTable() {
+        return table;
+    }
+
+    public void setTable(String table) {
+        this.table = table;
+    }
+
+    public Long getSourceId() {
+        return sourceId;
+    }
+
+    public void setSourceId(Long sourceId) {
+        this.sourceId = sourceId;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    @JsonIgnore
+    @JSONField(serialize = false)
+    public Set<MessageDetail> getNoticeDetails() {
+        return messageDetails;
+    }
+
+    public void setNoticeDetails(Set<MessageDetail> noticeDetails) {
+        this.messageDetails = noticeDetails;
+    }
+
+    public String getReceiver() {
+        return receiver;
+    }
+
+    public void setReceiver(String receiver) {
+        this.receiver = receiver;
+    }
+
+    public Integer getReaderNum() {
+        return readerNum;
+    }
+
+    public void setReaderNum(Integer readerNum) {
+        this.readerNum = readerNum;
+    }
+
+    public Integer getReceiverNum() {
+        return this.receiverNum;
+    }
+
+    public void setReceiverNum(Integer receiverNum) {
+        this.receiverNum = receiverNum;
+    }
+}

+ 149 - 0
donate-service/src/main/java/com/uas/service/donate/model/MessageDetail.java

@@ -0,0 +1,149 @@
+package com.uas.service.donate.model;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 消息明细表
+ *
+ */
+@Entity
+@Table(name = "donate$messagedetail")
+public class MessageDetail implements Serializable{
+
+    /**
+     * 序号
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * id
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "dmd_id")
+    private Long id;
+
+    /**
+     * 接收人UU
+     */
+    @Column(name = "dmd_receiveuseruu")
+    private Long receiveUserUU;
+
+    /**
+     * 关联接收人
+     */
+    @OneToOne
+    @JoinColumn(name = "dmd_receiveuseruu", insertable = false, updatable = false)
+    private User receiveUser;
+
+    /**
+     * 阅读时间
+     */
+    @Column(name = "dmd_readdate")
+    private Date readDate;
+
+    /**
+     * 阅读状态 0未读,1已读
+     */
+    @Column(name = "dmd_readstatus")
+    private Short readStatus;
+
+    /**
+     * 获取状态 0未获取,1已获取
+     */
+    @Column(name = "dmd_status")
+    private Short status;
+
+    /**
+     * 推送状态 0未推送,1已推送
+     */
+    @Column(name = "dmd_pushstatus")
+    private Short pushStatus;
+
+    /**
+     * 统计状态 0未统计,1已统计
+     */
+    @Column(name = "dmd_totalstatus")
+    private Short totalStatus;
+
+    /**
+     * 消息主表
+     */
+    @ManyToOne(cascade = CascadeType.ALL)
+    @JoinColumn(name = "dmd_dmid", nullable = false)
+    private Message message;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getReceiveUserUU() {
+        return receiveUserUU;
+    }
+
+    public void setReceiveUserUU(Long receiveUserUU) {
+        this.receiveUserUU = receiveUserUU;
+    }
+
+    public User getReceiveUser() {
+        return receiveUser;
+    }
+
+    public void setReceiveUser(User receiveUser) {
+        this.receiveUser = receiveUser;
+    }
+
+    public Date getReadDate() {
+        return readDate;
+    }
+
+    public void setReadDate(Date readDate) {
+        this.readDate = readDate;
+    }
+
+    public Short getReadStatus() {
+        return readStatus;
+    }
+
+    public void setReadStatus(Short readStatus) {
+        this.readStatus = readStatus;
+    }
+
+    public Short getStatus() {
+        return status;
+    }
+
+    public void setStatus(Short status) {
+        this.status = status;
+    }
+
+    public Short getPushStatus() {
+        return pushStatus;
+    }
+
+    public void setPushStatus(Short pushStatus) {
+        this.pushStatus = pushStatus;
+    }
+
+    public Short getTotalStatus() {
+        return totalStatus;
+    }
+
+    public void setTotalStatus(Short totalStatus) {
+        this.totalStatus = totalStatus;
+    }
+
+    public Message getNotice() {
+        return message;
+    }
+
+    public void setNotice(Message notice) {
+        this.message = notice;
+    }
+}

+ 0 - 483
donate-service/src/main/java/com/uas/service/donate/model/Organization.java

@@ -1,483 +0,0 @@
-package com.uas.service.donate.model;
-
-
-import javax.persistence.*;
-import java.io.Serializable;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-@Entity
-@Table(name="donate$organization")
-public class Organization implements Serializable{
-
-    private static final long serialVersionUID = 1L;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "org_id")
-    private Long id;
-
-    /**
-     * 审核状态
-     */
-    @Column(name="org_status")
-    private Integer status;
-
-    /**
-     *机构类别(公募/非公募)
-     */
-    @Column(name = "org_type")
-    private String type;
-
-    /**
-     * 机构全称
-     */
-    @Column(name="org_name")
-    private String name;
-
-    /**
-     * 机构电话
-     */
-    @Column(name="org_telphone")
-    private Long telphone;
-
-    /**
-     * 所属省
-     */
-    @Column(name = "Org_province")
-    private String province;
-
-    /**
-     * 所属市
-     */
-    @Column(name="org_city")
-    private String city;
-
-    /**
-     * 详细地址
-     */
-    @Column(name="org_address")
-    private String address;
-
-    /**
-     * 机构登记性质
-     */
-    @Column(name = "reg_type")
-    private String regType;
-
-    /**
-     * 主要领域
-     */
-    @Column(name = "major_area")
-    private String majorArea;
-
-    /**
-     * 年募捐额
-     */
-    @Column(name="year_donation_amount")
-    private Long yearDonationAmount;
-
-    /**
-     * 全职人数
-     */
-    @Column(name="full_time_population")
-    private Long fullTimePopulation;
-
-    /**
-     * 兼职人数
-     */
-    @Column(name="part_time_population")
-    private Long partTimePopulation;
-
-    /**
-     * 志愿者人数
-     */
-    @Column(name="voluntary_population")
-    private Long voluntaryPopulation;
-
-    /**
-     * 成立日期
-     */
-    @Column(name="create_time")
-    private Date createTime;
-
-    /**
-     * 官网地址
-     */
-    @Column(name="org_website")
-    private String website;
-
-    /**
-     * 机构简介
-     */
-    @Column(name="org_summary")
-    private String summary;
-
-    /**
-     * 负责人姓名
-     */
-    @Column(name="manager_name")
-    private String managerName;
-
-    /**
-     * 负责人身份证号
-     */
-    @Column(name="manager_idcard")
-    private Long managerIdcard;
-
-    /**
-     * 负责人办公电话
-     */
-    @Column(name="manager_oph")
-    private Long managerOph;
-
-    /**
-     * 负责人个人手机
-     */
-    @Column(name="manager_telphone")
-    private Long managerTelphone;
-
-    /**
-     * 联系人姓名
-     */
-    @Column(name="contact_name")
-    private String contactName;
-
-    /**
-     * 联系人身份证号
-     */
-    @Column(name="contact_idcard")
-    private Long contactIdcard;
-
-    /**
-     * 联系人电话
-     */
-    @Column(name="contact_telphone")
-    private Long contactTelphone;
-
-
-    /**
-     * 联系人电子邮箱
-     */
-    @Column(name ="contact_email")
-    private String contactEmail;
-
-    /**
-     * 银行卡开户名称
-     */
-    @Column(name="bank_card_name")
-    private String bankCardName;
-
-
-    /**
-     * 开户银行
-     */
-    @Column(name="card_of_bank")
-    private String cardOfBank;
-
-    /**
-     * 银行卡支行信息
-     */
-    @Column(name="Branch_message")
-    private String branchMessage;
-
-    /**
-     * 银行卡账号
-     */
-    @Column(name="bank_account")
-    private Long account;
-
-    /**
-     * 机构logo
-     */
-    @Column(name = "org_logo")
-    private String logo;
-
-    /**
-     * 机构证书
-     */
-    @Column(name = "org_certificate")
-    private String certificate;
-
-    /**
-     * 合作商户资料
-     */
-    @Column(name = "partner_material")
-    private String material;
-
-
-    /**
-     * 结算银行账号证明
-     */
-    @Column(name = "Bank_certify")
-    private String certify;
-
-
-
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public Integer getStatus() {
-        return status;
-    }
-
-    public void setStatus(Integer status) {
-        this.status = status;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Long getTelphone() {
-        return telphone;
-    }
-
-    public void setTelphone(Long telphone) {
-        this.telphone = telphone;
-    }
-
-    public String getProvince() {
-        return province;
-    }
-
-    public void setProvince(String province) {
-        this.province = province;
-    }
-
-    public String getCity() {
-        return city;
-    }
-
-    public void setCity(String city) {
-        this.city = city;
-    }
-
-    public String getAddress() {
-        return address;
-    }
-
-    public void setAddress(String address) {
-        this.address = address;
-    }
-
-    public String getRegType() {
-        return regType;
-    }
-
-    public void setRegType(String regType) {
-        this.regType = regType;
-    }
-
-    public String getMajorArea() {
-        return majorArea;
-    }
-
-    public void setMajorArea(String majorArea) {
-        this.majorArea = majorArea;
-    }
-
-    public Long getYearDonationAmount() {
-        return yearDonationAmount;
-    }
-
-    public void setYearDonationAmount(Long yearDonationAmount) {
-        this.yearDonationAmount = yearDonationAmount;
-    }
-
-    public Long getFullTimePopulation() {
-        return fullTimePopulation;
-    }
-
-    public void setFullTimePopulation(Long fullTimePopulation) {
-        this.fullTimePopulation = fullTimePopulation;
-    }
-
-    public Long getPartTimePopulation() {
-        return partTimePopulation;
-    }
-
-    public void setPartTimePopulation(Long partTimePopulation) {
-        this.partTimePopulation = partTimePopulation;
-    }
-
-    public Long getVoluntaryPopulation() {
-        return voluntaryPopulation;
-    }
-
-    public void setVoluntaryPopulation(Long voluntaryPopulation) {
-        this.voluntaryPopulation = voluntaryPopulation;
-    }
-
-    public String getCreateTime() {
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-        return sdf.format(this.createTime);
-    }
-
-    public void setCreateTime(Date createTime) {
-        this.createTime = createTime;
-    }
-
-    public String getWebsite() {
-        return website;
-    }
-
-    public void setWebsite(String website) {
-        this.website = website;
-    }
-
-    public String getSummary() {
-        return summary;
-    }
-
-    public void setSummary(String summary) {
-        this.summary = summary;
-    }
-
-    public String getManagerName() {
-        return managerName;
-    }
-
-    public void setManagerName(String managerName) {
-        this.managerName = managerName;
-    }
-
-    public Long getManagerIdcard() {
-        return managerIdcard;
-    }
-
-    public void setManagerIdcard(Long managerIdcard) {
-        this.managerIdcard = managerIdcard;
-    }
-
-    public Long getManagerOph() {
-        return managerOph;
-    }
-
-    public void setManagerOph(Long managerOph) {
-        this.managerOph = managerOph;
-    }
-
-    public Long getManagerTelphone() {
-        return managerTelphone;
-    }
-
-    public void setManagerTelphone(Long managerTelphone) {
-        this.managerTelphone = managerTelphone;
-    }
-
-    public String getContactName() {
-        return contactName;
-    }
-
-    public void setContactName(String contactName) {
-        this.contactName = contactName;
-    }
-
-    public Long getContactIdcard() {
-        return contactIdcard;
-    }
-
-    public void setContactIdcard(Long contactIdcard) {
-        this.contactIdcard = contactIdcard;
-    }
-
-    public Long getContactTelphone() {
-        return contactTelphone;
-    }
-
-    public void setContactTelphone(Long contactTelphone) {
-        this.contactTelphone = contactTelphone;
-    }
-
-    public String getContactEmail() {
-        return contactEmail;
-    }
-
-    public void setContactEmail(String contactEmail) {
-        this.contactEmail = contactEmail;
-    }
-
-    public String getBankCardName() {
-        return bankCardName;
-    }
-
-    public void setBankCardName(String bankCardName) {
-        this.bankCardName = bankCardName;
-    }
-
-    public String getCardOfBank() {
-        return cardOfBank;
-    }
-
-    public void setCardOfBank(String cardOfBank) {
-        this.cardOfBank = cardOfBank;
-    }
-
-    public String getBranchMessage() {
-        return branchMessage;
-    }
-
-    public void setBranchMessage(String branchMessage) {
-        this.branchMessage = branchMessage;
-    }
-
-    public Long getAccount() {
-        return account;
-    }
-
-    public void setAccount(Long account) {
-        this.account = account;
-    }
-
-    public String getLogo() {
-        return logo;
-    }
-
-    public void setLogo(String logo) {
-        this.logo = logo;
-    }
-
-    public String getCertificate() {
-        return certificate;
-    }
-
-    public void setCertificate(String certificate) {
-        this.certificate = certificate;
-    }
-
-    public String getMaterial() {
-        return material;
-    }
-
-    public void setMaterial(String material) {
-        this.material = material;
-    }
-
-    public String getCertify() {
-        return certify;
-    }
-
-    public void setCertify(String certify) {
-        this.certify = certify;
-    }
-}
-

+ 0 - 1
donate-service/src/main/java/com/uas/service/donate/service/MessageService.java

@@ -1,7 +1,6 @@
 package com.uas.service.donate.service;
 
 import org.springframework.http.ResponseEntity;
-
 import java.util.List;
 import java.util.Map;
 

+ 19 - 6
donate-service/src/main/java/com/uas/service/donate/service/UserService.java

@@ -2,12 +2,11 @@ package com.uas.service.donate.service;
 
 
 import com.uas.platform.core.model.PageInfo;
-import com.uas.service.donate.model.ActivityRecode;
-import com.uas.service.donate.model.ProjectRecode;
-import com.uas.service.donate.model.SearchFilter;
-import com.uas.service.donate.model.User;
+import com.uas.service.donate.model.*;
 import org.springframework.data.domain.Page;
 
+import javax.persistence.criteria.CriteriaBuilder;
+
 public interface UserService {
     //返回某人个人信息
     User findOne(Long id);
@@ -29,7 +28,7 @@ public interface UserService {
      * 获取已参与项目
      * @param pageInfo 分页参数
      * @param filter 查找filter
-     * @return 用户分页
+     * @return 项目记录分页
      */
     Page<ProjectRecode> getJoinedProjectRecords(PageInfo pageInfo, SearchFilter filter);
 
@@ -37,7 +36,21 @@ public interface UserService {
      * 获取已参与活动
      * @param pageInfo 分页参数
      * @param filter 查找filter
-     * @return 用户分页
+     * @return 活动记录分页
      */
     Page<ActivityRecode> getJoinedActivityRecords(PageInfo pageInfo, SearchFilter filter);
+
+    /**
+     * 获取收到的消息
+     * @param pageInfo 分页参数
+     * @param filter 查找filter
+     * @return message分页
+     */
+    Page<MessageDetail> getMessage(PageInfo pageInfo, SearchFilter filter);
+
+    /**
+     * 获取未读消息数量
+     * @return
+     */
+    Integer getUnreadMessageNum();
 }

+ 0 - 1
donate-service/src/main/java/com/uas/service/donate/service/impl/ProjectServiceImpl.java

@@ -6,7 +6,6 @@ import com.uas.platform.core.persistence.criteria.PredicateUtils;
 import com.uas.service.donate.dao.ActivityDao;
 import com.uas.service.donate.dao.ProjectDao;
 import com.uas.service.donate.dao.ProjectRecodeDao;
-import com.uas.service.donate.dao.UserDao;
 import com.uas.service.donate.model.Activity;
 import com.uas.service.donate.model.Project;
 import com.uas.service.donate.model.ProjectRecode;

+ 46 - 7
donate-service/src/main/java/com/uas/service/donate/service/impl/UserServiceImpl.java

@@ -3,13 +3,8 @@ package com.uas.service.donate.service.impl;
 import com.uas.account.util.AccountUtils;
 import com.uas.platform.core.model.PageInfo;
 import com.uas.service.donate.core.support.SystemSession;
-import com.uas.service.donate.dao.ActivityRecodeDao;
-import com.uas.service.donate.dao.ProjectRecodeDao;
-import com.uas.service.donate.dao.UserDao;
-import com.uas.service.donate.model.ActivityRecode;
-import com.uas.service.donate.model.ProjectRecode;
-import com.uas.service.donate.model.SearchFilter;
-import com.uas.service.donate.model.User;
+import com.uas.service.donate.dao.*;
+import com.uas.service.donate.model.*;
 import com.uas.service.donate.service.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
@@ -33,6 +28,14 @@ public class UserServiceImpl implements UserService {
     @Autowired
     private ProjectRecodeDao projectRecodeDao;
 
+    @Autowired
+    private MessageDao messageDao;
+
+    @Autowired
+    private MessageDetailDao messageDetailDao;
+
+    static final Short NOT_READ = 0;
+
     //返回某人个人信息
     public User findOne(Long id){
         return userDao.findOne(id);
@@ -130,4 +133,40 @@ public class UserServiceImpl implements UserService {
         }
         return null;
     }
+
+    /**
+     * 获取收到的消息
+     *
+     * @param pageInfo 分页参数
+     * @param filter   查找filter
+     * @return 用户分页
+     */
+    @Override
+    public Page<MessageDetail> getMessage(PageInfo pageInfo, SearchFilter filter) {
+        if (null != SystemSession.getUser()) {
+            final Long userUU = SystemSession.getUser().getUserUU();
+            return messageDetailDao.findAll(new Specification<MessageDetail>() {
+                @Override
+                public Predicate toPredicate(Root<MessageDetail> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
+                    query.where(cb.equal(root.get("receiveUserUU"), userUU));
+                    return null;
+                }
+            }, pageInfo);
+        }
+        return null;
+    }
+
+    /**
+     * 获取未读消息数量
+     *
+     * @return
+     */
+    @Override
+    public Integer getUnreadMessageNum() {
+        if (null != SystemSession.getUser()) {
+            final Long userUU = SystemSession.getUser().getUserUU();
+            return messageDetailDao.findByReceiveUserUUAndReadStatus(userUU, NOT_READ).size();
+        }
+        return null;
+    }
 }

+ 24 - 17
donate-service/src/main/webapp/resources/js/project/app.js

@@ -90,36 +90,43 @@ define([ 'angularAMD', 'ui.router', 'ui-bootstrap', 'ngLocal', 'ngTable', 'commo
                 alert("查询支付结果出错");
             });
 
+            var userUU = SessionService.getCookie('useruu');
             // 验证登录
             AuthenticationService.getAuthentication().success(function(data) {
                 if(data && data.content) {
                     $scope.user = data.content;
+                    // 如果是当前页已登录,就给userUU赋值
+                    if (angular.isUndefined(userUU) || null === userUU) {
+                        userUU = $scope.user.userUU;
+                    }
+                }
+                if (!angular.isUndefined(userUU) && null !== userUU) {
+                    //TODO 注册完毕将userUU放入cookie,在此处获取,进行查询是否已插入对应项目参加记录和参加活动
+                    Project.joinAfterDonate({projectRecodeId: tradeNo, userUU: userUU}, {}, function(data) {
+                        if (data.success) {
+                            console.log(data.success);
+                        }
+                        if (data.error) {
+                            console.log(data.error);
+                        }
+                    }, function (res) {
+                        console.log(res);
+                    });
+                    SessionService.removeCookie('useruu');
                 }
                 $scope.isAuthed = data !== null && !angular.isUndefined(data.content);
             });
-
-            var userUU = SessionService.getCookie('userUU');
-            if (!angular.isUndefined(userUU) && null != userUU) {
-                //TODO 注册完毕将userUU放入cookie,在此处获取,进行查询是否已插入对应项目参加记录和参加活动
-                Project.joinAfterDonate({projectRecodeId: tradeNo, userUU: userUU}, {}, function(data) {
-                    if (data.success) {
-                        console.log(data.success);
-                    }
-                    if (data.error) {
-                        console.log(data.error);
-                    }
-                }, function (res) {
-                    console.log(res);
-                });
-                SessionService.removeCookie('userUU');
-            }
         };
         loadData();
 
-        $scope.loginAfterDonate = function() {
+        $scope.registerAfterDonate = function() {
             AuthenticationService.redirectRegister();
         };
 
+        $scope.loginAfterDonate = function() {
+            AuthenticationService.redirectSignin();
+        }
+
     }]);
 
     app.controller('donateQrcodeCtrl', ['$scope', '$stateParams', '$http', function ($scope, $stateParams, $http) {

+ 2 - 2
donate-service/src/main/webapp/resources/js/user/controllers/UserCtrl.js

@@ -47,7 +47,7 @@ define([ 'app/app' ], function(app) {
             }
         }, {
             total: 0,
-            counts: [5, 10, 25, 50],
+            counts: [],
             getData: function ($defer, params) {
                 $scope.loading = true;
                 var pageParams = params.url();
@@ -81,7 +81,7 @@ define([ 'app/app' ], function(app) {
                 if(data && data.content) {
                     $scope.user = data.content;
                 }
-                // $scope.isAuthed = data !== null && !angular.isUndefined(data.content);
+                $scope.isAuthed = data !== null && !angular.isUndefined(data.content);
             });
 
             User.getUserHistory({}, {}, function(data) {

+ 1 - 1
donate-service/src/main/webapp/resources/view/project/donationsOver.html

@@ -188,7 +188,7 @@
             <!-- 有对应的活动,且已登录 -->
             <div ng-if="isAuthed && relatedActivity" class="txt">捐款成功后已自动参与【<a style="margin-left: 0;" href="/activity#/detail/{{relatedActivity.id}}" target="_blank"><span ng-bind="relatedActivity.name"></span></a>】活动,将有机会获得丰厚奖品。<a href="/activity#/detail/{{relatedActivity.id}}" target="_blank">立即查看</a></div>
             <!--TODO 有对应的活动,未登录,未注册 -->
-            <div ng-if="!isAuthed && !projectRecodeId && relatedActivity" class="txt">捐款成功,<span ng-click="loginAfterDonate(projectRecode.id)" style="cursor: pointer;">点此注册</span>之后将自动参与【<a style="margin-left: 0;" href="/activity#/detail/{{relatedActivity.id}}" target="_blank"><span ng-bind="relatedActivity.name"></span></a>】活动,有机会获得丰厚奖品。<a href="/activity#/detail/{{relatedActivity.id}}" target="_blank">立即查看</a></div>
+            <div ng-if="!isAuthed && !projectRecodeId && relatedActivity" class="txt">捐款成功,在此页面<span ng-click="registerAfterDonate(projectRecode.id)" style="cursor: pointer; color: #ff6000;">注册</span>/<span ng-click="loginAfterDonate(projectRecode.id)" style="cursor: pointer; color: #5078cb;">登录</span>之后将自动参与【<a style="margin-left: 0;" href="/activity#/detail/{{relatedActivity.id}}" target="_blank"><span ng-bind="relatedActivity.name"></span></a>】活动,有机会获得丰厚奖品。<a href="/activity#/detail/{{relatedActivity.id}}" target="_blank">立即查看</a></div>
             <!-- 有对应的活动,注册完毕跳回此页 -->
             <div ng-if="!isAuthed && projectRecodeId && relatedActivity" class="txt">已自动参与【<a style="margin-left: 0;" href="/activity#/detail/{{relatedActivity.id}}" target="_blank"><span ng-bind="relatedActivity.name"></span></a>】活动,有机会获得丰厚奖品。<a href="/activity#/detail/{{relatedActivity.id}}" target="_blank">立即查看</a></div>
             <!-- 无对应的活动 -->

+ 7 - 13
donate-service/src/main/webapp/resources/view/user/user_center.html

@@ -937,25 +937,19 @@
                                 </td>
                             </tr>
                             </tbody>
-                            <tbody ng-repeat="message in $data">
+                            <tbody ng-repeat="messageDetail in $data">
                             <tr class="news-list">
-                                <td class="read">{{$index + 1}}<em ng-class="{'red':message.readStatus != 1}"></em></td>
-                                <td>{{message.title}}</td>
-                                <td class="third">{{message.context}}</td>
+                                <td class="read">{{$index + 1}}<em ng-class="{'red':messageDetail.message.readStatus != 1}"></em></td>
+                                <td>{{messageDetail.message.title}}</td>
+                                <td class="third"><span ng-bind-html="messageDetail.message.context"></span></td>
                             </tr>
-                            <tr class="news-detail">
+                            <tr class="news-detail" style="display: none;">
                                 <td colspan="3">
                                     <div class="new-top">
-                                        <!--<p> 全新优软一元捐感恩回馈活动 011期马上要开始咯~</p>-->
-                                        <!--<p>届时活动将会关联全平台所有项目,只要在活动时间内在平台上先出您的爱心,即可参加活动抽奖!</p>-->
-                                        <!--<p>本次活动将会抽出全新iPhone X  30台!</p>-->
-                                        {{message.detail}}
-                                        <p>更多好礼请点击链接查看:<a href="http://www.usoftmall.com/">http://www.usoftmall.com/</a></p>
-                                        <div class="img">
-                                            <img src="{{message.img}}" alt="活动缩略图"/>
+                                        <div class="img" ng-bind-html="messageDetail.message.detail">
                                         </div>
                                         <div class="time-list">
-                                            <span>{{message.date | date: 'yyyy-MM-dd'}}</span> <span class="show-up">收起</span>
+                                            <span>{{messageDetail.message.date | date: 'yyyy-MM-dd'}}</span> <span class="show-up">收起</span>
                                         </div>
                                     </div>
                                 </td>