微信公众平台开发—成语接龙

一、源码

package org.xs.dntown.wx.idiom.modules.web;

import java.util.Date;
import java.util.List;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xs.dntown.wx.common.utils.MessageUtil;
import org.xs.dntown.wx.common.web.BaseController;
import org.xs.dntown.wx.core.modules.entity.UserInfo;
import org.xs.dntown.wx.core.modules.entity.enums.ModuleEnum;
import org.xs.dntown.wx.core.modules.entity.req.BaseMsgReq;
import org.xs.dntown.wx.core.modules.service.LogService;
import org.xs.dntown.wx.core.modules.service.UserService;
import org.xs.dntown.wx.idiom.modules.entity.IdiomListInfo;
import org.xs.dntown.wx.idiom.modules.entity.IdiomUserInfo;
import org.xs.dntown.wx.idiom.modules.entity.enums.StepEnum;
import org.xs.dntown.wx.idiom.modules.service.IdiomListService;
import org.xs.dntown.wx.idiom.modules.service.IdiomUserService;

/**
 * 核心Controller
 */
@Controller(value = "idiomCoreController")
@RequestMapping("idiom")
public class CoreController extends BaseController {

	@Autowired
	private IdiomUserService idiomUserService;

	@Autowired
	private IdiomListService idiomListService;

	@Autowired
	private UserService userService;

	@Autowired
	private LogService logService;

	/**
	 * 文本消息
	 */
	@ResponseBody
	@RequestMapping(value = "msg", produces = { "text/plain;charset=utf-8" })
	public String textMsg(HttpServletRequest request) throws Exception {
		String result = "";
		String openId = "";
		String userName = "";
		String content = "";
		try {

			//得到接收消息实体
			BaseMsgReq msgReq = (BaseMsgReq)request.getAttribute("msgReq");
			openId = msgReq.getFromUserName();
			content = msgReq.getContent();

			//得到用户信息实体
			UserInfo userInfo = (UserInfo)request.getAttribute("userInfo");
			userName = userInfo.getUserName();

			log.info("收到消息:" + msgReq.getContent());

			//更新模块
			userService.setModule(msgReq.getFromUserName(), ModuleEnum.idiom.getValue());

			//得到接龙用户信息实体
			IdiomUserInfo iUserInfo = idiomUserService.getByOpenId(userInfo.getOpenId());
			if(iUserInfo == null) {
				log.info("新增接龙用户");

				//如果没有就新增
				iUserInfo = new IdiomUserInfo();
				iUserInfo.setOpenId(userInfo.getOpenId());
				iUserInfo.setModuleStep(StepEnum.normal.getValue());
				iUserInfo.setStepTime(new Date());
				iUserInfo.setIsAnswered(false);
				idiomUserService.add(iUserInfo);
			}

			//刷新模块(1小时)
			long timeDiff = new Date().getTime() - userInfo.getModuleTime().getTime();
			long hoursDiff = timeDiff / (1000 * 60 * 60);
			if(hoursDiff >= 1) {
				idiomUserService.setStep(userInfo.getOpenId(), StepEnum.normal.getValue());
				iUserInfo.setModuleStep(StepEnum.normal.getValue());
			}

			log.info("开始转入步骤");
			//出题
			if(msgReq.getContent().equals("开始")) {

				//完成上一个成语
				if(!StringUtils.isEmpty(iUserInfo.getIdiomId()) && iUserInfo.getModuleStep().equals(StepEnum.answer.getValue())) {
					//处理答题结果
					disposeAnswer(iUserInfo, msgReq);

					result += finishAnswer(iUserInfo, msgReq, false) + "\n";
				}

				log.info("开始下一题");

				//下一题
				result = nextIdiom(iUserInfo, result);

				logService.addInfoLog(openId, userName, content, result, ModuleEnum.idiom.getValue(), StepEnum.answer.getValue());
				result += MessageUtil.msgReqToXml(msgReq, result);
				log.info(result);
				return result;
			}
			//答案
			else if(msgReq.getContent().equals("答案") && iUserInfo.getModuleStep().equals(StepEnum.answer.getValue())) {

				//返回答案
				if(!StringUtils.isEmpty(iUserInfo.getIdiomId())) {

					log.info("返回答案");

					//完成答题
					result += finishAnswer(iUserInfo, msgReq, true);

					//设置步骤
					iUserInfo.setModuleStep(StepEnum.normal.getValue());
					iUserInfo.setStepTime(new Date());
					idiomUserService.update(iUserInfo);

					logService.addInfoLog(openId, userName, content, result, ModuleEnum.game24.getValue(), StepEnum.answer.getValue());
					result = MessageUtil.msgReqToXml(msgReq, result);
					log.info(result);
					return result;
				}
			}
			//排行榜
			else if(msgReq.getContent().equals("排行") || msgReq.getContent().equals("排行榜")) {

				log.info("返回排行榜");

				result += "【排行榜】\n";

				boolean flag = false;
				List<IdiomUserInfo> list = idiomUserService.getTopScope(1000);
				if(list != null && list.size() > 0) {
					for (int i = 0; i < list.size(); i++) {
						if(list.get(i).getOpenId().equals(iUserInfo.getOpenId())) {
							flag = true;
						}
						//TODO 优化
						UserInfo sUserInfo = userService.getByOpenId(list.get(i).getOpenId());
						if(sUserInfo != null) {
							result += "No." + (i + 1) + " 『" + sUserInfo.getUserName() + "』(" + list.get(i).getScore() + "分)\n";
						}
					}
				}

				if(!flag) {
					result += "No." + (Integer.parseInt(idiomUserService.getRankScope(iUserInfo.getScore()))) + " 『" + userInfo.getUserName() + "』(" + iUserInfo.getScore() + "分)";
				} else {
					result = result.substring(0, result.length() - 1);
				}

				logService.addInfoLog(openId, userName, content, result, ModuleEnum.idiom.getValue(), StepEnum.normal.getValue());
				result = MessageUtil.msgReqToXml(msgReq, result);
				log.info(result);
				return result;
			}

			//如果是新进来就刷新状态
			if(msgReq.getContent().equals("接龙")) {

				//完成答题
				finishAnswer(iUserInfo, msgReq, true);

				//设置步骤
				iUserInfo.setModuleStep(StepEnum.normal.getValue());
				iUserInfo.setStepTime(new Date());
				idiomUserService.update(iUserInfo);
			}

			//如果是答题状态
			if(iUserInfo.getModuleStep().equals(StepEnum.answer.getValue())) {

				//返回处理答题结果
				result = disposeAnswer(iUserInfo, msgReq);
				logService.addInfoLog(openId, userName, content, result, ModuleEnum.idiom.getValue(), StepEnum.answer.getValue());
				result = MessageUtil.msgReqToXml(msgReq, result);
				log.info(result);
				return result;
			}

			//返回接龙公告
			result += "『成语接龙』\n";
			result += "【规则】\n";
			result += "有3种接龙方式:\n";
			result += "与尾字相同接龙,积分+3\n";
			result += "与尾字谐音接龙,积分+1\n";
			result += "包含尾字接龙,积分+1\n";
			result += "连胜有积分奖励\n";
			result += "【说明】\n";
			result += "1、输入“开始”:开始答题\n";
			result += "2、输入“答案”:完成答题\n";
			result += "3、输入“排行”:查看排行\n";
			result += "4、输入“公告”:返回首页";
			logService.addInfoLog(openId, userName, content, result, ModuleEnum.idiom.getValue(), StepEnum.normal.getValue());
			result = MessageUtil.msgReqToXml(msgReq, result);
		} catch (Exception e) {
			log.debug("执行失败");
			logService.addErrorLog(openId, userName, content, "", ModuleEnum.idiom.getValue(), StepEnum.normal.getValue(), e);
			e.printStackTrace();
		}

		//返回消息
		log.info(result);
		return result;
	}

