Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinWang15 committed Jul 10, 2017
0 parents commit a5c858b
Show file tree
Hide file tree
Showing 730 changed files with 224,418 additions and 0 deletions.
130 changes: 130 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# 圈子App期末报告

![](https://i.imgur.com/7peLkFi.jpg)

## 设计宗旨
* 人和人之间形成各种各样的圈子(E.g. 班级、寝室、实验室、社团、公司)

* 现在有很多社交圈子App,却鲜有提高效率的“工作圈子”
* 我设计的是一个工作圈子、效率圈子

* 为一个人的所有圈子提供统一的入口,一个平台处理所有待办事项


## 技术宗旨
* 一套核心(用户系统、圈子系统、消息系统、ACL)
* 无限可能的插件(服务器插件+客户端插件)
* HTML跨平台实现,可以于iOS、android、微信上运行
![App架构示意图](https://i.imgur.com/YHM9014.png)

这种可插拔的模块化、内核插件分离设计,很符合app的业务需要。

# Kernel层设计详述
## User
用户相关系统,包括用户注册、登入、鉴权、个人信息设置等模块。

## Group
群组系统,包括群组的建立、基本信息设定、用户加入群组、用户邀请别的用户加入群组、群组头像的生成、最近群组信息更新等。包括访问群组内其他成员与@mention他们的接口。

## Message & Notification
消息提醒系统,给每个用户一个统一的收件箱接收所有的群组消息。消息分为3种优先级,任何插件层的具体服务都可以调用消息系统给用户发消息,消息的出口也分站内界面、推送、短信/邮件(当前未实现)等多种。用户点击消息,app自动跳转到消息发源的服务。

## Access Control List
(本功能暂未在代码中实现,仅为设计)权限控制系统,允许服务对每个用户设定不同的权限级别,授权不同的角色做不同的操作。在真正的应用场景下,这种设置是很必要的,比如只有Product Manager可以在看板中把一个项目从阶段1推进到阶段2,普通的程序员不行。但这个期末Project时间有限,现在做的是所有人都有所有权限。

# Plugin层功能
为了印证设计以及让App看起来详实一些,我挑选了5个Plugin进行实现,接下来将简单对它们进行说明。
## Contact
通讯录,非常简单的一个功能,主要示范如何读取同组联系人的信息。
另外,添加了把群里用户保存到手机通讯录的功能。

## Forum
论坛,一个标准的论坛功能,带发帖、回帖、浏览等功能。
添加了在论坛中@mention同组别的用户的功能,被@mention的人会收到通知,帖子被回也会收到通知。

## Netdisk
网盘(文件共享)功能, 比较实用的功能,支持圈内用户间分享文件。
支持给文件上tag标签,支持实用tag标签进行过滤。
对于文档类型的文件(doc、pdf、xls等),手机端可以直接点击下载并查看。
但对于非文档类型的文件,手机阅览很不方便,日后如果有时间完善这个程序,我希望做一个屏幕穿越功能:电脑端打开某一个网站,显示一个二维码,在手机里扫描那个二维码,自动进行“屏幕穿越”,把网盘的上传、下载功能都穿越到网页上。
或者一种不那么酷的方式是,为这整套app做一个PC端。

## Kanban
这是综合性较强的一个功能,常见于软件工程中的项目管理。类似一个高级版的TODOLIST,但是任务却分多个阶段,每个阶段可以设置deadline、设置子任务,每个子任务可以分配给不同的人完成。系统有一些复杂性,圈子的力量在这个系统中最能够体现。(设想一个用户同时在多个开发组,他能在消息中看到一个统一的待办事项,点击消息又能到某个具体开发组里,看整个项目的流程。做任务时遇到困难,他还可以添加子任务并分配给队友,以获得帮助)
![看板概念](https://i.imgur.com/T3d5LV0.png)

## 相册
简单的图片上传和在线查看功能,支持同时上传多张图片,图片可来源于相册或直接使用相机拍摄。

## (未实现)活地图
类似于微信定位实时分享,可以看到别的成员的地理位置,可以设置导航到他们身边。

## (未实现)AA账本
适用于寝室等圈子,某成员交了一笔费/买了一件公用的商品/付了一笔餐费,现在这里记一笔,并选择参与的成员。到月末/认为方便的时间,自动计算出划款数量,统一结算。

# App截图
![](https://i.imgur.com/h2TQrpz.png)
![](https://i.imgur.com/f5bujme.png)
![](https://i.imgur.com/gDzvX8N.png)
# 未来打算
## ACL
如前所述,ACL是一个重要的功能,还未能完成,如果项目有机会后续发展成为产品,第一个应该完成的就是它。

## SDK和Developer Guide
插件式的设计允许开发者开发任何自己想要的功能。
应该分别提供Server和Client的SDK,来让开发者方便地访问Kernel中的四大模块所暴露的接口,并用它们开发自己的业务。
这个功能在打后期可以试着上线,甚至可以做个圈子应用市场,潜力无穷啊。

## 网页客户端
手机App在某些情况下可能不是特别好用,特别是当我们在做一个效率工具的时候。所以,我还考虑开发一个功能完全一样的网页版客户端,这样能最大利用PC的优势,更加高效地办公。

## 微信集成
因为本来就是用HTML5做的,所以放在微信上跑并不难。只是需要去申请服务号,才能调用微信的定位、扫码接口,才能把微信绑定(或者直接用微信注册)和对用户的信息推送做在微信上。

# 程序代码运行方式
代码运行方式比较繁琐,如果想看效果直接运行apk就好,我已经部署在公网服务器。
## Server部署
Server使用了Laravel框架(Laravel.com),需要composer包管理器(getcomposer.org)
1. 解压缩Server源代码包
2. 安装composer
3. cd进工程目录
4. 执行composer install安装依赖库
5. chmod storage和bootstrap目录,确保webserver有写权限
6. 复制.env.example文件到.env文件,并修改参数,配置DB_HOST、API_DOMAIN等信息
7. 建立数据库(需要和.env中信息对应)
8. 运行php artisan migrate和php artisan db:seed,来初始化数据库
9. 运行php artisan route:cache和php artisan api:cache
10. 安装Redis并开启Redis服务
11. 配置后台服务运行php artisan queue:work,配置计划任务每隔1分钟运行php artisan schedule:run
12. 应当可以正常运行,出现500可以看./storage/logs/laravel.log

## Client部署
Client端使用了Ionic框架(基于Angular 4)和Apache Cordova混合App框架
开发、编译和打包中大量使用NodeJS脚本,所以需要先下载NodeJS(推荐版本6.x)
假设已经安装好NodeJS、JDK和Android SDK,你需要按照如下步骤编译
1. 解压缩Client源代码包
2. cd进工程目录
3. 执行npm install安装依赖库
4. 执行npm install -g cordova
5. 执行npm install -g ionic
6. 执行ionic platform add android
7. 复制./src/config/environment.ts.example到./src/config/environment.ts并修改其内容,指向后端
8. 执行ionic run android或者ionic build android

## 直接运行APK
账户1:[email protected] / secret
账户2:[email protected] / secret
也可以自己注册账户、自己建圈子并邀请另一个自己注册的账户加入圈子

# 遇到困难
* 在App架构方面斟酌了挺久的,原来想只做一个AA账本功能,和老师讨论后决定加入更多的可拓展性。所以业务就不能写死,必须写得灵活,有清晰的层次分割。
* 以前一直是AngularJS的用户,现在切换到了时髦的Angular4,适应了一段时间。
* 在比较短的时间内很难完成自己所有的设想,所以一些只能写在报告里,分享概念了。如果之后有理由把这个App拿出来好好做的话可以实现。

# 进步
* 设计了一套结构清晰、灵活的系统,更多的力气被放到Kernel上,通过Kernel向上层Plugin暴露接口,我达到了极高的可拓展性。每个功能都可以给一个团队独立开发,互不影响。这种分层那么清楚的App,在我做的所有作品中还是第一次,感觉很有成就感。


# 联系方式
王轲 [email protected]
![](https://i.imgur.com/q19lzLL.png)
17 changes: 17 additions & 0 deletions app/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs
# editorconfig.org

root = true

[*]
indent_style = space
indent_size = 2

# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
34 changes: 34 additions & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Specifies intentionally untracked files to ignore when using Git
# http://git-scm.com/docs/gitignore

*~
*.sw[mnpcod]
*.log
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace
.vscode/
npm-debug.log*

.idea/
.sass-cache/
.tmp/
.versions/
coverage/
dist/
node_modules/
tmp/
temp/
hooks/
platforms/
plugins/
plugins/android.json
plugins/ios.json
$RECYCLE.BIN/
.DS_Store
Thumbs.db
UserInterfaceState.xcuserstate

src/config/environment.ts
79 changes: 79 additions & 0 deletions app/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<widget id="com.quanzi.app" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>圈子</name>
<description>圈子 App</description>
<content src="index.html"/>
<access origin="*"/>
<allow-navigation href="http://ionic.local/*"/>
<allow-intent href="http://*/*"/>
<allow-intent href="https://*/*"/>
<allow-intent href="tel:*"/>
<allow-intent href="sms:*"/>
<allow-intent href="mailto:*"/>
<allow-intent href="geo:*"/>
<preference name="webviewbounce" value="false"/>
<preference name="UIWebViewBounce" value="false"/>
<preference name="DisallowOverscroll" value="true"/>
<preference name="android-minSdkVersion" value="16"/>
<preference name="BackupWebStorage" value="none"/>
<preference name="SplashMaintainAspectRatio" value="true"/>
<preference name="FadeSplashScreenDuration" value="300"/>
<preference name="SplashShowOnlyFirstTime" value="false"/>
<preference name="SplashScreen" value="screen"/>
<preference name="SplashScreenDelay" value="3000"/>
<platform name="android">
<allow-intent href="market:*"/>
<icon src="resources\android\icon\drawable-ldpi-icon.png" density="ldpi"/>
<icon src="resources\android\icon\drawable-mdpi-icon.png" density="mdpi"/>
<icon src="resources\android\icon\drawable-hdpi-icon.png" density="hdpi"/>
<icon src="resources\android\icon\drawable-xhdpi-icon.png" density="xhdpi"/>
<icon src="resources\android\icon\drawable-xxhdpi-icon.png" density="xxhdpi"/>
<icon src="resources\android\icon\drawable-xxxhdpi-icon.png" density="xxxhdpi"/>
<splash src="resources\android\splash\drawable-land-ldpi-screen.png" density="land-ldpi"/>
<splash src="resources\android\splash\drawable-land-mdpi-screen.png" density="land-mdpi"/>
<splash src="resources\android\splash\drawable-port-ldpi-screen.png" density="port-ldpi"/>
<splash src="resources\android\splash\drawable-port-mdpi-screen.png" density="port-mdpi"/>
<splash src="resources\android\splash\drawable-port-hdpi-screen.png" density="port-hdpi"/>
</platform>
<platform name="ios">
<allow-intent href="itms:*"/>
<allow-intent href="itms-apps:*"/>
<icon src="resources/ios/icon/icon.png" width="57" height="57"/>
<icon src="resources/ios/icon/[email protected]" width="114" height="114"/>
<icon src="resources/ios/icon/icon-40.png" width="40" height="40"/>
<icon src="resources/ios/icon/[email protected]" width="80" height="80"/>
<icon src="resources/ios/icon/[email protected]" width="120" height="120"/>
<icon src="resources/ios/icon/icon-50.png" width="50" height="50"/>
<icon src="resources/ios/icon/[email protected]" width="100" height="100"/>
<icon src="resources/ios/icon/icon-60.png" width="60" height="60"/>
<icon src="resources/ios/icon/[email protected]" width="120" height="120"/>
<icon src="resources/ios/icon/[email protected]" width="180" height="180"/>
<icon src="resources/ios/icon/icon-72.png" width="72" height="72"/>
<icon src="resources/ios/icon/[email protected]" width="144" height="144"/>
<icon src="resources/ios/icon/icon-76.png" width="76" height="76"/>
<icon src="resources/ios/icon/[email protected]" width="152" height="152"/>
<icon src="resources/ios/icon/[email protected]" width="167" height="167"/>
<icon src="resources/ios/icon/icon-small.png" width="29" height="29"/>
<icon src="resources/ios/icon/[email protected]" width="58" height="58"/>
<icon src="resources/ios/icon/[email protected]" width="87" height="87"/>
<splash src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" height="1136"/>
<splash src="resources/ios/splash/Default-667h.png" width="750" height="1334"/>
<splash src="resources/ios/splash/Default-736h.png" width="1242" height="2208"/>
<splash src="resources/ios/splash/Default-Landscape-736h.png" width="2208" height="1242"/>
<splash src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" height="1536"/>
<splash src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" height="2048"/>
<splash src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" height="768"/>
<splash src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" height="2048"/>
<splash src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" height="2732"/>
<splash src="resources/ios/splash/Default-Portrait~ipad.png" width="768" height="1024"/>
<splash src="resources/ios/splash/Default@2x~iphone.png" width="640" height="960"/>
<splash src="resources/ios/splash/Default~iphone.png" width="320" height="480"/>
</platform>
<plugin name="ionic-plugin-keyboard" spec="~2.2.1"/>
<plugin name="cordova-plugin-whitelist" spec="1.3.1"/>
<plugin name="cordova-plugin-console" spec="1.0.5"/>
<plugin name="cordova-plugin-statusbar" spec="2.2.2"/>
<plugin name="cordova-plugin-device" spec="1.1.4"/>
<plugin name="cordova-plugin-splashscreen" spec="~4.0.1"/>
<icon src="resources\android\icon\drawable-xhdpi-icon.png"/>
</widget>
37 changes: 37 additions & 0 deletions app/config/copy.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// this is a custom dictionary to make it easy to extend/override
// provide a name for an entry, it can be anything such as 'copyAssets' or 'copyFonts'
// then provide an object with a `src` array of globs and a `dest` string
module.exports = {
copyFroalaEditorCss: {
src: '{{ROOT}}/node_modules/froala-editor/css/froala_editor.pkgd.min.css',
dest: '{{SRC}}/assets/',
},
copyFontAwesome: {
src: '{{ROOT}}/node_modules/font-awesome/css/font-awesome.min.css',
dest: '{{SRC}}/assets/',
},
copyFontsAwesomeFonts: {
src: 'node_modules/font-awesome/fonts/*',
dest: '{{WWW}}/fonts/',
},
copyAssets: {
src: ['{{SRC}}/assets/**/*'],
dest: '{{WWW}}/assets',
},
copyIndexContent: {
src: ['{{SRC}}/index.html', '{{SRC}}/manifest.json', '{{SRC}}/service-worker.js'],
dest: '{{WWW}}',
},
copyFonts: {
src: ['{{ROOT}}/node_modules/ionicons/dist/fonts/**/*', '{{ROOT}}/node_modules/ionic-angular/fonts/**/*'],
dest: '{{WWW}}/assets/fonts',
},
copyPolyfills: {
src: ['{{ROOT}}/node_modules/ionic-angular/polyfills/polyfills.js'],
dest: '{{BUILD}}',
},
copySwToolbox: {
src: ['{{ROOT}}/node_modules/sw-toolbox/sw-toolbox.js'],
dest: '{{BUILD}}',
},
}
Loading

0 comments on commit a5c858b

Please sign in to comment.