Wijmo 日历插件 一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!! 前言 HOLD住! 总结:

Wijmo 日历插件

说明:

  因为项目(OA)的需要,我负责开发日程的模块,相信大家用过谷歌的日历了吧,是不是觉得挺好用,但又苦于无法实现?

  这里告诉你一个很好的插件,Wijmo,而里面有一个类似谷歌的日历事件插件,真的很好很强大,注意,我不是托。

  当时找到这个插件的时候,真心佩服那些牛逼的外国开发员,能做到这么厉害,并且还开源了。

  因为菜鸟,苦苦做了一个多星期才完成,个中原因能归结为:

1、没有中文的介绍和帮助,百度谷歌就是找不到很好的例子。

2、英文不行,看官网API很吃力,没有认真看官网的Demo。

3、不是很熟悉js。

技术要点:

1、基本的js、jQuery使用

2、正则表达式的使用(确实很好很强大)

3、wijmo 日历事件插件的基本使用

4、JSON的基本使用

废话不说,先上几张效果图,还在完善中,希望能帮到有需要的人。

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

我的Demo 图:

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

开始上代码,首先这个日历中的数据是要存到本地的,所以要创建数据库。

贴上数据库代码:代码是用SQL 2008的,里面的注释很清楚了,仅供参考。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*********************************************************
 
说明:日历事件表:保存日历事件的信息
 
作者:Frank
 
2013-6-17 17:34:05
 
*********************************************************/
 
USE HFOA
IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[tsk_calendar_events]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
    DROP TABLE [dbo].[tsk_calendar_events]
GO
 
CREATE TABLE [dbo].[tsk_calendar_events]
(
--除了id不是插件的关键字,所有的都是插件的关键字,都要注意转换,有些不用转,带c开头的都要转,不然插件会显示错误
    id int identity (1,1) NOT NULL,                 --日历事件编号
    allday VARCHAR(10) NULL,                        --是否为全天事件
    calendar VARCHAR(20) NULL,                      --该事件属于哪个日程的,有 My 和 Work
    csubject VARCHAR(100) NULL,                     --事件主题,显示时必须转为 subject
    color VARCHAR(20) NULL,                         --该事件的重要程度,以颜色来区分
    cdescription varchar(250) NULL,                 --日程事件的描述,显示时必须转为 description
    cstart VARCHAR(50) NOT NULL,                    --开始时间,页面显示时必须转为 start 格式为 new Date(2013,5,17,6,0)
    cend VARCHAR(50) NOT NULL,                      --结束时间,注意,页面显示到页面的时候必须把字段名改为 end ,否则该日历插件会报错 格式为 new Date(2013,5,17,6,0)
    cid VARCHAR(50) NOT NULL,                       --日历插件的 id,页面显示时必须转为 id
    isNewEvent VARCHAR(10) NULL,                    --是否为新事件
    location VARCHAR(100) NULL,                     --事件地点
    recurrenceState VARCHAR(20) NULL,               --当有重复事件的时候,该事件为主事件还是派生的 重复事件
    parentRecurrenceId VARCHAR(50) NULL,            --重复事件的主事件 Id  
     
) ON [PRIMARY]
 
GO
 
 
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日历事件编号' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'id'                   
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否为全天事件' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'allday'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'该事件属于哪个日程的,有 My 和 Work' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'calendar'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'事件主题,显示时必须转为 subject' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'csubject'               
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'该事件的重要程度,以颜色来区分' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'color'           
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日程事件的描述,显示时必须转为 description' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'cdescription'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'开始时间,页面显示时必须转为 start 格式为 new Date(2013,5,17,6,0)' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'cstart'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'结束时间,注意,页面显示到页面的时候必须把字段名改为 end ,否则该日历插件会报错 格式为 new Date(2013,5,17,6,0)' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'cend'     
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日历插件的 id,页面显示时必须转为 id ' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'cid'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否为新事件' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'isNewEvent'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'事件地点' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'location'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'当有重复事件的时候,该事件为主事件还是派生的 重复事件' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'recurrenceState'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重复事件的主事件 Id' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'parentRecurrenceId'
GO
 
 
 
 
/*********************************************************
 
说明:日历事件重复表:保存日历事件重复的信息
 
作者:Frank
 
2013-6-17 17:34:05
 
*********************************************************/
 
