Browse Source

【UAS招标】招标答疑功能;招标相关接口。

dongbw 9 years ago
parent
commit
86cbb66908
38 changed files with 4186 additions and 194 deletions
  1. 6 7
      src/main/java/com/uas/platform/b2b/controller/PurchaseTenderController.java
  2. 272 0
      src/main/java/com/uas/platform/b2b/controller/SaleTenderQuestionController.java
  3. 26 36
      src/main/java/com/uas/platform/b2b/controller/SnapshotController.java
  4. 15 0
      src/main/java/com/uas/platform/b2b/dao/PurchaseTenderAnswerDao.java
  5. 27 0
      src/main/java/com/uas/platform/b2b/dao/PurchaseTenderQuestionDao.java
  6. 17 0
      src/main/java/com/uas/platform/b2b/dao/SaleTenderAnswerDao.java
  7. 31 0
      src/main/java/com/uas/platform/b2b/dao/SaleTenderQuestionDao.java
  8. 114 3
      src/main/java/com/uas/platform/b2b/erp/controller/TenderController.java
  9. 14 4
      src/main/java/com/uas/platform/b2b/erp/controller/UserSpaceDetailController.java
  10. 18 5
      src/main/java/com/uas/platform/b2b/erp/model/PurchaseTenderErp.java
  11. 44 0
      src/main/java/com/uas/platform/b2b/erp/model/SaleTenderErp.java
  12. 9 1
      src/main/java/com/uas/platform/b2b/erp/service/TenderService.java
  13. 65 8
      src/main/java/com/uas/platform/b2b/erp/service/impl/TenderServiceImpl.java
  14. 41 0
      src/main/java/com/uas/platform/b2b/model/PurchaseTender.java
  15. 258 0
      src/main/java/com/uas/platform/b2b/model/PurchaseTenderAnswer.java
  16. 198 0
      src/main/java/com/uas/platform/b2b/model/PurchaseTenderQuestion.java
  17. 35 3
      src/main/java/com/uas/platform/b2b/model/SaleTender.java
  18. 268 0
      src/main/java/com/uas/platform/b2b/model/SaleTenderAnswer.java
  19. 202 0
      src/main/java/com/uas/platform/b2b/model/SaleTenderQuestion.java
  20. 12 45
      src/main/java/com/uas/platform/b2b/search/SearchService.java
  21. 26 69
      src/main/java/com/uas/platform/b2b/search/SearchServiceImpl.java
  22. 9 4
      src/main/java/com/uas/platform/b2b/service/PurchaseTenderService.java
  23. 3 0
      src/main/java/com/uas/platform/b2b/service/VendorService.java
  24. 85 0
      src/main/java/com/uas/platform/b2b/service/impl/PurchaseTenderServiceImpl.java
  25. 23 0
      src/main/java/com/uas/platform/b2b/service/impl/VendorsServiceImpl.java
  26. 556 1
      src/main/webapp/resources/js/index/app.js
  27. 44 0
      src/main/webapp/resources/js/index/services/Purc.js
  28. 0 6
      src/main/webapp/resources/tpl/index/home/pagingRelease.html
  29. 82 0
      src/main/webapp/resources/tpl/index/purc/tender_answer.html
  30. 295 0
      src/main/webapp/resources/tpl/index/purc/tender_answer_detail.html
  31. 399 0
      src/main/webapp/resources/tpl/index/purc/tender_answer_list.html
  32. 3 0
      src/main/webapp/resources/tpl/index/purc/tenderlist.html
  33. 9 2
      src/main/webapp/resources/tpl/index/sale/tender.html
  34. 101 0
      src/main/webapp/resources/tpl/index/sale/tender_question.html
  35. 308 0
      src/main/webapp/resources/tpl/index/sale/tender_question_detail.html
  36. 170 0
      src/main/webapp/resources/tpl/index/sale/tender_question_history.html
  37. 400 0
      src/main/webapp/resources/tpl/index/sale/tender_question_list.html
  38. 1 0
      src/main/webapp/resources/tpl/index/sale/tenderlist.html

+ 6 - 7
src/main/java/com/uas/platform/b2b/controller/PurchaseTenderController.java

@@ -3,11 +3,9 @@ package com.uas.platform.b2b.controller;
 import com.alibaba.dubbo.common.utils.CollectionUtils;
 import com.alibaba.fastjson.JSONObject;
 import com.uas.platform.b2b.erp.model.SaleTenderErp;
-import com.uas.platform.b2b.model.Attach;
-import com.uas.platform.b2b.model.FileUpload;
-import com.uas.platform.b2b.model.PurchaseTender;
-import com.uas.platform.b2b.model.SearchFilter;
+import com.uas.platform.b2b.model.*;
 import com.uas.platform.b2b.search.SearchService;
+import com.uas.platform.b2b.service.AttachService;
 import com.uas.platform.b2b.service.PurchaseTenderService;
 import com.uas.platform.b2b.service.UserService;
 import com.uas.platform.b2b.support.JxlsExcelView;
@@ -40,9 +38,7 @@ import org.springframework.web.servlet.ModelAndView;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
 
 /**
  * 招标单
@@ -60,6 +56,9 @@ public class PurchaseTenderController {
     @Autowired
     private SearchService searchService;
 
+    @Autowired
+    private AttachService attachService;
+
     @Autowired
     private UserService userService;
 

+ 272 - 0
src/main/java/com/uas/platform/b2b/controller/SaleTenderQuestionController.java

@@ -0,0 +1,272 @@
+package com.uas.platform.b2b.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.uas.platform.b2b.model.FileUpload;
+import com.uas.platform.b2b.model.PurchaseTenderAnswer;
+import com.uas.platform.b2b.model.SaleTenderQuestion;
+import com.uas.platform.b2b.model.SearchFilter;
+import com.uas.platform.b2b.search.SearchService;
+import com.uas.platform.b2b.service.AttachService;
+import com.uas.platform.b2b.service.PurchaseTenderService;
+import com.uas.platform.b2b.service.UserService;
+import com.uas.platform.b2b.support.SystemSession;
+import com.uas.platform.b2b.support.UsageBufferedLogger;
+import com.uas.platform.core.logging.BufferedLoggerManager;
+import com.uas.platform.core.model.PageParams;
+import com.uas.platform.core.model.Status;
+import com.uas.platform.core.util.serializer.FlexJsonUtils;
+import com.uas.platform.core.web.bind.RequestState;
+import com.uas.search.b2b.model.SPage;
+import com.uas.search.b2b.model.Sort;
+import com.uas.search.b2b.util.SearchConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 投标提问单
+ * Created by dongbw
+ * 17/09/13 10:22.
+ */
+@RestController
+@RequestMapping("/tender/question")
+public class SaleTenderQuestionController {
+
+    @Autowired
+    private PurchaseTenderService purchaseTenderService;
+
+    @Autowired
+    private SearchService searchService;
+
+    @Autowired
+    private AttachService attachService;
+
+    @Autowired
+    private UserService userService;
+
+    private final static UsageBufferedLogger logger = BufferedLoggerManager.getLogger(UsageBufferedLogger.class);
+
+    /**
+     * 作为投标方,在投标时进行咨询
+     *
+     * @param id
+     * @return
+     */
+    @RequestMapping(value = "/send/{id}", method = RequestMethod.POST)
+    @ResponseBody
+    public ResponseEntity<String> sendQuestion(String json, @PathVariable("id") Long id, FileUpload uploadItem) {
+        SaleTenderQuestion question = FlexJsonUtils.fromJson(json, SaleTenderQuestion.class);
+        SaleTenderQuestion saleTenderQuestion = purchaseTenderService.sendQuestion(question, id, uploadItem);
+        logger.log("客户投标提问", "对招标单招标方提问", "招标单号:" +
+                saleTenderQuestion.getSaleTenderAnswer().getTenderCode() + ",提问单号:" + saleTenderQuestion.getCode());
+        return new ResponseEntity<String>(HttpStatus.OK);
+    }
+
+    /**
+     * 作为招标方,回答疑问
+     *
+     * @return
+     */
+    @RequestMapping(value = "/answer/send", method = RequestMethod.POST)
+    @ResponseBody
+    public ResponseEntity<String> sendAnswer(String json, FileUpload uploadItem) {
+        PurchaseTenderAnswer answer = FlexJsonUtils.fromJson(json, PurchaseTenderAnswer.class);
+        PurchaseTenderAnswer purchaseTenderAnswer = purchaseTenderService.sendAnswer(answer, uploadItem);
+        logger.log("招标答疑", "对招标单投标方答疑", "招标单号:" +
+                purchaseTenderAnswer.getTenderCode() + ",答疑单号:" + purchaseTenderAnswer.getCode());
+        return new ResponseEntity<String>(HttpStatus.OK);
+    }
+
+
+    /**
+     * 查看投标提问单详情
+     *
+     * @param id   提问单id
+     * @return
+     */
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    @ResponseBody
+    public SaleTenderQuestion getQuestionDetail(@PathVariable("id") Long id) {
+        return purchaseTenderService.getQuestionDetail(id);
+    }
+
+    /**
+     * 查看招标答疑单详情
+     *
+     * @param id  答疑单id
+     * @return
+     */
+    @RequestMapping(value = "/answer/{id}", method = RequestMethod.GET)
+    @ResponseBody
+    public PurchaseTenderAnswer getAnswerDetail(@PathVariable("id") Long id) {
+        return purchaseTenderService.getAnswerDetail(id);
+    }
+
+    /**
+     * 作为投标方,查看自己发出的提问单(全部)
+     *
+     * @param params 分页参数
+     * @return Spage
+     */
+    @RequestMapping(method = RequestMethod.GET)
+    @ResponseBody
+    public SPage<SaleTenderQuestion> getAllTenderQuestions(PageParams params, String searchFilter) {
+        if (logger != null) {
+            logger.log("招标提问单", "查看发出的招标提问(全部)");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(searchFilter);
+        String keyword = jsonObject.getString("keyword");
+        com.uas.search.b2b.model.PageParams pageParams = searchService.convertPageParams(params, searchFilter);
+        // 判断当前用户是否被客户分配
+        SearchFilter filter = userService.distribute();
+        if (filter != null && filter.getDistribute() == null) {
+            return null;
+        }
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("stq_id", false, Sort.Type.LONG, 1L));
+        pageParams.getFilters().put(SearchConstants.SORT_KEY, sortList);
+        pageParams.getFilters().put("stq_venduu", SystemSession.getUser().getEnterprise().getUu());
+        return searchService.searchSaleTenderQuestion(keyword, pageParams);
+    }
+
+    /**
+     * 作为投标方,查看自己发出的提问单(已回复)
+     *
+     * @param params 分页参数
+     * @return Spage
+     */
+    @RequestMapping(params = RequestState.DONE, method = RequestMethod.GET)
+    @ResponseBody
+    public SPage<SaleTenderQuestion> getDoneTenderQuestions(PageParams params, String searchFilter) {
+        if (logger != null) {
+            logger.log("招标提问单", "查看发出的招标提问(已回复)");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(searchFilter);
+        String keyword = jsonObject.getString("keyword");
+        com.uas.search.b2b.model.PageParams pageParams = searchService.convertPageParams(params, searchFilter);
+        // 判断当前用户是否被客户分配
+        SearchFilter filter = userService.distribute();
+        if (filter != null && filter.getDistribute() == null) {
+            return null;
+        }
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("stq_id", false, Sort.Type.LONG, 1L));
+        pageParams.getFilters().put(SearchConstants.SORT_KEY, sortList);
+        pageParams.getFilters().put("stq_venduu", SystemSession.getUser().getEnterprise().getUu());
+        pageParams.getFilters().put("stq_status", Status.REPLIED.value());
+        return searchService.searchSaleTenderQuestion(keyword, pageParams);
+    }
+
+    /**
+     * 作为投标方,查看自己发出的提问单(未回复)
+     *
+     * @param params 分页参数
+     * @return Spage
+     */
+    @RequestMapping(params = RequestState.TODO, method = RequestMethod.GET)
+    @ResponseBody
+    public SPage<SaleTenderQuestion> getTodoTenderQuestions(PageParams params, String searchFilter) {
+        if (logger != null) {
+            logger.log("招标提问单", "查看发出的招标提问(未回复)");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(searchFilter);
+        String keyword = jsonObject.getString("keyword");
+        com.uas.search.b2b.model.PageParams pageParams = searchService.convertPageParams(params, searchFilter);
+        // 判断当前用户是否被客户分配
+        SearchFilter filter = userService.distribute();
+        if (filter != null && filter.getDistribute() == null) {
+            return null;
+        }
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("stq_id", false, Sort.Type.LONG, 1L));
+        pageParams.getFilters().put(SearchConstants.SORT_KEY, sortList);
+        pageParams.getFilters().put("stq_venduu", SystemSession.getUser().getEnterprise().getUu());
+        pageParams.getFilters().put("stq_status", Status.NOT_REPLY.value());
+        return searchService.searchSaleTenderQuestion(keyword, pageParams);
+    }
+
+    /**
+     * 作为招标方,查看自己收到的提问单(全部)
+     *
+     * @param params 分页参数
+     * @return Spage
+     */
+    @RequestMapping(value="/purc", method = RequestMethod.GET)
+    @ResponseBody
+    public SPage<SaleTenderQuestion> getAllTenderAnswers(PageParams params, String searchFilter) {
+        if (logger != null) {
+            logger.log("招标提问单", "查看收到的招标提问(全部)");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(searchFilter);
+        String keyword = jsonObject.getString("keyword");
+        com.uas.search.b2b.model.PageParams pageParams = searchService.convertPageParams(params, searchFilter);
+        // 判断当前用户是否被客户分配
+        SearchFilter filter = userService.distribute();
+        if (filter != null && filter.getDistribute() == null) {
+            return null;
+        }
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("stq_id", false, Sort.Type.LONG, 1L));
+        pageParams.getFilters().put(SearchConstants.SORT_KEY, sortList);
+        pageParams.getFilters().put("stq_ptaid", SystemSession.getUser().getEnterprise().getUu());
+        return searchService.searchSaleTenderQuestion(keyword, pageParams);
+    }
+
+    /**
+     * 作为招标方,查看自己收到的提问单(已回复)
+     *
+     * @param params 分页参数
+     * @return Spage
+     */
+    @RequestMapping(value="/purc", params = RequestState.DONE,method = RequestMethod.GET)
+    @ResponseBody
+    public SPage<SaleTenderQuestion> getDoneTenderAnswers(PageParams params, String searchFilter) {
+        if (logger != null) {
+            logger.log("招标提问单", "查看收到的招标提问(已回复)");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(searchFilter);
+        String keyword = jsonObject.getString("keyword");
+        com.uas.search.b2b.model.PageParams pageParams = searchService.convertPageParams(params, searchFilter);
+        // 判断当前用户是否被客户分配
+        SearchFilter filter = userService.distribute();
+        if (filter != null && filter.getDistribute() == null) {
+            return null;
+        }
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("stq_id", false, Sort.Type.LONG, 1L));
+        pageParams.getFilters().put(SearchConstants.SORT_KEY, sortList);
+        pageParams.getFilters().put("stq_ptaid", SystemSession.getUser().getEnterprise().getUu());
+        return searchService.searchSaleTenderQuestion(keyword, pageParams);
+    }
+
+    /**
+     * 作为招标方,查看自己收到的提问单(未回复)
+     *
+     * @param params 分页参数
+     * @return Spage
+     */
+    @RequestMapping(value="/purc", params = RequestState.TODO,method = RequestMethod.GET)
+    @ResponseBody
+    public SPage<SaleTenderQuestion> getTodoTenderAnswers(PageParams params, String searchFilter) {
+        if (logger != null) {
+            logger.log("招标提问单", "查看收到的招标提问(未回复)");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(searchFilter);
+        String keyword = jsonObject.getString("keyword");
+        com.uas.search.b2b.model.PageParams pageParams = searchService.convertPageParams(params, searchFilter);
+        // 判断当前用户是否被客户分配
+        SearchFilter filter = userService.distribute();
+        if (filter != null && filter.getDistribute() == null) {
+            return null;
+        }
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("stq_id", false, Sort.Type.LONG, 1L));
+        pageParams.getFilters().put(SearchConstants.SORT_KEY, sortList);
+        pageParams.getFilters().put("stq_ptaid", SystemSession.getUser().getEnterprise().getUu());
+        return searchService.searchSaleTenderQuestion(keyword, pageParams);
+    }
+}

+ 26 - 36
src/main/java/com/uas/platform/b2b/controller/SnapshotController.java

@@ -1,45 +1,17 @@
 package com.uas.platform.b2b.controller;
 
-import java.util.Hashtable;
-import java.util.List;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.ui.ModelMap;
-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.ResponseStatus;
-import org.springframework.web.bind.annotation.RestController;
-
 import com.uas.platform.b2b.core.util.ThreadUtils;
 import com.uas.platform.b2b.model.User;
-import com.uas.platform.b2b.service.AddPartnerService;
-import com.uas.platform.b2b.service.CartService;
-import com.uas.platform.b2b.service.MakeAcceptService;
-import com.uas.platform.b2b.service.MakeOrderChangeService;
-import com.uas.platform.b2b.service.MakeOrderService;
-import com.uas.platform.b2b.service.MakeReturnService;
-import com.uas.platform.b2b.service.PagingReleaseService;
-import com.uas.platform.b2b.service.PurchaseAcceptService;
-import com.uas.platform.b2b.service.PurchaseApBillService;
-import com.uas.platform.b2b.service.PurchaseApCheckService;
-import com.uas.platform.b2b.service.PurchaseBadInService;
-import com.uas.platform.b2b.service.PurchaseBadOutService;
-import com.uas.platform.b2b.service.PurchaseInquiryMouldService;
-import com.uas.platform.b2b.service.PurchaseInquiryService;
-import com.uas.platform.b2b.service.PurchaseMRBService;
-import com.uas.platform.b2b.service.PurchaseNoticeService;
-import com.uas.platform.b2b.service.PurchaseOrderChangeService;
-import com.uas.platform.b2b.service.PurchaseOrderService;
-import com.uas.platform.b2b.service.PurchaseProofingService;
-import com.uas.platform.b2b.service.PurchaseReturnService;
-import com.uas.platform.b2b.service.PurchaseTenderService;
-import com.uas.platform.b2b.service.SaleARCheckService;
-import com.uas.platform.b2b.service.SaleQuotationService;
-import com.uas.platform.b2b.service.VendorService;
+import com.uas.platform.b2b.service.*;
 import com.uas.platform.b2b.support.SystemSession;
 import com.uas.platform.core.model.Status;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Hashtable;
+import java.util.List;
 
 /**
  * 平台消息、任务快照
@@ -123,6 +95,9 @@ public class SnapshotController {
 	@Autowired
 	private VendorService vendorService;
 
+	@Autowired
+	private PurchaseTenderService purchaseTenderService;
+
 	/**
 	 * 统计待处理事项
 	 * 
@@ -551,6 +526,21 @@ public class SnapshotController {
 				}
 				hashtable.put("tender", count);
 				SystemSession.clear();
+//			}
+//		}).task(new Runnable() {
+//
+//			@Override
+//			public void run() {
+//				//客户招标提问
+//				SystemSession.setUser(user);
+//				int count = 0;
+//				List<Object[]> list = purchaseTenderService.getTenderQuestionCount("sale");
+//				for (Object[] objects : list){
+//					count = count + Integer.valueOf(objects[0].toString());
+//					break;
+//				}
+//				hashtable.put("tender", count);
+//				SystemSession.clear();
 			}
 		}).task(new Runnable() {
 

+ 15 - 0
src/main/java/com/uas/platform/b2b/dao/PurchaseTenderAnswerDao.java

@@ -0,0 +1,15 @@
+package com.uas.platform.b2b.dao;
+
+import com.uas.platform.b2b.model.PurchaseTenderAnswer;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 招标单答疑单
+ * 2017-09-11 10:07
+ */
+@Repository
+public interface PurchaseTenderAnswerDao extends JpaSpecificationExecutor<PurchaseTenderAnswer>, JpaRepository<PurchaseTenderAnswer, Long> {
+
+}

+ 27 - 0
src/main/java/com/uas/platform/b2b/dao/PurchaseTenderQuestionDao.java

@@ -0,0 +1,27 @@
+package com.uas.platform.b2b.dao;
+
+import com.uas.platform.b2b.model.PurchaseTenderQuestion;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 招标单提问单
+ * 2017-09-11 10:07
+ */
+@Repository
+public interface PurchaseTenderQuestionDao extends JpaSpecificationExecutor<PurchaseTenderQuestion>, JpaRepository<PurchaseTenderQuestion, Long> {
+
+
+	/**
+	 * 根据当前企业uu获取问题列表
+	 * @param uu
+	 * @return
+	 */
+	@Query("from PurchaseTenderQuestion q where q.purchaseTenderAnswer.enUU = :uu")
+	List<PurchaseTenderQuestion> findByVendUU(@Param("uu") Long uu);
+}

+ 17 - 0
src/main/java/com/uas/platform/b2b/dao/SaleTenderAnswerDao.java

