package com.qmth.qrzk.web.controller.question;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.qmth.qrzk.repository.common.enumeration.QuestionStatusEnum;
import com.qmth.qrzk.repository.constants.WebConstants;
import com.qmth.qrzk.repository.pager.model.PaperSkeletonDetail;
import com.qmth.qrzk.repository.service.query.QuestionQueryParams;
import com.qmth.qrzk.repository.service.query.QuestionSimilarityQueryParams;
import com.qmth.qrzk.repository.user.model.Book;
import com.qmth.qrzk.repository.user.model.Code;
import com.qmth.qrzk.repository.user.model.Course;
import com.qmth.qrzk.repository.user.model.Question;
import com.qmth.qrzk.repository.user.model.QuestionAttachment;
import com.qmth.qrzk.repository.user.model.QuestionOperationLog;
import com.qmth.qrzk.repository.user.model.QuestionOption;
import com.qmth.qrzk.repository.user.model.QuestionType;
import com.qmth.qrzk.repository.user.model.Role;
import com.qmth.qrzk.repository.user.model.SimilarQuestion;
import com.qmth.qrzk.repository.user.model.User;
import com.qmth.qrzk.repository.user.service.ICodeSerivce;
import com.qmth.qrzk.repository.user.service.IQuestionAttachmentService;
import com.qmth.qrzk.repository.user.service.IQuestionOperationLogService;
import com.qmth.qrzk.repository.user.service.IQuestionOptionService;
import com.qmth.qrzk.repository.user.service.IQuestionTypeService;
import com.qmth.qrzk.repository.user.service.IRoleService;
import com.qmth.qrzk.repository.user.service.IUserService;
import com.qmth.qrzk.repository.user.service.impl.BookServiceImpl;
import com.qmth.qrzk.repository.user.service.impl.CourseServiceImpl;
import com.qmth.qrzk.repository.user.service.impl.QuestionServiceImpl;
import com.qmth.qrzk.repository.utils.General;
import com.qmth.qrzk.repository.utils.ParamUtils;
import com.qmth.qrzk.web.controller.BaseAjaxController;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.util.JSONUtils;

@Controller("questionController")
@RequestMapping("/question")
public class QuestionController extends BaseAjaxController {
	
	private static final Logger log = Logger.getLogger(QuestionController.class);

	@Autowired
	private CourseServiceImpl courseService;

	@Autowired
	@Qualifier("questionTypeServiceImpl")
	private IQuestionTypeService questionTypeService;

	@Autowired
	private BookServiceImpl bookService;

	@Autowired
	@Qualifier("userServiceImpl")
	private IUserService userService;
	
	@Autowired
	@Qualifier("roleServiceImpl")
	private IRoleService roleService;

	@Autowired
	private QuestionServiceImpl questionService;

	@Autowired
	@Qualifier("questionOperationLogServiceImpl")
	private IQuestionOperationLogService questionOperationLogService;

	@Autowired
	@Qualifier("questionOptionServiceImpl")
	private IQuestionOptionService questionOptionServiceImpl;

	@Autowired
	@Qualifier("questionAttachmentServiceImpl")
	private IQuestionAttachmentService questionAttachmentService;

	@Autowired
	@Qualifier("codeServiceImpl")
	private ICodeSerivce codeSerivce;

	/**
	 * 新增试题
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/add")
	public ModelAndView add(HttpSession session, Model model) {
		User user = getCurUser(session);
		Role role = getCurRole(session);
		model.addAttribute("courses", courseService.findCoursesByUserId(user.getId()));
		model.addAttribute("user", user);
		model.addAttribute("role", role);
		ModelAndView modelAndView = new ModelAndView("/question/add");
		modelAndView.addObject("subjectList", null);
		return modelAndView;
	}

	/**
	 * 复制新增试题
	 * @param request
	 * @param response
	 * @param id 试题id
	 * @return
	 */
	@RequestMapping("/saveAdd/{id}")
	public ModelAndView saveAdd(HttpSession session, @PathVariable int id){
		User user = getCurUser(session);
		Role role = getCurRole(session);
		ModelAndView model = new ModelAndView("/question/add-save");
		model.addObject("user", user);
		model.addObject("role", role);
		
		//根据id查出需要复制新增的试题
		Question question = questionService.searchById(id);
		model.addObject("question", question);
		
		//根据试题中的课程id找到关联的一组用户
//		List<Integer> list_userId = courseService.findUsers(question.getCourseId());
//		if (list_userId.size() != 0) {
			List<User> ls_user = userService.getCanSetByUsers(question.getCourseId());
			model.addObject("users", ls_user);
//		}
	
		//根据当前用户ID得到对应的课程集合
		List<Course> courses = courseService.findCoursesByUserId(user.getId());
		if (courses.size() != 0) {
			model.addObject("courses", courses);
		}
		
		
		//根据课程id得到一组题型id
		List<Integer> list_questionType = questionTypeService
				.findQuestionTypes(question.getCourseId());
		if (list_questionType.size() != 0) {
			//根据一组题型id得到一组题型集合
			List<QuestionType> ls_questionType = questionTypeService
					.findNamesByCourseId(list_questionType);
			model.addObject("ls_questionType", ls_questionType);
		}
		List<Book> ls_book = bookService.findBooksInCourse(question.getCourseId());
		model.addObject("ls_book", ls_book);
		return model;
	}
	
	/**
	 * 进入查询列表页面
	 * 
	 * @param user_id
	 *            用户id
	 * @param mode
	 * @return 响应的url
	 */
	@RequestMapping("/list")
	public String list(HttpSession session, Model mode) {
		User user = getCurUser(session);
		Role role = getCurRole(session);
		//根据用户id得到对应课程列表
		List<Course> courses = courseService.findCoursesByUserId(user.getId());
		mode.addAttribute("courses", courses);
		
		List<Code> codes = codeSerivce.getAllCode();
		List<Code> status = new ArrayList<Code>();
		{
			status.add(new Code(QuestionStatusEnum.QUESTION_DRAFT.getKey(),QuestionStatusEnum.QUESTION_DRAFT.getValue()));
//			status.add(new Code(QuestionStatusEnum.QUESTION_PENDING.getKey(),QuestionStatusEnum.QUESTION_PENDING.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_APPROVED.getKey(),QuestionStatusEnum.QUESTION_APPROVED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_REJECTED.getKey(),QuestionStatusEnum.QUESTION_REJECTED.getValue()));
		}
		mode.addAttribute("status", status);
		mode.addAttribute("codes", codes);
		mode.addAttribute("role", role);
		return "/question/list";
	}
	
	/**
	 * 进入录入员查询列表页面
	 * 
	 * @param user_id
	 *            用户id
	 * @param mode
	 * @return 响应的url
	 */
	@RequestMapping("/toInputList")
	public String toInputList(HttpSession session, Model mode) {
		User user = getCurUser(session);
		//根据用户id得到对应课程列表
		List<Course> courses = courseService.findToInputCoursesByUserId(user.getId());
		mode.addAttribute("courses", courses);
		
		List<Code> codes = codeSerivce.getAllCode();
		List<Code> status = new ArrayList<Code>();
		{
			status.add(new Code(QuestionStatusEnum.QUESTION_DRAFT.getKey(),QuestionStatusEnum.QUESTION_DRAFT.getValue()));
//			status.add(new Code(QuestionStatusEnum.QUESTION_PENDING.getKey(),QuestionStatusEnum.QUESTION_PENDING.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_APPROVED.getKey(),QuestionStatusEnum.QUESTION_APPROVED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_REJECTED.getKey(),QuestionStatusEnum.QUESTION_REJECTED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_FINAL_APPROVED.getKey(),QuestionStatusEnum.QUESTION_FINAL_APPROVED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_FINAL_REJECTED.getKey(),QuestionStatusEnum.QUESTION_FINAL_REJECTED.getValue()));
		}
		mode.addAttribute("status", status);
		mode.addAttribute("codes", codes);
		return "/question/list";
	}
	