USE HFOA
IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[tsk_calendar_recu]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
    DROP TABLE [dbo].[tsk_calendar_recu]
GO
 
CREATE TABLE [dbo].[tsk_calendar_recu]
(
    id int identity (1,1) NOT NULL,                 --重复事件的id
    startTime VARCHAR(50) NULL,                     --开始时间 格式为 Date(2013,5,17,6,0)
    endTime VARCHAR(50) NULL,                       --结束时间 格式为 Date(2013,5,17,6,0)
    parentRecurrenceId VARCHAR(50) NULL,            --重复事件的主事件 Id
    recurrenceType VARCHAR(20) NULL,                --事件重复的类型,有每天、每周等
    patternStartDate VARCHAR(50) NULL,              --主事件的开始时间 格式为 new Date(2013,5,17,6,0) 
    event_id int NOT NULL,                          --日历主表主键 Id
     
) ON [PRIMARY]
 
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重复事件的id' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'id'                
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'开始时间 格式为 Wed Jun 19 2013 20:30:00' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'startTime'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'结束时间 格式为 Wed Jun 19 2013 20:30:00' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'endTime'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重复事件的主事件 Id' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'parentRecurrenceId'            
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'事件重复的类型,有每天、每周等' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'recurrenceType'        
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'主事件的开始时间 格式为 Wed Jun 19 2013 20:30:00' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'patternStartDate'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日历主表主键 Id' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'event_id'
GO

  好了,最重要的数据库咱们已经设计好了,现在就来执行代码实施吧!

注意,涉及到2个表,一个是日历主事件表,一个是用来记录重复事件的表。

代码实施:

页面有2个:

1. tsk_EventsCalendar.aspx

2. tsk_EventsCalendar.aspx.cs

没错,就是用C#来写的,哈哈,被你发现了!不过原理都差不多的,我之前搞SSH,无奈公司不用Java开发,只好学学 ASP.NET 了。

1. tsk_EventsCalendar.aspx

 View Code

2. tsk_EventsCalendar.aspx.cs

 View Code

页面代码说明:

1、首先我知道js样式调用那样写是不符合规范的,不建议大家像我这样,我这样写是因为框架(整个OA)的框架搭建问题,只有这样写才能生效,就整个问题我也纠结了好一会。

2、代码不是很规范,效率有点低,希望各位看官将就着看。

入题:

1、初始化日历控件:

  a:引包,注意顺着不能乱(页面加载顺序有关),不然,出事你负责。。。。。。我已经深受其害了。

  b:初始化静态的日历控件(不好意思啊,最近在做 ASP.NET ,经常控件控件这样叫的,望大家理解理解。。。)

 放置一个div,用来初始化日历的   

<div id="eventscalendar">

</div>

用js来添加日历

 View Code

好了,一个静态的页面已经弄好了,这里为了大家能看到效果,给大家一个静态数据的 Demo,大家在页面中下载吧。

2、获取数据,并把数据提交到数据库。

封装一个获取数据的方法:

 View Code

到此,能够获取到数据,相信你应该知道怎么做了吧。。。。哈哈我就不多说了,大家看后台代码吧,

不过有些方法你不能直接写的,比如:Factory<tsk_calendar_eventsBean>.Instance.Update(entity);

因为这些是我们框架封装好的方法,^_^,是不是羡慕嫉妒恨?。。。 --!

注:

1、Newtonsoft.Json.Net20.dll 为引用,可以转换 JSON格式。

2、善用正则表达式,提高效率,把数据转为日历所需的格式。

