YY一个微信支持的赠品营销活动

中午羽之兄给我弄来一个雅诗兰黛下面Origins悦木之源的微信活动统计的活。

这家公司做营销的手笔可不小,此次活动看来倒也不是直接主办,估计是什么分销商搞的,在微信策划上略显不专业。

目的很简单,全国若干网点准备了一批小样,用户在微信上关注公众账号,回复特定文字和姓名联系方式,即可前往柜台领取小样。

公众账号后台使用的是编辑模式,在后台设定自动回复。问题来了,4天时间,有超过4000条回复消息,而微信的消息统计功能居然不能按照关键字统计。

我想说,即使能统计,如此大的量,若是大量超过专柜备货,那么势必引起客户不满。应当在客户线上登记的时候即将其信息写入到自己的系统,到线下门店在通过微信扫码连接线上用户。YY如下(前提当然是开发模式):

  1. 用户通过各种渠道关注微信账号,关注动作会给服务器推送一个事件,记录关注的来源,甚至可以用带参数的二维码记录扫码关注的具体来源
  2. 用户点击申领菜单,按自动回复提示输入姓名和联系方式,这里服务器即可将openid,姓名和手机方式信息关联起来
  3. 48小时内,赠品有任何新动态,可以直接通过客服接口回复消息给用户。
  4. 由于openid授权信息包括了用户填写的城市,甚至可以在用户发消息的时候调用地理位置接口获得用户的位置,我们可以提供给客户最近的门店信息,一条地理位置消息回复。
  5. 用户前往门店后,通过扫描门店专有的带参数二维码,系统可以将用户信息和申领结果绑定。在后台记录可以查询,并可以避免重复申领。
  6. 根据用户领取的产品类型,门店位置,可以将用户分组,安排后续营销。

Linux服务器运维笔记

做运维,哥不专业,随手记一些有用的命令备忘而已。
 

Ubuntu,显示已经安装的ppa,来自万能的StackOverflow,还有如何删除

grep -RoPish "ppa.launchpad.net/[^/]+/[^/ ]+" /etc/apt | sort -u | sed -r 's/\.[^/]+\//:/'

设置Ubuntu自动启动服务

sudo update-rc.d SERVICE_NAME defaults
sudo update-rc.d -f SERVICE_NAME remove

CentOS下则使用chkconfig命令

实时显示日志内容

tail -f access.log

所有子目录的权限改为755(跳过文件)StackOverflow

find /path/to/base/dir -type d -exec chmod 755 {} +

改命令行默认语言,解决SSH中文乱码

Ubuntu: /etc/default/locale

CentOS: /etc/sysconfig/i18n

OSChina

命令行自动完成不工作AskUbuntu

sudo apt-get install bash-completion

Apache 日志统计

# 解压所有日志,并统计所有pdf下载量
gzip -cd access.log.*.gz | grep -c ".pdf"

# 统计APAC Portal的实际访问数
cat access.log.1 | grep " 200 " | grep -v "OPTIONS" | \
grep -v "gsa-crawler" | grep -v "/world-time" | grep -v "/share-price" | \
grep -v "wp-admin" | 
grep -v "wp-cron" | grep -v "/rss-feed/" | grep -v "favicon.ico" | \
grep -v ".jpg" | grep -v ".png" | grep -v ".css" | grep -v ".js" | grep -v ".eot" | \
grep -c ""

# 统计前访问量前20的资源
cat access.log.1 | grep '200' | awk '{print $11}'| sort | uniq -c | sort -nr | head -20

# 总流量
cat access.log.1 | awk '{sum+=$10} END {print sum/1024/1024/1024}'
# 上周的错误日志
cat error.log.1 | grep -v "file_get_contentsep "error" | grep -v "sending a SIGKILL" | grep -v "MaxRequestWorkers" | less

# 每小时访问量
awk '{print $4}' access.log |cut -c 2-15|sort|uniq -c

Apache / MySQL 定期自动打包备份,自动上传到FTP

cd /var/www/witower/backups
mysqldump -uroot -pPASSWD witower [--all-databases] | gzip -c > database.sql.gz