	@RequestMapping("/getInputTaskCourses")
	@ResponseBody
	public Map<String, Object> getInputTaskCourses(HttpServletRequest request, HttpSession session) {
		Map<String,Object> result = new HashMap<String, Object>();
		
		User user = getCurUser(session);
		//根据用户id得到对应课程列表
		List<Course> courses = courseService.findToInputCoursesByUserId(user.getId());
		result.put("courses", courses);
		
		Map<Integer, Object> courseBookMap = new HashMap<Integer, Object>();
		for(Course course : courses){
			List<Book> books = bookService.findBooksInCourse(course.getId());
			courseBookMap.put(course.getId(), books);
		}
		result.put("courseBookMap", courseBookMap);
		
		List<Code> codes = codeSerivce.getAllCode();
		List<Code> status = new ArrayList<Code>();
		{
			status.add(new Code(QuestionStatusEnum.QUESTION_DRAFT.getKey(),QuestionStatusEnum.QUESTION_DRAFT.getValue()));
//			status.add(new Code(QuestionStatusEnum.QUESTION_PENDING.getKey(),QuestionStatusEnum.QUESTION_PENDING.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_APPROVED.getKey(),QuestionStatusEnum.QUESTION_APPROVED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_REJECTED.getKey(),QuestionStatusEnum.QUESTION_REJECTED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_FINAL_APPROVED.getKey(),QuestionStatusEnum.QUESTION_FINAL_APPROVED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_FINAL_REJECTED.getKey(),QuestionStatusEnum.QUESTION_FINAL_REJECTED.getValue()));
		}
		result.put("status", status);
		result.put("codes", codes);
		
		result.put("appPath", this.getBasePath(request));
		return result;
	}
	
	@RequestMapping("/getSelectInfo")
	@ResponseBody
	public Map<String,Object> list(HttpServletResponse response) {
		List<Code> codes = codeSerivce.getAllCode();
		List<Code> status = new ArrayList<Code>();
		QuestionStatusEnum[] qs=QuestionStatusEnum.values();
		for(int i=0;i<qs.length;i++){
			Code c=new Code(qs[i].getKey(),qs[i].getValue());
			status.add(c);
		}
		Map<String,Object> resultMap = successResult("");
		resultMap.put("codes", codes);
		resultMap.put("status", status);
		return resultMap;
	}
	
	@RequestMapping("/getZujuanInfo")
	@ResponseBody
	public Map<String,Object> getZujuanInfo(HttpSession session,HttpServletResponse response,int courseId,int typeId,int bookId) {
		Course course=courseService.findById(courseId);
		QuestionType type=questionTypeService.queryById(typeId);
		Book book=bookService.queryById(bookId);
		
		Map<String,Object> resultMap = successResult("");
		resultMap.put("course", course);
		resultMap.put("type", type);
		resultMap.put("book", book);
		return resultMap;
	}

	/**
	 * 进入审核列表页面
	 * 
	 * @param user_id
	 *            用户id
	 * @param mode
	 * @return 响应的url
	 */
	@RequestMapping("/getAuditTaskCourses")
	@ResponseBody
	public Map<String,Object> getAuditTaskCourses(HttpServletRequest request, HttpSession session) {
		Map<String,Object> result = new HashMap<String,Object>();
		
		User user = getCurUser(session);
		Role role = getCurRole(session);
		//根据用户id得到对应课程列表
		List<Course> courses = courseService.findToAuditCoursesByUserId(user.getId());
		result.put("courses", courses);
		
		Map<Integer, Object> courseBookMap = new HashMap<Integer, Object>();
		for(Course course : courses){
			List<Book> books = bookService.findBooksInCourse(course.getId());
			courseBookMap.put(course.getId(), books);
		}
		result.put("courseBookMap", courseBookMap);
		
		List<Code> codes = codeSerivce.getAllCode();
		List<Code> status = new ArrayList<Code>();
		{
			status.add(new Code(QuestionStatusEnum.QUESTION_DRAFT.getKey(),QuestionStatusEnum.QUESTION_DRAFT.getValue()));
//			status.add(new Code(QuestionStatusEnum.QUESTION_PENDING.getKey(),QuestionStatusEnum.QUESTION_PENDING.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_APPROVED.getKey(),QuestionStatusEnum.QUESTION_APPROVED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_REJECTED.getKey(),QuestionStatusEnum.QUESTION_REJECTED.getValue()));
		}
		result.put("status", status);
		result.put("codes", codes);
		result.put("role", role);
		result.put("appPath", this.getBasePath(request));
		
		return result;
	}
	
	@RequestMapping(value="/saveAudit")
	@ResponseBody
	public Map<String,Object> saveAudit(int quesId,String auditResult,String remark, HttpSession session){
		try{
			User user = getCurUser(session);
			questionService.saveAudit(quesId, user.getId(), auditResult, remark);
			Map<String,Object> resultMap = successResult("保存细目表的审核结果成功");
			return resultMap;
		}catch(Exception e){
			log.error("保存试题[id=" + quesId + "]的审核结果失败，原因：" + e.getMessage(), e);
			return failedResult("提交试题审核结果失败");
		}
	}
	
	@RequestMapping(value="/getAuditLogs")
	@ResponseBody
	public Map<String,Object> getAuditLogs(int quesId){
		try{
			Map<String,Object> resultMap = successResult("查询审核日志成功");
			resultMap.put("auditLogs",questionService.getAuditLogs(quesId));
			return resultMap;
		}catch(Exception e){
			log.error("查询试题[id=" + quesId + "]的审核日志失败，原因：" + e.getMessage(), e);
			return failedResult("查询审核日志失败");
		}
	}
	
	/**
	 * 根据试题id获取详情信息
	 * @param id  试题id
 	 * @return
	 */
	@RequestMapping("/quesDetail/{id}")
	@ResponseBody
	public Map<String, Object> quesDetail(@PathVariable int id) {
		//根据试题id查询出对应的试题
		Question question = questionService.searchById(id);
		//根据题型id得到对应的题型对象
		QuestionType questionType = questionTypeService.queryById(question.getTypeId());
		List<QuestionOption> options = questionOptionServiceImpl.findByQuestionId(question.getId());
		question.setOptions(options);
		General.quesWordToHtmlForShow(question);
		question.setOptions(null);
//		List<QuestionAttachment> atts = null;
//		atts = questionAttachmentService.queryByQuestionId(question.getId());
		List<User> setTeachers = null;
		{
			setTeachers = userService.queryUsersByCourseId(question.getCourseId());
			{//处理试题里面的命题教师不在配置的命题教师列表里面的情况
				String setTeacher = question.getSetTeacherName();
				if(setTeacher == null){
					setTeacher = "";
					question.setSetTeacherName("");
				}
				boolean tExist = false;
				for(User t:setTeachers){
					if(setTeacher.equals(t.getName())){
						tExist = true;
						break;
					}
				}
				if(!tExist){
					User t = new User();
					t.setName(setTeacher);
					setTeachers.add(0, t);
				}
			}
			
		}

		Map<String,Object> resultMap = successResult("查询试题成功");
		resultMap.put("question", question);
		resultMap.put("questionType", questionType);
		resultMap.put("options", options);
		resultMap.put("setTeachers", setTeachers);
		resultMap.put("isUsedByPaper", questionService.isUsedByPaper(id));
		
//		if (atts != null) {
//			resultMap.put("atts", atts);
//		}
		return resultMap;
	}
	
	@RequestMapping(value="/isUsedByPaper")
	@ResponseBody
	public Map<String,Object> isUsedByPaper(int quesId){
		try{
			Map<String,Object> resultMap = successResult("查询试题是否已被试卷引用成功");
			Course course = courseService.findCourseByQuesId(quesId);
			boolean isUsedByPaper = true;
			if(course.getOpenEdit() != null && course.getOpenEdit().equals(1)){
				isUsedByPaper = false;
			}else{
				isUsedByPaper = questionService.isUsedByPaper(quesId);
			}
			resultMap.put("used", isUsedByPaper);
			return resultMap;
		}catch(Exception e){
			log.error("查询试题[quesId=" + quesId + "]是否已被试卷引用失败，原因：" + e.getMessage(), e);
			return failedResult("查询试题是否已被试卷引用失败");
		}
	}
	
	@RequestMapping(value = "/questionForEdit")
    public ModelAndView questionForEdit(int courseId) {
		ModelAndView result = new ModelAndView("/question/question");
		result.addObject("setTeachers", userService.queryUsersByCourseId(courseId));
		result.addObject("books", bookService.findBooksInCourse(courseId));
		result.addObject("questionTypes", questionTypeService.queryByCourseId(courseId));
        return result;
    }

