最代码网站中关于动态表event的设计思路

原文:最代码网站中关于动态表event的设计思路

为了能将最代码整站用户的操作都展现出来,需要设计一种动态类型,既可以根据业务无限扩展,也可以指定某些用户行为是可以产生多少牛币交换的,这样就在原先javaniu的零散的表设计基础上抽象出event表

表结构如下:

CREATE TABLE `javaniu_event` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `create_time` datetime NOT NULL,
  `update_time` datetime default NULL,
  `event_rule_id` bigint(20) NOT NULL default '0' COMMENT '用户注册\r\n下载代码\r\n浏览分享\r\n浏览寻求\r\n收藏分享\r\n收藏寻求\r\n浏览活动\r\n追加悬赏\r\n加入活动\r\n拜师\r\n关注用户\r\n发表心情\r\n发表寻求\r\n评论寻求\r\n评论代码\r\n上传代码\r\n下载代码\r\n分享代码\r\n关注用户\r\n浏览分享\r\n浏览寻求\r\n管理员删除代码\r\n收藏分享\r\n收藏寻求\r\n获取勋章\r\n拜师傅\r\n发起活动\r\n浏览活动\r\n加入活动\r\n追加悬赏\r\n连续一周发表心情\r\n用户周贡献排行\r\n用户月贡献排行\r\n用户年贡献排行\r\n代码下载周排行\r\n代码下载月排行\r\n代码下载年排行',
  `user_id` bigint(20) NOT NULL default '0',
  `source_user_id` bigint(20) NOT NULL default '0',
  `source_id` bigint(20) NOT NULL default '0',
  `target_id` bigint(20) NOT NULL default '0',
  `status` int(2) NOT NULL default '0' COMMENT '-1删除0待审核2正常',
  `type` int(2) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `create_time` (`create_time`),
  KEY `userid_status` (`user_id`,`status`),
  KEY `event_rule_id_source_id` (`event_rule_id`,`source_id`),
  KEY `event_rule_id_status` (`event_rule_id`,`status`),
  KEY `type_source_id` (`type`,`source_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

关联表event_rule可以指定牛币规则及其动态显示信息,结构如下:

CREATE TABLE `javaniu_event_rule` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `create_time` datetime NOT NULL,
  `update_time` datetime default NULL,
  `type` int(1) NOT NULL COMMENT '注册+1\r\n发表心情+1\r\n连续一周发表心情+5\r\n分享代码+1\r\n分享代码被下载+n(n为分享者者自定义牛币)\r\n寻求代码-2\r\n上传代码+1\r\n上传代码被下载+1\r\n代码被设为最佳+n(n为寻求者者自定义牛币)\r\n删除代码-1\r\n无效寻求-2\r\n无效代码-2\r\n管理员奖赏+n\r\n管理员惩罚-n\r\n周top10+5\r\n月top10+10\r\n年top10+100\r\n信息完善+1\r\n包月vip+100\r\n师傅赠送+n牛币\r\n授予徽章+5牛币\r\n',
  `name` varchar(100) NOT NULL,
  `niubi` int(11) NOT NULL,
  `extend_json` varchar(1000) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

event的用户行为数据模型抽象如下:

 模型一:用户a通过事件x产生动态0=user_id_a 0 0 0
 a=>x=>0
 模型二:用户a通过事件x产生产生用户a的数据1=user_id_a 0 0 1
 a=>x=>1
 模型三:用户a通过事件x对用户b的数据1产生用户a的数据2=user_id_a b 1 2
 a=>x+b+1=>2 
 模型四:用户a通过事件x对用户b的数据1产生动态0=user_id_a b 1 0
 a=>x+b+1=>0
 模型五:用户a通过事件x对用户b产生动态0=user_id_a b 0 0
 a=>x+b=>0
 
 排列组合:
 user_id source_user_id source_id target_id
 user_id
 user_id source_user_id
 user_id source_user_id source_id
 user_id source_user_id source_id target_id

这样就囊括了所有会出现的用户event,只要在java层做业务转换即可:

最核心的event数据转换java类源码:

package com.zuidaima.core.service.impl;

	private void setSourceAndTarget(Event event, EventRule _eventRule) {
		try {
			EventRule eventRule = new EventRule();
			eventRule.setCreateTime(_eventRule.getCreateTime());
			eventRule.setExtendJson(_eventRule.getExtendJson());
			eventRule.setId(_eventRule.getId());
			eventRule.setName(_eventRule.getName());
			eventRule.setNiubi(_eventRule.getNiubi());
			eventRule.setType(_eventRule.getType());
			eventRule.setUpdateTime(_eventRule.getUpdateTime());
			BaseEntity source = null;
			BaseEntity target = null;
			long sourceId = event.getSourceId();
			long targetId = event.getTargetId();
			JSONObject extend = eventRule.getExtend();
			extend = eventRule.getExtend();
			String description = (String) extend.get("description");
			String _description = null;
			Answer answer = null;
			Project project = null;
			switch (eventRule.getType()) {
			case ModuleConstants.EVENT_TYPE_RULE_PROJECT_CREATE:
			case ModuleConstants.EVENT_TYPE_RULE_PROJECT_DELETE_BY_USER:
			case ModuleConstants.EVENT_TYPE_RULE_PROJECT_DELETE_BY_ADMIN:
			case ModuleConstants.EVENT_TYPE_RULE_PROJECT_VIEW:
			case ModuleConstants.EVENT_TYPE_RULE_PROJECT_COLLECT:
			case ModuleConstants.EVENT_TYPE_RULE_PROJECT_REWARD:
				if (sourceId > 0) {
					source = projectService.findOneById(sourceId);
				}
				if (targetId > 0) {
					target = projectService.findOneById(targetId);
				}
				project = (Project) target;
				if (source != null) {
					project = (Project) source;
				}
				if (project == null) {
					return;
				}
				_description = String.format(
						description,
						ModuleConstants.PROJECT_TYPE_DESC_MAP.get(
								project.getType()).getDesc());
				break;
			case ModuleConstants.EVENT_TYPE_RULE_POST_CREATE:
			case ModuleConstants.EVENT_TYPE_RULE_POST_DELETE_BY_USER:
			case ModuleConstants.EVENT_TYPE_RULE_POST_DELETE_BY_ADMIN:
				if (sourceId > 0) {
					source = postService.findOneById(sourceId);
				}
				if (targetId > 0) {
					target = postService.findOneById(targetId);
				}
				Post post = (Post) target;
				if (source != null) {
					post = (Post) source;
				}
				_description = String.format(description,
						ModuleConstants.POST_TYPE_DESC_MAP.get(post.getType()));
				break;
			// case ModuleConstants.EVENT_TYPE_RULE_GROUP_CREATE://暂时没有这种动态
			case ModuleConstants.EVENT_TYPE_RULE_GROUP_JOIN_IN:
			case ModuleConstants.EVENT_TYPE_RULE_GROUP_DELETE_BY_USER:
				// case
				// ModuleConstants.EVENT_TYPE_RULE_GROUP_DELETE_BY_ADMIN://暂时没有这种动态
				if (sourceId > 0) {
					source = groupService.findOneById(sourceId);
				}
				if (targetId > 0) {
					target = groupService.findOneById(targetId);
				}
				Group group = (Group) source;

				_description = String
						.format(description,
								ModuleConstants.GROUP_TYPE_DESC_MAP.get(group
										.getType()));
				break;
			case ModuleConstants.EVENT_TYPE_RULE_COMMENT_CREATE:
			case ModuleConstants.EVENT_TYPE_RULE_COMMENT_DELETE_BY_USER:
			case ModuleConstants.EVENT_TYPE_RULE_COMMENT_DELETE_BY_ADMIN:
				target = commentService.findOneById(targetId);
				Comment comment = (Comment) target;
				int commentType = comment.getType();
				if (commentType == ModuleConstants.COMMENT_TYPE_ANSWER) {
					source = answerService.findOneById(sourceId);
					answer = (Answer) source;
					project = (Project) answer.getTarget();
					_description = String.format(
							description,
							ModuleConstants.PROJECT_TYPE_DESC_MAP.get(
									project.getType()).getDesc());
				} else if (commentType == ModuleConstants.COMMENT_TYPE_PROJECT) {
					source = projectService.findOneById(sourceId);
					project = (Project) source;
					_description = String.format(
							description,
							ModuleConstants.PROJECT_TYPE_DESC_MAP.get(
									project.getType()).getDesc());
				} else if (commentType == ModuleConstants.COMMENT_TYPE_POST) {
					source = postService.findOneById(sourceId);
					post = (Post) source;
					_description = String.format(description,
							ModuleConstants.POST_TYPE_DESC_MAP.get(post
									.getType()));
				} else {

				}
				break;
			case ModuleConstants.EVENT_TYPE_RULE_ANSWER_CREATE:
			case ModuleConstants.EVENT_TYPE_RULE_ANSWER_BEEN_SET_PERFECT:
				source = projectService.findOneById(sourceId);
				target = answerService.findOneById(targetId);
				project = (Project) source;
				_description = String.format(
						description,
						ModuleConstants.PROJECT_TYPE_DESC_MAP.get(
								project.getType()).getDesc());
				break;
			case ModuleConstants.EVENT_TYPE_RULE_ANSWER_GET:
			case ModuleConstants.EVENT_TYPE_RULE_ANSWER_DELETE_BY_USER:
			case ModuleConstants.EVENT_TYPE_RULE_ANSWER_DELETE_BY_ADMIN:
				source = answerService.findOneById(sourceId);
				answer = (Answer) source;
				Project _project = (Project) answer.getTarget();
				_description = String.format(
						description,
						ModuleConstants.PROJECT_TYPE_DESC_MAP.get(
								_project.getType()).getDesc());
				break;
			case ModuleConstants.EVENT_TYPE_RULE_REPUTATION_CREATE:
				if (sourceId > 0) {
					source = reputationService.findOneById(sourceId);
				}
				if (targetId > 0) {
					target = reputationService.findOneById(targetId);
				}
				break;
			case ModuleConstants.EVENT_TYPE_RULE_USER_FOLLOW:
				source = userService.findOneById(sourceId);
				User _user = (User) source;
				_description = String
						.format(description,
								"<a href='/user/n/" + _user.getName()
										+ ".htm'>" + _user.getName() + "</a>");
				break;
			case ModuleConstants.EVENT_TYPE_RULE_MENTION_COMMENT:
				target = commentService.findOneById(targetId);
				comment = (Comment) target;
				commentType = comment.getType();
				if (commentType == ModuleConstants.COMMENT_TYPE_ANSWER) {
					source = answerService.findOneById(sourceId);
					answer = (Answer) source;
					project = (Project) answer.getTarget();
					_description = String.format(
							description,
							ModuleConstants.PROJECT_TYPE_DESC_MAP.get(
									project.getType()).getDesc());
				} else if (commentType == ModuleConstants.COMMENT_TYPE_PROJECT) {
					source = projectService.findOneById(sourceId);
					project = (Project) source;
					_description = String.format(
							description,
							ModuleConstants.PROJECT_TYPE_DESC_MAP.get(
									project.getType()).getDesc());
				} else if (commentType == ModuleConstants.COMMENT_TYPE_POST) {
					source = postService.findOneById(sourceId);
					post = (Post) source;
					_description = String.format(description,
							ModuleConstants.POST_TYPE_DESC_MAP.get(post
									.getType()));
				} else {

				}
				break;
			case ModuleConstants.EVENT_TYPE_RULE_MENTION_POST:
				source = postService.findOneById(sourceId);
				break;
			default:
				_description = description;
			}

			extend.put("description", _description);
			eventRule.setExtend(extend);
			eventRule.setExtendJson(extend.toString());
			event.setEventRule(eventRule);

			event.setSource(source);
			event.setTarget(target);
		} catch (Exception e) {
			logger.error("Fail to setSourceAndTarget event:" + event);
		}
	}

freemarker显示层转换核心代码:

<#switch event.eventRule.type>
				<#case event_type_rule_post_create>
					<@event_post_macro event.target/>
					<#break>
				<#case event_type_rule_project_create>
					<@event_project_macro event event.target/>
					<#break>
				<#case event_type_rule_project_view>
				<#case event_type_rule_project_collect>
				<#case event_type_rule_project_reward>
					<@event_project_macro event event.source/>
					<#break>
				<#case event_type_rule_comment_create>
					<@event_comment_macro event event.target/>
					<#break>
				<#case event_type_rule_answer_create>
					<@event_answer_macro event event.target/>
					<#break>
				<#case event_type_rule_answer_get>
				<#case event_type_rule_answer_been_set_perfect>
					<@event_answer_macro event event.source/>
					<#break>
				<#case event_type_rule_mention_comment>
					<@event_comment_macro event event.target/>
					<#break>
				<#case event_type_rule_mention_post>
					<@event_post_macro event.source/>
					<#break>
				</#switch>

比如其中一种event type的freemarker macro代码如下:

<!--event post-->
<#macro event_post_macro post>
	<div class="content margin_top5">
		${post.contentExt}
		<span class="comments_count">
			<a target="_blank" href="/mood/${post.id}/comment.htm" rel="nofollow"><img alt="${post.thirdSort}个评论" src="/resource/img/comment.gif">&nbsp;&nbsp;${post.thirdSort}</a>
		</span>
	</div>
</#macro>

这样的设计符合高内聚低耦合的设计思路,未来可以根据业务实现无限扩张,当然代价就是event表越来越大,但可以通过分库分表来分担压力,大家可以参考下,有好的意见可以留言。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供了两个 api - 一个是跳转到登录页面,请自行登录 `/login` - 一个是通用购买演出票 api,请自行传入对应参数, 支持定时功能 `/buy?event=xxx&ticketId=xxx&cron_time=xxx` - 支持自动选择观演人 `need_select` 如果不传,则不会选择观演人,如果传了,则会获取 `select_num` 的值进行观演人数量的选择, 具体逻辑参见代码 ```sh $ curl "http://127.0.0.1:9997/buy?event=169893&ticketId=xxx&need_select=True&ticketNum=1&select_num=1" ``` - 现可通过 [xiudong-go](https://github.com/ronething/xiudong-go) 进行 ticketId 的获取 - 如果多次刷新 login 且登录页面没有进行登录,可能会存在线程阻塞问题,因为 max_workers 设置了 10 个, 暂时可以通过关闭窗口解决 - 如果确认订单页面显示已售罄,需要不断刷新直到出现立即支付,这一点在捡漏的时候很有用 - 只是给大家提供点思路,其他请自行阅读代码,祝大家好运 - **注意:** 有问题请先看 , 没有则新开 issue 提问即可 ### 成功截图 昨晚抢到了。不错。 -------- 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
好的,我可以给你分享一下我对于设计和开发Python打飞机游戏的一些思路代码实现。 首先,我们使用Pygame这个游戏开发框架来实现游戏。Pygame是Python的一个游戏开发库,可以帮助我们快速地开发2D游戏。在开始开发之前,我们需要先安装Pygame库,可以通过pip进行安装。 接下来,我们需要设计游戏的场景和元素。打飞机游戏的场景通常是一个背景图片,我们可以通过Pygame的Surface对象来加载和显示图片。游戏的元素包括玩家飞机、敌机、子弹等,我们可以使用Pygame的Sprite类来实现这些元素。 在游戏,玩家可以通过键盘控制飞机的移动和发射子弹。我们可以通过监听键盘事件来实现这个功能。同时,敌机会不断地从顶部下落,玩家需要躲避敌机并发射子弹来打击敌机。 下面是一个简单的代码实现,可以供你参考: ```python import pygame import random # 初始化Pygame pygame.init() # 设置游戏窗口大小 WIDTH = 480 HEIGHT = 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("打飞机") # 加载背景图片 bg_image = pygame.image.load("background.png").convert_alpha() # 定义玩家飞机类 class Player(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.image.load("player.png").convert_alpha() self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y def move_left(self): self.rect.x -= 5 def move_right(self): self.rect.x += 5 def shoot(self): bullet = Bullet(self.rect.centerx, self.rect.top) all_sprites.add(bullet) bullets.add(bullet) # 定义子弹类 class Bullet(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.image.load("bullet.png").convert_alpha() self.rect = self.image.get_rect() self.rect.x = x - self.rect.width // 2 self.rect.y = y - self.rect.height def update(self): self.rect.y -= 10 if self.rect.bottom < 0: self.kill() # 定义敌机类 class Enemy(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.image.load("enemy.png").convert_alpha() self.rect = self.image.get_rect() self.rect.x = random.randint(0, WIDTH - self.rect.width) self.rect.y = -self.rect.height def update(self): self.rect.y += 5 if self.rect.top > HEIGHT: self.kill() # 创建游戏精灵组 all_sprites = pygame.sprite.Group() player = Player(WIDTH // 2, HEIGHT - 100) enemies = pygame.sprite.Group() bullets = pygame.sprite.Group() all_sprites.add(player) # 设置游戏循环 clock = pygame.time.Clock() running = True while running: # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: player.move_left() elif event.key == pygame.K_RIGHT: player.move_right() elif event.key == pygame.K_SPACE: player.shoot() # 创建敌机 if random.randint(1, 50) == 1: enemy = Enemy() all_sprites.add(enemy) enemies.add(enemy) # 更新游戏精灵 all_sprites.update() # 检测子弹和敌机的碰撞 hits = pygame.sprite.groupcollide(bullets, enemies, True, True) # 更新屏幕 screen.blit(bg_image, (0, 0)) all_sprites.draw(screen) pygame.display.flip() # 控制游戏帧率 clock.tick(60) # 退出Pygame pygame.quit() ``` 这段代码实现了一个简单的打飞机游戏,你可以根据自己的需求进行修改和扩展。希望我的回答能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值