3、注意有了重复事件(数据表2)的处理,这个表是日历主表的附属表,是 obj里的子对象。 obj.recurrencePattern,如果没有创建重复事件,是没有 recurrencePattern的对象的。

4、别把这个东西看太难了,我当时百度谷歌找不到教程,这不,一个星期也研究些皮毛了,大家加油啊!

5、数据库设计,因为这个日历有他的 Id,但是我们可以用自增的Id,只做一些处理就好了。

6、字段设计最好跟日历的属性对应,个别的处理一下,在显示的时候用 正则表达式处理就可以了。

7、学会用火狐调试,断点调试,可以看出有什么对象,有什么属性。

最后几点建议:

1、有官网API,即使是英文的,也尽量去看,因为官网是最全面的,谁叫他是开发者,难道官网会比一个经过自己学习后翻译出来的差吗?

2、多看官网的Demo ,对了 Wijmo 还有很多 jQuery 特效,都不错的。

3、学会用狐火的FireBug,这样才能调试程序,知道有什么对象,有什么属性!

4、多写博客,多与人分享交流,那么这个世界就会更加美好了!

5、代码注意注释和风格,最好一屏能读完,提高可读性,方便维护!

6、多上博客园(没有打广告的嫌疑),真的,即使你不是学习,也能了解到很多东西,最重要的是有很多妹子图 ^.^!

以下附上源代码,大家快来拍砖!。。。

下载地址:http://download.csdn.net/detail/hyd8480188/5614657

要一分,给我挣挣分好吗,没有分了。

如果你也没有分,给我邮箱我给你发。

 
 

前言

 今天下午3点,我按照惯例,打开游戏服务器,开新服部署嘛,游戏在腾讯开放平台,简单。闭着眼睛都OK。于是一*的复制黏贴拷贝,把服务器加起来,然后启动查看日志。

。。。。突然发现不断的有Exception??搞什么飞机??丢失表Usr_user??刚才不是导了数据库吗?不存在?怎么会??

我瞬间意识到。我摊上事了,我摊上大事了。。检查刚才的复制黏贴,发现我没改数据库名,这一下子把第二个服的数据库整个干掉了。

我擦!!不会吧??背后一凉就软滩在凳子上了。

备份?没有。

数据库还有渣吗?select count(*) ....  0!

备份????真的没有。。。。

怎么能没备份啊!!@@!

怎么办?几十个玩家充值了几千元。连个渣也没了。

找玩家求饶?送礼包?? 你觉得玩家会放过你????天真。

linux服务器 + mysql数据库 + 游戏缓存 + flash的as3前端。怎么搞。。。我完蛋了。

HOLD住!

 我要HOLD住!冷静,虽然大脑一片空白。马上Google找mysql有无自动备份的。。。没看到。问同事,求助。我靠,他们怎么好像没反应啊。。。

这个时候,有个哥们提示我,用 mysqlbinlog

这玩意是什么。马上google,知道mysql自身会有个操作的备份。我靠!希望来了。赶快进入mysql目录,查看下。果然看到几十个bin文件。

网上继续搜。大概知道mysql会保存30天内的数据库操作在bin文件。OK。

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结: 

我们达洛克2服才刚运行了2天,算起来应该就是最后2个bin文件。还好。用

mysqlbinlog --no-defaults mysql-bin.000026 > mysql-bin.000026.txt

导出了SQL,检查下:

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:
# at 472331597
#130619 18:04:23 server id 1  end_log_pos 472331772     Query   thread_id=2657  exec_time=0     error_code=0
SET TIMESTAMP=1371636263/*!*/;
UPDATE USR_RESOURCE SET MODIDATE = '2013-06-19 18:04:23',SILVER = 283 WHERE USERCODE='001UR1371634524003511'
/*!*/;
# at 472331772
#130619 18:04:23 server id 1  end_log_pos 472331799     Xid = 226001034
COMMIT/*!*/;
# at 472331799
#130619 18:04:23 server id 1  end_log_pos 472331871     Query   thread_id=2657  exec_time=0     error_code=0
SET TIMESTAMP=1371636263/*!*/;
BEGIN
Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