cd /var/www/witower
tar czf ~/witower_$((`date +%d`%3)).tar.gz ./

cd ~
curl -T witower_$((`date +%d`%3)).tar.gz ftp://HOST --user LOGIN:PASSWD

# 使用 ssh 备份
scp all-databases_$((`date +%d`%7)).sql.gz uicestone@witower.com:~/backup/home-server/database/

MySQL更改数据目录

StackOverflow

使用rsync通过ssh增量备份到远程目录

rsync -a -e ssh --info=progress2 /var/www uicestone@witower.com:~/backup/home-server

配置ssh-keygen做到无密码登录ssh

使用ssh-keygen命令在本地生成rsa_key和rsa_key.pub文件,将rsa_key.pub中的内容追加到目标机器目标用户的~/.ssh/authorized_keys内,如需创建文件,注意权限必须为600,.ssh目录的权限必须为700,/etc/ssh/sshd_config中RSA认证相关配置需开启

定时和延时任务

定时任务crontab -e已经很熟悉

延时任务,或者说一次性的定时任务,则通过at命令实现

sudo at [time]
at> [command1]
at> [command2]
(Ctrl+D结束保存)

另有atq(检查队列),atrm(删除任务)供君选择。

Ubuntu定时自动安全更新,内附拆分日志方法

https://help.ubuntu.com/community/AutomaticSecurityUpdates

配置SNMP监控服务

360云监控使用SNMP协议,虽然360提供了服务器配置脚本,但好奇心+不放心还是让我自己配置了一下

sudo apt-get install snmp snmpd

CentOS的话包名为:CentOS下的一篇教程

net-snmp:提供了一个入口,使得监控服务器可以通过snmp协议从这个入口与被监控机器通信
net-snmp-devel: 是为了使用net-snmp-config, net-snmp-utils是为了使用snmpwalk
net-snmp-libs:  提供了运行需要的库文件
net-snmp-utils: 提供了一套工具,可以利用snmp协议进行通信

按照/etc/snmp/snmpd.conf的提示,在/var/lib/snmp/snmpd.conf中创建了用户。但是测试失败。经过提醒,注释掉/etc/snmp/snmp.conf中的mibs,安装snmp-mibs-downloader包。再次运行本机测试脚本

snmpwalk -v 3 -l authNoPriv -a MD5 -u 'authOnlyUser' -A 'mypassword' '127.0.0.1:161' 'sysDescr'

成功。附赠测试UDP端口的方式

nc -vuz uice.lu 161

显示硬盘S.M.A.R.T.信息

sudo smartctl -a -d ata /dev/sda

递归列出所有子目录git status 原帖

