ASP.NET Core初体验

前两天试了下ASP.NET Core MVC,很好用。微软整合了大量前端工具,npm、Bower都可以很方便地使用了,甚至对Grunt、Gulp这类的工具都有集成一些任务管理器,这对前端来说,是一件鼓舞人心的事。

ASP.NET Core MVC的推荐目录结构也进行了调整,新增了wwwroot这样一个静态目录,js、css、图片都可以放这里面,而Bower管理的第三方前端库则会自动下载到wwwroot里面的lib目录下。作为强迫症的我,wwwroot这个目录必须全部是自动生成的。通过Gulp,可以很轻松的实现这一点。继承原先的目录结构习惯,在解决方案下建立Scripts、Styles、Images文件夹,里面用来放原始的js、less和图片,然后通过Gulp进行合并、压缩、复制到wwwroot目录下,这样wwwroot这个目录就可以在git里面排除掉了。完美。而在ASP.NET Core的项目目录下默认的.gitignore文件里,微软其实是已经有这样的想法:

1
2
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

在代码层面,和之前差别不大,基本上M、V、C的代码都可以直接拿过来用。在bundle上有一些变化,然而我是直接删掉了默认的bundle配置,既然可以方便地使用Gulp了,为啥不用呢?

在View中,新增了environment的语法,可以通过environment标签来控制开发环境和生产环境的不同输出,主要是用来控制css、js这些文件的引用,在开发环境下使用未压缩的文件,在生产环境下使用压缩过的文件。还提供了cdn的方式,可以配置多个链接,优先使用CDN的链接,通过asp-fallback-test来检查CDN的链接是否可用,不可用的话再切换为本地的链接。和之前Bundle里面的方式差不多,只是使用起来更简单了。现在css、js这些文件的缓存控制也比以前更简单,只需要加上asp-append-version="true"即可在文件名后面自动加上版本号后缀。

项目部署上面,确实遇到了一个坑。我是通过Web Deploy来自动部署的,花了半天时间才终于搞定。

  1. IIS里应用程序池中的.NET CLR版本要选择“无托管代码”

  2. 安装.NET Core Windows Server Hosting,这里有个大坑,安装完之后要执行一下iisreset,我没有执行这一步,导致出现了HTTP Error 502.5 - Process Failure的问题,从事件查看器里面看到的错误日志是:Failed to start process with commandline '"dotnet" .\****.dll', ErrorCode = '0x80070002'.。遇到同样问题的朋友可以试试iisreset或者重启机器。

  3. 安装HttpPlatformHandler

  4. 还有个就是我当时用Web Delpoy往服务器部署的时候,文件总是推不上去,后来Google了一下,在pubxml里面加上了以下两行:

    1
    2
    <AllowUntrustedCertificate>True</AllowUntrustedCertificate>
    <UsePowerShell>False</UsePowerShell>
  5. 下载Provisioning PowerShell script,在服务器上使用PowerShell运行,输入应用程序池的名称即可。

Plan B

今天从外面回来的路上,我在想,我的Plan B是什么。

直到刚刚,看到阮一峰老师新文章《你的B计划在哪里?》,才发现,我之前所想的那些Plan B其实并不算Plan B,而是基于Plan A的一些妥协与调整。真正的Plan B应该是那些实施起来非常艰苦,不到走投无路自己没办法下定决心去做的计划,但他往往是所有的Plan A都失败的情况下,能救命的计划。

前段时间很幸运接到了一个非常好的项目,APP的外包开发,要求签完合同两个月内完成。这对我来说,是个挑战,也是个机遇。一直很想转型,做前端也挺久了,然而现在的我越来越发现,在公司的这些项目对我而言没有任何挑战性,纯粹是堆时间。而且业务变动及其不稳定,加上一直被需求赶着走,甚至没有时间停下来整顿代码、理清逻辑,导致目前代码中的业务逻辑错综复杂,特别多的坑,搞得我心力交瘁。

我之前是下定了决心,如果项目能谈下来,我可以从公司离职,全职去搞这个外包。一来,Money肯定比工资多,二来也是个锻炼自己、强迫自己去学习与转型的机会,三来,自己可以找到更感兴趣的地方,或许可以找回曾经的那种感觉。项目完成之后,如果有新项目那就接着干,如果找不到新的项目,再找工作也不迟。这是我最初的Plan A。