大概是这种结构。

冷静下来,分析了。我还原数据库,只要从建库开始第一个sql重新执行到最后一个。理论上数据库就会被还原。但是bin文件里面是所有的SQL操作,我要筛选出 达洛克战记2服 的。网上说用 cat / more / less 等命令。我靠,这他妈也太复杂了把?

于是我zip了所有bin文件,回传到本地,用c#写了个过滤代码,找到 use darok2_2,知道这段内容都是 达洛克战记2服 的数据。

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:
        public void test()
        {
            FileStream stream = File.OpenRead(@"E:玩转中国程序设计达洛克战记xtar-backupsvn达洛克战记2xsvnserver-deploymysql-bin.000027.txtmysql-bin.000027.txt");
            StreamReader reader = new StreamReader(stream, Encoding.GetEncoding("GBK"));

            FileStream streamO = File.Create(@"E:玩转中国程序设计达洛克战记xtar-backupsvn达洛克战记2xsvnserver-deploymysql-bin.000027.txt 00027.out.txt");
            StreamWriter writer = new StreamWriter(streamO, Encoding.GetEncoding("GBK"));

            Encoding gbk = Encoding.GetEncoding("GBK");
            Encoding utf = Encoding.Default;

            string strLine = reader.ReadLine();

            while (strLine != null)
            {

                if (!strLine.StartsWith("use darok2_2", StringComparison.OrdinalIgnoreCase))
                {
                    strLine = reader.ReadLine();
                    continue;
                }

                do
                {
                    if (strLine == null)
                        break;

                    if (strLine.StartsWith("use", StringComparison.OrdinalIgnoreCase) && !strLine.StartsWith("use darok2_2", StringComparison.OrdinalIgnoreCase))
                    {
                        strLine = reader.ReadLine();
                        break;
                    }

                    if (strLine.StartsWith("INSERT", StringComparison.OrdinalIgnoreCase) || strLine.StartsWith("DELETE", StringComparison.OrdinalIgnoreCase) || strLine.StartsWith("UPDATE", StringComparison.OrdinalIgnoreCase))
                    {
                        writer.Write(strLine);
                        writer.WriteLine(";");
                    }
                    else
                    {
                    }
                    strLine = reader.ReadLine();

                }
                while (true);
            }

            writer.Flush();
            writer.Close();

            reader.Close();
        }、
Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

这样,我就得到过滤出来的SQL文件了。本地我建了个数据库测试下,发现第一句就卡死了??HOLD住!!!

再细心看看,发现中文到了txt全部是乱码了。安静思考了下:

linux数据库用的是GBK。因此bin文件导出的格式一定是GBK。那么代码用GBK读取,然后GBK写入就ok了(代码里面已经修复了)

再导入,顺利了。

进入数据库在看,发现中文还是乱码。。。。奇怪。那可能是mysql设置的问题了,和linux环境下不一致。我只要把这些过滤的SQL在达洛克服务器上走一遍应该就ok了。

上传SQL,运行脚本:

mysql -uxxxx -pxxxx darok2_2 <  000027.out.txt.

等了10分钟。。。进入腾讯朋友网,开启游戏。一切又光明了。

总结:

各位看官,别看我洋洋洒洒几句废话貌似几分钟的事情。在那个接近崩溃,连数据库渣都没的条件下。我是多么惨的度过了2个小时。

 mysqlbinlog

各位真心要记在心里。如果有全量备份+这个增量备份,基本上数据是不会丢失的。嗨。真实虚惊一场啊。

我们团队的页游 达洛克战记
 

