├── .gitignore
├── README.md
├── app.js
├── config.coffee
├── config.js
├── controlers
├── adminCtr.coffee
├── adminCtr.js
├── departmentCtr.coffee
├── departmentCtr.js
├── installCtr.coffee
├── installCtr.js
├── reportCtr.coffee
├── reportCtr.js
├── userCtr.coffee
└── userCtr.js
├── models
├── departmentsModel.coffee
├── departmentsModel.js
├── reportModel.coffee
├── reportModel.js
├── usersModel.coffee
└── usersModel.js
├── other&this
└── db-info.md
├── package.json
├── public
├── css
│ ├── adminDepartment.css
│ ├── adminDepartment.less
│ ├── adminGroup.css
│ ├── adminGroup.less
│ ├── adminStyle.css
│ ├── adminStyle.less
│ ├── adminUser.css
│ ├── adminUser.less
│ ├── bootstrap.min.css
│ ├── header.css
│ ├── header.less
│ ├── pepper-grinder
│ │ ├── images
│ │ │ ├── animated-overlay.gif
│ │ │ ├── ui-bg_diagonal-maze_20_6e4f1c_10x10.png
│ │ │ ├── ui-bg_diagonal-maze_40_000000_10x10.png
│ │ │ ├── ui-bg_fine-grain_10_eceadf_60x60.png
│ │ │ ├── ui-bg_fine-grain_10_f8f7f6_60x60.png
│ │ │ ├── ui-bg_fine-grain_15_eceadf_60x60.png
│ │ │ ├── ui-bg_fine-grain_15_f7f3de_60x60.png
│ │ │ ├── ui-bg_fine-grain_15_ffffff_60x60.png
│ │ │ ├── ui-bg_fine-grain_65_654b24_60x60.png
│ │ │ ├── ui-bg_fine-grain_68_b83400_60x60.png
│ │ │ ├── ui-icons_222222_256x240.png
│ │ │ ├── ui-icons_3572ac_256x240.png
│ │ │ ├── ui-icons_8c291d_256x240.png
│ │ │ ├── ui-icons_b83400_256x240.png
│ │ │ ├── ui-icons_fbdb93_256x240.png
│ │ │ └── ui-icons_ffffff_256x240.png
│ │ ├── jquery-ui-1.10.3.custom.css
│ │ └── jquery-ui-1.10.3.custom.min.css
│ ├── reportStyle.css
│ ├── reportStyle.less
│ ├── style.css
│ ├── style.less
│ ├── treeList.css
│ └── treeList.less
├── img
│ ├── glyphicons-halflings-white.png
│ └── glyphicons-halflings.png
├── js
│ ├── ReportModel.coffee
│ ├── ReportModel.js
│ ├── TreeList.coffee
│ ├── TreeList.js
│ ├── admin
│ │ ├── DepartmentUserMode.coffee
│ │ ├── DepartmentUserMode.js
│ │ ├── admingroup.coffee
│ │ ├── admingroup.js
│ │ ├── department.coffee
│ │ ├── department.js
│ │ ├── users.coffee
│ │ └── users.js
│ ├── bootstrap.min.js
│ ├── cs.js
│ ├── jquery-1.9.1.min.js
│ ├── jquery-ui-1.10.3.custom.min.js
│ ├── jquery.mobile-1.3.1.min.js
│ ├── knockout-2.2.1.js
│ ├── login.coffee
│ ├── login.js
│ ├── password.coffee
│ ├── password.js
│ ├── reportBase.coffee
│ ├── reportBase.js
│ ├── require.js
│ ├── showReports.coffee
│ ├── showReports.js
│ ├── subordinateReports.coffee
│ ├── subordinateReports.js
│ ├── validator-min.js
│ ├── validator.js
│ ├── writeReport.coffee
│ └── writeReport.js
├── mobile
│ ├── css
│ │ ├── images
│ │ │ ├── ajax-loader.gif
│ │ │ ├── icons-18-black.png
│ │ │ ├── icons-18-white.png
│ │ │ ├── icons-36-black.png
│ │ │ └── icons-36-white.png
│ │ ├── jquery.mobile-1.3.1.min.css
│ │ ├── reportStyle.css
│ │ └── reportStyle.less
│ └── js
│ │ ├── Model.coffee
│ │ ├── Model.js
│ │ ├── main.coffee
│ │ └── main.js
└── ueditor
│ ├── dialogs
│ ├── highlightcode
│ │ └── highlightcode.html
│ ├── internal.js
│ ├── link
│ │ └── link.html
│ ├── spechars
│ │ ├── spechars.html
│ │ └── spechars.js
│ ├── table
│ │ ├── dragicon.png
│ │ ├── edittable.css
│ │ ├── edittable.html
│ │ ├── edittable.js
│ │ ├── edittd.html
│ │ └── edittip.html
│ └── tangram.js
│ ├── editor_all.js
│ ├── editor_all_min.js
│ ├── editor_config.js
│ ├── lang
│ ├── en
│ │ ├── en.js
│ │ └── images
│ │ │ ├── addimage.png
│ │ │ ├── alldeletebtnhoverskin.png
│ │ │ ├── alldeletebtnupskin.png
│ │ │ ├── background.png
│ │ │ ├── button.png
│ │ │ ├── copy.png
│ │ │ ├── deletedisable.png
│ │ │ ├── deleteenable.png
│ │ │ ├── imglabel.png
│ │ │ ├── listbackground.png
│ │ │ ├── localimage.png
│ │ │ ├── music.png
│ │ │ ├── rotateleftdisable.png
│ │ │ ├── rotateleftenable.png
│ │ │ ├── rotaterightdisable.png
│ │ │ ├── rotaterightenable.png
│ │ │ └── upload.png
│ └── zh-cn
│ │ ├── images
│ │ ├── copy.png
│ │ ├── imglabel.png
│ │ ├── localimage.png
│ │ ├── music.png
│ │ └── upload.png
│ │ └── zh-cn.js
│ ├── themes
│ ├── default
│ │ ├── css
│ │ │ └── ueditor.css
│ │ ├── dialogbase.css
│ │ └── images
│ │ │ ├── anchor.gif
│ │ │ ├── arrow.png
│ │ │ ├── button-bg.gif
│ │ │ ├── cancelbutton.gif
│ │ │ ├── cursor_h.gif
│ │ │ ├── cursor_h.png
│ │ │ ├── cursor_v.gif
│ │ │ ├── cursor_v.png
│ │ │ ├── dialog-title-bg.png
│ │ │ ├── filescan.png
│ │ │ ├── highlighted.gif
│ │ │ ├── icons-all.gif
│ │ │ ├── icons.gif
│ │ │ ├── icons.png
│ │ │ ├── lock.gif
│ │ │ ├── neweditor-tab-bg.png
│ │ │ ├── pagebreak.gif
│ │ │ ├── scale.png
│ │ │ ├── spacer.gif
│ │ │ ├── sparator_v.png
│ │ │ ├── toolbar_bg.png
│ │ │ ├── unhighlighted.gif
│ │ │ ├── upload.png
│ │ │ ├── videologo.gif
│ │ │ ├── word.gif
│ │ │ └── wordpaste.png
│ └── iframe.css
│ └── third-party
│ └── SyntaxHighlighter
│ ├── shCore.js
│ └── shCoreDefault.css
├── routes
├── routeProfile.coffee
└── routeProfile.js
├── utils.coffee
├── utils.js
├── views
├── admin
│ ├── admingroup.hbs
│ ├── department.hbs
│ └── users.hbs
├── install.hbs
├── login.hbs
├── mobile
│ ├── layout.hbs
│ ├── login.hbs
│ ├── password.hbs
│ ├── show.hbs
│ ├── showsubordinate.hbs
│ └── write.hbs
├── password.hbs
├── show.hbs
├── showsubordinate.hbs
└── write.hbs
└── vo
├── Response.coffee
└── Response.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | node_modules/
3 | *.log
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 一天日报是一个开源的写日报工具,该工具简单易用,包含网页和手机版。使用该日报工具可以随时随地使用手机或者电脑写和浏览日报.
2 | site: http://waltershe.github.io/ribao/
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module dependencies.
3 | */
4 |
5 | var express = require('express')
6 | , http = require('http')
7 | , connect = require('connect')
8 | , routeProfile = require('./routes/routeProfile')
9 | , path = require('path')
10 | , redis = require("redis")
11 | , redisConfig = require('./config')
12 | , session = require('express-session')
13 | , redisStore = require('connect-redis')(session)
14 | , appport = redisConfig.app.port
15 | , sessiondbconfig = redisConfig.sessiondb;
16 |
17 | var app = express();
18 | var redisClient = redis.createClient(redisConfig.db.port,redisConfig.db.host);
19 | redisClient.on("error", function(err) {
20 | console.log(err);
21 | });
22 |
23 | // all environments
24 | app.set('port', appport || process.env.PORT || 3000);
25 | app.set('views', __dirname + '/views');
26 | app.set('view engine', 'hbs');
27 | app.use(require('morgan')('dev'));
28 | app.use(require('compression')());
29 | app.use(require('body-parser')());
30 | app.use(require('method-override')());
31 | app.use(require('cookie-parser')());
32 | app.use(session({ store: new redisStore({host:sessiondbconfig.host, port:sessiondbconfig.port, pass:sessiondbconfig.pass, db:sessiondbconfig.db, prefix:'sess', ttl:3600}), secret: 'iamwaltershe' }));
33 | //app.use(app.router);
34 | app.use(express.static(path.join(__dirname, 'public')));
35 |
36 | // development only
37 | if ('development' == app.get('env')) {
38 | app.use(require('errorhandler')());
39 | }
40 |
41 | routeProfile.createRoutes(app);
42 |
43 | http.createServer(app).listen(app.get('port'), function(){
44 | console.log('Express server listening on port ' + app.get('port'));
45 | });
46 |
--------------------------------------------------------------------------------
/config.coffee:
--------------------------------------------------------------------------------
1 |
2 | exports.db =
3 | host: "127.0.0.1"
4 | port: 6379
5 | db: 0 #Database index to use
6 | pass:null
7 |
8 | exports.sessiondb =
9 | host: "127.0.0.1"
10 | port: 6379
11 | db: 1 #Database index to use
12 | pass:null
13 |
14 | exports.app =
15 | port: 3000
16 |
17 |
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 |
4 | exports.db = {
5 | host: "127.0.0.1",
6 | port: 6379,
7 | db: 0,
8 | pass: null
9 | };
10 |
11 | exports.sessiondb = {
12 | host: "127.0.0.1",
13 | port: 6379,
14 | db: 1,
15 | pass: null
16 | };
17 |
18 | exports.app = {
19 | port: 3000
20 | };
21 |
22 | }).call(this);
23 |
--------------------------------------------------------------------------------
/controlers/adminCtr.coffee:
--------------------------------------------------------------------------------
1 | utils = require('../utils')
2 |
3 | exports.index = (req, res) ->
4 | return unless utils.authenticateAdmin(req,res)
5 | res.render("admin/department")
6 |
7 | exports.usersIndex = (req, res) ->
8 | return unless utils.authenticateAdmin(req,res)
9 | res.render("admin/users")
10 |
11 | exports.admingroupIndex = (req, res) ->
12 | return unless utils.authenticateAdmin(req,res)
13 | res.render("admin/admingroup")
14 |
15 |
--------------------------------------------------------------------------------
/controlers/adminCtr.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var utils;
4 |
5 | utils = require('../utils');
6 |
7 | exports.index = function(req, res) {
8 | if (!utils.authenticateAdmin(req, res)) {
9 | return;
10 | }
11 | return res.render("admin/department");
12 | };
13 |
14 | exports.usersIndex = function(req, res) {
15 | if (!utils.authenticateAdmin(req, res)) {
16 | return;
17 | }
18 | return res.render("admin/users");
19 | };
20 |
21 | exports.admingroupIndex = function(req, res) {
22 | if (!utils.authenticateAdmin(req, res)) {
23 | return;
24 | }
25 | return res.render("admin/admingroup");
26 | };
27 |
28 | }).call(this);
29 |
--------------------------------------------------------------------------------
/controlers/departmentCtr.coffee:
--------------------------------------------------------------------------------
1 | crypto = require('crypto');
2 | check = require('validator').check
3 | utils = require('../utils')
4 | departmentModel = require('../models/departmentsModel')
5 | {Response} = require('../vo/Response')
6 |
7 |
8 | #创建一个新部门
9 | exports.createDepartment = (req, res) ->
10 | return unless utils.authenticateAdmin(req,res)
11 |
12 | departmentName = req.body.departmentName
13 | parentId = req.body.pid
14 | try
15 | check(departmentName, "部门名称不能为空").notEmpty().notContains(":")
16 | departmentModel.createDepartment(departmentName, parentId, (response)->
17 | res.send(response))
18 | catch error
19 | errorMessage = error.message
20 | res.send(new Response(0, errorMessage))
21 |
22 | #删除部门
23 | exports.removeDepartment = (req, res) ->
24 | return unless utils.authenticateAdmin(req,res)
25 |
26 | departmentId = req.body.departmentId
27 | departmentModel.removeDepartment(departmentId, (response)->
28 | res.send(response))
29 |
30 | #更新部门
31 | exports.updateDepartment = (req, res) ->
32 | return unless utils.authenticateAdmin(req,res)
33 |
34 | departmentId = req.body.departmentId
35 | departmentName = req.body.departmentName
36 | parentId = req.body.pid
37 | try
38 | check(departmentName, "部门名称不能为空").notEmpty().notContains(":")
39 | departmentModel.updateDepartment(departmentId, departmentName, parentId, (response)->
40 | res.send(response))
41 | catch error
42 | errorMessage = error.message
43 | res.send(new Response(0,errorMessage))
44 |
45 | #获取所有部门
46 | exports.getAllDepartments = (req, res) ->
47 | departmentModel.getAllDepartments((response)->
48 | res.send(response))
49 |
--------------------------------------------------------------------------------
/controlers/departmentCtr.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var Response, check, crypto, departmentModel, utils;
3 |
4 | crypto = require('crypto');
5 |
6 | check = require('validator').check;
7 |
8 | utils = require('../utils');
9 |
10 | departmentModel = require('../models/departmentsModel');
11 |
12 | Response = require('../vo/Response').Response;
13 |
14 | exports.createDepartment = function(req, res) {
15 | var departmentName, error, errorMessage, parentId;
16 | if (!utils.authenticateAdmin(req, res)) {
17 | return;
18 | }
19 | departmentName = req.body.departmentName;
20 | parentId = req.body.pid;
21 | try {
22 | check(departmentName, "部门名称不能为空").notEmpty().notContains(":");
23 | return departmentModel.createDepartment(departmentName, parentId, function(response) {
24 | return res.send(response);
25 | });
26 | } catch (_error) {
27 | error = _error;
28 | errorMessage = error.message;
29 | return res.send(new Response(0, errorMessage));
30 | }
31 | };
32 |
33 | exports.removeDepartment = function(req, res) {
34 | var departmentId;
35 | if (!utils.authenticateAdmin(req, res)) {
36 | return;
37 | }
38 | departmentId = req.body.departmentId;
39 | return departmentModel.removeDepartment(departmentId, function(response) {
40 | return res.send(response);
41 | });
42 | };
43 |
44 | exports.updateDepartment = function(req, res) {
45 | var departmentId, departmentName, error, errorMessage, parentId;
46 | if (!utils.authenticateAdmin(req, res)) {
47 | return;
48 | }
49 | departmentId = req.body.departmentId;
50 | departmentName = req.body.departmentName;
51 | parentId = req.body.pid;
52 | try {
53 | check(departmentName, "部门名称不能为空").notEmpty().notContains(":");
54 | return departmentModel.updateDepartment(departmentId, departmentName, parentId, function(response) {
55 | return res.send(response);
56 | });
57 | } catch (_error) {
58 | error = _error;
59 | errorMessage = error.message;
60 | return res.send(new Response(0, errorMessage));
61 | }
62 | };
63 |
64 | exports.getAllDepartments = function(req, res) {
65 | return departmentModel.getAllDepartments(function(response) {
66 | return res.send(response);
67 | });
68 | };
69 |
70 | }).call(this);
71 |
--------------------------------------------------------------------------------
/controlers/installCtr.coffee:
--------------------------------------------------------------------------------
1 | crypto = require('crypto')
2 | userModel = require('../models/usersModel')
3 |
4 | exports.install = (req, res) ->
5 | userName = "admin"
6 | password = "1234567"
7 | hashedPassword = crypto.createHash("sha1").update(password).digest('hex')
8 | userModel.createDefaultAdmin(userName, hashedPassword, (response)->
9 | res.render("install"))
10 |
--------------------------------------------------------------------------------
/controlers/installCtr.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var crypto, userModel;
4 |
5 | crypto = require('crypto');
6 |
7 | userModel = require('../models/usersModel');
8 |
9 | exports.install = function(req, res) {
10 | var hashedPassword, password, userName;
11 | userName = "admin";
12 | password = "1234567";
13 | hashedPassword = crypto.createHash("sha1").update(password).digest('hex');
14 | return userModel.createDefaultAdmin(userName, hashedPassword, function(response) {
15 | return res.render("install");
16 | });
17 | };
18 |
19 | }).call(this);
20 |
--------------------------------------------------------------------------------
/controlers/reportCtr.coffee:
--------------------------------------------------------------------------------
1 | crypto = require('crypto');
2 | check = require('validator').check
3 | reportModel = require('../models/reportModel')
4 | userModel = require('../models/usersModel')
5 | utils = require('../utils')
6 | {Response} = require('../vo/Response')
7 |
8 | exports.index = (req, res) ->
9 | return unless utils.authenticateUser(req,res)
10 | res.redirect("/show")
11 |
12 | exports.writeIndex = (req, res) ->
13 | return unless utils.authenticateUser(req,res)
14 | showPage(req, res, "write")
15 |
16 | exports.settingMobile = (req, res) ->
17 | return unless utils.authenticateUser(req,res)
18 | res.render("mobile/settings", {'title':"设置", layout:"mobile/layout.hbs"})
19 |
20 | exports.writeIndexMobile = (req, res) ->
21 | return unless utils.authenticateUser(req,res)
22 | showPage(req, res, "mobile/write", {'title':"写日报", layout:"mobile/layout.hbs", "currentDateStr": getDateStr(new Date())})
23 |
24 | getDateStr = (date)->
25 | today = new Date()
26 | year = date.getFullYear()
27 | month = date.getMonth() + 1
28 | date = date.getDate()
29 | return "#{year}-#{month}-#{date}"
30 |
31 | exports.write = (req, res) ->
32 | return unless utils.authenticateUser(req,res)
33 | userId = req.session.userId
34 | dateStr = req.body.date
35 | content = req.body.content
36 |
37 | try
38 | check(dateStr).notEmpty()
39 | check(content).notEmpty()
40 | [year, months, date] = dateStr.split("-")
41 | #console.log "#{year}-#{months}-#{date}"
42 | check(year).notNull().isNumeric().len(4,4)
43 | check(months).notNull().isNumeric().len(1,2)
44 | check(date).notNull().isNumeric().len(1,2)
45 | reportModel.createReport(userId, content, dateStr, (response)->
46 | res.send(response))
47 | catch error
48 | res.send(new Response(0,"日期格式不正确或者内容为空"))
49 |
50 | exports.showIndex = (req, res) ->
51 | return unless utils.authenticateUser(req,res)
52 | showPage(req, res, "show")
53 |
54 | exports.showIndexMobile = (req, res) ->
55 | return unless utils.authenticateUser(req,res)
56 | showPage(req, res, "mobile/show", {'title':"我的日报", layout:"mobile/layout.hbs"})
57 |
58 | showPage = (req, res, pageTitle, data=null) ->
59 | userId = req.session.userId
60 | data = {} unless data
61 | data["hasSubordinate"] = false
62 | data["isLoginUser"] = utils.isLoginUser(req)
63 | data["isAdmin"] = utils.isAdmin(req)
64 | userModel.hasSubordinate(userId, (result)->
65 | if result
66 | data["hasSubordinate"] = true
67 | res.render(pageTitle, data))
68 |
69 | exports.showsubordinateIndex = (req, res) ->
70 | return unless utils.authenticateUser(req,res)
71 | userId = req.session.userId
72 | userModel.hasSubordinate(userId, (result)->
73 | if result
74 | res.render("showsubordinate", {hasSubordinate:true, isLoginUser:utils.isLoginUser(req),isAdmin:utils.isAdmin(req)})
75 | else
76 | res.send(new Response(0,'您还没有下属,不需要访问该页面')))
77 |
78 | exports.subordinateIndexMobile = (req, res) ->
79 | return unless utils.authenticateUser(req,res)
80 | userId = req.session.userId
81 | userModel.hasSubordinate(userId, (result)->
82 | if result
83 | res.render("mobile/showsubordinate", {title:"下属日报", layout:"mobile/layout.hbs", hasSubordinate:true, isLoginUser:utils.isLoginUser(req),isAdmin:utils.isAdmin(req)})
84 | else
85 | res.send(new Response(0,'您还没有下属,不需要访问该页面')))
86 |
87 |
88 | exports.getReports = (req, res) ->
89 | return unless utils.authenticateUser(req,res)
90 |
91 | #第几页
92 | page = req.body.page
93 | userId = req.body.userId
94 | #没有userId表示访问自己的日报
95 | userId = req.session.userId unless userId
96 |
97 | #每页显示条数
98 | numOfPage = req.body.numOfPage
99 | try
100 | check(page).isNumeric().min(1)
101 | check(page).isNumeric().min(1)
102 | reportModel.getReports(userId, page, numOfPage, (response)->
103 | res.send(response))
104 | catch error
105 | res.send(new Response(0,"页数和每页显示条数为非负数"))
106 |
107 | exports.getReportNum = (req, res) ->
108 | return unless utils.authenticateUser(req,res)
109 | userId = req.body.userId
110 | #没有userId表示访问自己的日报
111 | userId = req.session.userId unless userId
112 |
113 | reportModel.getReportNum(userId, (response)->
114 | res.send(response))
115 |
116 | exports.delete = (req, res) ->
117 | return unless utils.authenticateUser(req,res)
118 | userId = req.session.userId
119 | reportId = req.body.reportId
120 | reportModel.deleteReport(userId, reportId, (response)->
121 | res.send(response))
122 |
123 |
124 | exports.getSubordinateUserAndDepartment = (req, res) ->
125 | return unless utils.authenticateUser(req,res)
126 | userId = req.session.userId
127 | reportModel.getSubordinateUserAndDepartment(userId, (response)->
128 | res.send(response))
--------------------------------------------------------------------------------
/controlers/userCtr.coffee:
--------------------------------------------------------------------------------
1 | crypto = require('crypto')
2 | check = require('validator').check
3 | utils = require('../utils')
4 | userModel = require('../models/usersModel')
5 | {Response} = require('../vo/Response')
6 |
7 | exports.loginIndex = (req, res) ->
8 | res.render("login")
9 |
10 | exports.indexMobile = (req, res) ->
11 | if utils.isLoginUser(req)
12 | res.redirect('/m/write')
13 | else
14 | res.redirect('/m/login')
15 |
16 | exports.loginIndexMobile = (req, res) ->
17 | if utils.isLoginUser(req)
18 | res.redirect('/m/write')
19 | else
20 | res.render("mobile/login", {'title':"登录", layout:"mobile/layout.hbs"})
21 |
22 | exports.login = (req, res) ->
23 | userName = req.body.userName
24 | password = req.body.password
25 | hashedPassword = crypto.createHash("sha1").update(password).digest('hex')
26 | userModel.getAllUsersWithPassword((response)->
27 | return res.send(response) if response.state == 0
28 | users = response.data
29 | userId = null
30 | for key, value of users
31 | [id,property] = key.split(":")
32 |
33 | if (property == "user_name" and value == userName)
34 | userId = id
35 | break
36 |
37 | return res.send(new Response(1, "用户名:#{userName}不存在", 0)) unless userId
38 | #return res.render("login",{hasError:true, message:"用户名:#{userName}不存在"}) unless userId
39 |
40 | hasThisUser = false
41 | for key, value of users
42 | [id,property] = key.split(":")
43 | if (id == userId and property == "password" and value == hashedPassword)
44 | userId = id
45 | hasThisUser = true
46 | break
47 | #return res.render("login",{hasError:true, message:"密码错误"}) unless hasThisUser
48 | return res.send(new Response(1, "密码错误", 0)) unless hasThisUser
49 | #console.log "userName:#{userName}, userId:#{userId}"
50 | req.session.userId = userId
51 |
52 | userModel.getAdminIds((response)->
53 | return res.send(new Response(1, "success", 1)) if response.state == 0
54 | ids = response.data
55 |
56 | for id in ids
57 | if id == userId
58 | req.session.isAdmin = 1
59 | break
60 | res.send(new Response(1, "success", 1))))
61 | #return res.redirect("/show")))
62 |
63 | exports.logout = (req, res) ->
64 | return unless utils.authenticateUser(req,res)
65 | req.session.destroy()
66 | res.redirect("/login")
67 |
68 | exports.logoutMobileIndex = (req, res) ->
69 | return unless utils.authenticateUser(req,res)
70 | req.session.destroy()
71 | res.render("mobile/login", {'title':"登录", layout:"mobile/layout.hbs"})
72 |
73 | exports.passwordIndex = (req, res) ->
74 | return unless utils.authenticateUser(req,res)
75 | userId = req.session.userId
76 | userModel.hasSubordinate(userId, (result)->
77 | data = {hasSubordinate: result, isLoginUser:utils.isLoginUser(req), isAdmin:utils.isAdmin(req)}
78 | res.render("password", data))
79 |
80 | exports.passwordMobileIndex = (req, res) ->
81 | return unless utils.authenticateUser(req,res)
82 | userId = req.session.userId
83 | userModel.hasSubordinate(userId, (result)->
84 | data = {hasSubordinate: result,'title':"修改密码", layout:"mobile/layout.hbs"}
85 | console.log data
86 | res.render("mobile/password", data))
87 |
88 | exports.changePassword = (req, res) ->
89 | return unless utils.authenticateUser(req,res)
90 |
91 | userId = req.session.userId
92 | oldPassword = crypto.createHash("sha1").update(req.body.oldPassword).digest('hex')
93 | newPassword = crypto.createHash("sha1").update(req.body.newPassword).digest('hex')
94 |
95 | userModel.changePassword(userId, newPassword, oldPassword, (response)->
96 | res.send(response))
97 |
98 |
99 | exports.createUser = (req, res) ->
100 | return unless utils.authenticateAdmin(req,res)
101 |
102 | userName = req.body.userName
103 | password = req.body.password
104 | departmentId = req.body.departmentId;
105 | superiorId = req.body.superiorId;
106 |
107 | try
108 | check(userName, "字符长度为2-25").len(2,25)
109 | check(password, "字符长度为7-25").len(7,25)
110 | catch error
111 | errorMessage = error.message
112 | return res.send(new Response(0, errorMessage))
113 |
114 | userModel.hasUser(userName, (response)->
115 | return res.send(response) if response.state == 0 or response.data
116 | hashedPassword = crypto.createHash("sha1").update(password).digest('hex')
117 | userModel.createUser(userName, hashedPassword, departmentId, superiorId, (response)->
118 | res.send(response)))
119 |
120 | exports.removeUser = (req, res) ->
121 | return unless utils.authenticateAdmin(req,res)
122 | userId = req.body.userId
123 | userModel.removeUser(userId, (response)->
124 | res.send(response))
125 |
126 | exports.updateUser = (req, res) ->
127 | return unless utils.authenticateAdmin(req,res)
128 | userId = req.body.userId
129 | userName = req.body.userName
130 | password = req.body.password
131 | departmentId = req.body.departmentId;
132 | superiorId = req.body.superiorId;
133 |
134 | try
135 | check(userName, "字符长度为6-25").len(6,25)
136 | hashedPassword = null
137 | hashedPassword = crypto.createHash("sha1").update(password).digest('hex') if password
138 | userModel.updateUser(userId, userName, hashedPassword, departmentId, superiorId, (response)->
139 | res.send(response))
140 | catch error
141 | res.send(new Response(0,error.errorMessage))
142 |
143 | exports.getAllUsers = (req, res) ->
144 | userModel.getAllUsers((response)->
145 | res.send(response))
146 |
147 | exports.getAdmins = (req, res) ->
148 | return unless utils.authenticateAdmin(req,res)
149 | userModel.getAdminIds((response)->
150 | res.send(response))
151 |
152 | exports.setAdmin = (req, res) ->
153 | return unless utils.authenticateAdmin(req,res)
154 | userId = req.body.userId
155 | userModel.setAdmin(userId, (response)->
156 | res.send(response))
157 |
158 | exports.deleteAdmin = (req, res) ->
159 | return unless utils.authenticateAdmin(req,res)
160 | userId = req.body.userId
161 | userModel.deleteAdmin(userId, (response)->
162 | res.send(response))
163 |
164 | exports.hasUser = (req, res) ->
165 | userName = req.body.userName
166 | userModel.hasUser(userName, (response)->
167 | res.send(response))
168 |
--------------------------------------------------------------------------------
/models/departmentsModel.coffee:
--------------------------------------------------------------------------------
1 |
2 | {Response} = require('../vo/Response')
3 | utils = require("../utils")
4 |
5 | exports.createDepartment = (departmentName, parentId, callback) ->
6 | client = utils.createClient()
7 |
8 | client.incr("next_department_id", (err, reply)->
9 | return utils.showDBError(callback, client) if err
10 |
11 | client.hset("departments", "#{reply}:name", departmentName)
12 | result = {name:departmentName}
13 |
14 | #id 以字符串形式返回
15 | department = {name:departmentName, id:"#{reply}"}
16 | if parentId
17 | client.hset("departments", "#{reply}:pid", parentId)
18 | result["pid"] = parentId
19 | department["pid"] = parentId
20 |
21 | client.quit()
22 |
23 | callback(new Response(1,'success',department)))
24 |
25 | #删除部门
26 | exports.removeDepartment = (departmentId, callback) ->
27 | client = utils.createClient()
28 | client.hdel("departments", "#{departmentId}:name", "#{departmentId}:pid", (err, reply)->
29 | return utils.showDBError(callback, client) if err
30 | client.hgetall("departments", (err, reply)->
31 | return utils.showDBError(callback, client) if err
32 | newDepartments = {}
33 | for key, value of reply
34 | childOfKey = key.split(":")
35 | if childOfKey[1] == "pid" and value == departmentId
36 | client.hdel("departments", key)
37 | else
38 | newDepartments[key] = value
39 |
40 | client.hgetall("users", (err, users)->
41 | return utils.showDBError(callback, client) if err
42 | for key, value of users
43 | childOfKey = key.split(":")
44 | if childOfKey[1] == "department_id" and value == departmentId
45 | client.hdel("users", key)
46 | callback(new Response(1,'success',newDepartments)))))
47 |
48 | #更新部门
49 | exports.updateDepartment = (departmentId, departmentName, parentId, callback)->
50 | client = utils.createClient()
51 |
52 | replycallback = (err, reply)->
53 | return utils.showDBError(callback, client) if err
54 | client.hgetall("departments", (err, reply)->
55 | client.quit()
56 | callback(new Response(1,'success',reply)))
57 |
58 | if parentId
59 | client.hmset("departments", "#{departmentId}:name", departmentName, "#{departmentId}:pid", parentId, replycallback)
60 | else
61 | client.hset("departments", "#{departmentId}:name", departmentName, replycallback)
62 |
63 | exports.getAllDepartments = (callback) ->
64 | client = utils.createClient()
65 | client.hgetall("departments", (err, reply)->
66 | return utils.showDBError(callback, client) if err
67 | client.quit()
68 | callback(new Response(1,'success',reply)))
--------------------------------------------------------------------------------
/models/departmentsModel.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var Response, utils;
4 |
5 | Response = require('../vo/Response').Response;
6 |
7 | utils = require("../utils");
8 |
9 | exports.createDepartment = function(departmentName, parentId, callback) {
10 | var client;
11 | client = utils.createClient();
12 | return client.incr("next_department_id", function(err, reply) {
13 | var department, result;
14 | if (err) {
15 | return utils.showDBError(callback, client);
16 | }
17 | client.hset("departments", "" + reply + ":name", departmentName);
18 | result = {
19 | name: departmentName
20 | };
21 | department = {
22 | name: departmentName,
23 | id: "" + reply
24 | };
25 | if (parentId) {
26 | client.hset("departments", "" + reply + ":pid", parentId);
27 | result["pid"] = parentId;
28 | department["pid"] = parentId;
29 | }
30 | client.quit();
31 | return callback(new Response(1, 'success', department));
32 | });
33 | };
34 |
35 | exports.removeDepartment = function(departmentId, callback) {
36 | var client;
37 | client = utils.createClient();
38 | return client.hdel("departments", "" + departmentId + ":name", "" + departmentId + ":pid", function(err, reply) {
39 | if (err) {
40 | return utils.showDBError(callback, client);
41 | }
42 | return client.hgetall("departments", function(err, reply) {
43 | var childOfKey, key, newDepartments, value;
44 | if (err) {
45 | return utils.showDBError(callback, client);
46 | }
47 | newDepartments = {};
48 | for (key in reply) {
49 | value = reply[key];
50 | childOfKey = key.split(":");
51 | if (childOfKey[1] === "pid" && value === departmentId) {
52 | client.hdel("departments", key);
53 | } else {
54 | newDepartments[key] = value;
55 | }
56 | }
57 | return client.hgetall("users", function(err, users) {
58 | if (err) {
59 | return utils.showDBError(callback, client);
60 | }
61 | for (key in users) {
62 | value = users[key];
63 | childOfKey = key.split(":");
64 | if (childOfKey[1] === "department_id" && value === departmentId) {
65 | client.hdel("users", key);
66 | }
67 | }
68 | return callback(new Response(1, 'success', newDepartments));
69 | });
70 | });
71 | });
72 | };
73 |
74 | exports.updateDepartment = function(departmentId, departmentName, parentId, callback) {
75 | var client, replycallback;
76 | client = utils.createClient();
77 | replycallback = function(err, reply) {
78 | if (err) {
79 | return utils.showDBError(callback, client);
80 | }
81 | return client.hgetall("departments", function(err, reply) {
82 | client.quit();
83 | return callback(new Response(1, 'success', reply));
84 | });
85 | };
86 | if (parentId) {
87 | return client.hmset("departments", "" + departmentId + ":name", departmentName, "" + departmentId + ":pid", parentId, replycallback);
88 | } else {
89 | return client.hset("departments", "" + departmentId + ":name", departmentName, replycallback);
90 | }
91 | };
92 |
93 | exports.getAllDepartments = function(callback) {
94 | var client;
95 | client = utils.createClient();
96 | return client.hgetall("departments", function(err, reply) {
97 | if (err) {
98 | return utils.showDBError(callback, client);
99 | }
100 | client.quit();
101 | return callback(new Response(1, 'success', reply));
102 | });
103 | };
104 |
105 | }).call(this);
106 |
--------------------------------------------------------------------------------
/other&this/db-info.md:
--------------------------------------------------------------------------------
1 | 安装redis数据库,安装完成后执行如下命令添加管理员账户:
2 | redis 127.0.0.1:6379> incr next_user_id
3 | (integer) 1
4 | 执行完该命令后表明 next_user_id 的值为1,然后执行如下命令(1:user_name和1:password中的1即为上一步执行incr next_user_id后的
5 | next_user_id的值)
6 | redis 127.0.0.1:6379> hmset users 1:user_name adminn 1:password 20eabe5d64b0e216796e834f52d61f
7 | OK
8 | 执行下面的命令将管理员adminn的id添加到管理员集合中
9 | redis 127.0.0.1:6379> sadd administrators 1
10 | (integer) 1
11 |
12 | 执行完以上命令后我们新增加了一个管理员账户adminn,密码为1234567。
13 |
14 | 下载源代码并解压缩到你的网站根目录,使用命令行工具进入该目录,然后输入
15 | $ npm install
16 | 安装依赖的库文件(确保你有管理员权限可以安装库文件),安装完成后,打开根目录下的config.js文件设置数据库信息和网站端口号。
17 | exports.db对象是数据库配置,exports.sessiondb是seesion数据库的数据库配置,seesion信息都存在redis数据库中,exports.app 对象中的
18 | port属性表示网站端口号,默认是80端口。配置设置好后执行
19 | $ node app.js
20 | 看到输出'Express server listening on port '80' 则表示服务器启动成功(这里的端口号80会和你在config.js中的exports.app.port保持一致)
21 | 进入网站主页你会看到登陆界面,输入管理员账户名 adminn,密码1234567则可以登陆成功。 进入管理后台设置部门,然后建立新用户,把建立好的用户名和密码告知
22 | 用户,用户使用用户名和密码登陆系统就可以写日报和查看日报了。
23 |
24 | 数据库字段说明:
25 |
26 | 用户数据:
27 | next_user_id (类型 string) 用户id值,每生成一个新用户该值通过incr方法递增1
28 |
29 | users (类型 hash) 所有注册用户信息存储在此
30 | 每个user包含如下key:value
31 | hmset("users", "#{userId}:user_name", userName, "#{userId}:password", password, "#{userId}:department_id", departmentId, "#{userId}:superior_id", superiorId)
32 | superiorId 为该用户直接上级用户的Id,如果没有直接上级,那么该 key 不存在
33 |
34 | 部门数据:
35 | next_department_id (类型 string) 部门id 的值,每生成一个新部门该值通过incr方法递增1
36 |
37 | departments (类型 hash) 所有部门信息存储在此
38 | 每个department包含如下key:value
39 | hset("departments", "#{departmentId}:name", departmentName, "#{departmentId}:pid", pid)
40 | pid 为该部门直接上级部门,如果没有直接上级部门,那么该 key 不存在
41 |
42 | 日报数据:
43 | next_report_id (类型 string) 日报id 的值,每生成一个新日报该值通过incr方法递增1
44 |
45 | userid:#{userId}:reportIds (类型 sorted sets)
46 | score 为日期数值 2004-04-09 转换为 20040409
47 | member 为report id
48 |
49 | userid:#{userId}:reports (类型 hash)
50 | #{reportId}:date为日报日期 #{reportId}:content为日报内容
51 |
52 | 管理员:
53 | administrators (类型 set) 存储的是用户id,管理员用户的id都在该集合中
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "one-day-daily-report-software-tool",
3 | "version": "0.9.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node app.js"
7 | },
8 | "dependencies": {
9 | "express": "4.10.1",
10 | "connect": "3.3.2",
11 | "express-session": "1.9.1",
12 | "body-parser": "1.9.2",
13 | "method-override": "2.3.0",
14 | "cookie-parser": "1.3.3",
15 | "morgan": "1.4.1",
16 | "errorhandler": "1.2.2",
17 | "compression": "1.2.0",
18 | "hbs": "2.7.0",
19 | "redis": "0.12.1",
20 | "connect-redis": "2.1.0",
21 | "validator": "2.1.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/public/css/adminDepartment.css:
--------------------------------------------------------------------------------
1 | #department {
2 | width: 720px;
3 | }
4 | #department #newDepartment,
5 | #department #departmentTree {
6 | float: left;
7 | margin: 20px 20px 0 0;
8 | background-color: #fbeed5;
9 | border: 1px solid #E5E5E5;
10 | border-radius: 5px 5px 5px 5px;
11 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
12 | padding: 10px 16px;
13 | width: 300px;
14 | height: 350px;
15 | overflow: auto;
16 | color: #555;
17 | }
18 | #department #departmentTree {
19 | padding: 10px 16px 10px 0;
20 | }
21 | #department #newDepartment .submitBtn {
22 | margin-top: 20px;
23 | }
24 | #department #newDepartment.update {
25 | background-color: #FAA732;
26 | border: 1px solid #c58433;
27 | }
28 |
--------------------------------------------------------------------------------
/public/css/adminDepartment.less:
--------------------------------------------------------------------------------
1 |
2 | #department {
3 | width:720px;
4 | #newDepartment, #departmentTree {
5 | float:left;
6 | margin:20px 20px 0 0;
7 | background-color: #fbeed5;
8 | border: 1px solid #E5E5E5;
9 | border-radius: 5px 5px 5px 5px;
10 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
11 | padding: 10px 16px;
12 | width: 300px;
13 | height:350px;
14 | overflow: auto;
15 | color: #555;
16 | }
17 |
18 | #departmentTree {
19 | padding: 10px 16px 10px 0;
20 | }
21 |
22 | #newDepartment {
23 | .submitBtn {
24 | margin-top: 20px;
25 | }
26 |
27 | &.update {
28 | background-color: #FAA732;
29 | border: 1px solid #c58433;
30 | }
31 | }
32 | }
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/public/css/adminGroup.css:
--------------------------------------------------------------------------------
1 | body.admin-admingroup section.container {
2 | width: 720px;
3 | }
4 | body.admin-admingroup #newAdministrator,
5 | body.admin-admingroup #adminlist {
6 | float: left;
7 | margin: 20px 20px 0 0;
8 | background-color: #fbeed5;
9 | border: 1px solid #E5E5E5;
10 | border-radius: 5px 5px 5px 5px;
11 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
12 | padding: 10px 16px;
13 | width: 300px;
14 | height: 430px;
15 | overflow: auto;
16 | }
17 | body.admin-admingroup #adminlist a.delete {
18 | float: right;
19 | margin-right: 10px;
20 | }
21 | body.admin-admingroup #adminlist li {
22 | padding: 6px 0 10px 5px;
23 | }
24 | body.admin-admingroup #adminlist li.itemOver {
25 | background-color: #78b608;
26 | border-radius: 5px 5px 5px 5px;
27 | }
28 |
--------------------------------------------------------------------------------
/public/css/adminGroup.less:
--------------------------------------------------------------------------------
1 |
2 | body.admin-admingroup {
3 | section.container {
4 | width: 720px;
5 | }
6 | #newAdministrator, #adminlist {
7 | float:left;
8 | margin:20px 20px 0 0;
9 | background-color: #fbeed5;
10 | border: 1px solid #E5E5E5;
11 | border-radius: 5px 5px 5px 5px;
12 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
13 | padding: 10px 16px;
14 | width: 300px;
15 | height:430px;
16 | overflow: auto;
17 | }
18 |
19 | #adminlist {
20 | a.delete {
21 | float:right;
22 | margin-right: 10px;
23 | }
24 | li {
25 | padding: 6px 0 10px 5px;
26 |
27 | &.itemOver {
28 | background-color: #78b608;
29 | border-radius: 5px 5px 5px 5px;
30 | }
31 | }
32 | }
33 | }
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/public/css/adminStyle.css:
--------------------------------------------------------------------------------
1 | .treeList ul {
2 | list-style: none;
3 | }
4 | .treeList li div {
5 | padding: 6px 0 10px 5px;
6 | }
7 | .treeList li div.treeListItemOver {
8 | background-color: #78b608;
9 | border-radius: 5px 5px 5px 5px;
10 | color: white;
11 | }
12 | .treeList li div.treeListItemSelected {
13 | background-color: #FAA732;
14 | border-radius: 5px 5px 5px 5px;
15 | color: white;
16 | }
17 | .treeList li div i {
18 | padding: 1px;
19 | }
20 | .treeList li div i.icon-minus,
21 | .treeList li div i.icon-plus {
22 | width: 12px;
23 | height: 12px;
24 | border: 1px solid #444444;
25 | margin-right: 5px;
26 | cursor: pointer;
27 | }
28 | .treeList li div span.delete,
29 | .treeList li div span.update,
30 | .treeList li div span.review {
31 | margin-right: 8px;
32 | font-size: 12px;
33 | height: 16px;
34 | padding: 2px 8px 4px 8px;
35 | float: right;
36 | }
37 | header {
38 | background-color: #FAFAFA;
39 | background-image: -moz-linear-gradient(center top, #ffffff, #f2f2f2);
40 | background-repeat: repeat-x;
41 | border: 1px solid #D4D4D4;
42 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.067);
43 | min-height: 40px;
44 | width: 100%;
45 | }
46 | header.navbar a.brand {
47 | padding-left: 40px;
48 | }
49 | #department {
50 | width: 720px;
51 | }
52 | #department #newDepartment,
53 | #department #departmentTree {
54 | float: left;
55 | margin: 20px 20px 0 0;
56 | background-color: #fbeed5;
57 | border: 1px solid #E5E5E5;
58 | border-radius: 5px 5px 5px 5px;
59 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
60 | padding: 10px 16px;
61 | width: 300px;
62 | height: 350px;
63 | overflow: auto;
64 | color: #555;
65 | }
66 | #department #departmentTree {
67 | padding: 10px 16px 10px 0;
68 | }
69 | #department #newDepartment .submitBtn {
70 | margin-top: 20px;
71 | }
72 | #department #newDepartment.update {
73 | background-color: #FAA732;
74 | border: 1px solid #c58433;
75 | }
76 | body.admin-users #users {
77 | width: 720px;
78 | }
79 | body.admin-users #users #newUser,
80 | body.admin-users #users #updateUser,
81 | body.admin-users #users #usersTree {
82 | float: left;
83 | margin: 20px 20px 0 0;
84 | background-color: #fbeed5;
85 | border: 1px solid #E5E5E5;
86 | border-radius: 5px 5px 5px 5px;
87 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
88 | padding: 10px 16px;
89 | width: 300px;
90 | height: 430px;
91 | overflow: auto;
92 | }
93 | body.admin-users #users #usersTree {
94 | padding: 10px 16px 10px 0;
95 | }
96 | body.admin-users #users #updateUser {
97 | background-color: #FAA732;
98 | border: 1px solid #c58433;
99 | }
100 | body.admin-admingroup section.container {
101 | width: 720px;
102 | }
103 | body.admin-admingroup #newAdministrator,
104 | body.admin-admingroup #adminlist {
105 | float: left;
106 | margin: 20px 20px 0 0;
107 | background-color: #fbeed5;
108 | border: 1px solid #E5E5E5;
109 | border-radius: 5px 5px 5px 5px;
110 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
111 | padding: 10px 16px;
112 | width: 300px;
113 | height: 430px;
114 | overflow: auto;
115 | }
116 | body.admin-admingroup #adminlist a.delete {
117 | float: right;
118 | margin-right: 10px;
119 | }
120 | body.admin-admingroup #adminlist li {
121 | padding: 6px 0 10px 5px;
122 | }
123 | body.admin-admingroup #adminlist li.itemOver {
124 | background-color: #78b608;
125 | border-radius: 5px 5px 5px 5px;
126 | }
127 | .no-close .ui-dialog-titlebar-close {
128 | display: none;
129 | }
130 | * {
131 | color: #555;
132 | }
133 | .errorTip {
134 | color: red;
135 | padding-left: 5px;
136 | }
137 | div.title {
138 | margin: 0 0 10px 0;
139 | padding: 0;
140 | }
141 | div.title h2 {
142 | display: inline;
143 | font-size: 16px;
144 | padding-left: 5px;
145 | }
146 |
--------------------------------------------------------------------------------
/public/css/adminStyle.less:
--------------------------------------------------------------------------------
1 | @import-once "treeList";
2 | @import-once "header";
3 | @import-once "adminDepartment";
4 | @import-once "adminUser";
5 | @import-once "adminGroup";
6 |
7 | //hide dialog close button
8 | .no-close .ui-dialog-titlebar-close {
9 | display: none;
10 | }
11 |
12 | * {color: #555;}
13 |
14 | .errorTip {
15 | color: red;
16 | padding-left:5px;
17 | }
18 |
19 | div.title {
20 | margin:0 0 10px 0;
21 | padding:0;
22 |
23 | h2 {
24 | display: inline;
25 | font-size: 16px;
26 | padding-left: 5px;
27 | }
28 | }
--------------------------------------------------------------------------------
/public/css/adminUser.css:
--------------------------------------------------------------------------------
1 | body.admin-users #users {
2 | width: 720px;
3 | }
4 | body.admin-users #users #newUser,
5 | body.admin-users #users #updateUser,
6 | body.admin-users #users #usersTree {
7 | float: left;
8 | margin: 20px 20px 0 0;
9 | background-color: #fbeed5;
10 | border: 1px solid #E5E5E5;
11 | border-radius: 5px 5px 5px 5px;
12 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
13 | padding: 10px 16px;
14 | width: 300px;
15 | height: 430px;
16 | overflow: auto;
17 | }
18 | body.admin-users #users #usersTree {
19 | padding: 10px 16px 10px 0;
20 | }
21 | body.admin-users #users #updateUser {
22 | background-color: #FAA732;
23 | border: 1px solid #c58433;
24 | }
25 |
--------------------------------------------------------------------------------
/public/css/adminUser.less:
--------------------------------------------------------------------------------
1 |
2 | body.admin-users {
3 | #users {
4 | width: 720px;
5 | #newUser, #updateUser, #usersTree {
6 | float:left;
7 | margin:20px 20px 0 0;
8 | background-color: #fbeed5;
9 | border: 1px solid #E5E5E5;
10 | border-radius: 5px 5px 5px 5px;
11 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
12 | padding: 10px 16px;
13 | width: 300px;
14 | height:430px;
15 | overflow: auto;
16 | }
17 |
18 | #usersTree {
19 | padding: 10px 16px 10px 0;
20 | }
21 |
22 | #updateUser {
23 | background-color: #FAA732;
24 | border: 1px solid #c58433;
25 | }
26 | }
27 | }
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/public/css/header.css:
--------------------------------------------------------------------------------
1 | header {
2 | background-color: #FAFAFA;
3 | background-image: -moz-linear-gradient(center top, #ffffff, #f2f2f2);
4 | background-repeat: repeat-x;
5 | border: 1px solid #D4D4D4;
6 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.067);
7 | min-height: 40px;
8 | width: 100%;
9 | }
10 | header.navbar a.brand {
11 | padding-left: 40px;
12 | }
13 |
--------------------------------------------------------------------------------
/public/css/header.less:
--------------------------------------------------------------------------------
1 | header {
2 | background-color: #FAFAFA;
3 | background-image: -moz-linear-gradient(center top , #FFFFFF, #F2F2F2);
4 | background-repeat: repeat-x;
5 | border: 1px solid #D4D4D4;
6 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.067);
7 | min-height: 40px;
8 | width:100%;
9 |
10 | &.navbar a.brand {
11 | padding-left: 40px;
12 | }
13 | }
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/animated-overlay.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/animated-overlay.gif
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-bg_diagonal-maze_20_6e4f1c_10x10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-bg_diagonal-maze_20_6e4f1c_10x10.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-bg_diagonal-maze_40_000000_10x10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-bg_diagonal-maze_40_000000_10x10.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-bg_fine-grain_10_eceadf_60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-bg_fine-grain_10_eceadf_60x60.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-bg_fine-grain_10_f8f7f6_60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-bg_fine-grain_10_f8f7f6_60x60.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-bg_fine-grain_15_eceadf_60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-bg_fine-grain_15_eceadf_60x60.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-bg_fine-grain_15_f7f3de_60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-bg_fine-grain_15_f7f3de_60x60.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-bg_fine-grain_15_ffffff_60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-bg_fine-grain_15_ffffff_60x60.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-bg_fine-grain_65_654b24_60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-bg_fine-grain_65_654b24_60x60.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-bg_fine-grain_68_b83400_60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-bg_fine-grain_68_b83400_60x60.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-icons_3572ac_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-icons_3572ac_256x240.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-icons_8c291d_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-icons_8c291d_256x240.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-icons_b83400_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-icons_b83400_256x240.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-icons_fbdb93_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-icons_fbdb93_256x240.png
--------------------------------------------------------------------------------
/public/css/pepper-grinder/images/ui-icons_ffffff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/css/pepper-grinder/images/ui-icons_ffffff_256x240.png
--------------------------------------------------------------------------------
/public/css/reportStyle.css:
--------------------------------------------------------------------------------
1 | .treeList ul {
2 | list-style: none;
3 | }
4 | .treeList li div {
5 | padding: 6px 0 10px 5px;
6 | }
7 | .treeList li div.treeListItemOver {
8 | background-color: #78b608;
9 | border-radius: 5px 5px 5px 5px;
10 | color: white;
11 | }
12 | .treeList li div.treeListItemSelected {
13 | background-color: #FAA732;
14 | border-radius: 5px 5px 5px 5px;
15 | color: white;
16 | }
17 | .treeList li div i {
18 | padding: 1px;
19 | }
20 | .treeList li div i.icon-minus,
21 | .treeList li div i.icon-plus {
22 | width: 12px;
23 | height: 12px;
24 | border: 1px solid #444444;
25 | margin-right: 5px;
26 | cursor: pointer;
27 | }
28 | .treeList li div span.delete,
29 | .treeList li div span.update,
30 | .treeList li div span.review {
31 | margin-right: 8px;
32 | font-size: 12px;
33 | height: 16px;
34 | padding: 2px 8px 4px 8px;
35 | float: right;
36 | }
37 | header {
38 | background-color: #FAFAFA;
39 | background-image: -moz-linear-gradient(center top, #ffffff, #f2f2f2);
40 | background-repeat: repeat-x;
41 | border: 1px solid #D4D4D4;
42 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.067);
43 | min-height: 40px;
44 | width: 100%;
45 | }
46 | header.navbar a.brand {
47 | padding-left: 40px;
48 | }
49 | .no-close .ui-dialog-titlebar-close {
50 | display: none;
51 | }
52 | * {
53 | color: #555;
54 | }
55 | div.title h1 {
56 | display: inline;
57 | font-size: 18px;
58 | padding-left: 5px;
59 | margin: 0;
60 | }
61 | #reportCreation {
62 | background-color: #fbeed5;
63 | border: 1px solid #E5E5E5;
64 | border-radius: 5px 5px 5px 5px;
65 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
66 | padding: 0 20px 18px 20px;
67 | }
68 | #reportCreation textarea {
69 | width: 100%;
70 | }
71 | #reportCreation #dateTxt {
72 | margin-bottom: 20px;
73 | }
74 | #reportCreation #reportSubmitBtn {
75 | margin-top: 20px;
76 | }
77 | html,
78 | body {
79 | height: 100%;
80 | width: 100%;
81 | }
82 | body.subordinate .navbar {
83 | margin-bottom: 0;
84 | }
85 | body.subordinate #userList {
86 | float: left;
87 | margin-top: 0px;
88 | border-right: 1px solid #E5E5E5;
89 | padding: 10px 16px 10px 0;
90 | height: 91%;
91 | width: 310px;
92 | }
93 | body.subordinate #userList div.title {
94 | padding-left: 15px;
95 | }
96 | body.subordinate #userList #userTree {
97 | margin: 0 10px 0 0;
98 | padding: 0;
99 | width: 300px;
100 | }
101 | body.subordinate #reports {
102 | float: left;
103 | padding-left: 30px;
104 | width: 65%;
105 | }
106 | body.subordinate #reports li.report {
107 | border-bottom: 1px solid #E5E5E5;
108 | }
109 | #reportList li.report {
110 | border-bottom: 1px solid #E5E5E5;
111 | padding: 10px;
112 | margin-bottom: 15px;
113 | float: left;
114 | width: 100%;
115 | }
116 | #reportList li.report .date span {
117 | font-size: 18px;
118 | font-weight: bold;
119 | color: #1a700b;
120 | padding-left: 5px;
121 | }
122 | #reportList li.report .content {
123 | margin: 0;
124 | padding: 0;
125 | }
126 | #reportList li.report .reply,
127 | #reportList li.report .delete {
128 | float: right;
129 | padding: 0 20px 0 0;
130 | }
131 | #reportList div.pagination {
132 | float: right;
133 | margin: 5px 0;
134 | }
135 | #reportList div.pagination span {
136 | margin: 0 15px;
137 | font-size: 16px;
138 | }
139 | #reportList div.pagination button {
140 | margin-top: -8px;
141 | }
142 | #loginDiv {
143 | background-color: #fbeed5;
144 | border: 1px solid #E5E5E5;
145 | border-radius: 5px 5px 5px 5px;
146 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
147 | padding: 10px 16px;
148 | width: 230px;
149 | minheight: 230px;
150 | }
151 | #loginDiv #errorTip {
152 | color: red;
153 | margin: 0 0 20px 0;
154 | }
155 | body.passoword section {
156 | background-color: #fbeed5;
157 | border: 1px solid #E5E5E5;
158 | border-radius: 5px 5px 5px 5px;
159 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
160 | padding: 10px 16px;
161 | width: 230px;
162 | height: 280px;
163 | }
164 | body.passoword .errorTip {
165 | color: red;
166 | padding-left: 5px;
167 | }
168 | body.passoword #successTip {
169 | color: green;
170 | padding-top: 10px;
171 | display: none;
172 | }
173 | body.passoword #passwordErrorTip {
174 | color: red;
175 | padding-top: 10px;
176 | display: none;
177 | }
178 |
--------------------------------------------------------------------------------
/public/css/reportStyle.less:
--------------------------------------------------------------------------------
1 | @import-once "treeList";
2 | @import-once "header";
3 |
4 | //hide dialog close button
5 | .no-close .ui-dialog-titlebar-close {
6 | display: none;
7 | }
8 |
9 | * {color: #555;}
10 |
11 | div.title {
12 | h1 {
13 | display: inline;
14 | font-size: 18px;
15 | padding-left: 5px;
16 | margin:0;
17 | }
18 | }
19 |
20 | //创建日报页面
21 | #reportCreation {
22 | background-color: #fbeed5;
23 | border: 1px solid #E5E5E5;
24 | border-radius: 5px 5px 5px 5px;
25 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
26 | padding: 0 20px 18px 20px;
27 | textarea {
28 | width: 100%;
29 | }
30 |
31 | #dateTxt {
32 | margin-bottom:20px;
33 | }
34 |
35 |
36 | #reportSubmitBtn {
37 | margin-top: 20px;
38 | }
39 | }
40 |
41 | html, body {
42 | height:100%;
43 | width:100%;
44 | }
45 |
46 | //查看下属日报页面
47 | body.subordinate {
48 | .navbar {
49 | margin-bottom: 0;}
50 |
51 |
52 |
53 | #userList {
54 | float:left;
55 | margin-top: 0px;
56 | border-right: 1px solid #E5E5E5;
57 | padding: 10px 16px 10px 0;
58 | height:91%;
59 | width: 310px;
60 |
61 | div.title {
62 | padding-left:15px;
63 | }
64 |
65 | #userTree {
66 | margin:0 10px 0 0;
67 | padding:0;
68 | width: 300px;
69 | }
70 | }
71 |
72 | #reports {
73 | float:left;
74 | padding-left: 30px;
75 | //background-color: #f00;
76 | //min-width:400px;
77 |
78 |
79 | li.report {
80 | //background-color: #eeeeee;
81 | border-bottom: 1px solid #E5E5E5;
82 | }
83 | width:65%;
84 | }
85 |
86 |
87 | }
88 |
89 | //查看我的日报页面
90 | #reportList {
91 | li.report {
92 | //background-color: #eeeeee;
93 | border-bottom: 1px solid #E5E5E5;
94 | //border-radius: 5px 5px 5px 5px;
95 | padding: 10px;
96 | margin-bottom:15px;
97 | float:left;
98 | width:100%;
99 | .date span{
100 | font-size: 18px;
101 | font-weight: bold;
102 | color: #1a700b;
103 | padding-left:5px;
104 | }
105 |
106 | .content{
107 | margin:0;
108 | padding:0;
109 | }
110 |
111 | .reply, .delete {
112 | float: right;
113 | padding: 0 20px 0 0;
114 |
115 | }
116 | }
117 |
118 | div.pagination {
119 | float: right;
120 | margin: 5px 0;
121 |
122 | span {
123 | margin:0 15px;
124 | font-size:16px;
125 | }
126 |
127 | button {
128 | margin-top:-8px;
129 | }
130 | }
131 | }
132 |
133 | // 登陆页面
134 | #loginDiv {
135 | background-color: #fbeed5;
136 | border: 1px solid #E5E5E5;
137 | border-radius: 5px 5px 5px 5px;
138 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
139 | padding: 10px 16px;
140 | width: 230px;
141 | minheight:230px;
142 |
143 | #errorTip {
144 | color:red;
145 | margin:0 0 20px 0;
146 | }
147 | }
148 |
149 | //修改密码页面
150 | body.passoword {
151 | section {
152 | background-color: #fbeed5;
153 | border: 1px solid #E5E5E5;
154 | border-radius: 5px 5px 5px 5px;
155 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
156 | padding: 10px 16px;
157 | width: 230px;
158 | height:280px;
159 | }
160 |
161 | .errorTip {
162 | color: red;
163 | padding-left:5px;
164 | }
165 |
166 | #successTip {
167 | color:green;
168 | padding-top:10px;
169 | display:none;
170 | }
171 |
172 | #passwordErrorTip {
173 | color:red;
174 | padding-top:10px;
175 | display:none;
176 | }
177 | }
178 |
179 |
180 |
--------------------------------------------------------------------------------
/public/css/style.css:
--------------------------------------------------------------------------------
1 | .treeList ul {
2 | list-style: none;
3 | }
4 | .treeList li div {
5 | padding: 6px 0 10px 5px;
6 | }
7 | .treeList li div.treeListItemOver {
8 | background-color: #78b608;
9 | border-radius: 5px 5px 5px 5px;
10 | color: white;
11 | }
12 | .treeList li div.treeListItemSelected {
13 | background-color: #FAA732;
14 | border-radius: 5px 5px 5px 5px;
15 | color: white;
16 | }
17 | .treeList li div i {
18 | padding: 1px;
19 | }
20 | .treeList li div i.icon-minus,
21 | .treeList li div i.icon-plus {
22 | width: 12px;
23 | height: 12px;
24 | border: 1px solid #444444;
25 | margin-right: 5px;
26 | cursor: pointer;
27 | }
28 | .treeList li div span.delete,
29 | .treeList li div span.update,
30 | .treeList li div span.review {
31 | margin-right: 8px;
32 | font-size: 12px;
33 | height: 16px;
34 | padding: 2px 8px 4px 8px;
35 | float: right;
36 | }
37 | header {
38 | background-color: #FAFAFA;
39 | background-image: -moz-linear-gradient(center top, #ffffff, #f2f2f2);
40 | background-repeat: repeat-x;
41 | border: 1px solid #D4D4D4;
42 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.067);
43 | min-height: 40px;
44 | width: 100%;
45 | }
46 | header.navbar a.brand {
47 | padding-left: 40px;
48 | }
49 | /**
50 | header {
51 | background-color: #FAFAFA;
52 | background-image: -moz-linear-gradient(center top , #FFFFFF, #F2F2F2);
53 | background-repeat: repeat-x;
54 | border: 1px solid #D4D4D4;
55 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.067);
56 | min-height: 40px;
57 | width:100%;
58 | }
59 |
60 | #reportCreation {
61 | margin-top: 20px;
62 | background-color: #fbeed5;
63 | border: 1px solid #E5E5E5;
64 | border-radius: 5px 5px 5px 5px;
65 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
66 | padding: 18px;
67 | textarea {
68 | width: 98%;
69 | }
70 |
71 |
72 | #submitBtn {
73 | margin-right: 10%;
74 | clear: both;
75 | }
76 | }
77 |
78 | #reportList {
79 | margin-top:30px;
80 | li.report {
81 | background-color: #eeeeee;
82 | border: 1px solid #E5E5E5;
83 | border-radius: 5px 5px 5px 5px;
84 | padding: 5px;
85 | margin-top:10px;
86 | width: 100%;
87 | float:left;
88 |
89 | .date {
90 | font-size: 18px;
91 | font-weight: bold;
92 | }
93 |
94 | .reply, .delete {
95 | float: right;
96 | padding: 0 20px 0 0;
97 |
98 | }
99 | }
100 |
101 | div.pagination {
102 | float: left;
103 | }
104 | }
105 |
106 | #department {
107 | width:720px;
108 | #newDepartment,#departmentTree {
109 | float:left;
110 | margin:20px 20px 0 0;
111 | background-color: #fbeed5;
112 | border: 1px solid #E5E5E5;
113 | border-radius: 5px 5px 5px 5px;
114 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
115 | padding: 10px 16px;
116 | width: 300px;
117 | height:350px;
118 | overflow: auto;
119 | color: #555;
120 | }
121 |
122 | #newDepartment {
123 | .submitBtn {
124 | margin-top: 20px;
125 | }
126 |
127 | &.update {
128 | background-color: #FAA732;
129 | border: 1px solid #c58433;
130 | }
131 | }
132 |
133 | #departmentTree {
134 | li div {
135 | &.on {
136 | background-color: #78b608;
137 | //border: 1px solid #165fe5;
138 | border-radius: 5px 5px 5px 5px;
139 | color:white;
140 | }
141 |
142 | &.selected {
143 | background-color: #FAA732;
144 | border-radius: 5px 5px 5px 5px;
145 | color:white;
146 | }
147 |
148 |
149 | padding: 6px 0 10px 5px;
150 |
151 | i{
152 | padding:1px;
153 | //background-color: #f00;
154 | &.icon-minus, &.icon-plus {
155 | width:12px;
156 | height:12px;
157 | border: 1px solid #444444;
158 | margin-right: 5px;
159 | cursor: pointer;
160 | }
161 | }
162 |
163 | span.delete, span.update {
164 | margin-right:8px;
165 | font-size: 12px;
166 | height:16px;
167 | padding: 2px 8px 4px 8px;
168 | float:right;
169 | }
170 | }
171 | }
172 | }
173 |
174 | .errorTip {
175 | color: red;
176 | padding-left:5px;
177 | }
178 |
179 | div.title {
180 | margin:0 0 10px 0;
181 | padding:0;
182 |
183 | h2 {
184 | display: inline;
185 | font-size: 16px;
186 | padding-left: 5px;
187 | }
188 | }
189 |
190 | body.login {
191 | #loginDiv {
192 | margin-top: 20px;
193 | background-color: #fbeed5;
194 | border: 1px solid #E5E5E5;
195 | border-radius: 5px 5px 5px 5px;
196 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
197 | padding: 18px;
198 | width: 220px;
199 |
200 | .submitBtn {
201 | margin-top: 20px;
202 | }
203 | }
204 | }
205 |
206 | body.admin-users {
207 | #users {
208 | width: 720px;
209 | #newUser, #usersTree {
210 | float:left;
211 | margin:20px 20px 0 0;
212 | background-color: #fbeed5;
213 | border: 1px solid #E5E5E5;
214 | border-radius: 5px 5px 5px 5px;
215 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
216 | padding: 10px 16px;
217 | width: 300px;
218 | height:430px;
219 | overflow: auto;
220 | color: #555;
221 | }
222 | }
223 | }
224 |
225 | */
226 |
--------------------------------------------------------------------------------
/public/css/style.less:
--------------------------------------------------------------------------------
1 | @import-once "treeList";
2 | @import-once "header";
3 |
4 | /**
5 | header {
6 | background-color: #FAFAFA;
7 | background-image: -moz-linear-gradient(center top , #FFFFFF, #F2F2F2);
8 | background-repeat: repeat-x;
9 | border: 1px solid #D4D4D4;
10 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.067);
11 | min-height: 40px;
12 | width:100%;
13 | }
14 |
15 | #reportCreation {
16 | margin-top: 20px;
17 | background-color: #fbeed5;
18 | border: 1px solid #E5E5E5;
19 | border-radius: 5px 5px 5px 5px;
20 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
21 | padding: 18px;
22 | textarea {
23 | width: 98%;
24 | }
25 |
26 |
27 | #submitBtn {
28 | margin-right: 10%;
29 | clear: both;
30 | }
31 | }
32 |
33 | #reportList {
34 | margin-top:30px;
35 | li.report {
36 | background-color: #eeeeee;
37 | border: 1px solid #E5E5E5;
38 | border-radius: 5px 5px 5px 5px;
39 | padding: 5px;
40 | margin-top:10px;
41 | width: 100%;
42 | float:left;
43 |
44 | .date {
45 | font-size: 18px;
46 | font-weight: bold;
47 | }
48 |
49 | .reply, .delete {
50 | float: right;
51 | padding: 0 20px 0 0;
52 |
53 | }
54 | }
55 |
56 | div.pagination {
57 | float: left;
58 | }
59 | }
60 |
61 | #department {
62 | width:720px;
63 | #newDepartment,#departmentTree {
64 | float:left;
65 | margin:20px 20px 0 0;
66 | background-color: #fbeed5;
67 | border: 1px solid #E5E5E5;
68 | border-radius: 5px 5px 5px 5px;
69 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
70 | padding: 10px 16px;
71 | width: 300px;
72 | height:350px;
73 | overflow: auto;
74 | color: #555;
75 | }
76 |
77 | #newDepartment {
78 | .submitBtn {
79 | margin-top: 20px;
80 | }
81 |
82 | &.update {
83 | background-color: #FAA732;
84 | border: 1px solid #c58433;
85 | }
86 | }
87 |
88 | #departmentTree {
89 | li div {
90 | &.on {
91 | background-color: #78b608;
92 | //border: 1px solid #165fe5;
93 | border-radius: 5px 5px 5px 5px;
94 | color:white;
95 | }
96 |
97 | &.selected {
98 | background-color: #FAA732;
99 | border-radius: 5px 5px 5px 5px;
100 | color:white;
101 | }
102 |
103 |
104 | padding: 6px 0 10px 5px;
105 |
106 | i{
107 | padding:1px;
108 | //background-color: #f00;
109 | &.icon-minus, &.icon-plus {
110 | width:12px;
111 | height:12px;
112 | border: 1px solid #444444;
113 | margin-right: 5px;
114 | cursor: pointer;
115 | }
116 | }
117 |
118 | span.delete, span.update {
119 | margin-right:8px;
120 | font-size: 12px;
121 | height:16px;
122 | padding: 2px 8px 4px 8px;
123 | float:right;
124 | }
125 | }
126 | }
127 | }
128 |
129 | .errorTip {
130 | color: red;
131 | padding-left:5px;
132 | }
133 |
134 | div.title {
135 | margin:0 0 10px 0;
136 | padding:0;
137 |
138 | h2 {
139 | display: inline;
140 | font-size: 16px;
141 | padding-left: 5px;
142 | }
143 | }
144 |
145 | body.login {
146 | #loginDiv {
147 | margin-top: 20px;
148 | background-color: #fbeed5;
149 | border: 1px solid #E5E5E5;
150 | border-radius: 5px 5px 5px 5px;
151 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
152 | padding: 18px;
153 | width: 220px;
154 |
155 | .submitBtn {
156 | margin-top: 20px;
157 | }
158 | }
159 | }
160 |
161 | body.admin-users {
162 | #users {
163 | width: 720px;
164 | #newUser, #usersTree {
165 | float:left;
166 | margin:20px 20px 0 0;
167 | background-color: #fbeed5;
168 | border: 1px solid #E5E5E5;
169 | border-radius: 5px 5px 5px 5px;
170 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
171 | padding: 10px 16px;
172 | width: 300px;
173 | height:430px;
174 | overflow: auto;
175 | color: #555;
176 | }
177 | }
178 | }
179 |
180 | */
181 |
182 |
--------------------------------------------------------------------------------
/public/css/treeList.css:
--------------------------------------------------------------------------------
1 | .treeList ul {
2 | list-style: none;
3 | }
4 | .treeList li div {
5 | padding: 6px 0 10px 5px;
6 | }
7 | .treeList li div.treeListItemOver {
8 | background-color: #78b608;
9 | border-radius: 5px 5px 5px 5px;
10 | color: white;
11 | }
12 | .treeList li div.treeListItemSelected {
13 | background-color: #FAA732;
14 | border-radius: 5px 5px 5px 5px;
15 | color: white;
16 | }
17 | .treeList li div i {
18 | padding: 1px;
19 | }
20 | .treeList li div i.icon-minus,
21 | .treeList li div i.icon-plus {
22 | width: 12px;
23 | height: 12px;
24 | border: 1px solid #444444;
25 | margin-right: 5px;
26 | cursor: pointer;
27 | }
28 | .treeList li div span.delete,
29 | .treeList li div span.update,
30 | .treeList li div span.review {
31 | margin-right: 8px;
32 | font-size: 12px;
33 | height: 16px;
34 | padding: 2px 8px 4px 8px;
35 | float: right;
36 | }
37 |
--------------------------------------------------------------------------------
/public/css/treeList.less:
--------------------------------------------------------------------------------
1 |
2 | .treeList {
3 | ul {list-style: none;}
4 |
5 | li div {
6 | &.treeListItemOver {
7 | background-color: #78b608;
8 | //border: 1px solid #165fe5;
9 | border-radius: 5px 5px 5px 5px;
10 | color:white;
11 | }
12 |
13 | &.treeListItemSelected {
14 | background-color: #FAA732;
15 | border-radius: 5px 5px 5px 5px;
16 | color:white;
17 | }
18 |
19 | padding: 6px 0 10px 5px;
20 |
21 | i{
22 | padding:1px;
23 | &.icon-minus, &.icon-plus {
24 | width:12px;
25 | height:12px;
26 | border: 1px solid #444444;
27 | margin-right: 5px;
28 | cursor: pointer;
29 | }
30 | }
31 |
32 | span.delete, span.update, span.review {
33 | margin-right:8px;
34 | font-size: 12px;
35 | height:16px;
36 | padding: 2px 8px 4px 8px;
37 | float:right;
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/public/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/public/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/public/js/ReportModel.coffee:
--------------------------------------------------------------------------------
1 | # report model层,处理数据调用和解析 ---------------------------------------------------------------
2 | class ReportModel
3 |
4 | @createReport: (data, callback)->
5 | $.post("/write", data, (response)->
6 | callback(response)
7 | , "json")
8 |
9 | @deleteReport: (data, callback)->
10 | $.post("/delete", data, (response)->
11 | callback(response)
12 | , "json")
13 |
14 | @getReportNum: (userId, callback)->
15 | $.post("/getreportnum", {userId:userId}, (response)->
16 | callback(response)
17 | , "json")
18 |
19 | @getSubordinateUserAndDepartment: (callback)->
20 | $.post("/getsubordinateuseranddepartment",(response)->
21 | callback(response)
22 | , "json")
23 |
24 | #返回数据格式为[ { date: '2013-4-30',cotent: '
4.30 reports' },{ date: '2013-4-30',content: '4.30 reports' }]
25 | @getReports: (data, callback)->
26 | $.post("/getreports", data, (response)->
27 | callback(response)
28 | , "json")
29 |
30 | window.ReportModel = ReportModel
--------------------------------------------------------------------------------
/public/js/ReportModel.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var ReportModel;
4 |
5 | ReportModel = (function() {
6 |
7 | function ReportModel() {}
8 |
9 | ReportModel.createReport = function(data, callback) {
10 | return $.post("/write", data, function(response) {
11 | return callback(response);
12 | }, "json");
13 | };
14 |
15 | ReportModel.deleteReport = function(data, callback) {
16 | return $.post("/delete", data, function(response) {
17 | return callback(response);
18 | }, "json");
19 | };
20 |
21 | ReportModel.getReportNum = function(userId, callback) {
22 | return $.post("/getreportnum", {
23 | userId: userId
24 | }, function(response) {
25 | return callback(response);
26 | }, "json");
27 | };
28 |
29 | ReportModel.getSubordinateUserAndDepartment = function(callback) {
30 | return $.post("/getsubordinateuseranddepartment", function(response) {
31 | return callback(response);
32 | }, "json");
33 | };
34 |
35 | ReportModel.getReports = function(data, callback) {
36 | return $.post("/getreports", data, function(response) {
37 | return callback(response);
38 | }, "json");
39 | };
40 |
41 | return ReportModel;
42 |
43 | })();
44 |
45 | window.ReportModel = ReportModel;
46 |
47 | }).call(this);
48 |
--------------------------------------------------------------------------------
/public/js/TreeList.coffee:
--------------------------------------------------------------------------------
1 |
2 | #树形列表基类 ----------------------------------------------------------------------------------
3 | class TreeListBase
4 |
5 | constructor: (@containerNode, @dataSource=null)->
6 | @editingItem = null
7 |
8 | $(@containerNode).addClass("treeList")
9 |
10 | $(@containerNode).on("mouseenter", "li div", (event)->
11 | $(@).addClass('treeListItemOver') unless $(this) == @editingItem)
12 |
13 | $(@containerNode).on("mouseleave", "li div", (event)->
14 | $(@).removeClass('treeListItemOver') unless $(this) == @editingItem)
15 |
16 | @treeNodes = {}
17 |
18 | self = @
19 | $(@containerNode).on("click", "li i.icon-circle-arrow-right", (event)->
20 | event.stopImmediatePropagation()
21 | $(@).addClass('icon-circle-arrow-down').removeClass('icon-circle-arrow-right')
22 | name = $(@).parent().parent().attr("id")
23 | $("##{name}").append(self.treeNodes[name])
24 | delete self.treeNodes[name]
25 |
26 | if self.editingItem
27 | $("#{self.containerNode} span.update, #{self.containerNode} span.delete").hide()
28 | else
29 | $("#{self.containerNode} span.update, #{self.containerNode} span.delete").show())
30 |
31 | $(@containerNode).on("click", "li i.icon-circle-arrow-down", (event)->
32 | event.stopImmediatePropagation()
33 | $(@).addClass('icon-circle-arrow-right').removeClass('icon-circle-arrow-down')
34 | name = $(@).parent().parent().attr("id")
35 | self.treeNodes[name] = $(@).parent().next().detach())
36 |
37 | show: (@dataSource)->
38 | $(@containerNode).empty()
39 | @renderTree(@containerNode, @getDepartTreeData())
40 |
41 | #收缩的菜单项依旧收缩
42 | for name, _ of @treeNodes
43 | ul = $("##{name}").find("ul:first")
44 | ul.prev().find("i:first").addClass('icon-plus-sign').removeClass('icon-minus-sign')
45 | @treeNodes[name] = ul.detach()
46 |
47 | showEditingItem: ->
48 | return unless @editingItem
49 | @editingItem.parent().removeClass('treeListItemSelected')
50 | $("#{@containerNode} span.update, #{@containerNode} span.delete").show()
51 | @editingItem = null
52 |
53 | getEditingItemId: ->
54 | return null unless @editingItem
55 | @editingItem.parent().attr('id')
56 |
57 | # render a tree
58 | renderTree: (node, data)->
59 | throw new Error("renderTree method must implement in child class.")
60 |
61 | # render a department tree
62 | getDepartTreeData: ->
63 | departs = @dataSource
64 | treeData = []
65 | for value in departs
66 | rootnode = {label:value.name, id:value.id};
67 | treeData.push(rootnode) unless value.pid
68 |
69 | findChidren = (node, departs)->
70 | for value in departs
71 | if value.pid == node.id
72 | node.children = [] unless node.children
73 | childNode = {label:value.name, id:value.id}
74 | node.children.push(childNode)
75 | findChidren(childNode, departs)
76 |
77 | for node in treeData
78 | findChidren(node, departs)
79 |
80 | treeData
81 |
82 | #树形列表 ----------------------------------------------------------------------------------
83 | class TreeList extends TreeListBase
84 | constructor: (@containerNode, @dataSource=null)->
85 | super(@containerNode, @dataSource=null)
86 |
87 | @iconName = "book"
88 |
89 | $(@containerNode).on("click", "span.update", (event)=>
90 | t = $(event.target)
91 | t.parent().removeClass('treeListItemOver').addClass('treeListItemSelected')
92 | $("#{@containerNode} span.update, #{@containerNode} span.delete").hide()
93 | if @editingItem
94 | @editingItem.parent().removeClass('treeListItemSelected')
95 | @editingItem = t
96 | updateEvent = jQuery.Event("update")
97 | updateEvent["itemId"] = t.parent().attr('id')
98 | $(@containerNode).trigger(updateEvent))
99 |
100 | $(@containerNode).on("click", "span.delete", (event)=>
101 | t = $(event.target)
102 | deleteEvent = jQuery.Event("delete")
103 | deleteEvent["itemId"] = t.parent().attr('id')
104 | $(@containerNode).trigger(deleteEvent))
105 |
106 | show: (@dataSource, @iconName)->
107 | console.log @iconName
108 | super(@dataSource)
109 |
110 |
111 | # render a tree
112 | renderTree: (node, data)->
113 | $(node).append("")
114 | newnode = "#{node} ul:first"
115 | for value in data
116 | linode = "#{value.label}删除编辑
"
117 | if value.children
118 | linode = "#{value.label}删除编辑
"
119 |
120 | $(newnode).append(linode)
121 | newnode2 = "#{newnode} ##{value.id}node"
122 | if value.children
123 | @renderTree(newnode2, value.children)
124 | null
125 |
126 | window.TreeList = TreeList
127 |
128 | #树形列表2 ----------------------------------------------------------------------------------
129 | class TreeList2 extends TreeListBase
130 | constructor: (@containerNode, @dataSource=null)->
131 | super(@containerNode, @dataSource=null)
132 |
133 | $(@containerNode).on("click", "span.review", (event)=>
134 | t = $(event.target)
135 | t.parent().removeClass('treeListItemOver').addClass('treeListItemSelected')
136 | if @editingItem
137 | @editingItem.parent().removeClass('treeListItemSelected')
138 | @editingItem.show()
139 | @editingItem = t
140 | updateEvent = jQuery.Event("review")
141 | updateEvent["itemId"] = t.parent().attr('id')
142 | $(@containerNode).trigger(updateEvent))
143 |
144 | # render a tree
145 | renderTree: (node, data)->
146 | $(node).append("")
147 | newnode = "#{node} ul:first"
148 | for value in data
149 | value.node ?= 0
150 | linode = "#{value.label}查看
"
151 | if value.node == 1
152 | linode = "#{value.label}
"
153 |
154 | $(newnode).append(linode)
155 | newnode2 = "#{newnode} ##{value.id}node#{value.node}"
156 | if value.children
157 | @renderTree(newnode2, value.children)
158 | null
159 |
160 | window.TreeList2 = TreeList2
--------------------------------------------------------------------------------
/public/js/admin/DepartmentUserMode.coffee:
--------------------------------------------------------------------------------
1 |
2 | # department model层,处理数据调用和解析 ---------------------------------------------------------------
3 | class DepartmemtModel
4 |
5 | @getAllDepartments: (callback)->
6 | $.get("/admin/alldepartments",
7 | (response)->
8 | if response.state == 1
9 | departments = DepartmemtModel.parseDepartments(response.data)
10 | response['data'] = departments
11 | callback(response)
12 | , "json")
13 | # data 后台返回数据 Object { 1:name="PHP", 2:name="IOS", 3:name="p2", 3:pid="1"}
14 | # 输出数据 Object { 1:{id:1, name:"PHP"}, 2:{id:2, name:"ios"},3:{id:3, name:"p2", pid:"1"}}
15 | @parseDepartments: (data)->
16 | resultObj = {}
17 | for key, value of data
18 | childOfKey = key.split(":")
19 | departmentId = childOfKey[0]
20 | resultObj[departmentId] ?= {id: departmentId}
21 | if childOfKey[1] == "name"
22 | resultObj[departmentId]["name"] = value
23 | else if childOfKey[1] == "pid"
24 | resultObj[departmentId]["pid"] = value
25 |
26 | result = []
27 | for key2, value2 of resultObj
28 | result.push(value2)
29 |
30 | # h该函数输出数据 [{id:1, name:"PHP"}, {id:2, name:"ios"},{id:3, name:"p2", pid:"1"}]
31 | result
32 |
33 | @createNewDepartment: (data, callback)->
34 | $.post("/admin/createDepartment", data,
35 | (response)->
36 | callback(response)
37 | , "json")
38 |
39 | @updateDepartment: (data, callback)->
40 | $.post("/admin/updatedepartment", data,
41 | (response)->
42 | if response.state == 1
43 | departments = DepartmemtModel.parseDepartments(response.data)
44 | response['data'] = departments
45 | callback(response)
46 | , "json")
47 |
48 | @removeDepartment: (data, callback)->
49 | $.post("/admin/removedepartment", data,(response)->
50 | if response.state == 1
51 | departments = DepartmemtModel.parseDepartments(response.data)
52 | response.data = departments
53 | callback(response)
54 | , "json")
55 |
56 | window.DepartmemtModel = DepartmemtModel
57 |
58 | # user model层,处理数据调用和解析 ---------------------------------------------------------------
59 | class UserModel
60 |
61 | @setAdministrator: (userId, callback)->
62 | $.post("/admin/setadmin", {userId:userId}, (response)->
63 | callback(response)
64 | , "json")
65 |
66 | @deleteAdministrator: (userId, callback)->
67 | $.post("/admin/deleteadmin", {userId:userId}, (response)->
68 | callback(response)
69 | , "json")
70 |
71 | @getAdmins: (callback)->
72 | $.post("/admin/getadmins", (response)->
73 | callback(response)
74 | , "json")
75 |
76 | @hasUser: (userName, callback)->
77 | $.post("/admin/hasuser", {userName:userName}, (response)->
78 | callback(response)
79 | , "json")
80 |
81 | @login: (data, callback)->
82 | $.post("/login", data, (response)->
83 | callback(response)
84 | , "json")
85 |
86 | @createUser: (data, callback)->
87 | $.post("/admin/createuser", data, (response)->
88 | if response.state == 1
89 | user = response.data
90 | user["name"] = user["userName"]
91 | delete user["userName"]
92 | if user["superiorId"]
93 | user["pid"] = user["superiorId"]
94 | delete user["superiorId"]
95 | response.data = user
96 | UserModel.allUsers.push(user)
97 | callback(response)
98 | , "json")
99 |
100 | @updateUser: (data, callback)->
101 | $.post("/admin/updateuser", data, (response)->
102 | if response.state == 1
103 | users = UserModel.parseUsers(response.data)
104 | response.data = users
105 | UserModel.allUsers = users
106 | callback(response)
107 | ,"json")
108 |
109 | @changePassword: (data, callback)->
110 | $.post("/password", data, (response)->
111 | if response.state == 1
112 | callback(response)
113 | ,"json")
114 |
115 | @removeUser: (data, callback)->
116 | $.post("/admin/removeuser", data, (response)->
117 | if response.state == 1
118 | users = UserModel.parseUsers(response.data)
119 | response.data = users
120 | UserModel.allUsers = users
121 | callback(response)
122 | ,"json")
123 |
124 | @getAllUsers: (callback)->
125 | $.get("/admin/getallusers",(response)->
126 | if response.state == 1
127 | users = UserModel.parseUsers(response.data)
128 | response.data = users
129 | UserModel.allUsers = users
130 | callback(response)
131 | , "json")
132 |
133 | @allUsers: []
134 |
135 | @getLocalAllUsers: ->
136 | @allUsers
137 |
138 | # data 后台返回数据 Object { 1:user_name="walter", 1:department_id="7", 1:superior_id:"3"}
139 | @parseUsers: (data)->
140 |
141 | resultObj = {} #Object { 1:{id:1, name:"walter",pid:"3", departmentId:"7"}}
142 | for key, value of data
143 | childOfKey = key.split(":")
144 | userId = childOfKey[0]
145 | resultObj[userId] ?= {id: userId}
146 | if childOfKey[1] == "user_name"
147 | resultObj[userId]["name"] = value
148 | else if childOfKey[1] == "department_id"
149 | resultObj[userId]["departmentId"] = value
150 | else if childOfKey[1] == "superior_id"
151 | resultObj[userId]["pid"] = value
152 |
153 | result = []
154 | for key2, value2 of resultObj
155 | result.push(value2)
156 |
157 | # h该函数输出数据 [{id:1, name:"walter",pid:"3", departmentId:"7"}]
158 | result
159 |
160 | window.UserModel = UserModel
--------------------------------------------------------------------------------
/public/js/admin/admingroup.coffee:
--------------------------------------------------------------------------------
1 |
2 | # -----------------------------------------------------------------------------------------------
3 | AdminGroupViewModel = ->
4 | self = @
5 |
6 | self.departments = ko.observableArray([])
7 | self.selectedDepartment = ko.observable(null)
8 |
9 | self.users = ko.observableArray([])
10 | self.selectedUser = ko.observable(null)
11 |
12 | self.admins = ko.observableArray([])
13 |
14 | self.valid = ko.computed(->
15 | self.selectedDepartment() and self.selectedUser())
16 |
17 | self.submit = ->
18 | console.log "fail: 必须选择一个成员" unless self.valid()
19 | user = self.selectedUser()
20 | UserModel.setAdministrator(user["id"], (response)->
21 | return if response.state == 0
22 | self.admins.push(user))
23 |
24 | self
25 |
26 |
27 | # 初始化 ----------------------------------------------------------------------------
28 | init = ->
29 | adminvm = new AdminGroupViewModel()
30 | ko.applyBindings(adminvm)
31 |
32 | DepartmemtModel.getAllDepartments((response)->
33 | adminvm.departments(response.data))
34 |
35 | UserModel.getAllUsers((response)->
36 | return if response.state == 0
37 |
38 | users = response.data
39 | UserModel.getAdmins((response)->
40 | return if response.state == 0
41 | adminIds = response.data
42 | admins = getAdmins(users, adminIds)
43 | adminvm.admins(admins))
44 | null)
45 |
46 | getAdmins = (allUsers, adminIds)->
47 | result = []
48 | for adminId in adminIds
49 | for user in allUsers
50 | if adminId == user["id"]
51 | result.push(user)
52 | break
53 | result
54 |
55 | $("#depar").change( ->
56 | departmentId = adminvm.selectedDepartment()?['id']
57 | users = UserModel.getLocalAllUsers()
58 | departmentUsers = getUsersByDepartmentId(departmentId, users)
59 | adminvm.users(departmentUsers)
60 | admins = adminvm.admins()
61 | #从部门成员中移除管理员
62 | for admin in admins
63 | for user in users
64 | if user["id"] == admin["id"]
65 | adminvm.users.remove(user)
66 | break
67 | )
68 |
69 | #根据部门Id获取该部门所有成员
70 | getUsersByDepartmentId = (departmentId, allUsers)->
71 | result = []
72 | return result unless departmentId
73 |
74 | for user in allUsers
75 | result.push(user) if departmentId == user["departmentId"]
76 | result
77 |
78 | $("#adminlist").on("click", "a.delete", (event)->
79 | userId = $(@).attr("userid")
80 | confirm(userId))
81 |
82 | deleteAdmin = (userId)->
83 | UserModel.deleteAdministrator(userId, (response)->
84 | return if response.state == 0
85 | admins = adminvm.admins()
86 | for admin in admins
87 | return adminvm.admins.remove(admin) if admin["id"] == userId)
88 |
89 | confirm = (userId)->
90 | $("#dialog-confirm").dialog({
91 | dialogClass: "no-close",
92 | resizable: false,
93 | height:160,
94 | modal: true,
95 | buttons: {
96 | "删除": ->
97 | deleteAdmin(userId)
98 | $(@).dialog("close")
99 | Cancel: ->
100 | $(this).dialog("close")}})
101 |
102 | $("#adminlist").on("mouseenter", "li", (event)->
103 | $(@).addClass('itemOver'))
104 |
105 | $("#adminlist").on("mouseleave", "li", (event)->
106 | $(@).removeClass('itemOver'))
107 |
108 | init()
--------------------------------------------------------------------------------
/public/js/admin/admingroup.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var AdminGroupViewModel, init;
4 |
5 | AdminGroupViewModel = function() {
6 | var self;
7 | self = this;
8 | self.departments = ko.observableArray([]);
9 | self.selectedDepartment = ko.observable(null);
10 | self.users = ko.observableArray([]);
11 | self.selectedUser = ko.observable(null);
12 | self.admins = ko.observableArray([]);
13 | self.valid = ko.computed(function() {
14 | return self.selectedDepartment() && self.selectedUser();
15 | });
16 | self.submit = function() {
17 | var user;
18 | if (!self.valid()) {
19 | console.log("fail: 必须选择一个成员");
20 | }
21 | user = self.selectedUser();
22 | return UserModel.setAdministrator(user["id"], function(response) {
23 | if (response.state === 0) {
24 | return;
25 | }
26 | return self.admins.push(user);
27 | });
28 | };
29 | return self;
30 | };
31 |
32 | init = function() {
33 | var adminvm, confirm, deleteAdmin, getAdmins, getUsersByDepartmentId;
34 | adminvm = new AdminGroupViewModel();
35 | ko.applyBindings(adminvm);
36 | DepartmemtModel.getAllDepartments(function(response) {
37 | return adminvm.departments(response.data);
38 | });
39 | UserModel.getAllUsers(function(response) {
40 | var users;
41 | if (response.state === 0) {
42 | return;
43 | }
44 | users = response.data;
45 | UserModel.getAdmins(function(response) {
46 | var adminIds, admins;
47 | if (response.state === 0) {
48 | return;
49 | }
50 | adminIds = response.data;
51 | admins = getAdmins(users, adminIds);
52 | return adminvm.admins(admins);
53 | });
54 | return null;
55 | });
56 | getAdmins = function(allUsers, adminIds) {
57 | var adminId, result, user, _i, _j, _len, _len1;
58 | result = [];
59 | for (_i = 0, _len = adminIds.length; _i < _len; _i++) {
60 | adminId = adminIds[_i];
61 | for (_j = 0, _len1 = allUsers.length; _j < _len1; _j++) {
62 | user = allUsers[_j];
63 | if (adminId === user["id"]) {
64 | result.push(user);
65 | break;
66 | }
67 | }
68 | }
69 | return result;
70 | };
71 | $("#depar").change(function() {
72 | var admin, admins, departmentId, departmentUsers, user, users, _i, _len, _ref, _results;
73 | departmentId = (_ref = adminvm.selectedDepartment()) != null ? _ref['id'] : void 0;
74 | users = UserModel.getLocalAllUsers();
75 | departmentUsers = getUsersByDepartmentId(departmentId, users);
76 | adminvm.users(departmentUsers);
77 | admins = adminvm.admins();
78 | _results = [];
79 | for (_i = 0, _len = admins.length; _i < _len; _i++) {
80 | admin = admins[_i];
81 | _results.push((function() {
82 | var _j, _len1, _results1;
83 | _results1 = [];
84 | for (_j = 0, _len1 = users.length; _j < _len1; _j++) {
85 | user = users[_j];
86 | if (user["id"] === admin["id"]) {
87 | adminvm.users.remove(user);
88 | break;
89 | } else {
90 | _results1.push(void 0);
91 | }
92 | }
93 | return _results1;
94 | })());
95 | }
96 | return _results;
97 | });
98 | getUsersByDepartmentId = function(departmentId, allUsers) {
99 | var result, user, _i, _len;
100 | result = [];
101 | if (!departmentId) {
102 | return result;
103 | }
104 | for (_i = 0, _len = allUsers.length; _i < _len; _i++) {
105 | user = allUsers[_i];
106 | if (departmentId === user["departmentId"]) {
107 | result.push(user);
108 | }
109 | }
110 | return result;
111 | };
112 | $("#adminlist").on("click", "a.delete", function(event) {
113 | var userId;
114 | userId = $(this).attr("userid");
115 | return confirm(userId);
116 | });
117 | deleteAdmin = function(userId) {
118 | return UserModel.deleteAdministrator(userId, function(response) {
119 | var admin, admins, _i, _len;
120 | if (response.state === 0) {
121 | return;
122 | }
123 | admins = adminvm.admins();
124 | for (_i = 0, _len = admins.length; _i < _len; _i++) {
125 | admin = admins[_i];
126 | if (admin["id"] === userId) {
127 | return adminvm.admins.remove(admin);
128 | }
129 | }
130 | });
131 | };
132 | confirm = function(userId) {
133 | return $("#dialog-confirm").dialog({
134 | dialogClass: "no-close",
135 | resizable: false,
136 | height: 160,
137 | modal: true,
138 | buttons: {
139 | "删除": function() {
140 | deleteAdmin(userId);
141 | return $(this).dialog("close");
142 | },
143 | Cancel: function() {
144 | return $(this).dialog("close");
145 | }
146 | }
147 | });
148 | };
149 | $("#adminlist").on("mouseenter", "li", function(event) {
150 | return $(this).addClass('itemOver');
151 | });
152 | return $("#adminlist").on("mouseleave", "li", function(event) {
153 | return $(this).removeClass('itemOver');
154 | });
155 | };
156 |
157 | init();
158 |
159 | }).call(this);
160 |
--------------------------------------------------------------------------------
/public/js/admin/department.coffee:
--------------------------------------------------------------------------------
1 | treeList = new TreeList("#departmentTree")
2 |
3 | #ViewModel---------------------------------------------------------------
4 | DepartmentViewModel = ->
5 | self = @
6 | self.departmentName = ko.observable('')
7 | self.updateDepartmentName = ko.observable('')
8 | self.validDepartmentName = ko.computed(->
9 | dname = $.trim(self.departmentName())
10 | dname.length >= 1)
11 |
12 | self.selectedParentDepartment = ko.observable(null)
13 |
14 | self.validDepartmentRelation = ko.computed(->
15 | dname = $.trim(self.departmentName())
16 | self.selectedParentDepartment()?["name"] != dname)
17 |
18 | self.validUpdateDepartmentRelation = ko.computed(->
19 | dname = $.trim(self.updateDepartmentName())
20 | self.selectedParentDepartment()?["name"] != dname)
21 |
22 | self.validUpdateDepartmentName = ko.computed(->
23 | dname = $.trim(self.updateDepartmentName())
24 | dname.length >= 1)
25 |
26 | self.updateDepartment = ko.observable(null)
27 |
28 | #self.departments = ko.observableArray([{name:'无', id:null},{name:'PHP', id:1},{name:'Tec Center', id:2, pid:1},{name:'ios',id:3,pid:1},{name:'Product', id:4}])
29 | self.departments = ko.observableArray(null);
30 |
31 |
32 | self.submit = ->
33 | if self.validDepartmentName()
34 | data = {departmentName: $.trim(self.departmentName()), pid: self.selectedParentDepartment()?["id"]}
35 | DepartmemtModel.createNewDepartment(data, (response)->
36 | return if response.state == 0
37 | self.departments.push(response.data)
38 | treeList.show(self.departments(), "book") )
39 |
40 | self
41 |
42 |
43 | # 初始化 ----------------------------------------------------------------------------
44 | init = ->
45 | departmentvm = new DepartmentViewModel()
46 | ko.applyBindings(departmentvm)
47 |
48 | $("#departmentTree").on("update", (event)->
49 | departmentId = event["itemId"]
50 | department = findDepartment(departmentId)
51 | departmentvm.updateDepartment(department)
52 | departmentvm.updateDepartmentName(department['name'])
53 | departmentvm.selectedParentDepartment(findParentDepartment(department)))
54 |
55 | findDepartment = (departmentId)->
56 | departments = departmentvm.departments()
57 | for department in departments
58 | if (department['id'] == departmentId)
59 | return department
60 |
61 | findParentDepartment = (department)->
62 | pid = department["pid"]
63 | if pid
64 | departments = departmentvm.departments()
65 | for department in departments
66 | if (department['id'] == pid)
67 | return department
68 | return null
69 |
70 | $("#cancelUpdateBtn").click( ->
71 | cancelUpdateDepartment())
72 |
73 | cancelUpdateDepartment = ->
74 | treeList.showEditingItem()
75 | departmentvm.updateDepartment(null)
76 |
77 | $("#updateBtn").click( ->
78 | departmentId = treeList.getEditingItemId()
79 | data = {departmentId:departmentId, departmentName:departmentvm.updateDepartmentName(), pid: departmentvm.selectedParentDepartment()?["id"]}
80 | DepartmemtModel.updateDepartment(data,(response)->
81 | return if response.state == 0
82 | cancelUpdateDepartment()
83 | departmentvm.departments(response["data"])
84 | treeList.show(response["data"], "book")))
85 |
86 |
87 | $("#departmentTree").on("delete", (event)->
88 | departmentId = event["itemId"]
89 | confirm(departmentId))
90 |
91 | deleteDepartment = (departmentId)->
92 | DepartmemtModel.removeDepartment({departmentId:departmentId}, (response)->
93 | return if response.state == 0
94 | departmentvm.departments(response.data)
95 | treeList.show(response["data"], "book"))
96 |
97 | confirm = (departmentId)->
98 | $("#dialog-confirm").dialog({
99 | dialogClass: "no-close",
100 | resizable: false,
101 | height:160,
102 | modal: true,
103 | buttons: {
104 | "删除": ->
105 | deleteDepartment(departmentId)
106 | $(@).dialog("close")
107 | Cancel: ->
108 | $(this).dialog("close")}})
109 |
110 | DepartmemtModel.getAllDepartments((response)->
111 | return if response.state == 0
112 | departmentvm.departments(response.data)
113 | treeList.show(response["data"], "book"))
114 |
115 | init()
--------------------------------------------------------------------------------
/public/js/admin/department.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var DepartmentViewModel, init, treeList;
4 |
5 | treeList = new TreeList("#departmentTree");
6 |
7 | DepartmentViewModel = function() {
8 | var self;
9 | self = this;
10 | self.departmentName = ko.observable('');
11 | self.updateDepartmentName = ko.observable('');
12 | self.validDepartmentName = ko.computed(function() {
13 | var dname;
14 | dname = $.trim(self.departmentName());
15 | return dname.length >= 1;
16 | });
17 | self.selectedParentDepartment = ko.observable(null);
18 | self.validDepartmentRelation = ko.computed(function() {
19 | var dname, _ref;
20 | dname = $.trim(self.departmentName());
21 | return ((_ref = self.selectedParentDepartment()) != null ? _ref["name"] : void 0) !== dname;
22 | });
23 | self.validUpdateDepartmentRelation = ko.computed(function() {
24 | var dname, _ref;
25 | dname = $.trim(self.updateDepartmentName());
26 | return ((_ref = self.selectedParentDepartment()) != null ? _ref["name"] : void 0) !== dname;
27 | });
28 | self.validUpdateDepartmentName = ko.computed(function() {
29 | var dname;
30 | dname = $.trim(self.updateDepartmentName());
31 | return dname.length >= 1;
32 | });
33 | self.updateDepartment = ko.observable(null);
34 | self.departments = ko.observableArray(null);
35 | self.submit = function() {
36 | var data, _ref;
37 | if (self.validDepartmentName()) {
38 | data = {
39 | departmentName: $.trim(self.departmentName()),
40 | pid: (_ref = self.selectedParentDepartment()) != null ? _ref["id"] : void 0
41 | };
42 | return DepartmemtModel.createNewDepartment(data, function(response) {
43 | if (response.state === 0) {
44 | return;
45 | }
46 | self.departments.push(response.data);
47 | return treeList.show(self.departments(), "book");
48 | });
49 | }
50 | };
51 | return self;
52 | };
53 |
54 | init = function() {
55 | var cancelUpdateDepartment, confirm, deleteDepartment, departmentvm, findDepartment, findParentDepartment;
56 | departmentvm = new DepartmentViewModel();
57 | ko.applyBindings(departmentvm);
58 | $("#departmentTree").on("update", function(event) {
59 | var department, departmentId;
60 | departmentId = event["itemId"];
61 | department = findDepartment(departmentId);
62 | departmentvm.updateDepartment(department);
63 | departmentvm.updateDepartmentName(department['name']);
64 | return departmentvm.selectedParentDepartment(findParentDepartment(department));
65 | });
66 | findDepartment = function(departmentId) {
67 | var department, departments, _i, _len;
68 | departments = departmentvm.departments();
69 | for (_i = 0, _len = departments.length; _i < _len; _i++) {
70 | department = departments[_i];
71 | if (department['id'] === departmentId) {
72 | return department;
73 | }
74 | }
75 | };
76 | findParentDepartment = function(department) {
77 | var departments, pid, _i, _len;
78 | pid = department["pid"];
79 | if (pid) {
80 | departments = departmentvm.departments();
81 | for (_i = 0, _len = departments.length; _i < _len; _i++) {
82 | department = departments[_i];
83 | if (department['id'] === pid) {
84 | return department;
85 | }
86 | }
87 | }
88 | return null;
89 | };
90 | $("#cancelUpdateBtn").click(function() {
91 | return cancelUpdateDepartment();
92 | });
93 | cancelUpdateDepartment = function() {
94 | treeList.showEditingItem();
95 | return departmentvm.updateDepartment(null);
96 | };
97 | $("#updateBtn").click(function() {
98 | var data, departmentId, _ref;
99 | departmentId = treeList.getEditingItemId();
100 | data = {
101 | departmentId: departmentId,
102 | departmentName: departmentvm.updateDepartmentName(),
103 | pid: (_ref = departmentvm.selectedParentDepartment()) != null ? _ref["id"] : void 0
104 | };
105 | return DepartmemtModel.updateDepartment(data, function(response) {
106 | if (response.state === 0) {
107 | return;
108 | }
109 | cancelUpdateDepartment();
110 | departmentvm.departments(response["data"]);
111 | return treeList.show(response["data"], "book");
112 | });
113 | });
114 | $("#departmentTree").on("delete", function(event) {
115 | var departmentId;
116 | departmentId = event["itemId"];
117 | return confirm(departmentId);
118 | });
119 | deleteDepartment = function(departmentId) {
120 | return DepartmemtModel.removeDepartment({
121 | departmentId: departmentId
122 | }, function(response) {
123 | if (response.state === 0) {
124 | return;
125 | }
126 | departmentvm.departments(response.data);
127 | return treeList.show(response["data"], "book");
128 | });
129 | };
130 | confirm = function(departmentId) {
131 | return $("#dialog-confirm").dialog({
132 | dialogClass: "no-close",
133 | resizable: false,
134 | height: 160,
135 | modal: true,
136 | buttons: {
137 | "删除": function() {
138 | deleteDepartment(departmentId);
139 | return $(this).dialog("close");
140 | },
141 | Cancel: function() {
142 | return $(this).dialog("close");
143 | }
144 | }
145 | });
146 | };
147 | return DepartmemtModel.getAllDepartments(function(response) {
148 | if (response.state === 0) {
149 | return;
150 | }
151 | departmentvm.departments(response.data);
152 | return treeList.show(response["data"], "book");
153 | });
154 | };
155 |
156 | init();
157 |
158 | }).call(this);
159 |
--------------------------------------------------------------------------------
/public/js/cs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license cs 0.4.3 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
3 | * Available via the MIT or new BSD license.
4 | * see: http://github.com/jrburke/require-cs for details
5 | */
6 |
7 | /*jslint */
8 | /*global define, window, XMLHttpRequest, importScripts, Packages, java,
9 | ActiveXObject, process, require */
10 |
11 | define(['coffee-script'], function (CoffeeScript) {
12 | 'use strict';
13 | var fs, getXhr,
14 | progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
15 | fetchText = function () {
16 | throw new Error('Environment unsupported.');
17 | },
18 | buildMap = {};
19 |
20 | if (typeof process !== "undefined" &&
21 | process.versions &&
22 | !!process.versions.node) {
23 | //Using special require.nodeRequire, something added by r.js.
24 | fs = require.nodeRequire('fs');
25 | fetchText = function (path, callback) {
26 | callback(fs.readFileSync(path, 'utf8'));
27 | };
28 | } else if ((typeof window !== "undefined" && window.navigator && window.document) || typeof importScripts !== "undefined") {
29 | // Browser action
30 | getXhr = function () {
31 | //Would love to dump the ActiveX crap in here. Need IE 6 to die first.
32 | var xhr, i, progId;
33 | if (typeof XMLHttpRequest !== "undefined") {
34 | return new XMLHttpRequest();
35 | } else {
36 | for (i = 0; i < 3; i += 1) {
37 | progId = progIds[i];
38 | try {
39 | xhr = new ActiveXObject(progId);
40 | } catch (e) {}
41 |
42 | if (xhr) {
43 | progIds = [progId]; // so faster next time
44 | break;
45 | }
46 | }
47 | }
48 |
49 | if (!xhr) {
50 | throw new Error("getXhr(): XMLHttpRequest not available");
51 | }
52 |
53 | return xhr;
54 | };
55 |
56 | fetchText = function (url, callback) {
57 | var xhr = getXhr();
58 | xhr.open('GET', url, true);
59 | xhr.onreadystatechange = function (evt) {
60 | //Do not explicitly handle errors, those should be
61 | //visible via console output in the browser.
62 | if (xhr.readyState === 4) {
63 | callback(xhr.responseText);
64 | }
65 | };
66 | xhr.send(null);
67 | };
68 | // end browser.js adapters
69 | } else if (typeof Packages !== 'undefined') {
70 | //Why Java, why is this so awkward?
71 | fetchText = function (path, callback) {
72 | var stringBuffer, line,
73 | encoding = "utf-8",
74 | file = new java.io.File(path),
75 | lineSeparator = java.lang.System.getProperty("line.separator"),
76 | input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
77 | content = '';
78 | try {
79 | stringBuffer = new java.lang.StringBuffer();
80 | line = input.readLine();
81 |
82 | // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
83 | // http://www.unicode.org/faq/utf_bom.html
84 |
85 | // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
86 | // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
87 | if (line && line.length() && line.charAt(0) === 0xfeff) {
88 | // Eat the BOM, since we've already found the encoding on this file,
89 | // and we plan to concatenating this buffer with others; the BOM should
90 | // only appear at the top of a file.
91 | line = line.substring(1);
92 | }
93 |
94 | stringBuffer.append(line);
95 |
96 | while ((line = input.readLine()) !== null) {
97 | stringBuffer.append(lineSeparator);
98 | stringBuffer.append(line);
99 | }
100 | //Make sure we return a JavaScript string and not a Java string.
101 | content = String(stringBuffer.toString()); //String
102 | } finally {
103 | input.close();
104 | }
105 | callback(content);
106 | };
107 | }
108 |
109 | return {
110 | fetchText: fetchText,
111 |
112 | get: function () {
113 | return CoffeeScript;
114 | },
115 |
116 | write: function (pluginName, name, write) {
117 | if (buildMap.hasOwnProperty(name)) {
118 | var text = buildMap[name];
119 | write.asModule(pluginName + "!" + name, text);
120 | }
121 | },
122 |
123 | version: '0.4.3',
124 |
125 | load: function (name, parentRequire, load, config) {
126 | var path = parentRequire.toUrl(name + '.coffee');
127 | fetchText(path, function (text) {
128 |
129 | //Do CoffeeScript transform.
130 | try {
131 | text = CoffeeScript.compile(text, config.CoffeeScript);
132 | } catch (err) {
133 | err.message = "In " + path + ", " + err.message;
134 | throw err;
135 | }
136 |
137 | //Hold on to the transformed text if a build.
138 | if (config.isBuild) {
139 | buildMap[name] = text;
140 | }
141 |
142 | //IE with conditional comments on cannot handle the
143 | //sourceURL trick, so skip it if enabled.
144 | /*@if (@_jscript) @else @*/
145 | if (!config.isBuild) {
146 | text += "\r\n//@ sourceURL=" + path;
147 | }
148 | /*@end@*/
149 |
150 | load.fromText(name, text);
151 |
152 | //Give result to load. Need to wait until the module
153 | //is fully parse, which will happen after this
154 | //execution.
155 | parentRequire([name], function (value) {
156 | load(value);
157 | });
158 | });
159 | }
160 | };
161 | });
162 |
--------------------------------------------------------------------------------
/public/js/login.coffee:
--------------------------------------------------------------------------------
1 | LoginViewModel = ->
2 | self = @
3 | self.userName = ko.observable('')
4 | self.password = ko.observable('')
5 |
6 | self.validUserName = ko.computed(->
7 | un = $.trim(self.userName())
8 | un.length >= 2 and un.length<=25)
9 |
10 | self.validPassword = ko.computed(->
11 | pw = $.trim(self.password())
12 | pw.length >= 7 and pw.length<=25)
13 |
14 | self.errorTip = ko.observable('')
15 |
16 | self.getErrorTip = ->
17 | unless self.validUserName()
18 | return self.errorTip("用户名长度为2-25个字符")
19 |
20 | unless self.validPassword()
21 | return self.errorTip("密码长度为7-25个字符")
22 |
23 | self.errorTip("")
24 |
25 | self.showErrorTip = ko.observable(false)
26 |
27 | self.valid = ko.computed(->
28 | self.validUserName() and self.validPassword())
29 |
30 | self.submit = ->
31 | self.showErrorTip(true)
32 |
33 | if self.valid()
34 | data = {userName: $.trim(self.userName()), password:$.trim(self.password())}
35 | UserModel.login(data, (response)->
36 | return if response.state == 0
37 | if response.data == 0
38 | return self.errorTip(response.message)
39 | if response.data == 1
40 | location.href = "/write")
41 | else
42 | unless self.validUserName()
43 | return result = "用户名长度为2-25个字符"
44 |
45 | unless self.validPassword()
46 | return result = "密码长度为7-25个字符"
47 |
48 | self
49 |
50 | ko.applyBindings(new LoginViewModel())
51 |
--------------------------------------------------------------------------------
/public/js/login.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var LoginViewModel;
4 |
5 | LoginViewModel = function() {
6 | var self;
7 | self = this;
8 | self.userName = ko.observable('');
9 | self.password = ko.observable('');
10 | self.validUserName = ko.computed(function() {
11 | var un;
12 | un = $.trim(self.userName());
13 | return un.length >= 2 && un.length <= 25;
14 | });
15 | self.validPassword = ko.computed(function() {
16 | var pw;
17 | pw = $.trim(self.password());
18 | return pw.length >= 7 && pw.length <= 25;
19 | });
20 | self.errorTip = ko.observable('');
21 | self.getErrorTip = function() {
22 | if (!self.validUserName()) {
23 | return self.errorTip("用户名长度为2-25个字符");
24 | }
25 | if (!self.validPassword()) {
26 | return self.errorTip("密码长度为7-25个字符");
27 | }
28 | return self.errorTip("");
29 | };
30 | self.showErrorTip = ko.observable(false);
31 | self.valid = ko.computed(function() {
32 | return self.validUserName() && self.validPassword();
33 | });
34 | self.submit = function() {
35 | var data, result;
36 | self.showErrorTip(true);
37 | if (self.valid()) {
38 | data = {
39 | userName: $.trim(self.userName()),
40 | password: $.trim(self.password())
41 | };
42 | return UserModel.login(data, function(response) {
43 | if (response.state === 0) {
44 | return;
45 | }
46 | if (response.data === 0) {
47 | return self.errorTip(response.message);
48 | }
49 | if (response.data === 1) {
50 | return location.href = "/write";
51 | }
52 | });
53 | } else {
54 | if (!self.validUserName()) {
55 | return result = "用户名长度为2-25个字符";
56 | }
57 | if (!self.validPassword()) {
58 | return result = "密码长度为7-25个字符";
59 | }
60 | }
61 | };
62 | return self;
63 | };
64 |
65 | ko.applyBindings(new LoginViewModel());
66 |
67 | }).call(this);
68 |
--------------------------------------------------------------------------------
/public/js/password.coffee:
--------------------------------------------------------------------------------
1 | # -----------------------------------------------------------------------------------------------
2 | PasswordViewModel = ->
3 | self = @
4 |
5 | validPassword = (password)->
6 | pw = $.trim(password)
7 | pw.length >= 7 and pw.length<=25
8 |
9 | self.oldpassword = ko.observable('')
10 | self.newpassword = ko.observable('')
11 | self.renewpassword = ko.observable('')
12 |
13 | self.validOldPassword = ko.computed(->
14 | validPassword(self.oldpassword()))
15 |
16 | self.validNewPassword = ko.computed(->
17 | validPassword(self.newpassword()))
18 |
19 | self.validRePassword = ko.computed(->
20 | $.trim(self.newpassword()) == $.trim(self.renewpassword()))
21 |
22 | self.valid = ko.computed(->
23 | self.validOldPassword() and self.validNewPassword() and self.validRePassword())
24 |
25 | self.submit = ->
26 | if self.valid()
27 | data = {newPassword: $.trim(self.newpassword()), oldPassword: $.trim(self.oldpassword())}
28 | UserModel.changePassword(data, (response)->
29 | return if response.state == 0
30 | if response.data == 1
31 | self.oldpassword('')
32 | self.newpassword('')
33 | self.renewpassword('')
34 | $("#successTip").css("display","block")
35 | $("#passwordErrorTip").css("display","none")
36 | else
37 | $("#passwordErrorTip").css("display","block")
38 | $("#successTip").css("display","none")
39 | )
40 | else
41 | console.log("creation fail.")
42 |
43 | self
44 |
45 |
46 | # 初始化 ----------------------------------------------------------------------------
47 | init = ->
48 | passwordvm = new PasswordViewModel()
49 | ko.applyBindings(passwordvm)
50 |
51 | init()
--------------------------------------------------------------------------------
/public/js/password.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var PasswordViewModel, init;
4 |
5 | PasswordViewModel = function() {
6 | var self, validPassword;
7 | self = this;
8 | validPassword = function(password) {
9 | var pw;
10 | pw = $.trim(password);
11 | return pw.length >= 7 && pw.length <= 25;
12 | };
13 | self.oldpassword = ko.observable('');
14 | self.newpassword = ko.observable('');
15 | self.renewpassword = ko.observable('');
16 | self.validOldPassword = ko.computed(function() {
17 | return validPassword(self.oldpassword());
18 | });
19 | self.validNewPassword = ko.computed(function() {
20 | return validPassword(self.newpassword());
21 | });
22 | self.validRePassword = ko.computed(function() {
23 | return $.trim(self.newpassword()) === $.trim(self.renewpassword());
24 | });
25 | self.valid = ko.computed(function() {
26 | return self.validOldPassword() && self.validNewPassword() && self.validRePassword();
27 | });
28 | self.submit = function() {
29 | var data;
30 | if (self.valid()) {
31 | data = {
32 | newPassword: $.trim(self.newpassword()),
33 | oldPassword: $.trim(self.oldpassword())
34 | };
35 | return UserModel.changePassword(data, function(response) {
36 | if (response.state === 0) {
37 | return;
38 | }
39 | if (response.data === 1) {
40 | self.oldpassword('');
41 | self.newpassword('');
42 | self.renewpassword('');
43 | $("#successTip").css("display", "block");
44 | return $("#passwordErrorTip").css("display", "none");
45 | } else {
46 | $("#passwordErrorTip").css("display", "block");
47 | return $("#successTip").css("display", "none");
48 | }
49 | });
50 | } else {
51 | return console.log("creation fail.");
52 | }
53 | };
54 | return self;
55 | };
56 |
57 | init = function() {
58 | var passwordvm;
59 | passwordvm = new PasswordViewModel();
60 | return ko.applyBindings(passwordvm);
61 | };
62 |
63 | init();
64 |
65 | }).call(this);
66 |
--------------------------------------------------------------------------------
/public/js/reportBase.coffee:
--------------------------------------------------------------------------------
1 |
2 | # ViewModel---------------------------------------------------------------
3 | ShowReportsViewModel = ->
4 | self = @
5 | self.reports = ko.observableArray([])
6 | self.reportNum = ko.observable(0)
7 | self.userId = ko.observable(null)
8 | self.pageNum = ko.computed(->
9 | pageNum = Math.ceil(self.reportNum() / NUMOFPAGE)
10 | pageNum = 1 if pageNum == 0
11 | pageNum)
12 |
13 | self.currentPage = ko.observable(1)
14 |
15 | self
16 |
17 | # 初始化 ---------------------------------------------------------------
18 |
19 | # 每页显示的日报条数
20 | NUMOFPAGE = 4
21 |
22 | getReports = (userId=null)->
23 | data = {page:reportvm.currentPage(), numOfPage:NUMOFPAGE, userId:userId}
24 | ReportModel.getReports(data, (response)->
25 | return if response.state == 0
26 | reportvm.reports(response.data))
27 |
28 | getReportNum = (userId=null)->
29 | ReportModel.getReportNum(userId, (response)->
30 | return if response.state == 0
31 | reportvm.reportNum(response.data))
32 |
33 | window.initPageState = ->
34 | reportvm.reports([])
35 | reportvm.reportNum(0)
36 | reportvm.userId(null)
37 |
38 |
39 | reportvm = new ShowReportsViewModel()
40 | ko.applyBindings(reportvm)
41 |
42 | window.getReports = getReports
43 | window.getReportNum = getReportNum
44 | window.reportvm = reportvm
45 |
46 | #翻页组件---------------------------------------
47 | $("div.pagination").on("click", "button.pageNext", ->
48 | gotoPage(reportvm.currentPage()+1)
49 | false)
50 |
51 | $("div.pagination").on("click", "button.pagePre", ->
52 | gotoPage(reportvm.currentPage()-1)
53 | false)
54 |
55 | window.gotoPage = (page)->
56 | reportvm.currentPage(page)
57 | getReports(reportvm.userId())
--------------------------------------------------------------------------------
/public/js/reportBase.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var NUMOFPAGE, ShowReportsViewModel, getReportNum, getReports, reportvm;
4 |
5 | ShowReportsViewModel = function() {
6 | var self;
7 | self = this;
8 | self.reports = ko.observableArray([]);
9 | self.reportNum = ko.observable(0);
10 | self.userId = ko.observable(null);
11 | self.pageNum = ko.computed(function() {
12 | var pageNum;
13 | pageNum = Math.ceil(self.reportNum() / NUMOFPAGE);
14 | if (pageNum === 0) {
15 | pageNum = 1;
16 | }
17 | return pageNum;
18 | });
19 | self.currentPage = ko.observable(1);
20 | return self;
21 | };
22 |
23 | NUMOFPAGE = 4;
24 |
25 | getReports = function(userId) {
26 | var data;
27 | if (userId == null) {
28 | userId = null;
29 | }
30 | data = {
31 | page: reportvm.currentPage(),
32 | numOfPage: NUMOFPAGE,
33 | userId: userId
34 | };
35 | return ReportModel.getReports(data, function(response) {
36 | if (response.state === 0) {
37 | return;
38 | }
39 | return reportvm.reports(response.data);
40 | });
41 | };
42 |
43 | getReportNum = function(userId) {
44 | if (userId == null) {
45 | userId = null;
46 | }
47 | return ReportModel.getReportNum(userId, function(response) {
48 | if (response.state === 0) {
49 | return;
50 | }
51 | return reportvm.reportNum(response.data);
52 | });
53 | };
54 |
55 | window.initPageState = function() {
56 | reportvm.reports([]);
57 | reportvm.reportNum(0);
58 | return reportvm.userId(null);
59 | };
60 |
61 | reportvm = new ShowReportsViewModel();
62 |
63 | ko.applyBindings(reportvm);
64 |
65 | window.getReports = getReports;
66 |
67 | window.getReportNum = getReportNum;
68 |
69 | window.reportvm = reportvm;
70 |
71 | $("div.pagination").on("click", "button.pageNext", function() {
72 | gotoPage(reportvm.currentPage() + 1);
73 | return false;
74 | });
75 |
76 | $("div.pagination").on("click", "button.pagePre", function() {
77 | gotoPage(reportvm.currentPage() - 1);
78 | return false;
79 | });
80 |
81 | window.gotoPage = function(page) {
82 | reportvm.currentPage(page);
83 | return getReports(reportvm.userId());
84 | };
85 |
86 | }).call(this);
87 |
--------------------------------------------------------------------------------
/public/js/showReports.coffee:
--------------------------------------------------------------------------------
1 |
2 | getReports()
3 | getReportNum()
4 |
5 | confirm = (reportId)->
6 | $("#dialog-confirm").dialog({
7 | dialogClass: "no-close",
8 | resizable: false,
9 | height:160,
10 | modal: true,
11 | buttons: {
12 | "删除": ->
13 | deleteReport(reportId)
14 | $(@).dialog("close")
15 | Cancel: ->
16 | $(this).dialog("close")}})
17 |
18 | $("#reportList").on("click", "p.delete", ->
19 | reportId = $(this).attr("reportId")
20 | confirm(reportId))
21 |
22 |
23 | deleteReport = (reportId)->
24 | ReportModel.deleteReport({reportId:reportId}, (response)->
25 | return if response.state == 0
26 |
27 | reportvm.reportNum(reportvm.reportNum()-1)
28 | page = reportvm.currentPage()
29 | if (reportvm.reports().length == 1 && reportvm.currentPage() > 1)
30 | page = reportvm.currentPage() - 1
31 | gotoPage(page))
32 |
--------------------------------------------------------------------------------
/public/js/showReports.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var confirm, deleteReport;
4 |
5 | getReports();
6 |
7 | getReportNum();
8 |
9 | confirm = function(reportId) {
10 | return $("#dialog-confirm").dialog({
11 | dialogClass: "no-close",
12 | resizable: false,
13 | height: 160,
14 | modal: true,
15 | buttons: {
16 | "删除": function() {
17 | deleteReport(reportId);
18 | return $(this).dialog("close");
19 | },
20 | Cancel: function() {
21 | return $(this).dialog("close");
22 | }
23 | }
24 | });
25 | };
26 |
27 | $("#reportList").on("click", "p.delete", function() {
28 | var reportId;
29 | reportId = $(this).attr("reportId");
30 | return confirm(reportId);
31 | });
32 |
33 | deleteReport = function(reportId) {
34 | return ReportModel.deleteReport({
35 | reportId: reportId
36 | }, function(response) {
37 | var page;
38 | if (response.state === 0) {
39 | return;
40 | }
41 | reportvm.reportNum(reportvm.reportNum() - 1);
42 | page = reportvm.currentPage();
43 | if (reportvm.reports().length === 1 && reportvm.currentPage() > 1) {
44 | page = reportvm.currentPage() - 1;
45 | }
46 | return gotoPage(page);
47 | });
48 | };
49 |
50 | }).call(this);
51 |
--------------------------------------------------------------------------------
/public/js/subordinateReports.coffee:
--------------------------------------------------------------------------------
1 | treeList = new TreeList2("#userTree")
2 |
3 | ReportModel.getSubordinateUserAndDepartment((response)->
4 | return if response.state == 0
5 | treeData = response.data
6 | treeList.renderTree("#userTree", treeData))
7 |
8 | #设置用户编辑界面状态
9 | $("#userTree").on("review", (event)->
10 | userId = event["itemId"]
11 | initPageState()
12 | reportvm.userId(userId)
13 | getReports(userId)
14 | getReportNum(userId))
15 |
--------------------------------------------------------------------------------
/public/js/subordinateReports.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var treeList;
4 |
5 | treeList = new TreeList2("#userTree");
6 |
7 | ReportModel.getSubordinateUserAndDepartment(function(response) {
8 | var treeData;
9 | if (response.state === 0) {
10 | return;
11 | }
12 | treeData = response.data;
13 | return treeList.renderTree("#userTree", treeData);
14 | });
15 |
16 | $("#userTree").on("review", function(event) {
17 | var userId;
18 | userId = event["itemId"];
19 | initPageState();
20 | reportvm.userId(userId);
21 | getReports(userId);
22 | return getReportNum(userId);
23 | });
24 |
25 | }).call(this);
26 |
--------------------------------------------------------------------------------
/public/js/writeReport.coffee:
--------------------------------------------------------------------------------
1 | validator = new Validator()
2 | editor = UE.getEditor('content')
3 |
4 | # ViewModel---------------------------------------------------------------
5 | WriteReportViewModel = ->
6 | self = @
7 | self.dateTxt = ko.observable(null)
8 | self.validDateTxt = ko.computed(->
9 | dateStr = $.trim(self.dateTxt())
10 | try
11 | validator.check(dateStr).notEmpty()
12 | [year, months, date] = dateStr.split("-")
13 | #console.log "#{year}-#{months}-#{date}"
14 | validator.check(year).notNull().isNumeric().len(4,4)
15 | validator.check(months).notNull().isNumeric().len(1,2)
16 | validator.check(date).notNull().isNumeric().len(1,2)
17 | return true
18 | catch error
19 | return false)
20 |
21 | self
22 |
23 | # 初始化 ---------------------------------------------------------------
24 | init = ->
25 | $("#dateTxt").datepicker();
26 | $("#dateTxt").datepicker("option", "dateFormat", "yy-mm-dd")
27 |
28 | reportvm = new WriteReportViewModel()
29 | ko.applyBindings(reportvm)
30 |
31 | getDateStr = (date)->
32 | today = new Date()
33 | year = date.getFullYear()
34 | month = date.getMonth() + 1
35 | date = date.getDate()
36 | return "#{year}-#{month}-#{date}"
37 |
38 | dateStr = getDateStr(new Date())
39 | reportvm.dateTxt(dateStr)
40 | #console.log $("#dateTxt").datepicker("getDate")
41 |
42 | $("#reportSubmitBtn").click((event)->
43 | return unless reportvm.validDateTxt()
44 | dateStr = getDateStr($("#dateTxt").datepicker("getDate"))
45 | data = {date:dateStr, content:editor.getContent()}
46 | ReportModel.createReport(data, (response)->
47 | return if response.state == 0
48 | window.location.href = "/show"))
49 |
50 | init()
--------------------------------------------------------------------------------
/public/js/writeReport.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var WriteReportViewModel, editor, init, validator;
4 |
5 | validator = new Validator();
6 |
7 | editor = UE.getEditor('content');
8 |
9 | WriteReportViewModel = function() {
10 | var self;
11 | self = this;
12 | self.dateTxt = ko.observable(null);
13 | self.validDateTxt = ko.computed(function() {
14 | var date, dateStr, months, year, _ref;
15 | dateStr = $.trim(self.dateTxt());
16 | try {
17 | validator.check(dateStr).notEmpty();
18 | _ref = dateStr.split("-"), year = _ref[0], months = _ref[1], date = _ref[2];
19 | validator.check(year).notNull().isNumeric().len(4, 4);
20 | validator.check(months).notNull().isNumeric().len(1, 2);
21 | validator.check(date).notNull().isNumeric().len(1, 2);
22 | return true;
23 | } catch (error) {
24 | return false;
25 | }
26 | });
27 | return self;
28 | };
29 |
30 | init = function() {
31 | var dateStr, getDateStr, reportvm;
32 | $("#dateTxt").datepicker();
33 | $("#dateTxt").datepicker("option", "dateFormat", "yy-mm-dd");
34 | reportvm = new WriteReportViewModel();
35 | ko.applyBindings(reportvm);
36 | getDateStr = function(date) {
37 | var month, today, year;
38 | today = new Date();
39 | year = date.getFullYear();
40 | month = date.getMonth() + 1;
41 | date = date.getDate();
42 | return "" + year + "-" + month + "-" + date;
43 | };
44 | dateStr = getDateStr(new Date());
45 | reportvm.dateTxt(dateStr);
46 | return $("#reportSubmitBtn").click(function(event) {
47 | var data;
48 | if (!reportvm.validDateTxt()) {
49 | return;
50 | }
51 | dateStr = getDateStr($("#dateTxt").datepicker("getDate"));
52 | data = {
53 | date: dateStr,
54 | content: editor.getContent()
55 | };
56 | return ReportModel.createReport(data, function(response) {
57 | if (response.state === 0) {
58 | return;
59 | }
60 | return window.location.href = "/show";
61 | });
62 | });
63 | };
64 |
65 | init();
66 |
67 | }).call(this);
68 |
--------------------------------------------------------------------------------
/public/mobile/css/images/ajax-loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/mobile/css/images/ajax-loader.gif
--------------------------------------------------------------------------------
/public/mobile/css/images/icons-18-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/mobile/css/images/icons-18-black.png
--------------------------------------------------------------------------------
/public/mobile/css/images/icons-18-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/mobile/css/images/icons-18-white.png
--------------------------------------------------------------------------------
/public/mobile/css/images/icons-36-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/mobile/css/images/icons-36-black.png
--------------------------------------------------------------------------------
/public/mobile/css/images/icons-36-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/mobile/css/images/icons-36-white.png
--------------------------------------------------------------------------------
/public/mobile/css/reportStyle.css:
--------------------------------------------------------------------------------
1 | body.subordinate .navbar {
2 | margin-bottom: 0;
3 | }
4 | body.subordinate #userList {
5 | float: left;
6 | margin-top: 0px;
7 | border-right: 1px solid #E5E5E5;
8 | padding: 10px 16px 10px 0;
9 | height: 91%;
10 | width: 310px;
11 | }
12 | body.subordinate #userList div.title {
13 | padding-left: 15px;
14 | }
15 | body.subordinate #userList #userTree {
16 | margin: 0 10px 0 0;
17 | padding: 0;
18 | width: 300px;
19 | }
20 | body.subordinate #reports {
21 | float: left;
22 | padding-left: 30px;
23 | width: 65%;
24 | }
25 | body.subordinate #reports li.report {
26 | border-bottom: 1px solid #E5E5E5;
27 | }
28 | #reportList {
29 | color: #555;
30 | }
31 | #reportList li.report {
32 | border-bottom: 1px solid #E5E5E5;
33 | padding: 10px;
34 | margin-bottom: 15px;
35 | float: left;
36 | width: 100%;
37 | }
38 | #reportList li.report .date span {
39 | font-size: 18px;
40 | font-weight: bold;
41 | color: #1a700b;
42 | padding-left: 5px;
43 | }
44 | #reportList li.report .content {
45 | margin: 0;
46 | padding: 0;
47 | }
48 | #reportList li.report .reply,
49 | #reportList li.report .delete {
50 | float: right;
51 | padding: 0 20px 0 0;
52 | }
53 | div.pageination {
54 | opacity: 0;
55 | }
56 | div.pageination div.pagetip {
57 | text-align: center;
58 | padding-top: 15px;
59 | }
60 | div.pageination div.aligncenter {
61 | text-align: center;
62 | }
63 |
--------------------------------------------------------------------------------
/public/mobile/css/reportStyle.less:
--------------------------------------------------------------------------------
1 |
2 |
3 | //查看下属日报页面
4 | body.subordinate {
5 | .navbar {
6 | margin-bottom: 0;}
7 |
8 |
9 |
10 | #userList {
11 | float:left;
12 | margin-top: 0px;
13 | border-right: 1px solid #E5E5E5;
14 | padding: 10px 16px 10px 0;
15 | height:91%;
16 | width: 310px;
17 |
18 | div.title {
19 | padding-left:15px;
20 | }
21 |
22 | #userTree {
23 | margin:0 10px 0 0;
24 | padding:0;
25 | width: 300px;
26 | }
27 | }
28 |
29 | #reports {
30 | float:left;
31 | padding-left: 30px;
32 | //background-color: #f00;
33 | //min-width:400px;
34 |
35 |
36 | li.report {
37 | //background-color: #eeeeee;
38 | border-bottom: 1px solid #E5E5E5;
39 | }
40 | width:65%;
41 | }
42 |
43 |
44 | }
45 |
46 | //查看我的日报页面
47 | #reportList {
48 | color: #555;
49 | li.report {
50 | //background-color: #eeeeee;
51 | border-bottom: 1px solid #E5E5E5;
52 | //border-radius: 5px 5px 5px 5px;
53 | padding: 10px;
54 | margin-bottom:15px;
55 | float:left;
56 | width:100%;
57 | .date span{
58 | font-size: 18px;
59 | font-weight: bold;
60 | color: #1a700b;
61 | padding-left:5px;
62 | }
63 |
64 | .content{
65 | margin:0;
66 | padding:0;
67 | }
68 |
69 | .reply, .delete {
70 | float: right;
71 | padding: 0 20px 0 0;
72 |
73 | }
74 | }
75 | }
76 |
77 | div.pageination {
78 | opacity: 0;
79 |
80 | div.pagetip {
81 | text-align:center;
82 | padding-top: 15px;
83 | }
84 |
85 | div.aligncenter {
86 | text-align:center;
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/public/mobile/js/Model.coffee:
--------------------------------------------------------------------------------
1 | # model层,处理数据调用和解析 ---------------------------------------------------------------
2 | class Model
3 |
4 | @login: (data, callback)->
5 | $.post("/login", data, (response)->
6 | callback(response)
7 | , "json")
8 |
9 | @logout: (callback)->
10 | $.post("/m/logout", (response)->
11 | callback(response)
12 | , "json")
13 |
14 | @createReport: (data, callback)->
15 | $.post("/write", data, (response)->
16 | callback(response)
17 | , "json")
18 |
19 | @deleteReport: (data, callback)->
20 | $.post("/delete", data, (response)->
21 | callback(response)
22 | , "json")
23 |
24 | @getReportNum: (userId, callback)->
25 | $.post("/getreportnum", {userId:userId}, (response)->
26 | callback(response)
27 | , "json")
28 |
29 | @getSubordinateUserAndDepartment: (callback)->
30 | $.post("/getsubordinateuseranddepartment",(response)->
31 | callback(response)
32 | , "json")
33 |
34 | #返回数据格式为[ { date: '2013-4-30',cotent: '
4.30 reports' },{ date: '2013-4-30',content: '4.30 reports' }]
35 | @getReports: (data, callback)->
36 | $.post("/getreports", data, (response)->
37 | callback(response)
38 | , "json")
39 |
40 | @changePassword: (data, callback)->
41 | $.post("/password", data, (response)->
42 | if response.state == 1
43 | callback(response)
44 | ,"json")
45 |
46 | window.Model = Model
--------------------------------------------------------------------------------
/public/mobile/js/Model.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var Model;
4 |
5 | Model = (function() {
6 |
7 | function Model() {}
8 |
9 | Model.login = function(data, callback) {
10 | return $.post("/login", data, function(response) {
11 | return callback(response);
12 | }, "json");
13 | };
14 |
15 | Model.logout = function(callback) {
16 | return $.post("/m/logout", function(response) {
17 | return callback(response);
18 | }, "json");
19 | };
20 |
21 | Model.createReport = function(data, callback) {
22 | return $.post("/write", data, function(response) {
23 | return callback(response);
24 | }, "json");
25 | };
26 |
27 | Model.deleteReport = function(data, callback) {
28 | return $.post("/delete", data, function(response) {
29 | return callback(response);
30 | }, "json");
31 | };
32 |
33 | Model.getReportNum = function(userId, callback) {
34 | return $.post("/getreportnum", {
35 | userId: userId
36 | }, function(response) {
37 | return callback(response);
38 | }, "json");
39 | };
40 |
41 | Model.getSubordinateUserAndDepartment = function(callback) {
42 | return $.post("/getsubordinateuseranddepartment", function(response) {
43 | return callback(response);
44 | }, "json");
45 | };
46 |
47 | Model.getReports = function(data, callback) {
48 | return $.post("/getreports", data, function(response) {
49 | return callback(response);
50 | }, "json");
51 | };
52 |
53 | Model.changePassword = function(data, callback) {
54 | return $.post("/password", data, function(response) {
55 | if (response.state === 1) {
56 | return callback(response);
57 | }
58 | }, "json");
59 | };
60 |
61 | return Model;
62 |
63 | })();
64 |
65 | window.Model = Model;
66 |
67 | }).call(this);
68 |
--------------------------------------------------------------------------------
/public/ueditor/dialogs/highlightcode/highlightcode.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
16 |
17 |
18 |
19 |
20 |
21 |
47 |
48 |
49 |
50 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/public/ueditor/dialogs/internal.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | var parent = window.parent;
3 | //dialog对象
4 | dialog = parent.$EDITORUI[window.frameElement.id.replace( /_iframe$/, '' )];
5 | //当前打开dialog的编辑器实例
6 | editor = dialog.editor;
7 |
8 | UE = parent.UE;
9 |
10 | domUtils = UE.dom.domUtils;
11 |
12 | utils = UE.utils;
13 |
14 | browser = UE.browser;
15 |
16 | ajax = UE.ajax;
17 |
18 | $G = function ( id ) {
19 | return document.getElementById( id )
20 | };
21 | //focus元素
22 | $focus = function ( node ) {
23 | setTimeout( function () {
24 | if ( browser.ie ) {
25 | var r = node.createTextRange();
26 | r.collapse( false );
27 | r.select();
28 | } else {
29 | node.focus()
30 | }
31 | }, 0 )
32 | };
33 | utils.loadFile(document,{
34 | href:editor.options.themePath + editor.options.theme + "/dialogbase.css?cache="+Math.random(),
35 | tag:"link",
36 | type:"text/css",
37 | rel:"stylesheet"
38 | });
39 | lang = editor.getLang(dialog.className.split( "-" )[2]);
40 |
41 | domUtils.on(window,'load',function () {
42 |
43 | var langImgPath = editor.options.langPath + editor.options.lang + "/images/";
44 | //针对静态资源
45 | for ( var i in lang.static ) {
46 | var dom = $G( i );
47 | if(!dom) continue;
48 | var tagName = dom.tagName,
49 | content = lang.static[i];
50 | if(content.src){
51 | //clone
52 | content = utils.extend({},content,false);
53 | content.src = langImgPath + content.src;
54 | }
55 | if(content.style){
56 | content = utils.extend({},content,false);
57 | content.style = content.style.replace(/url\s*\(/g,"url(" + langImgPath)
58 | }
59 | switch ( tagName.toLowerCase() ) {
60 | case "var":
61 | dom.parentNode.replaceChild( document.createTextNode( content ), dom );
62 | break;
63 | case "select":
64 | var ops = dom.options;
65 | for ( var j = 0, oj; oj = ops[j]; ) {
66 | oj.innerHTML = content.options[j++];
67 | }
68 | for ( var p in content ) {
69 | p != "options" && dom.setAttribute( p, content[p] );
70 | }
71 | break;
72 | default :
73 | domUtils.setAttributes( dom, content);
74 | }
75 | }
76 | } );
77 |
78 | })();
79 |
80 |
--------------------------------------------------------------------------------
/public/ueditor/dialogs/link/link.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
38 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/public/ueditor/dialogs/spechars/spechars.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/public/ueditor/dialogs/spechars/spechars.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created with JetBrains PhpStorm.
3 | * User: xuheng
4 | * Date: 12-9-26
5 | * Time: 下午1:09
6 | * To change this template use File | Settings | File Templates.
7 | */
8 | var charsContent = [
9 | { name:"tsfh", title:lang.tsfh, content:toArray("、,。,·,ˉ,ˇ,¨,〃,々,—,~,‖,…,‘,’,“,”,〔,〕,〈,〉,《,》,「,」,『,』,〖,〗,【,】,±,×,÷,∶,∧,∨,∑,∏,∪,∩,∈,∷,√,⊥,∥,∠,⌒,⊙,∫,∮,≡,≌,≈,∽,∝,≠,≮,≯,≤,≥,∞,∵,∴,♂,♀,°,′,″,℃,$,¤,¢,£,‰,§,№,☆,★,○,●,◎,◇,◆,□,■,△,▲,※,→,←,↑,↓,〓,〡,〢,〣,〤,〥,〦,〧,〨,〩,㊣,㎎,㎏,㎜,㎝,㎞,㎡,㏄,㏎,㏑,㏒,㏕,︰,¬,¦,℡,ˊ,ˋ,˙,–,―,‥,‵,℅,℉,↖,↗,↘,↙,∕,∟,∣,≒,≦,≧,⊿,═,║,╒,╓,╔,╕,╖,╗,╘,╙,╚,╛,╜,╝,╞,╟,╠,╡,╢,╣,╤,╥,╦,╧,╨,╩,╪,╫,╬,╭,╮,╯,╰,╱,╲,╳,▁,▂,▃,▄,▅,▆,▇,�,█,▉,▊,▋,▌,▍,▎,▏,▓,▔,▕,▼,▽,◢,◣,◤,◥,☉,⊕,〒,〝,〞")},
10 | { name:"lmsz", title:lang.lmsz, content:toArray("ⅰ,ⅱ,ⅲ,ⅳ,ⅴ,ⅵ,ⅶ,ⅷ,ⅸ,ⅹ,Ⅰ,Ⅱ,Ⅲ,Ⅳ,Ⅴ,Ⅵ,Ⅶ,Ⅷ,Ⅸ,Ⅹ,Ⅺ,Ⅻ")},
11 | { name:"szfh", title:lang.szfh, content:toArray("⒈,⒉,⒊,⒋,⒌,⒍,⒎,⒏,⒐,⒑,⒒,⒓,⒔,⒕,⒖,⒗,⒘,⒙,⒚,⒛,⑴,⑵,⑶,⑷,⑸,⑹,⑺,⑻,⑼,⑽,⑾,⑿,⒀,⒁,⒂,⒃,⒄,⒅,⒆,⒇,①,②,③,④,⑤,⑥,⑦,⑧,⑨,⑩,㈠,㈡,㈢,㈣,㈤,㈥,㈦,㈧,㈨,㈩")},
12 | { name:"rwfh", title:lang.rwfh, content:toArray("ぁ,あ,ぃ,い,ぅ,う,ぇ,え,ぉ,お,か,が,き,ぎ,く,ぐ,け,げ,こ,ご,さ,ざ,し,じ,す,ず,せ,ぜ,そ,ぞ,た,だ,ち,ぢ,っ,つ,づ,て,で,と,ど,な,に,ぬ,ね,の,は,ば,ぱ,ひ,び,ぴ,ふ,ぶ,ぷ,へ,べ,ぺ,ほ,ぼ,ぽ,ま,み,む,め,も,ゃ,や,ゅ,ゆ,ょ,よ,ら,り,る,れ,ろ,ゎ,わ,ゐ,ゑ,を,ん,ァ,ア,ィ,イ,ゥ,ウ,ェ,エ,ォ,オ,カ,ガ,キ,ギ,ク,グ,ケ,ゲ,コ,ゴ,サ,ザ,シ,ジ,ス,ズ,セ,ゼ,ソ,ゾ,タ,ダ,チ,ヂ,ッ,ツ,ヅ,テ,デ,ト,ド,ナ,ニ,ヌ,ネ,ノ,ハ,バ,パ,ヒ,ビ,ピ,フ,ブ,プ,ヘ,ベ,ペ,ホ,ボ,ポ,マ,ミ,ム,メ,モ,ャ,ヤ,ュ,ユ,ョ,ヨ,ラ,リ,ル,レ,ロ,ヮ,ワ,ヰ,ヱ,ヲ,ン,ヴ,ヵ,ヶ")},
13 | { name:"xlzm", title:lang.xlzm, content:toArray("Α,Β,Γ,Δ,Ε,Ζ,Η,Θ,Ι,Κ,Λ,Μ,Ν,Ξ,Ο,Π,Ρ,Σ,Τ,Υ,Φ,Χ,Ψ,Ω,α,β,γ,δ,ε,ζ,η,θ,ι,κ,λ,μ,ν,ξ,ο,π,ρ,σ,τ,υ,φ,χ,ψ,ω")},
14 | { name:"ewzm", title:lang.ewzm, content:toArray("А,Б,В,Г,Д,Е,Ё,Ж,З,И,Й,К,Л,М,Н,О,П,Р,С,Т,У,Ф,Х,Ц,Ч,Ш,Щ,Ъ,Ы,Ь,Э,Ю,Я,а,б,в,г,д,е,ё,ж,з,и,й,к,л,м,н,о,п,р,с,т,у,ф,х,ц,ч,ш,щ,ъ,ы,ь,э,ю,я")},
15 | { name:"pyzm", title:lang.pyzm, content:toArray("ā,á,ǎ,à,ē,é,ě,è,ī,í,ǐ,ì,ō,ó,ǒ,ò,ū,ú,ǔ,ù,ǖ,ǘ,ǚ,ǜ,ü")},
16 | { name:"zyzf", title:lang.zyzf, content:toArray("ㄅ,ㄆ,ㄇ,ㄈ,ㄉ,ㄊ,ㄋ,ㄌ,ㄍ,ㄎ,ㄏ,ㄐ,ㄑ,ㄒ,ㄓ,ㄔ,ㄕ,ㄖ,ㄗ,ㄘ,ㄙ,ㄚ,ㄛ,ㄜ,ㄝ,ㄞ,ㄟ,ㄠ,ㄡ,ㄢ,ㄣ,ㄤ,ㄥ,ㄦ,ㄧ,ㄨ")}
17 | ];
18 | (function createTab(content) {
19 | for (var i = 0, ci; ci = content[i++];) {
20 | var span = document.createElement("span");
21 | span.setAttribute("tabSrc", ci.name);
22 | span.innerHTML = ci.title;
23 | if (i == 1)span.className = "focus";
24 | domUtils.on(span, "click", function () {
25 | var tmps = $G("tabHeads").children;
26 | for (var k = 0, sk; sk = tmps[k++];) {
27 | sk.className = "";
28 | }
29 | tmps = $G("tabBodys").children;
30 | for (var k = 0, sk; sk = tmps[k++];) {
31 | sk.style.display = "none";
32 | }
33 | this.className = "focus";
34 | $G(this.getAttribute("tabSrc")).style.display = "";
35 | });
36 | $G("tabHeads").appendChild(span);
37 | domUtils.insertAfter(span, document.createTextNode("\n"));
38 | var div = document.createElement("div");
39 | div.id = ci.name;
40 | div.style.display = (i == 1) ? "" : "none";
41 | var cons = ci.content;
42 | for (var j = 0, con; con = cons[j++];) {
43 | var charSpan = document.createElement("span");
44 | charSpan.innerHTML = con;
45 | domUtils.on(charSpan, "click", function () {
46 | editor.execCommand("insertHTML", this.innerHTML);
47 | dialog.close();
48 | });
49 | div.appendChild(charSpan);
50 | }
51 | $G("tabBodys").appendChild(div);
52 | }
53 | })(charsContent);
54 | function toArray(str) {
55 | return str.split(",");
56 | }
57 |
--------------------------------------------------------------------------------
/public/ueditor/dialogs/table/dragicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/dialogs/table/dragicon.png
--------------------------------------------------------------------------------
/public/ueditor/dialogs/table/edittable.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | margin: 10px auto 0;
3 | font-size: 12px;
4 | overflow: hidden;
5 | }
6 |
7 | .clear {
8 | clear: both;
9 | }
10 |
11 | .wrapper .left {
12 | float: left;
13 | margin-left: 10px;;
14 | }
15 |
16 | .wrapper .right {
17 | float: right;
18 | margin-right: 10px;
19 | border-left: 2px dotted #EDEDED;
20 | padding-left: 15px;
21 | }
22 |
23 | .section {
24 | margin-bottom: 20px;
25 | overflow: hidden;
26 | }
27 |
28 | .section h3 {
29 | font-weight: bold;
30 | padding: 5px 0;
31 | margin-bottom: 10px;
32 | border-bottom: 1px solid #EDEDED;
33 | font-size: 12px;
34 | }
35 |
36 | .section ul {
37 | list-style: none;
38 | overflow: hidden;
39 | }
40 |
41 | .section li {
42 | float: left;
43 | }
44 |
45 | .section .tone {
46 | width: 80px;;
47 | }
48 |
49 | .section .preview {
50 | width: 220px;
51 | }
52 |
53 | .section .preview table {
54 | text-align: center;
55 | vertical-align: middle;
56 | color: #666;
57 | }
58 |
59 | .section .preview caption {
60 | font-weight: bold;
61 | }
62 |
63 | .section .preview td {
64 | border-width: 1px;
65 | border-style: solid;
66 | height: 22px;
67 | }
68 |
69 | .section .preview th {
70 | border-style: solid;
71 | border-color: #DDD;
72 | border-width: 2px 1px 1px 1px;
73 | height: 22px;
74 | background-color: #F7F7F7;
75 | }
--------------------------------------------------------------------------------
/public/ueditor/dialogs/table/edittable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/public/ueditor/dialogs/table/edittd.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
49 |
50 |
--------------------------------------------------------------------------------
/public/ueditor/dialogs/table/edittip.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 表格删除提示
5 |
6 |
17 |
18 |
19 |
27 |
32 |
33 |
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/addimage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/addimage.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/alldeletebtnhoverskin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/alldeletebtnhoverskin.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/alldeletebtnupskin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/alldeletebtnupskin.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/background.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/button.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/copy.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/deletedisable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/deletedisable.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/deleteenable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/deleteenable.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/imglabel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/imglabel.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/listbackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/listbackground.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/localimage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/localimage.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/music.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/rotateleftdisable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/rotateleftdisable.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/rotateleftenable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/rotateleftenable.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/rotaterightdisable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/rotaterightdisable.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/rotaterightenable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/rotaterightenable.png
--------------------------------------------------------------------------------
/public/ueditor/lang/en/images/upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/en/images/upload.png
--------------------------------------------------------------------------------
/public/ueditor/lang/zh-cn/images/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/zh-cn/images/copy.png
--------------------------------------------------------------------------------
/public/ueditor/lang/zh-cn/images/imglabel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/zh-cn/images/imglabel.png
--------------------------------------------------------------------------------
/public/ueditor/lang/zh-cn/images/localimage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/zh-cn/images/localimage.png
--------------------------------------------------------------------------------
/public/ueditor/lang/zh-cn/images/music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/zh-cn/images/music.png
--------------------------------------------------------------------------------
/public/ueditor/lang/zh-cn/images/upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/lang/zh-cn/images/upload.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/dialogbase.css:
--------------------------------------------------------------------------------
1 | /*弹出对话框页面样式组件
2 | */
3 |
4 | /*reset
5 | */
6 | html, body, div, span, applet, object, iframe,
7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8 | a, abbr, acronym, address, big, cite, code,
9 | del, dfn, em, font, img, ins, kbd, q, s, samp,
10 | small, strike, strong, sub, sup, tt, var,
11 | b, u, i, center,
12 | dl, dt, dd, ol, ul, li,
13 | fieldset, form, label, legend,
14 | table, caption, tbody, tfoot, thead, tr, th, td {
15 | margin: 0;
16 | padding: 0;
17 | outline: 0;
18 | font-size: 100%;
19 | }
20 |
21 | body {
22 | line-height: 1;
23 | }
24 |
25 | ol, ul {
26 | list-style: none;
27 | }
28 |
29 | blockquote, q {
30 | quotes: none;
31 | }
32 |
33 | ins {
34 | text-decoration: none;
35 | }
36 |
37 | del {
38 | text-decoration: line-through;
39 | }
40 |
41 | table {
42 | border-collapse: collapse;
43 | border-spacing: 0;
44 | }
45 |
46 | /*module
47 | */
48 | body {
49 | background-color: #fff;
50 | font: 12px/1.5 "宋体", "Arial Narrow", HELVETICA;
51 | color: #646464;
52 | }
53 |
54 | /*tab*/
55 | .tabhead {
56 | position: relative;
57 | z-index: 10;
58 | }
59 |
60 | .tabhead span {
61 | display: inline-block;
62 | padding: 0 5px;
63 | height: 30px;
64 | border: 1px solid #ccc;
65 | background: url("images/dialog-title-bg.png") repeat-x;
66 | text-align: center;
67 | line-height: 30px;
68 | cursor: pointer;
69 | *margin-right: 5px;
70 | }
71 |
72 | .tabhead span.focus {
73 | height: 31px;
74 | border-bottom: none;
75 | background: #fff;
76 | }
77 |
78 | .tabbody {
79 | position: relative;
80 | top: -1px;
81 | margin: 0 auto;
82 | border: 1px solid #ccc;
83 | }
84 |
85 | /*button*/
86 | a.button {
87 | display: block;
88 | text-align: center;
89 | line-height: 24px;
90 | text-decoration: none;
91 | height: 24px;
92 | width: 95px;
93 | border: 0;
94 | color: #838383;
95 | background: url(../../themes/default/images/icons-all.gif) no-repeat;
96 | }
97 |
98 | a.button:hover {
99 | background-position: 0 -30px;
100 | }
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/anchor.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/anchor.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/arrow.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/button-bg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/button-bg.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/cancelbutton.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/cancelbutton.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/cursor_h.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/cursor_h.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/cursor_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/cursor_h.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/cursor_v.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/cursor_v.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/cursor_v.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/cursor_v.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/dialog-title-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/dialog-title-bg.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/filescan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/filescan.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/highlighted.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/highlighted.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/icons-all.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/icons-all.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/icons.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/icons.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/icons.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/lock.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/lock.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/neweditor-tab-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/neweditor-tab-bg.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/pagebreak.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/pagebreak.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/scale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/scale.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/spacer.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/spacer.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/sparator_v.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/sparator_v.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/toolbar_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/toolbar_bg.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/unhighlighted.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/unhighlighted.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/upload.png
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/videologo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/videologo.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/word.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/word.gif
--------------------------------------------------------------------------------
/public/ueditor/themes/default/images/wordpaste.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalterShe/dailyReport/e3fcff6ec9b2f2372f85c38b30898b03521dcc3f/public/ueditor/themes/default/images/wordpaste.png
--------------------------------------------------------------------------------
/public/ueditor/themes/iframe.css:
--------------------------------------------------------------------------------
1 | /*可以在这里添加你自己的css*/
2 |
--------------------------------------------------------------------------------
/routes/routeProfile.coffee:
--------------------------------------------------------------------------------
1 |
2 | user = require('../controlers/userCtr')
3 | department = require('../controlers/departmentCtr')
4 | admin = require('../controlers/adminCtr')
5 | report = require('../controlers/reportCtr')
6 | installer = require('../controlers/installCtr')
7 |
8 | exports.createRutes = (app)->
9 | app.get('/install', installer.install)
10 | app.get('/', report.index);
11 | app.get('/write', report.writeIndex);
12 | app.post('/write', report.write);
13 | app.get('/password', user.passwordIndex);
14 | app.post('/password', user.changePassword);
15 | app.post('/delete', report.delete);
16 | app.get('/show', report.showIndex);
17 | app.post('/getsubordinateuseranddepartment', report.getSubordinateUserAndDepartment);
18 | app.get('/showsubordinate', report.showsubordinateIndex);
19 | app.post('/getreports', report.getReports);
20 | app.post('/getreportnum', report.getReportNum);
21 | app.get('/login', user.loginIndex);
22 | app.get('/logout', user.logout);
23 | app.post('/login', user.login);
24 | app.post('/admin/createuser', user.createUser);
25 | app.post('/admin/removeuser', user.removeUser);
26 | app.get('/admin/getallusers', user.getAllUsers);
27 | app.post('/admin/updateuser', user.updateUser);
28 | app.post('/admin/hasuser', user.hasUser);
29 |
30 | app.get('/admin', admin.index);
31 | app.get('/admin/users', admin.usersIndex);
32 | app.get('/admin/admingroup', admin.admingroupIndex);
33 |
34 | app.post('/admin/createdepartment', department.createDepartment);
35 | app.get('/admin/alldepartments', department.getAllDepartments);
36 | app.post('/admin/removedepartment', department.removeDepartment);
37 | app.post('/admin/updatedepartment', department.updateDepartment);
38 |
39 | app.post('/admin/setadmin', user.setAdmin);
40 | app.post('/admin/deleteadmin', user.deleteAdmin);
41 | app.post('/admin/getadmins', user.getAdmins);
42 |
43 | app.get('/m', user.indexMobile);
44 | app.get('/m/login', user.loginIndexMobile);
45 | app.get('/m/show', report.showIndexMobile);
46 | app.get('/m/write', report.writeIndexMobile);
47 | app.get('/m/showsubordinate', report.subordinateIndexMobile);
48 | app.get('/m/setting', report.settingMobile);
49 | app.get('/m/logout', user.logoutMobileIndex);
50 | app.get('/m/password', user.passwordMobileIndex)
--------------------------------------------------------------------------------
/routes/routeProfile.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var admin, department, installer, report, user;
4 |
5 | user = require('../controlers/userCtr');
6 |
7 | department = require('../controlers/departmentCtr');
8 |
9 | admin = require('../controlers/adminCtr');
10 |
11 | report = require('../controlers/reportCtr');
12 |
13 | installer = require('../controlers/installCtr');
14 |
15 | exports.createRoutes = function(app) {
16 | app.get('/install', installer.install);
17 | app.get('/', report.index);
18 | app.get('/write', report.writeIndex);
19 | app.post('/write', report.write);
20 | app.get('/password', user.passwordIndex);
21 | app.post('/password', user.changePassword);
22 | app.post('/delete', report["delete"]);
23 | app.get('/show', report.showIndex);
24 | app.post('/getsubordinateuseranddepartment', report.getSubordinateUserAndDepartment);
25 | app.get('/showsubordinate', report.showsubordinateIndex);
26 | app.post('/getreports', report.getReports);
27 | app.post('/getreportnum', report.getReportNum);
28 | app.get('/login', user.loginIndex);
29 | app.get('/logout', user.logout);
30 | app.post('/login', user.login);
31 | app.post('/admin/createuser', user.createUser);
32 | app.post('/admin/removeuser', user.removeUser);
33 | app.get('/admin/getallusers', user.getAllUsers);
34 | app.post('/admin/updateuser', user.updateUser);
35 | app.post('/admin/hasuser', user.hasUser);
36 | app.get('/admin', admin.index);
37 | app.get('/admin/users', admin.usersIndex);
38 | app.get('/admin/admingroup', admin.admingroupIndex);
39 | app.post('/admin/createdepartment', department.createDepartment);
40 | app.get('/admin/alldepartments', department.getAllDepartments);
41 | app.post('/admin/removedepartment', department.removeDepartment);
42 | app.post('/admin/updatedepartment', department.updateDepartment);
43 | app.post('/admin/setadmin', user.setAdmin);
44 | app.post('/admin/deleteadmin', user.deleteAdmin);
45 | app.post('/admin/getadmins', user.getAdmins);
46 | app.get('/m', user.indexMobile);
47 | app.get('/m/login', user.loginIndexMobile);
48 | app.get('/m/show', report.showIndexMobile);
49 | app.get('/m/write', report.writeIndexMobile);
50 | app.get('/m/showsubordinate', report.subordinateIndexMobile);
51 | app.get('/m/setting', report.settingMobile);
52 | app.get('/m/logout', user.logoutMobileIndex);
53 | return app.get('/m/password', user.passwordMobileIndex);
54 | };
55 |
56 | }).call(this);
57 |
--------------------------------------------------------------------------------
/utils.coffee:
--------------------------------------------------------------------------------
1 | redis = require("redis")
2 | {Response} = require('./vo/Response')
3 | dbconfig = require('./config').db
4 |
5 |
6 | #如果用户登陆了,返回true,否则返回false,并且转向登陆界面
7 | exports.authenticateUser = (req,res)->
8 | result = @isLoginUser(req)
9 | path = "/login"
10 | path = "/m/login" if @isMobileClient(req)
11 | res.redirect(path) unless result
12 |
13 | result
14 |
15 | exports.isMobileClient = (req)->
16 | urlArray = req.path.split("/")
17 | #console.log urlArray
18 | urlArray[1] == "m"
19 |
20 | #如果用户登陆了,返回true,否则返回false
21 | exports.isLoginUser = (req)->
22 | req.session?.userId and true
23 |
24 |
25 | #如果用户是管理员,返回true,否则返回false ,并且转向登陆界面
26 | exports.authenticateAdmin = (req,res)->
27 | result = @isAdmin(req)
28 | unless result
29 | if @isLoginUser(req)
30 | res.redirect('/show')
31 | else
32 | res.redirect('/login')
33 |
34 | result
35 |
36 | #如果用户是管理员,返回true,否则返回false
37 | exports.isAdmin = (req)->
38 | @isLoginUser(req) and req.session.isAdmin == 1
39 |
40 | exports.showDBError = (callback, client=null, message='数据库错误')->
41 | client.quit() if client
42 | callback(new Response(0,message))
43 |
44 | exports.createClient = ->
45 | client = redis.createClient(dbconfig.port, dbconfig.host)
46 | if dbconfig.pass
47 | client.auth(dbconfig.pass, (err)->
48 | throw err if err)
49 |
50 | client.on("error", (err)->
51 | console.log(err)
52 | client.end())
53 |
54 | client
55 |
56 |
57 |
--------------------------------------------------------------------------------
/utils.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var Response, dbconfig, redis;
4 |
5 | redis = require("redis");
6 |
7 | Response = require('./vo/Response').Response;
8 |
9 | dbconfig = require('./config').db;
10 |
11 | exports.authenticateUser = function(req, res) {
12 | var path, result;
13 | result = this.isLoginUser(req);
14 | path = "/login";
15 | if (this.isMobileClient(req)) {
16 | path = "/m/login";
17 | }
18 | if (!result) {
19 | res.redirect(path);
20 | }
21 | return result;
22 | };
23 |
24 | exports.isMobileClient = function(req) {
25 | var urlArray;
26 | urlArray = req.path.split("/");
27 | return urlArray[1] === "m";
28 | };
29 |
30 | exports.isLoginUser = function(req) {
31 | var _ref;
32 | return ((_ref = req.session) != null ? _ref.userId : void 0) && true;
33 | };
34 |
35 | exports.authenticateAdmin = function(req, res) {
36 | var result;
37 | result = this.isAdmin(req);
38 | if (!result) {
39 | if (this.isLoginUser(req)) {
40 | res.redirect('/show');
41 | } else {
42 | res.redirect('/login');
43 | }
44 | }
45 | return result;
46 | };
47 |
48 | exports.isAdmin = function(req) {
49 | return this.isLoginUser(req) && req.session.isAdmin === 1;
50 | };
51 |
52 | exports.showDBError = function(callback, client, message) {
53 | if (client == null) {
54 | client = null;
55 | }
56 | if (message == null) {
57 | message = '数据库错误';
58 | }
59 | if (client) {
60 | client.quit();
61 | }
62 | return callback(new Response(0, message));
63 | };
64 |
65 | exports.createClient = function() {
66 | var client;
67 | client = redis.createClient(dbconfig.port, dbconfig.host);
68 | if (dbconfig.pass) {
69 | client.auth(dbconfig.pass, function(err) {
70 | if (err) {
71 | throw err;
72 | }
73 | });
74 | }
75 | client.on("error", function(err) {
76 | console.log(err);
77 | return client.end();
78 | });
79 | return client;
80 | };
81 |
82 | }).call(this);
83 |
--------------------------------------------------------------------------------
/views/admin/admingroup.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 管理员设置-日报后台管理系统
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 |
26 |
27 |
28 |
添加管理员
29 |
30 |
32 |
33 |
35 |
37 |
38 |
39 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/views/admin/department.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 部门信息-日报后台管理系统
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 |
26 |
27 |
28 |
创建新部门
29 |
编辑部门
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
40 |
42 |
43 |
45 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/views/admin/users.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 用户管理-日报后台管理
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 |
26 |
27 |
28 |
创建新用户
29 |
32 |
34 |
35 |
37 |
39 |
41 |
43 |
44 |
45 |
47 |
48 |
50 |
52 |
53 |
54 |
更新用户信息
55 |
57 |
59 |
60 |
62 |
64 |
66 |
68 |
69 |
70 |
72 |
73 |
75 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/views/install.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Install-Daily Report
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 | 恭喜,安装成功!
17 | 管理员账户名为:admin,密码:1234567。登陆后进入“管理员控制台”开始设置部门和添加成员
18 |
19 |
20 |
--------------------------------------------------------------------------------
/views/login.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Login-Daily Report
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/views/mobile/layout.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{title}}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {{{body}}}
17 |
18 |
--------------------------------------------------------------------------------
/views/mobile/login.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
登录
4 |
5 |
23 |
34 |
35 |
36 |
37 |
38 |
登录错误提示
39 |
40 |
41 |
用户名长度为2-25个字符,密码长度为7-25个字符
42 |
43 |
44 |
--------------------------------------------------------------------------------
/views/mobile/password.hbs:
--------------------------------------------------------------------------------
1 |
2 |
6 |
31 |
32 |
33 |
34 | - 写日报
35 | - 我的日报
36 | {{#if hasSubordinate}}
37 | - 下属日报
38 | {{/if}}
39 |
40 |
41 |
42 |
48 |
49 |
50 |
51 |
52 |
修改密码错误提示
53 |
54 |
55 |
密码长度为7-25个字符并且老密码输入必须正确
56 |
57 |
58 |
--------------------------------------------------------------------------------
/views/mobile/show.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
1/1
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | - 写日报
24 | - 我的日报
25 | {{#if hasSubordinate}}
26 | - 下属日报
27 | {{/if}}
28 |
29 |
30 |
31 |
37 |
43 |
44 |
--------------------------------------------------------------------------------
/views/mobile/showsubordinate.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
19 |
25 |
26 |
--------------------------------------------------------------------------------
/views/mobile/write.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
25 |
26 |
27 |
28 |
29 | - 写日报
30 | - 我的日报
31 | {{#if hasSubordinate}}
32 | - 下属日报
33 | {{/if}}
34 |
35 |
36 |
37 |
43 |
44 |
45 |
46 |
错误提示
47 |
48 |
49 |
日期格式为xxxx-xx-xx(例如 2013-5-3)并且日报内容不能为空。
50 |
51 |
52 |
--------------------------------------------------------------------------------
/views/password.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 修改密码
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Daily Report
13 |
14 | - 写日报
15 | - 我的日报
16 | {{#if hasSubordinate}}
17 | - 下属日报
18 | {{/if}}
19 | - 修改密码
20 | {{#if isAdmin}}
21 | - 管理员控制台
22 | {{/if}}
23 | {{#if isLoginUser}}
24 | - 退出
25 | {{/if}}
26 |
27 |
28 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/views/show.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 写日报
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Daily Report
16 |
17 | - 写日报
18 | - 我的日报
19 | {{#if hasSubordinate}}
20 | - 下属日报
21 | {{/if}}
22 | - 修改密码
23 | {{#if isAdmin}}
24 | - 管理员控制台
25 | {{/if}}
26 | {{#if isLoginUser}}
27 | - 退出
28 | {{/if}}
29 |
30 |
31 |
34 |
35 |
日报内容
36 |
37 |
38 | -
39 |
40 |
41 |
42 | 删除
43 |
44 |
45 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/views/showsubordinate.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 写日报
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
29 |
33 |
34 |
日报内容
35 |
36 |
37 | -
38 |
39 |
40 |
41 |
42 |
43 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/views/write.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 写日报
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Daily Report
17 |
18 | - 写日报
19 | - 我的日报
20 | {{#if hasSubordinate}}
21 | - 下属日报
22 | {{/if}}
23 | - 修改密码
24 | {{#if isAdmin}}
25 | - 管理员控制台
26 | {{/if}}
27 | {{#if isLoginUser}}
28 | - 退出
29 | {{/if}}
30 |
31 |
32 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/vo/Response.coffee:
--------------------------------------------------------------------------------
1 |
2 | class Response
3 | constructor: (@state, @message, @data=null) ->
4 |
5 | exports.Response = Response
--------------------------------------------------------------------------------
/vo/Response.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.1
2 | (function() {
3 | var Response;
4 |
5 | Response = (function() {
6 |
7 | function Response(state, message, data) {
8 | this.state = state;
9 | this.message = message;
10 | this.data = data != null ? data : null;
11 | }
12 |
13 | return Response;
14 |
15 | })();
16 |
17 | exports.Response = Response;
18 |
19 | }).call(this);
20 |
--------------------------------------------------------------------------------