	/**
	 * 获得下一题
	 */
	private String nextIdiom(IdiomUserInfo iUserInfo, String result) {
		//下一题
		Random r = new Random();
		String questionId = String.valueOf(r.nextInt(29543) + 1);
		iUserInfo.setIdiomId(questionId);
		iUserInfo.setModuleStep(StepEnum.answer.getValue());
		iUserInfo.setStepTime(new Date());
		iUserInfo.setIsAnswered(false);
		//更新模块
		idiomUserService.update(iUserInfo);
		//返回题目
		IdiomListInfo idiomListInfo = idiomListService.getById(questionId);
		if(!StringUtils.isEmpty(result)) {
			result += "\n";
		}
		result += idiomListInfo.getWord();
		return result;
	}

	/**
	 * 处理答题结果
	 */
	private String disposeAnswer(IdiomUserInfo iUserInfo, BaseMsgReq msgReq) {

		log.info("处理答题结果");

		String result = "";
		boolean flag = true;
		int score = 0;

		//上一个成语
		IdiomListInfo idiomListInfo = idiomListService.getById(iUserInfo.getIdiomId());

		//获得回答的成语
		IdiomListInfo idiomAnswerInfo = idiomListService.getByWord(msgReq.getContent());

		//没有这个成语
		if(idiomAnswerInfo == null) {
			result = "这不是成语吧";
			flag = false;
		} else {

			//判断是否匹配
			//如果是相同匹配
			if(idiomListInfo.getWordEnd().equals(idiomAnswerInfo.getWordBegin())) {
				result = "答对了,积分+3\n";
				flag = true;
				score = 3;
			}
			//如果是谐音匹配
			else if(idiomListInfo.getWordEndSpell().equals(idiomAnswerInfo.getWordBeginSpell())) {
				result = "答对了,谐音,积分+1\n";
				flag = true;
				score = 1;
			}
			//如果是包含匹配
			else if(idiomAnswerInfo.getWord().indexOf(idiomListInfo.getWordEnd()) > -1) {
				if(idiomListInfo.getId().equals(idiomAnswerInfo.getId())) {
					//不能是同一个成语
					result = "不能是同一个成语";
					flag = false;
				} else {
					result = "答对了,包含,积分+1\n";
					flag = true;
					score = 1;
				}
			}
			//不匹配
			else {
				result = "成语没接上";
				flag = false;
			}
		}

		//回答正确
		if(flag) {

			log.info("回答正确");

    		//下一题
    		idiomListInfo = idiomListService.getNextIdiom(idiomAnswerInfo.getWordEnd());
    		if(idiomListInfo != null) {
    			iUserInfo.setIdiomId(idiomListInfo.getId());
    			iUserInfo.setStepTime(new Date());
    			iUserInfo.setIsAnswered(false);

    			//返回题目
    			if(!StringUtils.isEmpty(result)) {
    				result += "\n";
    			}
    			result += idiomListInfo.getWord();
    		} else {
    			result += "我接不下去了,积分+5\n";
    			score += 5;
    			result = nextIdiom(iUserInfo, result);
    		}

    		//更新用户积分、次数、答对次数、连胜次数、最长连胜
			iUserInfo.setScore(iUserInfo.getScore() + score);
			iUserInfo.setRightTimes(iUserInfo.getRightTimes() + 1);
			iUserInfo.setTimes(iUserInfo.getTimes() + 1);
			iUserInfo.setComboTimes(iUserInfo.getComboTimes() + 1);
    		if(iUserInfo.getComboTimes() > iUserInfo.getBestTimes()) {
    			iUserInfo.setBestTimes(iUserInfo.getComboTimes());
    		}
    		iUserInfo.setStepTime(new Date());
    		iUserInfo.setIsAnswered(false);
		}
		//回答错误
		else {

			log.info("回答错误");

			//如果第一次回答
        	if(!iUserInfo.getIsAnswered()) {

	        	//更新用户积分、次数、答对次数、连胜次数、最长连胜
        		iUserInfo.setTimes(iUserInfo.getTimes() + 1);
        		iUserInfo.setIsAnswered(true);
        	}
		}

		//更新接龙用户
		idiomUserService.update(iUserInfo);

		return result;
	}