	/**
	 * 进入审核列表页面
	 * 
	 * @param user_id
	 *            用户id
	 * @param mode
	 * @return 响应的url
	 */
	@RequestMapping("/audit")
	public String audit(HttpSession session, Model mode) {
		User user = getCurUser(session);
		Role role = getCurRole(session);
		//根据用户id得到对应课程列表
		List<Course> courses = courseService.findToAuditCoursesByUserId(user.getId());
		mode.addAttribute("courses", courses);
		
		List<Code> codes = codeSerivce.getAllCode();
		List<Code> status = new ArrayList<Code>();
		{
			status.add(new Code(QuestionStatusEnum.QUESTION_DRAFT.getKey(),QuestionStatusEnum.QUESTION_DRAFT.getValue()));
//			status.add(new Code(QuestionStatusEnum.QUESTION_PENDING.getKey(),QuestionStatusEnum.QUESTION_PENDING.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_APPROVED.getKey(),QuestionStatusEnum.QUESTION_APPROVED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_REJECTED.getKey(),QuestionStatusEnum.QUESTION_REJECTED.getValue()));
		}
		mode.addAttribute("status", status);
		mode.addAttribute("codes", codes);
		mode.addAttribute("role", role);
		return "/question/audit";
	}

	/**
	 * 进入管理员试题列表页面
	 * 
	 * @param user_id
	 *            用户id
	 * @param mode
	 * @return 响应的url
	 */
	@RequestMapping("/mng")
	public String mng(Model mode,HttpServletRequest request) {
		//根据用户id得到对应课程列表
		List<Course> courses = courseService.queryAllCourses();
		mode.addAttribute("courses", courses);
		
		List<Code> codes = codeSerivce.getAllCode();
		List<Code> status = new ArrayList<Code>();
		{
			status.add(new Code(QuestionStatusEnum.QUESTION_DRAFT.getKey(),QuestionStatusEnum.QUESTION_DRAFT.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_APPROVED.getKey(),QuestionStatusEnum.QUESTION_APPROVED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_REJECTED.getKey(),QuestionStatusEnum.QUESTION_REJECTED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_FINAL_APPROVED.getKey(),QuestionStatusEnum.QUESTION_FINAL_APPROVED.getValue()));
			status.add(new Code(QuestionStatusEnum.QUESTION_FINAL_REJECTED.getKey(),QuestionStatusEnum.QUESTION_FINAL_REJECTED.getValue()));
		}
		mode.addAttribute("status", status);
		mode.addAttribute("codes", codes);
		mode.addAttribute("questionId", request.getParameter("questionId"));
		return "/question/mng";
	}
	