今天下午和益达见面,他希望我能够出来和他一起创业,有股份,但工资会比现在少很多。以他的项目以及他投资人的项目来看,其实并不会占用我太多的时间,在他们有需求的时候帮他们搞,在他们没需求的时候,我依旧可以做那个APP的外包。于我而言,虽然属于自己的时间少了,但是相比Plan A,我多了一些保底的收入,计划的安全性上更高了一点,2个月之后,即便没有新项目,没有去找新工作,也已然有保底工资,可以多一些缓冲的时间,多做一些选择和考虑。算是Plan A的一个比较中庸的变种。

然而,这些都是在那个APP项目能够谈拢的情况下的计划。如果那个APP的项目没能谈下来。那可就真的要考虑Plan B了。

留在原公司,是一个非常保守的方案,只是为了工资,没有自己的时间,没有乐趣,提升空间不大,前途渺茫。这是一个我很不情愿的Plan B。

和益达一起创业,给他们提供一些技术输出的同时换来一个办公场所+保底工资,牺牲了一部分自己的时间,但是依旧有不少时间做自己喜欢的事,可以接一些外包在手上干。规避了接不到活,又没工资的风险。融到钱也能有不错的回报。这似乎是一个比较安全稳妥的Plan B。

还有一个很激进的Plan,我心里很想这么干,但是需要很大的勇气。那就是直接自己出来做,接外包干。完全属于自己的时间,挑自己感兴趣的项目做,没有保底工资。是对Plan A的颠覆。但是可以获得自由、兴趣、成就感,算是人生职业生涯的一个转型。从此不再需要被项目催着走,不再会觉得加班没有补贴很亏。完全自己支配时间,由兴趣拉动,自己主动前进。当然,外包项目在金钱上的回报也比工资要大得多。如果手头能够一直有项目做,那自然是最好的,人既自由了,快乐了,钱也多了。而风险也不言而喻,就是不够稳定,一旦没有项目做,在金钱上,就是损失。这是一个我最向往,然而却未必能够有勇气去做的Plan B,但这会是我的目标。

之前对react native总是跃跃欲试,一直苦于没有时间和精力去真正静下心来开始学。这两天,花了很多时间去研究,总算真正开始了,也找到了久违的兴趣和好奇心。大爱react native,有种相见恨晚的感觉。2016年react native一定会成为焦点,越来越多的项目会尝试通过react native来实现。而我感觉很幸运,自己能够在这样的时间点,有这样的机会能够开始投身这个领域。

我想,是时候尝试一种新的生活了!

加油!

by Bean

凌晨于闵行

The End of 2015

不知不觉,2015年就快到尽头了。

这一年,经历了好多事。

自从5月20号离开新蛋之后,就开始了无休止的加班生活,仅有的一点周末,也被之前接的一些外包所占据,没有闲暇做自己的事,没有闲暇更新博客,总共只写了两篇文章,还都是在上班时间抽空写的。

这半年,论成长倒也成长了不少。技术上,在H5方面也积累了自己的一套框架,在和Native App甚至微信上的交互上实现了大一统,可以做到一个页面,同时给iOS、Android和微信H5使用,并可进行双向数据交互。职场上,也接触了更多的人和事,感触很多。

做了大半年的前端,等级也晋升为高级前端开发,但做着做着,也开始有点迷茫,不太看得清职业的发展方向。优秀的前端工程师很少,我感觉有这么几个原因:

  • 一是,做前端需要一定的设计基础,起码得有基础的美感,知道页面长什么样好看,知道主流的设计风格,甚至还得会PS,切图如果都不会,都不好意思说自己是做前端的。目前市面上不少前端的内容是一些以做后端为主的人顺带做的,能实现主要功能,但是在设计上或者一些更复杂的效果和功能上,就略显不足了。
  • 二是,做一个优秀的前端,代码基础也得扎实。之前面了一个CSS基础很好的哥们,人也很踏实很好学,就是没有js基础,只会做页面写样式。本想慢慢带他,教他js,是个不错的做前端的料子。招进来做了一两个月,无奈到最后还是被老大给劝退了。他是一开始做设计的,后面一直只写页面,写样式,和后端交互的那些js都是由后端的人写的,也导致他一直以来都以为前端只要写页面和样式就可以了。这样的前端,在要求比较高的公司就比较难生存,个人的发展也比较有限。
  • 三是,从职业发展角度上讲,做前端,发展的高度是限的。在很多公司,前端开发并不是一个受重视的角色。甚至很多公司前端就那么几个人,或者是把前端拆分到各个Team,每个Team配备一两个前端。这样的情况下,前端的发展前景很受限制,很难有晋升的机会。而且和其他前端的交流也很少,成长也慢很多。试想,开发经理、研发总监、CTO这些角色里,有多少是从前端做上去的?这也导致有不少优秀的前端转去做后端了。

