Browse Source

updatepengjs

mysq1123 6 years ago
parent
commit
97a9d99b9b
100 changed files with 32053 additions and 0 deletions
  1. 16 0
      conf/app.conf
  2. 9 0
      contanst/user.go
  3. 210 0
      controllers/backgroundc/admin.go
  4. 267 0
      controllers/backgroundc/api.go
  5. 100 0
      controllers/backgroundc/apidoc.go
  6. 17 0
      controllers/backgroundc/apimonitor.go
  7. 139 0
      controllers/backgroundc/apipublic.go
  8. 124 0
      controllers/backgroundc/auth.go
  9. 135 0
      controllers/backgroundc/code.go
  10. 384 0
      controllers/backgroundc/common.go
  11. 134 0
      controllers/backgroundc/env.go
  12. 163 0
      controllers/backgroundc/group.go
  13. 23 0
      controllers/backgroundc/home.go
  14. 73 0
      controllers/backgroundc/login.go
  15. 102 0
      controllers/backgroundc/property_notice.go
  16. 155 0
      controllers/backgroundc/role.go
  17. 271 0
      controllers/backgroundc/source.go
  18. 131 0
      controllers/backgroundc/template.go
  19. 82 0
      controllers/backgroundc/user.go
  20. 54 0
      controllers/frontc/api.go
  21. 146 0
      controllers/frontc/base.go
  22. 87 0
      controllers/frontc/login.go
  23. 43 0
      controllers/frontc/property_notice.go
  24. 57 0
      controllers/frontc/repair.go
  25. 128 0
      controllers/frontc/user.go
  26. 291 0
      controllers/frontc/user_repair.go
  27. 5 0
      initial/init.go
  28. 35 0
      initial/sql.go
  29. 54 0
      libs/http.go
  30. 29 0
      libs/response.go
  31. 96 0
      libs/string.go
  32. 73 0
      libs/upload.go
  33. 20 0
      libs/validate.go
  34. 17 0
      main.go
  35. 201 0
      models/backgroundm/admin.go
  36. 141 0
      models/backgroundm/api_detail.go
  37. 85 0
      models/backgroundm/api_public.go
  38. 77 0
      models/backgroundm/api_source.go
  39. 95 0
      models/backgroundm/auth.go
  40. 84 0
      models/backgroundm/code.go
  41. 83 0
      models/backgroundm/env.go
  42. 77 0
      models/backgroundm/group.go
  43. 69 0
      models/backgroundm/role.go
  44. 80 0
      models/backgroundm/role_auth.go
  45. 76 0
      models/backgroundm/template.go
  46. 59 0
      models/commonm/property_notice.go
  47. 34 0
      models/frontm/picture.go
  48. 264 0
      models/frontm/repair.go
  49. 54 0
      models/frontm/repair_user_picture.go
  50. 18 0
      models/frontm/user.go
  51. 45 0
      models/init.go
  52. 298 0
      ppgo_api_admin.sql
  53. 85 0
      routers/router.go
  54. 1 0
      static/README.md
  55. 139 0
      static/css/api.css
  56. 69 0
      static/css/apidoc.css
  57. 312 0
      static/css/app.css
  58. 422 0
      static/css/index.css
  59. 79 0
      static/css/login.css
  60. 51 0
      static/css/main.css
  61. 63 0
      static/css/message.css
  62. 76 0
      static/css/nprogress.css
  63. 22 0
      static/editor.md/BUGS.md
  64. 534 0
      static/editor.md/CHANGE.md
  65. 342 0
      static/editor.md/Gulpfile.js
  66. 22 0
      static/editor.md/LICENSE
  67. 119 0
      static/editor.md/README.md
  68. 24 0
      static/editor.md/bower.json
  69. 4450 0
      static/editor.md/css/editormd.css
  70. 98 0
      static/editor.md/css/editormd.logo.css
  71. 2 0
      static/editor.md/css/editormd.logo.min.css
  72. 5 0
      static/editor.md/css/editormd.min.css
  73. 3554 0
      static/editor.md/css/editormd.preview.css
  74. 5 0
      static/editor.md/css/editormd.preview.min.css
  75. 4407 0
      static/editor.md/docs/editormd.js.html
  76. BIN
      static/editor.md/docs/fonts/OpenSans-Bold-webfont.eot
  77. 1830 0
      static/editor.md/docs/fonts/OpenSans-Bold-webfont.svg
  78. BIN
      static/editor.md/docs/fonts/OpenSans-Bold-webfont.woff
  79. BIN
      static/editor.md/docs/fonts/OpenSans-BoldItalic-webfont.eot
  80. 1830 0
      static/editor.md/docs/fonts/OpenSans-BoldItalic-webfont.svg
  81. BIN
      static/editor.md/docs/fonts/OpenSans-BoldItalic-webfont.woff
  82. BIN
      static/editor.md/docs/fonts/OpenSans-Italic-webfont.eot
  83. 1830 0
      static/editor.md/docs/fonts/OpenSans-Italic-webfont.svg
  84. BIN
      static/editor.md/docs/fonts/OpenSans-Italic-webfont.woff
  85. BIN
      static/editor.md/docs/fonts/OpenSans-Light-webfont.eot
  86. 1831 0
      static/editor.md/docs/fonts/OpenSans-Light-webfont.svg
  87. BIN
      static/editor.md/docs/fonts/OpenSans-Light-webfont.woff
  88. BIN
      static/editor.md/docs/fonts/OpenSans-LightItalic-webfont.eot
  89. 1835 0
      static/editor.md/docs/fonts/OpenSans-LightItalic-webfont.svg
  90. BIN
      static/editor.md/docs/fonts/OpenSans-LightItalic-webfont.woff
  91. BIN
      static/editor.md/docs/fonts/OpenSans-Regular-webfont.eot
  92. 1831 0
      static/editor.md/docs/fonts/OpenSans-Regular-webfont.svg
  93. BIN
      static/editor.md/docs/fonts/OpenSans-Regular-webfont.woff
  94. 65 0
      static/editor.md/docs/index.html
  95. 25 0
      static/editor.md/docs/scripts/linenumber.js
  96. 202 0
      static/editor.md/docs/scripts/prettify/Apache-License-2.0.txt
  97. 2 0
      static/editor.md/docs/scripts/prettify/lang-css.js
  98. 28 0
      static/editor.md/docs/scripts/prettify/prettify.js
  99. 353 0
      static/editor.md/docs/styles/jsdoc-default.css
  100. 0 0
      static/editor.md/docs/styles/prettify-jsdoc.css

+ 16 - 0
conf/app.conf

@@ -0,0 +1,16 @@
+appname = PPGo_ApiAdmin
+httpport = 8081
+httpaddr = "localhost"
+runmode = dev
+
+# 站点名称
+site.name = API管理平台
+
+# 数据库配置
+db.host = 
+db.user = root
+db.password = ""
+db.port = 3306
+db.name = wuyebaoxiu
+db.prefix = pp_
+db.timezone = Asia/Shanghai

+ 9 - 0
contanst/user.go

@@ -0,0 +1,9 @@
+package contanst
+
+// 缓存前缀常量
+const CACHE_USERINFO  = "ui:" // 用户信息
+
+const (
+	MSG_OK  = 1
+	MSG_ERR = 0
+)

+ 210 - 0
controllers/backgroundc/admin.go