	/**
	 * 完成答题
	 */
	private String finishAnswer(IdiomUserInfo iUserInfo, BaseMsgReq msgReq, boolean flag) {

		log.info("完成答题");

		String result = "";

		//上一个成语
		IdiomListInfo idiomListInfo = idiomListService.getById(iUserInfo.getIdiomId());

		//下一题
		if(flag) {
			idiomListInfo = idiomListService.getNextIdiom(idiomListInfo.getWordEnd());
			if(idiomListInfo != null) {
				result += "答案:" + idiomListInfo.getWord() + "\n\n";
			} else {
				result += "答案我也不知道\n\n";
			}
		}

		int score = 0;

		int comboTimes = iUserInfo.getComboTimes();
		if(comboTimes > 1) {
			int rank = comboTimes / 5 + 1;
			score += Math.pow(2, rank);
		}

		//更新用户积分、次数、答对次数、连胜次数、最长连胜
		iUserInfo.setScore(iUserInfo.getScore() + score);
		iUserInfo.setStepTime(new Date());
		iUserInfo.setIsAnswered(false);
		iUserInfo.setComboTimes(0);

		//更新接龙用户
		idiomUserService.update(iUserInfo);

		result += "答对" + comboTimes + "题,连胜奖励积分+" + score;
		return result;
	}
}

源码地址:https://github.com/ctxsdhy/dntown 

二、演示

时间: 2024-10-28 16:36:22

微信公众平台开发—成语接龙的相关文章

微信公众平台开发(97) 图文消息

关键字:微信公众平台 开发模式 图文消息作者:方倍工作室原文:http://www.cnblogs.com/txw1958/p/weixin-97-news.html 在这篇微信公众平台开发教程中,我们将介绍如何灵活的使用图文消息功能.我们将只介绍被动回复消息中的图文消息,发送客服消息及高级群发消息接口的发送的图文消息与本文介绍的图文消息的各情况基本一致. 本文分为以下四个部分: 图文消息的定义 图文消息的实现 图文消息的类型 图文消息的回复 一.图文消息的定义 在微信公众平台消息中,发送被动响