这半年,我一直被产品需求追着跑,一直忙于实现各种业务功能,少有时间静下心来认真思考。遇到的很多问题,虽然找到了方法去解决,并且也积累了所谓经验,但是并没有时间去研究他为何未产生,真正的原因是什么,很多地方都是一知半解。渐渐意识到,原来自己还有那么多不足的地方。不像以前,自信得爆棚。

心里一直盘算着试着做做iOS,一直都没有闲暇真正去动手,年底谈了一个APP的活,明年终于可以开始干了!给自己一点压力,push着自己前进。

微信公众号中更换域名

问题描述

项目刚做的时候,并没有找到好的域名,所以用了一个比较长的域名。后来公司花钱买了一个心仪的域名,理所当然,我们需要启用新域名了。

我们的H5站点是基于微信的,由于微信的各种坑,这里有很多值得注意的地方。

首先,需要在公众号设置中,将新域名加入到业务域名以及JS接口安全域名中,在微信支付的开发配置中,也要将新域名加入支付授权目录中。这几个比较容易,因为他们都支持配置多个域名。

我们的页面加载之后会立即通过静默授权跳转去拿用户的code以换取openid,来实现自动登录,为了减少跳转,我们在微信公众号的自定义菜单中配置的链接就是微信的授权链接(形如https://open.weixin.qq.com/connect/oauth2/authorize?XXXXX&redirect_uri=h.xxx-old.com)。这里比较坑的是,授权回调页面域名只能配置一个,而且自定义菜单的修改最慢要24小时才能生效,而且你没法确定是什么时候生效,有的用户会生效,有的用户仍是旧的链接。所以这里的链接不能冒然改成新链接。不过我们可以这么实现。

解决方案

  1. 修改公众号自定义菜单中配置的链接,直接改为原域名http://h.xxx-old.com,在页面代码中做判断,如果没有拿到code参数,就主动跳转到微信的授权页面去拿code(这个原来就做了,为了让用户直接访问域名的时候也能拿到code)。这个生效可能需要24小时,稳妥的做法就是等24小时之后再进行后面的操作。

  2. 将代码中跳转到微信授权页面的redirect_uri改为新域名(形如https://open.weixin.qq.com/connect/oauth2/authorize?XXXXX&redirect_uri=h.xxx-new.com),同时将微信公众号中的授权回调页面域名改为新域名(这个是立即生效的)。这时,无论是从旧域名访问还是从新域名访问,授权回调的时候,都会成功跳转到新域名,并且带上code了。

  3. 修改公众号中的链接,改为微信授权链接,并且redirect_uri写成新域名(形如https://open.weixin.qq.com/connect/oauth2/authorize?XXXXX&redirect_uri=h.xxx-new.com)。这个时候,无论是更新后的链接还是尚未更新的链接,都能成功授权,只是直接用域名会多跳转一下而已。

Done.

by Bean

上午于莘庄

VS2015打包程序无法在XP下安装的问题

问题描述

最近有个需求,需要做一个WinForm程序,目标机器基本都是比较旧的XP机器。需要安装.net Framework环境以及添加快捷方式等,所以决定做一个安装程序。VS默认的是推荐使用InstallShield Limited Edition,经过尝试,发现实在不好用,而且Limited版还有不少限制。于是想用以前VS版本中的Installer Project。寻找了一下,发现有2015版的插件(Microsoft Visual Studio 2015 Installer Projects)。其他都很顺利,在Win7、Win8.1、Win10中安装都没有问题。唯独当我不远万里来到目标机器的时候,发现在XP系统上安装失败!安装程序莫名退出。纠结了几天,最终在网上搜到了解决方案。原因是这样,在VS2010之后的VS中,dpca.dll这个文件中最低的Windows版本已经不支持XP了,导致在用2010以上的VS版本打包的安装包在XP上总是失败的。

解决方法

  1. 关闭Visual Studio
  2. 从 C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\Deployment中复制dpca.dll文件到C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\VSI\bin中替换。(需要找仍在使用VS2010的小伙伴)
  3. 打开项目
  4. 重新编译

相关文章

再见,新蛋

最近开始变得敏感起来。上班路上,我开始变得格外注意窗外的风景。因为我知道,以后我将不会每天再走在这条熟悉的路上了。

这几天发生了太多事,甚至梦里都还在继续。以至于感觉过去了很久。

原本的想法很单纯,只是为了看看外面的世界,而我并没有想到,我这一去,我就真的要离开新蛋了。

携程和百度还有一家做教育的创业公司先后联系了我。百度让我提交更详细的资料,携程约我过去聊聊。我抱着参观一下携程的想法去了。

携程很大,大的让我感觉我太渺小了,置身其中,我就像一个小蚂蚁。我想,这么多人,他们应该也不知道我不是这里的吧。于是我装作很镇定,仿佛我就是携程员工一样。大摇大摆在里面转悠,观察着这里的一切。所有人忙忙碌碌,耳朵里各种声音混在一起突然感觉仿佛很安静,安静得只剩下我一个人。离HR跟我约的时间还有半个小时,我在这里转了一圈,看到了他们人事部的位置,于是走了过去,问了一下。面试这就提前开始了。

面试过程很顺利,先后聊了四五个人,最后拿到了Offer。携程的薪资多得我心动了,我在想,去还是不去呢,咋跟Peter交代呢。

我的自信心开始爆棚,突然感觉我好像真有两把刷子。跟家人汇报了一通,他们挺高兴的。

但这不是高潮。神通广大的Mylo那天下午联系我,问我是不是有异动的想法,让我去他那里,薪资不输携程,做的东西也比携程有意思。

于是果断从了Mylo。

那天晚上,梦见Mylo给每人发了一台iMac,非常高大上。但是没有工作场地,我们一群人就去砍木头,像搭帐篷一样搭了个棚子,坐在里面写代码,还有点漏雨。大风吹过,支撑的木头折了,大家又赶紧一起去修。创业很艰辛,但大家却忙得不亦乐乎。

昨天,去Mylo那里看了一下,虽然地段差了点,但里面环境还是可以的,一看就是创业公司的样子。比梦里搭的帐篷要好多了。

昨晚,偷偷在Peter桌上放了一瓶小花,留了个便签,今天早上他告诉我这是他收到最好的礼物的时候,我还是忍不住泪水地哗哗流。

我不是刻意在今天离职,但很巧合的是今天是5.20,我真心爱着这里的一切,热情的小伙伴们,扫地的阿姨,爬来爬去的乌龟……我舍不得离开。可我内心又渴望着离开,有更大的舞台在向我招手。

新蛋是我离开学校之后的第一站,这里记录了我成长的一切。我会永远记得这个温暖的大家庭,记得我在这里所发生的一切。

Newegg经历了太多的人来人往,每个人都终会有离开的一天。但,离开不代表结束,人虽离开,但情谊还在。

世界很大,我要出去闯了。无论在天涯海角,我的身上都会刻着Newegg的印记。无论我今后发展如何,我永远不会忘记Newegg对我的培养。

哭过,笑过。

擦干泪,开启新的篇章。

by Bean, the last time at Newegg.

Web Deploy 进阶

之前想写个Web Deploy的教程,结果一直耽搁了。最近又遇到一个比较高级的用法,打算暂时就不写基础教程了,把几个不常用的但是很有用的用法列一下。

1、部署的时候排除某些文件或文件夹。

这个功能其实很有用,比如一些自定义的config,里面包含了一些key或者很重要的信息,而你的代码是开源的,你希望分享源代码,但是这些服务器相关的key还是不能暴露的,这时候,你本地的config里可能只是一些测试的key,或者压根就可以是空的。在服务器上的config里,你可以放心大胆地配置这些key。每次部署的时候,我们就希望跳过这些config文件,而不至于用本地的config去替换掉线上的。

我们需要修改项目的配置文件,也就是.csproj文件,注意修改Release的,如果你发布选项中配置的是Release的话。

1
2
3
4
5
6
7
8
9
10
11
12
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<!-- 下面这一行用来排除指定文件夹,分号分割多个文件夹 -->
<ExcludeFoldersFromDeployment>Configurations</ExcludeFoldersFromDeployment>
<!-- 下面这一行用来排除指定文件,分号来分隔多个文件 -->
<ExcludeFilesFromDeployment>XXX.config;YYY.config</ExcludeFilesFromDeployment>
</PropertyGroup>

2、通过文件校验而不是修改时间来决定某个文件是否需要发布

这个功能同样很有用,尤其当你通过源代码管理的时候,你在不同的电脑上,虽然代码相同,但其实每个文件的修改时间并不同。这会导致你在这台电脑上部署了之后,在另一台电脑上修改了部分内容,却还是需要部署所有文件。当网络不给力的时候,部署需要很长时间。

我们需要修改部署配置文件,一般是Properties\PublishFiles\XXX.pubxml。

我们在PropertyGroup里添加这么一行就可以了

1
<MSDeployUseChecksum>true</MSDeployUseChecksum>

先写这两个。之后有空再写个详细的教程。一开始配置Web Deploy还是有不少注意点的。

by HADB @ Newegg

修复position:fixed在ios虚拟键盘弹出时错位的bug

问题描述:在使用bootstrap的navbar-fixed-top时,发现在iPhone上的微信里面,当点击input弹出输入法之后,顶部fixed的navbar消失,在输入法没有关闭的情况下,向上滚动,会发现navbar在半空中。

Google了一下,发现这个问题在iOS中很常见,Bootstrap也对此进行了说明(戳这里)。

Virtual keyboards

Also, note that if you’re using a fixed navbar or using inputs within a modal, iOS has a rendering bug that doesn’t update the position of fixed elements when the virtual keyboard is triggered. A few workarounds for this include transforming your elements to position: absolute or invoking a timer on focus to try to correct the positioning manually. This is not handled by Bootstrap, so it is up to you to decide which solution is best for your application.

不过我在最近刚更新的iOS8.3的Safari中,没有发现这个问题。在8.3的Safari中,点击input弹出输入法之后,fixed元素会失效,navbar回到最顶端,没有浮在半空中。猜测是在弹出虚拟键盘之后为了节省页面空间,而对fixed的元素进行了处理,但是在微信中的浏览器上处理出了点问题。

目前发现最好的解决方案是在点击input之后,直接把fixed的元素变成absolute的,不需要浏览器自己去做处理。

有人说在滚动时用timer实时调整元素位置,我觉得这个很低端。浏览器去处理fixed元素自然有它的道理,确实可以节省屏幕空间。我们其实也没有必要在这个情况下强制显示navbar,这时用户的重点在于输入。当我们input失去焦点之后,输入法关闭,这时我们再显示出navbar。

下面直接上代码:

添加这样一段css:

1
2
3
.fixfixed.navbar-fixed-top {
position: absolute;
}

添加这样一段js:

1
2
3
4
5
6
7
8
9
10
11
$(function () {
if (Modernizr.touch) {
$(document).on('focus', 'input', function () {
$(".navbar-fixed-top").addClass('fixfixed');
});
$(document).on('blur', 'input', function () {
$(".navbar-fixed-top").removeClass('fixfixed');
});
}
});

使用了Modernizr,仅在触屏上进行处理,对桌面浏览器不做处理,这样对于桌面浏览器上的体验更好。

完美解决问题!

by HADB

2015/4/13 凌晨 于 家中

再见,美罗

美罗走了。

第一次,因为一个人的离职,让我鼻头酸酸的,眼里噙着泪水。

他是我职业生涯第一个老大。

从我在公司实习以来,见证了一个又一个员工的离职,和今天的感觉完全不一样。

他坐在我斜后面,虽然我常常会感觉,总有一双眼睛在盯着我。因为我偶尔也是会逛逛贴吧,逛逛知乎,逛逛和工作无关的东西,我总觉得不正大光明。甚至我做过一个小工具,可以把屏幕黑掉,我的屏幕是光面的,很反光,可以当镜子用,我可以看看头发乱没乱,还可以看看美罗是不是在偷看我。而我每次都只看到他盯着自己的屏幕。

他是那样的平易近人。每天中午,和我们一起吃饭。周末,一起踢球。甚至,还拉我们一起玩COC。

我来面试的时候,见他第一眼,我在想,为何这个老大这么潮,当时他好像是染着红头发。后来我看到他以前的照片,简直就像古惑仔,哈哈。

一开始,我常常帮他做小工具。那时的我,虽说整天忙忙碌碌,却忙得不亦乐乎,很充实。那时他还没有坐在我后面,在离我很远很远的地方。我常常屁颠屁颠地绕很远很远的路到他那里,给他汇报今天的情况。

他总是会和我分享很多人生的道理。就连我那个来面试被拒的室友,都和我说,“感觉Mylo人还是很不错的,和我讲了很多道理,告诉我哪里不行,哪里需要提高。”他还告诉我怎么拍车牌,虽然我到现在还没拍到。

我记得,有一次突然下雨,而我没带伞。他走的时候和我说,我那里还有一把伞,你待会儿走的时候拿去用好了。而那晚,我和别人约好,出去见个面。那是我接的第一个比较大的私活,3W。对于刚毕业的我来说,已经是很大的数字了。那晚回来时还下着小雪,在公交站旁的路灯下,我望着天上飘着的雪,心里满满的感动。我在想,若不是美罗的伞,我今晚要冻成狗了。

从我第一天上班那天起,我就发现,这个老大很不一样。由于是第一天上班,我自然是比较积极。那时我还在学校,还没毕业。我早早就起了床。出了地铁等公交,遇到了他。那时我还不记得他叫什么名字,只知道他是老大。我喊了声,老大早。和他一起坐下了,我的公交卡放在钱包里,刷完卡后,钱包握在手里。他和我说,钱包要收起来,这样不安全。他和我聊了很多,我说我喜欢自己捣鼓网站,有自己的博客,他说他也是。他还告诉我以前解决了一个大问题之后,是多么多么开心,有成就感。而我也深有感触。当时就感觉,这是一个懂技术的老大,有共同语言啊。到公司之后发现,公司还没几个人。那会儿距离上班时间还有半个多小时。

后来,我请了几个月的假,搞毕业设计以及学驾照。当我再次回到公司的时候,已经离职了不少人,美罗的位置也搬到了我后面。几乎每天,他都是很早很早就到公司,而我每次也都是很早就来。有时我早,有时他早。而每天不变的就是:“早啊,Mylo!”、“小Bean早!”渐渐地,这已成了习惯。今年过完年刚过来的那几天,美罗没来,我还真有点不习惯。直到他回来,又恢复了每天的“Mylo早”、“小Bean早”。

他很Geek,和他一起做的微信招聘页面、年会系统等,都充满了极客范。小米手环刚出来,他就搞了好多个,有的作为我们的奖励,剩下的就拿来给大家用积点拍卖了。他甚至还搞过四轴飞行器、树莓派2,拿来进行拍卖。

他对我有点偏心。我毕业后回到公司的时候,刚好有个很大的显示器空着,他直接拿给我用了。我至今都用着这遭人羡慕的屏幕(也就是前面提到的会反光可以用来做镜子的屏幕),用grace的话,比架构师的屏幕都大。夏天那时候,他还会从冰箱拿可乐给我喝;台湾同事送他的水果,他也会拿些给我。我至今还记得那么大那么水灵的桃子,咬在嘴里的口感。他还会送我他刚淘的手机壳,虽然只要1块9,还包邮,但是心里满满的感激……这或许就是离老大近的好处吧。

文笔不好,但我觉得我想写点东西。这是美罗工作了9年的地方。

虽然不知道他在最后一封邮件里说的“FightingX”是个啥玩意,但感觉很Geek的样子。

我会哭,因为他是个好老大。

再见,美罗。

by Bean

2015/3/27 于 Newegg