@@ -0,0 +1,17 @@
+package com.uas.platform.b2b.dao;
+
+import com.uas.platform.b2b.model.SaleTenderAnswer;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 招标单答疑单
+ * 2017-09-11 10:29
+ */
+@Repository
+public interface SaleTenderAnswerDao extends JpaSpecificationExecutor<SaleTenderAnswer>, JpaRepository<SaleTenderAnswer, Long> {
+
+
+    SaleTenderAnswer findByEnUUAndTenderCode(Long enUU, String code);
+}

+ 31 - 0
src/main/java/com/uas/platform/b2b/dao/SaleTenderQuestionDao.java

@@ -0,0 +1,31 @@
+package com.uas.platform.b2b.dao;
+
+import com.uas.platform.b2b.model.SaleTenderQuestion;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+
+/**
+ * 投标单提问单
+ * 2017-09-11
+ */
+@Repository
+public interface SaleTenderQuestionDao extends JpaSpecificationExecutor<SaleTenderQuestion>, JpaRepository<SaleTenderQuestion, Long> {
+
+
+    SaleTenderQuestion findByVendUUAndCode(Long vendUU, String code);
+
+    /**
+     * 根据答疑单id修改提问单状态为已回复
+     * @param answerId
+     */
+    @Modifying@Transactional
+    @Query("update SaleTenderQuestion q set q.status = 201,q.replyDate = :replyDate where q.saleTenderAnswer.id = :answerId")
+    void setReplied(@Param("answerId") Long answerId, @Param("replyDate") Date replyDate);
+}

+ 114 - 3
src/main/java/com/uas/platform/b2b/erp/controller/TenderController.java

@@ -14,6 +14,7 @@ import com.uas.platform.b2b.temporary.model.DecideTender;
 import com.uas.platform.b2b.temporary.model.TenderContactInfo;
 import com.uas.platform.core.model.Constant;
 import com.uas.platform.core.model.PageParams;
+import com.uas.platform.core.model.Status;
 import com.uas.platform.core.util.serializer.FlexJsonUtils;
 import com.uas.platform.core.web.bind.RequestState;
 import com.uas.search.b2b.model.MultiValue;
@@ -195,7 +196,8 @@ public class TenderController {
     @RequestMapping(value = "/detail", method = RequestMethod.GET)
     @ResponseBody
     public PurchaseTender getTenderById(Long id) {
-        return tenderService.findById(id);
+        PurchaseTender tender =  tenderService.findById(id);
+        return tender;
     }
 
 
@@ -779,8 +781,8 @@ public class TenderController {
      * 提前开标
      */
     @RequestMapping(value = "/decide/inAdvance", method = RequestMethod.POST)
-    public ModelMap decideInAdvance(Long id) {
-        return tenderService.decideInAdvance(id);
+    public ModelMap decideInAdvance(Long id, Long date) {
+        return tenderService.decideInAdvance(id, date);
     }
 
     /**
@@ -809,4 +811,113 @@ public class TenderController {
         List<DecideTender> decideTenders = FlexJsonUtils.fromJsonArray(data, DecideTender.class);
         return tenderService.decideTenderAll(decideTenders);
     }
+
+
+    /**
+     * 获取提问单列表
+     */
+    @RequestMapping(value = "/question/list", method = RequestMethod.GET)
+    public List<PurchaseTenderQuestion> getQuestionList(Long uu) {
+        return tenderService.getQuestionList(uu);
+    }
+
+    /**
+     * 获取单个提问单详情
+     */
+    @RequestMapping(value = "/question/detail", method = RequestMethod.GET)
+    public SaleTenderQuestion getQuestionDetail(Long id) {
+        return tenderService.getQuestionDetail(id);
+    }
+
+    /**
+     * 获取当前招标单的全部提问单
+     */
+    @RequestMapping(value = "/question/this", method = RequestMethod.GET)
+    public PurchaseTenderAnswer getThisQuestionAll(Long tenderId) {
+        return tenderService.getThisQuestionAll(tenderId);
+    }
+
+    /**
+     * 保存答疑结果
+     */
+    @RequestMapping(value = "/question/answer/save", method = RequestMethod.POST)
+    public ModelMap saveQuestionAnswer(String data) throws UnsupportedEncodingException {
+        data = URLDecoder.decode(data, "UTF-8");
+        PurchaseTenderAnswer answer = FlexJsonUtils.fromJson(data, PurchaseTenderAnswer.class);
+        return tenderService.saveQuestionAnswer(answer);
+    }
+
+    /**
+     * 作为投标方,查看自己发出的提问单(全部)
+     *
+     * @param params 分页参数
+     * @return Spage
+     */
+    @RequestMapping(value = "/question", method = RequestMethod.GET)
+    @ResponseBody
+    public SPage<SaleTenderQuestion> getAllTenderQuestions(PageParams params, String searchFilter) {
+        JSONObject jsonObject = JSONObject.parseObject(searchFilter);
+        String keyword = jsonObject.getString("keyword");
+        com.uas.search.b2b.model.PageParams pageParams = searchService.convertPageParams(params, searchFilter);
+        // 判断当前用户是否被客户分配
+        SearchFilter filter = userService.distribute();
+        if (filter != null && filter.getDistribute() == null) {
+            return null;
+        }
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("stq_id", false, Sort.Type.LONG, 1L));
+        pageParams.getFilters().put(SearchConstants.SORT_KEY, sortList);
+        pageParams.getFilters().put("stq_ptaid", SystemSession.getUser().getEnterprise().getUu());
+        return searchService.searchSaleTenderQuestion(keyword, pageParams);
+    }
+
+    /**
+     * 作为投标方,查看自己发出的提问单(已回复)
+     *
+     * @param params 分页参数
+     * @return Spage
+     */
+    @RequestMapping(value = "/question",params = RequestState.DONE, method = RequestMethod.GET)
+    @ResponseBody
+    public SPage<SaleTenderQuestion> getDoneTenderQuestions(PageParams params, String searchFilter) {
+        JSONObject jsonObject = JSONObject.parseObject(searchFilter);
+        String keyword = jsonObject.getString("keyword");
+        com.uas.search.b2b.model.PageParams pageParams = searchService.convertPageParams(params, searchFilter);
+        // 判断当前用户是否被客户分配
+        SearchFilter filter = userService.distribute();
+        if (filter != null && filter.getDistribute() == null) {
+            return null;
+        }
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("stq_id", false, Sort.Type.LONG, 1L));
+        pageParams.getFilters().put(SearchConstants.SORT_KEY, sortList);
+        pageParams.getFilters().put("stq_ptaid", SystemSession.getUser().getEnterprise().getUu());
+        pageParams.getFilters().put("stq_status", Status.REPLIED.value());
+        return searchService.searchSaleTenderQuestion(keyword, pageParams);
+    }
+
+    /**
+     * 作为投标方,查看自己发出的提问单(未回复)
+     *
+     * @param params 分页参数
+     * @return Spage
+     */
+    @RequestMapping(value = "/question",params = RequestState.TODO, method = RequestMethod.GET)
+    @ResponseBody
+    public SPage<SaleTenderQuestion> getTodoTenderQuestions(PageParams params, String searchFilter) {
+        JSONObject jsonObject = JSONObject.parseObject(searchFilter);
+        String keyword = jsonObject.getString("keyword");
+        com.uas.search.b2b.model.PageParams pageParams = searchService.convertPageParams(params, searchFilter);
+        // 判断当前用户是否被客户分配
+        SearchFilter filter = userService.distribute();
+        if (filter != null && filter.getDistribute() == null) {
+            return null;
+        }
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("stq_id", false, Sort.Type.LONG, 1L));
+        pageParams.getFilters().put(SearchConstants.SORT_KEY, sortList);
+        pageParams.getFilters().put("stq_ptaid", SystemSession.getUser().getEnterprise().getUu());
+        pageParams.getFilters().put("stq_status", Status.NOT_REPLY.value());
+        return searchService.searchSaleTenderQuestion(keyword, pageParams);
+    }
 }

+ 14 - 4
src/main/java/com/uas/platform/b2b/erp/controller/UserSpaceDetailController.java

@@ -10,10 +10,7 @@ import com.uas.platform.b2b.model.InvitationRecord;
 import com.uas.platform.b2b.model.SearchFilter;
 import com.uas.platform.b2b.model.User;
 import com.uas.platform.b2b.search.SearchService;
-import com.uas.platform.b2b.service.AddPartnerService;
-import com.uas.platform.b2b.service.InvitationRecordService;
-import com.uas.platform.b2b.service.PurcOrderService;
-import com.uas.platform.b2b.service.UserService;
+import com.uas.platform.b2b.service.*;
 import com.uas.platform.b2b.support.SystemSession;
 import com.uas.platform.b2b.temporary.model.BasePartnersInfo;
 import com.uas.platform.core.model.Constant;
@@ -58,6 +55,9 @@ public class UserSpaceDetailController {
 	@Autowired
 	private UserService userService;
 
+	@Autowired
+	private VendorService vendorService;
+
 	/**
 	 * 获取添加合作伙伴数据
 	 * 
@@ -366,4 +366,14 @@ public class UserSpaceDetailController {
 		InvitationRecord record = FlexJsonUtils.fromJson(formStore, InvitationRecord.class);
 		return invitationRecordService.invite(record);
 	}
+
+	/**
+	 * 一键同步供应商和客户(接口是返回B2B端所有该企业的供应商和客户)
+	 *
+	 * @return
+	 */
+	@RequestMapping(value = "/synchronize", method = RequestMethod.GET)
+	private ModelMap  oneClickSync(Long enUU) {
+		return vendorService.getVendorsAndCustomers(enUU);
+	}
 }

+ 18 - 5
src/main/java/com/uas/platform/b2b/erp/model/PurchaseTenderErp.java

@@ -1,14 +1,13 @@
 package com.uas.platform.b2b.erp.model;
 
+import com.uas.platform.b2b.model.Attach;
+import com.uas.platform.b2b.model.Enterprise;
+
+import javax.persistence.*;
 import java.io.Serializable;
 import java.util.Date;
 import java.util.Set;
 
-import javax.persistence.*;
-
-import com.uas.platform.b2b.model.Attach;
-import com.uas.platform.b2b.model.Enterprise;
-
 /**
  *  招标单信息(因为存在根据日期判断状态,需要使用定时任务,采用视图)
  * Created by dongbw on 17/03/07 11:16.
@@ -175,6 +174,12 @@ public class PurchaseTenderErp implements Serializable {
     @Column(name = "pt_ifall")
     private Short ifAll;
 
+    /**
+     * 提问截止时间
+     */
+    @Column(name = "pt_questionenddate")
+    private Date questionEndDate;
+
     @Transient
     private Short bidEnNum;
 
@@ -385,6 +390,14 @@ public class PurchaseTenderErp implements Serializable {
     public void setBidEnNum(Short bidEnNum) {
         this.bidEnNum = bidEnNum;
     }
+
+    public Date getQuestionEndDate() {
+        return questionEndDate;
+    }
+
+    public void setQuestionEndDate(Date questionEndDate) {
+        this.questionEndDate = questionEndDate;
+    }
 }
 
 

+ 44 - 0
src/main/java/com/uas/platform/b2b/erp/model/SaleTenderErp.java