@@ -0,0 +1,210 @@
+/**********************************************
+** @Des: 管理员
+** @Author: haodaquan
+** @Date:   2017-09-16 14:17:37
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 11:14:07
+***********************************************/
+package backgroundc
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/libs"
+	"wuyebaoxiuapi/models/backgroundm"
+)
+
+type AdminController struct {
+	BaseController
+}
+
+func (self *AdminController) List() {
+	self.Data["pageTitle"] = "管理员管理"
+	self.display()
+	//self.TplName = "admin/list.html"
+}
+
+func (self *AdminController) Add() {
+	self.Data["pageTitle"] = "新增管理员"
+
+	// 角色
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	result, _ := backgroundm.RoleGetList(1, 1000, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["role_name"] = v.RoleName
+		list[k] = row
+	}
+
+	self.Data["role"] = list
+
+	self.display()
+}
+
+func (self *AdminController) Edit() {
+	self.Data["pageTitle"] = "编辑管理员"
+
+	id, _ := self.GetInt("id", 0)
+	Admin, _ := backgroundm.AdminGetById(id)
+	row := make(map[string]interface{})
+	row["id"] = Admin.Id
+	row["login_name"] = Admin.LoginName
+	row["real_name"] = Admin.RealName
+	row["phone"] = Admin.Phone
+	row["email"] = Admin.Email
+	row["role_ids"] = Admin.RoleIds
+	self.Data["admin"] = row
+
+	role_ids := strings.Split(Admin.RoleIds, ",")
+
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	result, _ := backgroundm.RoleGetList(1, 1000, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["checked"] = 0
+		for i := 0; i < len(role_ids); i++ {
+			role_id, _ := strconv.Atoi(role_ids[i])
+			if role_id == v.Id {
+				row["checked"] = 1
+			}
+			fmt.Println(role_ids[i])
+		}
+		row["id"] = v.Id
+		row["role_name"] = v.RoleName
+		list[k] = row
+	}
+	self.Data["role"] = list
+	self.display()
+}
+
+func (self *AdminController) AjaxSave() {
+	Admin_id, _ := self.GetInt("id")
+	if Admin_id == 0 {
+		Admin := new(backgroundm.Admin)
+		Admin.LoginName = strings.TrimSpace(self.GetString("login_name"))
+		Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
+		Admin.Phone = strings.TrimSpace(self.GetString("phone"))
+		Admin.Email = strings.TrimSpace(self.GetString("email"))
+		Admin.RoleIds = strings.TrimSpace(self.GetString("roleids"))
+		Admin.UpdateTime = time.Now().Unix()
+		Admin.UpdateId = self.userId
+		Admin.Status = 1
+
+		// 检查登录名是否已经存在
+		_, err := backgroundm.AdminGetByName(Admin.LoginName)
+
+		if err == nil {
+			self.ajaxMsg("登录名已经存在", MSG_ERR)
+		}
+		//新增
+		pwd, salt := libs.Password(4, "")
+		Admin.Password = pwd
+		Admin.Salt = salt
+		Admin.CreateTime = time.Now().Unix()
+		Admin.CreateId = self.userId
+		if _, err := backgroundm.AdminAdd(Admin); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+
+	Admin, _ := backgroundm.AdminGetById(Admin_id)
+	//修改
+	Admin.Id = Admin_id
+	Admin.UpdateTime = time.Now().Unix()
+	Admin.UpdateId = self.userId
+	Admin.LoginName = strings.TrimSpace(self.GetString("login_name"))
+	Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
+	Admin.Phone = strings.TrimSpace(self.GetString("phone"))
+	Admin.Email = strings.TrimSpace(self.GetString("email"))
+	Admin.RoleIds = strings.TrimSpace(self.GetString("roleids"))
+	Admin.UpdateTime = time.Now().Unix()
+	Admin.UpdateId = self.userId
+	Admin.Status = 1
+
+	resetPwd, _ := self.GetInt("reset_pwd")
+	if resetPwd == 1 {
+		pwd, salt := libs.Password(4, "")
+		Admin.Password = pwd
+		Admin.Salt = salt
+	}
+	if err := Admin.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg(strconv.Itoa(resetPwd), MSG_OK)
+}
+
+func (self *AdminController) AjaxDel() {
+
+	Admin_id, _ := self.GetInt("id")
+	status := strings.TrimSpace(self.GetString("status"))
+	if Admin_id == 1 {
+		self.ajaxMsg("超级管理员不允许操作", MSG_ERR)
+	}
+
+	Admin_status := 0
+	if status == "enable" {
+		Admin_status = 1
+	}
+	Admin, _ := backgroundm.AdminGetById(Admin_id)
+	Admin.UpdateTime = time.Now().Unix()
+	Admin.Status = Admin_status
+	Admin.Id = Admin_id
+
+	if err := Admin.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("操作成功", MSG_OK)
+}
+
+func (self *AdminController) Table() {
+	//列表
+	page, err := self.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := self.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+
+	realName := strings.TrimSpace(self.GetString("realName"))
+
+	StatusText := make(map[int]string)
+	StatusText[0] = "<font color='red'>禁用</font>"
+	StatusText[1] = "正常"
+
+	self.pageSize = limit
+	//查询条件
+	filters := make([]interface{}, 0)
+	//
+	if realName != "" {
+		filters = append(filters, "real_name__icontains", realName)
+	}
+	result, count := backgroundm.AdminGetList(page, self.pageSize, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["login_name"] = v.LoginName
+		row["real_name"] = v.RealName
+		row["phone"] = v.Phone
+		row["email"] = v.Email
+		row["role_ids"] = v.RoleIds
+		row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+		row["status"] = v.Status
+		row["status_text"] = StatusText[v.Status]
+		list[k] = row
+	}
+	self.ajaxList("成功", MSG_OK, count, list)
+}

+ 267 - 0
controllers/backgroundc/api.go

@@ -0,0 +1,267 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-08 17:48:30
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-09 18:50:41
+***********************************************/
+package backgroundc
+
+import (
+	"fmt"
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+)
+
+var (
+	AUDIT_STATUS = [5]string{"<span class='layui-badge layui-bg-black'>暂停使用</span>",
+		"<span class='layui-badge layui-bg-orange'>正在开发</span>",
+		"<span class='layui-badge layui-bg-blue'>正在审核</span>",
+		"<span class='layui-badge layui-bg-green'>审核通过</span>",
+		"<span class='layui-badge'>未通过</span>"}
+	AUDIT_STATUS_TEXT = [5]string{"暂停使用",
+		"正在开发",
+		"正在审核",
+		"审核通过",
+		"未通过"}
+	REQUEST_METHOD = [6]string{"未知", "GET", "POST", "PUT", "PATCH", "DELETE"}
+)
+
+type ApiController struct {
+	BaseController
+}
+
+func (self *ApiController) List() {
+	self.Data["pageTitle"] = "API接口"
+	self.Data["ApiCss"] = true
+	self.Data["auditStatus"] = AUDIT_STATUS_TEXT
+	self.display()
+}
+
+func (self *ApiController) Table() {
+	//列表
+	page, err := self.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := self.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+
+	apiName := strings.TrimSpace(self.GetString("apiName"))
+	status, _ := self.GetInt("status", -1)
+
+	//获取分组
+	sourceList := sourceLists()
+
+	self.pageSize = limit
+	//查询条件
+	filters := make([]interface{}, 0)
+	if status != -1 {
+		filters = append(filters, "status", status)
+	} else {
+		filters = append(filters, "status__in", []int{0, 1, 2, 3, 4})
+	}
+
+	if apiName != "" {
+		filters = append(filters, "api_name__icontains", apiName)
+	}
+	result, count := backgroundm.ApiDetailGetList(page, self.pageSize, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["api_name"] = v.ApiName
+		row["api_url"] = v.ApiUrl
+		row["status_text"] = AUDIT_STATUS[v.Status]
+		row["status"] = v.Status
+		row["method"] = REQUEST_METHOD[v.Method]
+		sourceInfo := getSourceInfo(sourceList, v.SourceId)
+		row["source_name"] = sourceInfo.SourceName
+		row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+		list[k] = row
+	}
+	self.ajaxList("成功", MSG_OK, count, list)
+}
+
+//查看详情
+func (self *ApiController) Detail() {
+	self.Data["ApiCss"] = true
+	id, _ := self.GetInt("id", 0)
+	detail, _ := backgroundm.ApiFullDetailById(id)
+	row := make(map[string]interface{})
+	row["id"] = detail.Id
+	row["source_id"] = detail.SourceId
+	row["api_url"] = detail.ApiUrl
+	row["api_name"] = detail.ApiName
+	row["detail"] = detail.Detail
+	row["status"] = detail.Status
+	row["create_name"] = detail.CreateName
+	row["update_name"] = detail.UpdateName
+	row["audit_name"] = detail.AuditName
+	row["audit_status"] = AUDIT_STATUS[detail.Status]
+	row["method"] = REQUEST_METHOD[detail.Method]
+	row["audit_time"] = beego.Date(time.Unix(detail.AuditTime, 0), "Y-m-d H:i:s")
+	row["update_time"] = beego.Date(time.Unix(detail.UpdateTime, 0), "Y-m-d H:i:s")
+
+	self.Data["pageTitle"] = "查看 " + detail.ApiName
+	self.Data["Detail"] = row
+	self.display()
+}
+
+//审核
+func (self *ApiController) Audit() {
+	self.Data["ApiCss"] = true
+	id, _ := self.GetInt("id", 0)
+	detail, _ := backgroundm.ApiFullDetailById(id)
+	row := make(map[string]interface{})
+	row["id"] = detail.Id
+	row["source_id"] = detail.SourceId
+	row["api_url"] = detail.ApiUrl
+	row["api_name"] = detail.ApiName
+	row["detail"] = detail.Detail
+	row["status"] = detail.Status
+	row["create_name"] = detail.CreateName
+	row["update_name"] = detail.UpdateName
+	row["audit_name"] = detail.AuditName
+	row["audit_status"] = AUDIT_STATUS[detail.Status]
+	row["method"] = REQUEST_METHOD[detail.Method]
+	row["audit_time"] = beego.Date(time.Unix(detail.AuditTime, 0), "Y-m-d H:i:s")
+	row["update_time"] = beego.Date(time.Unix(detail.UpdateTime, 0), "Y-m-d H:i:s")
+
+	self.Data["pageTitle"] = "审核 " + detail.ApiName
+	self.Data["Detail"] = row
+	self.display()
+}
+
+func (self *ApiController) AjaxDel() {
+
+	Api_id, _ := self.GetInt("id")
+	Api, _ := backgroundm.ApiDetailGetById(Api_id)
+	Api.UpdateTime = time.Now().Unix()
+	Api.UpdateId = self.userId
+
+	if Api.Status == 0 {
+		Api.Status = 1
+	} else {
+		Api.Status = 0
+	}
+
+	Api.Id = Api_id
+
+	//TODO 判断是否暂用API
+
+	if err := Api.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+func (self *ApiController) AjaxChangeStatus() {
+	Api_ids := strings.TrimSpace(self.GetString("ids"))
+	status, _ := self.GetInt("status")
+
+	if status == 1 {
+		status = 2
+	}
+	_, err := backgroundm.ApiChangeStatus(Api_ids, status)
+
+	if err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+//新增接口实例
+func (self *ApiController) Add() {
+	self.Data["pageTitle"] = "添加接口"
+	// //分组
+	// groupList := groupLists()
+	// self.Data["groupList"] = groupList
+	//资源
+	sourceList := sourceLists()
+	self.Data["sourceList"] = sourceList
+	fmt.Println(sourceList)
+	tmplates := templateLists()
+	self.Data["templates"] = tmplates
+
+	self.display()
+}
+
+//修改接口实例
+func (self *ApiController) Edit() {
+	self.Data["ApiCss"] = true
+	id, _ := self.GetInt("id", 0)
+	detail, _ := backgroundm.ApiFullDetailById(id)
+	row := make(map[string]interface{})
+	row["id"] = detail.Id
+	row["source_id"] = detail.SourceId
+	row["api_url"] = detail.ApiUrl
+	row["api_name"] = detail.ApiName
+	row["detail"] = detail.Detail
+	row["status"] = detail.Status
+	row["create_name"] = detail.CreateName
+	row["update_name"] = detail.UpdateName
+	row["audit_name"] = detail.AuditName
+	row["audit_status"] = AUDIT_STATUS[detail.Status]
+	row["method"] = detail.Method
+	row["audit_time"] = beego.Date(time.Unix(detail.AuditTime, 0), "Y-m-d H:i:s")
+	row["update_time"] = beego.Date(time.Unix(detail.UpdateTime, 0), "Y-m-d H:i:s")
+
+	self.Data["pageTitle"] = "查看 " + detail.ApiName
+	self.Data["Detail"] = row
+
+	sourceList := sourceLists()
+	self.Data["sourceList"] = sourceList
+
+	tmplates := templateLists()
+	self.Data["templates"] = tmplates
+
+	self.display()
+}
+
+func (self *ApiController) AjaxSave() {
+
+	Api_id, _ := self.GetInt("id")
+	if Api_id == 0 {
+		ApiDetail := new(backgroundm.ApiDetail)
+		ApiDetail.SourceId, _ = self.GetInt("source_id")
+		ApiDetail.Method, _ = self.GetInt("method")
+		ApiDetail.ApiName = strings.TrimSpace(self.GetString("api_name"))
+		ApiDetail.ApiUrl = strings.TrimSpace(self.GetString("api_url"))
+		ApiDetail.Detail = strings.TrimSpace(self.GetString("detail"))
+		ApiDetail.CreateId = self.userId
+		ApiDetail.UpdateId = self.userId
+		ApiDetail.CreateTime = time.Now().Unix()
+		ApiDetail.UpdateTime = time.Now().Unix()
+		ApiDetail.Status = 1
+		_, err := backgroundm.ApiDetailAdd(ApiDetail)
+		if err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+	//修改
+	ApiDetail, _ := backgroundm.ApiDetailGetById(Api_id)
+	ApiDetail.SourceId, _ = self.GetInt("source_id")
+	ApiDetail.Id, _ = self.GetInt("id")
+	ApiDetail.Method, _ = self.GetInt("method")
+	ApiDetail.ApiName = strings.TrimSpace(self.GetString("api_name"))
+	ApiDetail.ApiUrl = strings.TrimSpace(self.GetString("api_url"))
+	ApiDetail.Detail = strings.TrimSpace(self.GetString("detail"))
+
+	ApiDetail.UpdateId = self.userId
+	ApiDetail.UpdateTime = time.Now().Unix()
+	ApiDetail.Status, _ = self.GetInt("status")
+
+	ApiDetail.Status = 1
+	if err := ApiDetail.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}

+ 100 - 0
controllers/backgroundc/apidoc.go

@@ -0,0 +1,100 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-08 17:48:30
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-09 18:50:41
+***********************************************/
+package backgroundc
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+)
+
+type ApiDocController struct {
+	BaseController
+}
+
+func (self *ApiDocController) Index() {
+	self.Data["pageTitle"] = "API文档"
+	self.Data["ts"] = time.Now()
+
+	grouplists := groupLists()
+	self.Data["grouplists"] = grouplists
+
+	groupId, _ := self.GetInt("id", 1)
+	groupInfo, err := backgroundm.GroupGetById(groupId)
+
+	if err != nil {
+		fmt.Println("数据不存在")
+	}
+
+	//公共文档
+	apiPublic, err := backgroundm.ApiPublicGetByIds(groupInfo.ApiPublicIds)
+	self.Data["apiPublic"] = apiPublic
+
+	//环境
+	// env, err := models.EnvGetByIds(groupInfo.EnvIds)
+	// self.Data["env"] = env
+
+	// //状态码
+	// code, err := models.CodeGetByIds(groupInfo.CodeIds)
+	// self.Data["code"] = code
+
+	//接口
+	apiMenu, _ := backgroundm.ApiTreeData(groupId)
+	self.Data["apiMenu"] = apiMenu
+	self.Data["groupId"] = groupId
+
+	self.TplName = "apidoc/index.html"
+}
+
+func (self *ApiDocController) Public() {
+	apiPublicId, _ := self.GetInt("id", 1)
+	apiPublic, _ := backgroundm.ApiPublicGetById(apiPublicId)
+	self.Data["apiPublic"] = apiPublic
+	self.TplName = "apidoc/apipublic.html"
+}
+
+func (self *ApiDocController) Env() {
+	groupId, _ := self.GetInt("id", 0)
+	groupInfo, _ := backgroundm.GroupGetById(groupId)
+	env, _ := backgroundm.EnvGetByIds(groupInfo.EnvIds)
+	self.Data["env"] = env
+	self.TplName = "apidoc/env.html"
+}
+
+func (self *ApiDocController) Code() {
+	groupId, _ := self.GetInt("id", 0)
+	groupInfo, _ := backgroundm.GroupGetById(groupId)
+	code, _ := backgroundm.CodeGetByIds(groupInfo.CodeIds)
+	self.Data["code"] = code
+	self.TplName = "apidoc/code.html"
+}
+
+func (self *ApiDocController) ApiDetail() {
+	id, _ := self.GetInt("id", 0)
+	detail, _ := backgroundm.ApiFullDetailById(id)
+	row := make(map[string]interface{})
+	row["id"] = detail.Id
+	row["source_id"] = detail.SourceId
+	row["api_url"] = detail.ApiUrl
+	row["api_name"] = detail.ApiName
+	row["detail"] = detail.Detail
+	row["status"] = detail.Status
+	row["create_name"] = detail.CreateName
+	row["update_name"] = detail.UpdateName
+	row["audit_name"] = detail.AuditName
+	row["audit_status"] = AUDIT_STATUS[detail.Status]
+	row["method"] = REQUEST_METHOD[detail.Method]
+	row["audit_time"] = beego.Date(time.Unix(detail.AuditTime, 0), "Y-m-d H:i:s")
+	row["update_time"] = beego.Date(time.Unix(detail.UpdateTime, 0), "Y-m-d H:i:s")
+
+	self.Data["pageTitle"] = "查看 " + detail.ApiName
+	self.Data["Detail"] = row
+	self.TplName = "apidoc/apidetail.html"
+}

+ 17 - 0
controllers/backgroundc/apimonitor.go

@@ -0,0 +1,17 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-08 17:48:30
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-09 18:50:41
+***********************************************/
+package backgroundc
+
+type ApiMonitorController struct {
+	BaseController
+}
+
+func (self *ApiMonitorController) List() {
+	self.Data["pageTitle"] = "API文档"
+	self.display()
+}

+ 139 - 0
controllers/backgroundc/apipublic.go

@@ -0,0 +1,139 @@
+/**********************************************
+** @Des: 公共文档设置
+** @Author: haodaquan
+** @Date:   2018-01-16 17:48:30
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2018-01-16 17:48:30
+***********************************************/
+package backgroundc
+
+import (
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+)
+
+var ()
+
+type ApiPublicController struct {
+	BaseController
+}
+
+func (self *ApiPublicController) List() {
+	self.Data["pageTitle"] = "公共文档"
+	self.display()
+}
+
+func (self *ApiPublicController) Table() {
+	//列表
+	page, err := self.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := self.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+
+	ApiPublicName := strings.TrimSpace(self.GetString("ApiPublicName"))
+
+	self.pageSize = limit
+	//查询条件
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+
+	if ApiPublicName != "" {
+		filters = append(filters, "api_public_name__icontains", ApiPublicName)
+	}
+	result, count := backgroundm.ApiPublicGetList(page, self.pageSize, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["api_public_name"] = v.ApiPublicName
+		row["detail"] = v.Detail
+		row["sort"] = v.Sort
+		row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+		list[k] = row
+	}
+	self.ajaxList("成功", MSG_OK, count, list)
+}
+
+func (self *ApiPublicController) Add() {
+	self.Data["pageTitle"] = "新增公共文档"
+	tmplates := templateLists()
+	self.Data["templates"] = tmplates
+	self.display()
+}
+
+func (self *ApiPublicController) Edit() {
+	id, _ := self.GetInt("id", 0)
+	detail, _ := backgroundm.ApiPublicGetById(id)
+	row := make(map[string]interface{})
+	row["id"] = detail.Id
+	row["api_public_name"] = detail.ApiPublicName
+	row["detail"] = detail.Detail
+	row["sort"] = detail.Sort
+
+	self.Data["pageTitle"] = "查看 " + detail.ApiPublicName
+	self.Data["Detail"] = row
+
+	tmplates := templateLists()
+	self.Data["templates"] = tmplates
+	self.display()
+}
+
+func (self *ApiPublicController) AjaxSave() {
+
+	Pub_id, _ := self.GetInt("id")
+	if Pub_id == 0 {
+		ApiPublic := new(backgroundm.ApiPublic)
+
+		ApiPublic.ApiPublicName = strings.TrimSpace(self.GetString("api_public_name"))
+		ApiPublic.Detail = strings.TrimSpace(self.GetString("detail"))
+		ApiPublic.Sort, _ = self.GetInt("sort", 99)
+		ApiPublic.CreateId = self.userId
+		ApiPublic.UpdateId = self.userId
+		ApiPublic.CreateTime = time.Now().Unix()
+		ApiPublic.UpdateTime = time.Now().Unix()
+		ApiPublic.Status = 1
+		_, err := backgroundm.ApiPublicAdd(ApiPublic)
+		if err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+	//修改
+	ApiPublic, _ := backgroundm.ApiPublicGetById(Pub_id)
+	ApiPublic.Id, _ = self.GetInt("id")
+	ApiPublic.ApiPublicName = strings.TrimSpace(self.GetString("api_public_name"))
+	ApiPublic.Detail = strings.TrimSpace(self.GetString("detail"))
+	ApiPublic.Sort, _ = self.GetInt("sort", 99)
+	ApiPublic.UpdateId = self.userId
+	ApiPublic.UpdateTime = time.Now().Unix()
+	ApiPublic.Status = 1
+	if err := ApiPublic.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+func (self *ApiPublicController) AjaxDel() {
+
+	Pub_id, _ := self.GetInt("id")
+	Api, _ := backgroundm.ApiPublicGetById(Pub_id)
+	Api.UpdateTime = time.Now().Unix()
+	Api.UpdateId = self.userId
+	Api.Status = 0
+	Api.Id = Pub_id
+
+	//TODO 判断是否被使用
+
+	if err := Api.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}

+ 124 - 0
controllers/backgroundc/auth.go

@@ -0,0 +1,124 @@
+/**********************************************
+** @Des: 权限因子
+** @Author: haodaquan
+** @Date:   2017-09-09 16:14:31
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 11:23:40
+***********************************************/
+
+package backgroundc
+
+import (
+	"fmt"
+	"strings"
+	"time"
+
+	"wuyebaoxiuapi/utils"
+
+	"strconv"
+
+	"wuyebaoxiuapi/models/backgroundm"
+	"github.com/patrickmn/go-cache"
+)
+
+type AuthController struct {
+	BaseController
+}
+
+func (self *AuthController) Index() {
+
+	self.Data["pageTitle"] = "权限因子"
+	self.display()
+}
+
+func (self *AuthController) List() {
+	self.Data["zTree"] = true //引入ztreecss
+	self.Data["pageTitle"] = "权限因子"
+	self.display()
+}
+
+//获取全部节点
+func (self *AuthController) GetNodes() {
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	result, count := backgroundm.AuthGetList(1, 1000, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["pId"] = v.Pid
+		row["name"] = v.AuthName
+		row["open"] = true
+		list[k] = row
+	}
+
+	self.ajaxList("成功", MSG_OK, count, list)
+}
+
+//获取一个节点
+func (self *AuthController) GetNode() {
+	id, _ := self.GetInt("id")
+	result, _ := backgroundm.AuthGetById(id)
+	// if err == nil {
+	// 	self.ajaxMsg(err.Error(), MSG_ERR)
+	// }
+	row := make(map[string]interface{})
+	row["id"] = result.Id
+	row["pid"] = result.Pid
+	row["auth_name"] = result.AuthName
+	row["auth_url"] = result.AuthUrl
+	row["sort"] = result.Sort
+	row["is_show"] = result.IsShow
+	row["icon"] = result.Icon
+
+	fmt.Println(row)
+
+	self.ajaxList("成功", MSG_OK, 0, row)
+}
+
+//新增或修改
+func (self *AuthController) AjaxSave() {
+	auth := new(backgroundm.Auth)
+	auth.UserId = self.userId
+	auth.Pid, _ = self.GetInt("pid")
+	auth.AuthName = strings.TrimSpace(self.GetString("auth_name"))
+	auth.AuthUrl = strings.TrimSpace(self.GetString("auth_url"))
+	auth.Sort, _ = self.GetInt("sort")
+	auth.IsShow, _ = self.GetInt("is_show")
+	auth.Icon = strings.TrimSpace(self.GetString("icon"))
+	auth.UpdateTime = time.Now().Unix()
+
+	auth.Status = 1
+
+	id, _ := self.GetInt("id")
+	if id == 0 {
+		//新增
+		auth.CreateTime = time.Now().Unix()
+		auth.CreateId = self.userId
+		auth.UpdateId = self.userId
+		if _, err := backgroundm.AuthAdd(auth); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+	} else {
+		auth.Id = id
+		auth.UpdateId = self.userId
+		if err := auth.Update(); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+	}
+	utils.Che.Set("menu"+strconv.Itoa(self.user.Id), nil, cache.DefaultExpiration)
+	self.ajaxMsg("", MSG_OK)
+}
+
+//删除
+func (self *AuthController) AjaxDel() {
+	id, _ := self.GetInt("id")
+	auth, _ := backgroundm.AuthGetById(id)
+	auth.Id = id
+	auth.Status = 0
+	if err := auth.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	utils.Che.Set("menu"+strconv.Itoa(self.user.Id), nil, cache.DefaultExpiration)
+	self.ajaxMsg("", MSG_OK)
+}

+ 135 - 0
controllers/backgroundc/code.go

@@ -0,0 +1,135 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-09 12:53:05
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-25 18:50:54
+***********************************************/
+package backgroundc
+
+import (
+	"fmt"
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+)
+
+type CodeController struct {
+	BaseController
+}
+
+func (self *CodeController) List() {
+	self.Data["pageTitle"] = "状态码设置"
+	self.display()
+}
+
+func (self *CodeController) Add() {
+	self.Data["pageTitle"] = "新增状态码"
+	self.display()
+}
+
+func (self *CodeController) Edit() {
+	self.Data["pageTitle"] = "编辑状态码"
+
+	id, _ := self.GetInt("id", 0)
+	Code, _ := backgroundm.CodeGetById(id)
+	row := make(map[string]interface{})
+	row["id"] = Code.Id
+	row["code"] = Code.Code
+	row["desc"] = Code.Desc
+	row["detail"] = Code.Detail
+	self.Data["code"] = row
+	self.display()
+}
+
+func (self *CodeController) Table() {
+	//列表
+	page, err := self.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := self.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+	code := strings.TrimSpace(self.GetString("code"))
+
+	self.pageSize = limit
+	//查询条件
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	if code != "" {
+		filters = append(filters, "code", code)
+	}
+	result, count := backgroundm.CodeGetList(page, self.pageSize, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["code"] = v.Code
+		row["detail"] = v.Detail
+		row["desc"] = v.Desc
+		row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+		list[k] = row
+	}
+	self.ajaxList("成功", MSG_OK, count, list)
+}
+
+func (self *CodeController) AjaxSave() {
+	Code_id, _ := self.GetInt("id")
+	if Code_id == 0 {
+		Code := new(backgroundm.Code)
+
+		Code.Code = strings.TrimSpace(self.GetString("code"))
+		Code.Desc = strings.TrimSpace(self.GetString("desc"))
+		Code.Detail = strings.TrimSpace(self.GetString("detail"))
+		Code.CreateId = self.userId
+		Code.UpdateId = self.userId
+		Code.CreateTime = time.Now().Unix()
+		Code.UpdateTime = time.Now().Unix()
+		Code.Status = 1
+
+		res, err := backgroundm.CodeGetByName(Code.Code)
+		fmt.Println(res)
+		if err == nil {
+			self.ajaxMsg("状态码已经存在", MSG_ERR)
+		}
+
+		if _, err := backgroundm.CodeAdd(Code); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+
+	CodeUpdate, _ := backgroundm.CodeGetById(Code_id)
+	// 修改
+	CodeUpdate.Code = strings.TrimSpace(self.GetString("code"))
+	CodeUpdate.Desc = strings.TrimSpace(self.GetString("desc"))
+	CodeUpdate.Detail = strings.TrimSpace(self.GetString("detail"))
+	CodeUpdate.UpdateId = self.userId
+	CodeUpdate.UpdateTime = time.Now().Unix()
+	CodeUpdate.Status = 1
+
+	if err := CodeUpdate.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+func (self *CodeController) AjaxDel() {
+
+	Code_id, _ := self.GetInt("id")
+	Code, _ := backgroundm.CodeGetById(Code_id)
+	Code.UpdateTime = time.Now().Unix()
+	Code.UpdateId = self.userId
+	Code.Status = 0
+	Code.Id = Code_id
+
+	if err := Code.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}

+ 384 - 0
controllers/backgroundc/common.go

@@ -0,0 +1,384 @@
+/**********************************************
+** @Des: base controller
+** @Author: haodaquan
+** @Date:   2017-09-07 16:54:40
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-18 10:28:01
+***********************************************/
+package backgroundc
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+
+	"wuyebaoxiuapi/libs"
+	"wuyebaoxiuapi/utils"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+	"github.com/patrickmn/go-cache"
+)
+
+const (
+	MSG_OK  = 0
+	MSG_ERR = -1
+)
+
+type BaseController struct {
+	beego.Controller
+	controllerName string
+	actionName     string
+	user           *backgroundm.Admin
+	userId         int
+	userName       string
+	loginName      string
+	pageSize       int
+	allowUrl       string
+}
+
+//前期准备
+func (self *BaseController) Prepare() {
+	self.pageSize = 20
+	controllerName, actionName := self.GetControllerAndAction()
+	self.controllerName = strings.ToLower(controllerName[0 : len(controllerName)-10])
+	self.actionName = strings.ToLower(actionName)
+	self.Data["version"] = beego.AppConfig.String("version")
+	self.Data["siteName"] = beego.AppConfig.String("site.name")
+	self.Data["curRoute"] = self.controllerName + "." + self.actionName
+	self.Data["curController"] = self.controllerName
+	self.Data["curAction"] = self.actionName
+	// noAuth := "ajaxsave/ajaxdel/table/loginin/loginout/getnodes/start"
+	// isNoAuth := strings.Contains(noAuth, self.actionName)
+	fmt.Println(self.controllerName)
+	if (strings.Compare(self.controllerName, "apidoc")) != 0 {
+		self.auth()
+	}
+
+	self.Data["loginUserId"] = self.userId
+	self.Data["loginUserName"] = self.userName
+}
+
+//登录权限验证
+func (self *BaseController) auth() {
+	arr := strings.Split(self.Ctx.GetCookie("auth"), "|")
+	self.userId = 0
+	if len(arr) == 2 {
+		idstr, password := arr[0], arr[1]
+		userId, _ := strconv.Atoi(idstr)
+		if userId > 0 {
+			var err error
+
+			cheUser, found := utils.Che.Get("uid" + strconv.Itoa(userId))
+			user := &backgroundm.Admin{}
+			if found && cheUser != nil { //从缓存取用户
+				user = cheUser.(*backgroundm.Admin)
+			} else {
+				user, err = backgroundm.AdminGetById(userId)
+				utils.Che.Set("uid"+strconv.Itoa(userId), user, cache.DefaultExpiration)
+			}
+			if err == nil && password == libs.Md5([]byte(self.getClientIp()+"|"+user.Password+user.Salt)) {
+				self.userId = user.Id
+
+				self.loginName = user.LoginName
+				self.userName = user.RealName
+				self.user = user
+				self.AdminAuth()
+			}
+
+			isHasAuth := strings.Contains(self.allowUrl, self.controllerName+"/"+self.actionName)
+			//不需要权限检查
+			noAuth := "ajaxsave/ajaxdel/table/loginin/loginout/getnodes/start/show/ajaxapisave/index/group/public/env/code/apidetail"
+			isNoAuth := strings.Contains(noAuth, self.actionName)
+			if isHasAuth == false && isNoAuth == false {
+				self.Ctx.WriteString("没有权限")
+				self.ajaxMsg("没有权限", MSG_ERR)
+				return
+			}
+		}
+	}
+
+	if self.userId == 0 && (self.controllerName != "login" && self.actionName != "loginin") {
+		self.redirect(beego.URLFor("LoginController.LoginIn"))
+	}
+}
+
+func (self *BaseController) AdminAuth() {
+	cheMen, found := utils.Che.Get("menu" + strconv.Itoa(self.user.Id))
+	if found && cheMen != nil { //从缓存取菜单
+		menu := cheMen.(*CheMenu)
+		//fmt.Println("调用显示菜单")
+		self.Data["SideMenu1"] = menu.List1 //一级菜单
+		self.Data["SideMenu2"] = menu.List2 //二级菜单
+		self.allowUrl = menu.AllowUrl
+	} else {
+		// 左侧导航栏
+		filters := make([]interface{}, 0)
+		filters = append(filters, "status", 1)
+		if self.userId != 1 {
+			//普通管理员
+			adminAuthIds, _ := backgroundm.RoleAuthGetByIds(self.user.RoleIds)
+			adminAuthIdArr := strings.Split(adminAuthIds, ",")
+			filters = append(filters, "id__in", adminAuthIdArr)
+		}
+		result, _ := backgroundm.AuthGetList(1, 1000, filters...)
+		list := make([]map[string]interface{}, len(result))
+		list2 := make([]map[string]interface{}, len(result))
+		allow_url := ""
+		i, j := 0, 0
+		for _, v := range result {
+			if v.AuthUrl != " " || v.AuthUrl != "/" {
+				allow_url += v.AuthUrl
+			}
+			row := make(map[string]interface{})
+			if v.Pid == 1 && v.IsShow == 1 {
+				row["Id"] = int(v.Id)
+				row["Sort"] = v.Sort
+				row["AuthName"] = v.AuthName
+				row["AuthUrl"] = v.AuthUrl
+				row["Icon"] = v.Icon
+				row["Pid"] = int(v.Pid)
+				list[i] = row
+				i++
+			}
+			if v.Pid != 1 && v.IsShow == 1 {
+				row["Id"] = int(v.Id)
+				row["Sort"] = v.Sort
+				row["AuthName"] = v.AuthName
+				row["AuthUrl"] = v.AuthUrl
+				row["Icon"] = v.Icon
+				row["Pid"] = int(v.Pid)
+				list2[j] = row
+				j++
+			}
+		}
+		self.Data["SideMenu1"] = list[:i]  //一级菜单
+		self.Data["SideMenu2"] = list2[:j] //二级菜单
+
+		self.allowUrl = allow_url + "/home/index"
+		cheM := &CheMenu{}
+		cheM.AllowUrl = self.allowUrl
+		cheM.List1 = self.Data["SideMenu1"].([]map[string]interface{})
+		cheM.List2 = self.Data["SideMenu2"].([]map[string]interface{})
+		utils.Che.Set("menu"+strconv.Itoa(self.user.Id), cheM, cache.DefaultExpiration)
+	}
+
+}
+
+type CheMenu struct {
+	List1    []map[string]interface{}
+	List2    []map[string]interface{}
+	AllowUrl string
+}
+
+// 是否POST提交
+func (self *BaseController) isPost() bool {
+	return self.Ctx.Request.Method == "POST"
+}
+
+//获取用户IP地址
+func (self *BaseController) getClientIp() string {
+	s := self.Ctx.Request.RemoteAddr
+	l := strings.LastIndex(s, ":")
+	return s[0:l]
+}
+
+// 重定向
+func (self *BaseController) redirect(url string) {
+	self.Redirect(url, 302)
+	self.StopRun()
+}
+
+//加载模板
+func (self *BaseController) display(tpl ...string) {
+	var tplname string
+	if len(tpl) > 0 {
+		tplname = strings.Join([]string{tpl[0], "html"}, ".")
+	} else {
+		tplname = self.controllerName + "/" + self.actionName + ".html"
+	}
+	self.Layout = "public/layout.html"
+	self.TplName = tplname
+}
+
+//ajax返回
+func (self *BaseController) ajaxMsg(msg interface{}, msgno int) {
+	out := make(map[string]interface{})
+	out["status"] = msgno
+	out["message"] = msg
+	self.Data["json"] = out
+	self.ServeJSON()
+	self.StopRun()
+}
+
+//ajax返回 列表
+func (self *BaseController) ajaxList(msg interface{}, msgno int, count int64, data interface{}) {
+	out := make(map[string]interface{})
+	out["code"] = msgno
+	out["msg"] = msg
+	out["count"] = count
+	out["data"] = data
+	self.Data["json"] = out
+	self.ServeJSON()
+	self.StopRun()
+}
+
+//分组公共方法
+type groupList struct {
+	Id        int
+	GroupName string
+}
+
+func groupLists() (gl []groupList) {
+	groupFilters := make([]interface{}, 0)
+	groupFilters = append(groupFilters, "status", 1)
+	groupResult, _ := backgroundm.GroupGetList(1, 1000, groupFilters...)
+	for _, gv := range groupResult {
+		groupRow := groupList{}
+		groupRow.Id = int(gv.Id)
+		groupRow.GroupName = gv.GroupName
+		gl = append(gl, groupRow)
+	}
+	return gl
+}
+
+//获取单个分组信息
+func getGroupInfo(gl []groupList, groupId int) (groupInfo groupList) {
+	for _, v := range gl {
+		if v.Id == groupId {
+			groupInfo = v
+		}
+	}
+	return
+}
+
+type sourceList struct {
+	Id         int
+	SourceName string
+	GroupId    int
+	GroupName  string
+}
+
+func sourceLists() (sl []sourceList) {
+
+	grouplists := groupLists()
+	var groupinfo groupList
+	sourceFilters := make([]interface{}, 0)
+	sourceFilters = append(sourceFilters, "status", 1)
+	sourceResult, _ := backgroundm.ApiSourceGetList(1, 1000, sourceFilters...)
+	for _, sv := range sourceResult {
+		sourceRow := sourceList{}
+		sourceRow.Id = int(sv.Id)
+		sourceRow.GroupId = sv.GroupId
+		groupinfo = getGroupInfo(grouplists, sv.GroupId)
+		sourceRow.GroupName = groupinfo.GroupName
+		sourceRow.SourceName = sv.SourceName
+		sl = append(sl, sourceRow)
+	}
+	return sl
+}
+
+func getSourceInfo(gl []sourceList, sourceId int) (sourceInfo sourceList) {
+	for _, v := range gl {
+		if v.Id == sourceId {
+			sourceInfo = v
+		}
+	}
+	return
+}
+
+type envList struct {
+	Id      int
+	EnvName string
+	EnvHost string
+}
+
+func envLists() (sl []envList) {
+	envFilters := make([]interface{}, 0)
+	envFilters = append(envFilters, "status__in", 1)
+	envResult, _ := backgroundm.EnvGetList(1, 1000, envFilters...)
+	for _, sv := range envResult {
+		envRow := envList{}
+		envRow.Id = int(sv.Id)
+		envRow.EnvName = sv.EnvName
+		envRow.EnvHost = sv.EnvHost
+		sl = append(sl, envRow)
+	}
+	return sl
+}
+
+type templateList struct {
+	Id           int
+	TemplateName string
+	Detail       string
+}
+
+func templateLists() (sl []templateList) {
+	templateFilters := make([]interface{}, 0)
+	templateFilters = append(templateFilters, "status", 1)
+	templateResult, _ := backgroundm.TemplateGetList(1, 1000, templateFilters...)
+	for _, sv := range templateResult {
+		templateRow := templateList{}
+		templateRow.Id = int(sv.Id)
+		templateRow.TemplateName = sv.TemplateName
+		templateRow.Detail = sv.Detail
+		sl = append(sl, templateRow)
+	}
+	return sl
+}
+
+type codeList struct {
+	Id     int
+	Code   string
+	Desc   string
+	Detail string
+}
+
+func codeLists() (sl []codeList) {
+	codeFilters := make([]interface{}, 0)
+	codeFilters = append(codeFilters, "status", 1)
+	codeResult, _ := backgroundm.CodeGetList(1, 1000, codeFilters...)
+	for _, sv := range codeResult {
+		codeRow := codeList{}
+		codeRow.Id = int(sv.Id)
+		codeRow.Code = sv.Code
+		codeRow.Desc = sv.Desc
+		codeRow.Detail = sv.Detail
+		sl = append(sl, codeRow)
+	}
+	return sl
+}
+
+type apiPublicList struct {
+	Id            int
+	ApiPublicName string
+	Sort          int
+}
+
+func apiPublicLists() (sl []apiPublicList) {
+	apiPublicFilters := make([]interface{}, 0)
+	apiPublicFilters = append(apiPublicFilters, "status", 1)
+	apiPublicResult, _ := backgroundm.ApiPublicGetList(1, 1000, apiPublicFilters...)
+	for _, sv := range apiPublicResult {
+		apiPublicRow := apiPublicList{}
+		apiPublicRow.Id = int(sv.Id)
+		apiPublicRow.ApiPublicName = sv.ApiPublicName
+		apiPublicRow.Sort = sv.Sort
+		sl = append(sl, apiPublicRow)
+	}
+	return sl
+}
+
+type UploadController struct {
+	beego.Controller
+}
+
+
+func (self *UploadController)UploadImage() {
+	url := self.GetString("value")
+	imageUpload := libs.NewImageUpload()
+	result := imageUpload.Upload(url)
+	self.Data["json"] = result
+	self.ServeJSON()
+	self.StopRun()
+}

+ 134 - 0
controllers/backgroundc/env.go

@@ -0,0 +1,134 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-09 12:53:05
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-25 18:50:54
+***********************************************/
+package backgroundc
+
+import (
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+)
+
+type EnvController struct {
+	BaseController
+}
+
+func (self *EnvController) List() {
+	self.Data["pageTitle"] = "环境设置"
+	self.display()
+}
+
+func (self *EnvController) Add() {
+	self.Data["pageTitle"] = "新增环境"
+	self.display()
+}
+
+func (self *EnvController) Edit() {
+	self.Data["pageTitle"] = "编辑环境"
+
+	id, _ := self.GetInt("id", 0)
+	Env, _ := backgroundm.EnvGetById(id)
+	row := make(map[string]interface{})
+	row["id"] = Env.Id
+	row["env_name"] = Env.EnvName
+	row["env_host"] = Env.EnvHost
+	row["detail"] = Env.Detail
+	self.Data["env"] = row
+	self.display()
+}
+
+func (self *EnvController) Table() {
+	//列表
+	page, err := self.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := self.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+	envName := strings.TrimSpace(self.GetString("envName"))
+
+	self.pageSize = limit
+	//查询条件
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	if envName != "" {
+		filters = append(filters, "env_name__icontains", envName)
+	}
+	result, count := backgroundm.EnvGetList(page, self.pageSize, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["env_name"] = v.EnvName
+		row["detail"] = v.Detail
+		row["env_host"] = v.EnvHost
+		row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+		list[k] = row
+	}
+	self.ajaxList("成功", MSG_OK, count, list)
+}
+
+func (self *EnvController) AjaxSave() {
+	Env_id, _ := self.GetInt("id")
+	if Env_id == 0 {
+		Env := new(backgroundm.Env)
+
+		Env.EnvName = strings.TrimSpace(self.GetString("env_name"))
+		Env.EnvHost = strings.TrimSpace(self.GetString("env_host"))
+		Env.Detail = strings.TrimSpace(self.GetString("detail"))
+		Env.CreateId = self.userId
+		Env.UpdateId = self.userId
+		Env.CreateTime = time.Now().Unix()
+		Env.UpdateTime = time.Now().Unix()
+		Env.Status = 1
+
+		_, err := backgroundm.EnvGetByName(Env.EnvName)
+
+		if err == nil {
+			self.ajaxMsg("环境名称已经存在", MSG_ERR)
+		}
+
+		if _, err := backgroundm.EnvAdd(Env); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+
+	EnvUpdate, _ := backgroundm.EnvGetById(Env_id)
+	// 修改
+	EnvUpdate.EnvName = strings.TrimSpace(self.GetString("env_name"))
+	EnvUpdate.EnvHost = strings.TrimSpace(self.GetString("env_host"))
+	EnvUpdate.Detail = strings.TrimSpace(self.GetString("detail"))
+	EnvUpdate.UpdateId = self.userId
+	EnvUpdate.UpdateTime = time.Now().Unix()
+	EnvUpdate.Status = 1
+
+	if err := EnvUpdate.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+func (self *EnvController) AjaxDel() {
+
+	Env_id, _ := self.GetInt("id")
+	Env, _ := backgroundm.EnvGetById(Env_id)
+	Env.UpdateTime = time.Now().Unix()
+	Env.UpdateId = self.userId
+	Env.Status = 0
+	Env.Id = Env_id
+
+	if err := Env.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}

+ 163 - 0
controllers/backgroundc/group.go

@@ -0,0 +1,163 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-09 12:53:05
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-24 18:50:54
+***********************************************/
+package backgroundc
+
+import (
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+
+)
+
+type GroupController struct {
+	BaseController
+}
+
+func (self *GroupController) List() {
+	self.Data["pageTitle"] = "分组设置"
+	self.display()
+}
+
+func (self *GroupController) Add() {
+	self.Data["pageTitle"] = "新增分组"
+	envlists := envLists()
+	self.Data["envlists"] = envlists
+
+	codelists := codeLists()
+	self.Data["codelists"] = codelists
+
+	apiPublicLists := apiPublicLists()
+	self.Data["apiPublicLists"] = apiPublicLists
+
+	self.display()
+}
+
+func (self *GroupController) Edit() {
+	self.Data["pageTitle"] = "编辑分组"
+
+	id, _ := self.GetInt("id", 0)
+	group, _ := backgroundm.GroupGetById(id)
+	row := make(map[string]interface{})
+	row["id"] = group.Id
+	row["group_name"] = group.GroupName
+	row["detail"] = group.Detail
+	row["env_ids"] = group.EnvIds
+	row["code_ids"] = group.CodeIds
+	row["api_public_ids"] = group.ApiPublicIds
+	self.Data["group"] = row
+
+	envlists := envLists()
+	self.Data["envlists"] = envlists
+
+	codelists := codeLists()
+	self.Data["codelists"] = codelists
+
+	apiPublicLists := apiPublicLists()
+	self.Data["apiPublicLists"] = apiPublicLists
+
+	self.display()
+}
+
+func (self *GroupController) Table() {
+	//列表
+	page, err := self.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := self.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+
+	groupName := strings.TrimSpace(self.GetString("groupName"))
+
+	self.pageSize = limit
+	//查询条件
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	if groupName != "" {
+		filters = append(filters, "group_name__icontains", groupName)
+	}
+	result, count := backgroundm.GroupGetList(page, self.pageSize, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["group_name"] = v.GroupName
+		row["detail"] = v.Detail
+		row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+		list[k] = row
+	}
+	self.ajaxList("成功", MSG_OK, count, list)
+}
+
+func (self *GroupController) AjaxSave() {
+	Group_id, _ := self.GetInt("id")
+	if Group_id == 0 {
+		Group := new(backgroundm.Group)
+
+		Group.GroupName = strings.TrimSpace(self.GetString("group_name"))
+		Group.Detail = strings.TrimSpace(self.GetString("detail"))
+		Group.CodeIds = strings.TrimSpace(self.GetString("code_ids"))
+		Group.EnvIds = strings.TrimSpace(self.GetString("env_ids"))
+		Group.ApiPublicIds = strings.TrimSpace(self.GetString("api_public_ids"))
+		Group.CreateId = self.userId
+		Group.UpdateId = self.userId
+		Group.CreateTime = time.Now().Unix()
+		Group.UpdateTime = time.Now().Unix()
+		Group.Status = 1
+
+		// 检查登录名是否已经存在
+		_, err := backgroundm.GroupGetByName(Group.GroupName)
+
+		if err == nil {
+			self.ajaxMsg("分组名已经存在", MSG_ERR)
+		}
+
+		if _, err := backgroundm.GroupAdd(Group); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+
+	GroupUpdate, _ := backgroundm.GroupGetById(Group_id)
+	// 修改
+	GroupUpdate.GroupName = strings.TrimSpace(self.GetString("group_name"))
+	GroupUpdate.Detail = strings.TrimSpace(self.GetString("detail"))
+	GroupUpdate.CodeIds = strings.TrimSpace(self.GetString("code_ids"))
+	GroupUpdate.EnvIds = strings.TrimSpace(self.GetString("env_ids"))
+	GroupUpdate.ApiPublicIds = strings.TrimSpace(self.GetString("api_public_ids"))
+	GroupUpdate.UpdateId = self.userId
+	GroupUpdate.UpdateTime = time.Now().Unix()
+	GroupUpdate.Status = 1
+
+	if err := GroupUpdate.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+func (self *GroupController) AjaxDel() {
+
+	Group_id, _ := self.GetInt("id")
+	Group, _ := backgroundm.GroupGetById(Group_id)
+	Group.UpdateTime = time.Now().Unix()
+	Group.UpdateId = self.userId
+	Group.Status = 0
+	Group.Id = Group_id
+
+	//TODO 判断是否暂用分组
+
+	if err := Group.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}

+ 23 - 0
controllers/backgroundc/home.go

@@ -0,0 +1,23 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-08 10:21:13
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-09 18:04:41
+***********************************************/
+package backgroundc
+
+type HomeController struct {
+	BaseController
+}
+
+func (self *HomeController) Index() {
+	self.Data["pageTitle"] = "系统首页"
+	//self.display()
+	self.TplName = "public/main.html"
+}
+
+func (self *HomeController) Start() {
+	self.Data["pageTitle"] = "控制面板"
+	self.display()
+}

+ 73 - 0
controllers/backgroundc/login.go

@@ -0,0 +1,73 @@
+/**********************************************
+** @Des: login
+** @Author: haodaquan
+** @Date:   2017-09-07 16:30:10
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 11:55:21
+***********************************************/
+package backgroundc
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/libs"
+	"wuyebaoxiuapi/models/backgroundm"
+	"wuyebaoxiuapi/utils"
+	"github.com/patrickmn/go-cache"
+)
+
+type LoginController struct {
+	BaseController
+}
+
+//登录 TODO:XSRF过滤
+func (self *LoginController) LoginIn() {
+	if self.userId > 0 {
+		self.redirect(beego.URLFor("HomeController.Index"))
+	}
+	beego.ReadFromRequest(&self.Controller)
+	if self.isPost() {
+
+		username := strings.TrimSpace(self.GetString("username"))
+		password := strings.TrimSpace(self.GetString("password"))
+
+		if username != "" && password != "" {
+			user, err := backgroundm.AdminGetByName(username)
+			fmt.Println(user)
+			flash := beego.NewFlash()
+			errorMsg := ""
+			if err != nil || user.Password != libs.Md5([]byte(password+user.Salt)) {
+				errorMsg = "帐号或密码错误"
+			} else if user.Status == 0 {
+				errorMsg = "该帐号已禁用"
+			} else {
+				user.LastIp = self.getClientIp()
+				user.LastLogin = time.Now().Unix()
+				user.Update()
+				utils.Che.Set("uid"+strconv.Itoa(user.Id), user, cache.DefaultExpiration)
+				authkey := libs.Md5([]byte(self.getClientIp() + "|" + user.Password + user.Salt))
+				self.Ctx.SetCookie("auth", strconv.Itoa(user.Id)+"|"+authkey, 7*86400)
+
+				self.redirect(beego.URLFor("HomeController.Index"))
+			}
+			flash.Error(errorMsg)
+			flash.Store(&self.Controller)
+			self.redirect(beego.URLFor("LoginController.LoginIn"))
+		}
+	}
+	self.TplName = "login/login.html"
+}
+
+//登出
+func (self *LoginController) LoginOut() {
+	self.Ctx.SetCookie("auth", "")
+	self.redirect(beego.URLFor("LoginController.LoginIn"))
+}
+
+func (self *LoginController) NoAuth() {
+	self.Ctx.WriteString("没有权限")
+}

+ 102 - 0
controllers/backgroundc/property_notice.go

@@ -0,0 +1,102 @@
+package backgroundc
+
+import (
+	"wuyebaoxiuapi/models/commonm"
+	"time"
+	"strings"
+	"github.com/astaxie/beego"
+)
+
+type PropertyNoticeController struct {
+	BaseController
+}
+
+func (self *PropertyNoticeController)Index()  {
+	if self.IsAjax() == true {
+		//列表
+		page, err := self.GetInt("page")
+		if err != nil {
+			page = 1
+		}
+		limit, err := self.GetInt("limit")
+		if err != nil {
+			limit = 30
+		}
+		self.pageSize = limit
+		propertyNotice := commonm.NewPropertyNotice()
+		result, count := propertyNotice.FindPropertyNotices(page, self.pageSize)
+		list := make([]map[string]interface{}, len(result))
+		for k, v := range result {
+			row := make(map[string]interface{})
+			row["id"] = v.Id
+			row["title"] = v.Title
+			row["create_time"] = beego.Date(time.Unix(int64(v.CreateTime), 0), "Y-m-d H:i:s")
+			list[k] = row
+		}
+		self.ajaxList("成功", MSG_OK, count, list)
+	}
+	self.Data["pageTitle"] = "物业公告管理"
+	self.display()
+}
+
+func (self *PropertyNoticeController)Add()  {
+	if self.isPost() == true {
+		propertyNotice := commonm.NewPropertyNotice()
+		propertyNotice.Title = strings.TrimSpace(self.GetString("title"))
+		propertyNotice.Content = strings.TrimSpace(self.GetString("content"))
+
+		if propertyNotice.Title == "" {
+			self.ajaxMsg("请输入标题",MSG_ERR)
+		}
+
+		if propertyNotice.Content == ""{
+			self.ajaxMsg("请输入内容",MSG_ERR)
+		}
+		propertyNotice.CreateTime = int(time.Now().Unix())
+		if _, err := propertyNotice.Add(propertyNotice); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+	self.Data["pageTitle"] = "新增物业公告"
+	self.display()
+}
+
+func (self *PropertyNoticeController)Edit()  {
+	propertyNotice := commonm.NewPropertyNotice()
+	id,_ := self.GetInt("id")
+	if self.isPost() == true {
+		propertyNotice.Title = strings.TrimSpace(self.GetString("title"))
+		propertyNotice.Content = strings.TrimSpace(self.GetString("content"))
+
+		if propertyNotice.Title == "" {
+			self.ajaxMsg("请输入标题",MSG_ERR)
+		}
+
+		if propertyNotice.Content == ""{
+			self.ajaxMsg("请输入内容",MSG_ERR)
+		}
+		if err := propertyNotice.Update(); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+	self.Data["pageTitle"] = "编辑物业公告"
+	propertyNoticeInfo,_ := propertyNotice.FindPropertyNoticeById(id)
+	self.Data["info"] = propertyNoticeInfo
+	self.display()
+}
+
+func (self *PropertyNoticeController)Del()  {
+	if self.isPost() == true {
+		propertyNotice := commonm.NewPropertyNotice()
+		propertyNotice.Id,_ = self.GetInt("id")
+		println(propertyNotice.Id)
+		if _,err := propertyNotice.Delete(propertyNotice.Id); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("删除成功", MSG_OK)
+	}
+}
+
+

+ 155 - 0
controllers/backgroundc/role.go

@@ -0,0 +1,155 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-14 14:23:32
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 11:31:13
+***********************************************/
+package backgroundc
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+)
+
+type RoleController struct {
+	BaseController
+}
+
+func (self *RoleController) List() {
+	self.Data["pageTitle"] = "角色管理"
+	self.display()
+}
+
+func (self *RoleController) Add() {
+	self.Data["zTree"] = true //引入ztreecss
+	self.Data["pageTitle"] = "新增角色"
+	self.display()
+}
+func (self *RoleController) Edit() {
+	self.Data["zTree"] = true //引入ztreecss
+	self.Data["pageTitle"] = "编辑角色"
+
+	id, _ := self.GetInt("id", 0)
+	role, _ := backgroundm.RoleGetById(id)
+	row := make(map[string]interface{})
+	row["id"] = role.Id
+	row["role_name"] = role.RoleName
+	row["detail"] = role.Detail
+	self.Data["role"] = row
+
+	//获取选择的树节点
+	roleAuth, _ := backgroundm.RoleAuthGetById(id)
+	authId := make([]int, 0)
+	for _, v := range roleAuth {
+		authId = append(authId, v.AuthId)
+	}
+	self.Data["auth"] = authId
+	fmt.Println(authId)
+	self.display()
+}
+
+func (self *RoleController) AjaxSave() {
+	role := new(backgroundm.Role)
+	role.RoleName = strings.TrimSpace(self.GetString("role_name"))
+	role.Detail = strings.TrimSpace(self.GetString("detail"))
+	role.CreateTime = time.Now().Unix()
+	role.UpdateTime = time.Now().Unix()
+	role.Status = 1
+	auths := strings.TrimSpace(self.GetString("nodes_data"))
+	role_id, _ := self.GetInt("id")
+	if role_id == 0 {
+		//新增
+		role.CreateTime = time.Now().Unix()
+		role.UpdateTime = time.Now().Unix()
+		role.CreateId = self.userId
+		role.UpdateId = self.userId
+		if id, err := backgroundm.RoleAdd(role); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		} else {
+			ra := new(backgroundm.RoleAuth)
+			authsSlice := strings.Split(auths, ",")
+			for _, v := range authsSlice {
+				aid, _ := strconv.Atoi(v)
+				ra.AuthId = aid
+				ra.RoleId = id
+				backgroundm.RoleAuthAdd(ra)
+			}
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+	//修改
+	role.Id = role_id
+	role.UpdateTime = time.Now().Unix()
+	role.UpdateId = self.userId
+	if err := role.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	} else {
+		// 删除该角色权限
+		backgroundm.RoleAuthDelete(role_id)
+		ra := new(backgroundm.RoleAuth)
+		authsSlice := strings.Split(auths, ",")
+		for _, v := range authsSlice {
+			aid, _ := strconv.Atoi(v)
+			ra.AuthId = aid
+			ra.RoleId = int64(role_id)
+			backgroundm.RoleAuthAdd(ra)
+		}
+
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+func (self *RoleController) AjaxDel() {
+
+	role_id, _ := self.GetInt("id")
+	role, _ := backgroundm.RoleGetById(role_id)
+	role.Status = 0
+	role.Id = role_id
+	role.UpdateTime = time.Now().Unix()
+
+	if err := role.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	// 删除该角色权限
+	//models.RoleAuthDelete(role_id)
+	self.ajaxMsg("", MSG_OK)
+}
+
+func (self *RoleController) Table() {
+	//列表
+	page, err := self.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := self.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+
+	roleName := strings.TrimSpace(self.GetString("roleName"))
+	self.pageSize = limit
+	//查询条件
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	if roleName != "" {
+		filters = append(filters, "role_name__icontains", roleName)
+	}
+	result, count := backgroundm.RoleGetList(page, self.pageSize, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["role_name"] = v.RoleName
+		row["detail"] = v.Detail
+		row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+		list[k] = row
+	}
+	self.ajaxList("成功", MSG_OK, count, list)
+}

+ 271 - 0
controllers/backgroundc/source.go

@@ -0,0 +1,271 @@
+/**********************************************
+** @Des: 资源设置
+** @Author: haodaquan
+** @Date:   2017-09-08 17:48:30
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-09 18:50:41
+***********************************************/
+package backgroundc
+
+import (
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+
+
+)
+
+type ApiSourceController struct {
+	BaseController
+}
+
+func (self *ApiSourceController) List() {
+	self.Data["pageTitle"] = "API资源"
+	self.display()
+}
+
+func (self *ApiSourceController) Table() {
+	//列表
+	page, err := self.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := self.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+
+	sourceName := strings.TrimSpace(self.GetString("sourceName"))
+
+	//获取分组
+	groupList := groupLists()
+
+	self.pageSize = limit
+	//查询条件
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	if sourceName != "" {
+		filters = append(filters, "source_name__icontains", sourceName)
+	}
+	result, count := backgroundm.ApiSourceGetList(page, self.pageSize, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["source_name"] = v.SourceName
+		row["group_id"] = v.GroupId
+		groupInfo := getGroupInfo(groupList, v.GroupId)
+		row["group_name"] = groupInfo.GroupName
+		row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+		list[k] = row
+	}
+	self.ajaxList("成功", MSG_OK, count, list)
+}
+
+// //显示所有的接口详情
+// func (self *ApiController) Show() {
+// 	self.Data["ApiCss"] = true
+// 	id, _ := self.GetInt("id", 0)
+// 	sourceName := strings.TrimSpace(self.GetString("sourceName"))
+// 	self.Data["pageTitle"] = sourceName
+
+// 	detail, _ := models.ApiDetailsGetById(id)
+// 	list := make([]map[string]interface{}, len(detail))
+
+// 	for k, v := range detail {
+// 		row := make(map[string]interface{})
+// 		row["id"] = v.Id
+// 		row["source_id"] = v.SourceId
+// 		row["api_url"] = v.ApiUrl
+// 		row["api_name"] = v.ApiName
+// 		row["detail"] = v.Detail
+// 		row["status"] = v.Status
+// 		row["create_name"] = v.CreateName
+// 		row["update_name"] = v.UpdateName
+// 		row["audit_name"] = v.AuditName
+// 		row["audit_status"] = AUDIT_STATUS[v.Status]
+// 		row["method"] = REQUEST_METHOD[v.Method]
+// 		row["audit_time"] = beego.Date(time.Unix(v.AuditTime, 0), "Y-m-d H:i:s")
+// 		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+// 		//参数
+// 		row["Params"], _ = models.ApiParamGetById(v.Id)
+// 		list[k] = row
+// 	}
+
+// 	self.Data["Detail"] = list
+// 	self.Data["sid"] = id
+// 	self.display("api/info")
+// }
+
+func (self *ApiSourceController) Add() {
+	self.Data["pageTitle"] = "新增资源"
+	//查询条件
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	result, _ := backgroundm.GroupGetList(1, 1000, filters...)
+	list := make([]map[string]interface{}, len(result))
+
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["group_name"] = v.GroupName
+		list[k] = row
+	}
+	self.Data["Groups"] = list
+	self.display()
+}
+
+func (self *ApiSourceController) Edit() {
+	self.Data["pageTitle"] = "编辑API"
+
+	id, _ := self.GetInt("id", 0)
+	Api, err := backgroundm.ApiSourceGetById(id)
+	if err != nil {
+		self.Ctx.WriteString("数据不存在")
+		return
+	}
+	row := make(map[string]interface{})
+	row["id"] = Api.Id
+	row["source_name"] = Api.SourceName
+	row["group_id"] = int(Api.GroupId)
+	self.Data["Source"] = row
+
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+	result, _ := backgroundm.GroupGetList(1, 1000, filters...)
+	list := make([]map[string]interface{}, len(result))
+
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["group_name"] = v.GroupName
+		list[k] = row
+	}
+	self.Data["Groups"] = list
+	self.display()
+}
+
+//存储资源
+func (self *ApiSourceController) AjaxSave() {
+	Api_id, _ := self.GetInt("id")
+	if Api_id == 0 {
+		Api := new(backgroundm.ApiSource)
+
+		Api.SourceName = strings.TrimSpace(self.GetString("source_name"))
+		Api.GroupId, _ = self.GetInt("group_id")
+		Api.CreateId = self.userId
+		Api.UpdateId = self.userId
+		Api.CreateTime = time.Now().Unix()
+		Api.UpdateTime = time.Now().Unix()
+		Api.Status = 1
+
+		// 检查登录名是否已经存在
+		_, err := backgroundm.ApiSourceGetByName(Api.SourceName)
+
+		if err == nil {
+			self.ajaxMsg("资源名已经存在", MSG_ERR)
+		}
+
+		if _, err := backgroundm.ApiSourceAdd(Api); err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+
+	ApiUpdate, _ := backgroundm.ApiSourceGetById(Api_id)
+	// 修改
+	ApiUpdate.SourceName = strings.TrimSpace(self.GetString("source_name"))
+	ApiUpdate.GroupId, _ = self.GetInt("group_id")
+	ApiUpdate.UpdateId = self.userId
+	ApiUpdate.UpdateTime = time.Now().Unix()
+	ApiUpdate.Status = 1
+
+	if err := ApiUpdate.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+func (self *ApiSourceController) AjaxDel() {
+	Api_id, _ := self.GetInt("id")
+	Api, _ := backgroundm.ApiSourceGetById(Api_id)
+	Api.UpdateTime = time.Now().Unix()
+	Api.UpdateId = self.userId
+	Api.Status = 0
+	Api.Id = Api_id
+
+	//TODO 判断是否暂用API
+
+	if err := Api.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+//新增接口实例
+// func (self *ApiController) AddApi() {
+// 	self.Data["pageTitle"] = "添加接口"
+// 	source_id, _ := self.GetInt("sid")
+// 	self.Data["Sid"] = source_id
+
+// 	sourceName := strings.TrimSpace(self.GetString("sourceName"))
+// 	self.Data["pageTitle"] = sourceName + " > " + "添加接口"
+// 	self.Data["sourceName"] = sourceName
+
+// 	//查询条件
+// 	self.display()
+// }
+
+// //修改接口实例
+// func (self *ApiController) EditApi() {
+// 	id, _ := self.GetInt("id", 0)
+// 	detail, _ := models.ApiDetailGetById(id)
+// 	params, _ := models.ApiParamGetById(detail.Id)
+// 	self.Data["Detail"] = detail
+// 	self.Data["Params"] = params
+// 	self.Data["ParamsCount"] = len(params)
+// 	self.display()
+// }
+
+// func (self *ApiController) AjaxApiSave() {
+
+// 	Api_id, _ := self.GetInt("id")
+// 	if Api_id == 0 {
+// 		ApiDetail := new(models.ApiDetail)
+// 		ApiDetail.SourceId, _ = self.GetInt("source_id")
+// 		ApiDetail.Method, _ = self.GetInt("method")
+// 		ApiDetail.ApiName = strings.TrimSpace(self.GetString("api_name"))
+// 		ApiDetail.ApiUrl = strings.TrimSpace(self.GetString("api_url"))
+// 		ApiDetail.Detail = strings.TrimSpace(self.GetString("detail"))
+// 		ApiDetail.CreateId = self.userId
+// 		ApiDetail.UpdateId = self.userId
+// 		ApiDetail.CreateTime = time.Now().Unix()
+// 		ApiDetail.UpdateTime = time.Now().Unix()
+// 		ApiDetail.Status = 1
+// 		_, err := models.ApiDetailAdd(ApiDetail)
+// 		if err != nil {
+// 			self.ajaxMsg(err.Error(), MSG_ERR)
+// 		}
+// 		self.ajaxMsg("", MSG_OK)
+// 	}
+// 	//修改
+// 	ApiDetail, _ := models.ApiDetailGetById(Api_id)
+// 	ApiDetail.SourceId, _ = self.GetInt("source_id")
+// 	ApiDetail.Id, _ = self.GetInt("id")
+// 	ApiDetail.Method, _ = self.GetInt("method")
+// 	ApiDetail.ApiName = strings.TrimSpace(self.GetString("api_name"))
+// 	ApiDetail.ApiUrl = strings.TrimSpace(self.GetString("api_url"))
+// 	ApiDetail.Detail = strings.TrimSpace(self.GetString("detail"))
+
+// 	ApiDetail.UpdateId = self.userId
+// 	ApiDetail.UpdateTime = time.Now().Unix()
+// 	ApiDetail.Status, _ = self.GetInt("status")
+
+// 	if err := ApiDetail.Update(); err != nil {
+// 		self.ajaxMsg(err.Error(), MSG_ERR)
+// 	}
+// 	self.ajaxMsg("", MSG_OK)
+// }

+ 131 - 0
controllers/backgroundc/template.go

@@ -0,0 +1,131 @@
+/**********************************************
+** @Des: 公共文档设置
+** @Author: haodaquan
+** @Date:   2018-01-16 17:48:30
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2018-01-16 17:48:30
+***********************************************/
+package backgroundc
+
+import (
+	"strings"
+	"time"
+
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/models/backgroundm"
+)
+
+var ()
+
+type TemplateController struct {
+	BaseController
+}
+
+func (self *TemplateController) List() {
+	self.Data["pageTitle"] = "模板管理"
+	self.display()
+}
+
+func (self *TemplateController) Table() {
+	//列表
+	page, err := self.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := self.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+
+	TemplateName := strings.TrimSpace(self.GetString("TemplateName"))
+
+	self.pageSize = limit
+	//查询条件
+	filters := make([]interface{}, 0)
+	filters = append(filters, "status", 1)
+
+	if TemplateName != "" {
+		filters = append(filters, "template_name__icontains", TemplateName)
+	}
+	result, count := backgroundm.TemplateGetList(page, self.pageSize, filters...)
+	list := make([]map[string]interface{}, len(result))
+	for k, v := range result {
+		row := make(map[string]interface{})
+		row["id"] = v.Id
+		row["template_name"] = v.TemplateName
+		row["detail"] = v.Detail
+		row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+		row["update_time"] = beego.Date(time.Unix(v.UpdateTime, 0), "Y-m-d H:i:s")
+		list[k] = row
+	}
+	self.ajaxList("成功", MSG_OK, count, list)
+}
+
+func (self *TemplateController) Add() {
+	self.Data["pageTitle"] = "新增模板"
+
+	self.display()
+}
+
+func (self *TemplateController) Edit() {
+	id, _ := self.GetInt("id", 0)
+	detail, _ := backgroundm.TemplateGetById(id)
+	row := make(map[string]interface{})
+	row["id"] = detail.Id
+	row["template_name"] = detail.TemplateName
+	row["detail"] = detail.Detail
+	self.Data["pageTitle"] = "查看 " + detail.TemplateName
+	self.Data["Detail"] = row
+	self.display()
+}
+
+func (self *TemplateController) AjaxSave() {
+
+	Pub_id, _ := self.GetInt("id")
+	if Pub_id == 0 {
+		Template := new(backgroundm.Template)
+
+		Template.TemplateName = strings.TrimSpace(self.GetString("template_name"))
+		Template.Detail = strings.TrimSpace(self.GetString("detail"))
+		Template.CreateId = self.userId
+		Template.UpdateId = self.userId
+		Template.CreateTime = time.Now().Unix()
+		Template.UpdateTime = time.Now().Unix()
+		Template.Status = 1
+		_, err := backgroundm.TemplateAdd(Template)
+		if err != nil {
+			self.ajaxMsg(err.Error(), MSG_ERR)
+		}
+		self.ajaxMsg("", MSG_OK)
+	}
+	//修改
+	Template, _ := backgroundm.TemplateGetById(Pub_id)
+	Template.Id, _ = self.GetInt("id")
+	Template.TemplateName = strings.TrimSpace(self.GetString("template_name"))
+	Template.Detail = strings.TrimSpace(self.GetString("detail"))
+
+	Template.UpdateId = self.userId
+	Template.UpdateTime = time.Now().Unix()
+	Template.Status = 1
+	if err := Template.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}
+
+func (self *TemplateController) AjaxDel() {
+
+	Pub_id, _ := self.GetInt("id")
+	Api, _ := backgroundm.TemplateGetById(Pub_id)
+	Api.UpdateTime = time.Now().Unix()
+	Api.UpdateId = self.userId
+	Api.Status = 0
+	Api.Id = Pub_id
+
+	//TODO 判断是否被使用
+
+	if err := Api.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}

+ 82 - 0
controllers/backgroundc/user.go

@@ -0,0 +1,82 @@
+/**********************************************
+** @Des: 用户
+** @Author: haodaquan
+** @Date:   2017-09-16 14:17:37
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 11:14:07
+***********************************************/
+package backgroundc
+
+import (
+	"strings"
+	"time"
+
+	"wuyebaoxiuapi/utils"
+
+	"strconv"
+
+	"wuyebaoxiuapi/libs"
+	"wuyebaoxiuapi/models/backgroundm"
+	cache "github.com/patrickmn/go-cache"
+
+)
+
+type UserController struct {
+	BaseController
+}
+
+func (self *UserController) Edit() {
+	self.Data["pageTitle"] = "资料修改"
+	id := self.userId
+	Admin, _ := backgroundm.AdminGetById(id)
+	row := make(map[string]interface{})
+	row["id"] = Admin.Id
+	row["login_name"] = Admin.LoginName
+	row["real_name"] = Admin.RealName
+	row["phone"] = Admin.Phone
+	row["email"] = Admin.Email
+	self.Data["admin"] = row
+	utils.Che.Set("uid"+strconv.Itoa(self.user.Id), nil, cache.DefaultExpiration)
+	self.display()
+}
+
+func (self *UserController) AjaxSave() {
+	Admin_id, _ := self.GetInt("id")
+	Admin, _ := backgroundm.AdminGetById(Admin_id)
+	//修改
+	Admin.Id = Admin_id
+	Admin.UpdateTime = time.Now().Unix()
+	Admin.UpdateId = self.userId
+	Admin.LoginName = strings.TrimSpace(self.GetString("login_name"))
+	Admin.RealName = strings.TrimSpace(self.GetString("real_name"))
+	Admin.Phone = strings.TrimSpace(self.GetString("phone"))
+	Admin.Email = strings.TrimSpace(self.GetString("email"))
+
+	resetPwd := self.GetString("reset_pwd")
+	if resetPwd == "1" {
+		pwdOld := strings.TrimSpace(self.GetString("password_old"))
+		pwdOldMd5 := libs.Md5([]byte(pwdOld + Admin.Salt))
+		if Admin.Password != pwdOldMd5 {
+			self.ajaxMsg("旧密码错误", MSG_ERR)
+		}
+
+		pwdNew1 := strings.TrimSpace(self.GetString("password_new1"))
+		pwdNew2 := strings.TrimSpace(self.GetString("password_new2"))
+
+		if pwdNew1 != pwdNew2 {
+			self.ajaxMsg("两次密码不一致", MSG_ERR)
+		}
+
+		pwd, salt := libs.Password(4, pwdNew1)
+		Admin.Password = pwd
+		Admin.Salt = salt
+	}
+	Admin.UpdateTime = time.Now().Unix()
+	Admin.UpdateId = self.userId
+	Admin.Status = 1
+
+	if err := Admin.Update(); err != nil {
+		self.ajaxMsg(err.Error(), MSG_ERR)
+	}
+	self.ajaxMsg("", MSG_OK)
+}

+ 54 - 0
controllers/frontc/api.go

@@ -0,0 +1,54 @@
+package frontc
+
+import(
+	"encoding/json"
+	"wuyebaoxiuapi/libs"
+	"fmt"
+)
+
+type ApiController struct {
+	BBaseController
+}
+
+// 模拟登录
+func (this *ApiController)Login()  {
+	http :=libs.NewHttp()
+	params := make(map[string]interface{})
+	userInfo := make(map[string]interface{})
+	userInfo["nickName"] = "pengjs"
+	userInfo["avatarUrl"] = "1.jpg"
+	userInfo["gender"] = 1
+	userInfo["school"] = "xxx"
+	params["is_repair_user"] = 2
+	params["username"] = "admin"
+	params["password"] = "123456"
+	params["types"] = 2
+	params["is_wechat_login"] = 0
+	params["openid"] = "o6iCm1FeosWAhRS88jOXmrXCUbUI"
+	params["username"] = "admin"
+	params["password"] = "123456"
+	jsonStr,_ := json.Marshal(userInfo)
+	params["userInfo"] = string(jsonStr)
+	fmt.Println("b:", string(jsonStr))
+	fmt.Println("c:", params["userInfo"])
+	result := http.Post("http://localhost:8081/user/login",params)
+	mapJson := libs.JsonToMap(result)
+	this.ajaxMsg(1,mapJson["message"],mapJson["data"])
+}
+// 修改密码
+func (this *ApiController)UpdatePassword()  {
+	http :=libs.NewHttp()
+	params := make(map[string]interface{})
+	params["old_password"] = "123456"
+	params["new_password"] = "111111"
+	params["confirm_password"] = "o6iCm1FeosWAhRS88jOXmrXCUbUI"
+	result := http.Post("http://localhost:8081/user/UpdatePassword",params)
+	mapJson := libs.JsonToMap(result)
+	this.ajaxMsg(1,mapJson["message"],mapJson["data"])
+}
+
+
+
+
+
+

+ 146 - 0
controllers/frontc/base.go

@@ -0,0 +1,146 @@
+package frontc
+
+import (
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/utils"
+	"strconv"
+	"wuyebaoxiuapi/models/frontm"
+	"wuyebaoxiuapi/contanst"
+	"wuyebaoxiuapi/libs"
+	"strings"
+	"time"
+	"wuyebaoxiuapi/models/backgroundm"
+	"github.com/patrickmn/go-cache"
+)
+
+type BaseController struct {
+	BBaseController
+	userInfo *backgroundm.Admin
+}
+
+type BBaseController struct {
+	beego.Controller
+}
+
+const (
+	MSG_OK  = 1
+	MSG_ERR = 0
+)
+
+func (self *BaseController) Prepare() {
+
+	auth := "1|1"//self.Ctx.GetCookie(contanst.CACHE_USERINFO+"auth")
+	println("auth:"+auth)
+	authArr := strings.Split(auth,"|")
+	var cuserid int
+	var _ error
+	if len(authArr) == 2 {
+		userid := authArr[0]
+		cuserid,_ = strconv.Atoi(userid)
+		self.userInfo = self.findCacheUserInfo(cuserid)
+		if self.userInfo == nil {
+			self.userInfo,_= backgroundm.AdminGetById(cuserid)
+		}
+	}
+
+	if cuserid <= 0 {
+		self.Data["json"] = map[string]interface{}{"code": 0, "message": "登录过期"}
+		self.ServeJSON()
+	}
+}
+
+// 上传图片
+func (self *BaseController)UploadImage() {
+	self.Prepare()
+	url := self.GetString("url")
+	imageUpload := libs.NewImageUpload()
+	result := imageUpload.Upload(url)
+	if result["status"] == MSG_ERR {
+		self.ajaxMsg(MSG_ERR,result["message"],nil)
+	}
+	self.ajaxMsg(MSG_OK,"",result["image"])
+}
+
+func (self *BaseController)addPicture(data map[string]interface{})(int64, error) {
+	picture := frontm.NewPicture()
+	picture.CreateTime = int(time.Now().Unix())
+	picture.Path = libs.ConvertString(data["image"])
+	id ,err :=  picture.Add();
+	if int(id) > 0 {
+		repairUserPicture := frontm.NewRepairUserPicture()
+		repairUserPicture.PictureId = int(id)
+		if data["types"] == 2 {
+			repairUserPicture.Types = 2
+			repairUserPicture.RepairId = data["repairId"].(int)
+		}else{
+			repairUserPicture.Types = 1
+		}
+		repairUserPicture.UserId = self.userInfo.Id
+		return repairUserPicture.Add();
+	}
+	return 0,err
+}
+
+func (self *BaseController)deletePicture(image string)(int64, error) {
+	picture := frontm.NewPicture()
+	repairUserPicture := frontm.NewRepairUserPicture()
+	picture,err := picture.FindPictureByPath(image)
+	if picture != nil {
+		return repairUserPicture.DeleteByPictureId(picture.Id)
+	}
+	return 0,err
+}
+
+// 缓存用户信息
+func (self *BBaseController)cacheUserInfo(user *backgroundm.Admin)  {
+	authkey := libs.Md5([]byte( user.Password + user.Salt))
+	self.Ctx.SetCookie(contanst.CACHE_USERINFO+"auth", strconv.Itoa(user.Id)+"|"+authkey, 7*86400)
+	utils.Che.Set(contanst.CACHE_USERINFO+strconv.Itoa(user.Id), user, cache.DefaultExpiration)
+}
+
+// 获取缓存用户信息
+func (self *BaseController)findCacheUserInfo(userid int)(*backgroundm.Admin)  {
+	user,_  := utils.Che.Get(contanst.CACHE_USERINFO+strconv.Itoa(userid))
+	println(user)
+	if user != nil {
+		return user.(*backgroundm.Admin)
+	}
+	return nil
+
+}
+
+//ajax返回
+func (self *BBaseController) ajaxMsg( msgno int,msg interface{},data  interface{}) {
+	self.Data["json"] = libs.NewResponse().AjaxMsg(msgno,msg,data)
+	self.ServeJSON()
+	self.StopRun()
+}
+// 是否POST提交
+func (self *BBaseController) isPost() bool {
+	return self.Ctx.Request.Method == "POST"
+}
+
+//ajax返回 列表
+func (self *BBaseController) ajaxList( msgno int,msg interface{}, count int64, data interface{}) {
+	self.Data["json"] = libs.NewResponse().AjaxList(msgno,msg,count,data)
+	self.ServeJSON()
+	self.StopRun()
+}
+
+// 注销用户信息
+func (this *BBaseController)unsetUserInfo(user *frontm.User,admin *backgroundm.Admin){
+	if user != nil {
+		user.Id = admin.Id
+		user.LoginName = admin.LoginName
+		user.Phone = admin.Phone
+		user.CreateTime = admin.CreateTime
+		user.Gender = admin.Gender
+		user.NickName = admin.NickName
+		user.AvatarUrl = admin.AvatarUrl
+		user.Openid = admin.Openid
+		user.School = admin.School
+		user.DailyAddress = admin.DailyAddress
+		user.Rating = admin.Rating
+		user.Types = admin.Types
+	}
+}

+ 87 - 0
controllers/frontc/login.go

@@ -0,0 +1,87 @@
+package frontc
+
+import (
+	"wuyebaoxiuapi/models/backgroundm"
+	"strings"
+	"wuyebaoxiuapi/libs"
+	"time"
+	"wuyebaoxiuapi/models/frontm"
+)
+
+type LoginController struct {
+	BBaseController
+}
+
+// 登录
+func (this *LoginController)Login(){
+	if this.isPost() == true {
+		user := new(backgroundm.Admin)
+		user.Types ,_= this.GetInt("types")
+		isWechatLogin ,_:= this.GetInt("is_wechat_login")
+		cnuserinfo := new(frontm.User)
+		// 是否是微信登录
+		if isWechatLogin == 1 {
+			user.Openid = strings.TrimSpace(this.GetString("openid"))
+			cuserInfo := strings.TrimSpace(this.GetString("userInfo"))
+			fuserInfo,err := backgroundm.FindUserInfoByOpenid(user.Openid)
+			if user.Openid != ""  && cuserInfo != "" && err != nil{
+				userinfoMap := libs.JsonToMap(cuserInfo)
+				user.Salt = libs.GetRandomString(4)
+				user.Password = libs.Md5([]byte("000000"+user.Salt))
+				user.NickName = libs.ConvertString(userinfoMap["nickName"])
+				user.AvatarUrl = libs.ConvertString(userinfoMap["avatarUrl"])
+				user.Gender = 0 // int(userinfoMap["gender"])
+				user.School = libs.ConvertString(userinfoMap["school"])
+				user.CreateTime = time.Now().Unix()
+				id,err := backgroundm.UserAdd(user)
+				if err != nil {
+					this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试。",nil)
+				}
+				user.Id = int(id)
+				this.unsetUserInfo(cnuserinfo,user)
+				// 缓存用户信息
+				this.cacheUserInfo(user)
+				this.ajaxMsg(MSG_OK,"登录成功",cnuserinfo)
+			}
+			if fuserInfo != nil {
+
+				this.unsetUserInfo(cnuserinfo,fuserInfo)
+				// 缓存用户信息
+				this.cacheUserInfo(fuserInfo)
+				this.ajaxMsg(MSG_OK,"登录成功",cnuserinfo)
+			}else{
+				this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试。",nil)
+			}
+		}else{
+			user.LoginName = strings.TrimSpace(this.GetString("username"))
+			user.Password = strings.TrimSpace(this.GetString("password"))
+			println("username:"+user.LoginName)
+			if user.LoginName == "" {
+				this.ajaxMsg(MSG_ERR,"请输入用户名",nil)
+			}
+
+			if user.Password == "" {
+				this.ajaxMsg(MSG_ERR,"请输入密码",nil)
+			}
+			// 根据用户名,查找用户信息
+			userInfo,err := backgroundm.FindUserInfoByName(user.LoginName)
+			if err != nil{
+				this.ajaxMsg(MSG_ERR,"用户名错误",nil)
+			}
+			md5Password := libs.Md5([]byte(user.Password+userInfo.Salt))
+			if md5Password != userInfo.Password {
+				this.ajaxMsg(MSG_ERR,"密码错误",nil)
+			}
+			this.unsetUserInfo(cnuserinfo,userInfo)
+			// 缓存用户信息
+			this.cacheUserInfo(userInfo)
+			this.ajaxMsg(MSG_OK,"登录成功",cnuserinfo)
+		}
+	}
+	this.ajaxMsg(MSG_OK,"登录成功",nil)
+}
+
+
+
+
+

+ 43 - 0
controllers/frontc/property_notice.go

@@ -0,0 +1,43 @@
+package frontc
+
+import (
+	"wuyebaoxiuapi/models/commonm"
+	"github.com/astaxie/beego"
+	"time"
+)
+
+type PropertyNoticeController struct {
+	BaseController
+}
+
+func (this *PropertyNoticeController)List()  {
+	this.Prepare()
+	//列表
+	page, err := this.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := this.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+
+	propertyNotice := commonm.NewPropertyNotice()
+	result, count := propertyNotice.FindPropertyNotices(page, limit)
+	for k, v := range result {
+		propertyNotice := commonm.NewPropertyNotice()
+		propertyNotice.Id = v.Id
+		propertyNotice.Title = v.Title
+		propertyNotice.FCreateTime = beego.Date(time.Unix(int64(v.CreateTime), 0), "Y年m月d日")
+		result[k] = propertyNotice
+	}
+	this.ajaxList(MSG_OK,"成功" , count, result)
+}
+
+func (this *PropertyNoticeController)Detail()  {
+	this.Prepare()
+	id, _ := this.GetInt("id")
+	propertyNotice := commonm.NewPropertyNotice()
+	propertyNotice,_ = propertyNotice.FindPropertyNoticeById(id)
+	this.ajaxMsg(MSG_OK,"",propertyNotice)
+}

+ 57 - 0
controllers/frontc/repair.go

@@ -0,0 +1,57 @@
+package frontc
+
+import(
+	"wuyebaoxiuapi/models/frontm"
+)
+
+type RepairController struct {
+	BaseController
+}
+
+// 用户报修
+func (this *RepairController)Repair()  {
+	this.Prepare()
+	repair := new(frontm.Repair)
+	image  := this.GetString("image")
+	repair.School = this.GetString("school")
+	repair.Position = this.GetString("position")
+	repair.ApplicantName = this.GetString("applicant_name")
+	repair.ApplicantPhone = this.GetString("applicant_phone")
+	repair.ApplicantContent = this.GetString("applicant_content")
+	repair.Address = this.GetString("address")
+	repair.ApplicantUserId = this.userInfo.Id
+	repair.Status = 1
+
+	if image == "" {
+		this.ajaxMsg(MSG_ERR,"请上传图片",nil)
+	}
+
+	if repair.School == "" {
+		this.ajaxMsg(MSG_ERR,"请填写学校",nil)
+	}
+
+	if repair.Position == "" {
+		this.ajaxMsg(MSG_ERR,"请填写位置",nil)
+	}
+
+	if repair.ApplicantName == "" {
+		this.ajaxMsg(MSG_ERR,"请填写保修人的姓名",nil)
+	}
+
+	if repair.ApplicantPhone == "" {
+		this.ajaxMsg(MSG_ERR,"请填写联系电话",nil)
+	}
+
+	//if false == libs.Validate().IsPhone(repair.ApplicantPhone){
+	//	this.ajaxMsg(MSG_ERR,"请填写正确的联系电话",nil)
+	//}
+	id,err := frontm.RepairAdd(repair)
+	if err != nil {
+		this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试。",nil)
+	}
+	data := make(map[string]interface{})
+	data["image"] = image
+	data["repairId"] = id
+	this.addPicture(data)
+	this.ajaxMsg(MSG_OK,"报修成功",nil)
+}

+ 128 - 0
controllers/frontc/user.go

@@ -0,0 +1,128 @@
+package frontc
+
+import (
+	"wuyebaoxiuapi/libs"
+	"wuyebaoxiuapi/models/backgroundm"
+)
+
+type UserController struct {
+	BaseController
+}
+// 用户信息
+func (this *UserController)Info() {
+	this.Prepare()
+	this.Data["json"] = map[string]interface{}{"code": 1, "message": "","data":this.userInfo}
+}
+
+// 修改密码
+func (this *UserController)UpdatePassword() {
+	this.Prepare()
+	user := new(backgroundm.Admin)
+	userInfo := this.userInfo
+	oldPassword := this.GetString("old_password")         // 原密码
+	newPassword := this.GetString("new_password")         // 新密码
+	confirmPassword := this.GetString("confirm_password") // 确认密码
+	if oldPassword == "" {
+		this.ajaxMsg(MSG_ERR,"请输入原密码",nil)
+	}
+	md5Password := libs.Md5([]byte(oldPassword+userInfo.Salt))
+
+	if  md5Password != userInfo.Password{
+		this.ajaxMsg(MSG_ERR,"原密码输入错误",nil)
+	}
+	if newPassword == "" {
+		this.ajaxMsg(MSG_ERR,"请输入新密码",nil)
+	}
+
+	if oldPassword == newPassword {
+		this.ajaxMsg(MSG_ERR,"原密码与新密码不能一致",nil)
+	}
+
+	if confirmPassword == "" {
+		this.ajaxMsg(MSG_ERR,"请输入确认密码",nil)
+	}
+
+	if newPassword !=  confirmPassword{
+		this.ajaxMsg(MSG_ERR,"两次输入的密码,不一致",nil)
+	}
+	user.Id = userInfo.Id
+	user.Salt = libs.GetRandomString(4)
+	user.Password = libs.Md5([]byte(newPassword+user.Salt))
+	if err := user.UpdatePassword(); err != nil {
+		this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试",nil)
+	}
+	this.ajaxMsg(MSG_OK,"密码修改成功",nil)
+}
+
+// 修改头像
+func (this *UserController)UpdateAvatarUrl()  {
+	this.Prepare()
+	user := new(backgroundm.Admin)
+	avatarUrl := this.GetString("avatar_url")
+	user.Id = this.userInfo.Id
+	user.AvatarUrl = avatarUrl
+	if user.AvatarUrl == "" {
+		this.ajaxMsg(MSG_ERR,"请上传头像",nil)
+	}
+	if err := user.Update(); err != nil {
+		this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试",nil)
+	}
+	data := make(map[string]interface{})
+	data["image"] = avatarUrl
+	data["types"] = 1
+	this.addPicture(data)
+	this.ajaxMsg(MSG_OK,"头像修改成功",nil)
+}
+
+// 修改学校
+func (this *UserController)UpdateSchool()  {
+	this.Prepare()
+	user := new(backgroundm.Admin)
+	school := this.GetString("school")
+	user.Id = this.userInfo.Id
+	user.School = school
+	if user.School == "" {
+		this.ajaxMsg(MSG_ERR,"请填写学校",nil)
+	}
+	if err := user.Update(); err != nil {
+		this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试",nil)
+	}
+	this.ajaxMsg(MSG_OK,"学校修改成功",nil)
+}
+
+// 修改日常地址
+func (this *UserController)UpdateDailyAddress()  {
+	this.Prepare()
+	user := new(backgroundm.Admin)
+	dailyAddress := this.GetString("daily_address")
+	user.Id = this.userInfo.Id
+	user.DailyAddress = dailyAddress
+	if user.DailyAddress == "" {
+		this.ajaxMsg(MSG_ERR,"请填写日常地址",nil)
+	}
+	if err := user.Update(); err != nil {
+		this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试",nil)
+	}
+	this.ajaxMsg(MSG_OK,"日常地址修改成功",nil)
+}
+
+// 修改手机号码
+func (this *UserController)UpdatepPhone()  {
+	this.Prepare()
+	user := new(backgroundm.Admin)
+	phone := this.GetString("phone")
+	//if false == libs.Validate().IsPhone(phone){
+	//	this.ajaxMsg(MSG_ERR,"请输入正确的手机号码",nil)
+	//}
+	user.Id = this.userInfo.Id
+	user.Phone = phone
+	if err := user.Update(); err != nil {
+		this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试",nil)
+	}
+	this.ajaxMsg(MSG_OK,"手机号码修改成功",nil)
+}
+
+
+
+
+

+ 291 - 0
controllers/frontc/user_repair.go

@@ -0,0 +1,291 @@
+package frontc
+
+import (
+	"wuyebaoxiuapi/models/frontm"
+	"wuyebaoxiuapi/models/backgroundm"
+	"time"
+)
+
+// 用户维修控制器
+type UserRepairController struct {
+	BaseController
+}
+
+// 用户报修数量
+func (this *UserRepairController)UserRepairCount()  {
+	if this.userInfo.Types != 0 {
+		this.Data["json"] = map[string]interface{}{"code": 0, "message": "登录过期"}
+		this.ServeJSON()
+	}
+	repair := frontm.NewRepair()
+	count := repair.FindRepairUserRepairCount(this.userInfo.Id)
+	result := make(map[string]interface{})
+	result["count"] = count
+	this.ajaxMsg(MSG_OK,"",result)
+}
+
+// 报修用户报修列表
+func (this *UserRepairController)RepairUserRepairs() {
+	userid := this.userInfo.Id
+	page, err := this.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := this.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+
+	repair := frontm.NewRepair()
+
+	repairs,total := repair.FindRepairUserRepairs(userid,page,limit)
+	outReRepairs := make([]*frontm.OutReRepair,0)
+	for _, v := range repairs {
+		outReRepair := new(frontm.OutReRepair)
+		this.fmtOutReRepair(v,outReRepair)
+		outReRepairs = append(outReRepairs,outReRepair)
+	}
+	this.ajaxList(MSG_OK,"",total,outReRepairs)
+}
+
+func (this *UserRepairController)fmtOutReRepair(repair *frontm.Repair,outReRepair *frontm.OutReRepair) {
+	repairUserPicture := frontm.NewRepairUserPicture()
+	outReRepair.Id = repair.Id
+	outReRepair.School = repair.School
+	outReRepair.Position = repair.Position
+	outReRepair.ApplicantName = repair.ApplicantName
+	outReRepair.ApplicantPhone = repair.ApplicantPhone
+	outReRepair.ApplicantUserId = repair.ApplicantUserId
+	outReRepair.CreateTime = repair.CreateTime
+	outReRepair.RepairUserId = repair.RepairUserId
+	outReRepair.Status = repair.Status
+	outReRepair.RepairTime = repair.RepairTime
+	outReRepair.ApplicantContent = repair.ApplicantContent
+	outReRepair.Address = repair.Address
+	// 查找维修图片
+	images := repairUserPicture.FindPictureByUserIdAndReparId(repair.ApplicantUserId,repair.Id)
+	outReRepair.RepairImages = images
+	// 查找维修图片
+	outReRepair.ServiceImages = repairUserPicture.FindPictureByUserIdAndReparId(repair.RepairUserId,repair.Id)
+}
+
+// 维修用户维修数量
+func (this *UserRepairController)RepairUserRepairCount()  {
+	if this.userInfo.Types != 0 {
+		this.Data["json"] = map[string]interface{}{"code": 0, "message": "登录过期"}
+		this.ServeJSON()
+	}
+
+	repair := frontm.NewRepair()
+	result := make(map[string]interface{})
+	// 待维修数量
+	result["WRepairCount"] = repair.FindServiceUserWRepairCount(this.userInfo.Id)
+	// 已维修数量
+	result["HRepairCount"] = repair.FindServiceUserHRepairCount(this.userInfo.Id)
+
+	this.ajaxMsg(MSG_OK,"",result)
+}
+
+// 管理员维修数量
+func (this *UserRepairController)AdminRepairCount()  {
+	repair := frontm.NewRepair()
+	admin := new(backgroundm.Admin)
+	result := make(map[string]interface{})
+	// 待维修数量
+	result["WRepairCount"] = repair.FindAdminWRepairCount(0)
+	// 已维修数量
+	result["HRepairCount"] = repair.FindAdminHRepairCount(0)
+	// 查找维修工人数量
+	result["RepairWorkerCount"] = admin.FindRepairWorkerCount()
+	this.ajaxMsg(MSG_OK,"",result)
+}
+
+// 维修工人列表
+func (this *UserRepairController)RepairWorkers()  {
+	repairWorkers,total := this.findRepairWorkers(false)
+	this.ajaxList(MSG_OK,"",total,repairWorkers)
+}
+
+// 维修工人维修列表
+func (this *UserRepairController)RepairWorkerRepairs() {
+	id, _ := this.GetInt("id")
+	page, err := this.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := this.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+	repair := frontm.NewRepair()
+	repairs,total := repair.FindRepairsByUserId(id,page,limit)
+	this.ajaxList(MSG_OK,"",total,repairs)
+}
+
+// 管理员待维修列表
+func (this *UserRepairController)AdminWRepairs() {
+	page, err := this.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := this.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+	repair := frontm.NewRepair()
+	repairs,total :=repair.FindAdminWRepairs(page,limit)
+	outReRepairs := make([]*frontm.OutReRepair,0)
+	for _, v := range repairs {
+		outReRepair := new(frontm.OutReRepair)
+		this.fmtOutReRepair(v,outReRepair)
+		outReRepairs = append(outReRepairs,outReRepair)
+	}
+	this.ajaxList(MSG_OK,"",total,outReRepairs)
+}
+// 管理员已维修列表
+func (this *UserRepairController)AdminHRepairs() {
+	page, err := this.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := this.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+	repair := frontm.NewRepair()
+	repairs,total :=repair.FindAdminHRepairs(page,limit)
+	outReRepairs := make([]*frontm.OutReRepair,0)
+	for _, v := range repairs {
+		outReRepair := new(frontm.OutReRepair)
+		this.fmtOutReRepair(v,outReRepair)
+		outReRepairs = append(outReRepairs,outReRepair)
+	}
+	this.ajaxList(MSG_OK,"",total,outReRepairs)
+}
+// 指派维修工人列表
+func (this *UserRepairController)AssignRepairWorkers()  {
+	repairWorkers,total := this.findRepairWorkers(true)
+	this.ajaxList(MSG_OK,"",total,repairWorkers)
+}
+
+// 指派维修任务
+func (this *UserRepairController)AssignRepairTask(){
+	id, _ := this.GetInt("id")
+	repairUserId, _ := this.GetInt("repair_user_id")
+	if id <= 0 {
+		this.ajaxMsg(MSG_ERR,"请选择维修任务",nil)
+	}
+	if repairUserId <= 0 {
+		this.ajaxMsg(MSG_ERR,"请指派维修工人",nil)
+	}
+	repair := frontm.NewRepair()
+	if _,err := repair.AssignRepairTask(id,repairUserId); err != nil {
+		this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试",nil)
+	}
+	this.ajaxMsg(MSG_OK,"指派成功",nil)
+}
+
+// 查找维修工人列表
+func (this *UserRepairController)findRepairWorkers(isAssign bool)([]*backgroundm.RepairWorker,
+	int64)  {
+	page, err := this.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := this.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+	repairWorkers := make([]*backgroundm.RepairWorker,0)
+	admin := new(backgroundm.Admin)
+	repair := frontm.NewRepair()
+	admins,total := admin.FindRepairWorkers(page,limit)
+	for _, v := range admins {
+		repairWorker := new(backgroundm.RepairWorker)
+		repairWorker.Id = v.Id
+		repairWorker.LoginName = v.LoginName
+		repairWorker.Phone = v.Phone
+		repairWorker.NickName = v.NickName
+		repairWorker.AvatarUrl = v.AvatarUrl
+		// 查找维修用户待维修数量
+		repairWorker.WRepairCount = repair.FindServiceUserWRepairCount(v.Id)
+		if isAssign == false {
+			// 查找维修用户已维修数量
+			repairWorker.HRepairCount = repair.FindServiceUserHRepairCount(v.Id)
+		}else{
+			// 查找维修用户已维修数量
+			repairWorker.HRepairCount = 0
+		}
+		repairWorkers = append(repairWorkers, repairWorker)
+	}
+	return repairWorkers,total
+}
+
+// 查找维修用户待维修列表
+func (this *UserRepairController)ServiceUserWRepairs()()  {
+	page, err := this.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := this.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+	repair := frontm.NewRepair()
+	repairs,total :=repair.FindServiceUserWRepairs(this.userInfo.Id,page,limit)
+	outReRepairs := make([]*frontm.OutReRepair,0)
+	for _, v := range repairs {
+		outReRepair := new(frontm.OutReRepair)
+		this.fmtOutReRepair(v,outReRepair)
+		outReRepairs = append(outReRepairs,outReRepair)
+	}
+	this.ajaxList(MSG_OK,"",total,outReRepairs)
+}
+
+// 查找维修用户待维修列表
+func (this *UserRepairController)ServiceUserHRepairs()()  {
+	page, err := this.GetInt("page")
+	if err != nil {
+		page = 1
+	}
+	limit, err := this.GetInt("limit")
+	if err != nil {
+		limit = 30
+	}
+	repair := frontm.NewRepair()
+	repairs,total :=repair.FindServiceUserHRepairs(this.userInfo.Id,page,limit)
+	outReRepairs := make([]*frontm.OutReRepair,0)
+	for _, v := range repairs {
+		outReRepair := new(frontm.OutReRepair)
+		this.fmtOutReRepair(v,outReRepair)
+		outReRepairs = append(outReRepairs,outReRepair)
+	}
+	this.ajaxList(MSG_OK,"",total,outReRepairs)
+}
+
+// 确认维修
+func (this *UserRepairController)ConfirmRepair()()  {
+	repair := frontm.NewRepair()
+	repair.Id, _ = this.GetInt("id")
+	image := this.GetString("image")
+	if repair.Id <= 0 {
+		this.ajaxMsg(MSG_ERR,"请选择要确认维修的任务",nil)
+	}
+	repair.RepairUserId = this.userInfo.Id
+	repair.RepairTime = int(time.Now().Unix())
+
+	if _,err := repair.ConfirmRepair(); err != nil {
+		this.ajaxMsg(MSG_ERR,"系统繁忙,请稍后再试",nil)
+	}
+	data := make(map[string]interface{})
+	data["image"] = image
+	data["repairId"] = repair.Id
+	this.addPicture(data)
+	this.ajaxMsg(MSG_OK,"维修成功",nil)
+}
+
+
+
+
+
+

+ 5 - 0
initial/init.go

@@ -0,0 +1,5 @@
+package initial
+
+func Init()  {
+	InitSql()
+}

+ 35 - 0
initial/sql.go

@@ -0,0 +1,35 @@
+package initial
+
+import (
+	"github.com/astaxie/beego"
+	"net/url"
+	"github.com/astaxie/beego/orm"
+)
+
+func InitSql() {
+	dbhost := beego.AppConfig.String("db.host")
+	dbport := beego.AppConfig.String("db.port")
+	dbuser := beego.AppConfig.String("db.user")
+	dbpassword := beego.AppConfig.String("db.password")
+	dbname := beego.AppConfig.String("db.name")
+	timezone := beego.AppConfig.String("db.timezone")
+	if dbport == "" {
+		dbport = "3306"
+	}
+	dsn := dbuser + ":" + dbpassword + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname + "?charset=utf8"
+	// fmt.Println(dsn)
+
+	if timezone != "" {
+		dsn = dsn + "&loc=" + url.QueryEscape(timezone)
+	}
+	orm.RegisterDataBase("default", "mysql", dsn)
+	//orm.RegisterModel(new(backgroundm.Auth), new(backgroundm.Role), new(backgroundm.RoleAuth), new(backgroundm.Admin),
+	//	new(backgroundm.Group), new(backgroundm.Env), new(backgroundm.Code), new(backgroundm.ApiSource), new(backgroundm.ApiDetail),
+	// new(backgroundm.ApiPublic),
+	//	new(backgroundm.Template),new(commonm.PropertyNotice),
+	//	new(frontm.User),
+	//)
+	if beego.AppConfig.String("runmode") == "dev" {
+		orm.Debug = true
+	}
+}

+ 54 - 0
libs/http.go

@@ -0,0 +1,54 @@
+package libs
+
+import (
+	"github.com/astaxie/beego/httplib"
+	"errors"
+	"crypto/tls"
+)
+
+type Http struct {
+
+}
+
+func NewHttp()*Http  {
+	return new(Http)
+}
+
+func (http *Http)Post(url string,params map[string]interface{}) string {
+	request := httplib.Post(url).Debug(true)
+	setHeader(request)
+	setParams(params,request)
+	response,err := request.String()
+	if err != nil{
+		errors.New(err.Error())
+	}
+	return response
+
+}
+
+func (http *Http)Get(url string,params map[string]interface{}) string {
+	request := httplib.Get(url).Debug(true)
+	setParams(params,request)
+	setHeader(request)
+	response,err := request.String()
+	if err != nil{
+		errors.New(err.Error())
+	}
+	return response
+
+}
+
+func setParams(params map[string]interface{},request *httplib.BeegoHTTPRequest)  {
+	for k,v := range params {
+		request.Param(k,ConvertString(v))
+	}
+	request.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
+}
+
+func setHeader(request *httplib.BeegoHTTPRequest)  {
+	request.Header("Accept-Encoding","gzip,deflate,sdch")
+	request.Header("Content-Type","application/json;charset=utf-8")
+	request.Header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36")
+}
+
+

+ 29 - 0
libs/response.go

@@ -0,0 +1,29 @@
+package libs
+
+type Response struct {
+
+}
+func NewResponse()*Response  {
+	return new(Response)
+}
+
+//ajax返回
+func (self *Response) AjaxMsg( msgno int,msg interface{},data interface{})map[string]interface{} {
+	out := make(map[string]interface{})
+	out["code"] = msgno
+	out["message"] = msg
+	out["data"] = data
+	return out
+}
+
+//ajax返回 列表
+func (self *Response) AjaxList( msgno int,msg interface{}, count int64, data interface{})map[string]interface{} {
+	out := make(map[string]interface{})
+	out["code"] = msgno
+	out["msg"] = msg
+	out["count"] = count
+	out["data"] = data
+	return out
+}
+
+

+ 96 - 0
libs/string.go

@@ -0,0 +1,96 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-08 00:24:25
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 10:12:06
+***********************************************/
+
+package libs
+
+import (
+	"crypto/md5"
+	"fmt"
+	"math/rand"
+	"regexp"
+	"time"
+	"github.com/bitly/go-simplejson"
+	"strconv"
+	"encoding/json"
+)
+
+var emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?")
+
+func Md5(buf []byte) string {
+	hash := md5.New()
+	hash.Write(buf)
+	return fmt.Sprintf("%x", hash.Sum(nil))
+}
+
+func SizeFormat(size float64) string {
+	units := []string{"Byte", "KB", "MB", "GB", "TB"}
+	n := 0
+	for size > 1024 {
+		size /= 1024
+		n += 1
+	}
+
+	return fmt.Sprintf("%.2f %s", size, units[n])
+}
+
+func IsEmail(b []byte) bool {
+	return emailPattern.Match(b)
+}
+
+func Password(len int, pwdO string) (pwd string, salt string) {
+	salt = GetRandomString(4)
+	defaultPwd := "george518"
+	if pwdO != "" {
+		defaultPwd = pwdO
+	}
+	pwd = Md5([]byte(defaultPwd + salt))
+	return pwd, salt
+}
+
+// 生成32位MD5
+// func MD5(text string) string{
+//    ctx := md5.New()
+//    ctx.Write([]byte(text))
+//    return hex.EncodeToString(ctx.Sum(nil))
+// }
+
+//生成随机字符串
+func GetRandomString(lens int) string {
+	str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	bytes := []byte(str)
+	result := []byte{}
+	r := rand.New(rand.NewSource(time.Now().UnixNano()))
+	for i := 0; i < lens; i++ {
+		result = append(result, bytes[r.Intn(len(bytes))])
+	}
+	return string(result)
+}
+
+// json转换成map
+func JsonToMap(value string)(map[string]interface{}){
+	byteValue := []byte(value)
+	js, _ := simplejson.NewJson(byteValue)
+	nodes, _ := js.Map()
+	return nodes
+}
+// map转换为json
+func MapToJson(value interface{}) string {
+	jsonStr,_ := json.Marshal(value)
+	return string(jsonStr)
+}
+// 转化成字符串
+func ConvertString(value interface{})string{
+	switch value.(type) {
+	case string:
+		return  value.(string)
+	case int:
+		return strconv.Itoa(value.(int))
+	default:
+		return ""
+	}
+}

+ 73 - 0
libs/upload.go

@@ -0,0 +1,73 @@
+package libs
+
+import (
+	"strings"
+	"encoding/base64"
+	"time"
+	"os"
+	"strconv"
+	"bufio"
+	"github.com/astaxie/beego/logs"
+	"wuyebaoxiuapi/contanst"
+)
+
+type ImageUpload struct {
+
+}
+
+const UPLOAD_DIR = "./static/upload/"
+func NewImageUpload() (*ImageUpload) {
+	return new(ImageUpload)
+}
+
+func (this *ImageUpload)Upload(url string) (map[string]interface{}) {
+	DataArr := strings.Split(url, ",")
+
+	//去除包装,获取到base64编码
+	imgBase64 := DataArr[1][:len(DataArr[1])-2]
+	result := make(map[string]interface{})
+	//base64转码
+	imgs, err := base64.StdEncoding.DecodeString(imgBase64)
+	if err != nil {
+		logs.Debug("base64 decode error:", err)
+		result["status"] = contanst.MSG_ERR
+		result["message"] = ""
+		result["image"] = ""
+		return result
+	}
+	timenow := time.Now().Unix()
+	file, err := os.OpenFile(UPLOAD_DIR+strconv.FormatInt(timenow, 10)+".jpg", os.O_CREATE|os.O_WRONLY, 0644)
+	if err != nil {
+		logs.Debug("create file error:", err)
+		result["status"] = contanst.MSG_ERR
+		result["message"] = ""
+		result["image"] = ""
+		return result
+	}
+	w := bufio.NewWriter(file) //创建新的 Writer 对象
+
+	_, err3 := w.WriteString(string(imgs))
+	if err3 != nil {
+		logs.Debug("write error:", err3)
+		result["status"] = contanst.MSG_ERR
+		result["message"] = ""
+		result["image"] = ""
+		return result
+	}
+	w.Flush()
+	defer file.Close()
+	imgname := strconv.FormatInt(timenow, 10) + ".jpg"
+	result["status"] = contanst.MSG_ERR
+	result["image"] = imgname
+	return result
+}
+
+func (this *ImageUpload)checkFileIsExist(filename string) bool {
+	var exist = true
+	if _, err := os.Stat(filename); os.IsNotExist(err) {
+		exist = false
+	}
+	return exist
+}
+
+

+ 20 - 0
libs/validate.go

@@ -0,0 +1,20 @@
+package libs
+
+import "regexp"
+
+type IValidate struct {
+
+}
+
+func Validate() (*IValidate) {
+	return new(IValidate)
+}
+
+// 验证手机号码
+func (*IValidate)IsPhone(phone string)(bool)  {
+	regular := "^(13[0-9]|14[57]|15[0-35-9]|18[07-9])\\\\d{8}$"
+	reg := regexp.MustCompile(regular)
+	return reg.MatchString(phone)
+}
+
+

+ 17 - 0
main.go

@@ -0,0 +1,17 @@
+package main
+
+import (
+	_ "wuyebaoxiuapi/routers"
+	"wuyebaoxiuapi/utils"
+	"github.com/patrickmn/go-cache"
+	"time"
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/initial"
+)
+
+func main() {
+	//println(libs.Md5([]byte("123456"+"i8Nf")))
+	initial.Init()
+	utils.Che = cache.New(60*time.Minute, 120*time.Minute)
+	beego.Run()
+}

+ 201 - 0
models/backgroundm/admin.go

@@ -0,0 +1,201 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-16 15:42:43
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 11:48:17
+***********************************************/
+package backgroundm
+
+import (
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type Admin struct {
+	Id         int
+	LoginName  string
+	RealName   string
+	Password   string
+	RoleIds    string
+	Phone      string
+	Email      string
+	Salt       string
+	LastLogin  int64
+	LastIp     string
+	Status     int
+	CreateId   int
+	UpdateId   int
+	CreateTime int64
+	UpdateTime int64
+
+	Gender int
+	NickName string
+	AvatarUrl string
+	Openid string
+	School string
+	DailyAddress string
+	Rating int
+	Types int // 类型(0:管理员,1:维修人员,2:保修用户)
+}
+
+func (a *Admin) TableName() string {
+	return models.TableName("uc_admin")
+}
+func init() {
+	orm.RegisterModel(new(Admin))
+}
+
+func AdminAdd(a *Admin) (int64, error) {
+	return orm.NewOrm().Insert(a)
+}
+
+func AdminGetByName(loginName string) (*Admin, error) {
+	a := new(Admin)
+	err := orm.NewOrm().QueryTable(models.TableName("uc_admin")).Filter("login_name", loginName).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+}
+
+func AdminGetList(page, pageSize int, filters ...interface{}) ([]*Admin, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*Admin, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("uc_admin"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+	return list, total
+}
+
+func AdminGetById(id int) (*Admin, error) {
+	r := new(Admin)
+	err := orm.NewOrm().QueryTable(models.TableName("uc_admin")).Filter("id", id).One(r)
+	if err != nil {
+		return nil, err
+	}
+	return r, nil
+}
+
+func (a *Admin) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}
+
+// func RoleAuthDelete(id int) (int64, error) {
+// 	query := orm.NewOrm().QueryTable(TableName("role_auth"))
+// 	return query.Filter("role_id", id).Delete()
+// }
+
+// func RoleAuthMultiAdd(ras []*RoleAuth) (n int, err error) {
+// 	query := orm.NewOrm().QueryTable(TableName("role_auth"))
+// 	i, _ := query.PrepareInsert()
+// 	for _, ra := range ras {
+// 		_, err := i.Insert(ra)
+// 		if err == nil {
+// 			n = n + 1
+// 		}
+// 	}
+// 	i.Close() // 别忘记关闭 statement
+// 	return n, err
+// }
+
+
+
+//#########################用户#######################################
+
+
+// 根据openid,查找用户信息。用于用户小程序登录是否已经注册。
+func FindUserInfoByOpenid(openid string)(*Admin,error)  {
+
+	a := new(Admin)
+	println(a)
+	err := orm.NewOrm().QueryTable(models.TableName("uc_admin")).Filter("openid", openid).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+
+
+}
+
+func UserAdd(a *Admin)(int64, error)  {
+	return orm.NewOrm().Insert(a)
+}
+
+func FindUserInfoByName(loginName string) (*Admin, error) {
+	a := new(Admin)
+	err := orm.NewOrm().QueryTable(models.TableName("uc_admin")).Filter("login_name", loginName).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+
+}
+
+func (a *Admin) UpdatePassword(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}
+
+
+//##################维修工人#######################
+type RepairWorkerCount struct {
+	Count int64
+}
+// 维修工人
+type RepairWorker struct {
+	Id         int
+	LoginName  string
+	Phone      string
+	NickName string
+	AvatarUrl string
+	WRepairCount int64
+	HRepairCount int64
+}
+
+
+// 查找维修工人数量
+func (a *Admin)FindRepairWorkerCount()(int64)  {
+	o := orm.NewOrm()
+	repairWorkerCount := new(RepairWorkerCount)
+	err := o.Raw("SELECT count(*)" +
+		" as count FROM pp_uc_admin WHERE types = 2").QueryRow(&repairWorkerCount)
+
+	if err != nil {
+		return 0
+	}
+	return repairWorkerCount.Count
+}
+
+// 查找维修人列表
+func (a *Admin)FindRepairWorkers(page int , pageSize int)([]*Admin,int64)  {
+	list := make([]*Admin, 0)
+	qb, _ := orm.NewQueryBuilder("mysql")
+	qBuilder := qb.Select("*").From("pp_uc_admin").
+		Where("id > 0")
+
+	//qBuilder.And("types = 2")
+	offset := (page - 1) * pageSize
+	qBuilder.OrderBy("id").
+		Desc().
+		Limit(pageSize).
+		Offset(offset)
+	sql := qBuilder.String()
+	o := orm.NewOrm()
+	total, err := o.Raw(sql).QueryRows(&list)
+	if err != nil {
+		return  nil,0
+	}
+	return list,total
+}

+ 141 - 0
models/backgroundm/api_detail.go

@@ -0,0 +1,141 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-16 15:42:43
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-10-09 11:48:17
+***********************************************/
+package backgroundm
+
+import (
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type ApiDetail struct {
+	Id         int
+	SourceId   int
+	Method     int
+	ApiName    string
+	ApiUrl     string
+	Detail     string
+	Status     int
+	CreateId   int
+	AuditId    int
+	UpdateId   int
+	CreateTime int64
+	UpdateTime int64
+	AuditTime  int64
+}
+type ApiDetails struct {
+	Id         int
+	SourceId   int
+	Method     int
+	ApiName    string
+	ApiUrl     string
+	Detail     string
+	Status     int
+	CreateId   int
+	AuditId    int
+	UpdateId   int
+	CreateTime int64
+	UpdateTime int64
+	AuditTime  int64
+	CreateName string
+	UpdateName string
+	AuditName  string
+}
+
+type ApiSourceList struct {
+	Id         int
+	SourceName string
+	ApiLists   []*ApiList
+}
+
+type ApiList struct {
+	Id      int
+	Method  int
+	ApiName string
+}
+func init() {
+	orm.RegisterModel(new(ApiDetail))
+}
+func ApiTreeData(groupId int) ([]*ApiSourceList, error) {
+	list := make([]*ApiSourceList, 0)
+	sql := "SELECT id,source_name FROM pp_api_source WHERE group_id=?"
+	orm.NewOrm().Raw(sql, groupId).QueryRows(&list)
+	apiList := make([]*ApiSourceList, 0)
+	for _, apisource := range list {
+		detailList := make([]*ApiList, 0)
+		detail_sql := "SELECT id,method,api_name FROM pp_api_detail WHERE source_id=? AND status=3"
+		orm.NewOrm().Raw(detail_sql, apisource.Id).QueryRows(&detailList)
+		apisource.ApiLists = detailList
+		apiList = append(apiList, apisource)
+	}
+	return apiList, nil
+}
+
+func (a *ApiDetail) TableName() string {
+	return models.TableName("api_detail")
+}
+
+func ApiDetailAdd(a *ApiDetail) (int64, error) {
+	return orm.NewOrm().Insert(a)
+}
+
+func ApiDetailGetById(id int) (*ApiDetail, error) {
+	r := new(ApiDetail)
+	err := orm.NewOrm().QueryTable(models.TableName("api_detail")).Filter("id", id).One(r)
+	if err != nil {
+		return nil, err
+	}
+	return r, nil
+}
+
+func ApiFullDetailById(id int) (detail *ApiDetails, err error) {
+	sql := "SELECT pp_api_detail.*,a.real_name as create_name,b.real_name as update_name,c.real_name as audit_name FROM pp_api_detail LEFT JOIN pp_uc_admin as a ON pp_api_detail.create_id=a.id  LEFT JOIN pp_uc_admin as b ON pp_api_detail.update_id=b.id  LEFT JOIN pp_uc_admin as c ON pp_api_detail.audit_id=c.id  WHERE pp_api_detail.id=?"
+	err = orm.NewOrm().Raw(sql, id).QueryRow(&detail)
+	return
+}
+
+func ApiDetailsGetById(id int) ([]*ApiDetails, error) {
+	list := make([]*ApiDetails, 0)
+	sql := "SELECT pp_api_detail.*,a.real_name as create_name,b.real_name as update_name,c.real_name as audit_name FROM pp_api_detail LEFT JOIN pp_uc_admin as a ON pp_api_detail.create_id=a.id  LEFT JOIN pp_uc_admin as b ON pp_api_detail.update_id=b.id LEFT JOIN pp_uc_admin as c ON pp_api_detail.audit_id=c.id WHERE pp_api_detail.source_id=?"
+	orm.NewOrm().Raw(sql, id).QueryRows(&list)
+
+	return list, nil
+}
+
+func ApiDetailGetList(page, pageSize int, filters ...interface{}) ([]*ApiDetail, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*ApiDetail, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("api_detail"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+
+	return list, total
+}
+
+func (a *ApiDetail) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}
+
+func ApiChangeStatus(ids string, status int) (num int64, err error) {
+
+	sql := "UPDATE pp_api_detail set status=? where id in (" + ids + ")"
+	res, err := orm.NewOrm().Raw(sql, status).Exec()
+	num = 0
+	if err == nil {
+		num, _ = res.RowsAffected()
+	}
+	return num, err
+}

+ 85 - 0
models/backgroundm/api_public.go

@@ -0,0 +1,85 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-16 15:42:43
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-10-09 11:48:17
+***********************************************/
+package backgroundm
+
+import (
+	"time"
+
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type ApiPublic struct {
+	Id            int
+	ApiPublicName string
+	Detail        string
+	Sort          int
+	Status        int
+	CreateId      int
+	UpdateId      int
+	CreateTime    int64
+	UpdateTime    int64
+}
+
+func (a *ApiPublic) TableName() string {
+	return models.TableName("api_public")
+}
+
+func ApiPublicGetList(page, pageSize int, filters ...interface{}) ([]*ApiPublic, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*ApiPublic, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("api_public"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("sort").Limit(pageSize, offset).All(&list)
+
+	return list, total
+}
+
+func ApiPublicAdd(a *ApiPublic) (int64, error) {
+	return orm.NewOrm().Insert(a)
+}
+
+func ApiPublicGetById(id int) (ApiPublic, error) {
+	var list ApiPublic
+	query := orm.NewOrm().QueryTable(models.TableName("api_public"))
+	query.Filter("id", id).Filter("status", 1).One(&list)
+	return list, nil
+}
+
+func ApiPublicGetByIds(ids string) ([]*ApiPublic, error) {
+	list := make([]*ApiPublic, 0)
+	sql := "SELECT * FROM pp_api_public WHERE id in(" + ids + ")"
+	orm.NewOrm().Raw(sql).QueryRows(&list)
+
+	return list, nil
+}
+func init() {
+	orm.RegisterModel(new(ApiPublic))
+}
+func (a *ApiPublic) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (a *ApiPublic) Delete(id int64, update_id int) (int64, error) {
+	sql := "UPDATE pp_api_public SET status=0,update_id=?,update_time=? WHERE id=?"
+	res, err := orm.NewOrm().Raw(sql, update_id, time.Now().Unix(), id).Exec()
+	if err == nil {
+		num, _ := res.RowsAffected()
+		return num, nil
+	}
+	return 0, err
+}

+ 77 - 0
models/backgroundm/api_source.go

@@ -0,0 +1,77 @@
+/**********************************************
+** @Des: 接口资源
+** @Author: haodaquan
+** @Date:   2018-01-14 15:42:43
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2018-01-14 15:42:43
+***********************************************/
+package backgroundm
+
+import (
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type ApiSource struct {
+	Id         int
+	GroupId    int
+	SourceName string
+	Status     int
+	CreateId   int
+	AuditId    int
+	UpdateId   int
+	CreateTime int64
+	UpdateTime int64
+	AuditTime  int64
+}
+
+func (a *ApiSource) TableName() string {
+	return models.TableName("api_source")
+}
+
+func ApiSourceAdd(a *ApiSource) (int64, error) {
+	return orm.NewOrm().Insert(a)
+}
+
+func ApiSourceGetByName(ApiSourceName string) (*ApiSource, error) {
+	a := new(ApiSource)
+	err := orm.NewOrm().QueryTable(models.TableName("api_source")).Filter("source_name", ApiSourceName).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+}
+
+func ApiSourceGetList(page, pageSize int, filters ...interface{}) ([]*ApiSource, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*ApiSource, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("api_source"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+	// total := int64(12)
+	return list, total
+}
+func init() {
+	orm.RegisterModel(new(ApiSource))
+}
+func ApiSourceGetById(id int) (*ApiSource, error) {
+	r := new(ApiSource)
+	err := orm.NewOrm().QueryTable(models.TableName("api_source")).Filter("id", id).One(r)
+	if err != nil {
+		return nil, err
+	}
+	return r, nil
+}
+
+func (a *ApiSource) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}

+ 95 - 0
models/backgroundm/auth.go

@@ -0,0 +1,95 @@
+/**********************************************
+** @Des: 权限因子
+** @Author: haodaquan
+** @Date:   2017-09-09 20:50:36
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 21:42:08
+***********************************************/
+package backgroundm
+
+import (
+	"fmt"
+
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type Auth struct {
+	Id         int
+	AuthName   string
+	AuthUrl    string
+	UserId     int
+	Pid        int
+	Sort       int
+	Icon       string
+	IsShow     int
+	Status     int
+	CreateId   int
+	UpdateId   int
+	CreateTime int64
+	UpdateTime int64
+}
+
+func (a *Auth) TableName() string {
+	return models.TableName("uc_auth")
+}
+
+func AuthGetList(page, pageSize int, filters ...interface{}) ([]*Auth, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*Auth, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("uc_auth"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("pid", "sort").Limit(pageSize, offset).All(&list)
+
+	return list, total
+}
+
+func AuthGetListByIds(authIds string, userId int) ([]*Auth, error) {
+
+	list1 := make([]*Auth, 0)
+	var list []orm.Params
+	//list:=[]orm.Params
+	var err error
+	if userId == 1 {
+		//超级管理员
+		_, err = orm.NewOrm().Raw("select id,auth_name,auth_url,pid,icon,is_show from pp_uc_auth where status=? order by pid asc,sort asc", 1).Values(&list)
+	} else {
+		_, err = orm.NewOrm().Raw("select id,auth_name,auth_url,pid,icon,is_show from pp_uc_auth where status=1 and id in("+authIds+") order by pid asc,sort asc", authIds).Values(&list)
+	}
+
+	for k, v := range list {
+		fmt.Println(k, v)
+	}
+
+	fmt.Println(list)
+	return list1, err
+}
+
+func AuthAdd(auth *Auth) (int64, error) {
+	return orm.NewOrm().Insert(auth)
+}
+func init() {
+	orm.RegisterModel(new(Auth))
+}
+func AuthGetById(id int) (*Auth, error) {
+	a := new(Auth)
+
+	err := orm.NewOrm().QueryTable(models.TableName("uc_auth")).Filter("id", id).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+}
+
+func (a *Auth) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}

+ 84 - 0
models/backgroundm/code.go

@@ -0,0 +1,84 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-16 15:42:43
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-25 11:48:17
+***********************************************/
+package backgroundm
+
+import (
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type Code struct {
+	Id         int
+	Code       string
+	Desc       string
+	Detail     string
+	Status     int
+	CreateId   int
+	UpdateId   int
+	CreateTime int64
+	UpdateTime int64
+}
+
+func (a *Code) TableName() string {
+	return models.TableName("set_code")
+}
+
+func CodeAdd(a *Code) (int64, error) {
+	return orm.NewOrm().Insert(a)
+}
+
+func CodeGetByName(CodeName string) (*Code, error) {
+	a := new(Code)
+	err := orm.NewOrm().QueryTable(models.TableName("set_code")).Filter("code", CodeName).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+}
+
+func CodeGetList(page, pageSize int, filters ...interface{}) ([]*Code, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*Code, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("set_code"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+
+	return list, total
+}
+
+func CodeGetByIds(ids string) ([]*Code, error) {
+	list := make([]*Code, 0)
+	sql := "SELECT * FROM pp_set_code WHERE id in(" + ids + ")"
+	orm.NewOrm().Raw(sql).QueryRows(&list)
+
+	return list, nil
+}
+func init() {
+	orm.RegisterModel(new(Code))
+}
+func CodeGetById(id int) (*Code, error) {
+	r := new(Code)
+	err := orm.NewOrm().QueryTable(models.TableName("set_code")).Filter("id", id).One(r)
+	if err != nil {
+		return nil, err
+	}
+	return r, nil
+}
+
+func (a *Code) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}

+ 83 - 0
models/backgroundm/env.go

@@ -0,0 +1,83 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-16 15:42:43
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-25 11:48:17
+***********************************************/
+package backgroundm
+
+import (
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type Env struct {
+	Id         int
+	EnvName    string
+	EnvHost    string
+	Detail     string
+	Status     int
+	CreateId   int
+	UpdateId   int
+	CreateTime int64
+	UpdateTime int64
+}
+
+func (a *Env) TableName() string {
+	return models.TableName("set_env")
+}
+
+func EnvAdd(a *Env) (int64, error) {
+	return orm.NewOrm().Insert(a)
+}
+
+func EnvGetByName(EnvName string) (*Env, error) {
+	a := new(Env)
+	err := orm.NewOrm().QueryTable(models.TableName("set_env")).Filter("env_name", EnvName).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+}
+
+func EnvGetList(page, pageSize int, filters ...interface{}) ([]*Env, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*Env, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("set_env"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+	return list, total
+}
+
+func EnvGetByIds(ids string) ([]*Env, error) {
+	list := make([]*Env, 0)
+	sql := "SELECT * FROM pp_set_env WHERE id in(" + ids + ")"
+	orm.NewOrm().Raw(sql).QueryRows(&list)
+
+	return list, nil
+}
+func init() {
+	orm.RegisterModel(new(Env))
+}
+func EnvGetById(id int) (*Env, error) {
+	r := new(Env)
+	err := orm.NewOrm().QueryTable(models.TableName("set_env")).Filter("id", id).One(r)
+	if err != nil {
+		return nil, err
+	}
+	return r, nil
+}
+
+func (a *Env) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}

+ 77 - 0
models/backgroundm/group.go

@@ -0,0 +1,77 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-16 15:42:43
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-24 11:48:17
+***********************************************/
+package backgroundm
+
+import (
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type Group struct {
+	Id           int
+	GroupName    string
+	Detail       string
+	ApiPublicIds string
+	CodeIds      string
+	EnvIds       string
+	Status       int
+	CreateId     int
+	UpdateId     int
+	CreateTime   int64
+	UpdateTime   int64
+}
+
+func (a *Group) TableName() string {
+	return models.TableName("set_group")
+}
+
+func GroupAdd(a *Group) (int64, error) {
+	return orm.NewOrm().Insert(a)
+}
+
+func GroupGetByName(groupName string) (*Group, error) {
+	a := new(Group)
+	err := orm.NewOrm().QueryTable(models.TableName("set_group")).Filter("group_name", groupName).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+}
+
+func GroupGetList(page, pageSize int, filters ...interface{}) ([]*Group, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*Group, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("set_group"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+	return list, total
+}
+func init() {
+	orm.RegisterModel(new(Group))
+}
+func GroupGetById(id int) (*Group, error) {
+	r := new(Group)
+	err := orm.NewOrm().QueryTable(models.TableName("set_group")).Filter("id", id).One(r)
+	if err != nil {
+		return nil, err
+	}
+	return r, nil
+}
+
+func (a *Group) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}

+ 69 - 0
models/backgroundm/role.go

@@ -0,0 +1,69 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-14 15:24:51
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 11:48:52
+***********************************************/
+package backgroundm
+
+import (
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type Role struct {
+	Id         int
+	RoleName   string
+	Detail     string
+	Status     int
+	CreateId   int
+	UpdateId   int
+	CreateTime int64
+	UpdateTime int64
+}
+
+func (a *Role) TableName() string {
+	return models.TableName("uc_role")
+}
+
+func RoleGetList(page, pageSize int, filters ...interface{}) ([]*Role, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*Role, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("uc_role"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+	return list, total
+}
+
+func RoleAdd(role *Role) (int64, error) {
+	id, err := orm.NewOrm().Insert(role)
+	if err != nil {
+		return 0, err
+	}
+	return id, nil
+}
+func init() {
+	orm.RegisterModel(new(Role))
+}
+func RoleGetById(id int) (*Role, error) {
+	r := new(Role)
+	err := orm.NewOrm().QueryTable(models.TableName("uc_role")).Filter("id", id).One(r)
+	if err != nil {
+		return nil, err
+	}
+	return r, nil
+}
+
+func (r *Role) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(r, fields...); err != nil {
+		return err
+	}
+	return nil
+}

+ 80 - 0
models/backgroundm/role_auth.go

@@ -0,0 +1,80 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-15 11:44:13
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-17 11:49:13
+***********************************************/
+package backgroundm
+
+import (
+	"bytes"
+	"strconv"
+	"strings"
+
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type RoleAuth struct {
+	AuthId int `orm:"pk"`
+	RoleId int64
+}
+
+func (ra *RoleAuth) TableName() string {
+	return models.TableName("uc_role_auth")
+}
+
+func RoleAuthAdd(ra *RoleAuth) (int64, error) {
+	return orm.NewOrm().Insert(ra)
+}
+
+func RoleAuthGetById(id int) ([]*RoleAuth, error) {
+	list := make([]*RoleAuth, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("uc_role_auth"))
+	_, err := query.Filter("role_id", id).All(&list, "AuthId")
+	if err != nil {
+		return nil, err
+	}
+	return list, nil
+}
+
+func RoleAuthDelete(id int) (int64, error) {
+	query := orm.NewOrm().QueryTable(models.TableName("uc_role_auth"))
+	return query.Filter("role_id", id).Delete()
+}
+
+//获取多个
+func RoleAuthGetByIds(RoleIds string) (Authids string, err error) {
+	list := make([]*RoleAuth, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("uc_role_auth"))
+	ids := strings.Split(RoleIds, ",")
+	_, err = query.Filter("role_id__in", ids).All(&list, "AuthId")
+	if err != nil {
+		return "", err
+	}
+	b := bytes.Buffer{}
+	for _, v := range list {
+		if v.AuthId != 0 && v.AuthId != 1 {
+			b.WriteString(strconv.Itoa(v.AuthId))
+			b.WriteString(",")
+		}
+	}
+	Authids = strings.TrimRight(b.String(), ",")
+	return Authids, nil
+}
+func init() {
+	orm.RegisterModel(new(RoleAuth))
+}
+func RoleAuthMultiAdd(ras []*RoleAuth) (n int, err error) {
+	query := orm.NewOrm().QueryTable(models.TableName("uc_role_auth"))
+	i, _ := query.PrepareInsert()
+	for _, ra := range ras {
+		_, err := i.Insert(ra)
+		if err == nil {
+			n = n + 1
+		}
+	}
+	i.Close() // 别忘记关闭 statement
+	return n, err
+}

+ 76 - 0
models/backgroundm/template.go

@@ -0,0 +1,76 @@
+/**********************************************
+** @Des: markdown模板
+** @Author: haodaquan
+** @Date:   2018-01-16 15:42:43
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2018-01-16 11:48:17
+***********************************************/
+package backgroundm
+
+import (
+	"time"
+
+	"github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models"
+)
+
+type Template struct {
+	Id           int
+	TemplateName string
+	Detail       string
+	Status       int
+	CreateId     int
+	UpdateId     int
+	CreateTime   int64
+	UpdateTime   int64
+}
+
+func (a *Template) TableName() string {
+	return models.TableName("set_template")
+}
+
+func TemplateGetList(page, pageSize int, filters ...interface{}) ([]*Template, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*Template, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("set_template"))
+	if len(filters) > 0 {
+		l := len(filters)
+		for k := 0; k < l; k += 2 {
+			query = query.Filter(filters[k].(string), filters[k+1])
+		}
+	}
+	total, _ := query.Count()
+	query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+
+	return list, total
+}
+
+func TemplateAdd(a *Template) (int64, error) {
+	return orm.NewOrm().Insert(a)
+}
+
+func TemplateGetById(id int) (Template, error) {
+	var list Template
+	query := orm.NewOrm().QueryTable(models.TableName("set_template"))
+	query.Filter("id", id).Filter("status", 1).One(&list)
+	return list, nil
+}
+func init() {
+	orm.RegisterModel(new(Template))
+}
+func (a *Template) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (a *Template) Delete(id int64, update_id int) (int64, error) {
+	sql := "UPDATE pp_set_template SET status=0,update_id=?,update_time=? WHERE id=?"
+	res, err := orm.NewOrm().Raw(sql, update_id, time.Now().Unix(), id).Exec()
+	if err == nil {
+		num, _ := res.RowsAffected()
+		return num, nil
+	}
+	return 0, err
+}

+ 59 - 0
models/commonm/property_notice.go

@@ -0,0 +1,59 @@
+package commonm
+
+import ("github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models")
+
+// 物业公告
+type PropertyNotice struct {
+	Id int
+	Title string
+	Content string
+	CreateTime int
+	FCreateTime string
+}
+func init() {
+	orm.RegisterModel(new(PropertyNotice))
+}
+func (a *PropertyNotice) TableName() string {
+	return models.TableName("property_notice")
+}
+func NewPropertyNotice()(*PropertyNotice)  {
+	return new(PropertyNotice)
+}
+
+func (a *PropertyNotice) Add(propertyNotice *PropertyNotice)(int64, error) {
+	return orm.NewOrm().Insert(a)
+}
+
+func (a *PropertyNotice)FindPropertyNotices(page, pageSize int) ([]*PropertyNotice, int64) {
+	offset := (page - 1) * pageSize
+	list := make([]*PropertyNotice, 0)
+	query := orm.NewOrm().QueryTable(models.TableName("property_notice"))
+	total, _ := query.Count()
+	query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+	return list, total
+}
+
+func (a *PropertyNotice)FindPropertyNoticeById(id int) (*PropertyNotice, error) {
+	err := orm.NewOrm().QueryTable(models.TableName("property_notice")).Filter("id", id).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+}
+
+func (a *PropertyNotice) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (a *PropertyNotice)Delete(id int) (int64, error) {
+	query := orm.NewOrm().QueryTable(models.TableName("property_notice"))
+	return query.Filter("id", id).Delete()
+}
+
+
+
+

+ 34 - 0
models/frontm/picture.go

@@ -0,0 +1,34 @@
+package frontm
+
+import ("github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models")
+
+type Picture struct {
+	Id  int
+	CreateTime int
+	Path string
+}
+
+func NewPicture()(*Picture)  {
+	return new(Picture)
+}
+func init() {
+	orm.RegisterModel(new(Picture))
+}
+func (a *Picture) TableName() string {
+	return models.TableName("picture")
+}
+
+func (a *Picture)Add()(int64, error)  {
+	return orm.NewOrm().Insert(a)
+}
+
+func (a *Picture)FindPictureByPath(path string) (*Picture,error) {
+	err := orm.NewOrm().QueryTable(models.TableName("picture")).Filter("path", path).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+}
+
+

+ 264 - 0
models/frontm/repair.go

@@ -0,0 +1,264 @@
+package frontm
+
+import (
+	"github.com/astaxie/beego/orm"
+ "wuyebaoxiuapi/models"
+)
+
+// 报修
+type Repair struct {
+	Id int
+	School string
+	Position string
+	ApplicantName string
+	ApplicantPhone string
+	ApplicantUserId int
+	CreateTime int
+	RepairUserId int
+	Status int
+	RepairTime int
+	ApplicantContent string
+	Address string
+	//RepairUserPicture *RepairUserPicture `orm:"rel(fk)"`
+}
+
+type RepairCount struct {
+	Count int64
+}
+
+type OutReRepair struct {
+	Id int
+	School string
+	Position string
+	ApplicantName string
+	ApplicantPhone string
+	ApplicantUserId int
+	CreateTime int
+	RepairUserId int
+	Status int
+	RepairTime int
+	ApplicantContent string
+	Address string
+	RepairImages []string   // 报修图片
+	ServiceImages []string  // 维修图片
+}
+
+
+func (a *Repair) TableName() string {
+	return models.TableName("repair")
+}
+func init() {
+	orm.RegisterModel(new(Repair))
+}
+func NewRepair() *Repair {
+	return new(Repair)
+}
+func RepairAdd(a *Repair)(int64, error)  {
+	return orm.NewOrm().Insert(a)
+}
+// 报修用户报修列表
+func (a *Repair)FindRepairUserRepairs(userid int,page int , pageSize int)([]*Repair,int64)  {
+	return a.FindRepairsByUserId(userid,page,pageSize)
+}
+
+func (a *Repair)FindRepairsByUserId(userid int,page int , pageSize int) ([]*Repair,int64) {
+	list := make([]*Repair, 0)
+	qBuilder := a.UserRepairQBuilder("*")
+	qBuilder.And("applicant_user_id = ?")
+	qBuilder.And("status > 0")
+	offset := (page - 1) * pageSize
+	qBuilder.OrderBy("id").
+		Desc().
+		Limit(pageSize).
+		Offset(offset)
+	sql := qBuilder.String()
+	o := orm.NewOrm()
+	total, err := o.Raw(sql, userid).QueryRows(&list)
+	if err != nil {
+		return  nil,0
+	}
+	return list,total
+}
+// 报修用户报修数量
+func (a *Repair)FindRepairUserRepairCount(userid int)(int64)  {
+	return a.findRepairCountByStatus(userid,2,"status > 0")
+}
+
+// --------------维修用户维修管理----------------------
+// 查找维修用户待维修数量
+func (a *Repair)FindServiceUserWRepairCount(userid int)(int64)  {
+	return a.findRepairCountByStatus(userid,2,"status = 2")
+}
+// 查找维修用户已维修数量
+func (a *Repair)FindServiceUserHRepairCount(userid int)(int64)  {
+	return a.findRepairCountByStatus(userid,2,"status > 2")
+}
+// 查找维修用户待维修列表
+func (a *Repair)FindServiceUserWRepairs(userid int,page int , pageSize int)([]*Repair,int64)  {
+	list := make([]*Repair, 0)
+	qBuilder := a.UserRepairQBuilder("*")
+	qBuilder.And("applicant_user_id = ?")
+	qBuilder.And("status = 2")
+	offset := (page - 1) * pageSize
+	qBuilder.OrderBy("id").
+		Desc().
+		Limit(pageSize).
+		Offset(offset)
+	sql := qBuilder.String()
+	o := orm.NewOrm()
+	total, err := o.Raw(sql, userid).QueryRows(&list)
+	if err != nil {
+		return  nil,0
+	}
+	return list,total
+}
+// 查找维修用户已维修列表
+func (a *Repair)FindServiceUserHRepairs(userid int,page int , pageSize int)([]*Repair,int64)  {
+	list := make([]*Repair, 0)
+	qBuilder := a.UserRepairQBuilder("*")
+	qBuilder.And("repair_user_id = ?")
+	qBuilder.And("status > 2")
+	offset := (page - 1) * pageSize
+	qBuilder.OrderBy("id").
+		Desc().
+		Limit(pageSize).
+		Offset(offset)
+	sql := qBuilder.String()
+	o := orm.NewOrm()
+	total, err := o.Raw(sql, userid).QueryRows(&list)
+	if err != nil {
+		return  nil,0
+	}
+	return list,total
+}
+
+// 确认维修
+func (a *Repair)ConfirmRepair()(int,error){
+	o := orm.NewOrm()
+	_, err := o.Raw("UPDATE pp_repair SET status = 3 , repair_time = ? WHERE id = ?" +
+		" and status = 2 and repair_user_id=?", a.RepairTime,a.Id, a.RepairUserId).Exec()
+	if err != nil {
+		return a.Id,nil
+	}
+	return 0,nil
+}
+
+
+// --------------管理员维修管理----------------------
+// 查找待维修数量
+func (a *Repair)FindAdminWRepairCount(userid int)(int64)  {
+	return a.findRepairCountByStatus(userid,0,"status > 0  and status < 3")
+}
+// 查找已维修数量
+func (a *Repair)FindAdminHRepairCount(userid int)(int64)  {
+	return a.findRepairCountByStatus(userid,0,"status >= 3")
+}
+
+// 查找待维修列表
+func (a *Repair)FindAdminWRepairs(page int , pageSize int)([]*Repair,int64)  {
+	list := make([]*Repair, 0)
+	qBuilder := a.UserRepairQBuilder("*")
+	qBuilder.And("status > 0  and status < 3")
+	offset := (page - 1) * pageSize
+	qBuilder.OrderBy("id").
+		Desc().
+		Limit(pageSize).
+		Offset(offset)
+	sql := qBuilder.String()
+	o := orm.NewOrm()
+	total, err := o.Raw(sql).QueryRows(&list)
+	if err != nil {
+		return  nil,0
+	}
+	return list,total
+}
+// 查找已维修列表
+func (a *Repair)FindAdminHRepairs(page int , pageSize int)([]*Repair,int64)  {
+	list := make([]*Repair, 0)
+	qBuilder := a.UserRepairQBuilder("*")
+	qBuilder.And("status >= 3")
+	offset := (page - 1) * pageSize
+	qBuilder.OrderBy("id").
+		Desc().
+		Limit(pageSize).
+		Offset(offset)
+	sql := qBuilder.String()
+	o := orm.NewOrm()
+	total, err := o.Raw(sql).QueryRows(&list)
+	if err != nil {
+		return  nil,0
+	}
+	return list,total
+}
+
+// 查找维修详情
+func (a *Repair)FindRepairById(id int)(*Repair,error)  {
+	err := orm.NewOrm().QueryTable(models.TableName("repair")).Filter("id", id).One(a)
+	if err != nil {
+		return nil, err
+	}
+	return a, nil
+}
+
+// 指派维修任务
+func (a *Repair)AssignRepairTask(id int,repairUserId int ) (int64,error) {
+	o := orm.NewOrm()
+	result, err := o.Raw("UPDATE pp_repair SET status = 2 , repair_user_id = ? WHERE id = ?" +
+		" and status = 1 ", repairUserId,id).Exec()
+	if err != nil {
+		return result.RowsAffected()
+	}
+	return 0,nil
+}
+
+// 用户报修SQL构造器
+func (a *Repair)UserRepairQBuilder(field string )(orm.QueryBuilder)  {
+	qb, _ := orm.NewQueryBuilder("mysql")
+	qBuilder := qb.Select(field).From("pp_repair ")
+	qBuilder.Where("id > 0")
+	//if userid > 0{
+	//	qBuilder.Where("userid = ?")
+	//}
+	return qBuilder
+}
+// 查找维修数量
+func (a *Repair)findRepairCountByStatus(userid int,types int, value string)(int64)  {
+	o := orm.NewOrm()
+	repairCount := new(RepairCount)
+	where := " id > 0"
+	if types == 1 {
+		where += " and repair_user_id =  ?"
+	}else if  types == 2{
+		where += " and applicant_user_id =  ?"
+	}
+	if value != "" {
+		where += " and "+value
+	}
+	var err error
+	if types == 0 {
+		err = o.Raw("SELECT count(*)" +
+			" as count FROM pp_repair WHERE"+where).QueryRow(&repairCount)
+	}else{
+		err = o.Raw("SELECT count(*)" +
+			" as count FROM pp_repair WHERE"+where,userid).QueryRow(&repairCount)
+	}
+
+	if err != nil {
+		return 0
+	}
+	return repairCount.Count
+}
+// 更新
+func (a *Repair) Update(fields ...string) error {
+	if _, err := orm.NewOrm().Update(a, fields...); err != nil {
+		return err
+	}
+	return nil
+}
+
+
+
+
+
+
+

+ 54 - 0
models/frontm/repair_user_picture.go

@@ -0,0 +1,54 @@
+package frontm
+
+import ("github.com/astaxie/beego/orm"
+	"wuyebaoxiuapi/models")
+
+type RepairUserPicture struct {
+	Id  int
+	UserId int
+	PictureId int
+	RepairId int
+	Types int
+}
+
+func NewRepairUserPicture()(*RepairUserPicture)  {
+	return new(RepairUserPicture)
+}
+
+func (a *RepairUserPicture) TableName() string {
+	return models.TableName("repair_user_picture")
+}
+
+func (a *RepairUserPicture)Add()(int64, error)  {
+	return orm.NewOrm().Insert(a)
+}
+
+func (a *RepairUserPicture)DeleteByPictureId(pictureId int) (int64, error) {
+	query := orm.NewOrm().QueryTable(models.TableName("repair_user_picture"))
+	return query.Filter("picture_id", pictureId).Delete()
+}
+
+type OutPicture struct {
+	Path string
+}
+// 查找维修图片
+func (a *RepairUserPicture)FindPictureByUserIdAndReparId(userid int,repairId int)([]string)  {
+	o := orm.NewOrm()
+	outPictures := make([]*OutPicture,0)
+	var err error
+	where := " pr.user_id = ? and pr.repair_id = ? and pr.types = 1 "
+	_,err = o.Raw("SELECT pp.path as path" +
+		" FROM pp_repair_user_picture pr left join pp_picture pp on pr.picture_id = pp.id WHERE"+where,userid,repairId).QueryRows(&outPictures)
+	if err != nil {
+		return nil
+	}
+	images := make([]string,0)
+	for _, v := range outPictures {
+		images = append(images,v.Path)
+	}
+	return images
+}
+
+func init() {
+	orm.RegisterModel(new(RepairUserPicture))
+}

+ 18 - 0
models/frontm/user.go

@@ -0,0 +1,18 @@
+package frontm
+
+type User struct {
+	Id         int
+	LoginName  string
+	Phone      string
+	CreateTime int64
+	Gender       int
+	NickName     string
+	AvatarUrl    string
+	Openid       string
+	School       string
+	DailyAddress string
+	Rating       int
+	Types int // 类型(0:管理员,1:维修人员,2:保修用户)
+}
+
+

+ 45 - 0
models/init.go

@@ -0,0 +1,45 @@
+/**********************************************
+** @Des: This file ...
+** @Author: haodaquan
+** @Date:   2017-09-08 00:18:02
+** @Last Modified by:   haodaquan
+** @Last Modified time: 2017-09-16 17:26:48
+***********************************************/
+
+package models
+
+import (
+	"github.com/astaxie/beego"
+	_ "github.com/go-sql-driver/mysql"
+)
+//
+//func Init() {
+//	dbhost := beego.AppConfig.String("db.host")
+//	dbport := beego.AppConfig.String("db.port")
+//	dbuser := beego.AppConfig.String("db.user")
+//	dbpassword := beego.AppConfig.String("db.password")
+//	dbname := beego.AppConfig.String("db.name")
+//	timezone := beego.AppConfig.String("db.timezone")
+//	if dbport == "" {
+//		dbport = "3306"
+//	}
+//	dsn := dbuser + ":" + dbpassword + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname + "?charset=utf8"
+//	// fmt.Println(dsn)
+//
+//	if timezone != "" {
+//		dsn = dsn + "&loc=" + url.QueryEscape(timezone)
+//	}
+//	orm.RegisterDataBase("default", "mysql", dsn)
+//	orm.RegisterModel(new(backgroundm.Auth), new(backgroundm.Role), new(backgroundm.RoleAuth), new(backgroundm.Admin),
+//		new(backgroundm.Group), new(backgroundm.Env), new(backgroundm.Code), new(backgroundm.ApiSource), new(backgroundm.ApiDetail), new(backgroundm.ApiPublic),
+//		new(backgroundm.Template),new(commonm.PropertyNotice),
+//		new(frontm.User),
+//	)
+//	if beego.AppConfig.String("runmode") == "dev" {
+//		orm.Debug = true
+//	}
+//}
+
+func TableName(name string) string {
+	return beego.AppConfig.String("db.prefix") + name
+}

File diff suppressed because it is too large
+ 298 - 0
ppgo_api_admin.sql


+ 85 - 0
routers/router.go

@@ -0,0 +1,85 @@
+package routers
+
+import (
+	"github.com/astaxie/beego"
+	"wuyebaoxiuapi/controllers/backgroundc"
+	"wuyebaoxiuapi/controllers/frontc"
+)
+
+func init() {
+	// 默认登录
+	beego.Router("/", &backgroundc.ApiDocController{}, "*:Index")
+	beego.Router("/login", &backgroundc.LoginController{}, "*:LoginIn")
+	beego.Router("/login_out", &backgroundc.LoginController{}, "*:LoginOut")
+	beego.Router("/no_auth", &backgroundc.LoginController{}, "*:NoAuth")
+
+	beego.Router("/home", &backgroundc.HomeController{}, "*:Index")
+	beego.Router("/home/start", &backgroundc.HomeController{}, "*:Start")
+	beego.AutoRouter(&backgroundc.ApiController{})
+	beego.AutoRouter(&backgroundc.ApiSourceController{})
+	beego.AutoRouter(&backgroundc.ApiPublicController{})
+	beego.AutoRouter(&backgroundc.TemplateController{})
+	beego.AutoRouter(&backgroundc.ApiDocController{})
+	// beego.AutoRouter(&controllers.ApiMonitorController{})
+	beego.AutoRouter(&backgroundc.EnvController{})
+	beego.AutoRouter(&backgroundc.CodeController{})
+
+	beego.AutoRouter(&backgroundc.GroupController{})
+	beego.AutoRouter(&backgroundc.AuthController{})
+	beego.AutoRouter(&backgroundc.RoleController{})
+	beego.AutoRouter(&backgroundc.AdminController{})
+	beego.AutoRouter(&backgroundc.UserController{})
+
+
+	beego.Router("/uploadimg", &backgroundc.UploadController{}, "*:UploadImage")
+
+	beego.Router("/propertynotice/edit", &backgroundc.PropertyNoticeController{}, "*:Edit")
+	beego.Router("/propertynotice/add", &backgroundc.PropertyNoticeController{}, "*:Add")
+	beego.Router("/propertynotice/index", &backgroundc.PropertyNoticeController{}, "*:Index")
+	beego.Router("/propertynotice/del", &backgroundc.PropertyNoticeController{}, "*:Del")
+
+	// 用户登录
+	beego.Router("/user/login", &frontc.LoginController{}, "*:Login")
+	// 更新密码
+	beego.Router("/user/updatePassword", &frontc.UserController{}, "*:UpdatePassword")
+	// 更新头像
+	beego.Router("/user/updateAvatarUrl", &frontc.UserController{}, "*:UpdateAvatarUrl")
+	// 更新学校
+	beego.Router("/user/updateSchool", &frontc.UserController{}, "*:UpdateSchool")
+	// 更新日常地址
+	beego.Router("/user/updateDailyAddress", &frontc.UserController{}, "*:UpdateDailyAddress")
+	// 更新手机号码
+	beego.Router("/user/updatepPhone", &frontc.UserController{}, "*:UpdatepPhone")
+	// 报修
+	beego.Router("/repair", &frontc.RepairController{}, "*:Repair")
+	// 报修用户报修数量
+	beego.Router("/userRepairCount", &frontc.UserRepairController{}, "*:UserRepairCount")
+	// 管理员报修数量
+	beego.Router("/adminRepairCount", &frontc.UserRepairController{}, "*:AdminRepairCount")
+	// 维修工人
+	beego.Router("/repairWorkers", &frontc.UserRepairController{}, "*:RepairWorkers")
+	// 管理员待维修列表
+	beego.Router("/adminWRepairs", &frontc.UserRepairController{}, "*:AdminWRepairs")
+	// 管理员已维修列表
+	beego.Router("/adminHRepairs", &frontc.UserRepairController{}, "*:AdminHRepairs")
+	// 报修用户报修列表
+	beego.Router("/repairUserRepairs", &frontc.UserRepairController{}, "*:RepairUserRepairs")
+	// 通知公告列表
+	beego.Router("/pn/list", &frontc.PropertyNoticeController{}, "*:List")
+	// 上传图片
+	beego.Router("/uploadImage", &frontc.BaseController{}, "*:UploadImage")
+	// 维修用户待维修列表
+	beego.Router("/serviceUserWRepairs", &frontc.UserRepairController{}, "*:ServiceUserWRepairs")
+	// 维修用户待维修列表
+	beego.Router("/serviceUserHRepairs", &frontc.UserRepairController{}, "*:ServiceUserHRepairs")
+	// 指派维修工人列表
+	beego.Router("/assignRepairWorkers", &frontc.UserRepairController{}, "*:AssignRepairWorkers")
+	// 指派维修任务
+	beego.Router("/assignRepairTask", &frontc.UserRepairController{}, "*:AssignRepairTask")
+	// 维修用户维修数量
+	beego.Router("/repairUserRepairCount", &frontc.UserRepairController{}, "*:RepairUserRepairCount")
+	// 确认维修
+	beego.Router("/confirmRepair", &frontc.UserRepairController{}, "*:ConfirmRepair")
+
+
+}

+ 1 - 0
static/README.md

@@ -0,0 +1 @@
+layui 2.1.2

+ 139 - 0
static/css/api.css

@@ -0,0 +1,139 @@
+@charset "utf-8";
+.nav-title{
+	margin-bottom: 0px;
+}
+.api_contrainer{
+	/*margin: 5px;*/
+	margin-top: 0px;
+	margin-right: 0px;
+	padding-right: 0px;
+	width: 100%;
+}
+.api_side{
+/*	border-top: 1px #e4e4e4 solid;
+	border-right: 1px #e4e4e4 solid;*/
+	padding:5px;
+	min-height: 500px;
+}
+
+.api_content{
+	border-left: 1px #f0f0f0 solid;
+	/*padding-left:5px;*/
+	min-height: 500px;
+}
+
+.api_list{
+	margin-top: 20px;
+}
+
+.api_list ul{
+
+}
+
+.api_list ul li{
+	color: #666;
+	display: block;
+	height: 35px;
+	line-height: 35px;
+}
+
+.api_list ul li.select{
+	background: rgb(236,248,238);
+	color: rgb(76,174,81);
+}
+.api_list ul li a {
+	display: block;
+	width: 60%;
+	float: left;
+}
+
+.api_list ul li span {
+	display: block;
+	width: 40%;
+	float: right;
+	display: none;
+	text-align: right;
+}
+
+.api_list ul li span a{
+	display: block;
+	width: 20px;
+	float: right;
+	margin-right: 10px;
+	color: rgb(76,174,81);
+}
+
+.api_list ul li span a:hover {
+	font-size: 16px;
+}
+
+.api_list ul li span a.red{
+	color: #FF5722;
+}
+
+
+/*.api_list ul li a:hover {
+	background: rgb(236,248,238);
+	color: rgb(76,174,81);
+	display: block;
+}*/
+
+/*.api_list ul li a.select {
+	background: rgb(236,248,238);
+	color: rgb(76,174,81);
+	display: block;
+}*/
+
+.api_info{
+	height:45px;
+	line-height: 45px;
+	background: #f6f6f6;
+	width: 100%
+}
+
+.api_info .title{
+	font-size: 14px;
+	float: left;
+	color: #009688;
+	text-indent: 0.5em;
+	font-weight: bold;
+}
+
+.api_info .tag{
+	font-size: 12px;
+	float: right;
+	color: #999;
+	padding-right: 5px;
+}
+
+.api-infos{
+	padding-left: 20px;
+	color: #666;
+	padding-bottom: 40px;
+}
+
+.api-infos .title{
+	font-size: 14px;
+	margin-top:20px;
+	color: #333;
+	margin-bottom: 10px;
+	font-weight: bold;
+}
+
+.api-infos ul{
+}
+
+.api-infos ul li{
+	display: block;
+	height: 30px;
+	line-height: 30px;
+}
+
+.desc{
+	font-size: 14px;
+	line-height: 20px;
+	color: #999;
+}
+
+
+

+ 69 - 0
static/css/apidoc.css

@@ -0,0 +1,69 @@
+@charset "utf-8";
+
+.site-tree{border-right: 1px solid #eee;height: 620px;}
+
+.site-tree .layui-tree {line-height: 25px;}
+.site-tree .layui-tree li {height: 25px}
+.site-tree .layui-tree li h2{line-height: 25px; 
+	font-size: 14px; padding-left: 20px;
+	cursor: pointer;
+	}
+.site-tree .layui-tree li :hover{background: #5FB878; color: #fff;}
+
+.site-tree .layui-tree .active{background: #5FB878; color: #fff;}
+.site-tree .layui-tree li a{
+	display: block;
+	height: 100%;
+	padding-left: 20px;}
+.site-tree .layui-tree li a cite{padding: 0 8px;}
+.site-tree .layui-tree .site-tree-noicon a cite{padding-left: 15px;}
+.site-tree .layui-tree li a em{
+	font-size: 12px;
+	color: #bbb;
+	padding-right: 5px; 
+	font-style: normal;}
+.copyrights{
+	position:absolute;
+	bottom: 0px;
+	height: 25px;
+	background: #efefef;
+	border:1px solid #e4e4e4;
+	width: 100%;
+	line-height: 25px;
+	text-align: center;
+	color: #999;
+}
+
+
+.site-content{
+
+}
+.site-content-header{
+	height: 60px;
+	line-height: 60px;
+	border-bottom: 1px solid #e4e4e4;
+	margin-bottom: 10px;
+}
+
+.site-content-header i{
+	font-size: 25px;
+	color: #999;
+	cursor: pointer;
+	padding-left: 20px;
+}
+
+.site-content-header span{
+	font-size: 20px;
+	color: #666;
+	cursor: pointer;
+}
+
+
+#api-main{
+	width: 99%;
+	overflow-y: scroll;
+	overflow-x:none;
+	padding-left: 10px;
+}
+
+

+ 312 - 0
static/css/app.css

@@ -0,0 +1,312 @@
+/** kit_admin-v1.0.5 MIT License By http://kit/zhengjinfan.cn e-mail:zheng_jinfan@126.com */
+.kit-sided .layui-side-scroll .layui-nav-item a,.layui-layout-admin .layui-header .layui-layout-right {
+	padding: 0
+}
+
+.kit-table,.kit-table .kit-table-header {
+	position: relative;
+	box-shadow: 0 1px 7px 0 #ccc
+}
+
+::-webkit-scrollbar {
+	width: 10px;
+	height: 10px
+}
+
+::-webkit-scrollbar-button:vertical {
+	display: none
+}
+
+::-webkit-scrollbar-corner,::-webkit-scrollbar-track {
+	background-color: #e2e2e2
+}
+
+::-webkit-scrollbar-thumb {
+	border-radius: 0;
+	background-color: rgba(0,0,0,.3)
+}
+
+::-webkit-scrollbar-thumb:vertical:hover {
+	background-color: rgba(0,0,0,.35)
+}
+
+::-webkit-scrollbar-thumb:vertical:active {
+	background-color: rgba(0,0,0,.38)
+}
+
+.kit-nav .layui-this,.layui-layout-left .layui-nav-item:hover {
+	background-color: #393D49!important
+}
+
+.kit-layout-admin .kit-logo-mobile {
+	display: none
+}
+
+.kit-nav .layui-nav-item {
+	line-height: 50px
+}
+
+.kit-nav .layui-nav-item .layui-nav-more {
+	top: 22px
+}
+
+.kit-nav .layui-nav-item .layui-nav-mored {
+	top: 16px
+}
+
+.kit-nav .layui-nav-item .layui-nav-child {
+	top: 55px
+}
+
+.kit-nav * {
+	font-size: 13px
+}
+
+.kit-nav .layui-nav-bar {
+	height: 0
+}
+
+.kit-nav .layui-this:after {
+	content: none
+}
+
+.kit-layout-admin .layui-footer {
+	height: 35px;
+	line-height: 35px
+}
+
+.kit-layout-admin .layui-body {
+	bottom: 35px;
+	top: 50px
+}
+
+.kit-layout-admin .layui-header {
+	height: 50px
+}
+
+.kit-layout-admin .layui-logo {
+	line-height: 50px
+}
+
+.kit-layout-admin .kit-side {
+	top: 50px
+}
+
+.kit-layout-admin .kit-sided {
+	width: 50px
+}
+
+.kit-side .layui-side-scroll,.kit-side .layui-side-scroll .layui-nav-tree {
+	width: auto
+}
+
+.kit-side .layui-side-scroll .kit-side-fold {
+	height: 35px;
+	background-color: #4A5064;
+	color: #aeb9c2;
+	line-height: 35px;
+	text-align: center;
+	cursor: pointer
+}
+
+.kit-sided .layui-side-scroll .layui-nav-item {
+	text-align: center
+}
+
+.kit-sided .layui-side-scroll a span {
+	display: none
+}
+
+.kit-layout-admin .kit-body-folded,.kit-layout-admin .kit-footer-folded {
+	left: 50px
+}
+
+.kit-table .kit-table-header {
+	height: 50px
+}
+
+.kit-table .kit-table-header .kit-search-btns {
+	padding: 10px;
+	position: absolute
+}
+
+.kit-table .kit-table-header .kit-search-inputs {
+	position: absolute;
+	right: 70px;
+	top: 0;
+	padding: 10px 25px 10px 10px
+}
+
+.kit-table .kit-table-header .kit-search-inputs .kit-search-keyword {
+	margin-right: 10px;
+	position: relative
+}
+
+.kit-table .kit-table-header .kit-search-inputs .kit-search-more {
+	cursor: pointer;
+	color: #009688;
+	position: absolute;
+	top: 15px;
+	right: -50px
+}
+
+.kit-table .kit-table-header .kit-search-inputs .kit-search-keyword input {
+	height: 30px;
+	line-height: 30px;
+	width: 200px;
+	padding-right: 32px
+}
+
+.kit-table .kit-table-header .kit-search-inputs .kit-search-keyword button {
+	position: absolute;
+	right: 0;
+	top: 0;
+	width: 30px;
+	height: 30px;
+	border: 0;
+	cursor: pointer;
+	background-color: #009688;
+	color: #fff
+}
+
+.kit-tab .kit-tab-tool,.kit-tab .kit-tab-tool-body .kit-line {
+	border-bottom: 1px solid #e2e2e2
+}
+
+.kit-table .kit-table-header .kit-search-btns .layui-btn {
+	padding: 0 15px
+}
+
+.kit-table .kit-search-mored {
+	width: 100%;
+	height: auto;
+	top: 51px;
+	background-color: #fff;
+	z-index: 5;
+	box-shadow: 0 4px 7px -3px #ccc;
+	position: absolute;
+	margin-bottom: 10px;
+	display: none
+}
+
+.kit-table .kit-search-mored .kit-search-body {
+	padding: 10px 10px 45px
+}
+
+.kit-table .kit-search-mored .kit-search-footer {
+	height: 50px;
+	bottom: 0;
+	left: 0;
+	position: absolute;
+	width: 100%;
+	border-top: 1px solid #e2e2e2;
+	text-align: right
+}
+
+.kit-tab,.kit-table .kit-table-body {
+	position: relative
+}
+
+.kit-table .kit-search-mored .kit-search-footer .kit-btn {
+	margin: 10px 5px;
+	padding: 0 15px
+}
+
+.kit-table .kit-search-mored .kit-search-footer .kit-btn:last-child {
+	margin-right: 15px
+}
+
+.kit-tab,.kit-table .kit-table-body .layui-table-view {
+	margin: 0
+}
+
+.kit-tab .kit-tab-tool {
+	position: absolute;
+	width: 10px;
+	height: 40px;
+	top: 0;
+	right: 10px;
+	/*border-left: 1px solid #e2e2e2;*/
+	line-height: 40px;
+	text-align: center;
+	cursor: pointer;
+	/*border-right: 1px solid #e2e2e2*/
+}
+
+.kit-tab .kit-tab-tool:hover {
+	background-color: #f3f3f3
+}
+
+.kit-tab .kit-tab-tool-body {
+	position: absolute;
+	top: 40px;
+	right: 10px;
+	width: 150px;
+	border: 1px solid #e2e2e2;
+	display: none;
+	background-color: #fff
+}
+
+.kit-tab .kit-tab-tool-body ul {
+	text-align: center;
+	padding: 8px 0
+}
+
+.kit-tab .kit-tab-tool-body ul li.kit-item {
+	line-height: 35px;
+	cursor: pointer;
+	color: #393D49
+}
+
+.kit-tab .kit-tab-tool-body ul li.kit-item:hover {
+	background-color: #f3f3f3
+}
+
+.kit-tab-bg{
+	background: #f2f2f2;
+}
+
+.kit-tab .layui-tab-title {
+	width: calc(100% - 20px);
+	padding-right: 0;
+	position: absolute
+}
+
+.kit-tab .layui-tab-content {
+	margin-top: 40px;
+	padding: 0
+}
+
+.kit-tab .layui-tab-content iframe {
+	width: 100%;
+	border: 0
+}
+
+@media screen and (max-width:950px) {
+	.kit-layout-admin .layui-body,.kit-layout-admin .layui-footer,.kit-layout-admin .layui-layout-left {
+		left: 50px
+	}
+
+	.kit-layout-admin .kit-side {
+		width: 50px
+	}
+
+	.kit-layout-admin .kit-side .layui-side-scroll .layui-nav li.layui-nav-item,.kit-layout-admin .kit-side .layui-side-scroll .layui-nav li.layui-nav-item dl dd {
+		text-align: center
+	}
+
+	.kit-layout-admin .kit-side .layui-side-scroll .layui-nav li.layui-nav-item a,.kit-layout-admin .kit-side .layui-side-scroll .layui-nav li.layui-nav-item dl dd a {
+		padding: 0;
+		cursor: pointer;
+	}
+
+	.kit-layout-admin .kit-side .layui-side-scroll .layui-nav li.layui-nav-item a span,.kit-layout-admin .kit-side .layui-side-scroll .layui-nav li.layui-nav-item dl dd a span,.kit-layout-admin .layui-logo,.kit-side .layui-side-scroll .kit-side-fold {
+		display: none;
+		cursor: pointer;
+	}
+
+	.kit-layout-admin .kit-logo-mobile {
+		display: block;
+		width: 50px
+	}
+}

+ 422 - 0
static/css/index.css

@@ -0,0 +1,422 @@
+h1,h2,h3{font-size: 14px;}
+
+.site-inline{font-size: 0;}
+.site-tree, .site-content{display: inline-block;  *display:inline; *zoom:1; vertical-align: top; font-size: 14px;}
+.site-tree{width: 220px; min-height: 900px; padding: 5px 0 20px;}
+.site-content{width: 899px; min-height: 900px; padding: 20px 0 10px 20px;}
+
+.header{height: 59px; border-bottom: 1px solid #404553;  background-color: #393D49;}
+.logo{position: absolute; left: 0; top: 16px;}
+.logo img{width: 82px; height: 31px;}
+.logo h1{ font-size: 24px; color: #fff }
+
+.header .layui-nav{position: absolute; right: 0; top: 0; padding: 0; background: none;}
+.header .layui-nav .layui-nav-item{margin: 0 20px; }
+.header .layui-nav .layui-nav-item[mobile]{display: none;}
+
+.header .layui-container .logo{left: 15px;}
+.header .layui-container .layui-nav{right: 15px;}
+
+.menu{position: absolute; right: 0; top: 0; line-height: 65px;}
+.menu a{display:inline-block; *display:inline; *zoom:1; vertical-align:top;}
+.menu a{position: relative; padding: 0 20px; margin: 0 20px; color: #c2c2c2; font-size: 14px;}
+.menu a:hover{color: #fff; transition: all .5s; -webkit-transition: all .5s}
+.menu a.this{color: #fff}
+.menu a.this::after{content: ''; position: absolute; left: 0; bottom: -1px; width: 100%; height: 5px; background-color: #5FB878;}
+
+.header-index{background-color: #05031A; border: none;}
+.header-index .site-banner-bg{}
+.header-index[spring]{background-color: #0D1206}
+.header-index[summer]{background-color: #0A0E11}
+.header-index[autumn]{background-color: #100903}
+.header-index[winter]{background-color: #0E0E0E}
+
+.header-demo{height: 60px; border-bottom: none;}
+.header-demo .logo{left: 40px;}
+.header-demo .layui-nav{top: 0;}
+.header-demo .layui-nav .layui-nav-item{margin: 0 10px;}
+
+.header-demo .layui-nav .layui-this a{padding: 0 30px;}
+
+.component{position: absolute; width: 200px; left: 120px; top: 16px; }
+.component .layui-input{height: 30px; padding-left: 12px; background-color: #424652; background-color: rgba(255,255,255,.05); border: none 0; color: #fff; font-size: 12px;}
+.component .layui-form-select .layui-edge{display: none; border-top-color: #999;}
+.component .layui-form-select dl{top: 36px; background-color: rgba(255,255,255,.9)}
+.header-demo .component{left: 185px;}
+
+.layui-side-child{width: 160px!important; left: 200px; bottom: 60px!important; border-right: 1px solid #eee; background-color: #fff;}
+.layui-side-child .layui-side-scroll{width: 170px;}
+.layui-side-child .layui-nav{padding: 10px 0; width: 160px; border-radius: 0; background: none}
+.layui-side-child .layui-nav-child{border-radius: 0;}
+.layui-side-child .layui-nav .layui-nav-title a, 
+.layui-side-child .layui-nav .layui-nav-title a:hover, 
+.layui-side-child .layui-nav-itemed>a{color: #666 !important;}
+.layui-side-child .layui-nav-itemed .layui-nav-child{margin-bottom: 10px; background: none !important;}
+.layui-side-child .layui-nav .layui-nav-item a{height: 30px; line-height: 30px; color: #666;}
+.layui-side-child .layui-nav .layui-nav-item a:hover{background: none !important;}
+.layui-side-child .layui-nav .layui-nav-child a{color: #999 !important;}
+.layui-side-child .layui-nav .layui-nav-more{display: none;}
+.layui-side-child .layui-nav-tree .layui-this, 
+.layui-side-child .layui-nav-tree .layui-this>a, 
+.layui-side-child .layui-nav-tree .layui-nav-child dd.layui-this, 
+.layui-side-child .layui-nav-tree .layui-nav-child dd.layui-this a{background: none; color: #5FB878 !important;}
+.layui-side-child .layui-nav .layui-nav-child a:hover{color: #009688 !important} 
+.layui-side-child .layui-nav-bar{background-color: #5FB878;}
+
+
+.footer{padding: 30px 0; line-height: 30px; text-align: center; color: #666; font-weight: 300;}
+body .layui-layout-admin .footer-demo{height: 50px; padding: 5px 0;}
+.footer a{padding: 0 5px;}
+.site-union{margin-top: 10px; color: #999;}
+.site-union>*{display: inline-block; vertical-align: middle;}
+.site-union a[upyun] img{width: 80px;}
+.site-union span{position: relative; top: 3px;}
+.site-union span a{padding: 0; display: inline; color: #999;}
+.site-union span a:hover{text-decoration: underline;}
+
+.footer-demo p{display: inline-block; vertical-align: middle; height: 50px; padding-right: 10px;}
+.footer-demo .site-union{position: relative; top: -9px;}
+
+.site-banner{position: relative; height: 600px; text-align: center; overflow: hidden; background-color: #393D49;}
+.site-banner-bg
+,.site-banner-main{position: absolute; left: 0; top: 0; width: 100%; height: 100%;}
+.site-banner-bg{background-position: center 0;}
+
+
+.site-zfj{padding-top: 25px; height: 220px;}
+.site-zfj i{position: absolute; left: 50%; top: 25px; width: 200px; height: 200px; margin-left: -100px; font-size: 200px; color: #c2c2c2;}
+
+@-webkit-keyframes site-zfj {
+  0% {opacity: 1;  -webkit-transform: translate3d(0, 0, 0) rotate(0deg) scale(1);}
+  10% {opacity: 0.8; -webkit-transform: translate3d(-100px, 0px, 0) rotate(10deg) scale(0.7);}
+  35% {opacity: 0.6; -webkit-transform: translate3d(100px, 0px, 0) rotate(30deg) scale(0.4);}
+  50% {opacity: 0.4; -webkit-transform: translate3d(0, 0, 0) rotate(360deg) scale(0);}
+  80% {opacity: 0.2; -webkit-transform: translate3d(0, 0, 0) rotate(720deg) scale(1);}
+  90% {opacity: 0.1; -webkit-transform: translate3d(0, 0, 0) rotate(3600deg) scale(6);}
+  100% {opacity: 1; -webkit-transform: translate3d(0, 0, 0) rotate(3600deg) scale(1);}
+}
+@keyframes site-zfj {
+  0% {opacity: 1;  transform: translate3d(0, 0, 0) rotate(0deg) scale(1);}
+  10% {opacity: 0.8; transform: translate3d(-100px, 0px, 0) rotate(10deg) scale(0.7);}
+  35% {opacity: 0.6; transform: translate3d(100px, 0px, 0) rotate(30deg) scale(0.4);}
+  50% {opacity: 0.4; transform: translate3d(0, 0, 0) rotate(360deg) scale(0);}
+  80% {opacity: 0.2; transform: translate3d(0, 0, 0) rotate(720deg) scale(1);}
+  90% {opacity: 0.1; transform: translate3d(0, 0, 0) rotate(3600deg) scale(6);}
+  100% {opacity: 1; transform: translate3d(0, 0, 0) rotate(3600deg) scale(1);}
+}
+
+@-webkit-keyframes site-desc {
+  0% { -webkit-transform: scale(1.1);}
+  100% {opacity: 1; -webkit-transform: scale(1);}
+}
+@keyframes site-desc {
+  0% { transform: scale(1.1);}
+  100% {transform: scale(1);}
+}
+
+.site-zfj-anim i{-webkit-animation-name: site-zfj; animation-name: site-zfj; -webkit-animation-duration: 5s; animation-duration: 5s;  -webkit-animation-timing-function: linear; animation-timing-function: linear;}
+
+
+.site-desc{position: relative; height: 70px; margin-top: 25px;  background: url(../images/layui/desc.png) center no-repeat;}
+.site-desc-anim{-webkit-animation-name: site-desc; animation-name: site-desc;}
+
+.site-desc cite{position: absolute; bottom: -40px; left: 0; width: 100%; color: #c2c2c2; font-style: normal;}
+.site-download{margin-top: 80px; font-size: 0;}
+.site-download a{position: relative; padding: 0 45px 0 90px; height: 60px; line-height: 60px; border: 1px solid #c2c2c2;  border-color: rgba(255,255,255,.2); font-size: 24px; color: #ccc; transition: all .5s; -webkit-transition: all .5s;}
+.site-download a:hover{border-color: rgba(255,255,255,.3); color: #fff; background-color: rgba(255,255,255,.05); border-radius: 30px;}
+.site-download a cite{position: absolute; left: 45px; font-size: 30px;}
+.site-version{position: relative; margin-top: 15px; color: #ccc; font-size: 12px;}
+.site-version span{padding: 0 3px;}
+.site-version *{font-style: normal;}
+.site-version a{color: #e2e2e2; text-decoration: underline;}
+
+.site-banner-other{position: absolute; left: 0; bottom: 30px; width: 100%; text-align: center; font-size: 0;}
+.site-banner-other iframe{border: none;}
+.site-banner-other a{display: inline-block; line-height: 28px; margin: 0 5px; padding: 0 8px; border-radius: 2px; color: #c2c2c2; color: rgba(255,255,255,.8); border: 1px solid #c2c2c2; border-color: rgba(255,255,255,.2); font-size: 14px; transition: all .5s; -webkit-transition: all .5s;}
+.site-banner-other a:hover{color: #fff; background-color: rgba(255,255,255,.1);}
+
+
+.site-idea{margin: 50px 0; font-size: 0; text-align: center; font-weight: 300;}
+.site-idea li{display: inline-block; vertical-align: top; *display: inline; *zoom:1; font-size: 14px; }
+.site-idea li{width: 298px; height: 150px; padding: 30px; line-height: 24px; margin-left: 30px; border: 1px solid #d2d2d2; text-align: left;}
+.site-idea li:first-child{margin-left: 0}
+.site-idea .layui-field-title{border-color: #d2d2d2}
+.site-idea .layui-field-title legend{margin: 0 20px 20px 0; padding: 0 20px; text-align: center;}
+
+/* 璧炲姪鍟� */
+.site-sponsor-home{margin-top: 40px; text-align: center;}
+.site-sponsor-home .layui-btn{position: relative; width: 233px; height: 65px; line-height: 65px; background: none; border-color: #212121; font-size: 26px; border-radius: 6px; /*padding-left: 55px;*/}
+.site-sponsor-home .layui-btn:hover{background: #4A4855; color: #BAB8C3;}
+.site-sponsor-home .layui-btn:before{/*position: absolute; left: 15px; top: 15px; content: ''; width: 30px; height: 30px; background: url(http://cdn.layui.com/upload/2018_1/168_1514869467160_26113.png) center; background-repeat: no-repeat; background-size: contain;*/}
+.site-sponsor-home p{position: relative; padding-top: 15px; font-size: 22px; color: #212121;}
+.site-sponsor-home p:before{content: ''; position: relative; top: -2px; display: inline-block; vertical-align: middle; width: 30px; height: 30px; margin-right: 10px; background: url(http://cdn.layui.com/upload/2018_1/168_1514869467160_26113.png) center; background-repeat: no-repeat; background-size: contain;}
+@media screen and (max-width: 750px) {
+  .site-sponsor-home .layui-btn{width: 180px; height: 45px; line-height: 45px; font-size: 20px;}
+  .site-sponsor-home p{font-size: 16px;}
+  .site-sponsor-home p:before{width: 20px; height: 20px;}
+}
+
+
+.site-tips{margin-bottom: 10px; padding: 15px; line-height: 22px; border-left: 5px solid #0078AD; background-color: #f2f2f2;}
+body .site-tips p{margin: 0;}
+body .layui-layer-notice .layui-layer-content{padding: 20px; line-height: 26px; background-color: #393D49; color: #fff; font-weight: 300;}
+.layui-layer-notice .layui-text{color: #f8f8f8;}
+.layui-layer-notice .layui-text a{color: #009688;}
+
+
+.site-dir{display: none;}
+.site-dir li{line-height: 26px; margin-left: 20px; overflow: visible; list-style-type: disc;}
+.site-dir li a{display: block;}
+.site-dir li a:active{color: #01AAED;}
+.site-dir li a.layui-this{color: #01AAED;}
+body .layui-layer-dir{box-shadow: none; border: 1px solid #d2d2d2;}
+body .layui-layer-dir .layui-layer-content{padding: 10px;}
+.site-dir a em{padding-left: 5px; font-size: 12px; color: #c2c2c2; font-style: normal;}
+
+
+
+.site-tree{border-right: 1px solid #eee;}
+
+.site-tree .layui-tree{line-height: 32px;}
+.site-tree .layui-tree li i{position: relative; font-size: 22px; color: #000}
+.site-tree .layui-tree li a cite{padding: 0 8px;}
+.site-tree .layui-tree .site-tree-noicon a cite{padding-left: 15px;}
+.site-tree .layui-tree li a em{font-size: 12px; color: #bbb; padding-right: 5px; font-style: normal;}
+.site-tree .layui-tree li h2{line-height: 36px; margin: 15px 0 5px; padding: 0 10px; background-color: #f2f2f2;}
+.site-tree .layui-tree li h2 a{background-color: #f2f2f2;}
+
+.site-tree .layui-tree li ul{margin-left: 27px; line-height: 28px;}
+.site-tree .layui-tree li ul a,
+.site-tree .layui-tree li ul a i{color: #777;}
+.site-tree .layui-tree li ul a:hover{color: #333;}
+.site-tree .layui-tree li ul li{margin-left: 25px; overflow: visible; list-style-type: disc; /*list-style-position: inside;*/}
+.site-tree .layui-tree li ul li cite,
+.site-tree .layui-tree .site-tree-noicon ul li cite{padding-left: 0;}
+
+.site-tree .layui-tree .layui-this a{color: #01AAED; background: #fefefe}
+.site-tree .layui-tree .layui-this .layui-icon{color: #01AAED;}
+
+
+
+.site-fix .site-tree{position: fixed; top: 0; bottom: 0; z-index: 666; min-height: 0; overflow: auto;  background-color: #fff;}
+.site-fix .site-content{margin-left: 220px;}
+.site-fix-footer .site-tree{/*margin-bottom: 120px;*/}
+
+
+.site-title{ margin: 30px 0 20px;}
+.site-title fieldset{border: none; padding: 0; border-top: 1px solid #eee;}
+.site-title fieldset legend{margin-left: 20px;  padding: 0 10px; font-size: 22px; font-weight: 300;}
+
+.site-text a{color: #01AAED;}
+.site-h1{margin-bottom: 20px; line-height: 40px; padding-bottom: 10px; color: #393D49; border-bottom: 1px solid #eee;  font-size: 24px; font-weight: 300;}
+.site-h1 .layui-icon{position: relative; top: 5px; font-size: 50px; margin-right: 10px;}
+.site-text{position:relative;}
+.site-text p{margin-bottom: 10px;  line-height:22px;}
+.site-text em{padding: 0 3px; font-weight: 500; font-style: italic; color: #666;}
+.site-text code{margin:0 5px; padding: 3px 10px; border: 1px solid #e2e2e2; background-color: #fbfbfb; color: #666; border-radius: 2px;}
+
+.site-table{width: 100%; margin: 10px 0;}
+.site-table thead{background-color:#f2f2f2; }
+.site-table th, 
+.site-table td{padding: 6px 15px; min-height: 20px; line-height: 20px; border:1px solid #ddd; font-size: 14px; font-weight: 400;}
+.site-table tr:nth-child(even){background: #fbfbfb;}
+
+.site-block{padding: 20px; border: 1px solid #eee;}
+.site-block .layui-form{margin-right: 200px;}
+
+
+.site-changelog .layui-timeline-title h2{display: inline-block;}
+.site-changelog .layui-timeline-title .layui-badge-rim{top: -2px; left: 10px;}
+
+.site-doc-color{font-size: 0;}
+.site-doc-color li{display: inline-block; vertical-align: middle; width: 180px; margin-left: 20px; margin-bottom: 20px; padding: 20px 10px; color: #fff; text-align: center; border-radius: 2px; line-height: 22px; font-size: 14px;}
+.site-doc-color li p[tips]{opacity: 0.8; font-size: 12px;}
+
+.site-doc-necolor li{width: 108px; margin-top: 15px; margin-left: 0; border-radius: 0;}
+
+.site-doc-bgcolor li{padding: 10px;}
+
+
+.site-doc-icon{margin-bottom: 50px; font-size: 0;}
+.site-doc-icon li{display: inline-block; vertical-align: middle; width: 127px; line-height: 25px; padding: 20px 0; margin-right: -1px; margin-bottom: -1px; border: 1px solid #e2e2e2; font-size: 14px; text-align: center; color: #666; transition: all .3s; -webkit-transition: all .3s;}
+.site-doc-icon li .layui-icon{display: inline-block; font-size: 36px;}
+
+.site-doc-icon li .fontclass{display: none;}
+.site-doc-icon li .name{color: #c2c2c2;}
+.site-doc-icon li:hover{background-color: #f2f2f2; color: #000;}
+
+
+.grid-demo{padding: 10px; line-height: 50px; text-align: center; background-color: #79C48C; color: #fff;}
+.grid-demo-bg1{background-color: #63BA79;}
+.grid-demo-bg2{background-color: #49A761;}
+.grid-demo-bg3{background-color: #38814A;}
+
+
+
+body .layui-layout-admin .site-demo{bottom: 60px; padding: 0;}
+body .site-demo-nav .layui-nav-item{line-height: 40px}
+.layui-nav-item .layui-icon{position: relative; font-size: 20px;}
+.layui-nav-item a cite{padding: 0 10px;}
+.site-demo .layui-main{margin: 15px; line-height: 22px;}
+.site-demo-editor{position: absolute; top: 0; bottom: 0; left: 0; width: 50%; }
+.site-demo-area{position: absolute; top: 0; bottom: 0; width: 100%;}
+.site-demo-editor textarea{position: absolute; width: 100%; height: 100%; padding: 10px; border: none; resize: none; background-color: #F7FBFF; background-color: #13151A; color: #999; font-family: Courier New; font-size: 12px; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}
+.site-demo-btn{position: absolute; bottom: 15px; right: 20px;}
+.site-demo-zanzhu{position: absolute; bottom: 0; left: 0; width: 100%; height: 90px; text-align: center; background-color: #e2e2e2; overflow: hidden;}
+.site-demo-zanzhu>*{position: relative; z-index: 1;}
+.site-demo-zanzhu:before{content: ""; position: absolute; z-index: 0; top: 50%; left: 50%; width: 120px; margin: -10px 0px 0px -60px; text-align: center; color: rgb(170, 170, 170); font-size: 18px; font-weight: 300; }
+
+.site-demo-result{position: absolute; right: 0; top: 0; bottom: 0; width: 50%;}
+.site-demo-result iframe{position: absolute; width: 100%; height: 100%;}
+
+.site-demo-button{margin-bottom: 30px;}
+.site-demo-button div{margin: 20px 30px 10px;}
+.site-demo-button .layui-btn+.layui-btn{margin-left: 0;}
+.site-demo-button .layui-btn{margin: 0 7px 10px 0; }
+
+.site-demo-text a{color: #01AAED;}
+
+.site-demo-laytpl{text-align: center;}
+.site-demo-laytpl textarea,
+.site-demo-laytpl div span{width: 40%;  padding: 15px; margin: 0 15px;}
+.site-demo-laytpl textarea{height: 300px; border: none; background-color: #3F3F3F; color: #E3CEAB; font-family: Courier New; resize: none;}
+.site-demo-laytpl div span{display: inline-block; text-align: center; background: #101010; color: #fff;}
+.site-demo-tplres{margin: 10px 0; text-align: center}
+.site-demo-tplres .site-demo-tplh2,
+.site-demo-tplres .site-demo-tplview{display: inline-block; width: 50%;}
+.site-demo-tplres h2{padding: 15px; background: #e2e2e2;}
+.site-demo-tplres h3{font-weight: 700;}
+.site-demo-tplres div{padding: 14px; border: 1px solid #e2e2e2; text-align: left;}
+
+.site-demo-upload,
+.site-demo-upload img{width: 200px; height: 200px; border-radius: 100%;}
+.site-demo-upload{position: relative; background: #e2e2e2;}
+.site-demo-upload .site-demo-upbar{position: absolute; top: 50%; left: 50%; margin: -18px 0 0 -56px;}
+.site-demo-upload .layui-upload-button{background-color: rgba(0,0,0,.2); color: rgba(255,255,255,1);}
+
+.site-demo-util{position: relative; width: 300px;}
+.site-demo-util img{width: 300px; border-radius: 100%;}
+.site-demo-util span{position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: #333; cursor: pointer;}
+@-webkit-keyframes demo-fengjie {
+  0% {-webkit-filter: blur(0); opacity: 1; background: #fff; height: 300px; border-radius: 100%;}
+  80% {-webkit-filter: blur(50px);  opacity: 0.95;}
+  100% {-webkit-filter: blur(20px); opacity: 0; background: #fff;}
+}
+@keyframes demo-fengjie {
+  0% {filter: blur(0); opacity: 1; background: #fff; height: 300px; border-radius: 100%;}
+  80% {filter: blur(50px);  opacity: 0.95;}
+  100% {filter: blur(20px); opacity: 0; background: #fff;}
+}
+.site-demo-fengjie{-webkit-animation-name: demo-fengjie; animation-name: demo-fengjie; -webkit-animation-duration: 5s; animation-duration: 5s;}
+
+.layui-layout-admin .site-demo-body{top: 106px;}
+.site-demo-title{position: fixed; left: 200px; right: 0; top: 65px;}
+.site-demo-code{position: absolute; left: 0; top: 0; width: 100%; height: 100%; border: none; padding: 10px; resize: none; font-size: 12px; background-color: #F7FBFF; color: #881280; font-family: Courier New;}
+
+.site-demo-overflow{overflow: hidden;}
+
+
+#trans-tooltip,
+#tip-arrow-bottom,
+#tip-arrow-top{display: none !important;}
+
+
+
+.alone{text-align: center; background-color: #009688; color: #fff; font-weight: 300; transition: all .3s; -webkit-transition: all .3s;}
+.alone:hover{background-color: #5FB878;}
+.alone a{display: block; padding: 50px 20px; color: #fff; font-size: 30px;}
+.alone a cite{display: block; padding-top: 10px; font-size: 14px;}
+
+
+.alone-banner{height: 190px; text-align: center; font-weight: 300; background-color: #009688; color:#fff;}
+.alone-banner h1{padding-top: 60px; line-height: 32px; font-size: 30px; font-weight: 300;}
+.alone-banner p{padding-top: 20px; color: #e2e2e2; color: rgba(255,255,255,.8);}
+
+.alone-nav .layui-tab-title li{margin-right: 30px; padding: 0; color: #666;}
+.alone-nav .layui-tab-title li a{  padding: 0 20px;}
+
+.alone-download{margin: 30px 0;}
+.alone-download .layui-btn{margin-right: 10px;}
+.alone-download span{display: inline-block; line-height: 44px; padding-right: 20px;}
+.alone-download span em{color: #999;}
+
+.alone-title{margin-top: 20px;}
+
+.alone-download-btn{text-align: center; margin-top: 50px; font-size: 0;}
+.alone-download-btn .layui-btn{position: relative; width: 206px; height: 60px; line-height: 60px; font-size: 26px; font-weight: 300;}
+.alone-download-btn .layui-btn+.layui-btn{margin: 0;}
+.alone-download-btn .alone-download-right{margin-left: 20px !important; border-color: #009688; background: none; color: #009688;}
+.alone-download-btn .layui-btn img{position: relative; top: -3px; width: 118px;}
+
+
+
+@media screen and (max-width: 750px) {
+  .layui-main{width: auto; margin: 0 10px;}
+  .logo,
+  .header-demo .logo{left: 10px;}
+  .component{display: none}
+
+  .header .layui-nav-child{left: auto; right: 0;}
+  .site-demo-overflow{overflow: auto;}
+
+  .site-nav-layim{display: none !important;}
+  .header .layui-nav .layui-nav-item{margin: 0;}
+  .header .layui-nav .layui-nav-item a{padding: 0 20px;}
+  .header .layui-nav .layui-nav-item[pc]{display: none;}
+  .header .layui-nav .layui-nav-item[mobile]{display: inline-block;}
+  .site-banner{height: 300px;}
+  .site-banner-bg{background-size: cover;}
+  .site-zfj{height: 100px; padding-top: 5px;}
+  .site-zfj i{top: 10px; width: 100px; height: 100px; margin-left: -50px; font-size: 100px;}
+  .site-desc{background-size: 70%; margin: 0;}
+  .site-desc cite{display: none;}
+  .site-download{margin-top: 0; }
+  .site-download a{height: 40px; line-height: 40px; padding: 0 25px 0 60px; border-radius: 30px; color: #fff; font-size: 16px;}
+  .site-download a cite{left: 20px;}
+  .site-banner-other{bottom: 10px;}
+
+  .site-idea{margin: 20px 0;}
+  .site-idea li{margin: 0 0 20px 0; width: 100%; height: auto; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}
+  .site-hengfu img{max-width: 100%}
+
+  .site-block .layui-form{margin-right: 0;}
+
+  .layui-layer-dir{display: none;}
+  .site-tree{position: fixed; top: 0; bottom: 0; min-height: 0; overflow: auto; z-index: 1000; left: -260px; background-color: #fff;  transition: all .3s; -webkit-transition: all .3s;}
+  .site-content{width: 100%; padding: 0; overflow: auto;}
+  .site-content img{max-width: 100%;}
+  .site-tree-mobile{display: block!important; position: fixed; z-index: 100000; bottom: 15px; left: 15px; width: 50px; height: 50px; line-height: 50px; border-radius: 2px; text-align: center; background-color: rgba(0,0,0,.7); color: #fff;}
+  .site-home .site-tree-mobile{display: none!important;}
+  .site-mobile .site-tree-mobile{display: none !important;}
+  .site-mobile .site-tree{left: 0;}
+  .site-mobile .site-mobile-shade{content: ''; position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0,0,0,.8); z-index: 999;}
+  .site-tree-mobile i{font-size: 20px;}
+  .layui-code-view{-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;}
+
+  .layui-layout-admin .layui-side{position: fixed; top: 0; left: -260px; transition: all .3s; -webkit-transition: all .3s; z-index: 10000;}
+  .layui-body{position: static; bottom: 0; left: 0;}
+  .site-mobile .layui-side{left: 0;}
+  .site-mobile .layui-side-child{top: 50%; left: 200px; height: 300px; margin-top: -100px;}
+
+  body .layui-layout-admin .footer-demo{position: static; height: auto; line-height: 30px;}
+  .footer-demo p{height: auto;}
+
+  .site-demo-area,
+  .site-demo-editor,
+  .site-demo-result,
+  .site-demo-editor textarea,
+  .site-demo-result iframe{position: static; width: 100%;}
+  .site-demo-editor textarea{height: 350px;}
+  .site-demo-zanzhu{display: none;}
+  .site-demo-btn{bottom: auto; top: 370px;}
+  .site-demo-result iframe{height: 500px;}
+
+  .site-demo-laytpl textarea, .site-demo-laytpl div span{margin: 0;}
+  .site-demo-tplres .site-demo-tplh2, .site-demo-tplres .site-demo-tplview{width: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;}
+
+  .site-demo-title{position: static; left: 0;}
+  body .layui-layout-admin .site-demo{}
+  .site-demo-code{position: static; height: 350px;}
+}
+
+

+ 79 - 0
static/css/login.css

@@ -0,0 +1,79 @@
+/*
+* @Author: haodaquan
+* @Date:   2017-09-07 22:04:13
+* @Last Modified by:   haodaquan
+* @Last Modified time: 2017-09-07 22:42:01
+*/
+
+.bg-img{
+    background: url(/static/img/login-bg.jpg) fixed center center;
+}
+
+body {
+    overflow: hidden;
+}
+.layer_notice {
+    background: #5fb878 none repeat scroll 0 0;
+    float: left;
+    height: 75px;
+    overflow: hidden;
+    padding: 10px;
+    width: 330px;
+}
+.layer_notice ul li {
+    color: #fff;
+}
+.video-player {
+    background-color: transparent;
+    min-width: 100%;
+    min-height: 100%;
+    display: block;
+    position: absolute;
+    z-index: 1;
+    top: 0;
+}
+
+.video_mask {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    left: 0;
+    top: 0;
+    z-index: 90;
+    background-color: rgba(0, 0, 0, 0.3);
+}
+
+.login {
+    height: 200px;
+    width: 260px;
+    padding: 20px;
+    background-color: rgba(0, 0, 0, 0.5);
+    border-radius: 4px;
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    margin: -150px 0 0 -150px;
+    z-index: 99;
+}
+
+.login h1 {
+    text-align: center;
+    color: #fff;
+    font-size: 24px;
+    margin-bottom: 20px;
+}
+
+.form_code {
+    position: relative;
+}
+
+.form_code .code {
+    position: absolute;
+    right: 0;
+    top: 1px;
+    cursor: pointer;
+}
+
+.login_btn {
+    width: 100%;
+}

+ 51 - 0
static/css/main.css

@@ -0,0 +1,51 @@
+@charset "utf-8";
+.x-slide_left{
+  width: 17px;
+  height: 61px;
+  background:  url(../img/icon.png) 0 0 no-repeat;
+  position: absolute;
+  top: 200px;
+  left: 0px;
+  cursor: pointer;
+}
+
+.nav-title{
+	height: 45px;
+	border: #e4e4e4 1px solid;
+	line-height: 45px;
+	padding-left: 10px;
+	padding-right: 10px;
+	margin-bottom: 10px;
+}
+
+.tl{
+	text-align: left;
+}
+.tr{
+	text-align: right;
+}
+
+.fl{
+	float: left;
+}
+.fr{
+	float: right;
+}
+
+.ml20{
+	margin-left: 20px; 
+}
+
+.ml8{
+	margin-left: 8px;
+}
+
+.mt10{
+	margin-top:10px;
+}
+
+.search_text{
+	text-align: right;padding-right: 10px;
+}
+
+

+ 63 - 0
static/css/message.css

@@ -0,0 +1,63 @@
+/** kit_admin-v1.0.5 MIT License By http://kit/zhengjinfan.cn e-mail:zheng_jinfan@126.com */
+.kit-message {
+    position: fixed;
+    right: 50px;
+    top: 50px;
+    z-index: 19940201;
+    border-radius: 3px
+}
+
+.kit-message .kit-message-item {
+    min-height: 40px;
+    background-color: #fff;
+    border-radius: 3px;
+    min-width: 250px;
+    margin-top: 15px;
+    position: relative;
+    border: 1px solid #ecf0f5
+}
+
+.kit-message .kit-message-item:first-child {
+    margin-top: 0
+}
+
+.kit-message .kit-message-item .kit-message-body {
+    margin-right: 40px;
+    line-height: 40px;
+    padding: 0 10px 0 20px
+}
+
+.kit-message .kit-message-item .kit-close {
+    width: 40px;
+    height: 40px;
+    position: absolute;
+    right: 0;
+    top: 0;
+    text-align: center;
+    line-height: 40px;
+    cursor: pointer
+}
+
+.kit-message .kit-skin-red {
+    color: #FF5722!important
+}
+
+.kit-message .kit-skin-orange {
+    color: #FFB800!important
+}
+
+.kit-message .kit-skin-cyan {
+    color: #2F4056!important
+}
+
+.kit-message .kit-skin-blue {
+    color: #1E9FFF!important
+}
+
+.kit-message .kit-skin-black {
+    color: #393D49!important
+}
+
+.kit-message .kit-skin-default {
+    color: #009688!important
+}

+ 76 - 0
static/css/nprogress.css

@@ -0,0 +1,76 @@
+/** kit_admin-v1.0.5 MIT License By http://kit/zhengjinfan.cn e-mail:zheng_jinfan@126.com */
+#nprogress {
+    pointer-events: none
+}
+
+#nprogress .bar {
+    background: #29d;
+    position: fixed;
+    z-index: 1031;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 2px
+}
+
+#nprogress .peg {
+    display: block;
+    position: absolute;
+    right: 0;
+    width: 100px;
+    height: 100%;
+    box-shadow: 0 0 10px #29d,0 0 5px #29d;
+    opacity: 1;
+    -webkit-transform: rotate(3deg) translate(0,-4px);
+    -ms-transform: rotate(3deg) translate(0,-4px);
+    transform: rotate(3deg) translate(0,-4px)
+}
+
+#nprogress .spinner {
+    display: block;
+    position: fixed;
+    z-index: 1031;
+    top: 15px;
+    right: 15px
+}
+
+#nprogress .spinner-icon {
+    width: 18px;
+    height: 18px;
+    box-sizing: border-box;
+    border: 2px solid transparent;
+    border-top-color: #29d;
+    border-left-color: #29d;
+    border-radius: 50%;
+    -webkit-animation: nprogress-spinner .4s linear infinite;
+    animation: nprogress-spinner .4s linear infinite
+}
+
+.nprogress-custom-parent {
+    overflow: hidden;
+    position: relative
+}
+
+.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner {
+    position: absolute
+}
+
+@-webkit-keyframes nprogress-spinner {
+    0% {
+        -webkit-transform: rotate(0)
+    }
+
+    100% {
+        -webkit-transform: rotate(360deg)
+    }
+}
+
+@keyframes nprogress-spinner {
+    0% {
+        transform: rotate(0)
+    }
+
+    100% {
+        transform: rotate(360deg)
+    }
+}

+ 22 - 0
static/editor.md/BUGS.md

@@ -0,0 +1,22 @@
+#Bugs
+
+> 说明:删除线表示已经解决。
+
+####IE8
+
+- ~~不能加载;~~
+- flowChart(流程图)、sequenceDiagram(序列图)不支持IE8;
+- ~~不支持Markdown转HTML页面解析预览;~~
+
+####IE8 & IE9 & IE10
+
+- KaTeX会出现解析错误,但不影响程序运行;
+
+####Sea.js
+
+- ~~Raphael.js无法加载;~~
+
+####Require.js
+
+- ~~CodeMirror编辑器的代码无法高亮;~~
+- ~~sequenceDiagram不支持: `Uncaught TypeError: Cannot call method 'isArray' of undefined.`~~

+ 534 - 0
static/editor.md/CHANGE.md

@@ -0,0 +1,534 @@
+## 更新日志
+
+### v1.0.x
+
+##### v1.0.0 beta
+
+预览版:基本功能完成;
+
+##### v1.0.0 releases
+
+发布 v1.0.0 正式版。
+
+主要更新:
+
+- 新建分支 `mathjax-version`,但不打算继续对此分支进行开发;
+
+- 移除 MathJax,改用 KaTeX [#2](https://github.com/pandao/editor.md/issues/2),解析和预览响应速度大幅度提高 [#3](https://github.com/pandao/editor.md/issues/3);
+    - 移除 `mathjax` 配置项;
+    - 移除 `mathjaxURL` 属性;
+    - 移除 `setMathJaxConfig()` 方法;
+    - 移除 `loadMathJax()` 方法;
+    - 移除MathJax的所有示例;
+    - 新增 `tex` 配置项,表示是否开启支持科学公式 TeX ,基于 KaTeX;
+    - 新增 `katexURL` 属性;
+    - 新增 `loadKaTeX` 方法;
+    - 新增 KaTeX 的示例;
+    
+- `setCodeEditor()` 方法更名为 `setCodeMirror()`;
+
+- 合并 CodeMirror 使用到的多个 JS 模块文件,大幅减少 HTTP 请求,加快下载速度;
+    - 新增合并后的两个模块文件:`./lib/codemirror/modes.min.js`、`./lib/codemirror/addons.min.js` ;
+    - `Gulpfile.js` 新增合并 CodeMirror 模块文件的任务方法 `codemirror-mode` 和 `codemirror-addon` ;
+    - 另外在使用 Require.js 时,因为 CodeMirror 的严格模块依赖的限制,不能使用上述合并的模块文件,仍然采用动态加载多个模块文件;
+    
+- 更新 `README.md` 等相关文档和示例;
+
+- 解决 Sea.js 环境下 Raphael.js 无法运行导致不支持流程图和时序图的问题,即必须先加载 Raphael.js ,后加载 Sea.js ;
+
+### v1.1.x
+
+##### v1.1.0
+
+主要更新:
+
+- 设计并更换了 Logo;
+- 新增添加图片、链接、锚点链接、代码块、预格式文本等操作弹出对话框层及示例;
+- 新增支持图片(跨域)上传;
+- 改用 `<textarea>` 来存放 Markdown 源文档;
+- 新增支持自定义工具栏;
+- 新增支持多语言;
+- 新增支持 Zepto.js;
+- 新增支持多个 Editor.md 并存和动态加载 Editor.md 及示例;
+- 新增支持智能识别和解析 HTML 标签及示例;
+- 新增多个外部操作方法接口及示例;
+- 修复了一些大大小小的 Bug;
+
+具体更新如下:
+
+- 更换 Logo,建立基础 VI;
+    - 创建了全系列 WebFont 字体 `dist/fonts/editormd-logo.*` ;
+    - 新增样式类 `editormd-logo` 等;
+
+- 改用 `<textarea>` 来存放 Markdown 源文档;
+    - 原先使用 `<script type="text/markdown"></script>` 来存放 Markdown 源文档;
+    - 创建 Editor.md 只需要写一个 `<div id="xxxx"></div>` ,如果没有添加 `class="editormd"` 属性会自动添加,另外如果不存在 `<textarea>` 标签,则也会自动添加 `<textarea>` ;
+
+- 新增支持智能识别和解析 HTML 标签,增强了 Markdown 语法的扩展性,几乎无限,例如:插入视频等等;
+    - 新增配置项 `htmlDecode` ,表示是否开启 HTML 标签识别和解析,但是为了安全性,默认不开启;
+    - 新增识别和解析 HTML 标签的示例;
+    
+- 新增插入链接、锚点链接、预格式文本和代码块的弹出对话框层;
+    - 弹出层改为使用固定定位;
+    - 新增动态创建对话框的方法 `createDialog()`;
+    - 新增静态属性 `editormd.codeLanguages` ,用于存放代码语言列表;
+
+- 开始支持图片上传;
+    - 新增添加图片(上传)弹出对话框层;
+    - 支持基于 iframe 的跨域上传,并添加相应的示例( PHP 版);
+    
+- 开始支持自定义工具栏图标及操作处理;
+    - 配置项 `toolbarIcons` 类型由数组更改为函数,返回一个图标按钮列表数组;
+    - 新增配置项 `toolbarHandlers` 和 `toolbarIconsTexts` ,分别用于自定义按钮操作处理和按钮内容文本;
+    - 新增方法 `getToolbarHandles()` ,用于可在外部使用默认的操作方法;
+    - 新增成员属性 `activeIcon` ,可获取当前或上次点击的工具栏图标的 jQuery 实例对象;
+    
+- 新增表单取值、自定义工具栏、图片上传、多个 Editor.md 并存和动态加载 Editor.md 等多个示例;
+
+- 新增插入锚点按钮和操作处理;
+
+- 新增预览 HTML 内容窗口的关闭按钮,之前只能按 ESC 才能退出 HTML 全窗口预览;
+
+- 新增多语言( l18n )及动态加载语言包支持;
+    - 新增英语 `en` 和繁体中文 `zh-tw` 语言包模块;
+    - 修改一些方法的内部实现以支持动态语言加载:
+        - `toolbarHandler()` 更为 `setToolbarHandler()` ;
+        - `setToolbar()` 方法包含 `setToolbarHandler()` ;
+        - 新建 `createInfoDialog()` 方法;
+	    - 修改 `showInfoDialog()` 和 `hideInfoDialog()` 方法的内部实现等;
+
+- 修改多次 Bug ,并优化触摸事件,改进对 iPad 的支持;
+
+- 工具栏新增清空按钮和清空方法 `clear()` ,解决工具栏文本会被选中出现蓝底的问题;
+
+- 配置项 `tocStartLevel` 的默认值由 2 改为 1,表示默认从 H1 开始生成 ToC;
+
+- 解决 IE8 下加载出错的问题;
+    - 新增两个静态成员属性 `isIE` 和 `isIE8` ,用于判断 IE8;
+    - 由于 IE8 不支持 FlowChart 和 SequenceDiagram,默认在 IE8 下不加载这两个组件,无论是否开启;
+
+- 新增 Zepto.js 的支持;
+	- 为了兼容 Zepto.js ,某些元素在操作处理上不再使用 `outerWidth()` 、 `outerHeight()` 、`hover()` 、`is()` 等方法;
+	- 为了避免修改 flowChart.js 和 sequence-diagram.js 的源码,所以想支持 flowChart 或 sequenceDiagram 得加上这一句: `var jQuery = Zepto;`;
+
+- 新增 `editormd.$name` 属性,修改 `editormd.homePage` 属性的新地址;
+
+- `editormd.markdownToHTML()` 新增方法返回一个 jQuery 实例对象;
+    - 该实例对象定义了一个 `getMarkdown()`方法,用于获取 Markdown 源代码;
+    - 该实例对象定义了一个 `tocContainer` 成员属性,即 ToC 列表的父层的 jQuery 实例对象;
+
+- 新增只读模式;
+    - 新增配置项 `readOnly` ,默认值为 `false` ,即可编辑模式;
+    - 其他相关改动;
+
+- 新增方法 `focus()` 、 `setCursor()` 、 `getCursor()` 、`setSelection()` 、`getSelection()` 、 `replaceSelection()` 和 `insertValue()` 方法,并增加对应的示例;
+
+- 新增配置项 `saveHTMLToTextarea` ,用于将解析后的 HTML 保存到 Textarea,以供提交到后台程序;
+    - `getHTML()` 方法必须在 `saveHTMLToTextarea == true` 的情况下才能使用;
+    - 新增 `getHTML()` 方法的别名 `getTextareaSavedHTML()` 方法;
+    - 新增方法 `getPreviewedHTML()` ,用于获取预览窗口的 HTML ;
+
+- 修复了一些大大小小的 Bugs;
+
+##### v1.1.1
+
+- 接受一个 pull 请求,修复了 `getHTML ()` 和 `getPreviewedHTML()` 方法中的 3 处错误;
+
+##### v1.1.2
+
+- 修复 Bug [#10](https://github.com/pandao/editor.md/issues/10);
+- 修复 Bug [#12](https://github.com/pandao/editor.md/issues/12);
+
+##### v1.1.3
+
+- 修复 Bug [#14](https://github.com/pandao/editor.md/issues/14);
+- 修复 Bug [#15](https://github.com/pandao/editor.md/issues/15);
+
+##### v1.1.4
+
+- 修复 Bug [#17](https://github.com/pandao/editor.md/issues/17);
+    - 修改了 `getToolbarHandles()` 和 `setToolbarHandler()` 方法;
+- 从 `editormd.scss` 中分离出 `editormd.logo.scss` ,并生成 `editormd.logo.css` ,以便单独使用;
+    - 同时修改了 `Gulpfile.js` 的相应任务;
+    
+##### v1.1.5
+
+- 修复 Bug [#18](https://github.com/pandao/editor.md/issues/18);
+    - 修改了 `showInfoDialog()` 和 `createInfoDialog()` 方法;
+    - 新增 `infoDialogPosition()` 方法;
+    
+- 修复 Bug [#20](https://github.com/pandao/editor.md/issues/20);
+    - 修改了引用的处理函数;
+    - 插入的 headers 的 `#` 号后面都加上了一个空格;
+
+##### v1.1.6
+
+修复多处 Bug,具体如下:
+    
+- 修复 Bug [#23](https://github.com/pandao/editor.md/issues/23),即 Headers 的 id 属性的重复及中文问题;
+    - 修改了 `editormd.markedRenderer()` 方法;
+
+- 修复 Bug [#24](https://github.com/pandao/editor.md/issues/24);
+    - 修改了 `setMarkdown()` 、 `clear()` 和 `loadedDisplay()` 方法的内部实现;
+    - 新增了 `katexRender()` 、 `flowChartAndSequenceDiagramRender()` 、 `previewCodeHighlight()` 方法;
+    
+- 修复有些情况下无法保存 Markdown 源文档到 textarea 的问题;
+    - 修改了 `setCodeMirror()` 、 `recreateEditor()` 等方法;
+
+- 修改了以上 Bug 及部分相关示例文件;
+
+##### v1.1.7
+
+修复多处 Bug,具体如下:
+
+- 修复 Bug [#25](https://github.com/pandao/editor.md/issues/25);
+    - 修改了 `loadedDisplay()` 方法,将 `settings.onload` 移动了 `CodeMirror.on("change")` 事件注册后再触发;
+
+- 修复 Bug [#26](https://github.com/pandao/editor.md/issues/26);
+    - 修改了 `saveToTextareas()` 方法;
+    - 新增 `state.loaded` 和 `state.watching` 两个属性;
+
+- 修改了以上 Bug 相关示例文件;
+
+##### v1.1.8
+
+改进功能,具体如下:
+
+- 改进 [#27](https://github.com/pandao/editor.md/issues/27);
+    - 新增配置项 `matchWordHighlight` ,可选值有: `true, false, "onselected"` ,默认值为 `true` ,即开启自动匹配和标示相同单词;
+
+- 改进 [#28](https://github.com/pandao/editor.md/issues/28);
+    - 将 `jquery.min.js` 、 `font-awesome.min.css` 、 `github-markdown.css` 移除(这是一个疏忽,它们不是动态加载的依赖模块或者不需要的,避免不必要的硬盘空间占用);
+
+- 修改了所有相关的示例文件;
+
+##### v1.1.9
+
+- 修复无法解析 heading link 的 Bug [#29](https://github.com/pandao/editor.md/issues/29);
+
+    - 修改了 `editormd.markedRenderer()` 方法的内部实现;
+    - 新增了 `editormd.trim()` ,用于清除字符串两边的空格;
+    - 修改了所有相关的示例文件和测试用例 `marked-heading-link-test.html` ;
+    
+- 修改了 `README.md` ,添加了 `Shields.io` 图标;
+
+### v1.2
+
+##### v1.2.0
+
+v1.2.0 主要更新:
+
+- 新增代码折叠、搜索替换、自定义样式主题和自定义快捷键等功能;
+- 新增 Emoji 表情、@Link 、GFM Task Lists 支持;
+- 新增表格插入、Emoji 表情插入、HTML 实体字符插入、使用帮助等对话框;
+- 新增插件扩展机制;
+- 新增手动加载依赖模块方式;
+- 改用 `Prefixes.css` 作 CSS 前缀预处理;
+- 改进和增强工具栏自定义功能,完善事件监听和处理方法;
+- 部分功能改进(更加方便的预格式文本/代码插入、自动闭合标签等)、新增多个方法、改进 Require.js 支持和修复多个 Bug 等等;
+
+**具体更新如下:**
+
+- 新建 v1.1.x 分支;
+    - v1.2 文件结构变动较大;
+
+- 新增代码折叠、自动闭合标签和搜索替换功能;
+    - 搜索快捷键 `Ctrl + F / Command + F` ;
+    - 替换快捷键 `Ctrl + Shift + F / Command + Option + F` ;
+    - 折叠快捷键 `Ctrl + Q / Command + Q` ;
+
+- 新增自定义主题支持;
+    - 新增 3 个成员方法 `setTheme()` 、 `setCodeMirrorOption()` 和 `getCodeMirrorOption()` ;
+
+- 新增 @Link 支持;
+
+- 新增 GFM Task Lists 支持;
+
+- 新增 Emoji 表情支持;
+    - 支持 Github emoji `:emoji-name:` 、FontAwesome icons(`:fa-xxx:`)、Twitter emoji (twemoji) ( `:tw-xxxx:` )、Editor.md logo icons( `:editormd-logo:` )形式的 Emoji;
+    - 新增属性 `editormd.emoji` 、 `editormd.twemoji` 、 `editormd.urls` 和 `editormd.regex`;
+    
+- 新增 HTML 实体字符插入、插入表格和使用帮助对话框;
+    - 修改了 `createDialog()` 等方法;
+    - 新增 `mask` 成员属性和锁屏方法 `editormd.lockScreen()` 、 `editormd.fn.lockScreen()` ;
+
+- 改进插入预格式文本和代码对话框;
+    - 将 `<textarea>` 改为 `CodeMirror` ,输入更加方便和直观;
+
+- 新增自定义键盘快捷键功能;
+    - 新增 2 个方法: `addKeyMap()` 和 `removeKayMap()`;
+
+- 改用 `Prefixes.css` 作CSS前缀预处理;
+    - SCSS前缀预处理mixins改用 [Prefixes.scss](https://github.com/pandao/prefixes.scss "Prefixes.scss");
+
+- 改进和增强工具栏自定义功能;
+	- 新增配置项 `toolbarCustomIcons` ,用于增加自定义工具栏的功能,可以直接插入 HTML 标签,不使用默认的元素创建图标;
+    - 新增工具栏列表预设值属性 `editormd.toolbarModes` ;
+    - 移除成员属性 `toolbarIconHandlers` ;
+
+- 完善和新增事件处理方法;
+	- 新增事件回调注册方法 `on()` ;
+	- 新增事件回调移除方法 `off()` ;
+	- 新增事件回调处理配置项: `onresize` 、 `onscroll` 、`onpreviewscroll` 、 `onpreviewing` 、 `onpreviewed` 、`onwatch` 和 `onunwatch` ;
+
+- 新增手动加载依赖模块方式,以便可同步使用成员方法;
+    - 新增属性 `autoLoadModules` ,默认值为 `true` ;
+
+- 新增插件及扩展机制;
+    
+    - 新增插件自定义机制,改变整体结构(包括文件结构),以便更加方便地实现插件扩展;
+	- 新增对象扩展方法 `extends()` 、 `set()` ;
+
+- 新增成员方法和属性:
+
+    - 新增两个方法: `setValue()` 、`getValue()`;
+	- 新增 `config()` 方法,用于加载后重新配置;
+	- 增加两个属性 `cm` ,是 `codeEditor` 的简写, `cmElement` 是 `codeMirror` 的别名;
+
+- 成员方法的改进:
+
+	- 改进: `showToolbar()` 和 `hideToolbar()` 方法增加一个 `callback` 函数,用于直接回调操作;
+	- 改进:修改了 `previewCodeHighlight()` 方法;
+	- 更名: `recreateEditor()` 更名为 `recreate()` ;
+    - 移除 `setMarked()` 方法;
+    
+- 新增 HTML 标签解析过滤机制;
+    - 通过设置 `settings.htmlDecode = "style,script,iframe"` 来实现过滤指定标签的解析;
+
+- 改进 Require.js 支持;
+    - 修复 Require.js 下 CodeMirror 编辑器的代码无法高亮的问题;
+    - 更新 `underscore` 版本至 `1.8.2` ;
+    - 移除 `editormd.requirejsInit()` 和 `editormd.requireModules()` 方法;
+    - 新增 `Require.js/AMD` 专用版本文件 `editormd.amd.js` ;
+    - 新建 Gulp 任务 `amd` ;
+
+- 修改和新增以上改进等相关示例;
+
+### v1.3
+
+#### v1.3.0
+
+主要更新:
+
+- 预设键盘快捷键处理(粗体等),插入 Markdown 更加方便;
+- 更新 CodeMirror 版本为 `5.0` ;
+- 更新 Marked 版本为 `0.3.3`;
+- 新增自动高度和工具栏固定定位功能;
+- 改进表格插入对话框;
+- 工具栏新增三个按钮,分别是将所选文本首字母转成大写、转成小写、转成大写;
+- 修改使用帮助文档;
+- 修复多个 Bug;
+
+具体更新如下:
+
+- 新增常用键盘快捷键预设处理;
+    - 新增属性 `editormd.keyMaps` ,预设一些常用操作,例如插入粗体等;
+    - 新增成员方法 `registerKeyMaps()` ;
+    - 退出HTML全屏预览快捷键更改为 `Shift + ESC`;
+    - 新增配置项 `disabledKeyMaps` ,用于屏蔽一些快捷键操作;
+- 更新 CodeMirror 版本为 `5.0`;
+    - 修改无法输入 `/` 的问题;
+- 更新 Marked 版本为 `0.3.3`;
+- 新增自动高度和工具栏固定定位(滚动条拖动时)模式;
+    - 新增配置项 `settings.autoHeight` ;
+    - 新增配置项 `settings.toolbarAutoFixed` ;
+    - 新增方法 `setToolbarAutoFixed(true|false)` ;
+- 新增邮箱地址自动添加链接功能;
+    - 新增配置项 `emailLink` ,默认为 `true` ; 
+- 改进表格插入对话框;
+- 工具栏新增三个按钮,分别是将所选文本首字母转成大写、转成小写、转成大写;
+    - 新增方法 `editormd.ucwords()` ,别名 `editormd.wordsFirstUpperCase()` ;
+    - 新增方法 `editormd.ucfirst()` ,别名 `editormd.firstUpperCase()` ;
+    - 新增两个成员方法 `getSelections()` 和 `getSelections()` ;
+
+- 修复 Font awesome 图标 emoji 部分无法解析的 Bug,[#39](https://github.com/pandao/editor.md/issues/39)
+- 改进 @link 功能 [#40](https://github.com/pandao/editor.md/issues/40);
+    - 新增配置项 `atLink` ,默认为 `true` ; 
+- 修复无法输入 `/` 的问题 [#42](https://github.com/pandao/editor.md/issues/42);
+- 修改使用帮助说明的错误 [#43](https://github.com/pandao/editor.md/issues/43);
+- 新增配置项 `pluginPath`,默认为空时,等于 `settings.path + "../plugins/"` ;
+
+### v1.4
+
+#### v1.4.0
+
+主要更新:
+
+- 新增延迟解析机制,预览更即时;
+- 新增跳转到指定行的功能和对话框;
+- 新增 ToC 下拉菜单、自定义 ToC 容器的功能;
+- 新增跳转到行、搜索的工具栏按钮;
+- 新增支持插入和解析(打印)分页符;
+- 改进快捷键功能和自动高度模式等;
+- 改进:将锚点链接改名为引用链接;
+- 改进编辑器重建和重配置功能;
+- 修复多个 Bug;
+
+具体更新:
+
+- 新增延迟解析预览的机制,解决输入太多太快出现的 “延迟卡顿” 问题;
+    - 新增配置项 `delay` ,默认值为 `300`;
+    - 修复当输入速度太快时,解析Flowchart会抛出错误的问题;
+- 修改 iPad 等移动终端的浏览器无法上传图片的问题 [#48](https://github.com/pandao/editor.md/issues/48);
+- 修复单独引用 `editormd.preview.css` 时无法显示 Font Awesome 和 Editor.md logo 字体的问题;
+- 更新和修改 Gulp 构建;
+    - 修改了 `Gulpfile.js` ,并且 `gulp-ruby-sass` 升级到最新版本 `1.0.0-alpha.3` ; 
+    - 编辑 SCSS 时,不再生成 CSS 的 Source map 文件;
+- 执行 jshint 和更正一些 JS 写法的不规范,精简了代码;
+- 新增配置项 `appendMarkdown` 和 `appendMarkdown()` 方法,用于(初始化前后)追加 Markdown 到 Textarea ;
+- 改进部分预设快捷键功能,包括 F9 (watch)、F10 (preview)、F11 (fullscreen)等;
+- 修复自动高度模式下出现的几个问题;
+    - 全屏退出时高度不正确的问题:修改了 `fullscreenExit()` 方法的内部实现;
+    - 当解析预览后的 HTML 内容高度高于 Markdown 源码编辑器高度时,无法正确预览的问题 [#49](https://github.com/pandao/editor.md/issues/49);
+- 修改 `onscroll` 和 `onpreviewscroll` 无法访问 `this` 的问题;
+- 修改 `init()` 方法,可以只设置一个参数;
+- 新增插入 TeX (KaTeX) 公式的快捷键 `Ctrl + Shift + K` 和插入方法 `tex()` ;
+- 将锚点链接改为引用链接,引用的链接改为插入到页尾;
+    - 工具栏的名称 `anchor` 改为 `reference-link`;
+    - 工具栏的名称 `htmlEntities` 改名为 `html-entities`;
+- 改进编辑器重建和重配置功能;
+    - 修改了 `loadedDisplay()` 方法;
+    - 修改了 `config()` 和 `recreate()` 方法;
+- 新增跳转到指定行的功能;
+    - 新增方法 `gotoLine()` ;
+    - 新增跳转到行对话框插件 `goto-line-dialog` ;
+    - 新增快捷键 `Ctrl + Alt + G` ;
+    - 改进 `executePlugin()` 方法;
+    - 修改了 `help-dialog/help.md` ;
+- 新增搜索工具栏按钮;
+    - 新增方法 `search()` 、`searchReplace()` 和 `searchReplaceAll()` ;
+    - 原全屏预览 HTML 按钮的图标改为 `fa-desktop`;
+    - 改为默认开启搜索替换功能;
+- 更换了关于 Editor.md 的标语( slogan );
+- 标题按钮 `h` 改为大写的 `H`;
+- `saveToTextareas()` 方法更名为 `save()`;
+- 新增 ToC 下拉菜单、自定义 ToC 容器的功能;
+    - 新增 Markdown 扩展语法 `[TOCM]` ,自动生成 ToC 下拉菜单;
+    - 新增配置项 `tocm` ,默认为 `true`,即可以使用 `[TOCM]` ;
+    - 新增配置项 `tocDropdown` 和 `tocTitle` ;
+    - 新增方法 `editormd.tocDropdownMenu()` ;
+    - 新增配置项 `tocContainer` ,值为 jQuery 选择器,默认为空;
+- 修改了配置项 `placeholder` 的默认值;
+- 改进对 IE8 的兼容支持;
+- 修复 Firefox 下因为 `Object.watch()` 而出现的问题;
+- 新增支持插入和解析(打印)分页符;
+    - 新增配置项 `pageBreak` ,默认值为 `true`;
+    - 新增语法 `[========]` ,即括号内至少 8 个等号;
+    - 新增插入分页符的工具栏图标和方法 `pagebreak()` ;
+    - 新增插入分页符的快捷键 `Shift + Alt + P`;
+- 修复一些 Bug,包括 [#51](https://github.com/pandao/editor.md/issues/51) 等;
+- 新增和修改以上更新的相关示例;
+
+#### v1.4.1
+
+- 新增配置项 `syncScrolling`,即是否开启同步滚动预览,默认值为 `false` ; 
+- 修复 Bug [#64](https://github.com/pandao/editor.md/issues/64);
+    - 更新 `editormd.katexURL` 资源地址的默认值,即更新版本为 `0.3.0` ; 
+    - 新增测试用例`tests/katex-tests.html`;
+    - 修改示例文件`examples/katex.html`; 
+- 修复 Bug [#66](https://github.com/pandao/editor.md/issues/66);
+- 修复编辑器工具栏按钮 `:hover` CSS3 transition 无效的问题; 
+- 修改了 `README.md`;
+
+#### v1.4.2
+
+- 改进和增强自定义工具栏功能,支持图标按钮右对齐 [#69](https://github.com/pandao/editor.md/issues/69);
+- 改进和增强 HTML 标签的解析过滤功能,支持过滤指定的属性等 [#70](https://github.com/pandao/editor.md/issues/70);
+- 删除分支 `mathjax-version` 和 `v1.1.9`;
+
+#### v1.4.3
+
+- 改进:可配置是否自动聚焦编辑器 [#74](https://github.com/pandao/editor.md/issues/74);
+	- 新增配置项 `autoFocus`,默认值为 `true`; 
+- 修复 Bug [#77](https://github.com/pandao/editor.md/issues/77);
+- 改进:帮助对话框里的链接改为新窗口打开,避免直接跳转到链接,导致编辑内容丢失的问题 [#79](https://github.com/pandao/editor.md/issues/79);
+- 改进和完善编辑器配置项;
+	- 新增配置项 `tabSize`、`indentUnit` 和 `lineWrapping`;
+	- 新增配置项 `autoCloseBrackets` 和 `showTrailingSpace` ;
+	- 新增配置项 `matchBrackets`、`indentWithTabs` 和 `styleSelectedText`;
+- 改进:修改 CSS `font-family`,改进跨平台中英文字体显示;
+- 修改了 `README.md`;
+
+#### v1.4.4
+
+- 修复 Bug [#81](https://github.com/pandao/editor.md/issues/81),即不支持 `:+1:` 的问题;
+- 修复 Bug [#85](https://github.com/pandao/editor.md/issues/85),即图片上传返回结果不支持 `Content-Type=application/json` 的问题;
+- 修复图片上传无法显示 loading 的问题;
+
+#### v1.4.5
+
+- 规范项目的中英文混排;
+- 新增配置项 `name`,用于指定 Markdown textarea 的 `name="xxxx"` 属性;
+- 修复 Bug,即无法正确解析公式的 `<` 和 `>` 的问题 [#87](https://github.com/pandao/editor.md/issues/87);
+- 修复 Bug,即 `getHTML()` 无效的问题 [#95](https://github.com/pandao/editor.md/issues/95);
+- 修复 Bug,即火狐上传图片后无法返回值的问题 [#96](https://github.com/pandao/editor.md/issues/96);
+    - 修改了图片上传插件;
+    - 修改 PHP 上传类及示例;
+- 方法更名:`extends()` 更名为 `extend()`,以兼容 IE8;
+- 修复 IE8 下 Emoji 正则表达式字符集越界的问题;
+- 更新了 `README.md` 和 `CHANGE.md` 等相关文档文件;
+
+
+### v1.5
+
+#### v1.5.0
+
+主要更新:
+
+- 新增:编辑器黑色主题 Dark,改进自定义主题功能(即工具栏、编辑区、预览区可分别设置主题样式);
+- 新增:多行公式支持;
+- 新增:支持非编辑状态下的 ToC 自定义容器;
+- 新增:支持设置为单向同步滚动;
+- 改进:编辑器样式美化,更换了滚动条样式; 
+- 改进:提高同步滚动定位的精确度;
+- 改进:修复和改进 HTML 标签及属性过滤功能;
+- 改进:修复在 Bootstrap 下的兼容性问题;
+- 修复多处 Bug;
+
+具体更新:
+
+- 新增:解析后的代码块自动换行;
+
+- 新增:支持多行公式;
+    - 新增:新增语法:\`\`\`math | latex | katex;
+    - 改进:美化 KaTeX 公式,即加大字号等;
+
+- 新增:支持设置为单向同步滚动,即只是编辑区单向同步滚动,配置项 `syncScrolling : "single"`;
+    - 新增:配置同步滚动示例文件 `sync-scrolling.html`;
+
+- 新增:增加了编辑器样式主题 Dark,即工具栏和预览区各自有一个暗黑色主题;
+    - 变更:自 `v1.5.0` 开始,配置项 `theme` 改为指定 Editor.md 本身的主题;
+    - 新增配置项 `editorTheme` ,用于指定编辑区的主题,即 CodeMirror 的主题;
+    - 新增配置项 `previewTheme` ,用于指定预览区的主题;
+    - 新增方法 `setEditorTheme()`,别名: `setCodeMirror()`;
+    - 新增方法 `setPreviewTheme()`;
+    - 修改了方法 `setTheme()` ;
+    - 更换了滚动条样式,Only Webkit;
+    - 改进全屏状态下的样式显示,去掉 JS 操作的部分,改为通过 CSS 样式类 `.editormd-fullscreen` 控制;
+    - 修改和增加相关的方法、SCSS 文件及示例文件 `themes.html`;
+
+- 新增:非编辑状态下 ToC 自定义容器支持;
+    - 新增配置项 `markdownSourceCode`,即解析后是否保留源码,默认为不保留 `false`;
+    - 新增配置项 `tocContainer`,值为自定义 ToC 容器的 ID 选择器 `#xxxxx`,默认为空;
+    - 新增和修改了相关示例文件;
+
+- 新增:新增加了 CSS 样式类 `editormd-preview-active`,可以控制全屏HTML预览时的内容层样式;
+    - 修改了 `previewing()` 和 `previewed()` 方法;
+    - 相关 issues [#103](https://github.com/pandao/editor.md/issues/103);
+    - 另外也调整了关闭按钮的位置;
+
+- 改进:修复插入 Emoji `:moon:` 无法显示的问题,修改为其是 `:waxing_gibbous_moon:` 的别名 [#94](https://github.com/pandao/editor.md/pull/94);
+
+- 改进:修改了 CodeMirror 代码行的左右内间距,使其不会挨着左边的行号层;
+    - 相关 issues [#97](https://github.com/pandao/editor.md/issues/97);
+
+- 改进:修改了同步滚动的定位算法,提高精确度;
+    - 修正问题 [#99](https://github.com/pandao/editor.md/issues/99);
+    - 修改了 `bindScrollEvent()` 方法;
+
+- 改进:完善 HTML 标签过滤功能,即代码块、`<pre>` 预格式文本和行内代码里的标签及属性不会被过滤;
+    - 修复 Bug [#105](https://github.com/pandao/editor.md/issues/105);
+- 改进:当不显示行号时 `settings.lineNumbers == false`,CodeMirror 行号层去掉右边框; 
+- 改进:根据指针在当前行的位置更合理插入标题和水平线 [#104](https://github.com/pandao/editor.md/pull/104);
+- 改进:调整了字体,优先显示 `"YaHei Consolas Hybrid", Consolas`;
+- 改进:修复在 Bootstrap 下的兼容性问题,即因为 box-sizing 写错位置导致的弹出层宽度等错位问题 [#107](https://github.com/pandao/editor.md/issues/107);

+ 342 - 0
static/editor.md/Gulpfile.js

@@ -0,0 +1,342 @@
+"use strict";
+
+var os           = require("os");
+var gulp         = require("gulp");
+var gutil        = require("gulp-util");
+var sass         = require("gulp-ruby-sass");
+var jshint       = require("gulp-jshint");
+var uglify       = require("gulp-uglifyjs");
+var rename       = require("gulp-rename");
+var concat       = require("gulp-concat");
+var notify       = require("gulp-notify");
+var header       = require("gulp-header");
+var minifycss    = require("gulp-minify-css");
+//var jsdoc        = require("gulp-jsdoc");
+//var jsdoc2md     = require("gulp-jsdoc-to-markdown");
+var pkg          = require("./package.json");
+var dateFormat   = require("dateformatter").format;
+var replace      = require("gulp-replace");
+
+pkg.name         = "Editor.md";
+pkg.today        = dateFormat;
+
+var headerComment = ["/*", 
+					" * <%= pkg.name %>",
+                    " *",
+					" * @file        <%= fileName(file) %> ",
+					" * @version     v<%= pkg.version %> ",
+					" * @description <%= pkg.description %>",
+					" * @license     MIT License",
+					" * @author      <%= pkg.author %>",
+					" * {@link       <%= pkg.homepage %>}",
+					" * @updateTime  <%= pkg.today('Y-m-d') %>",
+					" */", 
+					"\r\n"].join("\r\n");
+
+var headerMiniComment = "/*! <%= pkg.name %> v<%= pkg.version %> | <%= fileName(file) %> | <%= pkg.description %> | MIT License | By: <%= pkg.author %> | <%= pkg.homepage %> | <%=pkg.today('Y-m-d') %> */\r\n";
+
+var scssTask = function(fileName, path) {
+    
+    path = path || "scss/";
+    
+    var distPath = "css";
+    
+    return sass(path + fileName + ".scss", { style: "expanded", sourcemap: false, noCache : true })
+        .pipe(gulp.dest(distPath))
+        .pipe(header(headerComment, {pkg : pkg, fileName : function(file) { 
+            var name = file.path.split(file.base);
+            return name[1].replace("\\", "");
+        }}))
+       .pipe(gulp.dest(distPath)) 
+       .pipe(rename({ suffix: ".min" }))
+       .pipe(gulp.dest(distPath))
+       .pipe(minifycss())
+       .pipe(gulp.dest(distPath)) 
+        .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) { 
+            var name = file.path.split(file.base);
+            return name[1].replace("\\", "");
+        }}))
+       .pipe(gulp.dest(distPath)) 
+       .pipe(notify({ message: fileName + ".scss task completed!" }));
+};
+
+gulp.task("scss", function() { 
+	return scssTask("editormd");
+}); 
+
+gulp.task("scss2", function() { 
+	return scssTask("editormd.preview");
+}); 
+
+gulp.task("scss3", function() {
+	return scssTask("editormd.logo");
+}); 
+
+gulp.task("js", function() { 
+  return gulp.src("./src/editormd.js")
+            .pipe(jshint("./.jshintrc"))
+            .pipe(jshint.reporter("default"))
+            .pipe(header(headerComment, {pkg : pkg, fileName : function(file) { 
+                var name = file.path.split(file.base);
+                return name[1].replace(/[\\\/]?/, "");
+            }}))
+            .pipe(gulp.dest("./"))
+            .pipe(rename({ suffix: ".min" }))
+            .pipe(uglify())  // {outSourceMap: true, sourceRoot: './'}
+            .pipe(gulp.dest("./"))	
+            .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) {
+                var name = file.path.split(file.base + ( (os.platform() === "win32") ? "\\" : "/") );
+                return name[1].replace(/[\\\/]?/, "");
+            }}))
+            .pipe(gulp.dest("./"))
+            .pipe(notify({ message: "editormd.js task complete" }));
+}); 
+
+gulp.task("amd", function() {
+    var replaceText1 = [
+        'var cmModePath  = "codemirror/mode/";',
+        '            var cmAddonPath = "codemirror/addon/";', 
+        '',
+        '            var codeMirrorModules = [',
+        '                "jquery", "marked", "prettify",',
+        '                "katex", "raphael", "underscore", "flowchart",  "jqueryflowchart",  "sequenceDiagram",',
+        '',
+        '                "codemirror/lib/codemirror",',
+        '                cmModePath + "css/css",',
+        '                cmModePath + "sass/sass",', 
+        '                cmModePath + "shell/shell",', 
+        '                cmModePath + "sql/sql",',
+        '                cmModePath + "clike/clike",',
+        '                cmModePath + "php/php",',
+        '                cmModePath + "xml/xml",',
+        '                cmModePath + "markdown/markdown",', 
+        '                cmModePath + "javascript/javascript",',
+        '                cmModePath + "htmlmixed/htmlmixed",',
+        '                cmModePath + "gfm/gfm",',
+        '                cmModePath + "http/http",',
+        '                cmModePath + "go/go",', 
+        '                cmModePath + "dart/dart",', 
+        '                cmModePath + "coffeescript/coffeescript",',
+        '                cmModePath + "nginx/nginx",',
+        '                cmModePath + "python/python",', 
+        '                cmModePath + "perl/perl",',
+        '                cmModePath + "lua/lua",', 
+        '                cmModePath + "r/r", ',
+        '                cmModePath + "ruby/ruby", ',
+        '                cmModePath + "rst/rst",',
+        '                cmModePath + "smartymixed/smartymixed",', 
+        '                cmModePath + "vb/vb",',
+        '                cmModePath + "vbscript/vbscript",', 
+        '                cmModePath + "velocity/velocity",',
+        '                cmModePath + "xquery/xquery",',
+        '                cmModePath + "yaml/yaml",',
+        '                cmModePath + "erlang/erlang",', 
+        '                cmModePath + "jade/jade",',
+        '',
+        '                cmAddonPath + "edit/trailingspace", ',
+        '                cmAddonPath + "dialog/dialog", ',
+        '                cmAddonPath + "search/searchcursor", ',
+        '                cmAddonPath + "search/search", ',
+        '                cmAddonPath + "scroll/annotatescrollbar", ', 
+        '                cmAddonPath + "search/matchesonscrollbar", ',
+        '                cmAddonPath + "display/placeholder", ',
+        '                cmAddonPath + "edit/closetag", ',
+        '                cmAddonPath + "fold/foldcode",',
+        '                cmAddonPath + "fold/foldgutter",',
+        '                cmAddonPath + "fold/indent-fold",',
+        '                cmAddonPath + "fold/brace-fold",',
+        '                cmAddonPath + "fold/xml-fold", ',
+        '                cmAddonPath + "fold/markdown-fold",',
+        '                cmAddonPath + "fold/comment-fold", ',
+        '                cmAddonPath + "mode/overlay", ',
+        '                cmAddonPath + "selection/active-line", ',
+        '                cmAddonPath + "edit/closebrackets", ',
+        '                cmAddonPath + "display/fullscreen",',
+        '                cmAddonPath + "search/match-highlighter"',
+        '            ];',
+        '',
+        '            define(codeMirrorModules, factory);'
+    ].join("\r\n");
+    
+    var replaceText2 = [
+        "if (typeof define == \"function\" && define.amd) {",
+        "       $          = arguments[0];",
+        "       marked     = arguments[1];",
+        "       prettify   = arguments[2];",
+        "       katex      = arguments[3];",
+        "       Raphael    = arguments[4];",
+        "       _          = arguments[5];",
+        "       flowchart  = arguments[6];",
+        "       CodeMirror = arguments[9];",
+        "   }"
+    ].join("\r\n");
+    
+    gulp.src("src/editormd.js")
+        .pipe(rename({ suffix: ".amd" }))
+        .pipe(gulp.dest('./'))
+        .pipe(header(headerComment, {pkg : pkg, fileName : function(file) { 
+            var name = file.path.split(file.base);
+            return name[1].replace(/[\\\/]?/, "");
+        }}))
+        .pipe(gulp.dest("./"))
+        .pipe(replace("/* Require.js define replace */", replaceText1))
+        .pipe(gulp.dest('./'))
+        .pipe(replace("/* Require.js assignment replace */", replaceText2))
+        .pipe(gulp.dest('./'))
+        .pipe(rename({ suffix: ".min" }))
+        .pipe(uglify()) //{outSourceMap: true, sourceRoot: './'}
+        .pipe(gulp.dest("./"))
+        .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) {
+            var name = file.path.split(file.base + ( (os.platform() === "win32") ? "\\" : "/") );
+            return name[1].replace(/[\\\/]?/, "");
+        }}))
+        .pipe(gulp.dest("./"))
+        .pipe(notify({ message: "amd version task complete"}));
+}); 
+
+
+var codeMirror = {
+    path : {
+        src : {
+            mode : "lib/codemirror/mode",
+            addon : "lib/codemirror/addon"
+        },
+        dist : "lib/codemirror"
+    },
+    modes : [
+        "css",
+        "sass",
+        "shell",
+        "sql",
+        "clike",
+        "php",
+        "xml",
+        "markdown",
+        "javascript",
+        "htmlmixed",
+        "gfm",
+        "http",
+        "go",
+        "dart",
+        "coffeescript",
+        "nginx",
+        "python",
+        "perl",
+        "lua",
+        "r", 
+        "ruby", 
+        "rst",
+        "smartymixed",
+        "vb",
+        "vbscript",
+        "velocity",
+        "xquery",
+        "yaml",
+        "erlang",
+        "jade",
+    ],
+
+    addons : [
+        "edit/trailingspace", 
+        "dialog/dialog", 
+        "search/searchcursor", 
+        "search/search",
+        "scroll/annotatescrollbar", 
+        "search/matchesonscrollbar", 
+        "display/placeholder", 
+        "edit/closetag", 
+        "fold/foldcode",
+        "fold/foldgutter",
+        "fold/indent-fold",
+        "fold/brace-fold",
+        "fold/xml-fold", 
+        "fold/markdown-fold",
+        "fold/comment-fold", 
+        "mode/overlay", 
+        "selection/active-line", 
+        "edit/closebrackets", 
+        "display/fullscreen", 
+        "search/match-highlighter"
+    ]
+};
+
+gulp.task("cm-mode", function() { 
+    
+    var modes = [
+        codeMirror.path.src.mode + "/meta.js"
+    ];
+    
+    for(var i in codeMirror.modes) {
+        var mode = codeMirror.modes[i];
+        modes.push(codeMirror.path.src.mode + "/" + mode + "/" + mode + ".js");
+    }
+    
+    return gulp.src(modes)
+                .pipe(concat("modes.min.js"))
+                .pipe(gulp.dest(codeMirror.path.dist))
+                .pipe(uglify()) // {outSourceMap: true, sourceRoot: codeMirror.path.dist}
+                .pipe(gulp.dest(codeMirror.path.dist))	
+                .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) {
+                    var name = file.path.split(file.base + "\\"); 
+                    return (name[1]?name[1]:name[0]).replace(/\\/g, "");
+                }}))
+                .pipe(gulp.dest(codeMirror.path.dist))
+                .pipe(notify({ message: "codemirror-mode task complete!" }));
+}); 
+
+gulp.task("cm-addon", function() { 
+    
+    var addons = [];
+    
+    for(var i in codeMirror.addons) {
+        var addon = codeMirror.addons[i];
+        addons.push(codeMirror.path.src.addon + "/" + addon + ".js");
+    }
+    
+    return gulp.src(addons)
+                .pipe(concat("addons.min.js"))
+                .pipe(gulp.dest(codeMirror.path.dist))
+                .pipe(uglify()) //{outSourceMap: true, sourceRoot: codeMirror.path.dist}
+                .pipe(gulp.dest(codeMirror.path.dist))	
+                .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) {
+                    var name = file.path.split(file.base + "\\");
+                    return (name[1]?name[1]:name[0]).replace(/\\/g, "");
+                }}))
+                .pipe(gulp.dest(codeMirror.path.dist))
+                .pipe(notify({ message: "codemirror-addon.js task complete" }));
+}); 
+/*
+gulp.task("jsdoc", function(){
+    return gulp.src(["./src/editormd.js", "README.md"])
+               .pipe(jsdoc.parser())
+               .pipe(jsdoc.generator("./docs/html"));
+});
+
+gulp.task("jsdoc2md", function() {
+    return gulp.src("src/js/editormd.js")
+            .pipe(jsdoc2md())
+            .on("error", function(err){
+                gutil.log(gutil.colors.red("jsdoc2md failed"), err.message);
+            })
+            .pipe(rename(function(path) {
+                path.extname = ".md";
+            }))
+            .pipe(gulp.dest("docs/markdown"));
+});
+*/
+gulp.task("watch", function() {
+	gulp.watch("scss/editormd.scss", ["scss"]);
+	gulp.watch("scss/editormd.preview.scss", ["scss", "scss2"]);
+	gulp.watch("scss/editormd.logo.scss", ["scss", "scss3"]);
+	gulp.watch("src/editormd.js", ["js", "amd"]);
+});
+
+gulp.task("default", function() {
+    gulp.run("scss");
+    gulp.run("scss2");
+    gulp.run("scss3");
+    gulp.run("js");
+    gulp.run("amd");
+    gulp.run("cm-addon");
+    gulp.run("cm-mode");
+});

+ 22 - 0
static/editor.md/LICENSE

@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 pandao
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+

+ 119 - 0
static/editor.md/README.md

@@ -0,0 +1,119 @@
+# Editor.md
+
+![](https://pandao.github.io/editor.md/images/logos/editormd-logo-180x180.png)
+
+![](https://img.shields.io/github/stars/pandao/editor.md.svg)
+![](https://img.shields.io/github/forks/pandao/editor.md.svg)
+![](https://img.shields.io/github/tag/pandao/editor.md.svg)
+![](https://img.shields.io/github/release/pandao/editor.md.svg)
+![](https://img.shields.io/github/issues/pandao/editor.md.svg)
+![](https://img.shields.io/bower/v/editor.md.svg)
+
+**Editor.md** : The open source embeddable online markdown editor (component), based on CodeMirror & jQuery & Marked.
+
+### Features
+
+- Support Standard Markdown / CommonMark and GFM (GitHub Flavored Markdown);
+- Full-featured: Real-time Preview, Image (cross-domain) upload, Preformatted text/Code blocks/Tables insert, Code fold, Search replace, Read only, Themes, Multi-languages, L18n, HTML entities, Code syntax highlighting...;
+- Markdown Extras : Support [ToC (Table of Contents)](https://pandao.github.io/editor.md/examples/toc.html), [Emoji](https://pandao.github.io/editor.md/examples/emoji.html), [Task lists](https://pandao.github.io/editor.md/examples/task-lists.html), [@Links](https://pandao.github.io/editor.md/examples/@links.html)...;
+- Compatible with all major browsers (IE8+), compatible Zepto.js and iPad;
+- Support [decode & fliter of the HTML tags & attributes](https://pandao.github.io/editor.md/examples/html-tags-decode.html);
+- Support [TeX (LaTeX expressions, Based on KaTeX)](https://pandao.github.io/editor.md/examples/katex.html), [Flowchart](https://pandao.github.io/editor.md/examples/flowchart.html) and [Sequence Diagram](https://pandao.github.io/editor.md/examples/sequence-diagram.html) of Markdown extended syntax;
+- Support AMD/CMD (Require.js & Sea.js) Module Loader, and Custom/define editor plugins;
+
+[README & Examples (English)](https://pandao.github.io/editor.md/en.html)
+  
+
+--------
+
+**Editor.md** 是一款开源的、可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。
+
+![editormd-screenshot](https://pandao.github.io/editor.md/examples/images/editormd-screenshot.png "editormd-screenshot")
+
+#### 主要特性
+
+- 支持通用 Markdown / CommonMark 和 GFM (GitHub Flavored Markdown) 风格的语法,也可[变身为代码编辑器](https://pandao.github.io/editor.md/examples/change-mode.html);
+- 支持实时预览、图片(跨域)上传、预格式文本/代码/表格插入、代码折叠、跳转到行、搜索替换、只读模式、自定义样式主题和多语言语法高亮等功能;
+- 支持 [ToC(Table of Contents)](https://pandao.github.io/editor.md/examples/toc.html)、[Emoji表情](https://pandao.github.io/editor.md/examples/emoji.html)、[Task lists](https://pandao.github.io/editor.md/examples/task-lists.html)、[@链接](https://pandao.github.io/editor.md/examples/@links.html)等 Markdown 扩展语法;
+- 支持 TeX 科学公式(基于 [KaTeX](https://pandao.github.io/editor.md/examples/katex.html))、流程图 [Flowchart](https://pandao.github.io/editor.md/examples/flowchart.html) 和 [时序图 Sequence Diagram](https://pandao.github.io/editor.md/examples/sequence-diagram.html);
+- 支持[识别和解析 HTML 标签,并且支持自定义过滤标签及属性解析](https://pandao.github.io/editor.md/examples/html-tags-decode.html),具有可靠的安全性和几乎无限的扩展性;
+- 支持 AMD / CMD 模块化加载(支持 [Require.js](https://pandao.github.io/editor.md/examples/use-requirejs.html) & [Sea.js](https://pandao.github.io/editor.md/examples/use-seajs.html)),并且支持[自定义扩展插件](https://pandao.github.io/editor.md/examples/define-plugin.html);
+- 兼容主流的浏览器(IE8+)和 [Zepto.js](https://pandao.github.io/editor.md/examples/use-zepto.html),且支持 iPad 等平板设备;
+
+#### Examples
+
+[https://pandao.github.io/editor.md/examples/index.html](https://pandao.github.io/editor.md/examples/index.html)
+
+#### Download & install
+
+[Github download](https://github.com/pandao/editor.md/archive/master.zip)
+
+Bower install :
+
+```shell
+bower install editor.md
+```
+
+#### Usages
+
+HTML:
+
+```html
+<link rel="stylesheet" href="editormd.min.css" />
+<div id="editormd">
+    <textarea style="display:none;">### Hello Editor.md !</textarea>
+</div>
+```
+
+> Tip: Editor.md can auto append `<textarea>` tag;
+
+javascript:
+
+```html
+<script src="jquery.min.js"></script>
+<script src="editormd.min.js"></script>
+<script type="text/javascript">
+    $(function() {
+        var editor = editormd("editormd", {
+            path : "../lib/" // Autoload modules mode, codemirror, marked... dependents libs path
+        });
+
+        /*
+        // or
+        var editor = editormd({
+            id   : "editormd",
+            path : "../lib/"
+        });
+        */
+    });
+</script>
+```
+
+Using modular script loader :
+
+- [Using Require.js](https://github.com/pandao/editor.md/tree/master/examples/use-requirejs.html)
+- [Using Sea.js](https://github.com/pandao/editor.md/tree/master/examples/use-seajs.html)
+
+#### Dependents
+
+- [CodeMirror](http://codemirror.net/ "CodeMirror")
+- [marked](https://github.com/chjj/marked "marked")
+- [jQuery](http://jquery.com/ "jQuery")
+- [FontAwesome](http://fontawesome.io/ "FontAwesome")
+- [github-markdown.css](https://github.com/sindresorhus/github-markdown-css "github-markdown.css")
+- [KaTeX](http://khan.github.io/KaTeX/ "KaTeX")
+- [prettify.js](http://code.google.com/p/google-code-prettify/ "prettify.js")
+- [Rephael.js](http://raphaeljs.com/ "Rephael.js")
+- [flowchart.js](http://adrai.github.io/flowchart.js/ "flowchart.js")
+- [sequence-diagram.js](http://bramp.github.io/js-sequence-diagrams/ "sequence-diagram.js")
+- [Prefixes.scss](https://github.com/pandao/prefixes.scss "Prefixes.scss")
+
+#### Changes
+
+[Change logs](https://github.com/pandao/editor.md/blob/master/CHANGE.md)
+
+#### License
+
+The MIT License.
+
+Copyright (c) 2015 Pandao

+ 24 - 0
static/editor.md/bower.json

@@ -0,0 +1,24 @@
+{
+  "name": "editor.md",
+  "version": "1.5.0",
+  "homepage": "https://github.com/pandao/editor.md",
+  "authors": [
+    "Pandao <pandao@vip.qq.com>"
+  ],
+  "description": "Open source online markdown editor.",
+  "keywords": [
+    "editor.md",
+    "markdown",
+    "editor"
+  ],
+  "license": "MIT",
+  "ignore": [
+    "**/.*",
+    "research",
+    "docs",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ]
+}

File diff suppressed because it is too large
+ 4450 - 0
static/editor.md/css/editormd.css


+ 98 - 0
static/editor.md/css/editormd.logo.css

@@ -0,0 +1,98 @@
+/*
+ * Editor.md
+ *
+ * @file        editormd.logo.css 
+ * @version     v1.5.0 
+ * @description Open source online markdown editor.
+ * @license     MIT License
+ * @author      Pandao
+ * {@link       https://github.com/pandao/editor.md}
+ * @updateTime  2015-06-09
+ */
+
+/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */
+@font-face {
+  font-family: 'editormd-logo';
+  src: url("../fonts/editormd-logo.eot?-5y8q6h");
+  src: url(".../fonts/editormd-logo.eot?#iefix-5y8q6h") format("embedded-opentype"), url("../fonts/editormd-logo.woff?-5y8q6h") format("woff"), url("../fonts/editormd-logo.ttf?-5y8q6h") format("truetype"), url("../fonts/editormd-logo.svg?-5y8q6h#icomoon") format("svg");
+  font-weight: normal;
+  font-style: normal;
+}
+.editormd-logo,
+.editormd-logo-1x,
+.editormd-logo-2x,
+.editormd-logo-3x,
+.editormd-logo-4x,
+.editormd-logo-5x,
+.editormd-logo-6x,
+.editormd-logo-7x,
+.editormd-logo-8x {
+  font-family: 'editormd-logo';
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  font-size: inherit;
+  line-height: 1;
+  display: inline-block;
+  text-rendering: auto;
+  vertical-align: inherit;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+.editormd-logo:before,
+.editormd-logo-1x:before,
+.editormd-logo-2x:before,
+.editormd-logo-3x:before,
+.editormd-logo-4x:before,
+.editormd-logo-5x:before,
+.editormd-logo-6x:before,
+.editormd-logo-7x:before,
+.editormd-logo-8x:before {
+  content: "\e1987";
+  /* 
+  HTML Entity &#xe1987; 
+  example: <span class="editormd-logo">&#xe1987;</span>
+  */
+}
+
+.editormd-logo-1x {
+  font-size: 1em;
+}
+
+.editormd-logo-lg {
+  font-size: 1.2em;
+}
+
+.editormd-logo-2x {
+  font-size: 2em;
+}
+
+.editormd-logo-3x {
+  font-size: 3em;
+}
+
+.editormd-logo-4x {
+  font-size: 4em;
+}
+
+.editormd-logo-5x {
+  font-size: 5em;
+}
+
+.editormd-logo-6x {
+  font-size: 6em;
+}
+
+.editormd-logo-7x {
+  font-size: 7em;
+}
+
+.editormd-logo-8x {
+  font-size: 8em;
+}
+
+.editormd-logo-color {
+  color: #2196F3;
+}

File diff suppressed because it is too large
+ 2 - 0
static/editor.md/css/editormd.logo.min.css


File diff suppressed because it is too large
+ 5 - 0
static/editor.md/css/editormd.min.css


File diff suppressed because it is too large
+ 3554 - 0
static/editor.md/css/editormd.preview.css


File diff suppressed because it is too large
+ 5 - 0
static/editor.md/css/editormd.preview.min.css


File diff suppressed because it is too large
+ 4407 - 0
static/editor.md/docs/editormd.js.html


BIN
static/editor.md/docs/fonts/OpenSans-Bold-webfont.eot


File diff suppressed because it is too large
+ 1830 - 0
static/editor.md/docs/fonts/OpenSans-Bold-webfont.svg


BIN
static/editor.md/docs/fonts/OpenSans-Bold-webfont.woff


BIN
static/editor.md/docs/fonts/OpenSans-BoldItalic-webfont.eot


File diff suppressed because it is too large
+ 1830 - 0
static/editor.md/docs/fonts/OpenSans-BoldItalic-webfont.svg


BIN
static/editor.md/docs/fonts/OpenSans-BoldItalic-webfont.woff


BIN
static/editor.md/docs/fonts/OpenSans-Italic-webfont.eot


File diff suppressed because it is too large
+ 1830 - 0
static/editor.md/docs/fonts/OpenSans-Italic-webfont.svg


BIN
static/editor.md/docs/fonts/OpenSans-Italic-webfont.woff


BIN
static/editor.md/docs/fonts/OpenSans-Light-webfont.eot


File diff suppressed because it is too large
+ 1831 - 0
static/editor.md/docs/fonts/OpenSans-Light-webfont.svg


BIN
static/editor.md/docs/fonts/OpenSans-Light-webfont.woff


BIN
static/editor.md/docs/fonts/OpenSans-LightItalic-webfont.eot


File diff suppressed because it is too large
+ 1835 - 0
static/editor.md/docs/fonts/OpenSans-LightItalic-webfont.svg


BIN
static/editor.md/docs/fonts/OpenSans-LightItalic-webfont.woff


BIN
static/editor.md/docs/fonts/OpenSans-Regular-webfont.eot


File diff suppressed because it is too large
+ 1831 - 0
static/editor.md/docs/fonts/OpenSans-Regular-webfont.svg


BIN
static/editor.md/docs/fonts/OpenSans-Regular-webfont.woff


+ 65 - 0
static/editor.md/docs/index.html

@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>JSDoc: Home</title>
+
+    <script src="scripts/prettify/prettify.js"> </script>
+    <script src="scripts/prettify/lang-css.js"> </script>
+    <!--[if lt IE 9]>
+      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+    <![endif]-->
+    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+    <h1 class="page-title">Home</h1>
+
+    
+
+
+
+    
+
+
+    <h3> </h3>
+
+
+
+
+
+
+
+
+
+
+    
+
+
+
+
+
+
+
+
+
+</div>
+
+<nav>
+    <h2><a href="index.html">Home</a></h2>
+</nav>
+
+<br class="clear">
+
+<footer>
+    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0</a> on Mon Jun 08 2015 01:07:40 GMT+0800 (中国标准时间)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+</body>
+</html>

+ 25 - 0
static/editor.md/docs/scripts/linenumber.js

@@ -0,0 +1,25 @@
+/*global document */
+(function() {
+    var source = document.getElementsByClassName('prettyprint source linenums');
+    var i = 0;
+    var lineNumber = 0;
+    var lineId;
+    var lines;
+    var totalLines;
+    var anchorHash;
+
+    if (source && source[0]) {
+        anchorHash = document.location.hash.substring(1);
+        lines = source[0].getElementsByTagName('li');
+        totalLines = lines.length;
+
+        for (; i < totalLines; i++) {
+            lineNumber++;
+            lineId = 'line' + lineNumber;
+            lines[i].id = lineId;
+            if (lineId === anchorHash) {
+                lines[i].className += ' selected';
+            }
+        }
+    }
+})();

+ 202 - 0
static/editor.md/docs/scripts/prettify/Apache-License-2.0.txt

@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 2 - 0
static/editor.md/docs/scripts/prettify/lang-css.js

@@ -0,0 +1,2 @@
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
+/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);

File diff suppressed because it is too large
+ 28 - 0
static/editor.md/docs/scripts/prettify/prettify.js


+ 353 - 0
static/editor.md/docs/styles/jsdoc-default.css

@@ -0,0 +1,353 @@
+@font-face {
+    font-family: 'Open Sans';
+    font-weight: normal;
+    font-style: normal;
+    src: url('../fonts/OpenSans-Regular-webfont.eot');
+    src:
+        local('Open Sans'),
+        local('OpenSans'),
+        url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
+        url('../fonts/OpenSans-Regular-webfont.woff') format('woff'),
+        url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg');
+}
+
+@font-face {
+    font-family: 'Open Sans Light';
+    font-weight: normal;
+    font-style: normal;
+    src: url('../fonts/OpenSans-Light-webfont.eot');
+    src:
+        local('Open Sans Light'),
+        local('OpenSans Light'),
+        url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
+        url('../fonts/OpenSans-Light-webfont.woff') format('woff'),
+        url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg');
+}
+
+html
+{
+    overflow: auto;
+    background-color: #fff;
+    font-size: 14px;
+}
+
+body
+{
+    font-family: 'Open Sans', sans-serif;
+    line-height: 1.5;
+    color: #4d4e53;
+    background-color: white;
+}
+
+a, a:visited, a:active {
+    color: #0095dd;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+header
+{
+    display: block;
+    padding: 0px 4px;
+}
+
+tt, code, kbd, samp {
+    font-family: Consolas, Monaco, 'Andale Mono', monospace;
+}
+
+.class-description {
+    font-size: 130%;
+    line-height: 140%;
+    margin-bottom: 1em;
+    margin-top: 1em;
+}
+
+.class-description:empty {
+    margin: 0;
+}
+
+#main {
+    float: left;
+    width: 70%;
+}
+
+article dl {
+    margin-bottom: 40px;
+}
+
+section
+{
+    display: block;
+    background-color: #fff;
+    padding: 12px 24px;
+    border-bottom: 1px solid #ccc;
+    margin-right: 30px;
+}
+
+.variation {
+    display: none;
+}
+
+.signature-attributes {
+    font-size: 60%;
+    color: #aaa;
+    font-style: italic;
+    font-weight: lighter;
+}
+
+nav
+{
+    display: block;
+    float: right;
+    margin-top: 28px;
+    width: 30%;
+    box-sizing: border-box;
+    border-left: 1px solid #ccc;
+    padding-left: 16px;
+}
+
+nav ul {
+    font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
+    font-size: 100%;
+    line-height: 17px;
+    padding: 0;
+    margin: 0;
+    list-style-type: none;
+}
+
+nav ul a, nav ul a:visited, nav ul a:active {
+    font-family: Consolas, Monaco, 'Andale Mono', monospace;
+    line-height: 18px;
+    color: #4D4E53;
+}
+
+nav h3 {
+    margin-top: 12px;
+}
+
+nav li {
+    margin-top: 6px;
+}
+
+footer {
+    display: block;
+    padding: 6px;
+    margin-top: 12px;
+    font-style: italic;
+    font-size: 90%;
+}
+
+h1, h2, h3, h4 {
+    font-weight: 200;
+    margin: 0;
+}
+
+h1
+{
+    font-family: 'Open Sans Light', sans-serif;
+    font-size: 48px;
+    letter-spacing: -2px;
+    margin: 12px 24px 20px;
+}
+
+h2, h3
+{
+    font-size: 30px;
+    font-weight: 700;
+    letter-spacing: -1px;
+    margin-bottom: 12px;
+}
+
+h4
+{
+    font-size: 18px;
+    letter-spacing: -0.33px;
+    margin-bottom: 12px;
+    color: #4d4e53;
+}
+
+h5, .container-overview .subsection-title
+{
+    font-size: 120%;
+    font-weight: bold;
+    letter-spacing: -0.01em;
+    margin: 8px 0 3px 0;
+}
+
+h6
+{
+    font-size: 100%;
+    letter-spacing: -0.01em;
+    margin: 6px 0 3px 0;
+    font-style: italic;
+}
+
+.ancestors { color: #999; }
+.ancestors a
+{
+    color: #999 !important;
+    text-decoration: none;
+}
+
+.clear
+{
+    clear: both;
+}
+
+.important
+{
+    font-weight: bold;
+    color: #950B02;
+}
+
+.yes-def {
+    text-indent: -1000px;
+}
+
+.type-signature {
+    color: #aaa;
+}
+
+.name, .signature {
+    font-family: Consolas, Monaco, 'Andale Mono', monospace;
+}
+
+.details { margin-top: 14px; border-left: 2px solid #DDD; }
+.details dt { width: 120px; float: left; padding-left: 10px;  padding-top: 6px; }
+.details dd { margin-left: 70px; }
+.details ul { margin: 0; }
+.details ul { list-style-type: none; }
+.details li { margin-left: 30px; padding-top: 6px; }
+.details pre.prettyprint { margin: 0 }
+.details .object-value { padding-top: 0; }
+
+.description {
+    margin-bottom: 1em;
+    margin-top: 1em;
+}
+
+.code-caption
+{
+    font-style: italic;
+    font-size: 107%;
+    margin: 0;
+}
+
+.prettyprint
+{
+    border: 1px solid #ddd;
+    width: 80%;
+    overflow: auto;
+}
+
+.prettyprint.source {
+    width: inherit;
+}
+
+.prettyprint code
+{
+    font-size: 100%;
+    line-height: 18px;
+    display: block;
+    padding: 4px 12px;
+    margin: 0;
+    background-color: #fff;
+    color: #4D4E53;
+}
+
+.prettyprint code span.line
+{
+  display: inline-block;
+}
+
+.prettyprint.linenums
+{
+  padding-left: 70px;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.prettyprint.linenums ol
+{
+  padding-left: 0;
+}
+
+.prettyprint.linenums li
+{
+  border-left: 3px #ddd solid;
+}
+
+.prettyprint.linenums li.selected,
+.prettyprint.linenums li.selected *
+{
+  background-color: lightyellow;
+}
+
+.prettyprint.linenums li *
+{
+  -webkit-user-select: text;
+  -moz-user-select: text;
+  -ms-user-select: text;
+  user-select: text;
+}
+
+.params, .props
+{
+    border-spacing: 0;
+    border: 0;
+    border-collapse: collapse;
+}
+
+.params .name, .props .name, .name code {
+    color: #4D4E53;
+    font-family: Consolas, Monaco, 'Andale Mono', monospace;
+    font-size: 100%;
+}
+
+.params td, .params th, .props td, .props th
+{
+    border: 1px solid #ddd;
+    margin: 0px;
+    text-align: left;
+    vertical-align: top;
+    padding: 4px 6px;
+    display: table-cell;
+}
+
+.params thead tr, .props thead tr
+{
+    background-color: #ddd;
+    font-weight: bold;
+}
+
+.params .params thead tr, .props .props thead tr
+{
+    background-color: #fff;
+    font-weight: bold;
+}
+
+.params th, .props th { border-right: 1px solid #aaa; }
+.params thead .last, .props thead .last { border-right: 1px solid #ddd; }
+
+.params td.description > p:first-child,
+.props td.description > p:first-child
+{
+    margin-top: 0;
+    padding-top: 0;
+}
+
+.params td.description > p:last-child,
+.props td.description > p:last-child
+{
+    margin-bottom: 0;
+    padding-bottom: 0;
+}
+
+.disabled {
+    color: #454545;
+}

+ 0 - 0
static/editor.md/docs/styles/prettify-jsdoc.css


Some files were not shown because too many files changed in this diff