outfox.dict.contest.service.ContestService.java Source code

Java tutorial

Introduction

Here is the source code for outfox.dict.contest.service.ContestService.java

Source

/**
 * @(#)ContestService.java, 2016-3-2. 
 * 
 * Copyright 2016 Yodao, Inc. All rights reserved.
 * YODAO PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package outfox.dict.contest.service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import outfox.dict.contest.dao.ContestDAO;
import outfox.dict.contest.data.*;
import outfox.dict.contest.front.data.ContestConsts;
import outfox.dict.contest.front.data.RequestParams;
import outfox.dict.contest.front.data.Result;
import outfox.dict.contest.util.ContestUtil;
import outfox.dict.contest.util.FileUtils;
import outfox.dict.contest.util.HttpToolKit;
import outfox.dict.contest.util.ImageUtils;

/**
 *
 * @author wangning
 *
 */
@Service
public class ContestService {

    private static final Logger LOG = Logger.getLogger(ContestService.class);

    @Autowired
    private ContestDAO contestDAO;

    @Autowired
    private RedisClient redisClient;

    @Autowired
    private CrontabService crontabService;

    public int user(UserEntity singerEntity) {
        return contestDAO.user(singerEntity);
    }

    /**
     * ??
     * @param singerEntity
     * @param callback
     * @return
     */
    public String signup(HttpServletRequest req, SingerEntity singerEntity, RequestParams params) {
        String callback = params.getCallback(); // jsonp?
        String userId = ContestUtil.getUserId(req); // ?
        boolean limitLogin = params.isLimitLogin(); // ??
        int state = params.getState();
        // state0state1?
        if (state == 0) {
            // 
            if (StringUtils.isBlank(userId) && limitLogin) {
                return Result.NOT_LOGIN.json(null, callback);
            }
        } else {
            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, callback);
            }
        }

        HttpResponse response = null;
        try {
            // ????
            singerEntity.setUserId(userId);
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            singerEntity.setSingupTime(timestamp);

            // 1: ?
            contestDAO.signup(singerEntity);

            // 2: ??
            String content = "{\"id\": " + singerEntity.getId() + ", \"name\": \"" + singerEntity.getName()
                    + "\", \"school\": \"" + singerEntity.getSchool() + "\", \"areaName\": \""
                    + singerEntity.getAreaName() + "\", \"audioUrl\": \"" + singerEntity.getAudioUrl()
                    + "\", \"musicName\": \"" + singerEntity.getMusicName() + "\", \"state\": "
                    + singerEntity.getState() + "}";
            List<NameValuePair> paramsList = new ArrayList<NameValuePair>();
            paramsList.add(new BasicNameValuePair("voteId", ContestConsts.VOTE_ID));
            paramsList.add(new BasicNameValuePair("content", content));
            paramsList.add(new BasicNameValuePair("picture", singerEntity.getPhotoUrl()));
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramsList, "UTF-8");
            response = HttpToolKit.getInstance().doPost(ContestConsts.ADD_VOTE_OPTION_INTERFACE, entity);
            JSONObject resObj = null;
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    resObj = JSON.parseObject(EntityUtils.toString(resEntity));
                }
            }
            int optionId = 0;
            if (resObj != null) {
                optionId = resObj.getJSONObject("data").getIntValue("optionId");
            }

            // 3: redis
            String optionVoteKey = ContestConsts.VOTE_OPTION_PREFIX_KEY + ContestConsts.VOTE_ID;
            Map<String, String> optionNumMap = new HashMap<String, String>();
            optionNumMap.put(String.valueOf(optionId), "0");
            if (redisClient.notExists(optionVoteKey)) {
                // miss cache
                redisClient.hmset(optionVoteKey, optionNumMap, ContestConsts.EXPIRE_SECONDS);
            } else {
                // hit cache
                redisClient.hmset(optionVoteKey, optionNumMap);
            }

            // 4: 
            JSONObject dataObj = new JSONObject();
            dataObj.put("id", optionId);
            return Result.SUCCESS.json(dataObj, callback);
        } catch (Exception e) {
            LOG.error("ContestService.signup error...", e);
        } finally {
            HttpToolKit.closeQuiet(response);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * 
     * @param request
     * @param callback
     * @return
     */
    public String uploadImg(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback(); // jsonp?
        String userId = ContestUtil.getUserId(req); // ?
        boolean limitLogin = params.isLimitLogin(); // ??
        // 
        if (StringUtils.isBlank(userId) && limitLogin) {
            return Result.NOT_LOGIN.json(null, callback);
        }

        try {
            byte[] image = ImageUtils.decodeBase64(req.getParameter("photo"));
            String photourl = ImageUtils.imageToOimage(image);
            JSONObject dataObj = new JSONObject();
            dataObj.put("photourl", photourl);
            return Result.SUCCESS.json(dataObj, callback);
        } catch (ExceptionService e) {
            if (ContestConsts.IMG_ERROR_CODE.equals(e.getErrorCode())) {
                return Result.IMG_ERROR.json(null, callback);
            } else {
                return Result.IMG_EXCEEDSIZE.json(null, callback);
            }
        } catch (Exception e) {
            LOG.error("ContestService.uploadimg error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * 
     * @param file
     * @param callback
     * @return
     */
    public String uploadAudio(HttpServletRequest req, MultipartFile file, RequestParams params) {
        String callback = params.getCallback(); // jsonp?
        String userId = ContestUtil.getUserId(req); // ?
        boolean limitLogin = params.isLimitLogin(); // ??
        // 
        if (StringUtils.isBlank(userId) && limitLogin) {
            return Result.NOT_LOGIN.json(null, callback);
        }

        try {
            String audiourl = FileUtils.uploadFile2Nos(file.getBytes());
            JSONObject dataObj = new JSONObject();
            dataObj.put("audiourl", audiourl);
            return Result.SUCCESS.json(dataObj, callback);
        } catch (Exception e) {
            LOG.error("ContestService.uploadAudio error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ??
     * @param callback
     * @return
     */
    public String listContestAreas(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback(); // jsonp?
        int period = params.getPeriod();
        try {
            List<AreaEntity> areaList = contestDAO.listContestAreas(period);
            if (areaList == null) {
                return Result.NOT_FOUND.json(null, callback);
            }
            JSONArray array = (JSONArray) JSONObject.toJSON(areaList);
            return Result.SUCCESS.json(array, callback);
        } catch (Exception e) {
            LOG.error("ContestService.listContestAreas error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ??
     * @param id
     * @param callback
     * @return
     */
    public String getSingerInfo(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback(); // jsonp?
        String key = ContestConsts.SINGER_INFO_PREFIX_KEY + params.getId();
        try {
            String singerInfo = crontabService.getSingerInfoMap().get(key);
            if (singerInfo == null) {
                return Result.NOT_FOUND.json(null, callback);
            }
            JSONObject jsonObj = JSON.parseObject(singerInfo);
            return Result.SUCCESS.json(jsonObj, callback);
        } catch (Exception e) {
            LOG.error("ContestService.getSingerInfo error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?
     * @param req
     * @param params
     * @return
     */
    public String listSingers(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        String areaName = params.getArea();
        String mode = params.getMode();
        int start = params.getStart();
        int end = params.getEnd();
        int state = params.getState();
        try {
            JSONArray jsonArray = null;

            if (StringUtils.isBlank(areaName)) {
                /** 1:  **/
                if ("rank".equals(mode)) {
                    // 1.1 ?
                    jsonArray = getRankListByCon(ContestConsts.RANK_PREFIX_KEY + state, start, end);
                } else {
                    // 1.2??
                    jsonArray = getRandomListByCon(ContestConsts.RANDOM_SHOWN_PREFIX_KEY + state, start, end);
                }
            } else {
                /** 2:  **/
                if ("rank".equals(mode)) {
                    // 2.1: ?
                    jsonArray = getRankListByCon(ContestConsts.RANK_PREFIX_KEY + areaName + ":" + state, start,
                            end);
                } else {
                    // 2.2: ??
                    jsonArray = getRandomListByCon(ContestConsts.RANDOM_SHOWN_PREFIX_KEY + areaName + ":" + state,
                            start, end);
                }
            }
            return Result.SUCCESS.json(jsonArray, callback);
        } catch (Exception e) {
            LOG.error("ContestService.listSingers error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?????
     */
    public JSONArray getRankListByCon(String prefixKey, int start, int end) {
        List<BaseEntity> rankList = crontabService.getSingersRankMap().get(prefixKey);
        if (rankList == null) {
            return null;
        }
        int maxIndex = rankList.size() - 1;
        if (end > maxIndex) {
            end = maxIndex;
        }
        List<SingerEntity> singerList = new ArrayList<SingerEntity>();
        for (int i = start; i <= end; i++) {
            BaseEntity ele = rankList.get(i);
            String singerStr = crontabService.getSingerInfoMap()
                    .get(ContestConsts.SINGER_INFO_PREFIX_KEY + ele.getId());
            singerList.add(JSON.parseObject(singerStr, SingerEntity.class));
        }
        return (JSONArray) JSON.toJSON(singerList);
    }

    /**
     * ????
     */
    public JSONArray getRandomListByCon(String prefixKey, int start, int end) {
        List<Integer> randomList = (List<Integer>) crontabService.getSingersRandomMap().get(prefixKey);
        if (randomList == null) {
            return null;
        }
        int maxIndex = randomList.size() - 1;
        if (end > maxIndex) {
            end = maxIndex;
        }
        List<SingerEntity> singerList = new ArrayList<SingerEntity>();
        for (int i = start; i <= end; i++) {
            Integer ele = randomList.get(i);
            String singerStr = crontabService.getSingerInfoMap().get(ContestConsts.SINGER_INFO_PREFIX_KEY + ele);
            singerList.add(JSON.parseObject(singerStr, SingerEntity.class));
        }
        return (JSONArray) JSON.toJSON(singerList);
    }

    /**
     * ?
     * @param params
     * @return
     */
    public String addVote(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        String optionId = params.getOptionId();
        int period = params.getPeriod();
        String userId = ContestUtil.getUserId(req);

        // ?
        if (StringUtils.isBlank(userId)) {
            return Result.NOT_LOGIN.json(null, callback);
        }

        HttpResponse response = null;
        try {

            // ?
            String singerStr = crontabService.getSingerInfoMap()
                    .get(ContestConsts.SINGER_INFO_PREFIX_KEY + optionId);
            SingerEntity singer = JSON.parseObject(singerStr, SingerEntity.class);
            long startTime = singer.getStartTime();
            long endTime = singer.getEndTime();
            long curTime = System.currentTimeMillis();
            if (curTime < startTime || curTime > endTime) {
                return Result.VOTE_EXCEEDTIME.json(null, callback);
            }

            int voteNum = 0;

            /** 1:  **/
            response = HttpToolKit.getInstance()
                    .doGet(ContestConsts.ADD_VOTE_INTERFACE + userId + "&optionIds=" + optionId);
            if (response != null) {
                HttpEntity addVoteEntity = response.getEntity();
                if (addVoteEntity != null) {
                    JSONObject json = JSON.parseObject(EntityUtils.toString(addVoteEntity));
                    JSONObject result = json.getJSONObject("result");
                    String code = result.getString("code");
                    if ("200".equals(code)) {
                        JSONArray dataArray = json.getJSONArray("data");
                        if (dataArray != null) {
                            JSONObject dataObj = dataArray.getJSONObject(0);
                            if (dataObj != null) {
                                voteNum = dataObj.getIntValue("voteNum");
                            }
                        }
                    } else if ("40003".equals(code)) {
                        return Result.VOTE_ISVOTED.json(null, callback);
                    } else {
                        return Result.SERVER_ERROR.json(null, callback);
                    }
                }
            }

            /** 2: ? **/
            int lotteryNum = 0, remainVoteNum = 0;

            // 2.1: ?
            LotteryUserEntity lotteryUser = contestDAO.getLotteryUserInfo(period, userId);
            if (lotteryUser != null) {
                // 2.2: ?
                lotteryNum = lotteryUser.getLotteryNum();
                remainVoteNum = lotteryUser.getRemainVoteNum() + 1;
                lotteryNum += remainVoteNum / ContestConsts.LOTTERY_NUM_FOR_VOTE;
                remainVoteNum = remainVoteNum % ContestConsts.LOTTERY_NUM_FOR_VOTE;
                lotteryUser.setLotteryNum(lotteryNum);
                lotteryUser.setRemainVoteNum(remainVoteNum);
                lotteryUser.setLastOpTime(new Timestamp(System.currentTimeMillis()));
                contestDAO.updateLotteryUserInfo(lotteryUser);
            } else {
                // 2.3: ??10
                lotteryUser = new LotteryUserEntity();
                lotteryUser.setFirtOpTime(new Timestamp(System.currentTimeMillis()));
                lotteryUser.setLastOpTime(new Timestamp(System.currentTimeMillis()));
                lotteryUser.setPeriod(period);
                lotteryUser.setRemainVoteNum(1);
                lotteryUser.setUserId(userId);
                lotteryUser.setLotteryNum(0);
                contestDAO.addLotteryUserInfo(lotteryUser);
            }
            JSONObject dataObj = new JSONObject();
            dataObj.put("voteNum", voteNum);
            dataObj.put("lotteryNum", lotteryNum);
            return Result.SUCCESS.json(dataObj, callback);
        } catch (Exception e) {
            LOG.error("ContestService.addVote error...", e);
        } finally {
            HttpToolKit.closeQuiet(response);
        }

        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * 
     * @param req
     * @param params
     * @return
     */
    @Transactional
    public String drawAward(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        int period = params.getPeriod();
        String userId = ContestUtil.getUserId(req);
        String userName = ContestUtil.getUserName(req);

        // ?
        if (StringUtils.isBlank(userId)) {
            return Result.NOT_LOGIN.json(null, callback);
        }

        try {
            /** 1: ? **/
            int lotteryNum = 0;
            LotteryUserEntity lotteryUser = contestDAO.getLotteryUserInfo(period, userId);
            if (lotteryUser != null) {
                lotteryNum = lotteryUser.getLotteryNum();
            }
            if (lotteryNum == 0) {
                return Result.LOTTERY_DENIED.json(null, callback);
            }

            JSONObject dataObj = new JSONObject();
            AwardEntity award = null;
            synchronized (this) {
                /** 2: ? **/
                // 2.1: ???
                List<AwardEntity> awardList = contestDAO.getAwardList(period);
                List<Double> probList = new ArrayList<Double>();
                if (awardList != null) {
                    for (AwardEntity ele : awardList) {
                        probList.add(ele.getProb());
                    }
                } else {
                    return Result.AWARD_USEDUP.json(null, callback);
                }
                // 2.2: ??
                RandomService randomService = new RandomService(probList);
                int index = randomService.getRandIndex(); // ?list
                award = awardList.get(index); // ?
                // 2.3: ???
                dataObj.put("min", award.getMin());
                dataObj.put("max", award.getMax());
                dataObj.put("type", award.getAwardType());
                dataObj.put("url", award.getUrl());

                /** 3: ?1? **/
                if (lotteryNum >= 1) {
                    lotteryNum -= 1;
                } else {
                    lotteryNum = 0;
                }
                lotteryUser.setLotteryNum(lotteryNum);
                lotteryUser.setLastOpTime(new Timestamp(System.currentTimeMillis()));
                contestDAO.updateLotteryUserInfo(lotteryUser);
                dataObj.put("lotteryNum", lotteryNum);

                /** 4: ???1 **/
                if (index > 0) {
                    // ?????1
                    int remainNum = award.getRemainNum() - 1;
                    award.setRemainNum(remainNum);
                    contestDAO.updateAwardInfo(award);
                }
            }

            /** 5: ?? **/
            WinAwardEntity winAwardRecord = new WinAwardEntity();
            winAwardRecord.setAwardId(award.getId());
            winAwardRecord.setAwardName(award.getAwardName());
            winAwardRecord.setAwardType(award.getAwardType());
            winAwardRecord.setTimestamp(new Timestamp(System.currentTimeMillis()));
            winAwardRecord.setUserId(userId);
            winAwardRecord.setUserName(userName);
            winAwardRecord.setPeriod(period);
            // ???????
            if (award.getAwardType() == 0) {
                winAwardRecord.setUsed(true);
            }
            contestDAO.addWinAwardRecord(winAwardRecord);

            /** 6: ???? **/
            return Result.SUCCESS.json(dataObj, callback);
        } catch (Exception e) {
            LOG.error("ContestService.drawAward error...", e);
        }

        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?????
     * @param req
     * @param params
     * @return
     */
    public String submitContactInfo(HttpServletRequest req, ContactEntity contactInfo, RequestParams params) {
        String callback = params.getCallback();
        int period = params.getPeriod();
        String userId = ContestUtil.getUserId(req);

        // ?
        if (StringUtils.isBlank(userId)) {
            return Result.NOT_LOGIN.json(null, callback);
        }

        try {
            WinAwardEntity winAwardRecord = null;
            synchronized (this) {
                // 1: ??
                winAwardRecord = contestDAO.getWinAwardRecord(period, userId);
                if (winAwardRecord == null) {
                    return Result.NOT_WINAWARD.json(null, callback);
                }

                // 2: used
                winAwardRecord.setUsed(true);
                contestDAO.updateWinAwardRecord(winAwardRecord);
            }
            // 3: ??
            contactInfo.setSubmitTime(new Timestamp(System.currentTimeMillis()));
            contactInfo.setUserId(userId);
            contactInfo.setWinAwardId(winAwardRecord.getId());
            contactInfo.setAwardId(winAwardRecord.getAwardId());
            contactInfo.setAwardName(winAwardRecord.getAwardName());
            contactInfo.setAwardType(winAwardRecord.getAwardType());
            contactInfo.setIp(ContestUtil.getIpAddr(req));
            contactInfo.setPeriod(period);
            contestDAO.addContactInfo(contactInfo);
            return Result.SUCCESS.json(null, callback);
        } catch (Exception e) {
            LOG.error("ContestService.submitContactInfo error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?????itemNum,itemNum20
     * @param request
     * @param params
     * @return
     */
    public String listWinners(HttpServletRequest request, RequestParams params) {
        String callback = params.getCallback();
        int itemNum = params.getItemNum();
        int period = params.getPeriod();
        boolean noCache = params.isNoCache();

        try {
            String winnerStr = redisClient.get(ContestConsts.WINNERS_PREFIX_KEY);
            JSONArray jsonArray = null;
            if (winnerStr != null && !noCache) {
                // hit cache
                jsonArray = JSONArray.parseArray(winnerStr);
            } else {
                // miss cache
                List<WinAwardEntity> winAwardList = contestDAO.getWinAwardList(period, itemNum);
                if (winAwardList != null) {
                    jsonArray = (JSONArray) JSON.toJSON(winAwardList);
                    redisClient.set(ContestConsts.WINNERS_PREFIX_KEY, jsonArray.toString(),
                            ContestConsts.EXPIRE_PER_MINUTES);
                }
            }
            return Result.SUCCESS.json(jsonArray, callback);
        } catch (Exception e) {
            LOG.error("ContestService.listWinners error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?
     * @param request
     * @param params
     * @return
     */
    public String getLotteryNum(HttpServletRequest request, RequestParams params) {
        String callback = params.getCallback();
        int period = params.getPeriod();
        String userId = ContestUtil.getUserId(request);

        LOG.info("getLotteryNum--userId = " + userId);

        // ?
        if (StringUtils.isBlank(userId)) {
            return Result.NOT_LOGIN.json(null, callback);
        }

        try {
            // 2.1: ?
            LotteryUserEntity lotteryUser = contestDAO.getLotteryUserInfo(period, userId);
            int lotteryNum = 0;
            if (lotteryUser != null) {
                lotteryNum = lotteryUser.getLotteryNum();
            }
            JSONObject dataObj = new JSONObject();
            dataObj.put("lotteryNum", lotteryNum);
            return Result.SUCCESS.json(dataObj, callback);
        } catch (Exception e) {
            LOG.error("ContestService.getLotteryNum error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * 
     * @param req
     * @param params
     * @return
     */
    public String addVoteForInner(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        String optionId = params.getOptionId(); // id
        int addVoteNum = params.getVotenum(); // 
        String userId = ContestUtil.getUserId(req);
        HttpResponse response = null;

        try {
            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, callback);
            }

            // 2: 
            if (addVoteNum > 0) {
                String url = ContestConsts.ADD_VOTE_INTERFACE + userId + "&optionIds=" + optionId
                        + "&limited=false";
                for (int i = 0; i < addVoteNum; i++) {
                    response = HttpToolKit.getInstance().doGet(url);
                    HttpToolKit.closeQuiet(response);
                }
            }

            // 3: ?
            SponsorOpEntity opRecord = new SponsorOpEntity();
            opRecord.setOperator(userId);
            opRecord.setOperateContent("?" + optionId + "" + addVoteNum);
            opRecord.setOperateTime(new Timestamp(System.currentTimeMillis()));
            opRecord.setIp(ContestUtil.getIpAddr(req));
            contestDAO.saveOpRecord(opRecord);

            return Result.SUCCESS.json(null, callback);
        } catch (Exception e) {
            LOG.error("ContestService.addVoteForInner error...", e);
        } finally {
            HttpToolKit.closeQuiet(response);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?
     * @param params
     * @return
     */
    @Transactional
    public String deleteSinger(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        String optionIds = params.getOptionIds();
        String userId = ContestUtil.getUserId(req);

        // ?
        if (StringUtils.isBlank(optionIds)) {
            return Result.NOT_FOUND.json(null, callback);
        }

        HttpResponse response = null;
        try {

            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, callback);
            }

            // 3: ?
            response = HttpToolKit.getInstance().doGet(ContestConsts.DEL_VOTE_OPTION_INTERFACE + optionIds);

            // 3 ?
            String[] idArray = optionIds.split("!");
            if (idArray != null) {
                Map<String, String> singerMap = crontabService.getSingerInfoMap();
                for (String optionId : idArray) {
                    String key = ContestConsts.SINGER_INFO_PREFIX_KEY + optionId;
                    String singerStr = singerMap.get(key);
                    if (singerStr != null) {
                        // ?
                        SingerEntity singer = JSON.parseObject(singerStr, SingerEntity.class);
                        singer.setStatus(DataStatus.DELETE);
                        contestDAO.updateSingerInfo(singer);
                        // 
                        singerMap.put(key, null);
                    }
                }
            }

            // 4: 
            crontabService.updateInfoInCache();
            return Result.SUCCESS.json(null, callback);
        } catch (Exception e) {
            LOG.error("ContestService.deleteSinger error...", e);
        } finally {
            HttpToolKit.closeQuiet(response);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ????
     * @param userId
     * @return
     */
    public boolean verifyAuthority(String userId) {
        List<SponsorEntity> sponsorList = contestDAO.getSponsorList();
        boolean hasAuthority = false;
        if (sponsorList != null) {
            for (SponsorEntity sponsor : sponsorList) {
                if (sponsor.getUserId().equals(userId)) {
                    hasAuthority = true;
                    break;
                }
            }
        }
        return hasAuthority;
    }

    /**
     * ?
     * @param req
     * @param params
     * @return
     */
    public String addSingerForCityContest(HttpServletRequest req, SceneContestEntity sceneContest,
            MultipartFile file) {
        String userId = ContestUtil.getUserId(req);

        try {
            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, null);
            }

            // 2: 
            String photoUrl = ImageUtils.imageToOimage(file.getBytes());
            sceneContest.setPhotoUrl(photoUrl);
            sceneContest.setPeriod(ContestConsts.PERIOD);
            contestDAO.addSingerInfoForCityContest(sceneContest);

            // 3 
            sceneContest.setRound1Id(ContestConsts.COMMENT_PREFIX + "round1_" + sceneContest.getId());
            sceneContest.setRound2Id(ContestConsts.COMMENT_PREFIX + "round2_" + sceneContest.getId());
            sceneContest.setRound3Id(ContestConsts.COMMENT_PREFIX + "round3_" + sceneContest.getId());
            contestDAO.updateSingerInfoForCityContest(sceneContest);
            return Result.SUCCESS.json(null, null);
        } catch (Exception e) {
            LOG.error("ContestService.addSingerForCityContest error...", e);
        }
        return Result.SERVER_ERROR.json(null, null);
    }

    /**
     * ?
     * @param req
     * @param type
     * @return
     */
    public String getSingersForCityContest(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        String userId = ContestUtil.getUserId(req);
        try {
            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, null);
            }

            List<SceneContestEntity> singers = contestDAO.getSingersForCityContest(params);
            JSONArray jsonArray = (JSONArray) JSON.toJSON(singers);
            return Result.SUCCESS.json(jsonArray, callback);
        } catch (Exception e) {
            LOG.error("ContestService.getSingersForCityContest error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * 
     * @param req
     * @param params
     * @return
     */
    public String riseInRankForCityContest(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        String userId = ContestUtil.getUserId(req);
        try {
            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, null);
            }
            contestDAO.riseInRankForCityContest(params);
            return Result.SUCCESS.json(null, callback);
        } catch (Exception e) {
            LOG.error("ContestService.riseInRankForCityContest error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     *  for ?
     * @param req
     * @param params
     * @return
     */
    public String addLikeNumForCityContest(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        String userId = ContestUtil.getUserId(req);
        HttpResponse response = null;
        try {
            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, null);
            }
            String url = ContestConsts.COMMENT_LIEK_INTERFACE + "?product=" + ContestConsts.COMMENT_PRODUCT
                    + "&item=" + params.getItem() + "&act=like" + "&likeNumStr=" + params.getVotenum();
            response = HttpToolKit.getInstance().doGet(url);

            JSONObject jsonObject = null;
            if (response != null) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String res = EntityUtils.toString(entity);
                    jsonObject = JSON.parseObject(res);
                }
            }
            return Result.SUCCESS.json(jsonObject, callback);
        } catch (Exception e) {
            LOG.error("ContestService.addLikeNumForCityContest error...", e);
        } finally {
            HttpToolKit.closeQuiet(response);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ??
     * @param req
     * @param params
     * @return
     */
    public String switchScreenForCityContest(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        String userId = ContestUtil.getUserId(req);
        try {
            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, null);
            }
            // 2: ?
            contestDAO.updateScreenState(params);

            // 3: redis
            String key = ContestConsts.SWITCH_SCREEN_KEY + ":" + params.getType();
            String value = redisClient.get(key);
            SwitchScreenEntity switchScreen = null;
            if (value != null) {
                // hit cache
                switchScreen = JSON.parseObject(value, SwitchScreenEntity.class);
                switchScreen.setSingerIds(params.getSingerIds());
                switchScreen.setState(params.getState());
                switchScreen.setRound(params.getRound());
            } else {
                // miss cache
                switchScreen = contestDAO.getScreenState(params.getType());
            }
            redisClient.set(key, JSON.toJSONString(switchScreen));
            return Result.SUCCESS.json(null, callback);
        } catch (Exception e) {
            LOG.error("ContestService.switchScreenForCityContest error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?????
     * @param req
     * @param params
     * @return
     */
    public String getScreenState(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        boolean noCache = params.isNoCache();

        try {
            String key = ContestConsts.SWITCH_SCREEN_KEY + ":" + params.getType();
            String value = redisClient.get(key);
            JSONObject jsonObject = null;
            if (value != null && !noCache) {
                // hit cache
                jsonObject = JSON.parseObject(value);
            } else {
                // miss cache
                SwitchScreenEntity switchScreen = contestDAO.getScreenState(params.getType());
                if (switchScreen != null) {
                    jsonObject = (JSONObject) JSON.toJSON(switchScreen);
                    // 
                    redisClient.set(key, JSON.toJSONString(switchScreen));
                }
            }
            return Result.SUCCESS.json(jsonObject, callback);
        } catch (Exception e) {
            LOG.error("ContestService.switchScreenForCityContest error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ??
     * @param req
     * @param params
     * @return
     */
    public String getSingersInfoForCityContest(HttpServletRequest req, RequestParams params) {
        String callback = params.getCallback();
        try {
            String singerIds = params.getSingerIds();
            if (StringUtils.isBlank(singerIds)) {
                return Result.NOT_FOUND.json(null, callback);
            }
            String[] idArray = singerIds.split("!");
            List<Integer> idList = new ArrayList<Integer>();
            for (String idstr : idArray) {
                idList.add(Integer.parseInt(idstr));
            }
            List<SceneContestEntity> singers = contestDAO.getSingersInfoForCityContest(idList);
            JSONArray jsonArray = (JSONArray) JSON.toJSON(singers);
            return Result.SUCCESS.json(jsonArray, callback);
        } catch (Exception e) {
            LOG.error("ContestService.getSingersForCityContest error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?  or 
     * @param req
     * @param params
     * @return
     */
    public String actForCityContest(HttpServletRequest req, HttpServletResponse res, RequestParams params) {
        String callback = params.getCallback();
        HttpResponse response = null;
        try {

            String userId = ContestUtil.getUserId(req, res);
            String key = "ydsinger:" + "act:" + userId + ":to:" + params.getItem();
            if (redisClient.get(key) != null) {
                return Result.VOTE_ISVOTED.json(null, callback);
            }
            String url = ContestConsts.COMMENT_ACT_INTERFACE + "?product=" + ContestConsts.COMMENT_PRODUCT
                    + "&item=" + params.getItem() + "&act=" + params.getAct();
            response = HttpToolKit.getInstance().doGet(url);
            JSONObject jsonObject = null;
            if (response != null) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity);
                    jsonObject = JSON.parseObject(result);
                }
            }
            // ?
            redisClient.set(key, "1");
            return Result.SUCCESS.json(jsonObject, callback);
        } catch (Exception e) {
            LOG.error("ContestService.actForCityContest error...", e);
        } finally {
            HttpToolKit.closeQuiet(response);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * 
     * @param req
     * @param params
     * @return
     */
    public String commentForCityContest(HttpServletRequest req, HttpServletResponse res, RequestParams params) {
        String callback = params.getCallback();
        HttpResponse response = null;
        try {

            // ???
            String userId = ContestUtil.getUserId(req, res);
            String key = "ydsinger:" + "comment:" + userId + ":to:" + params.getItem();
            if (redisClient.get(key) != null) {
                return Result.COMMENT_EXCEED.json(null, callback);
            }

            // ?
            CommentEntity comment = new CommentEntity();
            comment.setItem(params.getItem());
            comment.setContent(params.getContent());
            comment.setTime(System.currentTimeMillis());
            contestDAO.addComment(comment);

            // ?
            redisClient.set(key, "1");
            return Result.SUCCESS.json(null, callback);
        } catch (Exception e) {
            LOG.error("ContestService.commentForCityContest error...", e);
        } finally {
            HttpToolKit.closeQuiet(response);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?
     * @param req
     * @param res
     * @param params
     * @return
     */
    public String listCommentForCityContest(HttpServletRequest req, HttpServletResponse res, RequestParams params) {
        String callback = params.getCallback();
        int itemNum = params.getItemNum();
        String item = params.getItem();
        try {
            List<CommentEntity> commentList = contestDAO.listComment(item, itemNum);
            JSONArray array = (JSONArray) JSONObject.toJSON(commentList);
            return Result.SUCCESS.json(array, callback);
        } catch (Exception e) {
            LOG.error("ContestService.listCommentForCitContest error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?
     * @param req
     * @param res
     * @param params
     * @return
     */
    public String listCommentForInner(HttpServletRequest req, HttpServletResponse res, RequestParams params) {
        String callback = params.getCallback();
        String userId = ContestUtil.getUserId(req);
        try {
            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, callback);
            }

            int itemNum = params.getItemNum();
            List<CommentEntity> commentList = contestDAO.listTopKComment(itemNum);
            JSONArray array = (JSONArray) JSONObject.toJSON(commentList);
            return Result.SUCCESS.json(array, callback);
        } catch (Exception e) {
            LOG.error("ContestService.listCommentForInner error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

    /**
     * ?
     * @param req
     * @param res
     * @param params
     * @return
     */
    public String auditCommentForInner(HttpServletRequest req, HttpServletResponse res, RequestParams params) {
        String callback = params.getCallback();
        String userId = ContestUtil.getUserId(req);
        try {
            // 1: ???
            if (!verifyAuthority(userId)) {
                return Result.PERMISSION_DENIED.json(null, callback);
            }

            // 2: 
            contestDAO.auditCommentForInner(params.getId(), params.getAuditStatus());

            return Result.SUCCESS.json(null, callback);
        } catch (Exception e) {
            LOG.error("ContestService.listCommentForInner error...", e);
        }
        return Result.SERVER_ERROR.json(null, callback);
    }

}