Преглед изворни кода

编辑消息发送;消息事件修改

dongbw пре 8 година
родитељ
комит
1946fa1026
42 измењених фајлова са 1068 додато и 438 уклоњено
  1. 18 2
      donate-console/src/main/java/com/uas/console/donate/controller/MessageController.java
  2. 14 13
      donate-console/src/main/java/com/uas/console/donate/controller/OrgController.java
  3. 12 15
      donate-console/src/main/java/com/uas/console/donate/controller/UserController.java
  4. 20 0
      donate-console/src/main/java/com/uas/console/donate/dao/UserDao.java
  5. 2 2
      donate-console/src/main/java/com/uas/console/donate/event/ActivityPublishEvent.java
  6. 1 1
      donate-console/src/main/java/com/uas/console/donate/event/GetPrizePublishEvent.java
  7. 1 1
      donate-console/src/main/java/com/uas/console/donate/event/OrgAuditPublishEvent.java
  8. 1 1
      donate-console/src/main/java/com/uas/console/donate/event/ProjectAuditPublishEvent.java
  9. 1 1
      donate-console/src/main/java/com/uas/console/donate/event/ProjectConcludePublishEvent.java
  10. 1 1
      donate-console/src/main/java/com/uas/console/donate/event/ProjectFinancePublishEvent.java
  11. 2 2
      donate-console/src/main/java/com/uas/console/donate/event/ProjectPublishEvent.java
  12. 1 1
      donate-console/src/main/java/com/uas/console/donate/event/ProjectReportPublishEvent.java
  13. 1 1
      donate-console/src/main/java/com/uas/console/donate/listener/PublishListener.java
  14. 3 1
      donate-console/src/main/java/com/uas/console/donate/model/Message.java
  15. 1 1
      donate-console/src/main/java/com/uas/console/donate/model/Org.java
  16. 24 9
      donate-console/src/main/java/com/uas/console/donate/model/User.java
  17. 9 0
      donate-console/src/main/java/com/uas/console/donate/service/MessageService.java
  18. 8 0
      donate-console/src/main/java/com/uas/console/donate/service/OrgService.java
  19. 6 0
      donate-console/src/main/java/com/uas/console/donate/service/UserService.java
  20. 167 8
      donate-console/src/main/java/com/uas/console/donate/service/impl/MessageServiceImpl.java
  21. 57 1
      donate-console/src/main/java/com/uas/console/donate/service/impl/OrgServiceImpl.java
  22. 15 5
      donate-console/src/main/java/com/uas/console/donate/service/impl/UserServiceImpl.java
  23. 1 2
      donate-console/src/main/webapp/WEB-INF/views/index.html
  24. 16 0
      donate-console/src/main/webapp/resources/css/base.css
  25. 358 152
      donate-console/src/main/webapp/resources/js/index/app.js
  26. 5 0
      donate-console/src/main/webapp/resources/js/index/services/Message.js
  27. 5 0
      donate-console/src/main/webapp/resources/js/index/services/Organization.js
  28. 5 0
      donate-console/src/main/webapp/resources/js/index/services/User.js
  29. 69 20
      donate-console/src/main/webapp/resources/view/message/message_edit.html
  30. 2 2
      donate-console/src/main/webapp/resources/view/message/message_list.html
  31. 108 0
      donate-console/src/main/webapp/resources/view/message/select_receiver_org.html
  32. 0 174
      donate-console/src/main/webapp/resources/view/message/select_receiver_role.html
  33. 103 0
      donate-console/src/main/webapp/resources/view/message/select_receiver_user.html
  34. 5 5
      donate-console/src/main/webapp/resources/view/project/project_detail.html
  35. 1 1
      donate-service/src/main/java/com/uas/service/donate/event/ActivityJoinedPublishEvent.java
  36. 1 1
      donate-service/src/main/java/com/uas/service/donate/event/ProjectJoinedPublishEvent.java
  37. 1 1
      donate-service/src/main/java/com/uas/service/donate/event/TakePrizePublishEvent.java
  38. 1 1
      donate-service/src/main/java/com/uas/service/donate/listener/PublishListener.java
  39. 3 1
      donate-service/src/main/java/com/uas/service/donate/model/Message.java
  40. 4 3
      donate-service/src/main/java/com/uas/service/donate/model/Org.java
  41. 10 8
      donate-service/src/main/java/com/uas/service/donate/model/User.java
  42. 5 1
      donate-service/src/main/java/com/uas/service/donate/service/impl/UserServiceImpl.java

+ 18 - 2
donate-console/src/main/java/com/uas/console/donate/controller/MessageController.java

@@ -1,5 +1,6 @@
 package com.uas.console.donate.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.uas.console.donate.model.Message;
 import com.uas.console.donate.model.SearchFilter;
 import com.uas.console.donate.model.UsageBufferedLogger;
@@ -10,8 +11,11 @@ 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.ui.ModelMap;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 /**
  * 消息相关
  * Created by dongbw
@@ -35,7 +39,6 @@ public class MessageController {
      * @param searchFilter 查找filter
      * @return
      */