说明:

  因为项目(OA)的需要,我负责开发日程的模块,相信大家用过谷歌的日历了吧,是不是觉得挺好用,但又苦于无法实现?

  这里告诉你一个很好的插件,Wijmo,而里面有一个类似谷歌的日历事件插件,真的很好很强大,注意,我不是托。

  当时找到这个插件的时候,真心佩服那些牛逼的外国开发员,能做到这么厉害,并且还开源了。

  因为菜鸟,苦苦做了一个多星期才完成,个中原因能归结为:

1、没有中文的介绍和帮助,百度谷歌就是找不到很好的例子。

2、英文不行,看官网API很吃力,没有认真看官网的Demo。

3、不是很熟悉js。

技术要点:

1、基本的js、jQuery使用

2、正则表达式的使用(确实很好很强大)

3、wijmo 日历事件插件的基本使用

4、JSON的基本使用

废话不说,先上几张效果图,还在完善中,希望能帮到有需要的人。

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

我的Demo 图:

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

开始上代码,首先这个日历中的数据是要存到本地的,所以要创建数据库。

贴上数据库代码:代码是用SQL 2008的,里面的注释很清楚了,仅供参考。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*********************************************************
 
说明:日历事件表:保存日历事件的信息
 
作者:Frank
 
2013-6-17 17:34:05
 
*********************************************************/
 
USE HFOA
IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[tsk_calendar_events]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
    DROP TABLE [dbo].[tsk_calendar_events]
GO
 
CREATE TABLE [dbo].[tsk_calendar_events]
(
--除了id不是插件的关键字,所有的都是插件的关键字,都要注意转换,有些不用转,带c开头的都要转,不然插件会显示错误
    id int identity (1,1) NOT NULL,                 --日历事件编号
    allday VARCHAR(10) NULL,                        --是否为全天事件
    calendar VARCHAR(20) NULL,                      --该事件属于哪个日程的,有 My 和 Work
    csubject VARCHAR(100) NULL,                     --事件主题,显示时必须转为 subject
    color VARCHAR(20) NULL,                         --该事件的重要程度,以颜色来区分
    cdescription varchar(250) NULL,                 --日程事件的描述,显示时必须转为 description
    cstart VARCHAR(50) NOT NULL,                    --开始时间,页面显示时必须转为 start 格式为 new Date(2013,5,17,6,0)
    cend VARCHAR(50) NOT NULL,                      --结束时间,注意,页面显示到页面的时候必须把字段名改为 end ,否则该日历插件会报错 格式为 new Date(2013,5,17,6,0)
    cid VARCHAR(50) NOT NULL,                       --日历插件的 id,页面显示时必须转为 id
    isNewEvent VARCHAR(10) NULL,                    --是否为新事件
    location VARCHAR(100) NULL,                     --事件地点
    recurrenceState VARCHAR(20) NULL,               --当有重复事件的时候,该事件为主事件还是派生的 重复事件
    parentRecurrenceId VARCHAR(50) NULL,            --重复事件的主事件 Id  
     
) ON [PRIMARY]
 
GO
 
 
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日历事件编号' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'id'                   
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否为全天事件' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'allday'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'该事件属于哪个日程的,有 My 和 Work' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'calendar'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'事件主题,显示时必须转为 subject' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'csubject'               
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'该事件的重要程度,以颜色来区分' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'color'           
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日程事件的描述,显示时必须转为 description' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'cdescription'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'开始时间,页面显示时必须转为 start 格式为 new Date(2013,5,17,6,0)' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'cstart'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'结束时间,注意,页面显示到页面的时候必须把字段名改为 end ,否则该日历插件会报错 格式为 new Date(2013,5,17,6,0)' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'cend'     
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日历插件的 id,页面显示时必须转为 id ' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'cid'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否为新事件' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'isNewEvent'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'事件地点' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'location'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'当有重复事件的时候,该事件为主事件还是派生的 重复事件' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'recurrenceState'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重复事件的主事件 Id' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_events', @level2type=N'COLUMN', @level2name=N'parentRecurrenceId'
GO
 
 
 
 
/*********************************************************
 
说明:日历事件重复表:保存日历事件重复的信息
 
作者:Frank
 
2013-6-17 17:34:05
 
*********************************************************/
 