for i in /var/www/*/; do (cd $i && (echo $i; git status; sudo git prune; git fsck; wp core version)); done

配置L2TP over IPSec VPN

主要靠它,但有一处配置需要根据这里修改

在Ubuntu 16.04以上配置自动启动服务

新建启动脚本文件/etc/systemd/system/shadowsocks.service,

[Unit]
Description=Shadowsocks

[Service]
TimeoutStartSec=0
ExecStart=/usr/bin/ssserver -c /etc/shadowsocks.json

[Install]
WantedBy=multi-user.target

执行以下命令启动 shadowsocks 服务:

systemctl enable shadowsocks
systemctl start shadowsocks
systemctl status shadowsocks -l

Git应用层代理

git config --global http.proxy socks5://127.0.0.1:1080

MongoDB备份和恢复

mongodump --gzip --db=<database> --archive=<path>

mongorestore --gzip --archive=<path>

MongoDB Replication配置

Mongo> rs.initiate()

Elasticsearch 安装顺序 X-Pack证书配置 入门文档 

使用ES_JAVA_OPTS控制内存占用

ik分词插件 同义词配置

MongoDB到Elasticsearch同步工具mongo-es

Nginx授权用户名密码访问

echo "username:`openssl passwd -apr1`" | sudo tee -a /etc/nginx/htpasswd.users

站点配置文件中加入

auth_basic "Restricted Access";
 auth_basic_user_file /etc/nginx/htpasswd.users;

sudo切换用户的各种参数与用户环境、当前目录的对应

Summary of the differences found 
                             corrupted by user's 
        HOME=/root   uses root's PATH   env vars
sudo -i     Y            Y[2]              N
sudo -s     N            Y[2]              Y
sudo bash   N            Y[2]              Y
sudo su     Y            N[1]              Y

sudo su USER SCRIPT / sudo su USER -c ‘COMMAND’

Ubuntu下pm2的正解:

  • 脚本目录放在/var/www下,文件归属www-data
  • 为www-data设置密码,设置shell为bash
  • sudo pm2 startup ubuntu -u www-data
  • 使用www-data启动pm2,运行pm2 save
  • 编辑无sudo的部署命令,形成shell脚本xxx放在/usr/local/bin
  • 使用自己的用户进入项目目录,运行sudo su -c ‘xxx’来部署

将目录修改时间批量修改为其中最新文件的修改时间(仅在macOS测试过)

for i in *; do (cd "$i"; touch -mt $(date -r `find . -type f -exec stat -f "%m" \{} \; | sort -n -r | head -1` "+%Y%m%d%H%M") . ); done

Ubuntu dpkg E: Sub-process 错误

sudo mv /var/lib/dpkg/info /var/lib/dpkg/info.bak
sudo mkdir /var/lib/dpkg/info
sudo apt-get update
sudo apt-get -f install xxx
sudo mv /var/lib/dpkg/info/* /var/lib/dpkg/info.bak
sudo rm -rf /var/lib/dpkg/info
sudo mv /var/lib/dpkg/info.bak /var/lib/dpkg/info

Linux 硬盘分区、格式化、挂载

这里都有

将一个非git目录和一个git仓库(的某一个分支)同步

git clone --bare --branch <NAME> <GIT URL> .git
git config core.bare false
git add .

MySQL 8.0的开发环境密码设空

-- 用Homebrew安装的MySQL8.0默认空密码,不可以运行mysql_secure_installation
-- 遇上Sequel Pro无法连接的问题,需要把root默认验证方式改为mysql_native_password
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';

微信电商相关研究

最近要做一个微信电商项目,需要实现如下功能:

  • 微信菜单到微信内网页的用户身份认证
  • 微信内网页的支付宝支付
  • 网页版扫码用户身份认证+网页版跳转支付
  • 线下扫码关注渠道识别

微信菜单(微信内打开的任意链接)到网页的用户身份认证

使用“网页内授权获取用户基本信息”接口,可以让用户在微信内点击链接后,跳转到网站的一个页面,服务器可以拿到用户的openid,还可以选择性地拿到其他高级信息。Gist

有个问题,微信现在貌似已经全面禁用内置浏览器的Cookie和Session,遥想在用户使用微信浏览器浏览网页的过程中保持登录,那么只能自己使用$_GET。

直接将openid放在$_GET信息中是相对安全的,因为对于不同的公众账号,同一用户的openid是不一样的,参考知乎上的问答 参考维基百科。但由于openid可能在中途被截获,因此https连接更好。

线下扫码关注渠道识别

用到两个接口:生成带参数的二维码扫描带参数二维码事件

扫描后,用户会关注账号,服务器会收到微信发来的信息,后台可以根据二维码参数将用户和渠道进行绑定。代码暂时没写。

微信网页内的支付宝支付

这个不能有,因为调用不到支付宝App的接口,只能调用网页版,而网页版在微信里又没有Cookie,还要输入用户名密码,极其鸡肋。

 网页版扫码用户身份认证+网页版跳转支付

理论上可以有,跟网站用户名密码登录 是个什么关系,是否取代,需要研究一下。

大灰大鱼有个家~~新家探班

IMG_20140407_134933

IMG_20140407_142328 IMG_20140407_133546 IMG_20140407_141049 IMG_20140407_141342———————————我是分割线———————————

看上图,大鱼对大灰说:还是左边的房子好看~~大灰说:大鱼很吵的。。。(因为右边才是我们的房子:)

大灰大鱼先去看了粑粑麻麻的房子~方方正正的两间房,走进去,从视觉上来说,很小诶,不过大灰说等家具全部搬进去后就会显得很大了~~吼吼,粑粑麻麻的餐厅比我们大,所在的楼在我们后面一排,他们说以后举绿旗就是有饭吃,红旗就是没饭吃。。。不知是不是说笑的。。

然后就去了大灰和大鱼以后的家,可惜门锁住了,进不去,所以去了一楼房型一样的一间,餐厅挺小的,还有个储物柜,估计是会被打掉的节奏,有一段走道,面积2平左右,略鸡肋,旁边的一堵非承重墙也可能会被打掉,这样从视觉效果上来看,厅会更大。卧室九平左右,略小,不过卧室嘛~睡觉嘛~~有张舒服的大床足够了,嘻嘻!

接下来,当当当当~~~~我们的大厅!根据图纸估算,有17、18平左右~~~哇塞~大鱼看到后立马蹦蹦跳跳,叽叽喳喳的进去了。左侧墙面是凹进去的,大鱼看到后立即想到了自己微博里收藏的一个打造小书房的图片~大鱼一直想把这个设计做到自己以后的房间里去,而且大灰也想到了这点,噢吼吼~~~达成一致,很好。可以想象以后在大厅的角落里,大灰在工作,大鱼在看(yu)书(le),旁边再摆个大书柜,多么舒坦的小日子~~再往右看,是两扇窗,开得有点小,没有阳台,阳台是连着卧室的。这间房子的遗憾之点是木有飘窗,不过我们可以弄一个假的飘窗嘛~~大鱼脑子里有个初步的想法,但是实际运用起来还是得到时看尺寸,而且做了假飘窗,沙发和电视机就得整体往中间移,不知道会不会浪费地方,客厅还是以简洁温馨为主,吼吼。再来是沙发~一定得搞个舒服的沙发,累了就可以直接躺在上面休息了,看电视的时候也会很惬意,但是大鱼不要做沙发土豆。。

最后是卫生间和厨房,初步定下,卫生间用移门节约空间,厨房呢,至于最里面是水槽还是灶具,得再研究一下。

———————————我是分割线———————————

因某些原因,上述图片中的房子将不再会是大灰大鱼的新家,但是这不代表我们就没有家,寻家之旅已经展开。。。。。。

虽然新家的房型已经变了,但是装修理念仍然在脑海中,等新家有着落后再行定夺。

祝大灰大鱼在寻家之旅中一切顺利!

———————————我还是分割线———————————

在这三个多礼拜中,大灰和大鱼又去看了挺多的房子,大灰一个人也去了好多次,因为户型基本都一样,所以大鱼只能根据房东想起来这套房子大致是什么样的。着重的三个地方就是顾村、永和和上南,目前为止,真正坐下来谈过的也就一位,不过也就是这一位,让大鱼认识到了一毛不拔的中年老男人的形象,那您就慢慢的守着这套房吧。上南也中意过一套,地段很好,出门方便,不过房子老,而且,说真心话,小。。。戳戳手指。顾村呢远是肯定远的,上班很不方便,但是离双方父母近,而且周围就有装逼的starfucks和Costa~~ 七号线一部到静安寺也是很高大上的嘛~~最最关键的是,这周三去看了一套毛坯房,大啊~双飘窗啊~距离700米啊~六楼的三楼啊~环境不错啊~得房率也挺高啊~大鱼已经想象着这房子是我们的了,可是价钱也好好啊~~~!!哎~~~各有优点,真的是好纠结啊。但大鱼还是比较中意大房子。。。再戳戳手指。。。希望价钱还能再下来吧~~

恩 目前阶段就是这样滴~~~ 不过大灰说,付完钱后一个礼拜内就要领证了。。这个。。那个。。

——————————大灰笔记的分割线———————————

记在“金九银十”的开头。

在理智的顾村,中庸的永和和激进的上南中,前者还是在最后阶段占据到了绝对优势,不能否认,离父母进和房型房龄的优势已经超越了后两处的地段优势。

本来想150万房东到手的古北陆翔苑还价还到150万我们到手就出手。由于房子大,换房时间可以延长到15年以上,公积金贷款60万的15年每月月供现金部分反而比10年50万更少。90的首付我们还是没有问题的。

可是就在这个当口,顾村的房东们三缄其口,不是“卖掉了”就是“不卖了”。

换位思考,原因显而易见:“金九银十”。

这一年中的秋季,万物开始凋零的岁月,却是房产中介心中繁茂的暖春。房东们纷纷捂房等待楼市复苏,房产涨价。

要知道古北陆翔苑这样的早期动迁小区,业主自住率不到百分之五十,甚至三成左右是空置房。这样的小区,同样的房型仅一套在售,这就意味着“零挂牌”。相比现在的零选择零竞争,若“金九银十”带来的是量价齐升,倒也不是坏事。

以10月下旬为契机,若古北陆翔苑,古北菊翔苑同为最低价的可选房源超过3套,且净付价不满155万,则出手。

若不能满足这个条件,则等待12月上中旬的机会。

积极看房被迫切换为被动观望,文宝苑55平130没谈,永和55平145万谈失败,上南45平130万房型不满。

希望明年的今天,甚至几年后的今天看到现在的决定,不要后悔。

另外也给我家大鱼几个月的时间酝酿领证的心理,嘿嘿!

小服,爸爸喊你回家——在家搭建公网可访问服务器环境全过程

由于种种原因,最终还是决定在家搭建一个服务器环境,把所有的测试网站,Demo站,咪哩嘛啦站都移回家。

先看一下我有什么

  • 一台2008年10月入手的Acer 4930 笔记本电脑
  • 一根下行20M,上行2M的电信光纤接入
  • 一个花生壳DDNS服务账号,免费的
  • 一个域名(uice.lu)
  • 一个DNSPod账户,免费的

基本思路,就是将域名解析到花生壳的动态域名,利用花生壳的DDNS动态绑定到家中的IP,从路由器中转发需要的服务端口到笔记本上,在笔记本上安装Ubuntu Server来运行需要的服务。

确认中国电信对DDNS的态度

由于家中已经改为光猫,而光猫自带路由功能,并且是锁定的,没有端口转发这种功能。这就意味着即使我又拖了个路由器,但只是通过动态IP连接光猫的路由,处于二级路由的子网中。

要让自己路由器WAN口拿到公网IP,只有将电信光猫的路由功能关闭,学名“改桥接”。网上查了N多方法,最后的结论:打10000号。

10000号帮我转了报修台,969112一小时后给我回电,说可以操作,人马上到。要知道这可是5月1号的晚上9点!不得不佩服电信的值班水平。

电信小哥很有爱,说这在理论上是禁止的,因此如果有电话回访,要说他没来过。

他们可以拿到对应我这台光猫的超级密码,因此很容易就解决了。确认了PPPOE拨号用户名和密码,我家又恢复了通过路由器拨号上网。

在路由器中设置动态域名,端口转发

TP-LINK自带花生壳的服务,直接输入花生壳的用户名密码即可。现在的极路由那就更友好了,据说他们的DDNS服务更先进一些,下次试试。

端口转发只能通过IP进行,因此先在路由器的DHCP给笔记本的MAC地址来一个静态分配。192.168.1.128,嘿嘿,我喜欢这个IP。

挑些常用的端口设置转发,维基百科上有个比较全面的的端口服务和所占用的协议说明,照着这个我开了DNS的53,FTP的20,21,SSH的22,SSL的443,HTTP的80和备用的8080。

在笔记本上安装Ubuntu Server

下载了最新的LTS版Ubuntu Server ISO文件,Trusty Tahr,可信的……塔尔羊?这是神马……

不想刻盘了(主要是没有盘),通过U盘直接安装Ubuntu Server。像以前一样,使用U盘启动,启动器我用的grub4dos,menu.lst配置这样子:

title Ubuntu Live CD
find --set-root /ubuntu-14.04-server-amd64.iso
kernel /BOOT/vmlinuz boot=casper iso-scan/filename=/ubuntu-14.04-server-amd64.iso ro quiet splash locale=zh_CN.UTF-8
initrd /BOOT/initrd.gz

从U盘启动以后果然不出我所料,安装程序报CD-ROM中没有找到盘。爹没有用CD装好么?这个帖子表示ISO文件里有几个文件名的后缀名错了,不影响CD安装,但是挂Live CD就会出问题。我怎么记得12.04就有这个问题了,这么多年了没人理一下吗?

于是尝试把ISO文件真的挂载到/cdrom文件夹。

Alt F2进终端

mkdir /media/usb
mount -t vfat /dev/sdb1 /media/usb
mount -o loop /media/usb/ubuntu.xxx.iso /cdrom

Alt F1回来

这下差不多可以装了。不过到安装可选软件包那一步的时候自动跳回菜单了。没事,俺们手动进行下面的步骤,按照菜单顺序,装了grub启动器。

接下来配网卡。既然笔记本有无线,那咱们就不连网线啦,直接把无线配置成默认网卡。

安装wpa_passphrase是不用上网的,这个东西已经被包含在了Ubuntu的CD-ROM源中。apt-get install wpa_passphrase 提示没找到CD-ROM!意料之外情理之中。好吧,CD-ROM源,把我们的ISO再mount回来,只不过这次mount在/media/cdrom了。

根据Ren兄博客中的指示,最后配置成功了。中间遇到一个弱弱的问题,sudo some command > filename用来保存执行结果的时候,即使前面有sudo,写入文件时也会报2没有权限。当然,我可没那么好学,先输出到home目录以后sudo cp搞定。

由于没有安装可选软件包,许多基本的命令都没有像telnet, ssh, curl,自己apt install呗。对了,为了避免它再叫我挂载CD-ROM,把源列表编辑了一下,从cdrom://改成了网易搜狐的最新14.04源。

对了,Terminal不支持双字节编码,因此如果语言设置的是中文,在本机屏幕上会看到一个个小方块。不过只是显示的问题,以后从其他电脑SSH的时候不会有这个问题。如果不爽的话,这里有几条路。

最后

sudo apt install apache2 mysql php5 git

本来添加php的PPA来保持最新的,突然发现14.04自带的已经是5.5.9了,于是就不搞了。注意php要在MySQL之后装,不然还得手动装php的mysql扩展。

老机器原地复活,怎一个爽字得了?

先跑一阵子,关于稳定性和照片,以后奉上。

架设DNS服务器,让网内使用内网IP连接

我使用的是BIND,这里有一篇好文

然后把路由器的DHCP DNS设置为新服务器的IP就好,注意这里并不依赖路由器的53端口转发,因为咱们DNS服务器只在局域网内使用。

配置温度传感器

使用lm_sensors,http://www.linuxsong.org/2010/09/linux-look-cpu-temperature/

上两张图

Acer 4930G 服务器

Acer 4930G 服务器

 

Angular.js学习手记 Promise

原来我喜欢的那种功能,叫做promise的autounrapping。但是1.2开始,这个功能被deprecated。伤心。

上代码:

angular.
  module('myApp', ['ngResource'])
    .config(function($parseProvider){
      $parseProvider.unwrapPromises(true);
    })
    .controller('MyController', function($scope, Object) {
      $scope.objects = Object.query(['A', 'B', 'C']);
    })
    .service('Object', function($q, $timeout) {
      
      this.query = function(objects) {
        
        var deferred = $q.defer();

        $timeout(function() {
          deferred.notify('notified');
          console.log('promise notified');
          
          if (new Date().getTime() % 2) {
            deferred.resolve(objects);
          } else {
            deferred.reject(['D']);
          }
        }, 1000);

        return deferred.promise;
      };
    });

参考:

 

 

我是LubanLock的作者

——LubanLock,鲁班锁,我正在开发,并且已经开发了一年多的一款企业内部信息系统平台,代码托管在Github

不知是从什么时候开始,特别想做好一个企业信息系统。好吧,姑且这么叫它。也许这听起来永远没有移动App那么大众化,没有CRM、ERP那么专业,没有点评那么实用,没有豆瓣那么文艺。但我开始做了,而且看到了商机,我就想把它做好,就是这样。

2011年6月,受熟人委托,尝试着做了上大附中的评教系统。

当时的我,是一个法学院大三学生,正在备考司法考试。先前有接过一些制作网站的生意,使用PHPWind,Discuz!,PHPCMS,Joomla,ECShop,这样的一些CMS去完成,几乎没有自己写过后段代码,只是用Dreamweaver折腾了不少的HTML和CSS。

我很自信,至少在技术方面,尽管连半桶水也算不上,但是却接下了这个评教系统的任务。记得我从网上找了一个现成的B-S架构的php评教系统,甚至和php, MySQL环境都是打包的。这个系统可以满足我80%的需求,但我需要修改源码来满足剩下的20%。写的非常粗糙,以至于放在标准php环境中满眼都是报错。尽管如此我一行行读它的代码,一点点理解。大约一周以后,我改出了自己评教系统的第一个版本。由于修改了大量不符合新的php版本建议的代码,源代码修改幅度大约在一半。界面上则使用了一块大黑板,在上面显示所有该班级教师的信息。还挂了一面锦旗显示班级名称。

系统被我安装在客户学校内的一台教师用计算机上,当知道任何一台计算机都能用作服务器时,他们很吃惊,也很满意。系统很好地满足了一个机房的学生同时上线参与评教,最后查看评教结果和排序统计的需求。我的第一个自己写的B-S系统就此圆满完成。

司法考试结束之后,我进入了一家律师事务所,在那,我继承并发扬了大学时候做网站的干劲。这是一家十分年轻的律师事务所,老板在互联网和内部管理方式上都很有想法。我改版和新建了好多网站,于此同时打起了律所内部系统的主意。

律师事务所使用一个2万元买来的老旧asp系统记录所有的客户信息,案件信息和律师工作台账。当时界面填写信息十分繁琐,软件公司只有一个程序员偶尔过来修改程序。我决定自己重写这套系统。

我的提议很快被批准了。我撰写了一个系统功能计划,在上大附中系统代码的基础上,我建立了新的MySQL表,新的HTML界面,中间混杂着各种php代码和SQL语句。

当时的我甚至还不知道MVC,我从Discuz!获得启发,建立了controller, function和view文件夹,分离了界面和数据库读写,将重复使用很多的php+HTML表格绘制抽象为一个exportTable()函数,给它设置了各种复杂的参数,以不变应万变。

2012年夏天,仍然在使用Dreamweaver编写php, HTML和SQL代码的我加入了Github,将自己的系统项目(原名starsys,现名syssh)搬了上去。版本管理的好处?是的,即使至今仍依稀可见上传的第一版代码

后来,我分离了Model和Controller,引入了正规军Codeigniter框架,使用AJAX技术将整个系统改为内部导航不需要刷新整个页面。使用同一系统为上大附中提供服务,作为其校园信息系统,这意味着同一数据库开始存储多个公司的信息,同一组代码开始为不同的公司服务(尽管只有两家)。很有野心的我花600大洋注册了五字母短域名sys.sh,欲做在“上海”滩通用的“系统”。

但与此同时,系统被捆绑地越来越死,越来越不能添加新的功能。业务需求不断的不能被满足。甚至系统的梳理和通用化的抽象常常梳理掉原本实用的功能。老板很失望,说我主动性下降,我也很失望,说老板不提供资源。

我始终相信这套系统是一定可以被做好的。2013年中,我决定停止更新syssh,重写整个系统。

这样的重写是在什么背景下的呢?1. 我与上大附中的系统合约刚刚完成,对方对我的系统并不是很满意,很多后续的需求看起来也不能被实现。2. 律师事务所有越来越多的新功能需求,系统的更新却停滞甚至倒退,大家对我的实力开始怀疑。3. 朋友中有新的学校,企业,公司甚至政府单位欲使用类似的系统,新的一波需求伴随着商机袭来。

我决定一个需求也不答应,自己重写自己的系统。我要做一个在后端层面通用的东西,所有数据都可以被转换,存储进来,而不需要写新的代码。我要做一个在前端开放的东西,所有企业都可以定制他们自己的页面,甚至不需要经过我的许可。

这样的东西要组成很简单,但却可以有很多种变化,而且牢不可破。我给它想了个名字:鲁班锁

待续