<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          teamsalt任務(wù)管理系統(tǒng)

          聯(lián)合創(chuàng)作 · 2023-10-01 19:35

          teamsalt


          什么是teamsalt?

          teamsalt是一個在線的團隊寫作任務(wù)管理系統(tǒng)。
          teamsalt是team+salt(鹽),寓意就是作為鹽一樣,成為團隊中不可缺少的系統(tǒng)。
          系統(tǒng)設(shè)計參考了teambition、tower、worktile、fengcheco等。

          長什么樣呢?

          http://teamsalt.duapp.com/
          user: admin
          password: 1

          搭建在bae上面,使用bae2.0,可能訪問不太穩(wěn)定,打算遷移到其他平臺上面。

          技術(shù)選型

          1. 后臺

          • jfinal 基本可以負擔(dān)后臺

        2. 前臺

        3. 部署打包

          • grunt 使用grunt完成壓縮、合并等。

        4. 數(shù)據(jù)庫

          • mysql

          后臺開發(fā)說明

          后臺使用jfinal進行開發(fā),具體開發(fā),請查看jfinal開發(fā)手冊,30分鐘就可以閱讀完了。

          目錄結(jié)構(gòu)

          .
          ├── com
          │   └── teamsalt
          │       ├── common
          │       │   ├── Message.java                        // 請求返回 json 對象封裝類
          │       │   ├── TeamsaltConfig.java                    // jfinal 配置
          │       │   └── TeamsaltConstants.java                // 常量類
          │       ├── controller
          │       │   ├── CommentController.java                // 評論 controller
          │       │   ├── IndexController.java                // 首頁 controller
          │       │   ├── InviteController.java                // 邀請用戶 controller
          │       │   ├── ProjectController.java                // 項目 controller
          │       │   ├── TaskController.java                    // 任務(wù) controller
          │       │   ├── TasklistController.java                // 任務(wù)列表 controller
          │       │   └── UserController.java                    // 用戶 controller
          │       ├── filter
          │       │   ├── MainFilter.java                        // 使用Filter過濾main.html頁面,解決jfinal無法過濾靜態(tài)html的問題
          │       │   └── xss                                    // XSS 過濾攔截
          │       │       ├── CrossScriptingFilter.java
          │       │       ├── HTMLFilter.java
          │       │       └── RequestWrapper.java
          │       ├── interceptor
          │       │   ├── CheckLoginInterceptor.java            // 當(dāng)訪問/login頁面的時候,判斷是否已經(jīng)登錄,已經(jīng)登錄,則跳轉(zhuǎn)到/home
          │       │   └── GlobalLoginInterceptor.java            // 全局用戶登錄攔截器
          │       ├── kit                                        // 常用的一些工具類
          │       │   ├── ConfigKit.java
          │       │   ├── ContextKit.java
          │       │   ├── CookieKit.java
          │       │   ├── DateKit.java
          │       │   ├── HtmlTagKit.java
          │       │   ├── PwdKit.java
          │       │   └── UuidKit.java
          │       └── model                                    // model 層的各種對象
          │           ├── Comment.java
          │           ├── Invite.java
          │           ├── InviteUser.java
          │           ├── Project.java
          │           ├── ProjectTasklist.java
          │           ├── ProjectUser.java
          │           ├── Task.java
          │           ├── Tasklist.java
          │           ├── TasklistTask.java
          │           └── User.java
          ├── log4j.properties                                // log4j 配置
          └── S.java                                            // 采用 jetty 的啟動類

          代碼開發(fā)比較簡單,具體查看jfinal手冊就能進行代碼開發(fā)了。

          前臺開發(fā)說明

          前臺采用單頁面應(yīng)用程序(SPA)的開發(fā)方式,完全可以和后臺分離出來,部署在不同的服務(wù)器上面,而且可以將前臺用 phonegap 之類的工具,打包成android、ios、winPhone等的應(yīng)用,起初也就是這么設(shè)計的。

          js 文件的代碼路徑是在teamsalt/WebContent/js中,具體說明如下。

          js 目錄結(jié)構(gòu)

          .
          ├── app                                // 這個是壓縮代碼后產(chǎn)生的文件地方
          │   ├── common
          │   ├── model
          │   ├── object
          │   ├── router
          │   ├── ui-component
          │   ├── view
          │   └── widget
          ├── dist                            // 這個是壓縮時候的臨時文件
          │   ├── common
          │   ├── model
          │   ├── object
          │   ├── router
          │   ├── ui-component
          │   ├── view
          │   └── widget
          ├── gallery                            // 這個是需要的插件包
          │   ├── backbone
          │   ├── bootbox
          │   ├── bootstrap
          │   ├── contextmenu
          │   ├── datepicker
          │   ├── dropdownx
          │   ├── notify
          │   ├── perfect-scrollbar
          │   ├── popbox
          │   ├── select
          │   ├── tags
          │   ├── template
          │   ├── underscore
          │   └── xdate
          ├── jquery                            // jquery 
          │   └── jquery
          ├── node_modules                    // 使用 grunt 需要的插件,已經(jīng)提供
          │   ├── grunt
          │   ├── grunt-cmd-concat
          │   ├── grunt-cmd-transport
          │   ├── grunt-contrib-clean
          │   └── grunt-contrib-uglify
          ├── seajs                            // seajs 
          │   ├── 1.3.1
          │   ├── plugin-log
          │   ├── seajs
          │   └── seajs-text
          └── src                                // 這個是程序的源代碼了
              ├── common                        // 公共工具
              ├── model                        // model 層
              ├── object                        // 自定義的一個 map 對象
              ├── router                        // 路由器
              ├── ui-component                // 自定義的 ui 組件
              ├── view                        // view 層
              └── widget                        // 自定義的 widget 組件

          js 開發(fā)

          采用 seajs 和 backbone 進行代碼架構(gòu),同后臺同樣的 mvc 模式開發(fā)。

          model 層

          user.js

          define(function(require, exports, module) {
          
              var $ = require('jquery');
              var _ = require('underscore');
              var Backbone = require('backbone');
          
              var User = Backbone.Model.extend({
                  getUser : function(params, success) {
                      var url = '/user/profile/';
                      var self = this;
                      Util.query.g(url, '', function(result) {
                          success(result.other, params);
                      });
                  },
                  getUsersByProjectIdAndTaskId : function(params, success, error) {
                      this.fetch({
                          url : '/data/' + Util.curProjectId + '-users.json',
                          success : function(model, response, options) {
                              success(response);
                          },
                          error : function(XMLHttpRequest, textStatus, errorThrown) {
                              error(arguments);
                          }
                      });
                  },
                  getUsersByProject : function(params, success, error) {
                      var url = '/user/getProjectUsers';
                      Util.query.g(url, params, function(result) {
                          success(result.other);
                      });
                  },
                  // 得到所有用戶
                  getAllUser : function(params, success) {
                      var url = '/user/getAllUser';
                      Util.query.g(url, '', function(result) {
                          success(result.other);
                      });
                  }
              });
              module.exports = User;
          })

          control 層

          雖然叫做 view 但是在架構(gòu)上面,擔(dān)任的是 contro 層的功能。

          layout.js

          /**
           * @author zhaopeng
           * @datetime 2013-08-27
           * @description 程序任務(wù)主界面入口
           */
          define(function(require, exports, module){
          
              var $             = require('jquery');
              var _             = require('underscore');
              var Backbone     = require('backbone');
              var Bootstrap     = require('bootstrap');
          
              // 布局模板
              var layoutHtml     = require('./tpl/layout.html');
          
              // 模板
              var ProjectBar     = require('./header/projectBar');// header左側(cè)項目切換bar
              var UserinfoBar = require('./header/userinfoBar');// header右側(cè)用戶信息bar
              var SidebarTasklist     = require('./sidebar/sidebar-tasklist');// 左側(cè)側(cè)邊欄
              var SidebarUser     = require('./sidebar/sidebar-user');// 左側(cè)側(cè)邊欄
              var ListPanel     = require('./container/listPanel');// container左側(cè)列表
              var DetailPanel = require('./container/detailPanel');// container右側(cè)詳情
              var CommonView = require('./commonView');// 公共組件VIEW
          
              //模型
              var Comment =  require('../model/comment');
              var Project =  require('../model/project');
              var Task =  require('../model/task');
              var Tasklist =  require('../model/tasklist');
              var User =  require('../model/user');
          
              var Laoyout = Backbone.View.extend({
                  el: 'body',
                  events:{
                      'updateCommon #sidebar':'updateCommon',
                      'updateCommon #list-panel':'updateCommon',
                      'updateCommon #detail-panel':'updateCommon',
                      'deleteTask #detail-panel':'deleteTask',
                       'updateTask #detail-panel':'updateTask'
                  },            
                  initialize: function() {
                      this.$el.html(Util.tpl.t(layoutHtml,{})).hide().show('1000');
                      // 初始化模型,全部記載到map中
                      this.comment  =  new Comment();
                      this.project  =  new Project();
                      this.task     =  new Task();
                      this.tasklist =  new Tasklist();
                      this.user     =  new User();
          
                      Util.Models.put('comment',this.comment);
                      Util.Models.put('project',this.project);
                      Util.Models.put('task',this.task);
                      Util.Models.put('tasklist',this.tasklist);
                      Util.Models.put('user',this.user);
          
                      // 初始化布局界面
                      this.projectBar = new ProjectBar();
                      this.userinfoBar = new UserinfoBar();
                      this.sidebarTasklist = new SidebarTasklist();
                      this.sidebarUser = new SidebarUser();
                      this.listPanel = new ListPanel();
                      this.detailPanel = new DetailPanel();
          
                      Util.Views.put('projectBar',this.projectBar);
                      Util.Views.put('userinfoBar',this.userinfoBar);
                      Util.Views.put('sidebarTasklist',this.sidebarTasklist);
                      Util.Views.put('sidebarUser',this.sidebarUser);
                      Util.Views.put('listPanel',this.listPanel);
                      Util.Views.put('detailPanel',this.detailPanel);
                  },
                  updateCommon:function(e){
                      CommonView.init();
                  },
                  //刪除任務(wù)后,同步刪除列表中的數(shù)據(jù)
                  deleteTask:function(e,result){
                      this.listPanel.deleteTask(result.uuid);
                  },
                  //更新任務(wù)后,同步更新列表中的數(shù)據(jù)
                  updateTask:function(e,result){
                      this.listPanel.updateTask(result);
                  }
              });
          
              module.exports = Laoyout;
          })

          view 層

          使用 artTemplate 模板引擎,模板文件都存放在對應(yīng)的tpl文件夾下。

          layout.html

          <nav id="header" class="navbar navbar-default navbar-inverse navbar-static-top navbar-fixed-top" role="navigation">
              <!-- Brand and toggle get grouped for better mobile display -->
              <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
                  <span class="sr-only">Toggle navigation</span>
                  <span class="icon-bar"></span>
                  <span class="icon-bar"></span>
                  <span class="icon-bar"></span>
                </button>
          
              </div>
          
              <!-- Collect the nav links, forms, and other content for toggling -->
              <div class="collapse navbar-collapse navbar-ex1-collapse">
                <ul id="project-bar" class="nav navbar-nav">
          
                </ul>
                <a class="navbar-brand" href="#" style="margin-left: 40%;">teamsalt</a>
                <ul id="userinfo-bar" class="nav navbar-nav navbar-right">
          
                </ul>
              </div><!-- /.navbar-collapse -->    
            </nav>
          
          
            <aside id="sidebar">
              <section id="sidebar-tasklist" class="sidebar-menu">
              </section>
              <section id="sidebar-user" class="sidebar-menu">
              </section>    
            </aside>
            <div id="container" >
              <div id="list-panel" class="bor-r">
              </div>
              <div id="detail-panel">   
              </div>
            </div>
            <div class="notifications top-right"></div>

          使用 grunt 打包文件項目

          1. 安裝nodejs

          根據(jù)系統(tǒng)到 http://nodejs.org/ 下載安裝對應(yīng)的 nodejs。我用的是 linux 編譯后的版本,在.bashrc將 nodejs 添加到環(huán)境變量就好了。 如果是 windows 直接安裝就可以了。

          2. 安裝grunt命令行工具grunt-cli

          使用-g全局安裝,這樣可以在任何一個目錄里使用了。命令:npm install -g grunt-cli

          需要注意的是在 linux 或 mac 下有時會報沒有權(quán)限的錯誤,這時須在前面加一個sudo

          3. 安裝grunt

          代碼中已經(jīng)包含了 grunt 需要的插件,所有只需要安裝 grunt 就可以了。

          進入目錄,使用命令:npm install grunt --save-dev

          至此,安裝完畢。

          4. 打包 js 文件

          在 Gruntfile.js 中提供了一下幾個命令。

          grunt build-t        // 執(zhí)行 transport
          grunt build-c        // 執(zhí)行 concat
          grunt build-u        // 執(zhí)行 uglify
          grunt build-min        // 執(zhí)行壓縮
          grunt build-all        // 執(zhí)行以上所有命令
          grunt                // 執(zhí)行 clean, 刪除 app 和 dist 目錄

          壓縮提醒

          1. 壓縮合并后的代碼是放在teamsalt/WebContent/js/app/,如果部署只需要將app.js上傳到服務(wù)器就可以了。

          2. 在本地如何切換開發(fā)環(huán)境何生產(chǎn)環(huán)境的js代碼。

            // For development
                 if (location.href.indexOf("?pro") > 0) {
                     seajs.use("app/app");
                 }
                 // For production
                 else {
                     seajs.use("src/app");
                 }

          未來計劃

          對目前此系統(tǒng)暫停開發(fā),全心專注進行第二個版本的開發(fā),第二個版本具有更好的架構(gòu)設(shè)計,更輕快的開發(fā)速度,更多的功能特性。在基本版本完成之后,同樣也會選擇開源的方式進行發(fā)布。

          瀏覽 12
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          編輯 分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          編輯 分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  奇米伊人777 | 日韩成人AV一区 | 大色鬼AV | 日本成人1024 | 免费A级毛片 |