第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理

温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发 第三篇 :微信公众平台开发实战之请求消息,响应消息以及事件消息类的封装 首先,我们看看原来写的dopost方法: /** * 处理微信服务器发来的消息 */ public void doPost(HttpServletRequest request, HttpServletResponse response) thr

微信公众平台开发问答

微信公众平台开发问答是一个微信知识问答区,专注于提供微信应用及开发技术知识的整理.归类和检索. 主题:新手常见问题 问:我是新手,没有开发基础,应该如何学习微信公众平台的开发?答:先学习PHP和Mysql,可以在网上找相应的教程,也可参考书籍<PHP和MySQL Web开发(原书第4版)>:再学习微信公众平台开发入门教程,了解微信收发消息原理及回复:然后根据微信开发文档,熟悉接口,并在此基础上实现一些基本的小功能,并扩展到更复杂的功能上. 问:URL和Token是什么意思?有什么用?我应该如何

微信公众平台开发(103) JS API支付

本文介绍如何使用JS API支付接口完成微信支付. 一.JS API支付接口(getBrandWCPayRequest) 微信JS API只能在微信内置浏览器中使用,其他浏览器调用无效.微信提供getBrandWCPayRequest接口供商户前端网页调用,调用之前微信会鉴定商户支付权限,若商户具有调起支付的权限,则将开始支付流程.这里主要介绍支付前的接口调用规则,支付状态消息通知机制请参加下文.接口需要注意:所有传入参数都是字符串类型! getBrandWCPayRequest参数如表6-5所

微信公众平台开发(一) 申请微信公众账号

一.微信公众平台介绍 微信公众平台是腾讯公司在微信的基础上新增的功能模块,通过这一平台,个人和企业都可以打造一个微信的公众号,可以群发文字.图片.语音.视频.图文消息五个类别的内容. 二.注册微信公众号 1.注册地址: https://mp.weixin.qq.com/ 点击右上角的"立即注册"申请微信公众账号. 2.填写基本信息 3.激活邮箱账号 到邮箱中收取邮件,激活公众平台账号. 4.信息登记 通过邮箱激活后,填写基本信息.选择为"个人"后,后面只能选择&qu

微信公众平台开发

关于微信公众平台确实是个很好的东西,鉴于需要完成这样一个作业花了2天时间来研究这个,做出了一个简单的东西. 我们选择的语言是JAVA(当然PHP开发这个更简单,不过我没学,考虑时间成本而继续用自己熟悉的),所用的服务器是SAE(BAE也可以),以及一个微信公众平台测试账号.http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login,点击此处进入,用自己的微信扫描二维码就可以申请到一个测试号,高级接口都可以使用,仅仅用来测试是没有任何

[051] 微信公众平台开发教程第22篇-如何保证access_token长期有效

为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台开放了许多接口,包括自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等,开发者在调用这些接口时,都需要传入一个相同的参数access_token,它是公众账号的全局唯一票据,它是接口访问凭证. access_token的有效期是7200秒(两小时),在有效期内,可以一直使用,只有当access_token过期时,才需要再次调用接口获取access_token.在理想情况下,一个7x24小时运行的系统,每天只需

微信公众平台开发之会员卡

微信公众平台开发之会员卡是商家获取用户信息和实现线上线下交易的重要途径之一.通过在微信上发布会员卡,然后让用户填写自己的个人信息之后就可以领取到线上的会员卡,这个会员卡在线下也是可以使用的.可以在会员卡上发布一些最新通知,礼品券,优惠券,会员特权等等,用户达到一定的积分或者在线下消费一定的金额才可以领取这些优惠,这样可以吸引用户去获取积分实现每日签到的功能,这样用户就能看到我们推送的消息.下面就由微时代来简单介绍一下会员卡吧: 1.在微时代后台设置会员卡的回复信息,当用户回复关键词"会员卡&qu

微信公众平台开发之万能表单

微信公众平台开发之万能表单是为了方便我们得到用户的信息.我们可以在后台设置任何需要用户填写的信息,比如:电话,姓名,性别,工作等等信息,当然我们也可以设置一定的奖励,只要完善这些信息就可以得到一定的礼品,这样用户才会去填写这些信息,通过这样的方式可以很快的获取用户信息.下面就由微时代来简单介绍一下万能表单功能吧: 1. 在微时代后台万能表单的内容,给该万能表单设置关键词,这样当用户回复该关键词的时候就能进去填写资料了. 2. 为该表单添加选项,设置用户需要填写的内容,比如姓名,电话,性别,工作这