	@RequestMapping("/save")
	@ResponseBody
	public Map<String, Object> save(HttpSession session, @RequestBody String data) {
		try{
			User curUser = getCurUser(session);
			JSONObject obj = JSONObject.fromObject(data);
			JSONObject queObj = obj.getJSONObject("Question");
			if(General.isEmpty(queObj.getString("enableTime"))){
				queObj.put("enableTime", null);
			}
			String[] dateFormats = new String[] {"yyyy-MM-dd"};  
			JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
			
			Question question = (Question) JSONObject.toBean(queObj, Question.class);
			question.setBodyWord(null);
			question.setAnswerWord(null);
			List<QuestionOption> options = null;
			{
				String arr = obj.getString("arr");
				options=new ArrayList<QuestionOption>();
				// 增加选择表数据
				if (arr != "") {
					JSONArray array = JSONArray.fromObject(arr);
					for (int i = 0; i < array.size(); i++) {
						JSONObject object = JSONObject.fromObject(array.get(i));
						QuestionOption qo = new QuestionOption(question.getId(),
								object.getInt("optionNo"),
								object.getInt("isCorrectOption"),
								object.getString("content"),
								object.getString("summary"),
								new Date(), curUser.getId(),
								new Date(), curUser.getId());
						options.add(qo);
					}
				}
				question.setOptions(options);
			}
			question.setBodyWord(new byte[]{});
			question.setBodySummary(General.extractText(question.getBody()));
			question.setAnswerWord(new byte[]{});
			question.setAnswerSummary(General.extractText(question.getAnswer()));
			if (question.getOptions() != null && question.getOptions().size() > 0) {
				for(QuestionOption qo:question.getOptions()){
					qo.setContentWord(new byte[]{});
					qo.setSummary(General.extractText(qo.getContent()));
				}
			}
			question = questionService.save(question, curUser.getId());
			Map<String,Object> resultMap = successResult("保存试题成功");
			
			resultMap.put("question", question);
			resultMap.put("id", question.getId());
			return resultMap;
		}catch(Exception e){
			log.error("保存试题失败，原因:" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	@RequestMapping("/saveQues")
	@ResponseBody
	public Map<String, Object> saveQues(HttpSession session, @RequestBody Question question) {
		try{
			if(question.getId() != null && question.getId() > 0){
				if(questionService.isUsedByPaper(question.getId())){
					throw new RuntimeException("当前试题已经被试卷引用了，不能修改");
				}
			}
			User curUser = getCurUser(session);
			question.setBodyWord(new byte[]{});
			question.setBodySummary(General.extractText(question.getBody()));
			question.setAnswerWord(new byte[]{});
			question.setAnswerSummary(General.extractText(question.getAnswer()));
			if (question.getOptions() != null && question.getOptions().size() > 0) {
				for(QuestionOption qo:question.getOptions()){
					qo.setContentWord(new byte[]{});
					qo.setSummary(General.extractText(qo.getContent()));
				}
			}
			question = questionService.save(question, curUser.getId());
			Map<String,Object> resultMap = successResult("保存试题成功");
			
			resultMap.put("question", question);
			resultMap.put("id", question.getId());
			return resultMap;
		}catch(Exception e){
			log.error("保存试题失败，原因:" + e.getMessage(), e);
			return failedResult("保存试题失败，原因:" + e.getMessage());
		}
	}
	
	@RequestMapping("/report")
	public String report(Model model){
		return "/question/report";
	}
	
	@RequestMapping("/getStatusCount")
	@ResponseBody
	public Map<String,Object> getStatusCount(){
		Map<String,Object> result = new HashMap<String, Object>();
		List<Question> list=questionService.getStatusCount();
		QuestionStatusEnum[] qs=QuestionStatusEnum.values();
		
		//枚举类型存在的key
		List<String> keys=new ArrayList<String>();  
		for(QuestionStatusEnum qus:qs){
			keys.add(qus.getKey());
		}
		for(Question q:list){
			if(keys.contains(q.getStatusCode())){
				q.setStatusCode(QuestionStatusEnum.valueOf(q.getStatusCode()).getValue());
			}
		}
		result.put("rows", list);
		return result;
	}
	
	
	@RequestMapping("/getTypeChapter")
	@ResponseBody
	public Map<String, Object> getTypeChapter(Course param){
		Map<String,Object> result = new HashMap<String, Object>();
		
		if(null == param || null == param.getCode() || param.getCode().equals(""))
			return null;
		
		Course course = courseService.findByCode(param.getCode());
		List<QuestionType> questionTypes=questionTypeService.queryByCourseId(course.getId());
		
		JSONArray array=null;
		int chapter=10;
		//1.判断bookName是否为空 如果为空
//		if(question.getBookName()==null||question.getBookName().equals("")){
		if(true){
			//题型集合
			if(questionTypes.size()>0){
				chapter=questionService.getMaxChapterByCourseId(course.getId());
				
				array=getRows(questionTypes, chapter, course.getId(), 0);	//因为教材名字不存在
			}
		}else{
			//bookName不为空 获取教材id
//			Book book=bookService.get(question.getBookName());
//			
//			if(book.getChapterSize()!=null){
//				chapter=book.getChapterSize();
//			}
//			if(questionTypes.size()>0){
//				array=getRows(questionTypes, chapter,question.getCourseId(),book.getId());
//			}
		}
		if(array!=null){
			result.put("rows", array);
		}else{
			result.put("rows", "");
		}
		result.put("chapterSize", chapter);
		
		
		return result; 
	}
	
	/**
	 * 查询待审核试题
	 * 
	 * @param response
	 * @param question
	 *            查询试题的条件
	 */
	@RequestMapping("/search")
	@ResponseBody
	public Map<String,Object> search(HttpSession session, @RequestBody QuestionQueryParams question) {
		User user = getCurUser(session);
		List<Question> list = questionService.searchByCondition(question, user);
		Map<String,Object> result = new HashMap<String, Object>();
		result.put("rows", list);
		result.put("total", question.getTotalNum());
		return result;
	}
	
	
	/**
	 * 组卷查询试题
	 * 
	 * @param response
	 * @param question
	 *            查询试题的条件
	 * @param currentPage
	 *            当前页 用来做分页处理
	 */
	@RequestMapping("/zujuanSearch")
	public void zujuanSearch(HttpServletResponse response,HttpSession session,
			@RequestBody Question question, int currentPage,int paperId,boolean filterBySkel,String quesOperType,Integer paperDetailId) {
		List<Question> allQuestionsForZj = null;
		int count = filterBySkel ? (allQuestionsForZj = questionService.zjGetAllQuestions(question, paperId, quesOperType, paperDetailId)).size() : questionService.searchByConditionCountForZj(question);
		int pageSize = 3;
		int maxPageCount = count/pageSize + ((count%pageSize) == 0?0:1);
		if(currentPage > maxPageCount){
			currentPage = maxPageCount;
		}
		int startIndex = (currentPage - 1) * pageSize;
		
		List<Question> list = (count == 0) ? new ArrayList<Question>() : (filterBySkel ? allQuestionsForZj.subList(startIndex, (allQuestionsForZj.size() < (startIndex + pageSize)?allQuestionsForZj.size():(startIndex + pageSize))) : questionService.searchByConditionForZj(question,
				pageSize, startIndex));
		questionService.loadPapersIntoQuesList(list);
		for(Question q:list){
			General.quesWordToHtmlForShow(q);
			q.setIsCheck(1);
			//q.setStatusCode(QuestionStatusEnum.valueOf(q.getStatusCode()).getValue());
		}
		JSONArray array = new JSONArray();
		array.add(list);
		array.add(count);
		array.add(currentPage);
		
		this.outJsonString(response, array.toString());
	}
	
	/**
	 * 查询待审核试题
	 * 
	 * @param response
	 * @param question
	 *            查询试题的条件
	 * @param currentPage
	 *            当前页 用来做分页处理
	 */
	@RequestMapping("/searchAudit")
	@ResponseBody
	public Map<String,Object> searchAudit(HttpSession session,@RequestBody QuestionQueryParams question, int currentPage) {
		User user = getCurUser(session);
		question.setRows(3);
		question.setPage(currentPage);
		List<Question> list = questionService.searchToAuditByCondition(question,user);
		Map<String,Object> result = new HashMap<String, Object>();
		result.put("list", list);
		result.put("count", question.getTotalNum());
		result.put("currentPage", currentPage);
		return result;
	}
	
	/**
	 * 查询所有的试题
	 * 
	 * @param response
	 * @param questionsearchForMng
	 *            查询试题的条件
	 * @param currentPage
	 *            当前页 用来做分页处理
	 */
	@RequestMapping("/searchForMng")
	@ResponseBody
	public Map<String,Object> searchForMng(HttpSession session,@RequestBody QuestionQueryParams question, int currentPage) {
		User user = getCurUser(session);
		question.setRows(3);
		question.setPage(currentPage);
		List<Question> list = questionService.searchByConditionForMng(question,user);
		Map<String,Object> result = new HashMap<String, Object>();
		result.put("list", list);
		result.put("count", question.getTotalNum());
		result.put("currentPage", currentPage);
		return result;
	}

	/**
	 * 根据试题id得到一组选项
	 * @param response
	 * @param question
	 */
	@RequestMapping("/getOptions")
	public void getOptionsByQuestionId(HttpServletResponse response,
			@RequestBody Question question) {
		//question.getTypeId()==1表示单选 question.getTypeId()==2表示多选
		if (question.getTypeId() == 1 || question.getTypeId() == 2) {
			List<QuestionOption> options = questionOptionServiceImpl
					.findByQuestionId(question.getId());
			JSONArray array = JSONArray.fromObject(options);
			this.outJsonString(response, array.toString());
		} else {
			Question qu = questionService.searchById(question.getId());
			JSONObject object = JSONObject.fromObject(qu);
			this.outJsonString(response, object.toString());
		}
	}

	/**
	 * 加载试题类型
	 * 
	 * @param request
	 * @param response
	 * @param course
	 *            课程信息
	 */
	@RequestMapping("/loadQuestionType")
	public void loadQuestionType(HttpServletRequest request,
			HttpServletResponse response, @RequestBody Course course) {
		// 从前端接收课程id查询b_course_question_type表 所有question_type_id
		List<Integer> list_questionType = questionTypeService
				.findQuestionTypes(course.getId());

		if (list_questionType.size() != 0) {
			// 根据question_type_id查询表b_question_type对象集合
			List<QuestionType> ls_questionType = questionTypeService
					.findNamesByCourseId(list_questionType);

			// 构造json格式数据 返回前端
			JSONArray array = new JSONArray();
			JSONObject object = new JSONObject();
			for (int i = 0; i < ls_questionType.size(); i++) {
				object.put("id", ls_questionType.get(i).getId());
				object.put("name", ls_questionType.get(i).getName());
				array.add(object);
				object.clear();
			}
			this.outJsonString(response, array.toString());
		} else {
			this.outJsonString(response, "fail");
		}
	}
	
	/**
	 * 通过课程获取题型 2015-10-18 wubaizhi
	 * @param request
	 * @param response
	 * @param courseId
	 * @return
	 */
	@RequestMapping("/loadQuestionTypeByCourseId/{courseId}")
	@ResponseBody
	public List<QuestionType> loadQuestionTypeByCourseId(HttpServletRequest request, HttpServletResponse response, @PathVariable Integer courseId) {
		return questionTypeService.queryByCourseId(courseId);
	}
	
	/**
	 * 通过课程获取教材 2015-10-18 wubaizhi
	 * @param request
	 * @param response
	 * @param courseId
	 * @return
	 */
	@RequestMapping("/loadBooksByCourseId/{courseId}")
	@ResponseBody
	public List<Book> loadBooksByCourseId(HttpServletRequest request, HttpServletResponse response, @PathVariable Integer courseId) {
		return bookService.findBooksInCourse(courseId);
	}
	
	/**
	 * 通过课程获取命题教师 2015-10-18 wubaizhi
	 * @param request
	 * @param response
	 * @param courseId
	 * @return
	 */
	@RequestMapping("/loadTeachersByCourseId/{courseId}")
	@ResponseBody
	public List<User> loadTeachersByCourseId(@PathVariable Integer courseId) {
		return userService.queryUsersByCourseId(courseId);
	}
	
	/**
	 * 通过课程获取命题教师 2015-10-18 wubaizhi
	 * @param request
	 * @param response
	 * @param courseId
	 * @return
	 */
	@RequestMapping("/loadTeachersByQuesId/{quesId}")
	@ResponseBody
	public List<User> loadTeachersByQuesId(@PathVariable Integer quesId) {
		Question question = questionService.searchById(quesId);
		List<User> setTeachers = userService.queryUsersByCourseId(question.getCourseId());
		{//处理试题里面的命题教师不在配置的命题教师列表里面的情况
			String setTeacher = question.getSetTeacherName();
			if(setTeacher == null){
				setTeacher = "";
				question.setSetTeacherName("");
			}
			boolean tExist = false;
			for(User t:setTeachers){
				if(setTeacher.equals(t.getName())){
					tExist = true;
					break;
				}
			}
			if(!tExist){
				User t = new User();
				t.setName(setTeacher);
				setTeachers.add(0, t);
			}
		}
		return setTeachers;
	}

	/**
	 * 加载教材信息
	 * 
	 * @param request
	 * @param response
	 * @param course
	 *            课程信息
	 */
	@RequestMapping("/loadBook")
	public void loadBook(HttpServletRequest request,
			HttpServletResponse response, @RequestBody Course course) {
//		List<Integer> list_bookId = bookService.findBookIds(course.getId());
		if (course != null) {
			List<Book> ls_book = bookService.findBooksInCourse(course.getId());
			// 构造json格式数据 返回前端
			JSONArray array = new JSONArray();
			JSONObject object = new JSONObject();
			for (int i = 0; i < ls_book.size(); i++) {
				object.put("id", ls_book.get(i).getId());
				object.put("name", ls_book.get(i).getName());
				array.add(object);
				object.clear();
			}
			this.outJsonString(response, array.toString());
		} else {
			this.outJsonString(response, "fail");
		}
	}

	/**
	 * 加载试题教师
	 * 
	 * @param request
	 * @param response
	 * @param course
	 *            课程信息
	 */
	@RequestMapping("/loadTeacherName")
	public void loadTeacherName(HttpServletRequest request,
			HttpServletResponse response, @RequestBody Course course) {
		List<User> canSetByUsers = userService.getCanSetByUsers(course.getId());
//		List<Integer> list_userId = courseService.findUsers(course.getId());
		
		
		//找出表中存在学科秘书的用户id集合
//		List<Integer> userIds=roleService.findSECRETARY();
		
		if (canSetByUsers.size() != 0) {
//			List<User> ls_user = userService.findUsers(list_userId);
			// 构造json格式数据 返回前端
			JSONArray array = new JSONArray();
			for (User user:canSetByUsers) {
				JSONObject object = new JSONObject();
				object.put("id", user.getId());
				object.put("name", user.getName());
				array.add(object);
			}
			this.outJsonString(response, array.toString());
		} else {
			this.outJsonString(response, "fail");
		}
	}

	/**
	 * 根据试题id进入查看页面
	 * @param request
	 * @param id  试题id
 	 * @return
	 */
	@RequestMapping("/view/{id}")
	public ModelAndView view(HttpServletRequest request,@PathVariable int id) {
		User user = (User) request.getSession().getAttribute(
				WebConstants.WEB_SESSION_USER);
		Role role = (Role) request.getSession().getAttribute(
				WebConstants.WEB_SESSION_ROLE);
		//根据试题id查询出对应的试题
		Question question = questionService.searchById(id);
		//将试题状态更换前端可识别的状态
		question.setStatusCode(QuestionStatusEnum.valueOf(question.getStatusCode()).getValue());
		//根据课程id得到对应的课程
		Course course = courseService.findById(question.getCourseId());
		//根据题型id得到对应的题型对象
		QuestionType questionType = questionTypeService.queryById(question
				.getTypeId());
		//根据教材id得到对应的教材
		Book book = bookService.queryById(question.getBookId());
		List<QuestionOption> options = null;
		if (question.getTypeId() == 1 || question.getTypeId() == 2) {
			options = questionOptionServiceImpl.findByQuestionId(question
					.getId());
		}
		List<QuestionAttachment> atts = null;
		atts = questionAttachmentService.queryByQuestionId(question.getId());
		ModelAndView model = new ModelAndView("/question/view");
		model.addObject("question", question);
		model.addObject("role", role);
		model.addObject("user", user);
		model.addObject("course", course);
		model.addObject("questionType", questionType);
		model.addObject("book", book);
		if (options != null) {
			model.addObject("options", options);
		}
		if (atts != null) {
			model.addObject("atts", atts);
		}
		return model;
	}

	/**
	 * 进入编辑试题页面
	 * @param request
	 * @param id 试题id
	 * @return
	 */
	@RequestMapping("/edit/{id}")
	public ModelAndView editQuestion(HttpSession session,
			@PathVariable int id) {
		ModelAndView model = new ModelAndView("/question/edit");
		
		Question question = questionService.searchById(id);
		List<QuestionOption> options = null;

		
		Role role = getCurRole(session);
		if(role.getCode().equals("QUESTION_INPUTER")){//试题录入员
			List<User> ls_user = userService.getCanSetByUsers(question.getCourseId());
			model.addObject("allTeacher", ls_user);
		}

		// 是否是主观题 1表示单选 2表示多选
		if (question.getTypeId() == 1 || question.getTypeId() == 2) {
			options = questionOptionServiceImpl.findByQuestionId(question
					.getId());
		}
		model.addObject("question", question);
		if (options != null) {
			model.addObject("options", options);
		}
		List<QuestionAttachment> atts = null;
		atts = questionAttachmentService.queryByQuestionId(question.getId());
		if (atts != null) {
			model.addObject("atts", atts);
		}
		// 获取当前用户
		User user = getCurUser(session);
		model.addObject("user", user);

		List<Course> courses = courseService.findCoursesByUserId(user.getId());
		if (courses.size() != 0) {
			model.addObject("courses", courses);
		}

		List<Integer> list_questionType = questionTypeService
				.findQuestionTypes(question.getCourseId());
		if (list_questionType.size() != 0) {
			List<QuestionType> ls_questionType = questionTypeService
					.findNamesByCourseId(list_questionType);
			model.addObject("ls_questionType", ls_questionType);
		}
		List<Book> ls_book = bookService.findBooksInCourse(question.getCourseId());
		model.addObject("ls_book", ls_book);
		return model;
	}
	
	@RequestMapping("/getById/{id}")
	@ResponseBody
	public Question getById(@PathVariable Integer id) {
		Question question = questionService.searchById(id); 
		if(question != null){
			List<QuestionOption> options = questionOptionServiceImpl.findByQuestionId(question.getId());
			question.setOptions(options);
		}
		General.quesWordToHtmlForShow(question);
		return question;
	}
	
	/**
	 * 选中试题的时候根据id得到question对象和关联的options
	 * @param request
	 * @param response
	 * @param id
	 */
	@RequestMapping("/checkQuestion/{id}")
	public void checkQuestion(HttpServletRequest request,HttpServletResponse response, @PathVariable int id,int paperId,int quesTypeId,double score,String quesOperType,Integer paperDetailId){
		JSONObject object = new JSONObject();
		try{
			Question question=questionService.searchById(id);
			if(questionService.checkAllowAddIntoPaper(question, paperId, quesTypeId, score, quesOperType, paperDetailId)){
				List<QuestionOption> options=questionOptionServiceImpl.findByQuestionId(id);
				question.setOptions(options);
				General.quesWordToHtmlForShow(question);
				
				object.put("type", "success");
				object.put("question", question);
			}else{
				object.put("type", "fail");
				object.put("msg", "该题不允许添加到试卷中，原因：该题不符合细目表规则。");
			}
		}catch(Exception e){
			object.put("type", "fail");
			object.put("msg", e.getMessage());
			e.printStackTrace();
		}finally{
			this.outJsonString(response, object.toString());
		}
	}
	
	/**
	 * 根据所属角色进行操作试题状态并进行记录日志
	 * @param request
	 * @param response
	 * @param qol
	 */
	@RequestMapping("/submitAudit")
	public void submitAudit(HttpServletRequest request,
			HttpServletResponse response,@RequestBody QuestionOperationLog qol){
		Role role = (Role) request.getSession().getAttribute(
				WebConstants.WEB_SESSION_ROLE);
		User user = (User) request.getSession().getAttribute(
				WebConstants.WEB_SESSION_USER);
		qol.setCreatedBy(user.getId());
		Question question =new Question();
		question.setId(qol.getQuestionId());
		JSONObject object = new JSONObject();
		if(qol.getOperationCode().equals("allow")){
			if(role.getCode().equals("AUDIT_TEACHER")){
				question.setStatusCode(QuestionStatusEnum.QUESTION_APPROVED.getKey());
				qol.setOperationCode(QuestionStatusEnum.QUESTION_APPROVED.getValue());
				qol.setCreateTime(new Date());
				object.put("status", QuestionStatusEnum.QUESTION_APPROVED.getValue());
			}else if(role.getCode().equals("SECRETARY")){
				question.setStatusCode(QuestionStatusEnum.QUESTION_FINAL_APPROVED.getValue());
				qol.setOperationCode(QuestionStatusEnum.QUESTION_FINAL_APPROVED.getKey());
				qol.setCreateTime(new Date());
				object.put("status", QuestionStatusEnum.QUESTION_FINAL_APPROVED.getValue());
			}
			questionService.updateStatusCode(question);
			//记录操作日志
			questionOperationLogService.recordLog(qol);
		}else {
			if(role.getCode().equals("AUDIT_TEACHER")){
				question.setStatusCode(QuestionStatusEnum.QUESTION_REJECTED.getKey());
				qol.setOperationCode(QuestionStatusEnum.QUESTION_REJECTED.getValue());
				qol.setCreateTime(new Date());
				object.put("status", QuestionStatusEnum.QUESTION_REJECTED.getValue());
			}else if(role.getCode().equals("SECRETARY")){
				question.setStatusCode(QuestionStatusEnum.QUESTION_FINAL_REJECTED.getKey());
				qol.setOperationCode(QuestionStatusEnum.QUESTION_FINAL_REJECTED.getValue());
				qol.setCreateTime(new Date());
				object.put("status", QuestionStatusEnum.QUESTION_FINAL_REJECTED.getValue());
			}
			questionService.updateStatusCode(question);
			//记录操作日志
			questionOperationLogService.recordLog(qol);
		}
		object.put("type", "success");
		this.outJsonString(response, object.toString());
	}

	/**
	 * 新增试题
	 * 
	 * @param request
	 * @param question
	 *            试题信息
	 * @param arr
	 *            选项信息
	 */
	@RequestMapping("/insert")
	public void insert(HttpServletRequest request,
			HttpServletResponse response, @RequestBody String data) {
		JSONObject obj = JSONObject.fromObject(data);
		JSONObject queObj = obj.getJSONObject("Question");
		
		String[] dateFormats = new String[] {"yyyy-MM-dd"};  
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats)); 
		
		Question question = (Question) queObj.toBean(queObj, Question.class);
		question.setCreatedTime(new Date());
		question.setBodyWord(new byte[0]);
		question.setAnswerWord(new byte[0]);
		
		question.setRemark(General.removeHTMLCode(question.getRemark()));//把前端传入后端的脚本过滤
		String arr = obj.getString("arr");
		question.setStatusCode(QuestionStatusEnum.QUESTION_DRAFT.getKey()); // 命题状态
		
		int result = questionService.insertQuestion(question);
		
//		Question qu=questionService.searchById(question.getId());
//		new AppendLuceneIndex().appendSingleIndex(qu);		//新增试题即创建索引文件  存在一个问题新增试题成功后需返回questionId 然后处理索引信息
		if (result > 0) {
			// 增加附件信息
			List<QuestionAttachment> ls = addQuestionAttachment(question.getCreatedTime(), question.getCreatedBy(),
					question.getId());
			for (QuestionAttachment qa : ls) {
				questionAttachmentService.saveAttachment(qa);
			}

			// 增加选择表数据
			if (arr != "") {
				JSONArray array = JSONArray.fromObject(arr);
				for (int i = 0; i < array.size(); i++) {
					JSONObject object = JSONObject.fromObject(array.get(i));
					QuestionOption qo = new QuestionOption(question.getId(),
							object.getInt("optionNo"),
							object.getInt("isCorrectOption"),
							object.getString("content"),
							object.getString("summary"),
							question.getCreatedTime(), question.getCreatedBy(),
							question.getUpdatedTime(), question.getUpdatedBy());
					questionOptionServiceImpl.saveQuestionOption(qo);
				}
			}
			// 记录日志
			QuestionOperationLog qol = new QuestionOperationLog(
					question.getId(), "insert", question.getVersion(),
					question.getRemark(), question.getCreatedTime(),
					question.getCreatedBy());
			questionOperationLogService.recordLog(qol);
		}
		JSONObject object = new JSONObject();
		object.put("id", question.getId());
		object.put("success", "success");
		this.outJsonString(response, object.toString());
	}
	
	@RequestMapping("/zujuanSave")
	@ResponseBody
	public Map<String, Object> zujuanSave(HttpSession session, @RequestBody String data,int paperId,int quesTypeId,Integer paperDetailId) {
		try{
			User curUser = getCurUser(session);
			JSONObject obj = JSONObject.fromObject(data);
			JSONObject queObj = obj.getJSONObject("Question");
			
			String[] dateFormats = new String[] {"yyyy-MM-dd"};  
			JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats)); 
			
			Question question = (Question) queObj.toBean(queObj, Question.class);
			List<QuestionOption> options = null;
			{
				String arr = obj.getString("arr");
				options=new ArrayList<QuestionOption>();
				// 增加选择表数据
				if (arr != "") {
					JSONArray array = JSONArray.fromObject(arr);
					for (int i = 0; i < array.size(); i++) {
						JSONObject object = JSONObject.fromObject(array.get(i));
						QuestionOption qo = new QuestionOption(question.getId(),
								object.getInt("optionNo"),
								object.getInt("isCorrectOption"),
								object.getString("content"),
								object.getString("summary"),
								new Date(), curUser.getId(),
								new Date(), curUser.getId());
						options.add(qo);
					}
				}
				question.setOptions(options);
			}

			question.setBodyWord(new byte[]{});
			question.setBodySummary(General.extractText(question.getBody()));
			question.setAnswerWord(new byte[]{});
			question.setAnswerSummary(General.extractText(question.getAnswer()));
			if (question.getOptions() != null && question.getOptions().size() > 0) {
				for(QuestionOption qo:question.getOptions()){
					qo.setContentWord(new byte[]{});
					qo.setSummary(General.extractText(qo.getContent()));
				}
			}
			
			question = questionService.zujuanSave(question, curUser,paperId,quesTypeId,paperDetailId);
			Map<String,Object> resultMap = successResult("保存试题成功");
			
			resultMap.put("question", question);
			resultMap.put("id", question.getId());
			return resultMap;
		}catch(Exception e){
			log.error("保存试题失败，原因:" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	@RequestMapping("/calcRestQuesDetails")
	@ResponseBody
	public Map<String, Object> calcRestQuesDetails(HttpSession session, int paperId,int quesTypeId,double score) {
		try {
			List<PaperSkeletonDetail> restQuesDetails = questionService.calcRestQuesDetails(paperId, quesTypeId, score);
			Map<String,Object> resultMap = successResult("查询剩余题量成功");
			resultMap.put("restQuesDetails", restQuesDetails);
			return resultMap;
		}catch(Exception e){
			log.error("查询剩余题量失败，原因:" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	@RequestMapping("/calcAllRestQuesDetails")
	@ResponseBody
	public Map<String, Object> calcAllRestQuesDetails(HttpSession session, int paperId) {
		try {
			List<PaperSkeletonDetail> allRestQuesDetails = questionService.calcAllRestQuesDetails(paperId);
			Map<String,Object> resultMap = successResult("查询剩余题量成功");
			resultMap.put("allRestQuesDetails", allRestQuesDetails);
			return resultMap;
		}catch(Exception e){
			log.error("查询剩余题量失败，原因:" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	@RequestMapping("/changeQuesAttr")
	@ResponseBody
	public Map<String, Object> changeQuesAttr(HttpSession session, int quesId,String estimateDifficultyCode,String abilityCode,String chapterNo) {
		try {
			Question question = new Question();
			question.setId(quesId);
			question.setEstimateDifficultyCode(estimateDifficultyCode);
			question.setAbilityCode(abilityCode);
			question.setChapter(chapterNo);
			question.setUpdatedBy(this.getCurUser(session).getId());
			questionService.update(question);
			Map<String,Object> resultMap = successResult("更新试题属性成功");
			return resultMap;
		}catch(Exception e){
			log.error("更新试题属性失败，原因:" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	/**
	 * 删除此题，如果此题已被试卷使用，则不能被删除
	 * @param session
	 * @param quesId
	 * @return
	 */
	@RequestMapping("/delQues")
	@ResponseBody
	public Map<String, Object> delQues(HttpSession session, int quesId) {
		try {
			questionService.delQues(quesId, this.getCurUser(session));
			Map<String,Object> resultMap = successResult("删除试题成功");
			return resultMap;
		}catch(Exception e){
			log.error("删除试题失败，原因:" + e.getMessage(), e);
			return failedResult(e);
		}
	}
	
	/**
	 * 更新试题
	 * @param request
	 * @param response
	 * @param data
	 */
	@RequestMapping("/update")
	public void updateQuestion(HttpServletRequest request,
			HttpServletResponse response, @RequestBody String data) {
		JSONObject obj = JSONObject.fromObject(data);
		JSONObject queObj = obj.getJSONObject("Question");
		
		String[] dateFormats = new String[] {"yyyy-MM-dd"};  
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats)); 
		
		Question question = (Question) queObj.toBean(queObj, Question.class);
		question.setBodyWord(null);
		question.setAnswerWord(null);
		question.setUpdatedTime(new Date());
		
		question.setRemark(General.removeHTMLCode(question.getRemark()));//把前端传入后端的脚本过滤
		String arr = obj.getString("arr");
		
		if(question.getStatusCode().equals("QUESTION_REJECTED")||question.getStatusCode().equals("QUESTION_FINAL_REJECTED")){
			question.setStatusCode("QUESTION_DRAFT");
		}
		questionService.update(question);
		
		
//		AppendLuceneIndex lucene=new AppendLuceneIndex();
//		lucene.deleteIndex(String.valueOf(question.getId()));//先删除相应id的索引 
//		Question qu=questionService.searchById(question.getId());
//		lucene.appendSingleIndex(qu); 		//然后创建新索引

		// 增加附件信息
		List<QuestionAttachment> ls = addQuestionAttachment(question.getCreatedTime(), question.getCreatedBy(),
				question.getId());
		for (QuestionAttachment qa : ls) {
			questionAttachmentService.saveAttachment(qa);
		}

		// 先删除原来选项、然后再进行添加
		if (arr != "") {
			JSONArray array = JSONArray.fromObject(arr);
			for (int i = 0; i < array.size(); i++) {
				JSONObject object = JSONObject.fromObject(array.get(i));
				if (object.get("id") == null) {
					QuestionOption qo = new QuestionOption(question.getId(),
							object.getInt("optionNo"),
							object.getInt("isCorrectOption"),
							object.getString("content"),
							object.getString("summary"),
							question.getCreatedTime(), question.getCreatedBy(),
							question.getUpdatedTime(), question.getUpdatedBy());
					questionOptionServiceImpl.saveQuestionOption(qo);
				} else {
					QuestionOption qo = new QuestionOption(object.getInt("id"),
							question.getId(), object.getInt("optionNo"),
							object.getInt("isCorrectOption"),
							object.getString("content"),
							object.getString("summary"),
							question.getCreatedTime(), question.getCreatedBy(),
							question.getUpdatedTime(), question.getUpdatedBy());
					qo.setContentWord(null);
					questionOptionServiceImpl.update(qo);
				}
			}
		}
		// 记录日志
		QuestionOperationLog qol = new QuestionOperationLog(question.getId(),
				"update", question.getVersion(), question.getRemark(),
				question.getCreatedTime(), question.getCreatedBy());
		questionOperationLogService.recordLog(qol);

		JSONObject object = new JSONObject();
		object.put("id", question.getId());
		object.put("type", "success");
		this.outJsonString(response, object.toString());
	}

	/**
	 * 复制新增试题
	 * @param request
	 * @param response
	 * @param question
	 */
	@RequestMapping("/copyAdd")
	public void copyAdd(HttpServletRequest request,HttpServletResponse response, @RequestBody Question question) {
		Question qu = questionService.searchById(question.getId());
		Role role = (Role) request.getSession().getAttribute(
				WebConstants.WEB_SESSION_ROLE);
		User user = (User) request.getSession().getAttribute(
				WebConstants.WEB_SESSION_USER);
		if(role.getCode().equals("PROPOSITION_TEACHER")||role.getCode().equals("AUDIT_TEACHER")){
			qu.setSetBy(user.getId());
			qu.setSetTeacherName(user.getName());
		}
		qu.setStatusCode(QuestionStatusEnum.QUESTION_DRAFT.getKey());
		questionService.insertQuestion(qu);
		
//		new AppendLuceneIndex().appendSingleIndex(question);
		
		int result=qu.getId();
		List<QuestionOption> options = null;
		if (qu.getTypeId() == 1 || qu.getTypeId() == 2) {
			options = questionOptionServiceImpl.findByQuestionId(question
					.getId());
		}
		//复制选项按钮
		if(options!=null){
			for(QuestionOption qo:options){
				qo.setQuestionId(qu.getId());
				questionOptionServiceImpl.saveQuestionOption(qo);
			}
		}
		
		
		List<QuestionAttachment> atts = null;
		atts = questionAttachmentService.queryByQuestionId(question.getId());
		if(atts!=null){
			for(QuestionAttachment qa:atts){
				qa.setParentId(qu.getId());
				questionAttachmentService.saveAttachment(qa);
			}
		}
		
		// 记录日志
		QuestionOperationLog qol = new QuestionOperationLog(qu.getId(),
				"copyAdd", question.getVersion(), question.getRemark(),
				question.getCreatedTime(), question.getCreatedBy());
		questionOperationLogService.recordLog(qol);
		JSONObject object = new JSONObject();
		object.put("id", result);
		object.put("success", "success");
		this.outJsonString(response, object.toString());
	}

	/**
	 * 添加附件信息
	 * 
	 * @param request
	 * @param createTime
	 *            创建时间
	 * @param createBy
	 *            创建者
	 * @param parentId
	 *            父类型id
	 * @return
	 */
	private List<QuestionAttachment> addQuestionAttachment(Date createTime, int createBy,
			int parentId) {
		String realPath=ParamUtils.TemporaryDirPath;
		realPath += "upload/";
		List<QuestionAttachment> ls = new ArrayList<QuestionAttachment>();
		File file = new File(realPath);
		if (file.exists()) {
			String[] files = file.list();
			for (String ss : files) {
				QuestionAttachment qa = new QuestionAttachment();
				try {
					InputStream is = new FileInputStream(realPath + ss);
					int length = is.available();
					byte[] bytes = new byte[length];
					is.read(bytes);

					is.close();

					qa.setName(ss);
					qa.setSize(length);
					qa.setContent(bytes);
					qa.setCheckCode(String.valueOf(bytes.hashCode()));
					qa.setCreatedTime(createTime);
					qa.setCreatedBy(createBy);
					qa.setParentId(parentId);
					ls.add(qa);

				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			// 遍历完成后删除所有文件
			for (String ss : files) {
				File ff = new File(realPath + ss);
				ff.delete();
			}
		}
		return ls;
	}
	
	/**
	 * 导入QMQ文件
	 * @param request
	 * @param mode
	 * @return
	 */
	@RequestMapping("/import")
	public String importQMQFile(HttpServletRequest request, Model mode) {
		User user = (User) request.getSession().getAttribute(
				WebConstants.WEB_SESSION_USER);
		mode.addAttribute("user", user);
		return "/question/import";
	}
	
	/**
	 * 跳转到导入历史页面
	 * @param request
	 * @param mode
	 * @return
	 */
	@RequestMapping("/importHistory")
	public String importQMQFileHistory(HttpServletRequest request, Model mode) {
		return "/question/importHistory";
	}
	
	@RequestMapping("/queryAudit")
	@ResponseBody
	public void queryAudit(HttpServletRequest request,HttpServletResponse response, @RequestParam int id){
		JSONObject object =new JSONObject();
		try{
			JSONArray array=new JSONArray();
			List<QuestionOperationLog> list=questionOperationLogService.queryLogs(id);
			array.add(list);
			object.put("flag", "success");
//			object.putAll(array);
//			object.
		}catch(Exception e){
			object.put("flag", "failed");
			object.put("msg", e.getMessage());
			e.printStackTrace();
		}
		this.outJsonString(response, object.toString());
	}
	
	private JSONArray getRows(List<QuestionType> list,int chapterSize,int courseId,int bookId){
		JSONArray rows=new JSONArray();
		
		for(int j=0;j<list.size();j++){
			JSONObject obj=new JSONObject();
//			if(j==list.size()){
//				for(int i=0;i<chapterSize;i++){
//					Question question=new Question();
//					question.setBookId(bookId);
//					question.setCourseId(courseId);
//					question.setChapter(String.valueOf(i));
//					int count=questionService.getCountByChapter(question);
//					obj.put("questionCount"+i, count);
//				}
//				obj.put("name", "汇总");
//			}else{
				int total=0;
				for(int i=0;i<chapterSize;i++){
					Question question=new Question();
					question.setBookId(bookId);
					question.setCourseId(courseId);
					question.setTypeId(list.get(j).getId());
					question.setChapter(String.valueOf(i));
					
					int count=questionService.getCountByCondition(question);
					total+=count;
					obj.put("questionCount"+i, count);
				}
				obj.put("questionTypeTotalCount", total);
				
				obj.put("name", list.get(j).getName());
//			}
			rows.add(obj);
		}
		return rows;
	}
	
	@RequestMapping("/getReport")
	public String getReport(String courseCode, Model model){

		if(null == courseCode || courseCode.equals(""))
			model.addAttribute("errorMsg", "请输入课程代码！");
		else{
			Course course = courseService.findByCode(courseCode);
			if(course == null){
				model.addAttribute("errorMsg", courseCode + " 课程代码在数据库中不存在！");
			}else{
				List<QuestionType> questionTypes=questionTypeService.queryByCourseId(course.getId());
				int chapter=questionService.getMaxChapterByCourseId(course.getId());
				List<HashMap<String, Object>> quesCountMapList = questionService.getCountByCourseIdGroupByQuesTypeAndChapter(course.getId());
				
				HashMap<String, Long> quesCountMap = new HashMap<String, Long>();
				
				long total = 0;
				for(HashMap<String, Object> map : quesCountMapList){
					String mapKey = "qtChapterCount_" + map.get("quesTypeId") + "_" + map.get("chapter");
					quesCountMap.put(mapKey, (Long)map.get("count"));
					
					String chapterSum = "chapter_" + map.get("chapter");
					String quesTypeSum = "quesTypeSum_" + map.get("quesTypeId");
					if(null == quesCountMap.get(quesTypeSum)){
						quesCountMap.put(quesTypeSum, (Long)map.get("count"));
					}else{
						quesCountMap.put(quesTypeSum, quesCountMap.get(quesTypeSum) + (Long)map.get("count"));
					}
					
					if(null == quesCountMap.get(chapterSum)){
						quesCountMap.put(chapterSum, (Long)map.get("count"));
					}else{
						quesCountMap.put(chapterSum, quesCountMap.get(chapterSum) + (Long)map.get("count"));
					}
					
					total += (Long)map.get("count");
				}
				quesCountMap.put("total", (Long)total);
					
				model.addAttribute("questionTypes", questionTypes);
				model.addAttribute("chapter", chapter);
				model.addAttribute("quesCountMap", quesCountMap);
				model.addAttribute("courseCode", courseCode);
			}
		}
		
		return "/question/report";
	}
	
	@RequestMapping(value="/statAuditorJob")
	@ResponseBody
	public Map<String,Object> statAuditorJob(int courseId){
		try{
			Map<String,Object> resultMap = new HashMap<String, Object>();
			resultMap.put("auditorJob",questionService.statAuditorJobByCourseId(courseId));
			resultMap.put("draftNum",questionService.statDraftQuesNumByCourseId(courseId));
			return resultMap;
		}catch(Exception e){
			log.error("统计课程[id=" + courseId + "]的审核数据失败，原因：" + e.getMessage(), e);
			return failedResult("统计课程的审核数据失败");
		}
	}
	
	@RequestMapping(value="/statMyAuditJob")
	@ResponseBody
	public Map<String,Object> statMyAuditJob(HttpSession session){
		int userId = this.getCurUser(session).getId();
		try{
			Map<String,Object> resultMap = new HashMap<String, Object>();
			resultMap.put("auditJob",questionService.statMyAuditJob(userId));
			return resultMap;
		}catch(Exception e){
			log.error("统计个人所有负责的课程[id=" + userId + "]的审核数据失败，原因：" + e.getMessage(), e);
			return failedResult("统计个人所有负责的课程的审核数据失败");
		}
	}
	
	@RequestMapping(value="/statMyInputJob")
	@ResponseBody
	public Map<String,Object> statMyInputJob(HttpSession session){
		int userId = this.getCurUser(session).getId();
		try{
			Map<String,Object> resultMap = new HashMap<String, Object>();
			resultMap.put("inputJob",questionService.statMyInputJob(userId));
			return resultMap;
		}catch(Exception e){
			log.error("统计个人所有负责的课程[id=" + userId + "]的录题数据失败，原因：" + e.getMessage(), e);
			return failedResult("统计个人所有负责的课程的录题数据失败");
		}
	}
	
	@RequestMapping(value="/getNewQuestionNo/{courseCode}")
	@ResponseBody
	public Map<String, Object> getNewQuestionNo(@PathVariable String courseCode){
		Map<String,Object> resultMap = new HashMap<String, Object>();
		resultMap.put("questionNo", General.getNewQuestionNo(courseCode));
		return resultMap;
	}
	
	@RequestMapping(value="/getNewQuestionNoByCourseId/{courseId}")
	@ResponseBody
	public Map<String, Object> getNewQuestionNoByCourseId(@PathVariable int courseId){
		Map<String,Object> resultMap = new HashMap<String, Object>();
		Course course = courseService.findById(courseId);
		resultMap.put("questionNo", General.getNewQuestionNo(course.getCode()));
		return resultMap;
	}
	
	@RequestMapping(value="/checkAllQuestions")
	public void preview(HttpServletResponse response){
		StringBuffer info = new StringBuffer();
		info.append("<head><title>试题及选项数据检查结果</title><style>");
		info.append(".boderTbl {border-collapse:collapse;border:none;}");
		info.append(".boderTbl th{text-align:center;vertical-align:middle;border:1px solid #000000;padding:0px;}");
		info.append(".boderTbl td{text-align:left;vertical-align:middle;border:1px solid #000000;padding:0px;}");
		info.append("</style></head>");
		info.append("<table class=\"boderTbl\"><tr><th nowrap=\"nowrap\">序号</th><th>DB</th><th>题号</th><th>题干</th><th>问题描述</th></tr>");
		try {
			int num = 0;
			for(Integer quesId : questionService.findAllQuestionIds()){
				Question ques = questionService.searchQuestionWithOptionsById(quesId);
				if(ques == null){
					continue;
				}
				boolean bodySame = General.extractText(ques.getBody()).equals(General.null2String(ques.getBodySummary()));
				boolean answerSame = General.extractText(ques.getAnswer()).equals(General.null2String(ques.getAnswerSummary()));
				boolean optSame = true;
				if(ques.getOptions() != null){
					for(QuestionOption qo:ques.getOptions()){
						optSame = General.extractText(qo.getContent()).equals(General.null2String(qo.getSummary()));
						if(!optSame){
							break;
						}
					}
				}
				if(!bodySame || !answerSame || !optSame){
					info.append("<tr>");
					info.append("<td>").append(++num).append("</td>");
					info.append("<td>").append(ques.getId()).append("</td>");
					info.append("<td>").append(ques.getQuestionNo()).append("</td>");
					info.append("<td>").append(ques.getBody()).append("</td>");
					info.append("<td>");
					if(!bodySame){
						info.append("题干不匹配；");
					}
					if(!answerSame){
						info.append("答案不匹配；");
					}
					if(!optSame){
						info.append("选项不匹配；");
					}
					info.append("</td>");
					info.append("</tr>");
				}
			}
		} catch (Exception e) {
			log.info("--检查试题及选项出现异常，原因：" + e.getMessage(),e);
			info.append("<tr>");
			info.append("<td colspan=\"4\">").append("检查试题及选项出现异常，原因：" + e.getMessage()).append("</td>");
			info.append("</tr>");
		}
		info.append("</table>");
		try {
    		response.setCharacterEncoding("UTF-8");
    		response.setContentType("text/html;charset=UTF-8");
    		response.getWriter().append(info);
		} catch (Exception e) {
			log.warn("显示检查日志出现异常：" + e.getMessage(),e);
		}
	}
	
	@RequestMapping(value="/impQues")
	@ResponseBody
	public Map<String, Object> impQuesFromDocx(int attId,HttpSession session){
		try{
			Map<String,Object> resultMap = new HashMap<String, Object>();
			resultMap.put("logs",questionService.impQuesFromDocx(attId,this.getCurUser(session)));
			return resultMap;
		}catch(Exception e){
			log.error("导入试题文件[id=" + attId + "]出现了未知异常，原因：" + e.getMessage(), e);
			return failedResult("导入试题文件出现了未知异常，原因：" + e.getMessage());
		}
	}
	
	/**
	 * 检查所有试题相似度
	 * 
	 */
	@RequestMapping("/checkSimilarity")
	@ResponseBody
	public Map<String, Object> checkSimilarity() {
		List<SimilarQuestion> resultList = questionService.checkSimilarity();
		Map<String, Object> result = new HashMap<String, Object>();
		questionService.delAllQuestionSimilarity();
		questionService.addQuestionSimilarity(resultList);
		result.put("flag", "success");
		return result;
	}
	
	/**
	 * 检查指定题目相似度
	 * 
	 */
	@RequestMapping("/specifyCheckSimilarity")
	@ResponseBody
	public Map<String, Object> specifyCheckSimilarity(Integer course_id, Integer type_id, String quesBody) {
		Map<String, Object> resultMap = successResult("检查选项相似度");
		List<SimilarQuestion> resultList = questionService.specifyCheckSimilarity(course_id, type_id, quesBody);
		resultMap.put("allSimilarQuestion", resultList);
		return resultMap;
	}
	
	@RequestMapping(value="/queryQuestionSimilarity")
	@ResponseBody
	public Map<String, Object> queryQuestionSimilarity(@RequestBody QuestionSimilarityQueryParams params){
		Map<String,Object> result = new HashMap<String, Object>();
		List<SimilarQuestion> similarQuestion = questionService.queryQuestionSimilarity(params);
		int total = questionService.queryQuestionSimilarityCount(params);
		result.put("rows", similarQuestion);
		result.put("total", total);
		return result;
	}
	
	//查询试卷选择题答案占比
	@RequestMapping(value="/queryKeyTJ")
	@ResponseBody
	public Map<String, Object> queryQuestionKeyTJ(String pager_name){
		Map<String,Object> result = new HashMap<String, Object>();
		List<Question> list = questionService.queryQuestionKeyTJ(pager_name);
		result.put("rows", list);
		return result;
	}
	
	@RequestMapping(value="/queryQuestionSimilarityById/{questionId}")
	@ResponseBody
	public Map<String, Object> queryQuestionSimilarityById(@PathVariable int questionId){
		Map<String,Object> result = new HashMap<String, Object>();
		Question question = questionService.searchQuestionWithOptionsById(questionId);
		result.put("question", question);
		return result;
	}
}