-    @ResponseBody
     @RequestMapping(value= "/getAll", method = RequestMethod.GET)
     public Page<Message> getAllMessages(PageParams pageParams, String searchFilter){
         PageInfo pageInfo = new PageInfo(pageParams);
@@ -49,7 +52,6 @@ public class MessageController {
      * @param id 消息id
      * @return 消息详情
      */
-    @ResponseBody
     @RequestMapping(value= "/detail/{id}", method = RequestMethod.GET)
     public Message getDetailById(@PathVariable("id") Long id){
         Message message = messageService.getDetailById(id);
@@ -57,5 +59,19 @@ public class MessageController {
         return message;
     }
 
+    /**
+     * 发布消息
+     * @param message 消息内容
+     * @param receiver  接收对象
+     * @return 处理结果
+     */
+    @RequestMapping(value = "/publish", method = RequestMethod.POST)
+    public ModelMap publishMessage(@RequestParam String message, @RequestBody String receiver) {
+        List<String> receivers = JSON.parseArray(receiver, String.class);
+        Message msg = JSON.parseObject(message, Message.class);
+        ModelMap map = messageService.publishMessage(receivers, msg);
+        logger.log("消息中心", "在后台编辑并向指定用户发送消息", msg.getTitle(), null, (Long) map.get("id"));
+        return map;
+    }
 
 }

+ 14 - 13
donate-console/src/main/java/com/uas/console/donate/controller/OrgController.java

@@ -21,7 +21,7 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 
-@Controller
+@RestController
 @RequestMapping("/org")
 public class OrgController {
 
@@ -36,7 +36,6 @@ public class OrgController {
     /**
      * 发起机构,有草稿取出草稿,没有草稿就新增
      */
-    @ResponseBody
     @RequestMapping(value = "/show",method = RequestMethod.GET)
     public Org show(Long uuid){
         logger.log("机构入驻", "获取机构草稿");
@@ -46,7 +45,6 @@ public class OrgController {
     /**
      * 保存机构草稿
      */
-    @ResponseBody
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     public ModelMap save(@RequestParam(required = false) MultipartFile logo,
                          @RequestParam(required = false) MultipartFile certificate,
@@ -95,7 +93,6 @@ public class OrgController {
     /**
      *提交机构申请
      */
-    @ResponseBody
     @RequestMapping(value = "/submit",method = RequestMethod.POST)
     public ModelMap submit(@RequestParam(required = false) MultipartFile logo,
                       @RequestParam(required = false) MultipartFile certificate,
@@ -143,7 +140,6 @@ public class OrgController {
     /**
      * 查询某一机构详情信息
      */
-    @ResponseBody
     @RequestMapping(value = "/detail/{id}",method = RequestMethod.GET)
     public Org detail(@PathVariable("id") Long id){
         Org org = orgService.findOne(id);
@@ -154,7 +150,6 @@ public class OrgController {
     /**
      * 批准机构申请
      */
-    @ResponseBody
     @RequestMapping(value = "/approve/{id}",method = RequestMethod.POST)
     public ModelMap approve(@PathVariable("id") Long id){
         logger.log("机构入驻", "批准机构申请", null, null, id);
@@ -164,7 +159,6 @@ public class OrgController {
     /**
      * 拒绝机构申请
      */
-    @ResponseBody
     @RequestMapping(value = "/unapprove/{id}",method = RequestMethod.POST)
     public ModelMap unapprove(@PathVariable("id") Long id,String refuse){
         logger.log("机构入驻", "驳回机构申请", "理由:" + refuse, null, id);
@@ -197,7 +191,6 @@ public class OrgController {
      * @return 机构分页
      */
     @RequestMapping(method = RequestMethod.GET)
-    @ResponseBody
     public Page<Org> getAllOrgs(PageParams params, String searchFilter){
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -212,7 +205,6 @@ public class OrgController {
      * @return 机构分页
      */
     @RequestMapping(params = RequestState.DONE, method = RequestMethod.GET)
-    @ResponseBody
     public Page<Org> getAuditedOrgs(PageParams params, String searchFilter){
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -227,7 +219,6 @@ public class OrgController {
      * @return 机构分页
      */
     @RequestMapping(params = RequestState.TODO, method = RequestMethod.GET)
-    @ResponseBody
     public Page<Org> getUnauditedProjects(PageParams params, String searchFilter){
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -242,7 +233,6 @@ public class OrgController {
      * @return 机构分页
      */
     @RequestMapping(params = RequestState.REFUSED, method = RequestMethod.GET)
-    @ResponseBody
     public Page<Org> getDisagreedProjects(PageParams params, String searchFilter){
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -255,7 +245,6 @@ public class OrgController {
      * @return 各机构数量
      */
     @RequestMapping(value="/getOrgsNum", method = RequestMethod.GET)
-    @ResponseBody
     public ModelMap getOrgsNum(){
         logger.log("机构", "获取各类机构数量");
         return orgService.getOrgsNum();
@@ -267,9 +256,21 @@ public class OrgController {
      * @return
      */
     @RequestMapping(value="/delete/{id}", method = RequestMethod.DELETE)
-    @ResponseBody
     public ModelMap delete(@PathVariable("id") Long id){
         logger.log("机构", "删除机构信息(未通过)", null, null, id);
         return orgService.delete(id);
     }
+
+    /**
+     * 编辑消息时,获取机构列表
+     * @param params 分页参数
+     * @param keyword  关键词
+     * @return
+     */
+    @RequestMapping(value = "/getOrgOnMessage", method = RequestMethod.GET)
+    public Page<Org> getOrgOnMessage(PageParams params, String keyword) {
+        PageInfo pageInfo = new PageInfo(params);
+        logger.log("选择接收对象", "编辑消息时,选择结构接收对象");
+        return orgService.getOrgOnMessage(pageInfo, keyword);
+    }
 }

+ 12 - 15
donate-console/src/main/java/com/uas/console/donate/controller/UserController.java

@@ -10,12 +10,8 @@ import com.uas.platform.core.model.PageParams;
 import com.uas.platform.core.web.bind.RequestState;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
-import org.springframework.stereotype.Controller;
 import org.springframework.ui.ModelMap;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
@@ -23,7 +19,7 @@ import java.util.List;
  * 处理用户相关请求
  */
 
-@Controller
+@RestController
 @RequestMapping("/user")
 public class UserController extends CommonController {
 
@@ -39,7 +35,6 @@ public class UserController extends CommonController {
      * 获取所以用户信息
      * @return 用户list
      */
-    @ResponseBody
     @RequestMapping("/getUsers")
     public List<User> getUsers() {
         logger.log("用户", "获取所有用户信息");
@@ -51,7 +46,6 @@ public class UserController extends CommonController {
      * @param userUU 用户UU
      * @return 用户信息实体
      */
-    @ResponseBody
     @RequestMapping(value = "/detail/{userUU}", method = RequestMethod.GET)
     public User getDetailByUserUU(@PathVariable("userUU") Long userUU) {
         logger.log("用户", "获取单个用户信息:" + userUU);
@@ -65,7 +59,6 @@ public class UserController extends CommonController {
      * @return 用户分页
      */
     @RequestMapping(method = RequestMethod.GET)
-    @ResponseBody
     public Page<User> getAllUsers(PageParams params, String searchFilter) {
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -80,7 +73,6 @@ public class UserController extends CommonController {
      * @return 用户分页
      */
     @RequestMapping(params = RequestState.DONE, method = RequestMethod.GET)
-    @ResponseBody
     public Page<User> getAdmins(PageParams params, String searchFilter) {
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -95,7 +87,6 @@ public class UserController extends CommonController {
      * @return 用户分页
      */
     @RequestMapping(params = RequestState.TODO, method = RequestMethod.GET)
-    @ResponseBody
     public Page<User> getOrgUsers(PageParams params, String searchFilter) {
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -110,7 +101,6 @@ public class UserController extends CommonController {
      * @return 用户分页
      */
     @RequestMapping(params = RequestState.END, method = RequestMethod.GET)
-    @ResponseBody
     public Page<User> getOrgOperators(PageParams params, String searchFilter) {
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -123,7 +113,6 @@ public class UserController extends CommonController {
      * @return 各类用户数量
      */
     @RequestMapping(value = "/getUserNum", method = RequestMethod.GET)
-    @ResponseBody
     public ModelMap getUserNum() {
         logger.log("项目", "获取各类用户数量");
         return userService.getUserNum();
@@ -136,7 +125,6 @@ public class UserController extends CommonController {
      * @return 用户分页
      */
     @RequestMapping(value = "/getJoinedProjectRecords", method = RequestMethod.GET)
-    @ResponseBody
     public Page<ProjectRecode> getJoinedProjectRecords(PageParams params, String searchFilter) {
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -151,7 +139,6 @@ public class UserController extends CommonController {
      * @return 用户分页
      */
     @RequestMapping(value = "/getJoinedActivityRecords", method = RequestMethod.GET)
-    @ResponseBody
     public Page<ActivityRecode> getJoinedActivityRecords(PageParams params, String searchFilter) {
         PageInfo pageInfo = new PageInfo(params);
         SearchFilter filter = JSONObject.parseObject(searchFilter, SearchFilter.class);
@@ -159,4 +146,14 @@ public class UserController extends CommonController {
         return userService.getJoinedActivityRecords(pageInfo, filter);
     }
 
+    /**
+     * 获取所有用户类型
+     * @return 所有用户类型
+     */
+    @RequestMapping(value = "/getAllTypes", method = RequestMethod.GET)
+    public ModelMap getAllTypes() {
+        return new ModelMap("types", userService.getAllTypes());
+    }
+
+
 }

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

@@ -3,6 +3,7 @@ package com.uas.console.donate.dao;
 import com.uas.console.donate.model.User;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 
 import java.util.List;
@@ -10,5 +11,24 @@ import java.util.List;
 @Repository
 public interface UserDao extends JpaRepository<User,Long>, JpaSpecificationExecutor<User>{
 
+    /**
+     * 根据类型获取用户
+     * @param type
+     * @return
+     */
     List<User> findByType(String type);
+
+    /**
+     * 获取所有用户类型
+     * @return 用户类型list
+     */
+    @Query("select distinct u.type from User u order by u.type")
+    List<String> findAllTypes();
+
+    /**
+     * 根据机构id查找某机构所有用户
+     * @param orgId 机构id
+     * @return 用户list
+     */
+    List<User> findByOrgId(Long orgId);
 }

+ 2 - 2
donate-console/src/main/java/com/uas/console/donate/event/ActivityPublishEvent.java

@@ -35,7 +35,7 @@ public class ActivityPublishEvent extends PublishEvent<MessageDetail, Activity>
         // 发起人UU
         Long userUU = activity.getUserUU();
         // 类型
-        String type = "消息提醒";
+        String type = "所有用户";
         // 来源表
         String table = "donate$activity";
         // 来源id
@@ -47,7 +47,7 @@ public class ActivityPublishEvent extends PublishEvent<MessageDetail, Activity>
         // 内容
         String context = "新活动发布:" + activity.getName() + "(" + activity.getCode() + ")";
         // 接收对象
-        String receiver = "所有";
+        String receiver = "所有用户";
         Message message = new Message(userUU, title, context, type, table, sourceId, url, receiver);
         MessageDetail messageDetail = new MessageDetail();
         messageDetail.setMessage(message);

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/event/GetPrizePublishEvent.java

@@ -33,7 +33,7 @@ public class GetPrizePublishEvent extends PublishEvent<MessageDetail, ActivityRe
         // 发起人UU
         Long userUU = activity.getUserUU();
         // 类型
-        String type = "活动消息";
+        String type = "指定用户";
         // 来源表
         String table = "donate$activityrecode";
         // 来源id

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/event/OrgAuditPublishEvent.java

@@ -40,7 +40,7 @@ public class OrgAuditPublishEvent extends PublishEvent<MessageDetail, Org> {
         // 发起人UU
         Long userUU = org.getUuid();
         // 类型
-        String type = "机构消息";
+        String type = "指定用户";
         // 来源表
         String table = "donate$organization";
         // 来源id

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/event/ProjectAuditPublishEvent.java

@@ -38,7 +38,7 @@ public class ProjectAuditPublishEvent extends PublishEvent<MessageDetail, Projec
         // 发起人UU
         Long userUU = project.getUserUU();
         // 类型
-        String type = "项目消息";
+        String type = "指定用户";
         // 来源表
         String table = "donate$project";
         // 来源id

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/event/ProjectConcludePublishEvent.java

@@ -33,7 +33,7 @@ public class ProjectConcludePublishEvent extends PublishEvent<MessageDetail, Pro
         // 发起人UU
         Long userUU = project.getUserUU();
         // 类型
-        String type = "项目相关";
+        String type = "指定用户";
         // 来源表
         String table = "donate$projectconclude";
         // 来源id

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/event/ProjectFinancePublishEvent.java

@@ -33,7 +33,7 @@ public class ProjectFinancePublishEvent extends PublishEvent<MessageDetail, Proj
         // 发起人UU
         Long userUU = project.getUserUU();
         // 类型
-        String type = "项目相关";
+        String type = "指定用户";
         // 来源表
         String table = "donate$projectfinance";
         // 来源id

+ 2 - 2
donate-console/src/main/java/com/uas/console/donate/event/ProjectPublishEvent.java

@@ -35,7 +35,7 @@ public class ProjectPublishEvent extends PublishEvent<MessageDetail, Project> {
         // 发起人UU
         Long userUU = project.getUserUU();
         // 类型
-        String type = "消息提醒";
+        String type = "所有用户";
         // 来源表
         String table = "donate$project";
         // 来源id
@@ -47,7 +47,7 @@ public class ProjectPublishEvent extends PublishEvent<MessageDetail, Project> {
         // 内容
         String context = "新项目发布:" + project.getName() + "(" + project.getCode() + ")";
         // 接收对象
-        String receiver = "所有";
+        String receiver = "所有用户";
         Message message = new Message(userUU, title, context, type, table, sourceId, url, receiver);
         MessageDetail messageDetail = new MessageDetail();
         messageDetail.setMessage(message);

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/event/ProjectReportPublishEvent.java

@@ -33,7 +33,7 @@ public class ProjectReportPublishEvent extends PublishEvent<MessageDetail, Proje
         // 发起人UU
         Long userUU = project.getUserUU();
         // 类型
-        String type = "项目相关";
+        String type = "指定用户";
         // 来源表
         String table = "donate$projectreport";
         // 来源id

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/listener/PublishListener.java

@@ -191,7 +191,7 @@ public class PublishListener implements ApplicationListener<PublishEvent<?, ?>>
 		Set<Long> userUUs = new HashSet<>();
 		// 设置接收人数
 		message.setReceiverNum(receiverUsers.size());
-		// 为用户新增消息(这里是所有时,效率非常低,之后需要优化)
+		// 为用户新增消息(这里是所有用户时,效率非常低,之后需要优化)
 		for (User user : receiverUsers) {
 			try { //去除userUU为空值的情况
 				if (null != user.getUserUU() && !userUUs.contains(user.getUserUU())) {

+ 3 - 1
donate-console/src/main/java/com/uas/console/donate/model/Message.java

@@ -2,6 +2,7 @@ package com.uas.console.donate.model;
 
 import com.alibaba.fastjson.annotation.JSONField;
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.hibernate.validator.constraints.Length;
 
 import javax.persistence.*;
 import java.io.Serializable;
@@ -64,10 +65,11 @@ public class Message implements Serializable {
      * 消息正文
      */
     @Column(name = "dm_context")
+    @Length(max = 600)
     private String context;
 
     /**
-     * 消息类型(群体消息、私有消息)
+     * 消息类型(角色类型、机构对象、指定用户、所有用户--主动编辑)
      */
     @Column(name = "dm_type")
     private String type;

+ 1 - 1
donate-console/src/main/java/com/uas/console/donate/model/Org.java

@@ -32,7 +32,7 @@ public class Org implements Serializable{
 
 
     /**
-     *优软云账号
+     * 注册人UU
      */
     @Column(name="org_uuid")
     private Long uuid;

+ 24 - 9
donate-console/src/main/java/com/uas/console/donate/model/User.java

@@ -32,16 +32,22 @@ public class User implements Serializable{
     private String tel;
 
     @Column(name = "user_email")
-    private String userEmail;
+    private String email;
 
     @Column(name = "user_identity")
     private Integer identity;
 
+    /**
+     * 所属机构id
+     */
+    @Column(name = "user_orgid")
+    private Long orgId;
+
     /**
      * 所属机构
      */
-    @OneToOne(cascade = { CascadeType.REFRESH}, fetch = FetchType.EAGER)
-    @JoinColumn(name = "user_orgid")
+    @OneToOne(cascade = { CascadeType.REFRESH})
+    @JoinColumn(name = "user_orgid", insertable = false, updatable = false)
     @OrderBy("id")
     private Org org;
 
@@ -49,7 +55,7 @@ public class User implements Serializable{
     private Long userIMId;
 
     /**
-     * 用户所属类型
+     * 用户所属类型 (个人用户、管理员、机构用户、机构操作员)
      */
     @Column(name = "user_type")
     private String type;
@@ -77,10 +83,11 @@ public class User implements Serializable{
     }
 
     public User(UserView user) {
+        this.setType("个人用户");
         this.setUserUU(Long.valueOf(user.getDialectUID()));
         this.setName(user.getName());
         this.setTel(user.getUid());
-        this.setUserEmail(user.getSecondUID());
+        this.setEmail(user.getSecondUID());
     }
 
     public Long getUserUU() {
@@ -107,12 +114,12 @@ public class User implements Serializable{
         this.tel = tel;
     }
 
-    public String getUserEmail() {
-        return userEmail;
+    public String getEmail() {
+        return email;
     }
 
-    public void setUserEmail(String userEmail) {
-        this.userEmail = userEmail;
+    public void setEmail(String email) {
+        this.email = email;
     }
 
     public Integer getIdentity() {
@@ -170,4 +177,12 @@ public class User implements Serializable{
     public void setActTimes(Integer actTimes) {
         this.actTimes = actTimes;
     }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
 }

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

@@ -6,6 +6,7 @@ import com.uas.console.donate.model.SearchFilter;
 import com.uas.platform.core.model.PageInfo;
 import org.springframework.data.domain.Page;
 import org.springframework.http.ResponseEntity;
+import org.springframework.ui.ModelMap;
 
 import java.util.List;
 import java.util.Map;
@@ -54,4 +55,12 @@ public interface MessageService {
      * @param saveDetails 消息内容
      */
     void pushReleases(List<MessageDetail> saveDetails);
+
+    /**
+     * 发布消息
+     * @param receivers 接收对象
+     * @param message 消息实体
+     * @return 处理结果
+     */
+    ModelMap publishMessage(List<String> receivers, Message message);
 }

+ 8 - 0
donate-console/src/main/java/com/uas/console/donate/service/OrgService.java

@@ -58,4 +58,12 @@ public interface OrgService {
     ModelMap getOrgsNum();
 
     ModelMap delete(Long id);
+
+    /**
+     * 编辑消息时,获取机构列表
+     * @param pageInfo 页面参数
+     * @param keyword 关键词
+     * @return 机构分页
+     */
+    Page<Org> getOrgOnMessage(PageInfo pageInfo, String keyword);
 }

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

@@ -37,4 +37,10 @@ public interface UserService {
      * @return 用户分页
      */
     Page<ActivityRecode> getJoinedActivityRecords(PageInfo pageInfo, SearchFilter filter);
+
+    /**
+     * 获取所有用户类型
+     * @return 用户类型list
+     */
+    List<String> getAllTypes();
 }

+ 167 - 8
donate-console/src/main/java/com/uas/console/donate/service/impl/MessageServiceImpl.java

@@ -1,8 +1,11 @@
 package com.uas.console.donate.service.impl;
 
+import com.uas.account.util.AccountUtils;
 import com.uas.console.donate.MessageConfiguration;
+import com.uas.console.donate.core.support.SystemSession;
 import com.uas.console.donate.dao.MessageDao;
 import com.uas.console.donate.dao.MessageDetailDao;
+import com.uas.console.donate.dao.UserDao;
 import com.uas.console.donate.model.*;
 import com.uas.console.donate.service.MessageService;
 import com.uas.message.mail.service.MailService;
@@ -18,6 +21,7 @@ import org.springframework.data.jpa.domain.Specification;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.ui.ModelMap;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 
@@ -46,6 +50,9 @@ public class MessageServiceImpl implements MessageService {
     @Autowired
     private MessageConfiguration messageConfiguration;
 
+    @Autowired
+    private UserDao userDao;
+
     private static final UsageBufferedLogger logger = BufferedLoggerManager.getLogger(UsageBufferedLogger.class);
 
     private final static String PROD_URL = "http://113.105.74.140:8092/tigase/baiduPush";
@@ -69,9 +76,12 @@ public class MessageServiceImpl implements MessageService {
                                 PredicateUtils.like("type", keyword, false),
                                 PredicateUtils.like("user.name", keyword, false)));
                     }
-                    // 根据其实时间过滤
+                    // 根据起始时间过滤
                     if (null != filter.getFromDate()) {
                         pageInfo.expression(PredicateUtils.gte("publishDate", filter.getFromDate(), false));
+                    } else {
+                        //没选择时间段,就从当前时间过滤
+                        pageInfo.expression(PredicateUtils.gte("publishDate", new Date().getTime(), false));
                     }
                 }
                 query.where(pageInfo.getPredicates(root, query, builder));
@@ -156,13 +166,20 @@ public class MessageServiceImpl implements MessageService {
                 Map<String, Object> params = new HashMap<>();
                 User receiver = messageDetail.getReceiveUser();
                 // 如果imId为空,先去账户中心获取
-                //TODO 账户中心还未部署,部署之后打开注释
-//                if (null == receiver.getUserIMId()) {
-//                    Long imId = AccountUtils.getImIdByUserUU(messageDetail.getReceiveUserUU());
-//                    User user = userDao.findOne(receiver.getUserUU());
-//                    user.setUserIMId(imId);
-//                    receiver = userDao.save(user);
-//                }
+                if (null == receiver.getUserIMId()) {
+                    Long imId = null;
+                    try {
+                        imId = AccountUtils.getImIdByUserUU(messageDetail.getReceiveUserUU());
+                    } catch (Exception e) {
+                        logger.log("推送消息", "根据uu获取imId失败:" + messageDetail.getReceiveUserUU(), null, messageDetail.getMessage().getUserUU());
+                        e.printStackTrace();
+                    }
+                    if (null != imId) {
+                        User user = userDao.findOne(receiver.getUserUU());
+                        user.setUserIMId(imId);
+                        receiver = userDao.save(user);
+                    }
+                }
                 // 防止获取失败,再判断一次
                 if (null != receiver.getUserIMId()) {
                     params.put("master", messageDetail.getMessage().getUser().getOrg().getName());//账套 公司名称
@@ -196,4 +213,146 @@ public class MessageServiceImpl implements MessageService {
             messageDetailDao.setPushedByIds(detailIds.toArray());
         }
     }
+
+    /**
+     * 发布消息
+     *
+     * @param receivers 接收对象
+     * @param message   消息实体
+     * @return 处理结果
+     */
+    @Override
+    public ModelMap publishMessage(List<String> receivers, Message message) {
+        ModelMap map = new ModelMap();
+        if (!"所有用户".equals(message.getType()) && (null == receivers || CollectionUtils.isEmpty(receivers))) {
+            map.put("error", "未得到有效的接收对象");
+            return map;
+        }
+        if (null == message.getTitle() || null == message.getContext() || null == message.getType()) {
+            map.put("error", "必填项未填写,无法发布!");
+        }
+        // 按角色类型发送时,receivers为角色名称的数组
+        if ("角色类型".equals(message.getType())) {
+            return publishMessageByType(receivers, message);
+        } else if ("所有用户".equals(message.getType())) {
+            return publishMessageToAllUsers(message);
+        } else if ("机构对象".equals(message.getType())) {
+            return publishMessageToOrgUsers(receivers, message);
+        } else if ("指定用户".equals(message.getType())) {
+            return publishMessageToSelectedUsers(receivers, message);
+        }
+        map.put("error", "消息接收对象不满足处理条件,处理失败");
+        return map;
+    }
+
+    /**
+     * 给对应指定用户发送消息
+     * @param receivers  用户uu list
+     * @param message 消息内容
+     * @return 处理结果 消息id
+     */
+    private ModelMap publishMessageToSelectedUsers(List<String> receivers, Message message) {
+        List<Long> userUUs = new ArrayList<>();
+        for (String userUU : receivers) {
+            userUUs.add(Long.valueOf(userUU));
+        }
+        // 用于存放接收用户的list
+        List<User> receiveUsers = userDao.findAll(userUUs);
+        // 消息接收对象设置
+        message.setReceiver("指定用户");
+        message.setReceiverNum(receiveUsers.size());
+        // 向用户发布消息
+        return publishToReceivers(receiveUsers, message);
+    }
+
+    /**
+     * 给对应机构的用户发送消息
+     * @param receivers  机构id list
+     * @param message 消息内容
+     * @return 处理结果 及消息id
+     */
+    private ModelMap publishMessageToOrgUsers(List<String> receivers, Message message) {
+        // 用于存放接收用户的list
+        List<User> receiveUsers = new ArrayList<>();
+        for (String orgId : receivers) {
+            List<User> users = userDao.findByOrgId(Long.valueOf(orgId));
+            receiveUsers.addAll(users);
+        }
+        // 消息接收对象设置
+        message.setReceiver("部分机构用户");
+        message.setReceiverNum(receiveUsers.size());
+        // 向用户发布消息
+        return publishToReceivers(receiveUsers, message);
+    }
+
+    /**
+     * 给所有用户发布消息
+     * @param message 消息
+     * @return 处理结果 及消息id
+     */
+    private ModelMap publishMessageToAllUsers(Message message) {
+        // 用于存放接收用户的list
+        List<User> receiveUsers = userDao.findAll();
+        // 消息接收对象设置
+        message.setReceiver("所有用户");
+        message.setReceiverNum(receiveUsers.size());
+        // 向用户发布消息
+        return publishToReceivers(receiveUsers, message);
+    }
+
+    /**
+     * 根据角色类型发布消息
+     * @param receivers  接收用户
+     * @param message 消息
+     */
+    private ModelMap publishMessageByType(List<String> receivers, Message message) {
+        // 用于存放接收用户的list
+        List<User> receiveUsers = new ArrayList<>();
+        // 消息接收对象设置
+        StringBuffer messageReceiver = new StringBuffer();
+        for (String type : receivers) {
+            List<User> users = userDao.findByType(type);
+            receiveUsers.addAll(users);
+            if (!StringUtils.isEmpty(messageReceiver) && !"".contentEquals(messageReceiver)) {
+                messageReceiver.append(";");
+            }
+            messageReceiver.append(type);
+        }
+        message.setReceiver(String.valueOf(messageReceiver));
+        message.setReceiverNum(receiveUsers.size());
+        // 向用户发布消息
+        return publishToReceivers(receiveUsers, message);
+    }
+
+    /**
+     * 向用户发布消息
+     * @param receiveUsers 接收用户
+     * @param message 消息
+     */
+    private ModelMap publishToReceivers(List<User> receiveUsers, Message message) {
+        ModelMap map = new ModelMap();
+        Date now = new Date();
+        message.setDate(now);
+        if (null == message.getPublishDate()) {
+            message.setPublishDate(now);
+        }
+        message.setUserUU(SystemSession.getUser().getUserUU());
+        message = messageDao.save(message);
+        // 最终保存的消息
+        List<MessageDetail> messageDetails = new ArrayList<>();
+        // 已添加消息的用户UU
+        List<Long> userUU = new ArrayList<>();
+        for (User receiveUser : receiveUsers) {
+            if (null != receiveUser.getUserUU() && !userUU.contains(receiveUser.getUserUU())) {
+                MessageDetail messageDetail = new MessageDetail(receiveUser.getUserUU());
+                messageDetail.setMessage(message);
+                messageDetails.add(messageDetail);
+                userUU.add(receiveUser.getUserUU());
+            }
+        }
+        messageDetailDao.save(messageDetails);
+        map.put("id", message.getId());
+        map.put("success", "发布成功");
+        return map;
+    }
 }

+ 57 - 1
donate-console/src/main/java/com/uas/console/donate/service/impl/OrgServiceImpl.java

@@ -1,10 +1,13 @@
 package com.uas.console.donate.service.impl;
 
 
+import com.uas.console.donate.core.support.SystemSession;
 import com.uas.console.donate.dao.OrgDao;
+import com.uas.console.donate.dao.UserDao;
 import com.uas.console.donate.event.OrgAuditPublishEvent;
 import com.uas.console.donate.model.Org;
 import com.uas.console.donate.model.SearchFilter;
+import com.uas.console.donate.model.User;
 import com.uas.console.donate.service.OrgService;
 import com.uas.console.donate.util.ContextUtils;
 import com.uas.platform.core.model.PageInfo;
@@ -31,10 +34,25 @@ import java.util.List;
 public class OrgServiceImpl implements OrgService {
 
     private static final SimpleDateFormat codesdf=new SimpleDateFormat("yyyyMMddhhmmsssss");
+    /**
+     * 批准申请
+     */
+    private static final Integer BE_AGREED = 1;
+    /**
+     * 公募
+     */
+    private static final Integer PUBLIC = 1;
+    /**
+     * 非公募
+     */
+    private static final Integer NOT_PUBLIC = 2;
 
     @Autowired
     private OrgDao orgDao;
 
+    @Autowired
+    private UserDao userDao;
+
     //取出机构信息
     @Override
     public Org show(Long uuid){
@@ -73,6 +91,7 @@ public class OrgServiceImpl implements OrgService {
         org.setSubmitTime(date);
         //设置机构编号
         org.setCode(codesdf.format(date));
+        org.setUuid(SystemSession.getUser().getUserUU());
         try{
             org = orgDao.save(org);
         } catch (Exception e) {
@@ -110,8 +129,14 @@ public class OrgServiceImpl implements OrgService {
                 map.put("error", "未找到该机构记录");
                 return map;
             }
-            org.setStatus(1);
+            org.setStatus(BE_AGREED);
             org = orgDao.save(org);
+            // 保存成功之后,修改用户为机构用户
+            User user = userDao.findOne(SystemSession.getUser().getUserUU());
+            if (null != user) {
+                user.setType("机构用户");
+                userDao.save(user);
+            }
             // 产生消息
             ContextUtils.publishEvent(new OrgAuditPublishEvent(Collections.singletonList(org)));
             map.put("success", "批准成功");
@@ -252,4 +277,35 @@ public class OrgServiceImpl implements OrgService {
         return map;
     }
 
+    /**
+     * 编辑消息时,获取机构列表
+     *
+     * @param pageInfo 页面参数
+     * @param keyword  关键词
+     * @return 机构分页
+     */
+    @Override
+    public Page<Org> getOrgOnMessage(final PageInfo pageInfo, final String keyword) {
+        return orgDao.findAll(new Specification<Org>() {
+            @Override
+            public Predicate toPredicate(Root<Org> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
+                if (!StringUtils.isEmpty(keyword)) {
+                    pageInfo.expression(PredicateUtils.or(PredicateUtils.like("name", keyword, false, true),
+                            PredicateUtils.like("majorArea", keyword, false, true),
+                            PredicateUtils.like("managerName", keyword, false, true),
+                            PredicateUtils.like("managerOph", keyword, false, true)));
+                }
+                // type公募为1,非公募为2。数据库存数字,所以这里处理成精确匹配
+                if ("公募".equals(keyword)) {
+                    pageInfo.expression(PredicateUtils.eq("type", PUBLIC, false));
+                }
+                if ("非公募".equals(keyword)) {
+                    pageInfo.expression(PredicateUtils.eq("type", NOT_PUBLIC, false));
+                }
+                query.where(pageInfo.getPredicates(root, query, cb));
+                return null;
+            }
+        }, pageInfo);
+    }
+
 }

+ 15 - 5
donate-console/src/main/java/com/uas/console/donate/service/impl/UserServiceImpl.java

@@ -1,8 +1,10 @@
 package com.uas.console.donate.service.impl;
 
-import com.uas.console.donate.core.support.SystemSession;
 import com.uas.console.donate.dao.*;
-import com.uas.console.donate.model.*;
+import com.uas.console.donate.model.ActivityRecode;
+import com.uas.console.donate.model.ProjectRecode;
+import com.uas.console.donate.model.SearchFilter;
+import com.uas.console.donate.model.User;
 import com.uas.console.donate.service.UserService;
 import com.uas.platform.core.model.PageInfo;
 import com.uas.platform.core.persistence.criteria.PredicateUtils;
@@ -79,9 +81,7 @@ public class UserServiceImpl implements UserService{
                                 PredicateUtils.like("userUU", keyword, false, true),
                                 PredicateUtils.like("tel", keyword, false, true),
                                 PredicateUtils.like("userEmail", keyword, false, true),
-                                PredicateUtils.like("org.name", keyword, false, true),
-                                PredicateUtils.like("org.province", keyword, false, true),
-                                PredicateUtils.like("org.city", keyword, false, true)));
+                                PredicateUtils.like("org.name", keyword, false, true)));
                     }
                 }
                 query.where(pageInfo.getPredicates(root, query, cb));
@@ -161,4 +161,14 @@ public class UserServiceImpl implements UserService{
         }
         return null;
     }
+
+    /**
+     * 获取所有用户类型
+     *
+     * @return 用户类型list
+     */
+    @Override
+    public List<String> getAllTypes() {
+        return userDao.findAllTypes();
+    }
 }

+ 1 - 2
donate-console/src/main/webapp/WEB-INF/views/index.html

@@ -112,8 +112,7 @@
                         <i class="fa fa-angle-left pull-right"></i>
                     </a>
                     <ul class="treeview-menu">
-                        <!-- TODO 暂时隐藏,稍后完善 -->
-                        <!--<li ng-class="{'active' : thief == 'new'}"><a ui-sref="editMessage">编辑消息</a></li>-->
+                        <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>

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

@@ -303,4 +303,20 @@ div.active-time ul.dropdown-menu span.btn-group.pull-left>button.btn:nth-child(2
 /* 富文本编辑框ul ol 显示 */
 .introduce .note-editable ol,.introduce .note-editable ul{
 	padding-left: 20px;
+}
+
+/* 输入框非法样式 */
+.content-setting .error{
+	margin-left: 0!important;
+	font-size: 12px !important;
+	color: red !important;
+}
+.showEmpty{
+	border: 1px dashed red;
+}
+.content-setting .form-group input:focus {
+	border: 1px solid #66afe9 !important ;
+	outline: 0;
+	-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);
 }

+ 358 - 152
donate-console/src/main/webapp/resources/js/index/app.js

@@ -3405,17 +3405,54 @@ 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) {
+    app.controller('MessageNewCtrl', ['$scope', 'BaseService', 'toaster', 'Message', '$http', '$upload', '$rootScope', '$modal', 'User',
+        function($scope, BaseService, toaster, Message, $http, $upload, $rootScope, $modal, User) {
             BaseService.scrollBackToTop();
             $rootScope.tree = 'message';
             $rootScope.thief = 'new';
             $scope.loading = true;
             $scope.editorConfig = editorConfig;
+            $scope.types = [];
+
+            $scope.message = {
+                // (角色类型、机构对象、指定用户、所有用户)
+                type: '角色类型'
+            };
+
+            var loadType = function() {
+                // 获取所有用户类型
+                User.getAllTypes({}, {}, function(data) {
+                    angular.forEach(data.types, function(type) {
+                        var tempType={
+                            type: null,
+                            checked: false
+                        };
+                        tempType.type = type;
+                        $scope.types.push(tempType);
+                    });
+                });
+            };
+            loadType();
 
-            $scope.message = {};
-            // 默认按角色类型发送
-            $scope.ifPersonal = 0;
+            // 判断是否未选择
+            $scope.noChoose = true;
+            /**
+             * 选择角色类型
+             * @param tempType 角色类型var
+             */
+            $scope.checkType = function(tempType) {
+                tempType.checked = !tempType.checked;
+                if (tempType.checked) {
+                    $scope.noChoose = false;
+                } else {
+                    $scope.noChoose = true;
+                    angular.forEach($scope.types, function(temp) {
+                        if (temp.checked) {
+                            $scope.noChoose = false;
+                        }
+                    });
+                }
+            };
 
             // 日期选择
             $scope.openDatePicker = function ($event, item, openParam) {
@@ -3425,156 +3462,131 @@ define([ 'angularAMD', 'ui.router', 'ui-bootstrap', 'ngLocal', 'ngTable', 'file-
             };
 
             /**
-             * 选择接收对象
+             * 关闭选择发布时间模态框时清空发布时间
              */
-            $scope.selectReceiver = function (ifPersonal) {
-                if (ifPersonal === 1) {
-                    // 指定用户模态框
+            $scope.clearPublishDate = function() {
+                $scope.message.publishDate = null;
+            };
 
-                } else {
-                    // 按角色类型模态框
+            /**
+             * 选择接收对象
+             */
+            $scope.selectReceiver = function (receiveType) {
+                // 角色类型和所有用户都不采用弹窗
+                if (receiveType == '机构对象') {
+                    // 选择机构
                     $modal.open({
                         animation: true,
                         size: 'lg',
-                        templateUrl: 'static/view/message/select_receiver_role.html',
+                        templateUrl: 'static/view/message/select_receiver_org.html',
                         controller: 'RoleReceiverChooseCtrl',
-                        // resolve: {
-                        //     message: function () {
-                        //         return $scope.message;
-                        //     }
-                        // }
+                        resolve: {
+                            message: function() {
+                                return $scope.message;
+                            }
+                        }
                     }).result.then(function (data) {
-                        //TODO 选择接收对象
+                        // 添加接收对象
+                        // angular.forEach(data, function (org) {
+                        //     if (!$scope.orgs) {// 不存在就先创建
+                        //         $scope.orgs = [];
+                        //     }
+                        //     for (var i = 0; i < $scope.orgs.length; i++) {
+                        //         if ($scope.orgs[i].id == org.id) {
+                        //             // 反选时删除
+                        //             $scope.orgs.splice(i, 1);
+                        //             break; // 判定到已存在,就终止循环。
+                        //         }
+                        //     }
+                        //     if (org.checked) {
+                        //        $scope.orgs.push({
+                        //            id: org.id,
+                        //            name: org.name
+                        //        });
+                        //     }
+                        // });
+                        $scope.orgs = data;
+                        $rootScope.selectedOrgs = $scope.orgs;
                     }, 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 = [];
+                } else if (receiveType == '指定用户') {
+                    // 指定用户
+                    $modal.open({
+                        animation: true,
+                        size: 'lg',
+                        templateUrl: 'static/view/message/select_receiver_user.html',
+                        controller: 'RoleReceiverChooseCtrl',
+                        resolve: {
+                            message: function() {
+                                return $scope.message;
+                            }
                         }
-                        $scope.selectedProjects.push(project);
-                        $scope.projects.splice(i, 1);
-                        i = i-1;
-                    }
-                }
-            };
+                    }).result.then(function (data) {
+                        // // 添加接收对象
+                        // angular.forEach(data, function (user) {
+                        //     if (!$scope.users) {// 不存在就先创建
+                        //         $scope.users = [];
+                        //     }
+                        //     for (var i = 0; i < $scope.users.length; i++) {
+                        //         if ($scope.users[i].userUU == user.userUU) {
+                        //             $scope.users.splice(i, 1);
+                        //             i= i - 1;
+                        //             break; // 判定到已存在,就终止循环。
+                        //         }
+                        //     }
+                        //     if (user.checked) {
+                        //         $scope.users.push({
+                        //             userUU: user.userUU,
+                        //             name: user.name
+                        //         });
+                        //     }
+                        // });
+                        $scope.users = data;
+                        $rootScope.selectedUsers = $scope.users;
+                    }, function () {
 
-            // 删除选中
-            $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 receiver = [];
+                if ($scope.message.type == '角色类型') {
+                    angular.forEach($scope.types, function(temp) {
+                        if (temp.checked) {
+                            receiver.push(temp.type);
+                        }
+                    });
+                } else if ($scope.message.type == '机构对象') {
+                    angular.forEach($scope.orgs, function(org) {
+                        receiver.push(org.id);
+                    });
+                } else if ($scope.message.type == '指定用户') {
+                    angular.forEach($scope.users, function(user) {
+                        receiver.push(user.userUU);
+                    });
                 }
-                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) {
+                $scope.loading = true;
+                Message.publishMessage({message : $scope.message}, receiver, function(data) {
+                    if (data.success) {
                         toaster.pop('success', '发布成功');
-                    } else {
-                        toaster.pop('success', '保存成功');
+                        window.location.hash = '#/message/list';
+                    }
+                    if (data.error) {
+                        toaster.pop('error', data.error);
                     }
                     $scope.loading = false;
-                    window.location.hash = '#/activity';
-                }).error(function (data) {
-                    $scope.loadingShow = false;
+                }, function (res) {
+                    $scope.loading = false;
+                    console.log(res);
                     toaster.pop('error', '出现错误,操作失败');
                 });
                 // }
@@ -3585,42 +3597,236 @@ define([ 'angularAMD', 'ui.router', 'ui-bootstrap', 'ngLocal', 'ngTable', 'file-
     /**
      * 选择接收对象
      */
-    app.controller('RoleReceiverChooseCtrl', ['$scope', 'BaseService', 'toaster', 'Message', '$http', '$upload', '$rootScope', '$modal', 'ngTableParams',
-        function($scope, BaseService, toaster, Message, $http, $upload, $rootScope, $modal, ngTableParams) {
+    app.controller('RoleReceiverChooseCtrl', ['$scope', 'BaseService', 'toaster', 'Message', '$http', '$upload', '$rootScope', '$modalInstance', 'ngTableParams', 'Organization', 'User', 'message',
+        function($scope, BaseService, toaster, Message, $http, $upload, $rootScope, $modalInstance, ngTableParams, Organization, User, message) {
             $scope.loading = true;
-            $scope.active = 'personal';
-            $scope.orgs = [];
             $scope.checkedAll = false;
+            $scope.message = message;
+            $scope.tempOrgs = $rootScope.selectedOrgs ? angular.copy($rootScope.selectedOrgs) : [];
+            $scope.tempUsers = $rootScope.selectedUsers ? angular.copy($rootScope.selectedUsers) : [];
 
-            /**
-             * 修改用户类型
-             * @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.onSearch = function () {
+                $scope.tableParams.page(1);
+                $scope.tableParams.reload();
+            };
+
+            if ('机构对象' == message.type) {
+                $scope.tableParams = new ngTableParams({
+                    page: 1,
+                    count: 6,
+                    sorting: {
+                        'id': 'desc'
                     }
-                }
+                }, {
+                    total: 0,
+                    counts: [],
+                    getData: function ($defer, params) {
+                        $scope.loading = true;
+                        var pageParams = params.url();
+                        pageParams.keyword = $scope.keyword;
+                        Organization.getOrgOnMessage.call(null, BaseService.parseParams(pageParams), function (page) {
+                            if (page) {
+                                params.total(page.totalElements);
+                                $defer.resolve(page.content);
+                                // 选择接收对象时,将已存在的选中
+                                if ($scope.tempOrgs) {
+                                    var selected = 0;
+                                    angular.forEach(page.content, function (org) {
+                                        for (var i = 0; i < $scope.tempOrgs.length; i++) {
+                                            org.checked = false;
+                                            if (org.id == $scope.tempOrgs[i].id) {
+                                                org.checked = true;
+                                                selected = selected + 1;
+                                                break;
+                                            }
+                                        }
+                                    });
+                                    if (selected == page.size) {
+                                        $scope.checks.checked = true;
+                                    }
+                                }
+                            }
+                            $scope.loading = false;
+                        }, function (response) {
+                            $scope.loading = false;
+                            toaster.pop('error', '数据加载失败', response.data);
+                        });
+                    }
+                });
+            } else if ('指定用户' == message.type) {
+                $scope.tableParams = new ngTableParams({
+                    page: 1,
+                    count: 6,
+                    sorting: {
+                        'userUU': 'desc'
+                    }
+                }, {
+                    total: 0,
+                    counts: [],
+                    getData: function ($defer, params) {
+                        $scope.loading = true;
+                        var pageParams = params.url();
+                        pageParams.keyword = $scope.keyword;
+                        User.getAll.call(null, BaseService.parseParams(pageParams), function (page) {
+                            if (page) {
+                                params.total(page.totalElements);
+                                $defer.resolve(page.content);
+                                // 选择接收对象时,将已存在的选中
+                                if ($scope.tempUsers) {
+                                    var selected = 0;
+                                    angular.forEach(page.content, function (user) {
+                                        for (var i = 0; i < $scope.tempUsers.length; i++) {
+                                            user.checked = false;
+                                            if (user.userUU == $scope.tempUsers[i].userUU) {
+                                                user.checked = true;
+                                                selected = selected + 1;
+                                                break;
+                                            }
+                                        }
+                                    });
+                                    if (selected == page.size) {
+                                        $scope.checks.checked = true;
+                                    }
+                                }
+                            }
+                            $scope.loading = false;
+                        }, function (response) {
+                            $scope.loading = false;
+                            toaster.pop('error', '数据加载失败', response.data);
+                        });
+                    }
+                });
+            }
+
+
+
+            $scope.cancel = function () {
+                $scope.tempOrgs = $rootScope.selectedOrgs ? angular.copy($rootScope.selectedOrgs) : [];
+                $scope.tempUsers = $rootScope.selectedUsers ? angular.copy($rootScope.selectedUsers) : [];
+                $modalInstance.dismiss();
+            };
+
+            // 全选框
+            $scope.checks = {
+                checked: false
             };
 
             /**
              * 全选
              */
-            $scope.checkAll = function() {
-                $scope.checkedAll = !$scope.checkedAll;
-                angular.forEach($scope.orgs, function(org) {
-                    org.checked = $scope.checkedAll;
-                });
+            $scope.checkAll = function (type) {
+                $scope.checks.checked = true;
+                switch (type) {
+                    case 'org':
+                        angular.forEach($scope.tableParams.data, function (org) {
+                            if (!org.checked) {
+                                $scope.tempOrgs.push({
+                                    id: org.id,
+                                    name: org.name
+                                });
+                                org.checked = true;
+                            }
+                        });
+                        break;
+                    case 'user':
+                        angular.forEach($scope.tableParams.data, function (user) {
+                            if (!user.checked) {
+                                $scope.tempUsers.push({
+                                    userUU: user.userUU,
+                                    name: user.name
+                                });
+                                user.checked = true;
+                            }
+                        });
+                        break;
+                }
             };
 
             /**
-             * 根据数据类型获取用户列表
+             * 全反选
              */
-            $scope.loading = false;
+            $scope.unCheckAll = function (type) {
+                $scope.checks.checked = false;
+                angular.forEach($scope.tableParams.data, function (value) {
+                    value.checked = false;
+                    switch (type) {
+                        case 'org':
+                            for (var i = 0; i < $scope.tempOrgs.length; i++) {
+                                if (value.id == $scope.tempOrgs[i].id) {
+                                    $scope.tempOrgs.splice(i, 1);
+                                    i = i - 1;
+                                    break;
+                                }
+                            }
+                            break;
+                        case 'user':
+                            for (var i = 0; i < $scope.tempUsers.length; i++) {
+                                if (value.userUU == $scope.tempUsers[i].userUU) {
+                                    $scope.tempUsers.splice(i, 1);
+                                    i = i - 1;
+                                    break;
+                                }
+                            }
+                            break;
+                    }
+                });
+            };
+
+
+            // 单选
+            $scope.checkOne = function (value, type) {
+                var checked = true;
+                angular.forEach($scope.tableParams.data, function (org) { // 单选全部时,全选选中
+                    if (!org.checked) {
+                        checked = false;
+                    }
+                });
+                $scope.checks.checked = checked;
+                switch (type) {
+                    case 'org':
+                        if (value.checked) {
+                            $scope.tempOrgs.push({
+                                id: value.id,
+                                name: value.name
+                            });
+                        } else {
+                            for (var i = 0; i< $scope.tempOrgs.length; i++) {
+                                if (value.id == $scope.tempOrgs[i].id) {
+                                    $scope.tempOrgs.splice(i, 1);
+                                    i = i - 1;
+                                }
+                            }
+                        }
+                        break;
+                    case 'user':
+                        if (value.checked) {
+                            $scope.tempUsers.push({
+                                userUU: value.userUU,
+                                name: value.name
+                            });
+                        } else {
+                            for (var i = 0; i< $scope.tempUsers.length; i++) {
+                                if (value.userUU == $scope.tempUsers[i].userUU) {
+                                    $scope.tempUsers.splice(i, 1);
+                                    i = i - 1;
+                                }
+                            }
+                        }
+                        break;
+                }
+            };
+
+            $scope.ensure = function (type) {
+                switch (type) {
+                    case 'org':
+                        $modalInstance.close($scope.tempOrgs);
+                        break;
+                    case 'user':
+                        $modalInstance.close($scope.tempUsers);
+                        break;
+                }
+            };
         }]);
 
     /**

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

@@ -13,6 +13,11 @@ define ([ 'ngResource' ], function() {
                 params: {
                     id: 'id'
                 }
+            },
+            // 发布消息
+            publishMessage: {
+                url: 'message/publish',
+                method: 'POST'
             }
         });
     }]);

+ 5 - 0
donate-console/src/main/webapp/resources/js/index/services/Organization.js

@@ -54,6 +54,11 @@ define ([ 'ngResource' ], function() {
                 params : {
                     id: 'id'
                 }
+            },
+            // 在编辑消息时,获取机构列表
+            getOrgOnMessage: {
+                url: 'org/getOrgOnMessage',
+                method: 'GET'
             }
         });
     }]);

+ 5 - 0
donate-console/src/main/webapp/resources/js/index/services/User.js

@@ -41,6 +41,11 @@ define ([ 'ngResource' ], function() {
             getJoinedActivityRecords : {
                 url: 'user/getJoinedActivityRecords',
                 method: 'GET'
+            },
+            // 获取所有角色类型
+            getAllTypes: {
+                url: 'user/getAllTypes',
+                method: 'GET'
             }
         });
     }]);

+ 69 - 20
donate-console/src/main/webapp/resources/view/message/message_edit.html

@@ -17,7 +17,7 @@
         background: #ffffff;
         margin-bottom: 20px;
         width: 100%;
-        height: 620px;
+        height: 700px;
         border: 1px solid #dcdcdc;
         box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
     }
@@ -37,7 +37,7 @@
         font-weight: normal;
         color: #8da8b8;
     }
-    .content-setting .form-group input{
+    .content-setting .form-group input[type=text]{
         margin-right: 15px;
         width: 780px;
         height: 30px;
@@ -45,6 +45,11 @@
         color: #323232;
         border-radius: 0;
     }
+    .content-setting .form-group input[type=checkbox]{
+        margin:0 5px 0 15px;
+        font-size: 14px;
+        color: #323232;
+    }
     .content-setting .edit {
         position: relative;
         width: 780px;
@@ -113,8 +118,6 @@
     .introduce textarea{
         width: 780px;
         height: 325px;
-        border: 1px solid #ccc;
-        border-top: none;
         border-radius: 0;
     }
     .introduce .button{
@@ -145,7 +148,7 @@
         width: 100%;
         height: 100%;
     }
-    .modal-open .modal .modal-dialog{
+    .modal-open .modal .modal-dialog.timing{
         width: 450px;
         height: 180px;
     }
@@ -224,6 +227,20 @@
     div.fl.introduce input{
        width: 80%;
     }
+
+    /* 已选择展示样式 */
+    span.selected-item {
+        display: inline-block;
+        margin-right: 18px;
+        margin-bottom: 5px;
+        padding: 0 14px;
+        height: 30px;
+        line-height: 30px;
+        font-size: 14px;
+        color: #323232;
+        background: #ebf1f4;
+        border-radius: 3px;
+    }
 </style>
 <div class="wrapper">
     <!--主体内容-->
@@ -239,9 +256,11 @@
                         <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 class="form-control input-sm jp-width120" ng-model="message.type">
+                                    <option value="角色类型">角色类型</option>
+                                    <option value="机构对象">机构对象</option>
+                                    <option value="指定用户">指定用户</option>
+                                    <option value="所有用户">所有用户</option>
                                 </select>
                             </div>
                             <!--<div class="edit fl">-->
@@ -249,22 +268,51 @@
                                 <!--<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">
+                        <!-- 按角色类型时 -->
+                        <div ng-if="message.type == '角色类型'" class="form-group clearfix">
+                            <label class="control-label fl">请选择</label>
+                            <span ng-repeat="temp in types track by $index">
+                                <input type="checkbox" ng-checked="temp.checked" ng-click="checkType(temp)"><span ng-bind="temp.type"></span>
+                            </span>
+                            <span class="error" ng-show="submited && noChoose">*请选择发送对象</span>
+                        </div>
+                        <!-- 非所有用户及按类型时 -->
+                        <div ng-if="message.type != '角色类型' && message.type != '所有用户'" 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>
+                            <span style="cursor: pointer; color: #5078cb;" ng-click="selectReceiver(message.type)"><i class="fa fa-plus-square"></i>选择接收对象</span>
+                        </div>
+                        <!-- 机构对象已选择 -->
+                        <div ng-if="message.type == '机构对象' && orgs.length > 0" class="form-group clearfix" style="height:auto!important;">
+                            <label class="control-label fl">已选择</label>
+                            <span ng-repeat="org in orgs | limitTo: 20" class="selected-item">
+                                <span ng-bind="org.name"></span>
+                            </span>
+                            <span ng-if="orgs.length > 20">...</span>
+                        </div>
+                        <!-- 指定用户已选择 -->
+                        <div ng-if="message.type == '指定用户' && users.length > 0" class="form-group clearfix" style="height:auto!important;">
+                            <label class="control-label fl">已选择</label>
+                            <span ng-repeat="user in users | limitTo: 20" class="selected-item">
+                                <span ng-bind="user.name"></span>
+                            </span>
+                            <span ng-if="orgs.length > 20">...</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/>
+                            <input type="text" ng-model="message.title" maxlength="100" class="form-control fl" placeholder="请填写消息主题" required
+                                   ng-class="{'showEmpty' : submited && !message.title}"/>
+                            <span class="error" ng-show="submited && !message.title">*请填写消息主题</span>
                         </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>
+                                    <!--<summernote lang="zh-CN" ng-model="message.context" height="300px" maxlength="3500" config="editorConfig">-->
+                                    <!--</summernote>-->
+                                    <textarea ng-model="message.context" style="width: 100%;" title="消息内容" class="form-control f1" placeholder="请填写消息内容,最大长度为500"
+                                              maxlength="500" ng-class="{'showEmpty' : submited && !message.context}"></textarea>
+                                    <span class="error" ng-show="submited && !message.context">*请填写消息内容</span>
                                 </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>
@@ -275,27 +323,28 @@
     </div>
 </div>
 <!--定时发送弹出框-->
-<div class="modal setting" role="dialog" id="setting">
-    <div class="modal-dialog">
+<div class="modal setting" role="dialog" id="setting" data-backdrop="static" data-keyboard="false">
+    <div class="modal-dialog timing">
         <div class="modal-content">
             <div class="modal-header header">
                 <p class="fl">设置发送时间</p>
-                <div class="close fr" data-dismiss="modal">&times;</div>
+                <div class="close fr" data-dismiss="modal" ng-click="clearPublishDate()">&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"
+                           datepicker-popup="yyyy-MM-dd" 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-click="openDatePicker($event, message, '$publishTimeOpened')"
                            ng-class="{'showEmpty' : submited && !message.publishDate}">
+                    <span class="error" ng-show="submited && !message.publishDate">*请选择发布时间</span>
                 </div>
             </div>
             <div class="modal-footer footer text-right">
-                <a ng-click="publishMessage(messageForm.$invalid)">确认</a><a data-dismiss="modal">取消</a>
+                <a ng-click="publishMessage(messageForm.$invalid && !message.publishDate)">确认</a><a data-dismiss="modal" ng-click="clearPublishDate()">取消</a>
             </div>
         </div>
     </div>

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

@@ -351,11 +351,11 @@
                             <tr>
                                 <td width="45"></td>
                                 <td width="300">消息主题</td>
-                                <td width="100">发布时间</td>
+                                <td width="150">发布时间</td>
                                 <td width="160">接收对象</td>
                                 <td width="90">阅读情况</td>
                                 <td width="90">发送人</td>
-                                <td width="400"></td>
+                                <td width="200"></td>
                             </tr>
                             </thead>
                             <tbody ng-if="messageParams.total() == 0">

+ 108 - 0
donate-console/src/main/webapp/resources/view/message/select_receiver_org.html

@@ -0,0 +1,108 @@
+<style>
+    .btn {
+        border-radius: 0;
+    }
+
+    .modal-content {
+        border-radius: 0;
+        min-height: 600px;
+        min-width: 900px;
+    }
+    .modal-body {
+        min-height: 500px;
+    }
+
+    .content-title {
+        position: absolute;
+        left: 25px;
+        line-height: 24px;
+        padding: 0 15px 0 10px;
+        background: #fff;
+        z-index: 2;
+    }
+
+    #window-search .input-group-addon {
+        width: 70px;
+        height: 30px;
+        line-height: 30px;
+        display: inline-block;
+        background: #327ebe;
+        font-size: 16px;
+        text-align: center;
+        color: #fff!important;
+        padding: 0;
+        border: 0;
+        border-radius: 0;
+        position: absolute;
+        top: 0;
+        right: 15px;
+    }
+
+</style>
+<div class="modal-body">
+    <div class="headerline">
+        <span class="content-title"><i class="fa fa-fw fa-edit text-primary"></i>选择接收机构</span>
+    </div>
+    <form class="form-horizontal">
+        <div class="form-group" id="window-search">
+            <div class="col-md-3 col-sm-3"></div>
+            <div class="col-md-8 col-sm-8">
+                <input type="text" class="form-control input-sm"
+                       required placeholder="输入关键字查询" autofocus ng-model="keyword" ng-search="onSearch()"/>
+                <a class="btn input-group-addon" ng-click="onSearch()">搜索</a>
+            </div>
+        </div>
+    </form>
+    <!-- 机构对象 机构 -->
+    <table class="block table table-default table-striped table-bordered"
+           ng-table="tableParams">
+        <thead>
+        <tr class="header">
+            <th width="60" class="text-center">序号</th>
+            <th width="300" class="text-center">机构名称</th>
+            <th width="120" class="text-center">机构类别</th>
+            <th width="120" class="text-center">主要领域</th>
+            <th width="120" class="text-center">全职人数</th>
+            <th width="120" class="text-center">负责人</th>
+            <th width="180" class="text-center">办公电话</th>
+            <th width="90" class="text-center">
+                <a ng-show="!checks.checked" ng-click="checkAll('org')">全选</a>
+                <a ng-show="checks.checked" ng-click="unCheckAll('org')">全反选</a>
+            </th>
+        </tr>
+        </thead>
+        <tbody ng-if="tableParams.total() == 0">
+        <tr>
+            <td colspan="6">
+                <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>
+        <tr ng-repeat="org in $data">
+            <td class="text-center">{{$index + 1}}</td>
+            <td class="text-center" ng-bind="org.name"></td>
+            <td class="text-center" ng-bind="org.type == 1 ? '公募' : '非公募'"></td>
+            <td class="text-center" ng-bind="org.majorArea"></td>
+            <td class="text-center" ng-bind="org.fullTimePopulation"></td>
+            <td class="text-center" ng-bind="org.managerName"></td>
+            <td class="text-center" ng-bind="org.managerOph"></td>
+            <td class="text-center">
+                <input ng-model="org.checked" name="checkbox" ng-click="checkOne(org, 'org')" type="checkbox">
+            </td>
+        </tr>
+        </tbody>
+    </table>
+
+</div>
+<div class="modal-footer">
+    <button class="btn btn-info" style="border-radius: 0;" ng-click="ensure('org')" type="button">确认</button>
+    <button class="btn btn-default" style="border-radius: 0;" ng-click="cancel()" type="button">取消</button>
+</div>

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

@@ -1,174 +0,0 @@
-<!-- 按角色类型指定接收消息用户 -->
-<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>

+ 103 - 0
donate-console/src/main/webapp/resources/view/message/select_receiver_user.html

@@ -0,0 +1,103 @@
+<style>
+    .btn {
+        border-radius: 0;
+    }
+
+    .modal-content {
+        border-radius: 0;
+        min-height: 600px;
+        min-width: 900px;
+    }
+
+    .content-title {
+        position: absolute;
+        left: 25px;
+        line-height: 24px;
+        padding: 0 15px 0 10px;
+        background: #fff;
+        z-index: 2;
+    }
+
+    #window-search .input-group-addon {
+        width: 70px;
+        height: 30px;
+        line-height: 30px;
+        display: inline-block;
+        background: #327ebe;
+        font-size: 16px;
+        text-align: center;
+        color: #fff!important;
+        padding: 0;
+        border: 0;
+        border-radius: 0;
+        position: absolute;
+        top: 0;
+        right: 15px;
+    }
+
+</style>
+<div class="modal-body">
+    <div class="headerline">
+        <span class="content-title"><i class="fa fa-fw fa-edit text-primary"></i>选择指定用户</span>
+    </div>
+    <form class="form-horizontal">
+        <div class="form-group" id="window-search">
+            <div class="col-md-3 col-sm-3"></div>
+            <div class="col-md-8 col-sm-8">
+                <input type="text" class="form-control input-sm"
+                       required placeholder="输入关键字查询" autofocus ng-model="keyword" ng-search="onSearch()"/>
+                <a class="btn input-group-addon" ng-click="onSearch()">搜索</a>
+            </div>
+        </div>
+    </form>
+    <!-- 机构对象 机构 -->
+    <table class="block table table-default table-striped table-bordered"
+           ng-table="tableParams">
+        <thead>
+        <tr class="header">
+            <th width="120" class="text-center">用户UU</th>
+            <th width="120" class="text-center">用户名</th>
+            <th width="120" class="text-center">手机号</th>
+            <th width="180" class="text-center">邮箱</th>
+            <th width="180" class="text-center">所属机构</th>
+            <th width="90" class="text-center">用户类型</th>
+            <th width="90" class="text-center">
+                <a ng-show="!checks.checked" ng-click="checkAll('user')">全选</a>
+                <a ng-show="checks.checked" ng-click="unCheckAll('user')">全反选</a>
+            </th>
+        </tr>
+        </thead>
+        <tbody ng-if="tableParams.total() == 0">
+        <tr>
+            <td colspan="6">
+                <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>
+        <tr ng-repeat="user in $data">
+            <td class="text-center" ng-bind="user.userUU"></td>
+            <td class="text-center" ng-bind="user.name"></td>
+            <td class="text-center" ng-bind="user.tel"></td>
+            <td class="text-center" ng-bind="user.email"></td>
+            <td class="text-center" ng-bind="user.org.name || '无'"></td>
+            <td class="text-center" ng-bind="user.type ||'无'"></td>
+            <td class="text-center">
+                <input ng-model="user.checked" name="checkbox" ng-click="checkOne(user, 'user')" type="checkbox">
+            </td>
+        </tr>
+        </tbody>
+    </table>
+
+</div>
+<div class="modal-footer">
+    <button class="btn btn-info" style="border-radius: 0;" ng-click="ensure('user')" type="button">确认</button>
+    <button class="btn btn-default" style="border-radius: 0;" ng-click="cancel()" type="button">取消</button>
+</div>

+ 5 - 5
donate-console/src/main/webapp/resources/view/project/project_detail.html

@@ -337,23 +337,23 @@
             <div class="list-body clearfix">
                 <div class="msg-list fl">
                     <span class="fl">项目总募款</span>
-                    <span class="fl info mCount" ng-bind="project.totalAmount"></span>
+                    <span class="fl info mCount" ng-bind="project.totalAmount || 0 | number:2"></span>
                 </div>
                 <div class="msg-list fl">
                     <span class="fl">善款总支出</span>
-                    <span class="fl">{{totalCost | number:2}}元</span>
+                    <span class="fl">{{totalCost || 0 | number:2}}元</span>
                 </div>
                 <div class="msg-list fl">
                     <span class="fl">执行进度</span>
-                    <span class="fl">{{totalCost / totalAmount * 100 | number:2}}%</span>
+                    <span class="fl">{{totalCost / totalAmount * 100 || 0 | number:2}}%</span>
                 </div>
                 <div class="msg-list fl">
                     <span class="fl">执行成本</span>
-                    <span class="fl">{{executeCost | number:2}}({{executeCost/totalCost * 100 | number:2}}%)</span>
+                    <span class="fl">{{executeCost || 0 | number:2}}({{executeCost/totalCost * 100 || 0 | number:2}}%)</span>
                 </div>
                 <div class="msg-list fl">
                     <span class="fl">项目支出</span>
-                    <span class="fl">{{projectCost | number:2}}({{projectCost/totalCost * 100 | number:2}}%)</span>
+                    <span class="fl">{{projectCost || 0 | number:2}}({{projectCost/totalCost * 100 || 0 | number:2}}%)</span>
                 </div>
             </div>
         </div>

+ 1 - 1
donate-service/src/main/java/com/uas/service/donate/event/ActivityJoinedPublishEvent.java

@@ -36,7 +36,7 @@ public class ActivityJoinedPublishEvent extends PublishEvent<MessageDetail, Acti
         // 发起人UU
         Long userUU = activity.getUserUU();
         // 类型
-        String type = "活动消息";
+        String type = "指定用户";
         // 来源表
         String table = "donate$activityrecode";
         // 来源id

+ 1 - 1
donate-service/src/main/java/com/uas/service/donate/event/ProjectJoinedPublishEvent.java

@@ -33,7 +33,7 @@ public class ProjectJoinedPublishEvent extends PublishEvent<MessageDetail, Proje
         // 发起人UU
         Long userUU = project.getUserUU();
         // 类型
-        String type = "项目消息";
+        String type = "指定用户";
         // 来源表
         String table = "donate$projectrecode";
         // 来源id

+ 1 - 1
donate-service/src/main/java/com/uas/service/donate/event/TakePrizePublishEvent.java

@@ -36,7 +36,7 @@ public class TakePrizePublishEvent extends PublishEvent<MessageDetail, ActivityR
         // 发起人UU
         Long userUU = activity.getUserUU();
         // 类型
-        String type = "活动消息";
+        String type = "指定用户";
         // 来源表
         String table = "donate$activityrecode";
         // 来源id

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

@@ -181,7 +181,7 @@ public class PublishListener implements ApplicationListener<PublishEvent<?, ?>>
 		Set<Long> userUUs = new HashSet<>();
 		// 设置接收人数
 		message.setReceiverNum(receiverUsers.size());
-		// 为用户新增消息(这里是所有时,效率非常低,之后需要优化)
+		// 为用户新增消息(这里是所有用户时,效率非常低,之后需要优化)
 		for (User user : receiverUsers) {
 			try { //去除userUU为空值的情况
 				if (null != user.getUserUU() && !userUUs.contains(user.getUserUU())) {

+ 3 - 1
donate-service/src/main/java/com/uas/service/donate/model/Message.java

@@ -2,6 +2,7 @@ package com.uas.service.donate.model;
 
 import com.alibaba.fastjson.annotation.JSONField;
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.hibernate.validator.constraints.Length;
 
 import javax.persistence.*;
 import java.io.Serializable;
@@ -64,10 +65,11 @@ public class Message implements Serializable {
      * 消息正文
      */
     @Column(name = "dm_context")
+    @Length(max = 600)
     private String context;
 
     /**
-     * 消息类型
+     * 消息类型(角色类型、机构对象、指定用户、所有用户)
      */
     @Column(name = "dm_type")
     private String type;

+ 4 - 3
donate-service/src/main/java/com/uas/service/donate/model/Org.java

@@ -17,8 +17,9 @@ public class Org implements Serializable{
     private static final long serialVersionUID = 1L;
     private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 
-
-
+    /**
+     * id
+     */
     @Id
     @GeneratedValue(strategy= GenerationType.IDENTITY)
     @Column(name = "org_id")
@@ -32,7 +33,7 @@ public class Org implements Serializable{
 
 
     /**
-     *优软云账号
+     * 注册人UU
      */
     @Column(name="org_uuid")
     private Long uuid;

+ 10 - 8
donate-service/src/main/java/com/uas/service/donate/model/User.java

@@ -34,7 +34,7 @@ public class User implements Serializable{
     private String tel;
 
     @Column(name = "user_email")
-    private String userEmail;
+    private String email;
 
     @Column(name = "user_identity")
     private Integer identity;
@@ -54,7 +54,7 @@ public class User implements Serializable{
     private Long userIMId;
 
     /**
-     *用户所属类型
+     *用户所属类型 (个人用户、管理员、机构用户、机构操作员)
      */
     @Column(name = "user_type")
     private String type;
@@ -82,17 +82,19 @@ public class User implements Serializable{
     }
 
     public User(UserView user) {
+        this.setType("个人用户");
         this.setUserUU(Long.valueOf(user.getDialectUID()));
         this.setName(user.getName());
         this.setTel(user.getUid());
-        this.setUserEmail(user.getSecondUID());
+        this.setEmail(user.getSecondUID());
     }
 
     public User(com.uas.account.entity.User accountUser) {
+        this.setType("个人用户");
         this.setUserUU(Long.valueOf(accountUser.getDialectUID()));
         this.setName(accountUser.getName());
         this.setTel(accountUser.getUid());
-        this.setUserEmail(accountUser.getSecondUID());
+        this.setEmail(accountUser.getSecondUID());
     }
 
     public Long getUserUU() {
@@ -119,12 +121,12 @@ public class User implements Serializable{
         this.tel = tel;
     }
 
-    public String getUserEmail() {
-        return userEmail;
+    public String getEmail() {
+        return email;
     }
 
-    public void setUserEmail(String userEmail) {
-        this.userEmail = userEmail;
+    public void setEmail(String email) {
+        this.email = email;
     }
 
     public Integer getIdentity() {

+ 5 - 1
donate-service/src/main/java/com/uas/service/donate/service/impl/UserServiceImpl.java

@@ -18,6 +18,7 @@ import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
+import java.util.Date;
 
 @Service
 public class UserServiceImpl implements UserService {
@@ -157,7 +158,9 @@ public class UserServiceImpl implements UserService {
                 @Override
                 public Predicate toPredicate(Root<MessageDetail> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                     pageInfo.expression(PredicateUtils.or(PredicateUtils.eq("receiveUserUU", userUU, false),
-                            PredicateUtils.eq("message.receiver", "所有人", false)));
+                            PredicateUtils.eq("message.receiver", "所有用户", false)));
+                    // 发布时间比当前时间早的
+                    pageInfo.expression(PredicateUtils.gte("publishDate", new Date().getTime(), false));
                     query.where(pageInfo.getPredicates(root, query, cb));
                     return null;
                 }
@@ -195,6 +198,7 @@ public class UserServiceImpl implements UserService {
             return map;
         }
         detail.setReadStatus(Constant.YES);
+        detail.setReadDate(new Date());
         messageDetailDao.save(detail);
         // 修改阅读人数
         Message message = detail.getMessage();