USE HFOA
IF EXISTS(SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[tsk_calendar_recu]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
    DROP TABLE [dbo].[tsk_calendar_recu]
GO
 
CREATE TABLE [dbo].[tsk_calendar_recu]
(
    id int identity (1,1) NOT NULL,                 --重复事件的id
    startTime VARCHAR(50) NULL,                     --开始时间 格式为 Date(2013,5,17,6,0)
    endTime VARCHAR(50) NULL,                       --结束时间 格式为 Date(2013,5,17,6,0)
    parentRecurrenceId VARCHAR(50) NULL,            --重复事件的主事件 Id
    recurrenceType VARCHAR(20) NULL,                --事件重复的类型,有每天、每周等
    patternStartDate VARCHAR(50) NULL,              --主事件的开始时间 格式为 new Date(2013,5,17,6,0) 
    event_id int NOT NULL,                          --日历主表主键 Id
     
) ON [PRIMARY]
 
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重复事件的id' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'id'                
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'开始时间 格式为 Wed Jun 19 2013 20:30:00' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'startTime'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'结束时间 格式为 Wed Jun 19 2013 20:30:00' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'endTime'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重复事件的主事件 Id' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'parentRecurrenceId'            
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'事件重复的类型,有每天、每周等' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'recurrenceType'        
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'主事件的开始时间 格式为 Wed Jun 19 2013 20:30:00' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'patternStartDate'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'日历主表主键 Id' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'tsk_calendar_recu', @level2type=N'COLUMN', @level2name=N'event_id'
GO

  好了,最重要的数据库咱们已经设计好了,现在就来执行代码实施吧!

注意,涉及到2个表,一个是日历主事件表,一个是用来记录重复事件的表。

代码实施:

页面有2个:

1. tsk_EventsCalendar.aspx

2. tsk_EventsCalendar.aspx.cs

没错,就是用C#来写的,哈哈,被你发现了!不过原理都差不多的,我之前搞SSH,无奈公司不用Java开发,只好学学 ASP.NET 了。

1. tsk_EventsCalendar.aspx

 View Code

2. tsk_EventsCalendar.aspx.cs

 View Code

页面代码说明:

1、首先我知道js样式调用那样写是不符合规范的,不建议大家像我这样,我这样写是因为框架(整个OA)的框架搭建问题,只有这样写才能生效,就整个问题我也纠结了好一会。

2、代码不是很规范,效率有点低,希望各位看官将就着看。

入题:

1、初始化日历控件:

  a:引包,注意顺着不能乱(页面加载顺序有关),不然,出事你负责。。。。。。我已经深受其害了。

  b:初始化静态的日历控件(不好意思啊,最近在做 ASP.NET ,经常控件控件这样叫的,望大家理解理解。。。)

 放置一个div,用来初始化日历的   

<div id="eventscalendar">

</div>

用js来添加日历

 View Code

好了,一个静态的页面已经弄好了,这里为了大家能看到效果,给大家一个静态数据的 Demo,大家在页面中下载吧。

2、获取数据,并把数据提交到数据库。

封装一个获取数据的方法:

 View Code

到此,能够获取到数据,相信你应该知道怎么做了吧。。。。哈哈我就不多说了,大家看后台代码吧,

不过有些方法你不能直接写的,比如:Factory<tsk_calendar_eventsBean>.Instance.Update(entity);

因为这些是我们框架封装好的方法,^_^,是不是羡慕嫉妒恨?。。。 --!

注:

1、Newtonsoft.Json.Net20.dll 为引用,可以转换 JSON格式。

2、善用正则表达式,提高效率,把数据转为日历所需的格式。

3、注意有了重复事件(数据表2)的处理,这个表是日历主表的附属表,是 obj里的子对象。 obj.recurrencePattern,如果没有创建重复事件,是没有 recurrencePattern的对象的。

4、别把这个东西看太难了,我当时百度谷歌找不到教程,这不,一个星期也研究些皮毛了,大家加油啊!

5、数据库设计,因为这个日历有他的 Id,但是我们可以用自增的Id,只做一些处理就好了。

6、字段设计最好跟日历的属性对应,个别的处理一下,在显示的时候用 正则表达式处理就可以了。

7、学会用火狐调试,断点调试,可以看出有什么对象,有什么属性。

最后几点建议:

1、有官网API,即使是英文的,也尽量去看,因为官网是最全面的,谁叫他是开发者,难道官网会比一个经过自己学习后翻译出来的差吗?

2、多看官网的Demo ,对了 Wijmo 还有很多 jQuery 特效,都不错的。

3、学会用狐火的FireBug,这样才能调试程序,知道有什么对象,有什么属性!

4、多写博客,多与人分享交流,那么这个世界就会更加美好了!

5、代码注意注释和风格,最好一屏能读完,提高可读性,方便维护!

6、多上博客园(没有打广告的嫌疑),真的,即使你不是学习,也能了解到很多东西,最重要的是有很多妹子图 ^.^!

以下附上源代码,大家快来拍砖!。。。

下载地址:http://download.csdn.net/detail/hyd8480188/5614657

要一分,给我挣挣分好吗,没有分了。

如果你也没有分,给我邮箱我给你发。

前言

 今天下午3点,我按照惯例,打开游戏服务器,开新服部署嘛,游戏在腾讯开放平台,简单。闭着眼睛都OK。于是一*的复制黏贴拷贝,把服务器加起来,然后启动查看日志。

。。。。突然发现不断的有Exception??搞什么飞机??丢失表Usr_user??刚才不是导了数据库吗?不存在?怎么会??

我瞬间意识到。我摊上事了,我摊上大事了。。检查刚才的复制黏贴,发现我没改数据库名,这一下子把第二个服的数据库整个干掉了。

我擦!!不会吧??背后一凉就软滩在凳子上了。

备份?没有。

数据库还有渣吗?select count(*) ....  0!

备份????真的没有。。。。

怎么能没备份啊!!@@!

怎么办?几十个玩家充值了几千元。连个渣也没了。

找玩家求饶?送礼包?? 你觉得玩家会放过你????天真。

linux服务器 + mysql数据库 + 游戏缓存 + flash的as3前端。怎么搞。。。我完蛋了。

HOLD住!

 我要HOLD住!冷静,虽然大脑一片空白。马上Google找mysql有无自动备份的。。。没看到。问同事,求助。我靠,他们怎么好像没反应啊。。。

这个时候,有个哥们提示我,用 mysqlbinlog

这玩意是什么。马上google,知道mysql自身会有个操作的备份。我靠!希望来了。赶快进入mysql目录,查看下。果然看到几十个bin文件。

网上继续搜。大概知道mysql会保存30天内的数据库操作在bin文件。OK。

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结: 

我们达洛克2服才刚运行了2天,算起来应该就是最后2个bin文件。还好。用

mysqlbinlog --no-defaults mysql-bin.000026 > mysql-bin.000026.txt

导出了SQL,检查下:

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:
# at 472331597
#130619 18:04:23 server id 1  end_log_pos 472331772     Query   thread_id=2657  exec_time=0     error_code=0
SET TIMESTAMP=1371636263/*!*/;
UPDATE USR_RESOURCE SET MODIDATE = '2013-06-19 18:04:23',SILVER = 283 WHERE USERCODE='001UR1371634524003511'
/*!*/;
# at 472331772
#130619 18:04:23 server id 1  end_log_pos 472331799     Xid = 226001034
COMMIT/*!*/;
# at 472331799
#130619 18:04:23 server id 1  end_log_pos 472331871     Query   thread_id=2657  exec_time=0     error_code=0
SET TIMESTAMP=1371636263/*!*/;
BEGIN
Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

大概是这种结构。

冷静下来,分析了。我还原数据库,只要从建库开始第一个sql重新执行到最后一个。理论上数据库就会被还原。但是bin文件里面是所有的SQL操作,我要筛选出 达洛克战记2服 的。网上说用 cat / more / less 等命令。我靠,这他妈也太复杂了把?

于是我zip了所有bin文件,回传到本地,用c#写了个过滤代码,找到 use darok2_2,知道这段内容都是 达洛克战记2服 的数据。

Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:
        public void test()
        {
            FileStream stream = File.OpenRead(@"E:玩转中国程序设计达洛克战记xtar-backupsvn达洛克战记2xsvnserver-deploymysql-bin.000027.txtmysql-bin.000027.txt");
            StreamReader reader = new StreamReader(stream, Encoding.GetEncoding("GBK"));

            FileStream streamO = File.Create(@"E:玩转中国程序设计达洛克战记xtar-backupsvn达洛克战记2xsvnserver-deploymysql-bin.000027.txt 00027.out.txt");
            StreamWriter writer = new StreamWriter(streamO, Encoding.GetEncoding("GBK"));

            Encoding gbk = Encoding.GetEncoding("GBK");
            Encoding utf = Encoding.Default;

            string strLine = reader.ReadLine();

            while (strLine != null)
            {

                if (!strLine.StartsWith("use darok2_2", StringComparison.OrdinalIgnoreCase))
                {
                    strLine = reader.ReadLine();
                    continue;
                }

                do
                {
                    if (strLine == null)
                        break;

                    if (strLine.StartsWith("use", StringComparison.OrdinalIgnoreCase) && !strLine.StartsWith("use darok2_2", StringComparison.OrdinalIgnoreCase))
                    {
                        strLine = reader.ReadLine();
                        break;
                    }

                    if (strLine.StartsWith("INSERT", StringComparison.OrdinalIgnoreCase) || strLine.StartsWith("DELETE", StringComparison.OrdinalIgnoreCase) || strLine.StartsWith("UPDATE", StringComparison.OrdinalIgnoreCase))
                    {
                        writer.Write(strLine);
                        writer.WriteLine(";");
                    }
                    else
                    {
                    }
                    strLine = reader.ReadLine();

                }
                while (true);
            }

            writer.Flush();
            writer.Close();

            reader.Close();
        }、
Wijmo 日历插件
一个线上运营着3000+人的游戏,因为我不小心一个DROP DATABASE,全没了。 怎么办??跟我HOLD住!!!
前言
HOLD住!
总结:

这样,我就得到过滤出来的SQL文件了。本地我建了个数据库测试下,发现第一句就卡死了??HOLD住!!!

再细心看看,发现中文到了txt全部是乱码了。安静思考了下:

linux数据库用的是GBK。因此bin文件导出的格式一定是GBK。那么代码用GBK读取,然后GBK写入就ok了(代码里面已经修复了)

再导入,顺利了。

进入数据库在看,发现中文还是乱码。。。。奇怪。那可能是mysql设置的问题了,和linux环境下不一致。我只要把这些过滤的SQL在达洛克服务器上走一遍应该就ok了。

上传SQL,运行脚本:

mysql -uxxxx -pxxxx darok2_2 <  000027.out.txt.

等了10分钟。。。进入腾讯朋友网,开启游戏。一切又光明了。

总结:

各位看官,别看我洋洋洒洒几句废话貌似几分钟的事情。在那个接近崩溃,连数据库渣都没的条件下。我是多么惨的度过了2个小时。

 mysqlbinlog

各位真心要记在心里。如果有全量备份+这个增量备份,基本上数据是不会丢失的。嗨。真实虚惊一场啊。