@@ -191,6 +191,13 @@ public class SaleTenderErp implements Serializable {
     @OrderBy("id")
     private Set<SaleTenderItemErp> saleTenderItems;
 
+    /**
+     * 问题单
+     */
+    @OneToMany(mappedBy = "saleTender", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
+    @OrderBy("id")
+    private Set<SaleTenderQuestion> saleTenderQuestions;
+
     /**
      * 投标企业uu
      */
@@ -230,6 +237,13 @@ public class SaleTenderErp implements Serializable {
     @Column(name = "st_result", insertable = false, updatable = false)
     private Short result;
 
+    /**
+     * 是否已截止提问,根据questionEndDate判断,为视图虚拟列 0 未截止提问,1已截止
+     * @param tender
+     */
+    @Column(name = "st_questionEnd", insertable = false, updatable = false)
+    private Short questionEnd;
+
     /**
      * 是否全包 (1为全包,0为部分供料)
      */
@@ -254,6 +268,12 @@ public class SaleTenderErp implements Serializable {
     @Column(name = "st_taxrate")
     private Integer taxrate;
 
+    /**
+     * 提问截止时间
+     */
+    @Column(name = "st_questionenddate")
+    private Date questionEndDate;
+
 
     public Long getId() {
         return id;
@@ -550,4 +570,28 @@ public class SaleTenderErp implements Serializable {
     public void setResult(Short result) {
         this.result = result;
     }
+
+    public Date getQuestionEndDate() {
+        return questionEndDate;
+    }
+
+    public void setQuestionEndDate(Date questionEndDate) {
+        this.questionEndDate = questionEndDate;
+    }
+
+    public Set<SaleTenderQuestion> getSaleTenderQuestions() {
+        return saleTenderQuestions;
+    }
+
+    public void setSaleTenderQuestions(Set<SaleTenderQuestion> saleTenderQuestions) {
+        this.saleTenderQuestions = saleTenderQuestions;
+    }
+
+    public Short getQuestionEnd() {
+        return questionEnd;
+    }
+
+    public void setQuestionEnd(Short questionEnd) {
+        this.questionEnd = questionEnd;
+    }
 }

+ 9 - 1
src/main/java/com/uas/platform/b2b/erp/service/TenderService.java

@@ -181,11 +181,19 @@ public interface TenderService {
      */
     ModelMap publishTender(Long id);
 
-    ModelMap decideInAdvance(Long id);
+    ModelMap decideInAdvance(Long id, Long date);
 
     ModelMap getSaleTenderVendors(Long id);
 
     ModelMap sendMobileMessage(Long id);
 
     ModelMap decideTenderAll(List<DecideTender> decideTenders);
+
+    List<PurchaseTenderQuestion> getQuestionList(Long uu);
+
+    SaleTenderQuestion getQuestionDetail(Long id);
+
+    PurchaseTenderAnswer getThisQuestionAll(Long tenderId);
+
+    ModelMap saveQuestionAnswer(PurchaseTenderAnswer answer);
 }

+ 65 - 8
src/main/java/com/uas/platform/b2b/erp/service/impl/TenderServiceImpl.java

@@ -17,7 +17,6 @@ import com.uas.platform.b2b.temporary.model.*;
 import com.uas.platform.core.model.Constant;
 import com.uas.platform.core.util.HttpUtil;
 import com.uas.platform.core.util.serializer.FlexJsonUtils;
-import org.apache.commons.lang3.time.DateUtils;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
@@ -89,6 +88,15 @@ public class TenderServiceImpl implements TenderService {
     @Autowired
     private MessageConf messageConf;
 
+    @Autowired
+    private PurchaseTenderQuestionDao purchaseTenderQuestionDao;
+
+    @Autowired
+    private PurchaseTenderAnswerDao purchaseTenderAnswerDao;
+
+    @Autowired
+    private SaleTenderQuestionDao saleTenderQuestionDao;
+
     /**
      * 短信接口
      */
@@ -354,7 +362,11 @@ public class TenderServiceImpl implements TenderService {
 
     @Override
     public PurchaseTender findById(Long id) {
-        return purchaseTenderDao.findOne(id);
+        PurchaseTender tender = purchaseTenderDao.findOne(id);
+        // 已投标企业统计
+        Integer saleTenders = saleTenderDao.findNumOfBIdEn(tender.getEnUU(), tender.getCode(), "待投标");
+        tender.setBidEnNum(Short.valueOf(String.valueOf(saleTenders)));
+        return tender;
     }
 
     /**
@@ -527,17 +539,18 @@ public class TenderServiceImpl implements TenderService {
      * @return
      */
     @Override
-    public ModelMap decideInAdvance(Long id) {
+    public ModelMap decideInAdvance(Long id, Long date) {
         ModelMap map = new ModelMap();
         PurchaseTender tender = purchaseTenderDao.findOne(id);
         if (null == tender) {
             map.put("error", "根据id未找到对应招标单");
             return map;
         }
-        Date currentTime = new Date();
-        //获取昨天时间
-        Date backupTime = DateUtils.addDays(currentTime, -1);
-        tender.setEndDate(backupTime);
+//        Date currentTime = new Date();
+//        //获取昨天时间
+//        Date backupTime = DateUtils.addDays(currentTime, -1);
+        // 传日期时间戳进行设置
+        tender.setEndDate(new Date(date));
         tender.setStatus("待评标");
         purchaseTenderDao.save(tender);
         // 不开放的要同时把投标单发布状态修改
@@ -545,7 +558,7 @@ public class TenderServiceImpl implements TenderService {
             List<SaleTender> saleTenders = saleTenderDao.findByEnUUAndCode(tender.getEnUU(), tender.getCode());
             List<SaleTender> saveList = new ArrayList<>();
             for (SaleTender saleTender : saleTenders) {
-                saleTender.setEndDate(backupTime);
+                saleTender.setEndDate(new Date(date));
 //                saleTender.setStatus("待评标");
                 saveList.add(saleTender);
             }
@@ -650,6 +663,8 @@ public class TenderServiceImpl implements TenderService {
             oldTender.setUser(purchaseTender.getUser());
             oldTender.setUserTel(purchaseTender.getUserTel());
             oldTender.setUseruu(purchaseTender.getUseruu());
+            oldTender.setIfAll(purchaseTender.getIfAll());
+            oldTender.setQuestionEndDate(purchaseTender.getQuestionEndDate());
             oldTender.setTenderAttaches(purchaseTender.getTenderAttaches());
             oldTender = purchaseTenderDao.save(oldTender);
             if (!CollectionUtils.isEmpty(enInfos)) { // 不为空时,是修改过供应商的。
@@ -1220,5 +1235,47 @@ public class TenderServiceImpl implements TenderService {
         return map;
     }
 
+    @Override
+    public List<PurchaseTenderQuestion> getQuestionList(Long uu) {
+        return purchaseTenderQuestionDao.findByVendUU(uu);
+    }
+
+    @Override
+    public SaleTenderQuestion getQuestionDetail(Long id) {
+        return saleTenderQuestionDao.findOne(id);
+    }
+
+    @Override
+    public PurchaseTenderAnswer getThisQuestionAll(Long tenderId) {
+        PurchaseTender tender = purchaseTenderDao.findOne(tenderId);
+        if (null != tender) {
+            return tender.getAnswer();
+        }
+        return null;
+    }
+
+    @Override
+    public ModelMap saveQuestionAnswer(PurchaseTenderAnswer answer) {
+        ModelMap map = new ModelMap();
+        Set<Attach> answerAttaches = answer.getAnswerAttaches();
+        PurchaseTenderAnswer purchaseTenderAnswer = purchaseTenderAnswerDao.findOne(answer.getId());
+        if (!CollectionUtils.isEmpty(answerAttaches)) {
+            attachDao.save(answerAttaches);
+            purchaseTenderAnswer.setAnswerAttaches(answerAttaches);
+        }
+        purchaseTenderAnswer.setCode(answer.getCode());
+        purchaseTenderAnswer.setAuditDate(answer.getAuditDate());
+        purchaseTenderAnswer.setInDate(answer.getInDate());
+        purchaseTenderAnswer.setRecorder(answer.getRecorder());
+        purchaseTenderAnswer.setRemark(answer.getRemark());
+        purchaseTenderAnswer.setReplyDate(answer.getReplyDate());
+        purchaseTenderAnswer.setStatus(answer.getStatus());
+        // 对应提问单修改为已回复
+        purchaseTenderAnswer = purchaseTenderAnswerDao.save(purchaseTenderAnswer);
+        saleTenderQuestionDao.setReplied(purchaseTenderAnswer.getId(), purchaseTenderAnswer.getReplyDate());
+        map.put("success", true);
+        map.put("id", purchaseTenderAnswer.getId());
+        return map;
+    }
 }
 

+ 41 - 0
src/main/java/com/uas/platform/b2b/model/PurchaseTender.java

@@ -169,6 +169,11 @@ public class PurchaseTender implements Serializable {
     @JoinTable(name = "purc$tenderattach", joinColumns = @JoinColumn(name = "pt_id", referencedColumnName = "pt_id"), inverseJoinColumns = @JoinColumn(name="at_id", referencedColumnName = "at_id"))
     private Set<Attach> tenderAttaches;
 
+    /**
+     * 招标回答
+     */
+    @OneToOne(mappedBy = "tender", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
+    private PurchaseTenderAnswer answer;
 
     /**
      * 是否截止(0未截止,1已截止)
@@ -195,6 +200,18 @@ public class PurchaseTender implements Serializable {
     @Column(name = "pt_ifall")
     private Short ifAll;
 
+    /**
+     * 提问截止时间
+     */
+    @Column(name = "pt_questionenddate")
+    private Date questionEndDate;
+
+    /**
+     * 是否截止提问(0未截止,1已截止)
+     */
+    @Column(name = "pt_questionend", insertable = false, updatable = false)
+    private Short questionEnd;
+
     @Transient
     private Short bidEnNum;
 
@@ -429,6 +446,30 @@ public class PurchaseTender implements Serializable {
     public void setIfAll(Short ifAll) {
         this.ifAll = ifAll;
     }
+
+    public Date getQuestionEndDate() {
+        return questionEndDate;
+    }
+
+    public void setQuestionEndDate(Date questionEndDate) {
+        this.questionEndDate = questionEndDate;
+    }
+
+    public PurchaseTenderAnswer getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(PurchaseTenderAnswer answer) {
+        this.answer = answer;
+    }
+
+    public Short getQuestionEnd() {
+        return questionEnd;
+    }
+
+    public void setQuestionEnd(Short questionEnd) {
+        this.questionEnd = questionEnd;
+    }
 }
 
 

+ 258 - 0
src/main/java/com/uas/platform/b2b/model/PurchaseTenderAnswer.java

@@ -0,0 +1,258 @@
+package com.uas.platform.b2b.model;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * 招标方答疑单 (招标单关联)
+ * Created by dongbw
+ * 17/09/07 17:32.
+ */
+@Table(name = "purc$tenderanswer")
+@Entity
+public class PurchaseTenderAnswer implements Serializable {
+
+    /**
+     * 序列号
+     */
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "purc$tenderanswer_gen")
+    @SequenceGenerator(name = "purc$tenderanswer_gen", sequenceName = "purc$tenderanswer_seq", allocationSize = 1)
+    @Column(name = "pta_id")
+    private Long id;
+
+    /**
+     * 答疑编号
+     */
+    @Column(name = "pta_code")
+    private String code;
+
+    /**
+     * 招标企业UU
+     */
+    @Column(name = "pta_enuu")
+    private Long enUU;
+
+    /**
+     * 招标企业
+     */
+    @OneToOne
+    @JoinColumn(name = "pta_enuu", insertable = false, updatable = false)
+    private Enterprise enterprise;
+
+    /**
+     * 招标编号
+     */
+    @Column(name = "pta_tendercode")
+    private String tenderCode;
+
+    /**
+     * 招标标题
+     */
+    @Column(name = "pta_tendertitle")
+    private String tenderTitle;
+
+
+    /**
+     * 答疑截止时间
+     */
+    @Column(name = "pta_questionenddate")
+    private Date questionEndDate;
+
+
+    /**
+     * 录入时间
+     */
+    @Column(name = "pta_inDate")
+    private Date inDate;
+
+    /**
+     * 录入人
+     */
+    @Column(name = "pta_recorder")
+    private String recorder;
+
+    /**
+     * UAS审核时间
+     */
+    @Column(name = "pta_auditdate")
+    private Date auditDate;
+
+    /**
+     * 回复时间
+     */
+    @Column(name = "pta_replydate")
+    private Date replyDate;
+
+
+    /**
+     * 答疑备注
+     */
+    @Column(name = "pta_remark")
+    private String remark;
+
+    /**
+     * 处理状态
+     */
+    @Column(name = "pta_status")
+    private Short status;
+
+    /**
+     * 招标单
+     */
+    @OneToOne
+    @JoinColumn(name = "pta_ptid")
+    private PurchaseTender tender;
+
+    /**
+     * 投标提问单
+     */
+    @OneToMany(mappedBy = "purchaseTenderAnswer", cascade = {CascadeType.REFRESH, CascadeType.MERGE, CascadeType.PERSIST}, fetch = FetchType.EAGER)
+    @OrderBy("id")
+    private Set<PurchaseTenderQuestion> purchaseTenderQuestions;
+
+    /**
+     * 答疑附件
+     */
+    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.REFRESH})
+    @JoinTable(name = "purc$tenderanswerattach", joinColumns = @JoinColumn(name = "pta_id", referencedColumnName = "pta_id"), inverseJoinColumns = @JoinColumn(name="at_id", referencedColumnName = "at_id"))
+    private Set<Attach> answerAttaches;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Long getEnUU() {
+        return enUU;
+    }
+
+    public void setEnUU(Long enUU) {
+        this.enUU = enUU;
+    }
+
+    public String getTenderCode() {
+        return tenderCode;
+    }
+
+    public void setTenderCode(String tenderCode) {
+        this.tenderCode = tenderCode;
+    }
+
+    public String getTenderTitle() {
+        return tenderTitle;
+    }
+
+    public void setTenderTitle(String tenderTitle) {
+        this.tenderTitle = tenderTitle;
+    }
+
+    public Date getQuestionEndDate() {
+        return questionEndDate;
+    }
+
+    public void setQuestionEndDate(Date questionEndDate) {
+        this.questionEndDate = questionEndDate;
+    }
+
+    public Date getInDate() {
+        return inDate;
+    }
+
+    public void setInDate(Date inDate) {
+        this.inDate = inDate;
+    }
+
+    public Date getReplyDate() {
+        return replyDate;
+    }
+
+    public void setReplyDate(Date replyDate) {
+        this.replyDate = replyDate;
+    }
+
+
+    public Short getStatus() {
+        return status;
+    }
+
+    public void setStatus(Short status) {
+        this.status = status;
+    }
+
+    public Enterprise getEnterprise() {
+        return enterprise;
+    }
+
+    public void setEnterprise(Enterprise enterprise) {
+        this.enterprise = enterprise;
+    }
+
+    public String getRecorder() {
+        return recorder;
+    }
+
+    public void setRecorder(String recorder) {
+        this.recorder = recorder;
+    }
+
+    public Date getAuditDate() {
+        return auditDate;
+    }
+
+    public void setAuditDate(Date auditDate) {
+        this.auditDate = auditDate;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public Set<PurchaseTenderQuestion> getPurchaseTenderQuestions() {
+        return purchaseTenderQuestions;
+    }
+
+    public void setPurchaseTenderQuestions(Set<PurchaseTenderQuestion> purchaseTenderQuestions) {
+        this.purchaseTenderQuestions = purchaseTenderQuestions;
+    }
+
+    public Set<Attach> getAnswerAttaches() {
+        return answerAttaches;
+    }
+
+    public void setAnswerAttaches(Set<Attach> answerAttaches) {
+        this.answerAttaches = answerAttaches;
+    }
+
+    @JsonIgnore
+    @JSONField(serialize = false)
+    public PurchaseTender getTender() {
+        return tender;
+    }
+
+    public void setTender(PurchaseTender tender) {
+        this.tender = tender;
+    }
+}

+ 198 - 0
src/main/java/com/uas/platform/b2b/model/PurchaseTenderQuestion.java

@@ -0,0 +1,198 @@
+package com.uas.platform.b2b.model;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * 投标方提问单 (招标单关联)
+ * Created by dongbw
+ * 17/09/07 18:17.
+ */
+@Table(name = "sale$tenderquestion")
+@Entity
+public class PurchaseTenderQuestion implements Serializable {
+
+    /**
+     * 序列号
+     */
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sale$tenderquestion_gen")
+    @SequenceGenerator(name = "sale$tenderquestion_gen", sequenceName = "sale$tenderquestion_seq", allocationSize = 1)
+    @Column(name = "stq_id")
+    private Long id;
+
+    /**
+     * 提问编号
+     */
+    @Column(name = "stq_code")
+    private String code;
+
+    /**
+     * 投标企业UU
+     */
+    @Column(name = "stq_venduu")
+    private Long vendUU;
+
+    /**
+     * 投标企业
+     */
+    @OneToOne
+    @JoinColumn(name = "stq_venduu", insertable = false, updatable = false)
+    private Enterprise vendor;
+
+    /**
+     * 提出时间
+     */
+    @Column(name = "stq_indate")
+    private Date inDate;
+
+    /**
+     * 回复时间
+     */
+    @Column(name = "stq_replydate")
+    private Date replyDate;
+
+    /**
+     * 提问主题
+     */
+    @Column(name = "stq_topic")
+    private String topic;
+
+    /**
+     * 处理状态
+     */
+    @Column(name = "stq_status")
+    private Short status;
+
+    /**
+     * 咨询内容
+     */
+    @Column(name = "stq_content")
+    private String content;
+
+    /**
+     * 投标单id
+     */
+    @Column(name = "stq_stid")
+    private Long stId;
+
+    /**
+     * 招标答疑单
+     */
+    @ManyToOne(cascade = CascadeType.REFRESH)
+    @JoinColumn(name = "stq_ptaid", nullable = false)
+    private PurchaseTenderAnswer purchaseTenderAnswer;
+
+    /**
+     * 提问附件
+     */
+    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.REFRESH})
+    @JoinTable(name = "sale$tenderquestionattach", joinColumns = @JoinColumn(name = "stq_id", referencedColumnName = "stq_id"), inverseJoinColumns = @JoinColumn(name="at_id", referencedColumnName = "at_id"))
+    private Set<Attach> questionAttaches;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+
+    public Long getVendUU() {
+        return vendUU;
+    }
+
+    public void setVendUU(Long vendUU) {
+        this.vendUU = vendUU;
+    }
+
+    public Date getInDate() {
+        return inDate;
+    }
+
+    public void setInDate(Date inDate) {
+        this.inDate = inDate;
+    }
+
+    public Date getReplyDate() {
+        return replyDate;
+    }
+
+    public void setReplyDate(Date replyDate) {
+        this.replyDate = replyDate;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public Short getStatus() {
+        return status;
+    }
+
+    public void setStatus(Short status) {
+        this.status = status;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Enterprise getVendor() {
+        return vendor;
+    }
+
+    public void setVendor(Enterprise vendor) {
+        this.vendor = vendor;
+    }
+
+    @JsonIgnore
+    @JSONField(serialize = false)
+    public PurchaseTenderAnswer getPurchaseTenderAnswer() {
+        return purchaseTenderAnswer;
+    }
+
+    public void setPurchaseTenderAnswer(PurchaseTenderAnswer purchaseTenderAnswer) {
+        this.purchaseTenderAnswer = purchaseTenderAnswer;
+    }
+
+    public Set<Attach> getQuestionAttaches() {
+        return questionAttaches;
+    }
+
+    public void setQuestionAttaches(Set<Attach> questionAttaches) {
+        this.questionAttaches = questionAttaches;
+    }
+
+    public Long getStId() {
+        return stId;
+    }
+
+    public void setStId(Long stId) {
+        this.stId = stId;
+    }
+}

+ 35 - 3
src/main/java/com/uas/platform/b2b/model/SaleTender.java

@@ -1,6 +1,7 @@
 package com.uas.platform.b2b.model;
 
 import com.alibaba.fastjson.annotation.JSONField;
+import com.uas.platform.b2b.erp.model.SaleTenderItemErp;
 import com.uas.platform.b2b.temporary.model.TenderContactInfo;
 import org.codehaus.jackson.annotate.JsonIgnore;
 
@@ -256,6 +257,19 @@ public class SaleTender implements Serializable, Comparable<SaleTender> {
     @Column(name = "st_taxrate")
     private Integer taxrate;
 
+    /**
+     * 提问截止时间
+     */
+    @Column(name = "st_questionenddate")
+    private Date questionEndDate;
+
+    /**
+     * 是否已截止提问,根据questionEndDate判断,为视图虚拟列 0 未截止提问,1已截止
+     * @param tender
+     */
+    @Column(name = "st_questionEnd", insertable = false, updatable = false)
+    private Short questionEnd;
+
     public SaleTender(PurchaseTender tender) {
         this.setCode(tender.getCode());
         this.setCertificate(tender.getCertificate());
@@ -277,6 +291,7 @@ public class SaleTender implements Serializable, Comparable<SaleTender> {
         this.setRecorderuu(tender.getUseruu());
         this.setPtId(tender.getId());
         this.setIfAll(tender.getIfAll());
+        this.setQuestionEndDate(tender.getQuestionEndDate());
     }
 
     public SaleTender(PurchaseTender tender, TenderContactInfo contactInfo) {
@@ -297,13 +312,14 @@ public class SaleTender implements Serializable, Comparable<SaleTender> {
         this.setStatus("待投标");// 转了投标单,默认是待投标状态
         this.setTitle(tender.getTitle());
         this.setEnUU(tender.getEnUU());
+        this.setRecorderuu(tender.getUseruu());
+        this.setPtId(tender.getId());
+        this.setIfAll(tender.getIfAll());
+        this.setQuestionEndDate(tender.getQuestionEndDate());
         this.setUserTel(contactInfo.getContactTel());
         this.setUser(contactInfo.getContact());
         this.setUseruu(contactInfo.getContactUU());
         this.setUserEmail(contactInfo.getContactEmail());
-        this.setRecorderuu(tender.getUseruu());
-        this.setPtId(tender.getId());
-        this.setIfAll(tender.getIfAll());
     }
 
     public SaleTender() {
@@ -612,4 +628,20 @@ public class SaleTender implements Serializable, Comparable<SaleTender> {
     public void setTaxrate(Integer taxrate) {
         this.taxrate = taxrate;
     }
+
+    public Date getQuestionEndDate() {
+        return questionEndDate;
+    }
+
+    public void setQuestionEndDate(Date questionEndDate) {
+        this.questionEndDate = questionEndDate;
+    }
+
+    public Short getQuestionEnd() {
+        return questionEnd;
+    }
+
+    public void setQuestionEnd(Short questionEnd) {
+        this.questionEnd = questionEnd;
+    }
 }

+ 268 - 0
src/main/java/com/uas/platform/b2b/model/SaleTenderAnswer.java

@@ -0,0 +1,268 @@
+package com.uas.platform.b2b.model;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.uas.platform.b2b.erp.model.SaleTenderErp;
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * 招标方答疑单 (投标单关联)
+ * Created by dongbw
+ * 17/09/07 18:02.
+ */
+@Table(name = "purc$tenderanswer")
+@Entity
+public class SaleTenderAnswer implements Serializable {
+
+    /**
+     * 序列号
+     */
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "purc$tenderanswer_gen")
+    @SequenceGenerator(name = "purc$tenderanswer_gen", sequenceName = "purc$tenderanswer_seq", allocationSize = 1)
+    @Column(name = "pta_id")
+    private Long id;
+
+    /**
+     * 答疑编号
+     */
+    @Column(name = "pta_code")
+    private String code;
+
+    /**
+     * 招标企业UU
+     */
+    @Column(name = "pta_enuu")
+    private Long enUU;
+
+    /**
+     * 招标企业
+     */
+    @OneToOne
+    @JoinColumn(name = "pta_enuu", insertable = false, updatable = false)
+    private Enterprise enterprise;
+
+    /**
+     * 招标编号
+     */
+    @Column(name = "pta_tendercode")
+    private String tenderCode;
+
+    /**
+     * 招标标题
+     */
+    @Column(name = "pta_tendertitle")
+    private String tenderTitle;
+
+    /**
+     * 答疑截止时间
+     */
+    @Column(name = "pta_questionenddate")
+    private Date questionEndDate;
+
+    /**
+     * 录入时间
+     */
+    @Column(name = "pta_indate")
+    private Date inDate;
+
+    /**
+     * 录入人
+     */
+    @Column(name = "pta_recorder")
+    private String recorder;
+
+    /**
+     * UAS审核时间
+     */
+    @Column(name = "pta_auditdate")
+    private Date auditDate;
+
+    /**
+     * 回复时间
+     */
+    @Column(name = "pta_replydate")
+    private Date replyDate;
+
+
+    /**
+     * 答疑备注
+     */
+    @Column(name = "pta_remark")
+    private String remark;
+
+    /**
+     * 处理状态
+     */
+    @Column(name = "pta_status")
+    private Short status;
+
+    /**
+     * 招标单id
+     */
+    @Column(name = "pta_ptid")
+    private Long tenderId;
+
+    /**
+     * 投标提问单
+     */
+    @OneToMany(mappedBy = "saleTenderAnswer", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
+    @OrderBy("id")
+    private Set<SaleTenderQuestion> saleTenderQuestions;
+
+    /**
+     * 答疑附件
+     */
+    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.REFRESH})
+    @JoinTable(name = "purc$tenderanswerattach", joinColumns = @JoinColumn(name = "pta_id", referencedColumnName = "pta_id"), inverseJoinColumns = @JoinColumn(name="at_id", referencedColumnName = "at_id"))
+    private Set<Attach> answerAttaches;
+
+    public SaleTenderAnswer() {
+    }
+
+    public SaleTenderAnswer(SaleTenderErp saleTender) {
+        this.enterprise = saleTender.getEnterprise();
+        this.enUU = saleTender.getEnUU();
+        this.questionEndDate = saleTender.getQuestionEndDate();
+        this.tenderCode = saleTender.getCode();
+        this.tenderTitle = saleTender.getTitle();
+        this.tenderId = saleTender.getPtId();
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Long getEnUU() {
+        return enUU;
+    }
+
+    public void setEnUU(Long enUU) {
+        this.enUU = enUU;
+    }
+
+    public String getTenderCode() {
+        return tenderCode;
+    }
+
+    public void setTenderCode(String tenderCode) {
+        this.tenderCode = tenderCode;
+    }
+
+    public String getTenderTitle() {
+        return tenderTitle;
+    }
+
+    public void setTenderTitle(String tenderTitle) {
+        this.tenderTitle = tenderTitle;
+    }
+
+    public Date getQuestionEndDate() {
+        return questionEndDate;
+    }
+
+    public void setQuestionEndDate(Date questionEndDate) {
+        this.questionEndDate = questionEndDate;
+    }
+
+    public Date getInDate() {
+        return inDate;
+    }
+
+    public void setInDate(Date inDate) {
+        this.inDate = inDate;
+    }
+
+    public Date getReplyDate() {
+        return replyDate;
+    }
+
+    public void setReplyDate(Date replyDate) {
+        this.replyDate = replyDate;
+    }
+
+
+    public Short getStatus() {
+        return status;
+    }
+
+    public void setStatus(Short status) {
+        this.status = status;
+    }
+
+    public Enterprise getEnterprise() {
+        return enterprise;
+    }
+
+    public void setEnterprise(Enterprise enterprise) {
+        this.enterprise = enterprise;
+    }
+
+    public String getRecorder() {
+        return recorder;
+    }
+
+    public void setRecorder(String recorder) {
+        this.recorder = recorder;
+    }
+
+    public Date getAuditDate() {
+        return auditDate;
+    }
+
+    public void setAuditDate(Date auditDate) {
+        this.auditDate = auditDate;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    @JsonIgnore
+    @JSONField(serialize = false)
+    public Set<SaleTenderQuestion> getSaleTenderQuestions() {
+        return saleTenderQuestions;
+    }
+
+    public void setSaleTenderQuestions(Set<SaleTenderQuestion> saleTenderQuestions) {
+        this.saleTenderQuestions = saleTenderQuestions;
+    }
+
+    public Set<Attach> getAnswerAttaches() {
+        return answerAttaches;
+    }
+
+    public void setAnswerAttaches(Set<Attach> answerAttaches) {
+        this.answerAttaches = answerAttaches;
+    }
+
+    public Long getTenderId() {
+        return tenderId;
+    }
+
+    public void setTenderId(Long tenderId) {
+        this.tenderId = tenderId;
+    }
+}

+ 202 - 0
src/main/java/com/uas/platform/b2b/model/SaleTenderQuestion.java

@@ -0,0 +1,202 @@
+package com.uas.platform.b2b.model;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.uas.platform.b2b.erp.model.SaleTenderErp;
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * 投标方提问单 (投标单关联)
+ * Created by dongbw
+ * 17/09/07 18:10.
+ */
+@Table(name = "sale$tenderquestion")
+@Entity
+public class SaleTenderQuestion implements Serializable {
+
+    /**
+     * 序列号
+     */
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sale$tenderquestion_gen")
+    @SequenceGenerator(name = "sale$tenderquestion_gen", sequenceName = "sale$tenderquestion_seq", allocationSize = 1)
+    @Column(name = "stq_id")
+    private Long id;
+
+    /**
+     * 提问编号
+     */
+    @Column(name = "stq_code")
+    private String code;
+
+    /**
+     * 投标企业UU
+     */
+    @Column(name = "stq_venduu")
+    private Long vendUU;
+
+    /**
+     * 投标企业
+     */
+    @OneToOne
+    @JoinColumn(name = "stq_venduu", insertable = false, updatable = false)
+    private Enterprise vendor;
+
+    /**
+     * 提出时间
+     */
+    @Column(name = "stq_indate")
+    private Date inDate;
+
+    /**
+     * 回复时间
+     */
+    @Column(name = "stq_replydate")
+    private Date replyDate;
+
+
+    /**
+     * 提问主题
+     */
+    @Column(name = "stq_topic")
+    private String topic;
+
+
+    /**
+     * 处理状态
+     */
+    @Column(name = "stq_status")
+    private Short status;
+
+
+    /**
+     * 提问内容
+     */
+    @Column(name = "stq_content")
+    private String content;
+
+    /**
+     * 投标单
+     */
+    @ManyToOne(cascade = CascadeType.REFRESH)
+    @JoinColumn(name = "stq_stid", nullable = false)
+    private SaleTenderErp saleTender;
+
+    /**
+     * 招标答疑单
+     */
+    @ManyToOne(cascade = {CascadeType.REFRESH, CascadeType.MERGE})
+    @JoinColumn(name = "stq_ptaid", nullable = false)
+    private SaleTenderAnswer saleTenderAnswer;
+
+    /**
+     * 提问附件
+     */
+    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.REFRESH})
+    @JoinTable(name = "sale$tenderquestionattach", joinColumns = @JoinColumn(name = "stq_id", referencedColumnName = "stq_id"), inverseJoinColumns = @JoinColumn(name="at_id", referencedColumnName = "at_id"))
+    private Set<Attach> questionAttaches;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Enterprise getVendor() {
+        return vendor;
+    }
+
+    public void setVendor(Enterprise vendor) {
+        this.vendor = vendor;
+    }
+
+    public Long getVendUU() {
+        return vendUU;
+    }
+
+    public void setVendUU(Long vendUU) {
+        this.vendUU = vendUU;
+    }
+
+    public Date getInDate() {
+        return inDate;
+    }
+
+    public void setInDate(Date inDate) {
+        this.inDate = inDate;
+    }
+
+    public Date getReplyDate() {
+        return replyDate;
+    }
+
+    public void setReplyDate(Date replyDate) {
+        this.replyDate = replyDate;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public Short getStatus() {
+        return status;
+    }
+
+    public void setStatus(Short status) {
+        this.status = status;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Set<Attach> getQuestionAttaches() {
+        return questionAttaches;
+    }
+
+    public void setQuestionAttaches(Set<Attach> questionAttaches) {
+        this.questionAttaches = questionAttaches;
+    }
+
+    public SaleTenderAnswer getSaleTenderAnswer() {
+        return saleTenderAnswer;
+    }
+
+    public void setSaleTenderAnswer(SaleTenderAnswer saleTenderAnswer) {
+        this.saleTenderAnswer = saleTenderAnswer;
+    }
+
+    @JsonIgnore
+    @JSONField(serialize = false)
+    public SaleTenderErp getSaleTender() {
+        return saleTender;
+    }
+
+    public void setSaleTender(SaleTenderErp saleTender) {
+        this.saleTender = saleTender;
+    }
+}

+ 12 - 45
src/main/java/com/uas/platform/b2b/search/SearchService.java

@@ -1,58 +1,17 @@
 package com.uas.platform.b2b.search;
 
-import java.util.List;
-import java.util.Map;
-
 import com.uas.account.entity.UserSpaceDetail;
 import com.uas.account.support.Page;
 import com.uas.platform.b2b.erp.model.B2BCustomer;
 import com.uas.platform.b2b.erp.model.B2BVendor;
 import com.uas.platform.b2b.erp.model.SaleTenderErp;
-import com.uas.platform.b2b.model.Cart;
-import com.uas.platform.b2b.model.Component;
-import com.uas.platform.b2b.model.DeputyOrder;
-import com.uas.platform.b2b.model.Enterprise;
-import com.uas.platform.b2b.model.InvitationRecord;
-import com.uas.platform.b2b.model.Kind;
-import com.uas.platform.b2b.model.MakeAccept;
-import com.uas.platform.b2b.model.MakeOrder;
-import com.uas.platform.b2b.model.MakeOrderChangeItem;
-import com.uas.platform.b2b.model.MakeReturn;
-import com.uas.platform.b2b.model.PagingReleaseDetail;
-import com.uas.platform.b2b.model.Product;
-import com.uas.platform.b2b.model.PurcInquiry;
-import com.uas.platform.b2b.model.PurcInquiryItemInfo;
-import com.uas.platform.b2b.model.PurchaseAccept;
-import com.uas.platform.b2b.model.PurchaseApBill;
-import com.uas.platform.b2b.model.PurchaseApBillOut;
-import com.uas.platform.b2b.model.PurchaseApCheck;
-import com.uas.platform.b2b.model.PurchaseBadIn;
-import com.uas.platform.b2b.model.PurchaseBadOut;
-import com.uas.platform.b2b.model.PurchaseForecastAll;
-import com.uas.platform.b2b.model.PurchaseInquiryItem;
-import com.uas.platform.b2b.model.PurchaseInquiryMould;
-import com.uas.platform.b2b.model.PurchaseMRB;
-import com.uas.platform.b2b.model.PurchaseNotice;
-import com.uas.platform.b2b.model.PurchaseOrderAll;
-import com.uas.platform.b2b.model.PurchaseOrderChange;
-import com.uas.platform.b2b.model.PurchaseOrderDone;
-import com.uas.platform.b2b.model.PurchaseOrderEnd;
-import com.uas.platform.b2b.model.PurchaseOrderReceived;
-import com.uas.platform.b2b.model.PurchaseOrderTodo;
-import com.uas.platform.b2b.model.PurchaseOrderWaiting;
-import com.uas.platform.b2b.model.PurchaseProofingApproval;
-import com.uas.platform.b2b.model.PurchaseProofingItem;
-import com.uas.platform.b2b.model.PurchaseProofingSend;
-import com.uas.platform.b2b.model.PurchaseReturn;
-import com.uas.platform.b2b.model.PurchaseTender;
-import com.uas.platform.b2b.model.SaleARCheck;
-import com.uas.platform.b2b.model.SaleQuotationAll;
-import com.uas.platform.b2b.model.SaleQuotationDone;
-import com.uas.platform.b2b.model.SaleSendAll;
-import com.uas.platform.b2b.model.Vendor;
+import com.uas.platform.b2b.model.*;
 import com.uas.search.b2b.model.PageParams;
 import com.uas.search.b2b.model.SPage;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * 搜索接口
  * 
@@ -547,4 +506,12 @@ public interface SearchService {
 	 * @return
 	 */
 	public SPage<SaleQuotationDone> searchSaleQuotationDoneIds(String keyword, PageParams pageParams);
+
+	/**
+	 * 查找投标提问单
+	 * @param keyword
+	 * @param pageParams
+	 * @return
+	 */
+    SPage<SaleTenderQuestion> searchSaleTenderQuestion(String keyword, PageParams pageParams);
 }

+ 26 - 69
src/main/java/com/uas/platform/b2b/search/SearchServiceImpl.java

@@ -1,82 +1,16 @@
 package com.uas.platform.b2b.search;
 
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Predicate;
-import javax.persistence.criteria.Root;
-
-import com.uas.platform.b2b.core.util.SplitArray;
-import com.uas.platform.b2b.model.*;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-
 import com.alibaba.fastjson.JSONObject;
 import com.uas.account.entity.UserSpaceDetail;
 import com.uas.account.support.Page;
 import com.uas.account.util.AccountUtils;
-import com.uas.platform.b2b.dao.BrandDao;
-import com.uas.platform.b2b.dao.CartDao;
-import com.uas.platform.b2b.dao.ComponentDao;
-import com.uas.platform.b2b.dao.DeputyOrderDao;
-import com.uas.platform.b2b.dao.EnterpriseDao;
-import com.uas.platform.b2b.dao.InvitationRecordDao;
-import com.uas.platform.b2b.dao.KindDao;
-import com.uas.platform.b2b.dao.MakeAcceptDao;
-import com.uas.platform.b2b.dao.MakeOrderChangeItemDao;
-import com.uas.platform.b2b.dao.MakeOrderDao;
-import com.uas.platform.b2b.dao.MakeReturnDao;
-import com.uas.platform.b2b.dao.PagingReleaseDetailDao;
-import com.uas.platform.b2b.dao.ProductDao;
-import com.uas.platform.b2b.dao.PurcInquiryDao;
-import com.uas.platform.b2b.dao.PurcInquiryItemInfoDao;
-import com.uas.platform.b2b.dao.PurchaseAcceptDao;
-import com.uas.platform.b2b.dao.PurchaseApBillDao;
-import com.uas.platform.b2b.dao.PurchaseApBillOutDao;
-import com.uas.platform.b2b.dao.PurchaseApCheckDao;
-import com.uas.platform.b2b.dao.PurchaseBadInDao;
-import com.uas.platform.b2b.dao.PurchaseBadOutDao;
-import com.uas.platform.b2b.dao.PurchaseForecastAllDao;
-import com.uas.platform.b2b.dao.PurchaseInquiryItemDao;
-import com.uas.platform.b2b.dao.PurchaseInquiryMouldDao;
-import com.uas.platform.b2b.dao.PurchaseMRBDao;
-import com.uas.platform.b2b.dao.PurchaseNoticeDao;
-import com.uas.platform.b2b.dao.PurchaseOrderAllDao;
-import com.uas.platform.b2b.dao.PurchaseOrderChangeDao;
-import com.uas.platform.b2b.dao.PurchaseOrderDoneDao;
-import com.uas.platform.b2b.dao.PurchaseOrderEndDao;
-import com.uas.platform.b2b.dao.PurchaseOrderReceivedDao;
-import com.uas.platform.b2b.dao.PurchaseOrderTodoDao;
-import com.uas.platform.b2b.dao.PurchaseOrderWaitingDao;
-import com.uas.platform.b2b.dao.PurchaseProofingApprovalDao;
-import com.uas.platform.b2b.dao.PurchaseProofingItemDao;
-import com.uas.platform.b2b.dao.PurchaseProofingSendDao;
-import com.uas.platform.b2b.dao.PurchaseReturnDao;
-import com.uas.platform.b2b.dao.PurchaseTenderDao;
-import com.uas.platform.b2b.dao.SaleARCheckDao;
-import com.uas.platform.b2b.dao.SaleQuotationAllDao;
-import com.uas.platform.b2b.dao.SaleQuotationDoneDao;
-import com.uas.platform.b2b.dao.SaleSendAllDao;
-import com.uas.platform.b2b.dao.SaleTenderDao;
-import com.uas.platform.b2b.dao.SaleTenderErpDao;
-import com.uas.platform.b2b.dao.VendorDao;
+import com.uas.platform.b2b.core.util.SplitArray;
+import com.uas.platform.b2b.dao.*;
 import com.uas.platform.b2b.erp.model.B2BCustomer;
 import com.uas.platform.b2b.erp.model.B2BVendor;
 import com.uas.platform.b2b.erp.model.SaleTenderErp;
 import com.uas.platform.b2b.erp.model.SaleTenderItemErp;
+import com.uas.platform.b2b.model.*;
 import com.uas.platform.b2b.support.SystemSession;
 import com.uas.platform.core.persistence.criteria.PredicateFactory;
 import com.uas.platform.core.persistence.criteria.PredicateUtils;
@@ -84,6 +18,19 @@ import com.uas.search.b2b.model.PageParams;
 import com.uas.search.b2b.model.SPage;
 import com.uas.search.b2b.service.SearchService.Table_name;
 import com.uas.search.b2b.util.SearchConstants;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * 搜索实现
@@ -236,6 +183,9 @@ public class SearchServiceImpl implements com.uas.platform.b2b.search.SearchServ
 	@Autowired
 	private SaleQuotationDoneDao saleQuotationDoneDao;
 
+	@Autowired
+	private SaleTenderQuestionDao saleTenderQuestionDao;
+
 	/**
 	 * 联想词size
 	 */
@@ -1408,4 +1358,11 @@ public class SearchServiceImpl implements com.uas.platform.b2b.search.SearchServ
 		return toSPage(idsPage, content);
 	}
 
+	@Override
+	public SPage<SaleTenderQuestion> searchSaleTenderQuestion(String keyword, PageParams pageParams) {
+		SPage<Long> idsPage = searchService.searchIds(keyword, Table_name.SALE$TENDERQUESTION, pageParams);
+		List<SaleTenderQuestion> content = saleTenderQuestionDao.findAll(idsPage.getContent());
+		sortByProperty(content, SaleTenderQuestion.class, "id", idsPage.getContent());
+		return toSPage(idsPage, content);
+	}
 }

+ 9 - 4
src/main/java/com/uas/platform/b2b/service/PurchaseTenderService.java

@@ -1,10 +1,7 @@
 package com.uas.platform.b2b.service;
 
 import com.uas.platform.b2b.erp.model.SaleTenderErp;
-import com.uas.platform.b2b.model.Attach;
-import com.uas.platform.b2b.model.FileUpload;
-import com.uas.platform.b2b.model.PurchaseTender;
-import com.uas.platform.b2b.model.SearchFilter;
+import com.uas.platform.b2b.model.*;
 import com.uas.platform.b2b.temporary.model.TenderContactInfo;
 import com.uas.platform.core.model.PageInfo;
 import com.uas.search.b2b.model.SPage;
@@ -209,4 +206,12 @@ public interface PurchaseTenderService {
     ModelMap findMySaleTenderDetailByTenderId(Long tenderId);
 
     ModelMap findVendorSaleTenderDetailByTenderId(Long vendUU, Long tenderId);
+
+    SaleTenderQuestion sendQuestion(SaleTenderQuestion question, Long id, FileUpload uploadItem);
+
+    SaleTenderQuestion getQuestionDetail(Long id);
+
+    PurchaseTenderAnswer getAnswerDetail(Long id);
+
+    PurchaseTenderAnswer sendAnswer(PurchaseTenderAnswer answer, FileUpload uploadItem);
 }

+ 3 - 0
src/main/java/com/uas/platform/b2b/service/VendorService.java

@@ -5,6 +5,7 @@ import com.uas.platform.b2b.model.Vendor;
 import com.uas.platform.b2b.model.VendorContact;
 import com.uas.platform.core.model.PageInfo;
 import org.springframework.data.domain.Page;
+import org.springframework.ui.ModelMap;
 
 import java.util.List;
 
@@ -115,4 +116,6 @@ public interface VendorService {
 	 * 供应商同步到管理平台合作关系表
 	 */
 	void synchronizeToPartnerShipRecord();
+
+    ModelMap getVendorsAndCustomers(Long enUU);
 }

+ 85 - 0
src/main/java/com/uas/platform/b2b/service/impl/PurchaseTenderServiceImpl.java

@@ -36,6 +36,7 @@ import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
 import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
 import java.util.*;
 
 /**
@@ -95,6 +96,15 @@ public class PurchaseTenderServiceImpl implements PurchaseTenderService {
     @Autowired
     private PurchaseTenderErpDao purchaseTenderErpDao;
 
+    @Autowired
+    private SaleTenderQuestionDao saleTenderQuestionDao;
+
+    @Autowired
+    private SaleTenderAnswerDao saleTenderAnswerDao;
+
+    @Autowired
+    private PurchaseTenderAnswerDao purchaseTenderAnswerDao;
+
 
     /**
      *  发布或保存(新录入单据)
@@ -884,5 +894,80 @@ public class PurchaseTenderServiceImpl implements PurchaseTenderService {
         map.put("saleTender", saleTender);
         return map;
     }
+
+    @Override
+    public SaleTenderQuestion sendQuestion(SaleTenderQuestion question, Long id, FileUpload uploadItem) {
+        if (null != question) {
+            Long vendUU = SystemSession.getUser().getEnterprise().getUu();
+            SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
+            String code = "Q" + sdf.format(new Date());
+            SaleTenderQuestion saleTenderQuestion = saleTenderQuestionDao.findByVendUUAndCode(vendUU, code);
+            if (null != saleTenderQuestion) {
+                code = sdf.format(new Date());
+            }
+            question.setCode(code);
+            if (uploadItem != null && uploadItem.getFile() != null) {
+                Attach attach = attachService.upload(uploadItem, "saleTenderQuestion", "投标提问单附件");
+                attachDao.save(attach);
+                Set<Attach> attaches = new HashSet<Attach>();
+                attaches.add(attach);
+                question.setQuestionAttaches(attaches);
+            }
+            question.setStatus((short)Status.NOT_REPLY.value());
+            question.setInDate(new Date());
+            question.setVendUU(vendUU);
+            SaleTenderErp saleTender = saleTenderErpDao.findOne(id);
+            if (null != saleTender) {
+                question.setSaleTender(saleTender);
+                // 将部分信息设置到招标回答单据 (先查看该招标单是否已存在答疑单)
+                SaleTenderAnswer answer = saleTenderAnswerDao.findByEnUUAndTenderCode(saleTender.getEnUU(), saleTender.getCode());
+                if (null == answer) {
+                    answer = new SaleTenderAnswer(saleTender);
+//                    answer.setCode("A" + sdf.format(new Date()));
+                    answer.setStatus((short) Status.NOT_REPLY.value());
+                    answer = saleTenderAnswerDao.save(answer);
+                }
+                question.setSaleTenderAnswer(answer);
+                question = saleTenderQuestionDao.save(question);
+                return question;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public PurchaseTenderAnswer sendAnswer(PurchaseTenderAnswer answer, FileUpload uploadItem) {
+        if (null != answer) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
+            String code = "A" + sdf.format(new Date());
+            PurchaseTenderAnswer purchaseTenderAnswer = purchaseTenderAnswerDao.findOne(answer.getId());
+            purchaseTenderAnswer.setCode(code);
+            if (uploadItem != null && uploadItem.getFile() != null) {
+                Attach attach = attachService.upload(uploadItem, "PurchaseTenderAnswer", "招标答疑单附件");
+                attachDao.save(attach);
+                Set<Attach> attaches = new HashSet<Attach>();
+                attaches.add(attach);
+                purchaseTenderAnswer.setAnswerAttaches(attaches);
+            }
+            purchaseTenderAnswer.setStatus((short)Status.REPLIED.value());
+            purchaseTenderAnswer.setInDate(new Date());
+            purchaseTenderAnswer.setRecorder(SystemSession.getUser().getUserName());
+            purchaseTenderAnswer.setAuditDate(new Date());
+            purchaseTenderAnswer.setRemark(answer.getRemark());
+            purchaseTenderAnswer = purchaseTenderAnswerDao.save(purchaseTenderAnswer);
+            return purchaseTenderAnswer;
+        }
+        return null;
+    }
+
+    @Override
+    public SaleTenderQuestion getQuestionDetail(Long id) {
+        return saleTenderQuestionDao.findOne(id);
+    }
+
+    @Override
+    public PurchaseTenderAnswer getAnswerDetail(Long id) {
+        return purchaseTenderAnswerDao.findOne(id);
+    }
 }
 

+ 23 - 0
src/main/java/com/uas/platform/b2b/service/impl/VendorsServiceImpl.java

@@ -2,6 +2,8 @@ package com.uas.platform.b2b.service.impl;
 
 import com.uas.account.util.AccountUtils;
 import com.uas.platform.b2b.dao.*;
+import com.uas.platform.b2b.erp.model.B2BCustomer;
+import com.uas.platform.b2b.erp.model.B2BVendor;
 import com.uas.platform.b2b.model.Distribute;
 import com.uas.platform.b2b.model.Enterprise;
 import com.uas.platform.b2b.model.Vendor;
@@ -17,6 +19,7 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.ui.ModelMap;
 import org.springframework.util.CollectionUtils;
 
 import javax.persistence.criteria.CriteriaBuilder;
@@ -291,4 +294,24 @@ public class VendorsServiceImpl implements VendorService {
 		}
 	}
 
+	@Override
+	public ModelMap getVendorsAndCustomers(Long enUU) {
+		ModelMap map = new ModelMap();
+		List<B2BVendor> B2BVendors = new ArrayList<>();
+		List<Vendor> vendors = vendorDao.findByMyEnUU(enUU);
+		for (Vendor vendor : vendors) {
+			B2BVendor b2BVendor = new B2BVendor(vendor);
+			B2BVendors.add(b2BVendor);
+		}
+		List<B2BCustomer> B2BCustomers = new ArrayList<>();
+		List<Vendor> customers = vendorDao.findByVendEnUU(enUU);
+		for (Vendor customer : customers) {
+			B2BCustomer b2BCustomer = new B2BCustomer(customer);
+			B2BCustomers.add(b2BCustomer);
+		}
+		map.put("B2BVendors", B2BVendors);
+		map.put("B2BCustomers", B2BCustomers);
+		return map;
+	}
+
 }

+ 556 - 1
src/main/webapp/resources/js/index/app.js

@@ -131,6 +131,16 @@ define(['toaster', 'charts', 'ngTable', 'common/services', 'common/directives',
             url: "/tender",
             templateUrl: "static/tpl/index/purc/tenderlist.html",
             controller: 'PurcTenderCtrl'
+            /* 招标答疑列表 */
+        }).state('purc.tenderanswerlist', {
+            url: "/tender/answer",
+            templateUrl: "static/tpl/index/purc/tender_answer_list.html",
+            controller: 'PurcTenderAnswerListCtrl'
+            /* 招标答疑详情 */
+        }).state('purc.tenderanswerdetail', {
+            url: "/tender/answer/:id",
+            templateUrl: "static/tpl/index/purc/tender_answer_detail.html",
+            controller: 'PurcTenderAnswerDetailCtrl'
         }).state('purc.waiting.tenderlist', {
             url: "/tender",
             templateUrl: "static/tpl/index/purc/tenderlist.html",
@@ -225,6 +235,16 @@ define(['toaster', 'charts', 'ngTable', 'common/services', 'common/directives',
             url: "/tender",
             templateUrl: "static/tpl/index/sale/tenderlist.html",
             controller: 'SaleTenderCtrl'
+            /* 招标提问列表 */
+        }).state('sale.tenderquestionlist', {
+            url: "/tender/question",
+            templateUrl: "static/tpl/index/sale/tender_question_list.html",
+            controller: 'SaleTenderQuestionListCtrl'
+            /* 招标提问详情 */
+        }).state('sale.tenderquestiondetail', {
+            url: "/tender/question/:id",
+            templateUrl: "static/tpl/index/sale/tender_question_detail.html",
+            controller: 'SaleTenderQuestionDetailCtrl'
         }).state('sale.todo.tenderlist', {
             url: "/tender",
             templateUrl: "static/tpl/index/sale/tenderlist.html",
@@ -17549,7 +17569,7 @@ define(['toaster', 'charts', 'ngTable', 'common/services', 'common/directives',
             // var maxDate = angular.copy($scope.tender.publishDate);
             // maxDate = maxDate.setDate(maxDate.getDate() - 1);
             if ($scope.tender.publishDate instanceof Date) {
-                var maxDate = new Date($scope.tender.publishDate.getTime() - 1); // 不能选同一天
+                var maxDate = new Date($scope.tender.publishDate.getTime() - 24 * 60 * 60 * 1000 - 1); // 至少提前两天
             }
             return $scope.tender.publishDate ? $filter('date')(maxDate, 'yyyy-MM-dd') : "";
         };
@@ -18024,6 +18044,445 @@ define(['toaster', 'charts', 'ngTable', 'common/services', 'common/directives',
 
     }]);
 
+    /**
+     *  招标提问列表
+     *
+     */
+    app.controller('SaleTenderQuestionListCtrl', ['$scope', '$filter', 'SaleTenderQuestion', 'ngTableParams', 'toaster', 'BaseService', '$stateParams', '$modal', '$rootScope', 'AccountEnterprise',
+        function ($scope, $filter, SaleTenderQuestion, ngTableParams, toaster, BaseService, $stateParams, $modal, $rootScope, AccountEnterprise) {
+            BaseService.scrollBackToTop();
+            if ($rootScope.active) {
+                $scope.active = $rootScope.active;
+                $rootScope.active = null;
+            } else {
+                $scope.active = 'todo';
+            }
+            $scope.searchStatus = false;
+
+            /**
+             * 改变类型
+             */
+            var getTypeCondition = function (zone, condition) {
+                if (zone == -1) {
+                    condition.ifOpen = null;
+                } else if (zone == 1) {
+                    condition.ifOpen = 1;
+                } else {
+                    condition.ifOpen = 0;
+                }
+            };
+
+            $scope.dateZoneText = '不限';
+            $scope.typeText = '全部';
+            $scope.deliveryZoneText = '不限';
+            $scope.condition = {dateZone: 1, deliveryZone: -1, type: -1};
+
+            /* 时间筛选初始化*/
+            var fromDate = new Date();
+            var toDate = new Date();
+            fromDate.setMonth(fromDate.getMonth() - 1);
+            fromDate.setHours(0, 0, 0, 0);
+            toDate.setHours(23, 59, 59, 999);
+            $scope.condition.dateFrom = fromDate;
+            $scope.condition.dateTo = toDate;
+
+            $scope.changeDateZone = function (zone) {
+                $scope.condition.dateZone = zone;
+                $scope.dateZoneText = zone == 1 ? '最近一个月' : (zone == 3 ? '最近三个月' : (zone == 6 ? '最近六个月' : '自定义'));
+                $scope.condition.$dateZoneOpen = false;
+                getDateCondition(zone, $scope.condition);
+                $scope.tableParams.page(1);
+                $scope.tableParams.reload();
+            };
+            $scope.changeDeliveryZone = function (zone) {
+                $scope.condition.deliveryZoneText = zone;
+                $scope.deliveryZoneText = typeof zone == 'undefined' ? '不限' : (zone == -1 ? '不限' : (zone == 1 ? '一个月内' : '两个月内'));
+                $scope.condition.$delievryZoneOpen = false;
+                getDelveryCondition(zone, $scope.condition);
+                $scope.tableParams.page(1);
+                $scope.tableParams.reload();
+            };
+
+            $scope.changeType = function (type) {
+                $scope.condition.type = type;
+                $scope.typeText = typeof type == 'undefined' ? '全部' : (type == -1 ? '全部' : (type == 1 ? '公开' : '指定'));
+                getTypeCondition(type, $scope.condition);
+                $scope.tableParams.reload();
+            };
+
+            $scope.setActive = function (state) {
+                if ($scope.active != state) {
+                    $scope.active = state;
+                    if ($scope.tableParams.page() == 1)
+                        $scope.tableParams.reload();
+                    else
+                        $scope.tableParams.page(1);
+                }
+            };
+
+            //TODO 增加直接从数据库取方法之后修改
+            var getService = function () {
+                if ($scope.searchStatus) {
+                    return SaleTenderQuestion;
+                }
+                return SaleTenderQuestion;
+            };
+
+            $scope.tableParams = new ngTableParams({
+                page: 1,
+                count: 20,
+                sorting: {
+                    'id': 'desc'
+                }
+            }, {
+                total: 0,
+                counts: [5, 10, 25, 50],
+                getData: function ($defer, params) {
+                    $scope.loading = true;
+                    var pageParams = params.url();
+                    var realActive = {};
+                    pageParams.searchFilter = { // 筛选条件
+                        keyword: $scope.keyword,
+                        fromDate: getDateTime($scope.condition.dateFrom),
+                        endDate: getDateTime($scope.condition.dateTo)
+                    };
+                    AccountEnterprise.get({}, function (data) {
+                        $scope.currentEn = data;
+                    });
+                    getService()[getState($scope.active)].call(null, BaseService.parseParams(pageParams), function (page) {
+                        $scope.loading = false;
+                        params.total(page.totalElement);
+                        $defer.resolve(page.content);
+                        // $scope.keywordXls = angular.copy($scope.keyword); // 保存当前取值的关键词  做导出时需要的字段
+                    }, function (response) {
+                        $scope.loading = false;
+                        toaster.pop('error', '数据加载失败', response.data);
+                    });
+                }
+            });
+
+            //TODO 获得各分类未阅读数量
+
+            //TODO 设置单据已读
+
+            $scope.openDatePicker = function ($event, item, openParam) {
+                $event.preventDefault();
+                $event.stopPropagation();
+                item[openParam] = !item[openParam];
+            };
+
+            $scope.openFilterDatePicker = function ($event, item, openParam) {
+                $event.preventDefault();
+                $event.stopPropagation();
+                item[openParam] = !item[openParam];
+                if ($scope.condition.dateFrom && $scope.condition.dateTo && !item[openParam]) {
+                    $scope.tableParams.reload();
+                }
+            };
+
+            $scope.parseDate = function (dateStr) {
+                if (dateStr)
+                    return Date.parse(dateStr, 'yyyy-MM-dd');
+                return new Date();
+            };
+
+
+            // 选择查找日期
+            $scope.onDateCondition = function () {
+                $scope.tableParams.page(1);
+                $scope.tableParams.reload();
+            };
+
+            // 搜索框回车
+            $scope.onSearch = function (keyword) {
+                // 每次搜索重置获取数据方法
+                $scope.searchMethod = false;
+                if(keyword != null && keyword != '') {
+                    $scope.searchMethod = true;
+                }
+                $scope.tableParams.page(1);
+                $scope.tableParams.reload();
+            };
+
+        }]);
+
+    /**
+     * 投标单提问单详情
+     */
+    app.controller('SaleTenderQuestionDetailCtrl', ['$scope', 'toaster', 'BaseService', 'SaleTenderQuestion', '$stateParams'
+        , function($scope, toaster, BaseService, SaleTenderQuestion, $stateParams){
+        BaseService.scrollBackToTop();
+
+        $scope.loading = true;
+        var loadData = function () {
+            SaleTenderQuestion.getDetail({id: $stateParams.id}, function(data){
+                $scope.loading = false;
+                $scope.question = data;
+            } , function (response) {
+                $scope.loading = false;
+                toaster.pop('error', '数据加载失败');
+            });
+        };
+        loadData();
+
+    }]);
+
+    /**
+     *  招标答疑列表
+     *
+     */
+    app.controller('PurcTenderAnswerListCtrl', ['$scope', '$filter', 'SaleTenderQuestion', 'ngTableParams', 'toaster', 'BaseService', '$stateParams', '$modal', '$rootScope', 'AccountEnterprise',
+        function ($scope, $filter, SaleTenderQuestion, ngTableParams, toaster, BaseService, $stateParams, $modal, $rootScope, AccountEnterprise) {
+            BaseService.scrollBackToTop();
+            if ($rootScope.active) {
+                $scope.active = $rootScope.active;
+                $rootScope.active = null;
+            } else {
+                $scope.active = 'todo';
+            }
+            $scope.searchStatus = false;
+
+            /**
+             * 改变类型
+             */
+            var getTypeCondition = function (zone, condition) {
+                if (zone == -1) {
+                    condition.ifOpen = null;
+                } else if (zone == 1) {
+                    condition.ifOpen = 1;
+                } else {
+                    condition.ifOpen = 0;
+                }
+            };
+
+            /**
+             * 当前页面状态按钮过滤
+             */
+            var getAnswer = function (active) {
+                var fn = 'getAllAnswer';
+                switch (active) {
+                    case 'done':
+                        fn = 'getDoneAnswer';
+                        break;
+                    case 'todo':
+                        fn = 'getTodoAnswer';
+                        break;
+                }
+                return fn;
+            };
+
+            $scope.dateZoneText = '不限';
+            $scope.typeText = '全部';
+            $scope.deliveryZoneText = '不限';
+            $scope.condition = {dateZone: 1, deliveryZone: -1, type: -1};
+
+            /* 时间筛选初始化*/
+            var fromDate = new Date();
+            var toDate = new Date();
+            fromDate.setMonth(fromDate.getMonth() - 1);
+            fromDate.setHours(0, 0, 0, 0);
+            toDate.setHours(23, 59, 59, 999);
+            $scope.condition.dateFrom = fromDate;
+            $scope.condition.dateTo = toDate;
+
+            $scope.changeDateZone = function (zone) {
+                $scope.condition.dateZone = zone;
+                $scope.dateZoneText = zone == 1 ? '最近一个月' : (zone == 3 ? '最近三个月' : (zone == 6 ? '最近六个月' : '自定义'));
+                $scope.condition.$dateZoneOpen = false;
+                getDateCondition(zone, $scope.condition);
+                $scope.tableParams.page(1);
+                $scope.tableParams.reload();
+            };
+            $scope.changeDeliveryZone = function (zone) {
+                $scope.condition.deliveryZoneText = zone;
+                $scope.deliveryZoneText = typeof zone == 'undefined' ? '不限' : (zone == -1 ? '不限' : (zone == 1 ? '一个月内' : '两个月内'));
+                $scope.condition.$delievryZoneOpen = false;
+                getDelveryCondition(zone, $scope.condition);
+                $scope.tableParams.page(1);
+                $scope.tableParams.reload();
+            };
+
+            $scope.changeType = function (type) {
+                $scope.condition.type = type;
+                $scope.typeText = typeof type == 'undefined' ? '全部' : (type == -1 ? '全部' : (type == 1 ? '公开' : '指定'));
+                getTypeCondition(type, $scope.condition);
+                $scope.tableParams.reload();
+            };
+
+            $scope.setActive = function (state) {
+                if ($scope.active != state) {
+                    $scope.active = state;
+                    if ($scope.tableParams.page() == 1)
+                        $scope.tableParams.reload();
+                    else
+                        $scope.tableParams.page(1);
+                }
+            };
+
+            //TODO 增加直接从数据库取方法之后修改
+            var getService = function () {
+                if ($scope.searchStatus) {
+                    return SaleTenderQuestion;
+                }
+                return SaleTenderQuestion;
+            };
+
+            $scope.tableParams = new ngTableParams({
+                page: 1,
+                count: 20,
+                sorting: {
+                    'id': 'desc'
+                }
+            }, {
+                total: 0,
+                counts: [5, 10, 25, 50],
+                getData: function ($defer, params) {
+                    $scope.loading = true;
+                    var pageParams = params.url();
+                    var realActive = {};
+                    pageParams.searchFilter = { // 筛选条件
+                        keyword: $scope.keyword,
+                        fromDate: getDateTime($scope.condition.dateFrom),
+                        endDate: getDateTime($scope.condition.dateTo)
+                    };
+                    AccountEnterprise.get({}, function (data) {
+                        $scope.currentEn = data;
+                    });
+                    getService()[getAnswer($scope.active)].call(null, BaseService.parseParams(pageParams), function (page) {
+                        $scope.loading = false;
+                        params.total(page.totalElement);
+                        $defer.resolve(page.content);
+                        // $scope.keywordXls = angular.copy($scope.keyword); // 保存当前取值的关键词  做导出时需要的字段
+                    }, function (response) {
+                        $scope.loading = false;
+                        toaster.pop('error', '数据加载失败', response.data);
+                    });
+                }
+            });
+
+            //TODO 获得各分类未阅读数量
+
+            //TODO 设置单据已读
+
+            $scope.openDatePicker = function ($event, item, openParam) {
+                $event.preventDefault();
+                $event.stopPropagation();
+                item[openParam] = !item[openParam];
+            };
+
+            $scope.openFilterDatePicker = function ($event, item, openParam) {
+                $event.preventDefault();
+                $event.stopPropagation();
+                item[openParam] = !item[openParam];
+                if ($scope.condition.dateFrom && $scope.condition.dateTo && !item[openParam]) {
+                    $scope.tableParams.reload();
+                }
+            };
+
+            $scope.parseDate = function (dateStr) {
+                if (dateStr)
+                    return Date.parse(dateStr, 'yyyy-MM-dd');
+                return new Date();
+            };
+
+
+            // 选择查找日期
+            $scope.onDateCondition = function () {
+                $scope.tableParams.page(1);
+                $scope.tableParams.reload();
+            };
+
+            // 搜索框回车
+            $scope.onSearch = function (keyword) {
+                // 每次搜索重置获取数据方法
+                $scope.searchMethod = false;
+                if(keyword != null && keyword != '') {
+                    $scope.searchMethod = true;
+                }
+                $scope.tableParams.page(1);
+                $scope.tableParams.reload();
+            };
+
+        }]);
+
+    /**
+     * 招标答疑单详情
+     */
+    app.controller('PurcTenderAnswerDetailCtrl', ['$scope', 'toaster', 'BaseService', 'SaleTenderQuestion', '$stateParams', '$modal'
+        , function($scope, toaster, BaseService, SaleTenderQuestion, $stateParams, $modal){
+            BaseService.scrollBackToTop();
+
+            $scope.loading = true;
+            var loadData = function () {
+                SaleTenderQuestion.getAnswerDetail({id: $stateParams.id}, function(data){
+                    $scope.loading = false;
+                    $scope.answer = data;
+                    var now = new Date();
+                    if ($scope.answer.questionEndDate < now.getTime()) {
+                        $scope.answer.questionEnd = 1;
+                    } else {
+                        $scope.answer.questionEnd = 0;
+                    }
+                } , function (response) {
+                    $scope.loading = false;
+                    toaster.pop('error', '数据加载失败');
+                });
+            };
+            loadData();
+
+            // 回答
+            $scope.sendAnswer = function (){
+                var modalInstance = $modal.open({
+                    animation: true,
+                    templateUrl: 'static/tpl/index/purc/tender_answer.html',
+                    controller: 'PurcTenderAnswerCtrl',
+                    size: 'lg',
+                    resolve: {
+                        answer: function () {
+                            return $scope.answer;
+                        }	//传递当前答疑单到模态框Controller
+                    }
+                });
+                modalInstance.result.then(function () {
+                    toaster.pop('success', '答疑成功');
+                }, function () {
+
+                });
+            };
+
+        }]);
+
+    /**
+     * 招标单答疑
+     */
+    app.controller('PurcTenderAnswerCtrl', ['$scope', 'answer','$modalInstance', '$upload', 'toaster', function($scope, answer, $modalInstance, $upload ,toaster){
+        $scope.answer = answer;
+
+        $scope.cancel = function() {
+            $modalInstance.dismiss();
+        };
+
+        //确认回答
+        $scope.ok = function (form) {
+            $scope.loading = true;
+            var files = form.attachFile.$viewValue, file = files && files.length > 0 ? files[0] : null;
+            $upload.upload({
+                url: 'tender/question/answer/send',
+                method: 'POST',
+                file: file,
+                data: {
+                    json: $scope.answer
+                }
+            }).success(function (data) {
+                $scope.loading = false;
+                $modalInstance.close('success');
+            }).error(function (data) {
+                $scope.loading = false;
+                toaster.pop('error', '错误', '出现异常,答疑失败');
+            });
+        };
+    }]);
+
     /**
      *  平台公开招标
      *
@@ -18229,6 +18688,46 @@ define(['toaster', 'charts', 'ngTable', 'common/services', 'common/directives',
             toaster.pop('error', '数据加载失败', response.data);
         });
 
+        // 提问
+        $scope.sendQuestion = function (){
+            var modalInstance = $modal.open({
+                animation: true,
+                templateUrl: 'static/tpl/index/sale/tender_question.html',
+                controller: 'SaleTenderQuestionCtrl',
+                size: 'lg',
+                resolve: {
+                    saleTender: function () {
+                        return $scope.saleTender;
+                    }	//传递当前投标单到模态框Controller
+                }
+            });
+            modalInstance.result.then(function () {
+                toaster.pop('success', '提问成功');
+            }, function () {
+
+            });
+        };
+
+        // // 提问记录
+        // $scope.showQuestionHistory = function (){
+        //     var modalInstance = $modal.open({
+        //         animation: true,
+        //         templateUrl: 'static/tpl/index/sale/tender_question_history.html',
+        //         controller: 'saleTenderQuestionHistoryCtrl',
+        //         size: 'lg',
+        //         resolve: {
+        //             saleTender: function () {
+        //                 return $scope.saleTender;
+        //             }	//传递当前投标单到模态框Controller
+        //         }
+        //     });
+        //     modalInstance.result.then(function () {
+        //
+        //     }, function () {
+        //
+        //     });
+        // };
+
         $scope.upload = function (myFile) {  // 上传附件
             var file = $scope.myFile, file = file && file.length > 0 ? file : null;
             $upload.upload({
@@ -18364,6 +18863,62 @@ define(['toaster', 'charts', 'ngTable', 'common/services', 'common/directives',
         };
     }]);
 
+    /**
+     * 投标单提问
+     */
+    app.controller('SaleTenderQuestionCtrl', ['$scope', 'saleTender','$modalInstance', '$upload', 'toaster', function($scope, saleTender, $modalInstance, $upload ,toaster){
+        $scope.saleTender = saleTender;
+
+        // 当前日期,用作新增提问
+        $scope.currentDay = new Date();
+
+        $scope.question = {
+            inDate : null,
+            replyDate : null,
+            topic : null,
+            status : null,
+            content : null,
+            questionAttaches : []
+        };
+
+        $scope.cancel = function() {
+            $modalInstance.dismiss();
+        };
+
+        //确认提问
+        $scope.ok = function (form) {
+            $scope.loading = true;
+            var files = form.attachFile.$viewValue, file = files && files.length > 0 ? files[0] : null;
+            $upload.upload({
+                url: 'tender/question/send/' + $scope.saleTender.id,
+                method: 'POST',
+                file: file,
+                data: {
+                    json: $scope.question
+                }
+            }).success(function (data) {
+                $scope.loading = false;
+                $modalInstance.close('success');
+            }).error(function (data) {
+                $scope.loading = false;
+                toaster.pop('error', '错误', '出现异常,提问失败');
+            });
+        };
+    }]);
+
+    // /**
+    //  * 当前投标单提问记录
+    //  */
+    // app.controller('saleTenderQuestionHistoryCtrl', ['$scope', 'saleTender','$modalInstance', 'toaster', function($scope, saleTender, $modalInstance, toaster){
+    //     $scope.saleTender = saleTender;
+    //
+    //
+    //     $scope.cancel = function() {
+    //         $modalInstance.dismiss();
+    //     };
+    //
+    // }]);
+
     /**
      * 公开招标转投标单
      */

+ 44 - 0
src/main/webapp/resources/js/index/services/Purc.js

@@ -637,6 +637,50 @@ define([ 'ngResource'], function() {
 				method: 'GET'
 			}
 		});
+    }]).factory('SaleTenderQuestion', ['$resource', function($resource) {
+        return $resource('tender/question', {}, {
+            getAll: {
+            },
+            getDone: {
+                params: {
+                    _state: 'done'
+                }
+            },
+            getTodo: {
+                params: {
+                    _state: 'todo'
+                }
+            },
+            getAllAnswer: {
+            	url: 'tender/question/purc'
+            },
+            getDoneAnswer: {
+                url: 'tender/question/purc',
+                params: {
+                    _state: 'done'
+                }
+            },
+            getTodoAnswer: {
+                url: 'tender/question/purc',
+                params: {
+                    _state: 'todo'
+                }
+            },
+			getDetail: {
+            	url: 'tender/question/:id',
+				method: 'GET',
+				params: {
+            		id: 'id'
+				}
+			},
+            getAnswerDetail: {
+                url: 'tender/question/answer/:id',
+                method: 'GET',
+                params: {
+                    id: 'id'
+                }
+            }
+        });
 	}]).factory('PurcInquiryMould', ['$resource', function($resource) {
 		return $resource('sale/mould/:id', {}, {
 			getAll: {

+ 0 - 6
src/main/webapp/resources/tpl/index/home/pagingRelease.html

@@ -194,12 +194,6 @@
                     <a style="color: #5078cb;" ng-if="releaseDetail.pagingRelease.url != null" ng-click="setOneRead(releaseDetail.id)" href="{{::releaseDetail.pagingRelease.url}}" title="查看详情">{{releaseDetail.pagingRelease.context}}</a>
                     <span ng-if="releaseDetail.pagingRelease.url == null">{{::releaseDetail.pagingRelease.context}}</span>
                 </div>
-                <!--<div style="text-align: left;" ng-if="releaseDetail.pagingRelease.table == 'purc$orders' && releaseDetail.pagingRelease.category == 'purc' && releaseDetail.pagingRelease.sourceId != null">-->
-                    <!--<a style="color: #5078cb;" ng-click="setOneRead(releaseDetail.id)" ui-sref="purc.order_detail({id:releaseDetail.pagingRelease.sourceId})">{{releaseDetail.pagingRelease.context}}</a>-->
-                <!--</div>-->
-                <!--<div style="text-align: left;" ng-if="releaseDetail.pagingRelease.table != 'purc$orders'">-->
-                    <!--{{releaseDetail.pagingRelease.context}}-->
-                <!--</div>-->
             </td>
             <td ng-hide="active == 'todo'">
                 <div>{{releaseDetail.readDate | date:'yyyy-MM-dd HH:mm'}}</div>

+ 82 - 0
src/main/webapp/resources/tpl/index/purc/tender_answer.html

@@ -0,0 +1,82 @@
+<style>
+	.saleTender label{
+		font-weight: inherit;
+	}
+	.modal-body .row{
+		line-height: 34px;
+	}
+	.modal-content{
+		width:1080px;
+		margin-top: 50px;
+	}
+	.saleTender .modal-body .row{
+		margin: 0;
+		line-height: 34px;
+		margin-bottom: 10px;
+	}
+	.saleTender .modal-body .row .form-control{
+		height: 34px;
+		border: #bfbfbf 1px solid;
+		font-size: 14px;
+	}
+	.input-group-addon{
+		width: 60px;
+		padding: 0;
+		font-size: 12px;
+		background: #fff;
+	}
+	.input-group[class*="col-"]{
+		float: left;
+	}
+	.modal-footer{
+		border-top: none;
+		margin-right: 18px;
+		padding: 0 15px 15px;
+	}
+	.saleTender .col {
+		padding-left: 5px;
+		padding-right: 5px;
+		line-height: 30px;
+	}
+
+	/* 读取显示无法修改的数据 */
+	.unchanged-info {
+		color: #969595;
+		overflow: hidden;
+	}
+
+</style>
+<div class="loading" ng-class="{'in': loading}">
+	<i></i>
+</div>
+<div class="modal-header">
+	<h3 class="modal-title">招标答疑单</h3>
+</div>
+<form class="answer" name="answerForm" ng-submit="ok(answerForm)" novalidate>
+	<div class="modal-body" style="min-height: 500px;padding: 25px 25px 10px 25px;">
+		<div class="row">
+			<label class="col-md-2 col-sm-2 col">招标编号:</label>
+			<div class="col-md-4 col-sm-4 col unchanged-info" title="{{answer.tenderCode}}">{{answer.tenderCode}}</div>
+			<label class="col-md-2 col-sm-2 col">招标标题:</label>
+			<div class="col-md-4 col-sm-4 col unchanged-info" title="{{answer.tenderTitle}}">{{answer.tenderTitle}}</div>
+		</div>
+		<div class="row">
+			<label class="col-md-2 col-sm-2 col">回复备注:</label>
+			<div class="col-md-10 col-sm-10 col">
+				<input ng-model="answer.remark" class="form-control input-sm" type="text" required>
+			</div>
+		</div>
+		<div class="row">
+			<label class="col-md-2 col-sm-2 col">回复文件:</label>
+			<div class="col-md-10 col-sm-10 col">
+				<input type="file" ng-model="attachFile" ng-file-select required
+					ng-multiple="false" class="form-control input-sm" name="attachFile"
+					id="attachFile">
+			</div>
+		</div>
+	</div>
+	<div class="modal-footer">
+		<button class="btn btn-primary" type="submit" ng-disabled="!answerForm.$dirty && answerForm.$invalid">确认</button>
+		<button class="btn btn-warning" ng-click="cancel()" type="button">取消</button>
+	</div>
+</form>

+ 295 - 0
src/main/webapp/resources/tpl/index/purc/tender_answer_detail.html

@@ -0,0 +1,295 @@
+<!-- 答疑单详情 -->
+<style>
+
+    /* 标题 */
+    .bid-label {
+        height: 30px;
+        margin-left: 10px;
+        margin-right: 10px;
+        background-color: #e8e8e8;
+        box-shadow: 0 0 5px #6f6f6f;
+        border-top-right-radius: 20px;
+    }
+    /* 主体 */
+    .purc-bid {
+        line-height: 2;
+        font-size: 14px;
+    }
+    .purc-bid .row {
+        margin-left: 0px;
+        margin-right: 0px;
+        padding-left: 15px;
+        padding-right: 15px;
+    }
+    .bid-content {
+        background-color: #fff;
+    }
+
+    .bid-content>div>div {
+        margin-top: 3px;
+        margin-bottom: 3px;
+    }
+
+    /* 读取显示无法修改的数据 */
+    .unchanged-info {
+        color: #969595;
+        overflow: hidden;
+    }
+    /* 二级标题栏 */
+    .title-div {
+        font-size: 14px;
+        font-weight: 600;
+        padding-left: 30px;
+        height: 50px;
+        padding-top: 11px;
+    }
+
+    /* 输入框前描述 */
+    .bid-desc {
+        width: 100px;
+        float: left;
+    }
+    /* 输入框 */
+    .bid-input {
+        border: none;
+        border-bottom: 1px solid #323232;
+        text-align: center;
+    }
+    .bid-input:focus{
+        outline:none;
+        border-bottom: 1px solid #5078cb;
+    }
+
+
+    /* 基本信息 */
+    .base-info {
+        border-bottom: 1px solid #e8e8e8;
+        padding-bottom: 30px;
+        padding-top: 20px;
+        margin-bottom: 0; /* 去除index中公共样式影响 */
+    }
+
+    .prod-info {
+        border-bottom: 1px solid #e8e8e8;
+        padding-bottom: 30px;
+        padding-top: 20px;
+    }
+
+    /* 附件上传 */
+    .purc-tender .base-info .attach-upload {
+        display: inline;
+    }
+    .purc-tender .base-info .attach-upload input {
+        height: 100px;
+        width: 100px;
+        margin: 6px 0 0 100px;
+        opacity: 0;
+        z-index: 1;
+        position: relative;
+    }
+    .purc-tender .base-info .attach-upload input:hover {
+        cursor: pointer;
+    }
+    .fileInputContainer{
+        height:100px;
+        background-image: url('static/img/tender/upload.png');
+        position:relative;
+        width: 100px;
+        margin-left: 100px;
+        margin-top: 20px;
+    }
+    .fileInput{
+        height:100px;
+        font-size: 100px;
+        position:absolute;
+        margin-left: 100px;
+        margin-top: 20px;
+        right:0;
+        top:0;
+        opacity: 0;
+        filter:alpha(opacity=0);
+        cursor:pointer;
+    }
+
+    .attach-file {
+        margin-left: 130px;
+        width: 400px;
+    }
+
+    /* 右下角按钮 */
+    .div-btn-answer {
+        background-color: #fff;
+    }
+    .div-btn-answer .btn-answer>button {
+        width: 94px;
+        height: 36px;
+        font-size: 14px;
+        font-family: "Microsoft Yahei Regular";
+        border-radius: 0;
+    }
+
+    /* 日期选择器 */
+    .purc-bid .date-picker input {
+        border-radius: 0;
+        border: 1px solid #5078cb;
+        border-right: none;
+        font-size: 12px;
+    }
+    .purc-bid .date-picker span .btn-open {
+        color: #fff;
+        background-color: #5078cb;
+        border-radius: 0;
+        border: 1px solid #5078cb;
+        border-left: none;
+    }
+
+    /* 修改本页内btn的样式 及datepicker中的btn-success的样式 */
+    .purc-bid .date-picker .btn {
+        border-radius: 0;
+    }
+
+    .purc-bid .date-picker .btn-success {
+        background-color: #327EBE;
+    }
+    .purc-bid .date-picker ul {
+        border-radius: 0;
+    }
+    .purc-bid .date-picker ul div:focus {
+        outline: none;
+        border-radius: 0;
+        border: none;
+    }
+
+
+
+    .com_head{width:100%;height:40px;line-height:42px;background:url(static/img/comm_bg01.png) no-repeat center;background-size: 100%;}
+    .com_head span{margin-left:20px;color:#000;font-size:14px;}
+    .com_head a{color:#327ebe;float:right;margin-right:40px;font-size: 14px;}
+    .com_head a i{margin-left: 5px;line-height: 40px;}
+    .com_head a:hover{color: #d2272d;}
+
+    .com_title{width:100%;margin:0px auto;height:40px;line-height:40px;font-size:14px;color:#323232;background:#f5f5f5;}
+    .com_title font{color:#327ebe;}
+
+
+    .com_title01{height: 50px;line-height:50px;width:100%;border-bottom:#3578ba 1px dotted;border-top:#e8e8e8 1px solid;margin-top: -4px;} /*  这里修改过 margin-top*/
+    .com_title01 span{margin-left:20px;font-size: 14px;line-height: 50px;color: #555;font-weight: bold;}
+
+    .com_title01  a {
+        color: #5078cb;
+    }
+    .com_title01  a:hover {
+        cursor: pointer;
+        color: #55b6ff;
+    }
+
+    /*投标单*/
+    .tender-list,.tender-list02{width:100%;margin: 0 auto;background: #fff;}
+    .tender-list dl{width: 100%;margin:0 auto;}
+    .tender-list dl dt{width: 100%;margin:0 auto;height: 40px;}
+    .tender-list dl dt span{height: 40px;line-height: 48px;display: inline-block;color: #999;}
+    .tender-list dl dd{width: 100%;margin:0 auto;height: 100px;border-bottom: #ccc 1px dashed;overflow: hidden;}
+    .tender-list dl dd:hover{border: #d32526 1px solid;}
+    .tender-list dl dd span{height: 100px;line-height: 50px;display: inline-block;}
+    .tender-list dl span{width:10.6%;font-size: 14px;float: left;text-align: center;}
+    .tender-list dl span.wid01{width:25%;}
+    .tender-list dl span.wid01 p{font-size: 14px;line-height: 22px;text-align: left;margin: 0;}
+    .tender-list dl dd span.wid01{margin-top: 15px;}
+    .tender-list .com_title01 em,.tender-list02 .com_title01 em{margin-left: 5px;font-size: 16px;color: #f00;position: relative;top: 3px;}
+
+    /* 点击变输入框 */
+    .editAble{ width: 100%; height: 34px; border: none; font-size: 14px; text-align:center;line-height:34px;}
+
+    .not-answer {
+        text-align: center;
+        color: #969595;
+        margin-top: 20px;
+        font-size: large;
+    }
+</style>
+
+<div class="ng-scope">
+    <form name="bidForm">
+        <div class="purc-bid">
+            <div class="list-unstyled">
+                <div class="com_head">
+                    <span>投标答疑单</span>
+                </div>
+            </div>
+            <div class="bid-content ng-scope">
+                <div class="title-div" style="border-bottom: 1px dashed #327ebe;">
+                    <span class="col-xs-11">基本信息</span>&nbsp;
+                    <span ng-if="answer.status == 201" class="block">
+                        <span class="text-trans success">已回复</span>
+                    </span>
+                    <span ng-if="answer.status == 200" class="block">
+                        <span class="text-trans todo">待回复</span>
+                    </span>
+                </div>
+                <div class="row base-info">
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">招标编号:</div>
+                        <div class="unchanged-info">{{answer.tenderCode}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">招标项目:</div>
+                        <div class="unchanged-info">{{answer.tenderTitle}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">提问截止时间:</div>
+                        <div class="unchanged-info">{{answer.questionEndDate | date: 'yyyy-MM-dd'}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">答疑单号:</div>
+                        <div class="unchanged-info">{{answer.code}}</div>
+                    </div>
+                    <div class = "col-xs-12" ng-if="answer.remark">
+                        <div class="bid-desc">答疑备注:</div>
+                        <div class="unchanged-info">{{answer.remark}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">答疑单号:</div>
+                        <div class="unchanged-info">{{answer.code}}</div>
+                    </div>
+                </div>
+                <div class="wrap">
+                    <div class="content">
+                        <div class="tender-list">
+                            <div class="com_title01"><span>提问信息</span><em>*</em></div>
+                            <dl>
+                                <dt>
+                                    <span>序号</span>
+                                    <span class="wid01">提问信息</span>
+                                    <span class="wid01">提问企业</span>
+                                    <span>提问日期</span>
+                                    <span class="wid01">提问附件</span>
+                                </dt>
+                                <dd ng-repeat="question in answer.purchaseTenderQuestions | orderBy: 'id'">
+                                    <span>{{$index + 1}}</span>
+                                    <span class="wid01">
+                                        <p>单号:{{question.code}}</p>
+                                        <p>主题:{{question.topic}}</p>
+                                        <p>内容:{{question.content}}</p>
+                                    </span>
+                                    <span class="wid01">{{question.vendor.enName}}</span>
+                                    <span>{{question.inDate | date: 'yyyy-MM-dd'}}</span>
+                                    <span class="wid01" ng-show="question.questionAttaches.length > 0">
+                                        <p><a ng-repeat="attach in question.questionAttaches" class="" style="padding-left: 0; color: #5078cb;" href="file/{{attach.id}}">
+                                            {{::attach.name}}
+                                        </a></p>
+                                    </span>
+                                </dd>
+                            </dl>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-xs-12 div-btn-answer" style="padding: 30px;">
+                    <div class="col-xs-2 pull-right btn-answer">
+                        <button type="button" class="btn btn-primary" ng-if="answer.remark == null" ng-disabled="answer.questionEnd != 1" title="答疑截止时间之后,可以回复提问" ng-click="sendAnswer()">回答疑问</button>
+                        <button type="button" class="btn btn-info" ng-if="answer.remark != null" ng-disabled="answer.questionEnd != 1" title="答疑截止时间之后,可以回复提问" ng-click="sendAnswer()">修改回答</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </form>
+</div>

+ 399 - 0
src/main/webapp/resources/tpl/index/purc/tender_answer_list.html

@@ -0,0 +1,399 @@
+<style>
+    /* 顶部搜索框 */
+    .top-nav {
+        margin-bottom: 10px;
+    }
+
+    .top-nav #search_input {
+        height: 36px;
+        font-size: 16px;
+        font-family: '微软雅黑';
+        border: 1px solid #327EBE;
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+        text-align: center;
+    }
+
+    .top-nav #search_btn {
+        height: 36px;
+        padding-top: 0;
+        padding-bottom: 0;
+        font-size: 16px;
+        background: #327EBE;
+        border: 1px solid #327EBE;
+        color: #fff;
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+    }
+
+    /* 主内容区 */
+    .main-content {
+        font-size: 14px;
+    }
+
+    /* 选项菜单 招标单按钮*/
+    .div-menu .text-num {
+        color: rgb(211, 37, 38);
+        padding: 0 5px;
+    }
+
+    .btn-tender {
+        border-radius: 0;
+        width: 100%;
+        height: 40px;
+        font-size: 14px;
+    }
+
+    /* 选项按钮 */
+    /* 当前激活 */
+    .div-menu .menu-status .btn-selected {
+        background-color: #fff;
+        color: #D32526;
+        border: none;
+        border-bottom: 2px solid #D32526;
+        border-radius: 0;
+
+    }
+
+    .div-menu .menu-status .btn-selected:hover {
+        background-color: #f5f5f5;
+    }
+
+    .div-menu .btn-select {
+        background-color: #fff;
+        color: #000000;
+        border: none;
+        border-radius: 0;
+        height: 40px;
+        font-weight: 600;
+        padding: 0 20px 0 20px;
+        border-bottom: 2px solid #fff;
+    }
+
+    .div-menu {
+        border-bottom: 16px solid #f5f5f5;
+        height: 56px;
+    }
+
+    .div-menu .btn-select:hover {
+        border-bottom: 2px solid #D32526;
+    }
+
+    .div-menu .btn-select:focus {
+        border-bottom: 2px solid #D32526;
+    }
+
+    .div-menu .btn-select:first-child {
+        margin-left: 10px;
+    }
+
+    .div-menu > div:first-child .btn {
+        font-size: 16px;
+    }
+
+    /* 列表内容 */
+    .tender-table {
+        text-align: center;
+    }
+
+    .tender-table .header {
+        height: 50px;
+        background-color: #fff;
+        color: rgb(50, 50, 50);
+        border-bottom: 1px solid #e8e8e8;
+    }
+
+    .tender-table .header > th {
+        text-align: center;
+    }
+
+    .tender-table > tbody {
+        font-size: 14px;
+        color: #323232;
+        border: 1px solid transparent;
+    }
+
+    .tender-table > tbody.not-done > tr:nth-child(odd) {
+        height: 140px;
+    }
+
+    .tender-table > tbody.not-done > tr td div {
+        line-height: 25px;
+    }
+
+    .tender-table tbody.not-done > tr:nth-child(odd):hover {
+        border: 2px solid #D32526;
+
+    }
+
+    .tender-table > tbody.is-done:hover {
+        border: 2px solid #D32526;
+    }
+
+    .tender-table > tbody.is-done > tr:first-child {
+        background-color: #f5f5f5;
+        border-bottom: 1px solid #e8e8e8;
+    }
+
+    .tender-table > tbody.is-done > tr:first-child td {
+        padding: 10px 0;
+    }
+
+    .tender-table > tbody.is-done > tr {
+        border-bottom: 1px solid #e8e8e8;
+    }
+
+    .tender-table tbody.is-done > tr:last-child {
+        border-bottom: 1px solid #e8e8e8;
+
+    }
+
+    .tender-table tbody tr td a {
+        color: #327ebe;
+        /*border: #e8e8e8 1px solid;*/
+    }
+
+    .main-content .btn-group {
+        font-family: "Microsoft YaHei", "微软雅黑";
+        font-weight: 500;
+    }
+
+    .main-content .btn-group button {
+        font-weight: inherit;
+    }
+
+    .list-notnum {
+        text-align: left;
+        padding-left: 20px;
+    }
+
+    .list-notnum div {
+        padding-left: 5px;
+    }
+
+    .list-num {
+        text-align: right;
+    }
+
+    .pro-line-sty01 td div {
+        padding-left: 10px;
+    }
+
+    .pro-line-sty02 {
+        height: 120px;
+    }
+
+    .pro-line-sty02 td div {
+        line-height: 25px;
+    }
+
+    .main-content {
+        border: #e8e8e8 1px solid;
+    }
+
+    .div-menu {
+        border-bottom: 0;
+    }
+
+    #public .menu {
+        border-bottom: 0 !important;
+    }
+
+    .menu .new-dot {
+        width: 20px;
+        height: 20px;
+        line-height: 20px;
+        font-size: 12px;
+        color: #fff;
+        font-weight: inherit;
+        top: -2px;
+    }
+
+    /*2017年9月14日*/
+    /* 单据状态位置调整 */
+    .question-status {
+        margin-top: -20px;
+        right: 20px;
+    }
+</style>
+<link rel="stylesheet" href="static/css/public.css">
+<div class="loading in" ng-class="{'in': loading}">
+    <i></i>
+</div>
+<div id="public">
+    <!-- 顶部导航及搜索框 -->
+    <div class="pub-com_head">
+        <span>招标提问列表</span>
+        <div class="p-right">
+        </div>
+    </div>
+    <div class="menu condition block">
+        <div class="row">
+            <div class="col-xs-4">
+                <div class="btn-group btn-group-sm btn-group-justified">
+                    <div class="btn-group btn-group-sm">
+                        <button type="button" class="btn btn-default btn-line"
+                                ng-class="{'btn-info':active=='all'}" ng-click="setActive('all')">全部
+                            <b class="new-dot" ng-if="unread.all > 0">{{unread.all>99?'99+':unread.all}}</b>
+                        </button>
+                    </div>
+                    <div class="btn-group btn-group-sm">
+                        <button type="button" class="btn btn-default btn-line"
+                                ng-class="{'btn-info':active=='done'}" ng-click="setActive('done')">已回复
+                            <b class="new-dot"
+                               ng-if="unread.replied > 0">{{unread.replied>99?'99+':unread.replied}}</b>
+                        </button>
+                    </div>
+                    <div class="btn-group btn-group-sm">
+                        <button type="button" class="btn btn-default btn-line"
+                                ng-class="{'btn-info':active=='todo'}" ng-click="setActive('todo')">待回复
+                            <b class="new-dot"
+                               ng-if="unread.notReply > 0">{{unread.notReply>99?'99+':unread.notReply}}</b>
+                        </button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="block main-content">
+        <!-- 选项菜单和新增按钮 -->
+        <div class="block">
+            <div class="condition block">
+                <div class="search-bg condition block" style="padding: 10px 15px;">
+                    <div class="row">
+                        <div id="topSearch" style="float: left">
+                            <a ng-click="changeDateZone(1);condition.$open=false" title="最近一个月"
+                               ng-class="{'active':condition.dateZone=='1'}">最近一个月</a>
+                            <a ng-click="changeDateZone(3);condition.$open=false" title="最近三个月"
+                               ng-class="{'active':condition.dateZone=='3'}">最近三个月</a>
+                            <a ng-click="changeDateZone(6);condition.$open=false" title="最近六个月"
+                               ng-class="{'active':condition.dateZone=='6'}">最近六个月</a>
+                            <a ng-click="condition.$open=!condition.$open;changeDateZone(-1)" title="自定义"
+                               ng-class="{'active':condition.dateZone=='-1'}">自定义</a>
+                        </div>
+                        <div class="col-xs-6" style="float: right;">
+                            <div class="search">
+                                <div class="form-group form-group-sm has-feedback" dropdown auto-close="outsideClick"
+                                     on-toggle="searchAdvance=open">
+                                    <input type="search" class="form-control input-sm" ng-model="keyword"
+                                           ng-search="onSearch(keyword)" placeholder="输入单据编号、客户名称、物料名称搜索" style="width: 100%"/>
+                                    <a class="btn input-group-addon" ng-click="onSearch(keyword)">搜索</a>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="more-list more" ng-class="{'open': condition.$open}">
+                        <form class="form-inline">
+                            <div class="form-group ">
+                                <label>日期:</label>
+                                <div class="btn-group btn-menu" dropdown is-open="condition.$dateZoneOpen">
+                                    <ul class="dropdown-menu">
+                                        <li><a ng-click="changeDateZone(1)">一个月内</a></li>
+                                        <li><a ng-click="changeDateZone(6)">半年内</a></li>
+                                        <li><a ng-click="changeDateZone()">半年前</a></li>
+                                    </ul>
+                                </div>
+                                <div class="form-group input-group input-group-xs input-trigger">
+                                    <input type="text" ng-model="condition.dateFrom"
+                                           class="form-control" placeholder="从"
+                                           datepicker-popup="yyyy-MM-dd" is-open="condition.$fromOpened"
+                                           ng-required="true" max-date="condition.dateTo"
+                                           current-text="今天" clear-text="清除" close-text="关闭"
+                                           datepicker-options="{formatDayTitle: 'yyyy年M月', formatMonth: 'M月', showWeeks: false}"
+                                           ng-focus="openFilterDatePicker($event, condition, '$fromOpened')">
+                                    <span class="input-group-btn">
+							<button type="button" class="btn btn-default"
+                                    ng-click="openFilterDatePicker($event, condition, '$fromOpened')">
+								<i class="fa fa-calendar"></i>
+							</button>
+						</span>
+                                </div>
+                                <div class="form-group input-group input-group-xs input-trigger">
+                                    <input type="text" ng-model="condition.dateTo"
+                                           class="form-control" placeholder="到"
+                                           datepicker-popup="yyyy-MM-dd" is-open="condition.$toOpened"
+                                           ng-required="true" min-date="condition.dateFrom"
+                                           current-text="今天" clear-text="清除" close-text="关闭"
+                                           datepicker-options="{formatDayTitle: 'yyyy年M月', formatMonth: 'M月', showWeeks: false}"
+                                           ng-focus="openFilterDatePicker($event, condition, '$toOpened')">
+                                    <span class="input-group-btn">
+							<button type="button" class="btn btn-default"
+                                    ng-click="openFilterDatePicker($event, condition, '$toOpened')">
+								<i class="fa fa-calendar"></i>
+							</button>
+						</span>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <table class="tender-table block" ng-table="tableParams">
+            <thead>
+            <tr class="header">
+                <th width="200">提问单号</th>
+                <th width="300">提问主题</th>
+                <th width="150">答疑截止日期</th>
+                <th width="150">提问日期</th>
+                <th width="150">回复日期</th>
+                <th width="150">状态</th>
+            </tr>
+            </thead>
+            <tbody ng-if="tableParams.total() == 0">
+            <tr>
+                <td colspan="6">
+                    <div class="row text-muted info-container" style="padding: 50px 10px;">
+                        <div class="col-md-4 text-center">
+                            <br>
+                            <br>
+                            <div><img src="static/img/all/info.png" width="130px" height="90px"></div>
+                            <div class="f16">当前没有对应的提问单!</div>
+                        </div>
+                        <div class="col-md-8 br-l">
+                            <div class="f16">
+                                <p>尚无投标方对招标单发起提问!</p>
+                            </div>
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            </tbody>
+            <tbody class="is-done" ng-repeat="question in $data  | orderBy:'-id'">
+            <tr class="pro-line-sty01">
+                <td class="list-notnum" width="300" colspan="1">
+                    <div>
+                        招标单号:<a ui-sref="purc.evaluation({id:tender.id})" target="_self" title="点击查看对应评标单">{{question.saleTenderAnswer.tenderCode}}</a>
+                    </div>
+                </td>
+                <td class="list-notnum" width="350" colspan="2">
+                    <div>招标标题:{{question.saleTenderAnswer.tenderTitle}}</div>
+                </td>
+                <td class="list-notnum" width="300" colspan="3">
+                    <div>提问企业:{{question.vendor.enName}}</div>
+                </td>
+
+            </tr>
+            <tr class="pro-line-sty02">
+                <td class="list-notnum" width="200">
+                    <div><a ui-sref="purc.tenderanswerdetail({id:question.saleTenderAnswer.id})" target="_self" title="点击查看答疑单详情">{{question.code}}</a></div>
+                </td>
+                <td class="list-notnum" width="300">
+                    <div>{{question.topic}}</div>
+                </td>
+                <td class="list-notnum" width="150">{{question.saleTenderAnswer.questionEndDate | date:'yyyy-MM-dd'}}</td>
+                <td class="list-notnum" width="150">{{tender.inDate | date:'yyyy-MM-dd'}}</td>
+                <td class="list-notnum" width="150">{{tender.replyDate | date:'yyyy-MM-dd'}}</td>
+                <td>
+                    <div ng-if="question.status == 201" class="block question-status">
+                        <span class="text-trans success">已回复</span>
+                    </div>
+                    <div ng-if="question.status == 200" class="block question-status">
+                        <span class="text-trans todo">未回复</span>
+                    </div>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>

+ 3 - 0
src/main/webapp/resources/tpl/index/purc/tenderlist.html

@@ -165,6 +165,9 @@
                     <img src="static/img/icon/add.png">新增
                 </a>
             </div>
+            <div class="p-right">
+                <span ui-sref-active="active"><a ui-sref="purc.tenderanswerlist">招标提问列表</a></span>
+            </div>
         </div>
         <!-- 选项菜单和新增按钮 -->
         <div class="block">

+ 9 - 2
src/main/webapp/resources/tpl/index/sale/tender.html

@@ -249,8 +249,15 @@
     <form name="bidForm">
         <div class="purc-bid">
             <div class="list-unstyled">
-                <!--<div class="com_title">服务>招标<font>>投标中</font></div>-->
-                <div class="com_head"><span>投标单</span></div>
+                <div class="com_head">
+                    <span>投标单</span>
+                    <!--<span class="p-right">-->
+                        <!--<a ng-click="showQuestionHistory()" class="text-simple" title="查看当前单据提问记录">提问记录</a>-->
+                    <!--</span>-->
+                    <span class="p-right">
+                        <a ng-click="sendQuestion()" ng-show="saleTender.questionEnd != 1" class="text-simple" title="向招标方提问">提问</a>
+                    </span>
+                </div>
             </div>
             <div class="bid-content ng-scope">
                 <div class="title-div" style="border-bottom: 1px dashed #327ebe;">

+ 101 - 0
src/main/webapp/resources/tpl/index/sale/tender_question.html

@@ -0,0 +1,101 @@
+<style>
+	.saleTender label{
+		font-weight: inherit;
+	}
+	.modal-body .row{
+		line-height: 34px;
+	}
+	.modal-content{
+		width:1080px;
+		margin-top: 50px;
+	}
+	.saleTender .modal-body .row{
+		margin: 0;
+		line-height: 34px;
+		margin-bottom: 10px;
+	}
+	.saleTender .modal-body .row .form-control{
+		height: 34px;
+		border: #bfbfbf 1px solid;
+		font-size: 14px;
+	}
+	.input-group-addon{
+		width: 60px;
+		padding: 0;
+		font-size: 12px;
+		background: #fff;
+	}
+	.input-group[class*="col-"]{
+		float: left;
+	}
+	.modal-footer{
+		border-top: none;
+		margin-right: 18px;
+		padding: 0 15px 15px;
+	}
+	.saleTender .col {
+		padding-left: 5px;
+		padding-right: 5px;
+		line-height: 30px;
+	}
+
+	/* 读取显示无法修改的数据 */
+	.unchanged-info {
+		color: #969595;
+		overflow: hidden;
+	}
+
+</style>
+<div class="loading" ng-class="{'in': loading}">
+	<i></i>
+</div>
+<div class="modal-header">
+	<h3 class="modal-title">投标提问单</h3>
+</div>
+<form class="saleTender" name="saleTenderForm" ng-submit="ok(saleTenderForm)" novalidate>
+	<div class="modal-body" style="min-height: 500px;padding: 25px 25px 10px 25px;">
+		<div class="row">
+			<label class="col-md-1 col-sm-1 col">招标企业:</label>
+			<div class="col-md-3 col-sm-3 col unchanged-info" title="{{saleTender.enterprise.enName}}">{{saleTender.enterprise.enName}}</div>
+			<label class="col-md-1 col-sm-1 col">招标编号:</label>
+			<div class="col-md-3 col-sm-3 col unchanged-info" title="{{saleTender.code}}">{{saleTender.code}}</div>
+			<label class="col-md-1 col-sm-1 col">招标标题:</label>
+			<div class="col-md-3 col-sm-3 col unchanged-info" title="{{saleTender.title}}">{{saleTender.title}}</div>
+		</div>
+		<div class="row">
+			<label class="col-md-1 col-sm-1 col">答疑截止:</label>
+			<div class="col-md-3 col-sm-3 col unchanged-info" title="{{saleTender.questionEndDate | date:'yyyy-MM-dd'}}">{{saleTender.questionEndDate | date:'yyyy-MM-dd'}}</div>
+			<label class="col-md-1 col-sm-1 col">提问时间:</label>
+			<div class="col-md-3 col-sm-3 col unchanged-info" title="{{question.inDate | date:'yyyy-MM-dd'}}" ng-if="question.inDate">{{question.inDate | date:'yyyy-MM-dd'}}</div>
+			<div class="col-md-3 col-sm-3 col unchanged-info" title="{{currentDay | date:'yyyy-MM-dd'}}" ng-if="!question.inDate">{{currentDay | date:'yyyy-MM-dd'}}</div>
+			<label class="col-md-1 col-sm-1 col">回复时间:</label>
+			<div class="col-md-3 col-sm-3 col unchanged-info" title="{{question.replyDate | date:'yyyy-MM-dd'}}">{{question.replyDate | date:'yyyy-MM-dd'}}</div>
+		</div>
+		<div class="row">
+			<label class="col-md-1 col-sm-1 col">答疑主题:</label>
+			<div class="col-md-7 col-sm-5 col">
+				<input ng-model="question.topic" class="form-control input-sm" type="text">
+			</div>
+			<label class="col-md-1 col-sm-1 col">处理状态:</label>
+			<div class="col-md-3 col-sm-3 col unchanged-info" ng-if="question.status" title="{{question.status == '201' ? '已处理' : '待回复'}}">{{question.status == '201' ? '已处理' : '待回复'}}</div>
+		</div>
+		<div class="row">
+			<label class="col-md-1 col-sm-1 col">咨询内容:</label>
+			<div class="col-md-11 col-sm-11 col">
+				<textarea style="min-height: 20px; max-height: 400px; height: 100px;" ng-model="question.content" class="form-control input-sm" placeholder="请输入咨询内容"></textarea>
+			</div>
+		</div>
+		<div class="row">
+			<label class="col-md-1 col-sm-1 col">咨询文件:</label>
+			<div class="col-md-11 col-sm-11 col">
+				<input type="file" ng-model="attachFile" ng-file-select
+					ng-multiple="false" class="form-control input-sm" name="attachFile"
+					id="attachFile">
+			</div>
+		</div>
+	</div>
+	<div class="modal-footer">
+		<button class="btn btn-primary" type="submit" ng-disabled="!saleTenderForm.$dirty && saleTenderForm.$invalid">提交问题</button>
+		<button class="btn btn-warning" ng-click="cancel()" type="button">取消</button>
+	</div>
+</form>

+ 308 - 0
src/main/webapp/resources/tpl/index/sale/tender_question_detail.html

@@ -0,0 +1,308 @@
+<!-- 提问单详情 -->
+<style>
+
+    /* 标题 */
+    .bid-label {
+        height: 30px;
+        margin-left: 10px;
+        margin-right: 10px;
+        background-color: #e8e8e8;
+        box-shadow: 0 0 5px #6f6f6f;
+        border-top-right-radius: 20px;
+    }
+    /* 主体 */
+    .purc-bid {
+        line-height: 2;
+        font-size: 14px;
+    }
+    .purc-bid .row {
+        margin-left: 0px;
+        margin-right: 0px;
+        padding-left: 15px;
+        padding-right: 15px;
+    }
+    .bid-content {
+        background-color: #fff;
+    }
+
+    .bid-content>div>div {
+        margin-top: 3px;
+        margin-bottom: 3px;
+    }
+
+    /* 读取显示无法修改的数据 */
+    .unchanged-info {
+        color: #969595;
+        overflow: hidden;
+    }
+    /* 二级标题栏 */
+    .title-div {
+        font-size: 14px;
+        font-weight: 600;
+        padding-left: 30px;
+        height: 50px;
+        padding-top: 11px;
+    }
+
+    /* 输入框前描述 */
+    .bid-desc {
+        width: 100px;
+        float: left;
+    }
+    /* 输入框 */
+    .bid-input {
+        border: none;
+        border-bottom: 1px solid #323232;
+        text-align: center;
+    }
+    .bid-input:focus{
+        outline:none;
+        border-bottom: 1px solid #5078cb;
+    }
+
+
+    /* 基本信息 */
+    .base-info {
+        border-bottom: 1px solid #e8e8e8;
+        padding-bottom: 30px;
+        padding-top: 20px;
+        margin-bottom: 0; /* 去除index中公共样式影响 */
+    }
+
+    .prod-info {
+        border-bottom: 1px solid #e8e8e8;
+        padding-bottom: 30px;
+        padding-top: 20px;
+    }
+
+    /* 附件上传 */
+    .purc-tender .base-info .attach-upload {
+        display: inline;
+    }
+    .purc-tender .base-info .attach-upload input {
+        height: 100px;
+        width: 100px;
+        margin: 6px 0 0 100px;
+        opacity: 0;
+        z-index: 1;
+        position: relative;
+    }
+    .purc-tender .base-info .attach-upload input:hover {
+        cursor: pointer;
+    }
+    .fileInputContainer{
+        height:100px;
+        background-image: url('static/img/tender/upload.png');
+        position:relative;
+        width: 100px;
+        margin-left: 100px;
+        margin-top: 20px;
+    }
+    .fileInput{
+        height:100px;
+        font-size: 100px;
+        position:absolute;
+        margin-left: 100px;
+        margin-top: 20px;
+        right:0;
+        top:0;
+        opacity: 0;
+        filter:alpha(opacity=0);
+        cursor:pointer;
+    }
+
+    .attach-file {
+        margin-left: 130px;
+        width: 400px;
+    }
+
+    /* 右下角按钮 */
+    /*.bid-content>div {
+        background-color: #fff;
+    }
+    .bid-content>div>div>button,a {
+        width: 94px;
+        height: 36px;
+        font-size: 14px;
+        font-family: "Microsoft Yahei Regular";
+        color: #fff;
+        border-radius: 0;
+    }
+    .bid-content>div>div.btn-bid>button,a {
+        background-color: #327EBE;
+    }*/
+
+    /* 日期选择器 */
+    .purc-bid .date-picker input {
+        border-radius: 0;
+        border: 1px solid #5078cb;
+        border-right: none;
+        font-size: 12px;
+    }
+    .purc-bid .date-picker span .btn-open {
+        color: #fff;
+        background-color: #5078cb;
+        border-radius: 0;
+        border: 1px solid #5078cb;
+        border-left: none;
+    }
+
+    /* 修改本页内btn的样式 及datepicker中的btn-success的样式 */
+    .purc-bid .date-picker .btn {
+        border-radius: 0;
+    }
+
+    .purc-bid .date-picker .btn-success {
+        background-color: #327EBE;
+    }
+    .purc-bid .date-picker ul {
+        border-radius: 0;
+    }
+    .purc-bid .date-picker ul div:focus {
+        outline: none;
+        border-radius: 0;
+        border: none;
+    }
+
+
+
+    .com_head{width:100%;height:40px;line-height:42px;background:url(static/img/comm_bg01.png) no-repeat center;background-size: 100%;}
+    .com_head span{margin-left:20px;color:#000;font-size:14px;}
+    .com_head a{color:#327ebe;float:right;margin-right:40px;font-size: 14px;}
+    .com_head a i{margin-left: 5px;line-height: 40px;}
+    .com_head a:hover{color: #d2272d;}
+
+    .com_title{width:100%;margin:0px auto;height:40px;line-height:40px;font-size:14px;color:#323232;background:#f5f5f5;}
+    .com_title font{color:#327ebe;}
+
+
+    .com_title01{height: 50px;line-height:50px;width:100%;border-bottom:#3578ba 1px dotted;border-top:#e8e8e8 1px solid;margin-top: -4px;} /*  这里修改过 margin-top*/
+    .com_title01 span{margin-left:20px;font-size: 14px;line-height: 50px;color: #555;font-weight: bold;}
+
+    .com_title01  a {
+        color: #5078cb;
+    }
+    .com_title01  a:hover {
+        cursor: pointer;
+        color: #55b6ff;
+    }
+
+    /*投标单*/
+    .tender-list,.tender-list02{width:100%;margin: 0 auto;background: #fff;}
+    .tender-list dl{width: 100%;margin:0 auto;}
+    .tender-list dl dt{width: 100%;margin:0 auto;height: 40px;}
+    .tender-list dl dt span{height: 40px;line-height: 48px;display: inline-block;color: #999;}
+    .tender-list dl dd{width: 100%;margin:0 auto;height: 100px;border-bottom: #ccc 1px dashed;overflow: hidden;}
+    .tender-list dl dd:hover{border: #d32526 1px solid;}
+    .tender-list dl dd span{height: 100px;line-height: 50px;display: inline-block;}
+    .tender-list dl span{width:10.6%;font-size: 14px;float: left;text-align: center;}
+    .tender-list dl span.wid01{width:25%;}
+    .tender-list dl span.wid01 p{font-size: 14px;line-height: 22px;text-align: left;margin: 0;}
+    .tender-list dl dd span.wid01{margin-top: 15px;}
+    .tender-list .com_title01 em,.tender-list02 .com_title01 em{margin-left: 5px;font-size: 16px;color: #f00;position: relative;top: 3px;}
+
+    /* 点击变输入框 */
+    .editAble{ width: 100%; height: 34px; border: none; font-size: 14px; text-align:center;line-height:34px;}
+
+    .not-answer {
+        text-align: center;
+        color: #969595;
+        margin-top: 20px;
+        font-size: large;
+    }
+</style>
+
+<div class="ng-scope">
+    <form name="bidForm">
+        <div class="purc-bid">
+            <div class="list-unstyled">
+                <div class="com_head">
+                    <span>投标提问单</span>
+                </div>
+            </div>
+            <div class="bid-content ng-scope">
+                <div class="title-div" style="border-bottom: 1px dashed #327ebe;">
+                    <span class="col-xs-11">基本信息</span>&nbsp;
+                    <span ng-if="question.saleTenderAnswer.status == 201" class="block">
+                        <span class="text-trans success">已回复</span>
+                    </span>
+                    <span ng-if="question.saleTenderAnswer.status == 200" class="block">
+                        <span class="text-trans todo">待回复</span>
+                    </span>
+                </div>
+                <div class="row base-info">
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">招标编号:</div>
+                        <div class="unchanged-info">{{question.saleTenderAnswer.tenderCode}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">招标项目:</div>
+                        <div class="unchanged-info">{{question.saleTenderAnswer.tenderTitle}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">招标企业:</div>
+                        <div class="unchanged-info">{{question.saleTenderAnswer.enterprise.enName}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">提问单号:</div>
+                        <div class="unchanged-info">{{question.code}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">录入时间:</div>
+                        <div class="unchanged-info">{{question.inDate | date:'yyyy-MM-dd'}}</div>
+                    </div>
+                    <div class = "col-xs-12">
+                        <div class="bid-desc">提问主题:</div>
+                        <div class="unchanged-info">{{question.topic}}</div>
+                    </div>
+                    <div class = "col-xs-12">
+                        <div class="bid-desc">提问内容:</div>
+                        <div class="unchanged-info">{{question.content}}</div>
+                    </div>
+                    <div ng-if="question.questionAttaches.length" class="col-xs-12">
+                        <span class="bid-desc">提问附件:</span>
+                        <a ng-repeat="attach in question.questionAttaches" class="" style="padding-left: 0; color: #5078cb;" href="file/{{attach.id}}">
+                            {{::attach.name}}
+                        </a>
+                    </div>
+                </div>
+                <div  class="title-div" style="border-bottom: 1px dashed #327ebe;">
+                    <span>回答信息</span>
+                    <span style="color: rgb(211,37,38);">*</span>
+                </div>
+                <div class="not-answer" ng-show="question.saleTenderAnswer.auditDate == null">
+                    招标方暂未回答,请耐心等待!
+                </div>
+                <div class="row prod-info" ng-show="question.saleTenderAnswer.auditDate != null">
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">回复单号:</div>
+                        <div class="unchanged-info">{{question.saleTenderAnswer.code}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">回复时间:</div>
+                        <div class="unchanged-info">{{question.saleTenderAnswer.replyDate | date:'yyyy-MM-dd'}}</div>
+                    </div>
+                    <div class = "col-xs-4">
+                        <div class="bid-desc">回复人:</div>
+                        <div class="unchanged-info">{{question.saleTenderAnswer.recorder}}</div>
+                    </div>
+                    <div class = "col-xs-12">
+                        <div class="bid-desc">备注:</div>
+                        <div class="unchanged-info">{{question.saleTenderAnswer.remark}}</div>
+                    </div>
+                    <div class = "col-xs-12">
+                        <div class="bid-desc">附件:</div>
+                        <a ng-repeat="attach in question.saleTenderAnswer.answerAttaches" class="" style="padding-left: 0; color: #5078cb;" href="file/{{attach.id}}">
+                            {{::attach.name}}
+                        </a>
+                    </div>
+                </div>
+                <!--<div class="col-xs-12" style="padding: 30px;">-->
+                    <!--<div class="col-xs-2 pull-right btn-bid">-->
+                        <!--<a class="btn" ui-sref="purc.evaluation({id:bid.id})" ng-click="javascript:history.go(-1);">返回</a>-->
+                    <!--</div>-->
+                <!--</div>-->
+            </div>
+        </div>
+    </form>
+</div>

+ 170 - 0
src/main/webapp/resources/tpl/index/sale/tender_question_history.html

@@ -0,0 +1,170 @@
+<style>
+    body{
+        font-family: "Microsoft YaHei", "微软雅黑";
+    }
+    .btn {
+        border-radius: 0;
+    }
+
+    .modal-content {
+        /*margin-top: 100px;*/
+        min-height: 500px;
+        width: 1058px;
+        margin-left: auto;
+        margin-right: auto;
+        left: -35%;   /*居中*/
+        /*top: 100px;*/
+        padding: 0 27px;
+    }
+
+    /* 选项按钮 */
+    .menu-message .menu-status .btn-select {
+        background-color: #fff;
+        color: #000000;
+        border: none;
+        border-radius: 0;
+        height: 36px;
+        margin: 0 5px 0 5px;
+        padding: 0 15px 0 15px;
+        border-bottom: 2px solid #fff;
+    }
+
+    .menu-status {
+        height: 36px;
+        margin-bottom: 36px;
+    }
+
+    .menu-status .btn-select:hover {
+        border-bottom: 2px solid #D32526;
+    }
+
+    .menu-status .btn-select:focus {
+        border-bottom: 2px solid #D32526;
+    }
+    .menu-status .btn-select:first-child {
+        margin-left: 10px;
+    }
+
+    /* 顶部搜索框 */
+    .menu-message {
+        margin-top: 12px;
+    }
+    .menu-message #search_input {
+        height: 36px;
+        font-size: 16px;
+        font-family: '微软雅黑';
+        border: 1px solid #327EBE;
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+        text-align: center;
+    }
+
+    .menu-message #search_btn {
+        height: 36px;
+        padding-top: 0;
+        padding-bottom: 0;
+        font-size: 16px;
+        background: #327EBE;
+        border: 1px solid #327EBE;
+        color: #fff;
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+    }
+
+    /* 当前激活 */
+
+    .menu-message .menu-status .btn-selected {
+        background-color: #fff;
+        color: #D32526;
+        border: none;
+        border-bottom: 2px solid #D32526;
+        border-radius: 0;
+
+    }
+
+    .menu-message .menu-status .btn-selected:hover {
+        background-color: #f5f5f5;
+    }
+
+
+    /* 消息表格 */
+    .release-table thead tr th {
+        font-weight: 500;
+        color: rgb(0, 0, 0);
+        height: 50px;
+        text-align: center;
+    }
+
+    .release-table tbody tr td {
+        height: 50px;
+        text-align: center;
+    }
+
+    /*  .footer-click {
+          width: 200px;
+          position: relative;
+          top: -40px;
+      }*/
+    #notice-list .table{
+        border-top: #e8e8e8 1px solid;
+        border-left: #e8e8e8 1px solid;
+        border-right: #e8e8e8 1px solid;
+    }
+    #notice-list .table th,#notice-list .table td{
+        font-size: 14px;
+        vertical-align: middle;
+        border: none;
+        border-bottom: #e8e8e8 1px solid;
+    }
+    #notice-list input[type="checkbox"]{
+        vertical-align: sub;
+        margin-top: 0;
+    }
+
+    #notice-list .footer-click {
+        margin-left: 14px;
+    }
+    #notice-list .footer-click  input{
+        margin-right: 5px;
+    }
+</style>
+<div class="modal-body" id="notice-list">
+    <div class="loading in" ng-class="{'in': loading}">
+        <i></i>
+    </div>
+    <div class="col-xs-12" style="height: 14px;">
+        <div class="pull-right" style="margin-right: -33px; margin-top: -5px;">
+            <a ng-click="cancel()"><i class="fa fa-close fa-lg"></i></a>
+        </div>
+    </div>
+    <table class="block table release-table">
+        <thead>
+        <tr class="header">
+            <th width="40" ng-hide="active == 'done'"></th>
+            <th width="150">发起时间</th>
+            <th width="500">信息详情</th>
+            <th width="150" ng-hide="active == 'todo'">阅读时间</th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr ng-repeat="releaseDetail in $data">
+            <td ng-hide="active == 'done'">
+                <input ng-model="releaseDetail.checked" name="checkbox" ng-show="!releaseDetail.checked" ng-click="checkOne(releaseDetail)" type="checkbox">
+                <input ng-model="releaseDetail.checked" name="checkbox" ng-show="releaseDetail.checked" ng-click="unCheckOne(releaseDetail)" type="checkbox">
+            </td>
+            <td>
+                <div>{{releaseDetail.pagingRelease.date | date:'yyyy-MM-dd HH:mm'}}</div>
+            </td>
+            <td>
+                <div style="text-align: left;">
+                    <a style="color: #5078cb;" ng-if="releaseDetail.pagingRelease.url != null" ng-click="setOneRead(releaseDetail.id)" href="{{::releaseDetail.pagingRelease.url}}" title="查看详情">{{releaseDetail.pagingRelease.context}}</a>
+                    <span ng-if="releaseDetail.pagingRelease.url == null">{{::releaseDetail.pagingRelease.context}}</span>
+                </div>
+            </td>
+            <td ng-hide="active == 'todo'">
+                <div>{{releaseDetail.readDate | date:'yyyy-MM-dd HH:mm'}}</div>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>

+ 400 - 0
src/main/webapp/resources/tpl/index/sale/tender_question_list.html

@@ -0,0 +1,400 @@
+<style>
+    /* 顶部搜索框 */
+    .top-nav {
+        margin-bottom: 10px;
+    }
+
+    .top-nav #search_input {
+        height: 36px;
+        font-size: 16px;
+        font-family: '微软雅黑';
+        border: 1px solid #327EBE;
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+        text-align: center;
+    }
+
+    .top-nav #search_btn {
+        height: 36px;
+        padding-top: 0;
+        padding-bottom: 0;
+        font-size: 16px;
+        background: #327EBE;
+        border: 1px solid #327EBE;
+        color: #fff;
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+    }
+
+    /* 主内容区 */
+    .main-content {
+        font-size: 14px;
+    }
+
+    /* 选项菜单 招标单按钮*/
+    .div-menu .text-num {
+        color: rgb(211, 37, 38);
+        padding: 0 5px;
+    }
+
+    .btn-tender {
+        border-radius: 0;
+        width: 100%;
+        height: 40px;
+        font-size: 14px;
+    }
+
+    /* 选项按钮 */
+    /* 当前激活 */
+    .div-menu .menu-status .btn-selected {
+        background-color: #fff;
+        color: #D32526;
+        border: none;
+        border-bottom: 2px solid #D32526;
+        border-radius: 0;
+
+    }
+
+    .div-menu .menu-status .btn-selected:hover {
+        background-color: #f5f5f5;
+    }
+
+    .div-menu .btn-select {
+        background-color: #fff;
+        color: #000000;
+        border: none;
+        border-radius: 0;
+        height: 40px;
+        font-weight: 600;
+        padding: 0 20px 0 20px;
+        border-bottom: 2px solid #fff;
+    }
+
+    .div-menu {
+        border-bottom: 16px solid #f5f5f5;
+        height: 56px;
+    }
+
+    .div-menu .btn-select:hover {
+        border-bottom: 2px solid #D32526;
+    }
+
+    .div-menu .btn-select:focus {
+        border-bottom: 2px solid #D32526;
+    }
+
+    .div-menu .btn-select:first-child {
+        margin-left: 10px;
+    }
+
+    .div-menu > div:first-child .btn {
+        font-size: 16px;
+    }
+
+    /* 列表内容 */
+    .tender-table {
+        text-align: center;
+    }
+
+    .tender-table .header {
+        height: 50px;
+        background-color: #fff;
+        color: rgb(50, 50, 50);
+        border-bottom: 1px solid #e8e8e8;
+    }
+
+    .tender-table .header > th {
+        text-align: center;
+    }
+
+    .tender-table > tbody {
+        font-size: 14px;
+        color: #323232;
+        border: 1px solid transparent;
+    }
+
+    .tender-table > tbody.not-done > tr:nth-child(odd) {
+        height: 140px;
+    }
+
+    .tender-table > tbody.not-done > tr td div {
+        line-height: 25px;
+    }
+
+    .tender-table tbody.not-done > tr:nth-child(odd):hover {
+        border: 2px solid #D32526;
+
+    }
+
+    .tender-table > tbody.is-done:hover {
+        border: 2px solid #D32526;
+    }
+
+    .tender-table > tbody.is-done > tr:first-child {
+        background-color: #f5f5f5;
+        border-bottom: 1px solid #e8e8e8;
+    }
+
+    .tender-table > tbody.is-done > tr:first-child td {
+        padding: 10px 0;
+    }
+
+    .tender-table > tbody.is-done > tr {
+        border-bottom: 1px solid #e8e8e8;
+    }
+
+    .tender-table tbody.is-done > tr:last-child {
+        border-bottom: 1px solid #e8e8e8;
+
+    }
+
+    .tender-table tbody tr td a {
+        color: #327ebe;
+        /*border: #e8e8e8 1px solid;*/
+    }
+
+    .main-content .btn-group {
+        font-family: "Microsoft YaHei", "微软雅黑";
+        font-weight: 500;
+    }
+
+    .main-content .btn-group button {
+        font-weight: inherit;
+    }
+
+    .list-notnum {
+        text-align: left;
+        padding-left: 20px;
+    }
+
+    .list-notnum div {
+        padding-left: 5px;
+    }
+
+    .list-num {
+        text-align: right;
+    }
+
+    .pro-line-sty01 td div {
+        padding-left: 10px;
+    }
+
+    .pro-line-sty02 {
+        height: 120px;
+    }
+
+    .pro-line-sty02 td div {
+        line-height: 25px;
+    }
+
+    .main-content {
+        border: #e8e8e8 1px solid;
+    }
+
+    .div-menu {
+        border-bottom: 0;
+    }
+
+    #public .menu {
+        border-bottom: 0 !important;
+    }
+
+    .menu .new-dot {
+        width: 20px;
+        height: 20px;
+        line-height: 20px;
+        font-size: 12px;
+        color: #fff;
+        font-weight: inherit;
+        top: -2px;
+    }
+
+    /*2017年9月14日*/
+    /* 单据状态位置调整 */
+    .question-status {
+        margin-top: -20px;
+        right: 20px;
+    }
+</style>
+<link rel="stylesheet" href="static/css/public.css">
+<div class="loading in" ng-class="{'in': loading}">
+    <i></i>
+</div>
+<div id="public">
+    <!-- 顶部导航及搜索框 -->
+    <div class="pub-com_head">
+        <span>招标提问列表</span>
+        <div class="p-right">
+        </div>
+    </div>
+    <div class="menu condition block">
+        <div class="row">
+            <div class="col-xs-4">
+                <!-- TODO增加红点显示 -->
+                <div class="btn-group btn-group-sm btn-group-justified">
+                    <div class="btn-group btn-group-sm">
+                        <button type="button" class="btn btn-default btn-line"
+                                ng-class="{'btn-info':active=='all'}" ng-click="setActive('all')">全部
+                            <b class="new-dot" ng-if="unread.all > 0">{{unread.all>99?'99+':unread.all}}</b>
+                        </button>
+                    </div>
+                    <div class="btn-group btn-group-sm">
+                        <button type="button" class="btn btn-default btn-line"
+                                ng-class="{'btn-info':active=='done'}" ng-click="setActive('done')">已回复
+                            <b class="new-dot"
+                               ng-if="unread.replied > 0">{{unread.replied>99?'99+':unread.replied}}</b>
+                        </button>
+                    </div>
+                    <div class="btn-group btn-group-sm">
+                        <button type="button" class="btn btn-default btn-line"
+                                ng-class="{'btn-info':active=='todo'}" ng-click="setActive('todo')">待回复
+                            <b class="new-dot"
+                               ng-if="unread.notReply > 0">{{unread.notReply>99?'99+':unread.notReply}}</b>
+                        </button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="block main-content">
+        <!-- 选项菜单和新增按钮 -->
+        <div class="block">
+            <div class="condition block">
+                <div class="search-bg condition block" style="padding: 10px 15px;">
+                    <div class="row">
+                        <div id="topSearch" style="float: left">
+                            <a ng-click="changeDateZone(1);condition.$open=false" title="最近一个月"
+                               ng-class="{'active':condition.dateZone=='1'}">最近一个月</a>
+                            <a ng-click="changeDateZone(3);condition.$open=false" title="最近三个月"
+                               ng-class="{'active':condition.dateZone=='3'}">最近三个月</a>
+                            <a ng-click="changeDateZone(6);condition.$open=false" title="最近六个月"
+                               ng-class="{'active':condition.dateZone=='6'}">最近六个月</a>
+                            <a ng-click="condition.$open=!condition.$open;changeDateZone(-1)" title="自定义"
+                               ng-class="{'active':condition.dateZone=='-1'}">自定义</a>
+                        </div>
+                        <div class="col-xs-6" style="float: right;">
+                            <div class="search">
+                                <div class="form-group form-group-sm has-feedback" dropdown auto-close="outsideClick"
+                                     on-toggle="searchAdvance=open">
+                                    <input type="search" class="form-control input-sm" ng-model="keyword"
+                                           ng-search="onSearch(keyword)" placeholder="输入单据编号、客户名称、物料名称搜索" style="width: 100%"/>
+                                    <a class="btn input-group-addon" ng-click="onSearch(keyword)">搜索</a>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="more-list more" ng-class="{'open': condition.$open}">
+                        <form class="form-inline">
+                            <div class="form-group ">
+                                <label>日期:</label>
+                                <div class="btn-group btn-menu" dropdown is-open="condition.$dateZoneOpen">
+                                    <ul class="dropdown-menu">
+                                        <li><a ng-click="changeDateZone(1)">一个月内</a></li>
+                                        <li><a ng-click="changeDateZone(6)">半年内</a></li>
+                                        <li><a ng-click="changeDateZone()">半年前</a></li>
+                                    </ul>
+                                </div>
+                                <div class="form-group input-group input-group-xs input-trigger">
+                                    <input type="text" ng-model="condition.dateFrom"
+                                           class="form-control" placeholder="从"
+                                           datepicker-popup="yyyy-MM-dd" is-open="condition.$fromOpened"
+                                           ng-required="true" max-date="condition.dateTo"
+                                           current-text="今天" clear-text="清除" close-text="关闭"
+                                           datepicker-options="{formatDayTitle: 'yyyy年M月', formatMonth: 'M月', showWeeks: false}"
+                                           ng-focus="openFilterDatePicker($event, condition, '$fromOpened')">
+                                    <span class="input-group-btn">
+							<button type="button" class="btn btn-default"
+                                    ng-click="openFilterDatePicker($event, condition, '$fromOpened')">
+								<i class="fa fa-calendar"></i>
+							</button>
+						</span>
+                                </div>
+                                <div class="form-group input-group input-group-xs input-trigger">
+                                    <input type="text" ng-model="condition.dateTo"
+                                           class="form-control" placeholder="到"
+                                           datepicker-popup="yyyy-MM-dd" is-open="condition.$toOpened"
+                                           ng-required="true" min-date="condition.dateFrom"
+                                           current-text="今天" clear-text="清除" close-text="关闭"
+                                           datepicker-options="{formatDayTitle: 'yyyy年M月', formatMonth: 'M月', showWeeks: false}"
+                                           ng-focus="openFilterDatePicker($event, condition, '$toOpened')">
+                                    <span class="input-group-btn">
+							<button type="button" class="btn btn-default"
+                                    ng-click="openFilterDatePicker($event, condition, '$toOpened')">
+								<i class="fa fa-calendar"></i>
+							</button>
+						</span>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <table class="tender-table block" ng-table="tableParams">
+            <thead>
+            <tr class="header">
+                <th width="200">提问单号</th>
+                <th width="300">提问主题</th>
+                <th width="150">答疑截止日期</th>
+                <th width="150">提问日期</th>
+                <th width="150">回复日期</th>
+                <th width="150">状态</th>
+            </tr>
+            </thead>
+            <tbody ng-if="tableParams.total() == 0">
+            <tr>
+                <td colspan="6">
+                    <div class="row text-muted info-container" style="padding: 50px 10px;">
+                        <div class="col-md-4 text-center">
+                            <br>
+                            <br>
+                            <div><img src="static/img/all/info.png" width="130px" height="90px"></div>
+                            <div class="f16">当前没有对应的提问单!</div>
+                        </div>
+                        <div class="col-md-8 br-l">
+                            <div class="f16">
+                                <p>您尚未对任何招标单发起提问!</p>
+                            </div>
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            </tbody>
+            <tbody class="is-done" ng-repeat="question in $data  | orderBy:'-id'">
+            <tr class="pro-line-sty01">
+                <td class="list-notnum" width="300" colspan="1">
+                    <div>
+                        招标单号:<a ui-sref="sale.tender({id:tender.id})" target="_self" title="点击查看招标单详情">{{question.saleTenderAnswer.tenderCode}}</a>
+                    </div>
+                </td>
+                <td class="list-notnum" width="350" colspan="2">
+                    <div>招标标题:{{question.saleTenderAnswer.tenderTitle}}</div>
+                </td>
+                <td class="list-notnum" width="300" colspan="3">
+                    <div>招标企业:{{question.saleTenderAnswer.enterprise.enName}}</div>
+                </td>
+
+            </tr>
+            <tr class="pro-line-sty02">
+                <td class="list-notnum" width="200">
+                    <div><a ui-sref="sale.tenderquestiondetail({id:question.id})" target="_self" title="点击查看提问单详情">{{question.code}}</a></div>
+                </td>
+                <td class="list-notnum" width="300">
+                    <div>{{question.topic}}</div>
+                </td>
+                <td class="list-notnum" width="150">{{question.saleTenderAnswer.questionEndDate | date:'yyyy-MM-dd'}}</td>
+                <td class="list-notnum" width="150">{{question.inDate | date:'yyyy-MM-dd'}}</td>
+                <td class="list-notnum" width="150">{{question.replyDate | date:'yyyy-MM-dd'}}</td>
+                <td>
+                    <div ng-if="question.saleTenderAnswer.status == 201" class="block question-status">
+                        <span class="text-trans success">已回复</span>
+                    </div>
+                    <div ng-if="question.saleTenderAnswer.status == 200" class="block question-status">
+                        <span class="text-trans todo">待回复</span>
+                    </div>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>

+ 1 - 0
src/main/webapp/resources/tpl/index/sale/tenderlist.html

@@ -218,6 +218,7 @@
     <div class="pub-com_head">
         <span>客户招标</span>
         <div class="p-right">
+            <span ui-sref-active="active"><a ui-sref="sale.tenderquestionlist">招标提问列表</a></span>
         </div>
     </div>
     <div class="menu condition block">