dever 5 rokov pred
rodič
commit
1a31a951ce
74 zmenil súbory, kde vykonal 7172 pridanie a 0 odobranie
  1. 2 0
      app/boot.php
  2. 363 0
      app/content/database/audio.php
  3. 248 0
      app/content/database/audio_content.php
  4. 288 0
      app/content/database/books.php
  5. 337 0
      app/content/database/service.php
  6. 8 0
      app/content/index.php
  7. 174 0
      app/content/lib/Audio.php
  8. 60 0
      app/content/lib/Manage.php
  9. 36 0
      app/content/lib/Service.php
  10. 268 0
      app/push/database/data.php
  11. 302 0
      app/push/database/info.php
  12. 8 0
      app/push/index.php
  13. 144 0
      app/push/lib/Data.php
  14. 52 0
      app/push/lib/Manage.php
  15. 8 0
      boot.php
  16. 0 0
      common.php
  17. 75 0
      config/base.php
  18. 119 0
      config/env/localhost/default.php
  19. 6 0
      config/route.php
  20. 323 0
      data/compile/sknow/manage/layadmin/console.cmp.php
  21. 62 0
      data/compile/sknow/manage/layadmin/home.cmp.php
  22. 27 0
      data/compile/sknow/manage/layadmin/inc/head.cmp.php
  23. 13 0
      data/compile/sknow/manage/layadmin/inc/menu.cmp.php
  24. 64 0
      data/compile/sknow/manage/layadmin/inc/nav.cmp.php
  25. 49 0
      data/compile/sknow/manage/layadmin/inc/script.cmp.php
  26. 79 0
      data/compile/sknow/manage/layadmin/login.cmp.php
  27. 155 0
      data/compile/sknow/manage/layadmin/project/database/list.cmp.php
  28. 112 0
      data/compile/sknow/manage/layadmin/project/database/update.cmp.php
  29. 1 0
      data/readme
  30. 3 0
      package.json
  31. 1 0
      package/aliyun
  32. 7 0
      package/area/daemon/import.php
  33. 4 0
      package/area/index.php
  34. 4 0
      package/attr/index.php
  35. 2 0
      package/boot.php
  36. 4 0
      package/category/index.php
  37. 4 0
      package/excel/index.php
  38. 4 0
      package/invite/index.php
  39. 88 0
      package/manage/config/base.php
  40. 7 0
      package/manage/daemon/loop.php
  41. 7 0
      package/manage/daemon/main.php
  42. 4 0
      package/manage/index.php
  43. 4 0
      package/message/index.php
  44. 4 0
      package/oauth/index.php
  45. 14 0
      package/passport/LICENSE
  46. 2 0
      package/passport/README.md
  47. 42 0
      package/passport/api/main.php
  48. 93 0
      package/passport/config/base.php
  49. 125 0
      package/passport/database/app.php
  50. 94 0
      package/passport/database/code.php
  51. 85 0
      package/passport/database/combine.php
  52. 138 0
      package/passport/database/profession.php
  53. 165 0
      package/passport/database/system.php
  54. 494 0
      package/passport/database/user.php
  55. 216 0
      package/passport/database/wechat.php
  56. 8 0
      package/passport/index.php
  57. 680 0
      package/passport/lib/Base.php
  58. 107 0
      package/passport/lib/Code.php
  59. 35 0
      package/passport/lib/Cron.php
  60. 58 0
      package/passport/lib/Email.php
  61. 76 0
      package/passport/lib/Manage.php
  62. 38 0
      package/passport/src/Api.php
  63. 209 0
      package/passport/src/App.php
  64. 382 0
      package/passport/src/Applet.php
  65. 75 0
      package/passport/src/Login.php
  66. 392 0
      package/passport/src/Reg.php
  67. 86 0
      package/passport/src/User.php
  68. 4 0
      package/pay/index.php
  69. 4 0
      package/qrcode/index.php
  70. 4 0
      package/score/index.php
  71. 4 0
      package/share/index.php
  72. 4 0
      package/sms/index.php
  73. 4 0
      package/token/index.php
  74. 4 0
      package/upload/index.php

+ 2 - 0
app/boot.php

@@ -0,0 +1,2 @@
+<?php
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 363 - 0
app/content/database/audio.php

@@ -0,0 +1,363 @@
+<?php
+
+$audit = Dever::config('base')->audit;
+
+$status = array
+(
+    1 => '上架',
+    2 => '下架',
+);
+
+# 常用的col
+$col = 'id,name,pic_cover,price,num_add_view+num_view as num_view,content,`desc`';
+
+return array
+(
+	# 表名
+	'name' => 'audio',
+	# 显示给用户看的名称
+	'lang' => '语音课程',
+	'order' => 100,
+
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'list'		=> true,
+		),
+		
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-80',
+			'name' 		=> '标题',
+			'default' 	=> '',
+			'desc' 		=> '标题',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'list'		=> true,
+			'search'	=> 'fulltext',
+			//增加预览
+			'preview'	=> true,
+		),
+
+		'desc'		=> array
+		(
+			'type' 		=> 'varchar-500',
+			'name' 		=> '摘要',
+			'default' 	=> '',
+			'desc' 		=> '摘要',
+			'match' 	=> 'is_string',
+			'update'	=> 'textarea',
+		),
+
+		'price'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '销售价格',
+			'default' 	=> '',
+			'desc' 		=> '销售价格',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+		),
+
+		'old_price'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '原价',
+			'default' 	=> '',
+			'desc' 		=> '原价',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+		),
+
+  		'pic_cover'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '1:1封面图-图片尺寸380*380px或等比尺寸,上传大小不能超过2M,支持JPG、PNG、GIF格式,建议上传JPG格式',
+			'default' 	=> '',
+			'desc' 		=> '封面图',
+			'match' 	=> 'is_string',
+			'update'	=> 'image',
+			'key' 		=> '1',
+			'place'		=> '150',
+			//直接上传到云端
+			//'upload'	=> 'qiniu',
+			//上传大数据
+			//'large' 	=> true,
+		),
+
+		'num_add_view'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '浏览量基数',
+			'default' 	=> '0',
+			'desc' 		=> '浏览量基数',
+			'match' 	=> 'option',
+			//'update'	=> 'text',
+		),
+
+		'num_view'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '浏览量',
+			'default' 	=> '0',
+			'desc' 		=> '请填写浏览量',
+			'match' 	=> 'option',
+			'search'	=> 'order',
+			'list'		=> '{num_view}+{num_add_view}',
+		),
+
+		'buy_add_view'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '购买基数',
+			'default' 	=> '0',
+			'desc' 		=> '购买基数',
+			'match' 	=> 'option',
+			//'update'	=> 'text',
+		),
+
+		'buy_view'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '购买量',
+			'default' 	=> '0',
+			'desc' 		=> '购买量',
+			'match' 	=> 'option',
+			'search'	=> 'order',
+			'list'		=> '{buy_view}+{buy_add_view}',
+		),
+
+		'pdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '发布时间',
+			'match' 	=> array('is_numeric', time()),
+			'default'	=> '',
+			'desc' 		=> '',
+			'update'	=> 'date',
+			'callback'	=> 'maketime',
+			'insert'	=> true,
+			//'list'		=> 'date("Y-m-d H:i:s", {pdate})',
+			'auth'		=> '"{pdate}" > 0',
+		),
+
+		'reorder'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '排序(数值越大越靠前)',
+			'default' 	=> '1',
+			'desc' 		=> '请输入排序',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'search'	=> 'order',
+			'list'		=> true,
+			'order'		=> 'desc',
+			'edit'		=> true,
+		),
+
+		'udate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '更新时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+		),
+
+		'content'		=> array
+		(
+			'type' 		=> 'text-255',
+			'name' 		=> '课程介绍',
+			'default' 	=> '',
+			'desc' 		=> '请输入课程介绍',
+			'match' 	=> 'is_string',
+			'update'	=> 'editor',
+			'key'		=> '1',
+			//'media'		=> '5',//下面的音视频已经做到了
+			//直接上传到云端
+			//'upload'	=> 'qiniu',
+			//上传大数据
+			//'large' 	=> true,
+			//自定义编辑器右侧按钮
+			/*
+			'editor'	=> array
+			(
+				'name' => '选择插入模块',
+				'button' => array
+				(
+					array
+					(
+						# 名称
+						'name' => '图片',
+						# 资源库id
+						'key' => 1,
+						# 类型
+						'type' => 'image',
+					),
+					array
+					(
+						'name' => '音频',
+						'key' => 5,
+						'type' => 'media',
+					),
+					array
+					(
+						'name' => '视频',
+						'key' => 'video/lib/core.vod',
+					),
+					array
+					(
+						'name' => '直播',
+						'key' => 'video/lib/core.live',
+					),
+
+					array
+					(
+						'name' => '小程序',
+						'key' => 'content/lib/applet.update',
+						'type' => 'update',
+					),
+				),
+			),
+			*/
+		),
+
+		'status'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '状态',
+            'default'   => '1',
+            'desc'      => '状态',
+            'match'     => 'is_numeric',
+            'update'    => 'radio',
+            'option'    => $status,
+        ),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+		),
+	),
+	
+	# 管理功能
+	'manage' => array
+	(
+		//'insert' => false,
+		# 列表
+		'list_button' => array
+		(
+			'add' => array('新增章节', '"audio_content&project=content&search_option_audio_id={id}&oper_parent=audio&oper_project=content&oper_save_jump=audio&where_id={id}"'),
+			'list1' => array('章节列表', '"audio_content&search_option_audio_id={id}&oper_parent=audio"'),
+		),
+	),
+
+	# request 请求接口定义
+	'request' => array
+	(
+		'search' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'ids' => array('yes-id', 'in'),
+				'name' => array('yes', 'like'),
+				'id' => 'yes',
+				'status' => 1,
+				'state' => 1,
+			),
+			'type' => 'all',
+			'order' => array('reorder' => 'desc', 'pdate' => 'desc'),
+			'limit' => '0,1000',
+			'col' => 'name as name, id, id as value, "" as selected, "" as disabled|id',
+		),
+
+		'getAll' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'id' => 'yes',
+				'status' => 1,
+				'state' => 1,
+			),
+			'type' => 'all',
+			'order' => array('reorder' => 'desc','pdate' => 'desc'),
+			'page' => array(10, 'list'),
+			'col' => $col,
+		),
+
+		'getList' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'status' => 1,
+				'state' => 1,
+			),
+			'type' => 'all',
+			'order' => array('reorder' => 'desc','pdate' => 'desc'),
+			'limit' => '0,10',
+			'col' => $col,
+		),
+
+		'getRelation' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'noid' => array('yes-id', '!='),
+				'status' => 1,
+				'state' => 1,
+			),
+			'type' => 'all',
+			'order' => array('reorder' => 'desc','pdate' => 'desc'),
+			'limit' => '0,4',
+			'col' => $col,
+		),
+
+		'getOne' => array
+		(
+			# 匹配的正则或函数 选填项
+			'where' => array
+			(
+				'id' => 'yes',
+			),
+			'type' => 'one',
+			'col' => $col,
+		),
+		
+		# 更新浏览量
+		'addView' => array
+		(
+			'type' => 'update',
+			'where' => array
+			(
+				'id' => 'yes',
+			),
+			'set' => array
+			(
+				'num_view' => array('1', '+='),
+			),
+		),
+	),
+);

+ 248 - 0
app/content/database/audio_content.php

@@ -0,0 +1,248 @@
+<?php
+
+$status = array
+(
+    1 => '开启',
+    2 => '关闭',
+);
+
+$type = array
+(
+    1 => '收费',
+    2 => '免费',
+);
+
+$audio_status = array
+(
+    1 => '未转换',
+    2 => '转换中',
+    3 => '转换完成',
+);
+
+return array
+(
+    # 表名
+    'name' => 'audio_content',
+    # 显示给用户看的名称
+    'lang' => '章节管理',
+    'menu' => false,
+    'end' => array
+    (
+        'insert' => 'content/lib/audio.convert',
+        'update' => 'content/lib/audio.convert',
+    ),
+    # 数据结构
+    'struct' => array
+    (
+    
+        'id'        => array
+        (
+            'type'      => 'int-11',
+            'name'      => 'ID',
+            'default'   => '',
+            'desc'      => '',
+            'match'     => 'is_numeric',
+            'search'    => 'order',
+            //'list'        => true,
+        ),
+
+        'audio_id'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '课程',
+            'default'   => '',
+            'desc'      => '课程',
+            'match'     => 'is_numeric',
+            'update'    => 'hidden',
+            'value'     => Dever::input('search_option_audio_id')
+        ),
+
+        'name'      => array
+        (
+            'type'      => 'varchar-80',
+            'name'      => '标题',
+            'default'   => '',
+            'desc'      => '标题',
+            'match'     => 'is_string',
+            'update'    => 'text',
+            'search'    => 'fulltext',
+            'list'      => true,
+        ),
+
+        'reorder'       => array
+        (
+            'type'      => 'int-11',
+            'name'      => '章节数(数值越小越靠前)',
+            'default'   => '1',
+            'desc'      => '请输入排序',
+            'match'     => 'option',
+            'update'    => 'text',
+            'search'    => 'order',
+            'list'      => true,
+            'order'     => 'asc',
+            'edit'      => true,
+        ),
+
+        'type'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '是否收费',
+            'default'   => '1',
+            'desc'      => '是否收费',
+            'match'     => 'is_numeric',
+            'update'    => 'radio',
+            'option'    => $type,
+        ),
+
+        'desc'      => array
+        (
+            'type'      => 'varchar-500',
+            'name'      => '摘要',
+            'default'   => '',
+            'desc'      => '摘要',
+            'match'     => 'is_string',
+            'update'    => 'textarea',
+        ),
+
+        'content'      => array
+        (
+            'type'      => 'text-255',
+            'name'      => '课程展示内容-排版后显示的内容,可以有图片',
+            'default'   => '',
+            'desc'      => '内容',
+            'match'     => 'option',
+            'update'    => 'editor',
+            'key'       => 1,
+            //'search'  => 'fulltext',
+            //'list'        => true,
+        ),
+
+        'audio_content'      => array
+        (
+            'type'      => 'text-255',
+            'name'      => '语音内容-系统自动从中提取文字转成一段语音,多音字请用同音字替代,不显示在前端',
+            'default'   => '',
+            'desc'      => '语音内容',
+            'match'     => 'option',
+            'update'    => 'editor',
+            'key'       => 1,
+            //'search'  => 'fulltext',
+            //'list'        => true,
+        ),
+
+        'audio'      => array
+        (
+            'type'      => 'varchar-500',
+            'name'      => '语音文件',
+            'default'   => '',
+            'desc'      => '语音文件',
+            'match'     => 'is_string',
+        ),
+
+        'ali_request_id'      => array
+        (
+            'type'      => 'varchar-150',
+            'name'      => '阿里云请求的request_id',
+            'default'   => '',
+            'desc'      => '阿里云请求的request_id',
+            'match'     => 'is_string',
+            'update'    => 'text',
+        ),
+
+        'ali_task_id'      => array
+        (
+            'type'      => 'varchar-150',
+            'name'      => '阿里云请求的task_id',
+            'default'   => '',
+            'desc'      => '阿里云请求的task_id',
+            'match'     => 'is_string',
+            'update'    => 'text',
+        ),
+
+        'audio_status'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '转换状态',
+            'default'   => '1',
+            'desc'      => '转换状态',
+            'match'     => 'is_numeric',
+            //'update'    => 'radio',
+            'option'    => $audio_status,
+        ),
+
+        'status'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '状态',
+            'default'   => '1',
+            'desc'      => '状态',
+            'match'     => 'is_numeric',
+            'update'    => 'radio',
+            'option'    => $status,
+        ),
+
+        'num_add_view'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '学习量基数',
+            'default'   => '0',
+            'desc'      => '学习量基数',
+            'match'     => 'option',
+            //'update'  => 'text',
+        ),
+
+        'num_view'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '学习量',
+            'default'   => '0',
+            'desc'      => '请填写浏览量',
+            'match'     => 'option',
+            'search'    => 'order',
+            'list'      => '{num_view}+{num_add_view}',
+        ),
+
+        'state'     => array
+        (
+            'type'      => 'tinyint-1',
+            'name'      => '状态',
+            'default'   => '1',
+            'desc'      => '请选择状态',
+            'match'     => 'is_numeric',
+        ),
+        
+        'cdate'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '创建时间',
+            'match'     => array('is_numeric', time()),
+            'desc'      => '',
+            # 只有insert时才生效
+            'insert'    => true,
+            'search'    => 'date',
+            //'list'      => 'date("Y-m-d H:i:s", {cdate})',
+        ),
+    ),
+
+    'manage' => array
+    (
+
+    ),
+
+    'request' => array
+    (
+        'getData' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'audio_id' => 'yes',
+                'state' => 1,
+                'status' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'asc', 'id' => 'desc'),
+            'col' => '*',
+        ),
+    ),
+);

+ 288 - 0
app/content/database/books.php

@@ -0,0 +1,288 @@
+<?php
+
+$audit = Dever::config('base')->audit;
+
+$status = array
+(
+    1 => '上架',
+    2 => '下架',
+);
+
+# 常用的col
+$col = 'id,name,pic_cover,num_add_view+num_view as num_view,content,buy_link,`desc`';
+
+return array
+(
+    # 表名
+    'name' => 'books',
+    # 显示给用户看的名称
+    'lang' => '图书管理',
+    'order' => 98,
+
+    # 数据结构
+    'struct' => array
+    (
+        'id'        => array
+        (
+            'type'      => 'int-11',
+            'name'      => 'ID',
+            'default'   => '',
+            'desc'      => '',
+            'match'     => 'is_numeric',
+            'list'      => true,
+        ),
+        
+        'name'      => array
+        (
+            'type'      => 'varchar-80',
+            'name'      => '标题',
+            'default'   => '',
+            'desc'      => '标题',
+            'match'     => 'is_string',
+            'update'    => 'text',
+            'list'      => true,
+            'search'    => 'fulltext',
+            //增加预览
+            'preview'   => true,
+        ),
+
+        'price'     => array
+        (
+            'type'      => 'varchar-32',
+            'name'      => '销售价格',
+            'default'   => '',
+            'desc'      => '销售价格',
+            'match'     => 'is_string',
+            'update'    => 'text',
+        ),
+
+        'old_price'     => array
+        (
+            'type'      => 'varchar-32',
+            'name'      => '原价',
+            'default'   => '',
+            'desc'      => '原价',
+            'match'     => 'is_string',
+            'update'    => 'text',
+        ),
+
+        'desc'      => array
+        (
+            'type'      => 'varchar-500',
+            'name'      => '摘要',
+            'default'   => '',
+            'desc'      => '摘要',
+            'match'     => 'is_string',
+            'update'    => 'textarea',
+        ),
+
+        'buy_link'      => array
+        (
+            'type'      => 'varchar-500',
+            'name'      => '购买链接',
+            'default'   => '',
+            'desc'      => '购买链接',
+            'match'     => 'is_string',
+            'update'    => 'textarea',
+        ),
+
+        'pic_cover'     => array
+        (
+            'type'      => 'varchar-150',
+            'name'      => '1:1封面图-图片尺寸380*380px或等比尺寸,上传大小不能超过2M,支持JPG、PNG、GIF格式,建议上传JPG格式',
+            'default'   => '',
+            'desc'      => '封面图',
+            'match'     => 'is_string',
+            'update'    => 'image',
+            'key'       => '1',
+            'place'     => '150',
+            //直接上传到云端
+            //'upload'  => 'qiniu',
+            //上传大数据
+            //'large'   => true,
+        ),
+
+        'num_add_view'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '浏览量基数',
+            'default'   => '0',
+            'desc'      => '浏览量基数',
+            'match'     => 'option',
+            //'update'  => 'text',
+        ),
+
+        'num_view'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '浏览量',
+            'default'   => '0',
+            'desc'      => '请填写浏览量',
+            'match'     => 'option',
+            'search'    => 'order',
+            'list'      => '{num_view}+{num_add_view}',
+        ),
+
+        'pdate'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '发布时间',
+            'match'     => array('is_numeric', time()),
+            'default'   => '',
+            'desc'      => '',
+            'update'    => 'date',
+            'callback'  => 'maketime',
+            'insert'    => true,
+            //'list'        => 'date("Y-m-d H:i:s", {pdate})',
+            'auth'      => '"{pdate}" > 0',
+        ),
+
+        'reorder'       => array
+        (
+            'type'      => 'int-11',
+            'name'      => '排序(数值越大越靠前)',
+            'default'   => '1',
+            'desc'      => '请输入排序',
+            'match'     => 'option',
+            'update'    => 'text',
+            'search'    => 'order',
+            'list'      => true,
+            'order'     => 'desc',
+            'edit'      => true,
+        ),
+
+        'udate'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '更新时间',
+            'match'     => array('is_numeric', time()),
+            'desc'      => '',
+        ),
+
+        'status'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '状态',
+            'default'   => '1',
+            'desc'      => '状态',
+            'match'     => 'is_numeric',
+            'update'    => 'radio',
+            'option'    => $status,
+        ),
+
+        'state'     => array
+        (
+            'type'      => 'tinyint-1',
+            'name'      => '状态',
+            'default'   => '1',
+            'desc'      => '请选择状态',
+            'match'     => 'is_numeric',
+        ),
+
+        'cdate'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '录入时间',
+            'match'     => array('is_numeric', time()),
+            'desc'      => '',
+            # 只有insert时才生效
+            'insert'    => true,
+        ),
+    ),
+    
+    # 管理功能
+    'manage' => array
+    (
+
+    ),
+
+    # request 请求接口定义
+    'request' => array
+    (
+        'search' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'ids' => array('yes-id', 'in'),
+                'name' => array('yes', 'like'),
+                'id' => 'yes',
+                'status' => 1,
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc', 'pdate' => 'desc'),
+            'limit' => '0,1000',
+            'col' => 'name as name, id, id as value, "" as selected, "" as disabled|id',
+        ),
+
+        'getAll' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'id' => 'yes',
+                'status' => 1,
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc','pdate' => 'desc'),
+            'page' => array(10, 'list'),
+            'col' => $col,
+        ),
+
+        'getList' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'status' => 1,
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc','pdate' => 'desc'),
+            'limit' => '0,10',
+            'col' => $col,
+        ),
+
+        'getRelation' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'noid' => array('yes-id', '!='),
+                'status' => 1,
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc','pdate' => 'desc'),
+            'limit' => '0,4',
+            'col' => $col,
+        ),
+
+        'getOne' => array
+        (
+            # 匹配的正则或函数 选填项
+            'where' => array
+            (
+                'id' => 'yes',
+            ),
+            'type' => 'one',
+            'col' => $col,
+        ),
+        
+        # 更新浏览量
+        'addView' => array
+        (
+            'type' => 'update',
+            'where' => array
+            (
+                'id' => 'yes',
+            ),
+            'set' => array
+            (
+                'num_view' => array('1', '+='),
+            ),
+        ),
+    ),
+);

+ 337 - 0
app/content/database/service.php

@@ -0,0 +1,337 @@
+<?php
+
+$audit = Dever::config('base')->audit;
+
+$status = array
+(
+    1 => '上架',
+    2 => '下架',
+);
+
+# 常用的col
+$col = 'id,name,pic_cover,num_add_view+num_view as num_view,content,`desc`';
+
+return array
+(
+    # 表名
+    'name' => 'service',
+    # 显示给用户看的名称
+    'lang' => '服务咨询',
+    'order' => 99,
+
+    # 数据结构
+    'struct' => array
+    (
+        'id'        => array
+        (
+            'type'      => 'int-11',
+            'name'      => 'ID',
+            'default'   => '',
+            'desc'      => '',
+            'match'     => 'is_numeric',
+            'list'      => true,
+        ),
+        
+        'name'      => array
+        (
+            'type'      => 'varchar-80',
+            'name'      => '标题',
+            'default'   => '',
+            'desc'      => '标题',
+            'match'     => 'is_string',
+            'update'    => 'text',
+            'list'      => true,
+            'search'    => 'fulltext',
+        ),
+
+        'phone'      => array
+        (
+            'type'      => 'varchar-80',
+            'name'      => '咨询电话',
+            'default'   => '',
+            'desc'      => '咨询电话',
+            'match'     => 'is_string',
+            'update'    => 'text',
+        ),
+
+        'desc'      => array
+        (
+            'type'      => 'varchar-500',
+            'name'      => '摘要',
+            'default'   => '',
+            'desc'      => '摘要',
+            'match'     => 'is_string',
+            'update'    => 'textarea',
+        ),
+
+        'pic_cover'     => array
+        (
+            'type'      => 'varchar-150',
+            'name'      => '1:1封面图-图片尺寸380*380px或等比尺寸,上传大小不能超过2M,支持JPG、PNG、GIF格式,建议上传JPG格式',
+            'default'   => '',
+            'desc'      => '封面图',
+            'match'     => 'is_string',
+            'update'    => 'image',
+            'key'       => '1',
+            'place'     => '150',
+            //直接上传到云端
+            //'upload'  => 'qiniu',
+            //上传大数据
+            //'large'   => true,
+        ),
+
+        'num_add_view'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '浏览量基数',
+            'default'   => '0',
+            'desc'      => '浏览量基数',
+            'match'     => 'option',
+            //'update'  => 'text',
+        ),
+
+        'num_view'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '浏览量',
+            'default'   => '0',
+            'desc'      => '请填写浏览量',
+            'match'     => 'option',
+            'search'    => 'order',
+            'list'      => '{num_view}+{num_add_view}',
+        ),
+
+        'buy_add_view'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '购买基数',
+            'default'   => '0',
+            'desc'      => '购买基数',
+            'match'     => 'option',
+            //'update'  => 'text',
+        ),
+
+        'buy_view'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '购买量',
+            'default'   => '0',
+            'desc'      => '购买量',
+            'match'     => 'option',
+            'search'    => 'order',
+            'list'      => '{buy_view}+{buy_add_view}',
+        ),
+
+        'pdate'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '发布时间',
+            'match'     => array('is_numeric', time()),
+            'default'   => '',
+            'desc'      => '',
+            'update'    => 'date',
+            'callback'  => 'maketime',
+            'insert'    => true,
+            //'list'        => 'date("Y-m-d H:i:s", {pdate})',
+            'auth'      => '"{pdate}" > 0',
+        ),
+
+        'reorder'       => array
+        (
+            'type'      => 'int-11',
+            'name'      => '排序(数值越大越靠前)',
+            'default'   => '1',
+            'desc'      => '请输入排序',
+            'match'     => 'option',
+            'update'    => 'text',
+            'search'    => 'order',
+            'list'      => true,
+            'order'     => 'desc',
+            'edit'      => true,
+        ),
+
+        'content'       => array
+        (
+            'type'      => 'text-255',
+            'name'      => '内容',
+            'default'   => '',
+            'desc'      => '请输入内容',
+            'match'     => 'is_string',
+            'update'    => 'editor',
+            'key'       => '1',
+            //'media'       => '5',//下面的音视频已经做到了
+            //直接上传到云端
+            //'upload'  => 'qiniu',
+            //上传大数据
+            //'large'   => true,
+            //自定义编辑器右侧按钮
+            /*
+            'editor'    => array
+            (
+                'name' => '选择插入模块',
+                'button' => array
+                (
+                    array
+                    (
+                        # 名称
+                        'name' => '图片',
+                        # 资源库id
+                        'key' => 1,
+                        # 类型
+                        'type' => 'image',
+                    ),
+                    array
+                    (
+                        'name' => '音频',
+                        'key' => 5,
+                        'type' => 'media',
+                    ),
+                    array
+                    (
+                        'name' => '视频',
+                        'key' => 'video/lib/core.vod',
+                    ),
+                    array
+                    (
+                        'name' => '直播',
+                        'key' => 'video/lib/core.live',
+                    ),
+
+                    array
+                    (
+                        'name' => '小程序',
+                        'key' => 'content/lib/applet.update',
+                        'type' => 'update',
+                    ),
+                ),
+            ),
+            */
+        ),
+
+        'status'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '状态',
+            'default'   => '1',
+            'desc'      => '状态',
+            'match'     => 'is_numeric',
+            'update'    => 'radio',
+            'option'    => $status,
+        ),
+
+        'state'     => array
+        (
+            'type'      => 'tinyint-1',
+            'name'      => '状态',
+            'default'   => '1',
+            'desc'      => '请选择状态',
+            'match'     => 'is_numeric',
+        ),
+
+        'cdate'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '录入时间',
+            'match'     => array('is_numeric', time()),
+            'desc'      => '',
+            # 只有insert时才生效
+            'insert'    => true,
+        ),
+    ),
+    
+    # 管理功能
+    'manage' => array
+    (
+        
+    ),
+
+    # request 请求接口定义
+    'request' => array
+    (
+        'search' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'ids' => array('yes-id', 'in'),
+                'name' => array('yes', 'like'),
+                'id' => 'yes',
+                'status' => 1,
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc', 'pdate' => 'desc'),
+            'limit' => '0,1000',
+            'col' => 'name as name, id, id as value, "" as selected, "" as disabled|id',
+        ),
+
+        'getAll' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'id' => 'yes',
+                'status' => 1,
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc','pdate' => 'desc'),
+            'page' => array(10, 'list'),
+            'col' => $col,
+        ),
+
+        'getList' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'status' => 1,
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc','pdate' => 'desc'),
+            'limit' => '0,10',
+            'col' => $col,
+        ),
+
+        'getRelation' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'noid' => array('yes-id', '!='),
+                'status' => 1,
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc','pdate' => 'desc'),
+            'limit' => '0,4',
+            'col' => $col,
+        ),
+
+        'getOne' => array
+        (
+            # 匹配的正则或函数 选填项
+            'where' => array
+            (
+                'id' => 'yes',
+            ),
+            'type' => 'one',
+            'col' => $col,
+        ),
+        
+        # 更新浏览量
+        'addView' => array
+        (
+            'type' => 'update',
+            'where' => array
+            (
+                'id' => 'yes',
+            ),
+            'set' => array
+            (
+                'num_view' => array('1', '+='),
+            ),
+        ),
+    ),
+);

+ 8 - 0
app/content/index.php

@@ -0,0 +1,8 @@
+<?php
+
+define('DEVER_APP_NAME', 'content');
+define('DEVER_APP_LANG', '内容管理');
+define('DEVER_APP_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+define('DEVER_MANAGE_ORDER', 200);
+define('DEVER_MANAGE_ICON', 'glyphicon glyphicon-tower layui-icon-tabs');
+include(DEVER_APP_PATH . '../boot.php');

+ 174 - 0
app/content/lib/Audio.php

@@ -0,0 +1,174 @@
+<?php
+
+namespace Content\Lib;
+
+use Dever;
+
+class Audio
+{
+    public function get($data, $uid = false)
+    {
+        if (!is_array($data)) {
+            $data = Dever::db('content/audio')->getOne($data);
+        }
+        
+        if (!$data) {
+            Dever::alert('错误的课程信息');
+        }
+    
+        $data = $this->getContent($data, $uid);
+
+        return $data;
+    }
+
+    # 获取相关推荐
+    public function getRelation($info)
+    {
+        $where['noid'] = $info['id'];
+        return Dever::db('content/audio')->getRelation($where);
+    }
+
+    # 增加浏览量
+    public function addView($id)
+    {
+        Dever::db('content/audio')->addView($id);
+    }
+
+    # 获取课程列表
+    public function getList($id)
+    {
+        $where['audio_id'] = $id;
+        $data = Dever::db('content/audio_content')->getData($where);
+
+        return $data;
+    }
+
+    # 根据文字获取语音
+    public function convert($id)
+    {
+        Dever::daemon('content/lib/audio.convert_daemon?id=' . $id);
+    }
+
+    public function test_api($id)
+    {
+        $this->convert_daemon($id);
+
+        return 'ok';
+    }
+
+    public function convert_daemon($id)
+    {
+        $id = Dever::input('id');
+
+        $data = Dever::db('content/audio_content')->one($id);
+
+        if ($data && !$data['ali_request_id'] && $data['audio_content']) {
+            $request = $this->audio($data['id'], $data['audio_id'], $data['audio_content']);
+            if ($request) {
+                $update['where_id'] = $id;
+                $update['ali_request_id'] = $request[0];
+                $update['ali_task_id'] = $request[1];
+                $update['audio_status'] = 2;
+                Dever::db('content/audio_content')->update($update);
+            }
+        }
+    }
+
+    private function token()
+    {
+        $token = Dever::load('token/lib/aliyun')->token();
+
+        $url = 'https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts';
+        # 长文本
+        $url = 'https://nls-gateway.cn-shanghai.aliyuncs.com/rest/v1/tts/async';
+
+        return array
+        (
+            'url' => $url,
+            'token' => $token,
+            'appkey' => 'k6ZkLekn5NfRuhR4'
+        );
+    }
+
+    private function audio($id, $audio_id, $text)
+    {
+        $text = str_replace('</p>', "\r\n", $text);
+        $text = str_replace('<br>', "\r\n", $text);
+        $text = str_replace('<br />', "\r\n", $text);
+        $text = str_replace(' ', '', $text);
+        $text = str_replace('&nbsp;', " ", $text);
+        $text = strip_tags($text);
+
+        $config = $this->token();
+
+        $param['header']['appkey'] = $config['appkey'];
+        $param['header']['token'] = $config['token'];
+
+        $param['payload']['tts_request']['text'] = $text;
+        $param['payload']['tts_request']['voice'] = 'Aixia';
+        $param['payload']['tts_request']['format'] = 'wav';
+        $param['payload']['tts_request']['volume'] = 100;
+        $param['payload']['tts_request']['speech_rate'] = -150;
+        $param['payload']['tts_request']['pitch_rate'] = 0;
+        $param['payload']['enable_notify'] = false;
+        $param['payload']['notify_url'] = Dever::url('lib/audio.audio_address?id=' . $id, 'content');
+
+        $param['context']['device_id'] = 'my_php_audio';
+
+        $data = Dever::curl($config['url'], $param, 'post', true);
+        $data = Dever::json_decode($data);
+
+        if (isset($data['request_id']) && $data['request_id'] && isset($data['data']['task_id']) && $data['data']['task_id']) {
+            return array($data['request_id'], $data['data']['task_id']);
+        }
+
+        
+        return false;
+    }
+
+    public function audio_address_api()
+    {
+        $id = Dever::input('id');
+
+        $info = Dever::db('content/audio_content')->one($id);
+
+        if ($info && $info['ali_request_id'] && !$info['audio']) {
+            $config = $this->token();
+
+            $param['token'] = $config['token'];
+            $param['appkey'] = $config['appkey'];
+            $param['request_id'] = $info['ali_request_id'];
+            $param['task_id'] = $info['ali_task_id'];
+
+
+            $data = Dever::curl($config['url'], $param);
+            $data = Dever::json_decode($data);
+
+            if (isset($data['data']['audio_address']) && $data['data']['audio_address']) {
+                #成功
+                $update['where_id'] = $id;
+                $update['audio'] = $this->download($info['id'], $info['audio_id'], $data['data']['audio_address']);
+                $update['audio_status'] = 3;
+                Dever::db('content/audio_content')->update($update);
+            }
+        }
+
+        return 'ok';
+    }
+
+    private function download($id, $audio_id, $source)
+    {
+        $data = Dever::load('upload/save')->copy($source, 6);
+        $file = $data['url'];
+        return $file;
+
+        $path = Dever::path(Dever::data(), 'audio/' . $audio_id . '/');
+        $file = $path . $id . '.wav';
+        if (!file_exists($file)) {
+            $content = file_get_contents($source);
+            file_put_contents($file, $content);
+        }
+
+        return $file;
+    }
+}

+ 60 - 0
app/content/lib/Manage.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace Content\Lib;
+
+use Dever;
+
+class Manage
+{
+    private function search($table = 'content/audio')
+    {
+        $keyword = Dever::input('keyword');
+
+        $yes = Dever::input('yes');
+
+        $where = array();
+
+        $cate = Dever::input('cate');
+        if ($cate) {
+            $where['cate_id'] = $cate;
+        }
+
+        if ($yes) {
+            $yes = Dever::db($table)->search(array('ids' => $yes));
+        }
+        if (!$keyword) {
+            $where['limit'] = '0,50';
+            $data = Dever::db($table)->search($where);
+        } else {
+            $where['name'] = $keyword;
+            $data = Dever::db($table)->search($where);
+        }
+
+        $result = array();
+        if ($yes) {
+            foreach ($yes as $k => $v) {
+                if (isset($data[$k])) {
+                    unset($data[$k]);
+                }
+                $yes[$k]['selected'] = 'selected';
+            }
+            $data = $yes + $data;
+
+            $data = array_merge($data, array());
+        } else {
+            $data = array_merge($data, array());
+        }
+
+        if (!$data) {
+            Dever::alert('暂无数据');
+        }
+
+        return $data;
+    }
+
+    # 搜索语音课程
+    public function search_audio_api()
+    {
+        return $this->search('content/audio');
+    }
+}

+ 36 - 0
app/content/lib/Service.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace Content\Lib;
+
+use Dever;
+
+class Service
+{
+    public function get($data, $uid = false)
+    {
+        if (!is_array($data)) {
+            $data = Dever::db('content/service')->getOne($data);
+        }
+        
+        if (!$data) {
+            Dever::alert('错误的课程信息');
+        }
+    
+        $data = $this->getContent($data, $uid);
+
+        return $data;
+    }
+
+    # 获取相关推荐
+    public function getRelation($info)
+    {
+        $where['noid'] = $info['id'];
+        return Dever::db('content/service')->getRelation($where);
+    }
+
+    # 增加浏览量
+    public function addView($id)
+    {
+        Dever::db('content/service')->addView($id);
+    }
+}

+ 268 - 0
app/push/database/data.php

@@ -0,0 +1,268 @@
+<?php
+
+# 定义几个常用的选项
+$option = array
+(
+    1 => '显示',
+    2 => '不显示',
+);
+
+$type = Dever::config('base')->type;
+$type[10] = '链接';
+
+
+$list = function()
+{
+    return Dever::db('push/info')->state();
+};
+$info = Dever::input('search_option_info_id');
+$type_default = 1;
+if ($info) {
+    $info = Dever::load('push/info-one', $info);
+
+    if (!$info) {
+        echo 'error';die;
+    }
+    $function = explode(',', $info['function']);
+    
+    foreach ($type as $k => $v) {
+        if (!in_array($k, $function)) {
+            unset($type[$k]);
+        } else {
+            $type_default = $k;
+        }
+    }
+    $info['name'] .= '下的推送数据管理';
+    $info['col'] = explode(',', $info['col']);
+    /*
+    $preview = $info['preview'];
+    $preview_height = $info['preview_height'] ? $info['preview_height'] : 500;
+    */
+
+    $name_state = in_array(1, $info['col']);
+    $link_state = in_array(2, $info['col']);
+    $pic_state = in_array(3, $info['col']);
+    $content_state = in_array(4, $info['col']);
+    $share_pic_state = in_array(5, $info['col']);
+
+    /*
+    if ($info['data_type']) {
+        $type = explode("\r\n", $info['data_type']);
+    }
+    */
+} else {
+    $info = array();
+    $info['name'] = '推送数据管理';
+    $info['col_pic'] = '100X100';
+    $info['col_share_pic'] = '100X100';
+    $info['col_content'] = '30';
+    $info['type'] = 1;
+    $name_state = true;
+    $link_state = false;
+    $pic_state = false;
+    $share_pic_state = false;
+    $content_state = false;
+    $preview = '';
+    $preview_height = 0;
+}
+
+
+return array
+(
+    # 表名
+    'name' => 'data',
+    # 显示给用户看的名称
+    'lang' => $info['name'],
+    'order' => 20,
+    //'menu' => false,
+
+    //'desc' => '预览地址:<br /><iframe id="preview" height="'.$preview_height.'" width="100%"  frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="no" allowtransparency="yes" src="'.$preview.'" ></iframe>',
+
+    # 数据结构
+    'struct' => array
+    (
+        'id'        => array
+        (
+            'type'      => 'int-11',
+            'name'      => 'ID',
+            'default'   => '',
+            'desc'      => '',
+            'match'     => 'is_numeric',
+            //'search'  => 'order',
+            'order'     => 'desc',
+            //'list'        => true,
+        ),
+
+        'info_id'       => array
+        (
+            'type'      => 'int-11',
+            'name'      => '选择推送位',
+            'default'   => Dever::input('search_option_info_id', '1'),
+            'desc'      => '推送位',
+            'match'     => 'is_numeric',
+            'search'    => 'select',
+            'update'    => 'hidden',
+            'option'    => $list,
+            'list'      => true,
+            'value'     => Dever::input('search_option_info_id', '1'),
+        ),
+
+        'type'      => array
+        (
+            'type'      => 'int-11',
+            'name'      => '类型',
+            'default'   => ''.$type_default.'',
+            'desc'      => '请选择类型',
+            'match'     => 'is_numeric',
+            'update'    => 'radio',
+            'search'    => 'select',
+            'option'    => $type,
+            'control'   => 'type',
+        ),
+
+        'article_id'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '关联文章-如不选择,则点击进入文章列表',
+            'default'   => '',
+            'desc'      => '关联文章',
+            'match'     => 'option',
+            'update'    => 'select',
+            'show'      => 'type=1',
+            'update_search' => 'content/lib/manage.search_article',
+        ),
+
+        'olink'      => array
+        (
+            'type'      => 'varchar-400',
+            'name'      => '链接',
+            'default'   => '',
+            'desc'      => '请输入链接',
+            'match'     => 'option',
+            'update'    => 'text',
+            'show'      => 'type=10',
+            //'search'    => 'fulltext',
+            //'list'        => true,
+        ),
+        
+        'name'      => array
+        (
+            'type'      => 'varchar-60',
+            'name'      => '标题-手动干扰项,如想修改当前推送位的标题请在此修改',
+            'default'   => '',
+            'desc'      => '请输入标题',
+            'match'     => $name_state ? 'option' : 'option',
+            'update'    => $name_state ? 'text' : 'hidden',
+            'search'    => $name_state ? 'fulltext' : '',
+            'list'      => $name_state ? 'Dever::load("push/lib/manage.name", {id})' : false,
+            'edit'      => $name_state ? true : false,
+        ),
+
+        'link'      => array
+        (
+            'type'      => 'varchar-200',
+            'name'      => '链接-手动干扰项,如想修改当前推送位的链接请在此修改',
+            'default'   => '',
+            'desc'      => '请输入链接',
+            'match'     => $link_state ? 'option' : 'option',
+            //'update'    => $link_state ? 'text' : 'hidden',
+            //'search'    => $link_state ? 'fulltext' : '',
+            //'list'        => $link_state ? true : false,
+            //'edit'      => $link_state ? true : false,
+        ),
+
+        'pic'       => array
+        (
+            'type'      => 'varchar-200',
+            'name'      => '图片或图标-手动干扰项,请上传' . $info['col_pic'] . '大小的图片',
+            'default'   => '',
+            'desc'      => '请选择图片',
+            'match'     => $pic_state ? 'option' : 'option',
+            'update'    => $pic_state ? 'image' : 'hidden',
+            'search'    => $pic_state ? 'fulltext' : '',
+            //'list'        => $pic_state ? true : false,
+            'key'       => 1
+        ),
+
+        'content'       => array
+        (
+            'type'      => 'text-255',
+            'name'      => '描述-手动干扰项,字数请不要超过' . $info['col_content'] . '个汉字,前台展示时会自动过滤',
+            'default'   => '',
+            'desc'      => '请输入描述',
+            'match'     => $content_state ? 'option' : 'option',
+            //'update'    => $content_state ? 'editor' : 'hidden',
+        ),
+        
+        'reorder'       => array
+        (
+            'type'      => 'int-11',
+            'name'      => '排序(数值越大越靠前)',
+            'default'   => '1',
+            'desc'      => '请输入排序',
+            'match'     => 'option',
+            'update'    => 'text',
+            'search'    => 'order',
+            'list_name' => '排序',
+            'list'      => true,
+            'order'     => 'desc',
+            'edit'      => true,
+        ),
+
+        'state'     => array
+        (
+            'type'      => 'tinyint-1',
+            'name'      => '状态',
+            'default'   => '1',
+            'desc'      => '请选择状态',
+            'match'     => 'is_numeric',
+        ),
+        
+        'cdate'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '录入时间',
+            'match'     => array('is_numeric', time()),
+            'desc'      => '',
+            # 只有insert时才生效
+            'insert'    => true,
+            'list'      => 'date("Y-m-d H:i:s", {cdate})',
+        ),
+    ),
+
+    # request 请求接口定义
+    'request' => array
+    (
+        # 获取列表页
+        'getAll' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'info_id' => 'yes',
+                'type_no' => array('yes-type', '!='),
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc', 'id' => 'desc'),
+            'limit' => '0,10',
+            'col' => 'name,pic,olink as link,type,article_id,cdate',
+        ),
+
+        # 获取列表页 带有分页的
+        'getAllPage' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'info_id' => 'yes',
+                'type_no' => array('yes-type', '!='),
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc', 'id' => 'desc'),
+            'page' => array(10, 'list'),
+            'col' => 'name,pic,olink as link,type,article_id,cdate',
+        ),
+    ),
+);

+ 302 - 0
app/push/database/info.php

@@ -0,0 +1,302 @@
+<?php
+
+$type = array
+(
+    1 => '手动输入',
+);
+
+$function = Dever::config('base')->type;
+$function[10] = '链接';
+
+$col = array
+(
+    1 => '标题',
+    //2 => '链接',
+    3 => '图片',
+    //4 => '描述',
+);
+
+return array
+(
+    # 表名
+    'name' => 'info',
+    # 显示给用户看的名称
+    'lang' => '推送位管理',
+    'order' => 10,
+    'check' => 'key',
+    # 数据结构
+    'struct' => array
+    (
+        'id'        => array
+        (
+            'type'      => 'int-11',
+            'name'      => '推送位ID',
+            'default'   => '',
+            'desc'      => '',
+            'match'     => 'is_numeric',
+            //'search'  => 'order',
+            'order'     => 'desc',
+            //'list'        => true,
+        ),
+        
+        'name'      => array
+        (
+            'type'      => 'varchar-60',
+            'name'      => '推送位标题',
+            'default'   => '',
+            'desc'      => '请输入推送位标题',
+            'match'     => 'is_string',
+            'update'    => 'text',
+            'search'    => 'fulltext',
+            'list'      => true,
+            'edit'      => true,
+        ),
+
+        'key'       => array
+        (
+            'type'      => 'varchar-60',
+            'name'      => '推送位标识',
+            'default'   => '',
+            'desc'      => '推送位标识',
+            'match'     => 'is_string',
+            'update'    => Dever::input('where_id') ? 'hidden' : 'text',
+            'search'    => 'fulltext',
+            'list'      => true,
+            //'auth'      => '!{key}'
+        ),
+
+        'num'       => array
+        (
+            'type'      => 'int-11',
+            'name'      => '数据显示条数-为空或小于0则取默认值20,只对前台有效,当有分页时,则为每页显示的条数',
+            'default'   => '20',
+            'desc'      => '数据显示条数',
+            'match'     => 'is_numeric',
+            'update'    => 'text',
+            'list'      => true,
+            'edit'      => true,
+        ),
+
+        'type'      => array
+        (
+            'type'      => 'tinyint-1',
+            'name'      => '推送位类型',
+            'default'   => '1',
+            'desc'      => '请选择推送位类型',
+            'match'     => 'is_numeric',
+            'option'    => $type,
+            'update'    => 'radio',
+            'search'    => 'select',
+            //'list'        => true,
+            'control'       => 'type',
+        ),
+
+        /*
+        'data_type'     => array
+        (
+            'type'      => 'varchar-50',
+            'name'      => '数据类型定义-多个用换行隔开,必须有一个值,主要用于该推送位有多种不同类型的值',
+            'default'   => '默认类型',
+            'desc'      => '请选择推送位类型',
+            'match'     => 'is_string',
+            //'update'  => 'textarea',
+            //'show'        => array('type_1'),
+        ),
+
+        'code'      => array
+        (
+            'type'      => 'varchar-500',
+            'name'      => '自定义内容',
+            'default'   => '',
+            'desc'      => '请输入自定义内容',
+            'match'     => 'is_string',
+            'update'    => 'textarea',
+            'show'      => 'type=4,5,6',
+        ),
+
+        'sql_method'        => array
+        (
+            'type'      => 'tinyint-1',
+            'name'      => '选择sql执行之后的方法',
+            'default'   => '1',
+            'desc'      => '选择sql执行之后的方法',
+            'match'     => 'is_numeric',
+            'update'    => 'radio',
+            'option'    => $sqlMethod,
+            'show'      => 'type=5',
+        ),
+
+        'define'        => array
+        (
+            'type'      => 'varchar-100',
+            'name'      => '选择预定义方法',
+            'default'   => '',
+            'desc'      => '请选择预定义方法',
+            'match'     => 'is_string',
+            'update'    => 'select',
+            'option'    => $define,
+            'show'      => 'type=3'
+        ),
+        */
+
+        'function'       => array
+        (
+            'type'      => 'varchar-30',
+            'name'      => '启用的功能',
+            'default'   => '1,10',
+            'desc'      => '启用的功能',
+            'match'     => 'is_string',
+            'option'    => $function,
+            'update'    => 'checkbox',
+            'show'      => 'type=1',
+        ),
+
+        'col'       => array
+        (
+            'type'      => 'varchar-30',
+            'name'      => '启用的字段',
+            'default'   => '1',
+            'desc'      => '请选择启用的字段',
+            'match'     => 'is_string',
+            'option'    => $col,
+            'update'    => 'checkbox',
+            'show'      => 'type=1',
+            'control'   => 'col',
+        ),
+
+        'col_pic'       => array
+        (
+            'type'      => 'varchar-20',
+            'name'      => '图片尺寸提醒-请直接输入提醒的文字即可,如100X100',
+            'default'   => '100X100',
+            'desc'      => '图片尺寸提醒',
+            'match'     => 'is_string',
+            'update'    => 'text',
+            'show'      => 'col=3',
+        ),
+
+        'col_content'       => array
+        (
+            'type'      => 'int-11',
+            'name'      => '内容长度限制-必须是数字',
+            'default'   => '30',
+            'desc'      => '内容长度限制',
+            'match'     => 'is_numeric',
+            'update'    => 'text',
+            'show'      => 'col=4',
+        ),
+
+        /*
+        'relate_id'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '请输入推送位id',
+            'default'   => '',
+            'desc'      => '请输入推送位id',
+            'match'     => 'is_numeric',
+            'update'    => 'text',
+            'show'      => 'type=2',
+        ),
+
+        'preview'       => array
+        (
+            'type'      => 'varchar-200',
+            'name'      => '推送位预览地址',
+            'default'   => '',
+            'desc'      => '推送位预览地址',
+            'match'     => 'option',
+            'update'    => 'text',
+        ),
+
+        'preview_height'        => array
+        (
+            'type'      => 'int-11',
+            'name'      => '推送位预览的高度',
+            'default'   => '500',
+            'desc'      => '推送位预览的高度',
+            'match'     => 'option',
+            'update'    => 'text',
+        ),
+        */
+        
+        'reorder'       => array
+        (
+            'type'      => 'int-11',
+            'name'      => '排序(数值越大越靠前)',
+            'default'   => '1',
+            'desc'      => '请输入排序',
+            'match'     => 'option',
+            'update'    => 'text',
+            'search'    => 'order',
+            'list_name' => '排序',
+            'list'      => true,
+            'order'     => 'desc',
+            //'edit'        => true,
+        ),
+
+        'state'     => array
+        (
+            'type'      => 'tinyint-1',
+            'name'      => '状态',
+            'default'   => '1',
+            'desc'      => '请选择状态',
+            'match'     => 'is_numeric',
+        ),
+        
+        'cdate'     => array
+        (
+            'type'      => 'int-11',
+            'name'      => '录入时间',
+            'match'     => array('is_numeric', time()),
+            'desc'      => '',
+            # 只有insert时才生效
+            'insert'    => true,
+            'list'      => 'date("Y-m-d H:i:s", {cdate})',
+        ),
+    ),
+
+    # 权限精细控制 加入到该项目的详细权限中,注意与top的不同
+    /*
+    'auth' => array
+    (
+        # 数据来源
+        'data' => 'all',
+        # 所属项目
+        'project' => 'module',
+        # 项目名称
+        'project_name' => '推送位管理',
+    ),
+    */
+
+    'manage' => array
+    (
+        'delete' => false,
+        //'edit' => false,
+        //'insert' => $curPage ? true : false,
+        'list_button' => array
+        (
+            'add' => array('新增数据', '"data&search_option_info_id={id}&oper_parent=info"', '{type} == 1'),
+
+            'list' => array('数据列表', '"data&search_option_info_id={id}&oper_parent=info"'),
+        ),
+    ),
+
+    # request 请求接口定义
+    'request' => array
+    (
+        # 获取列表页
+        'getAll' => array
+        (
+            # 匹配的正则或函数 选填项
+            'option' => array
+            (
+                'type' => 'yes',
+                //'page_id' => 'yes',
+                'state' => 1,
+            ),
+            'type' => 'all',
+            'order' => array('reorder' => 'desc'),
+            'col' => '*',
+        ),
+    ),
+);

+ 8 - 0
app/push/index.php

@@ -0,0 +1,8 @@
+<?php
+
+define('DEVER_APP_NAME', 'push');
+define('DEVER_APP_LANG', '推送管理');
+define('DEVER_APP_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+define('DEVER_MANAGE_ORDER', 199);
+define('DEVER_MANAGE_ICON', 'glyphicon glyphicon-tower layui-icon-template-1');
+include(DEVER_APP_PATH . '../boot.php');

+ 144 - 0
app/push/lib/Data.php

@@ -0,0 +1,144 @@
+<?php
+
+namespace Push\Lib;
+
+use Dever;
+
+class Data
+{
+    public function get($key, $name, $total = 10, $page = false, $limit = false)
+    {
+        $info = $this->getInfo($key, $name, $total);
+
+        $data = array();
+        if ($info) {
+            if (!$info['num']) {
+                $info['num'] = 20;
+            }
+            if ($limit > 0) {
+                $info['num'] = $limit;
+            }
+
+            $where = array();
+            $where['info_id'] = $info['id'];
+
+            if ($page) {
+                $where['page'] = array($info['num'], 'list');
+                $data = Dever::db('push/data')->getAllPage($where);
+            } else {
+                $where['limit'] = '0,' . $info['num'];
+                $data = Dever::db('push/data')->getAll($where);
+            }
+
+            if ($data) {
+                foreach ($data as $k => $v) {
+                    $data[$k] = $this->getData($v);
+                }
+            }
+        }
+
+        return $data;
+    }
+
+    public function getOne($key, $name, $total = 10, $data_name)
+    {
+        $info = $this->getInfo($key, $name, $total);
+        $data = array();
+        if ($info) {
+            $where = array();
+            $where['info_id'] = $info['id'];
+            $where['name'] = $data_name;
+            $data = Dever::db('push/data')->one($where);
+            if ($data) {
+                $data = $this->getData($data);
+            } else {
+                $where['type'] = 10;
+                Dever::db('push/data')->insert($where);
+            }
+        }
+
+        return $data;
+    }
+
+    private function getInfo($key, $name, $total)
+    {
+        $info = Dever::db('push/info')->one(array('key' => $key));
+
+        if (!$info) {
+            $insert['key'] = $key;
+            $insert['name'] = $name;
+            $insert['num'] = $total;
+            $insert['col'] = '1,3';
+            $info['id'] = Dever::db('push/info')->insert($insert);
+            $info['num'] = $insert['num'];
+        }
+
+        return $info;
+    }
+
+    private function getData($info)
+    {
+        $info['id'] = 0;
+        if ($info['type'] < 10 || $info['type'] == 13) {
+            $table = Dever::config('base')->type_table[$info['type']];
+            $method = 'one';
+            if ($info['type'] == 1) {
+                $id = $info['article_id'];
+            }
+
+            unset($info['article_id']);
+            if ($id > 0) {
+                $info['id'] = $id;
+                $data = Dever::db($table)->$method($id);
+                if (isset($data) && $data) {
+                    if (isset($data['name']) && $data['name'] && !$info['name']) {
+                        $info['name'] = $data['name'];
+                    }
+
+                    if (isset($data['pic_cover']) && $data['pic_cover'] && !$info['pic']) {
+                        $info['pic'] = $data['pic_cover'];
+                    }
+
+                    if (isset($data['pdate']) && $data['pdate']) {
+                        $info['cdate'] = $data['pdate'];
+                    }
+
+                    if (isset($data['cate_id']) && $data['cate_id']) {
+                        $cate = Dever::db('content/cate')->one($data['cate_id']);
+                        $info['cate_name'] = $cate['name'];
+                    }
+
+                    if (isset($data['author_id']) && $data['author_id']) {
+                        $author = Dever::db('content/author')->one($data['author_id']);
+                        $info['author_name'] = $author['name'];
+                    }
+
+                    $info['link'] = Dever::load('main/content')->link($data);
+
+                    if (isset($data['template']) && $data['template'] == 2) {
+                        $info['name'] = '<i class="ico-video"></i>' . $info['name'];
+                    }
+                }
+            }
+        } else {
+            unset($info['article_id']);
+            if (isset($info['olink']) && $info['olink']) {
+                $info['link'] = $info['olink'];
+            }
+        }
+
+        if ($info['link']) {
+            if (!strstr($info['link'], 'http')) {
+                $info['link'] = 'http://' . $info['link'];
+            }
+        }
+
+        $info['cdate'] = date('Y-m-d', $info['cdate']);
+
+        if (isset($info['name']) && $info['name']) {
+            $info['name'] = Dever::cut($info['name'], 20, '...');
+        }
+
+        return $info;
+    }
+}

+ 52 - 0
app/push/lib/Manage.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace Push\Lib;
+
+use Dever;
+
+class Manage
+{
+    //{source_id} > 0 ? ("{name}" ? "{name}" : Dever::load("sad/supply-one#name", {source_id})) : "{name}"
+    public function name($id)
+    {
+        $info = Dever::db('push/data')->one($id);
+
+        if ($info['name']) {
+            return $info['name'];
+        }
+
+        if ($info['type'] < 10) {
+            $table = Dever::config('base')->type_table[$info['type']];
+            $audit = array
+            (
+                //'audit' => 2,
+                //'status' => 2,
+                'state' => 1,
+            );
+            if ($info['type'] == 1) {
+                $audit['id'] = $info['article_id'];
+                $data = Dever::db($table)->one($audit);
+            } elseif ($info['type'] == 2) {
+                $audit['id'] = $info['vod_id'];
+                $data = Dever::db($table)->one($audit);
+            } elseif ($info['type'] == 3) {
+                $audit['id'] = $info['live_id'];
+                $data = Dever::db($table)->one($audit);
+            } elseif ($info['type'] == 4) {
+                $audit['id'] = $info['journal_id'];
+                $data = Dever::db($table)->one($audit);
+            } elseif ($info['type'] == 6) {
+                $audit['id'] = $info['feature_id'];
+                $data = Dever::db($table)->one($audit);
+            } elseif ($info['type'] == 7) {
+                $data = Dever::db($table)->one(array('state' => 1, 'id' => $info['applet_id']));
+            }
+
+            if (isset($data) && $data && isset($data['name'])) {
+                return $data['name'];
+            }
+        }
+
+        return $info['name'];
+    }
+}

+ 8 - 0
boot.php

@@ -0,0 +1,8 @@
+<?php 
+define('DEVER_PROJECT', 'sknow');
+define('DEVER_PROJECT_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+if (defined('DEVER_PACKAGE')) {
+	include('dever_package/'.DEVER_PACKAGE.'/index.php');
+} else {
+	include('dever/boot.php');
+}

+ 0 - 0
common.php


+ 75 - 0
config/base.php

@@ -0,0 +1,75 @@
+<?php
+$config['base'] = array
+(
+	'name' => '知识付费平台',
+	'version' => '1.0.0 Beta',
+
+    # 设置分类组件中的栏目下的分类为系统使用的主分类
+    'category' => 1,
+
+    # 设置类型
+    'type' => array
+    (
+        1 => '需求',
+    ),
+
+    # 功能类型
+    'type_table' => array
+    (
+        1 => 'demand/info',
+    ),
+
+    # 审核配置
+    'audit' => array
+    (
+        1 => '未审核',
+        2 => '已审核',
+        3 => '审核未通过',
+    ),
+
+    # 小程序配置
+    'applet' => array
+    (
+        'project' => 'passport/system',
+        'url' => 'https://api.weixin.qq.com/sns/jscode2session',
+    ),
+
+    # 站点使用邮箱还是手机作为主账号
+    'account' => 'mobile',
+);
+
+
+# 前台通用配置
+$config['template'] = array
+(
+    # 静态页面目录
+    'assets' => array('pc', 'mobile'),
+
+    # 模板编译器目录
+    'template' => 'pc',
+
+    # 模板html文件的所在目录,默认为html
+    'path' => '',
+
+    'replace' => array
+    (
+        'css' => 'css/',
+        'js' => 'js/',
+        'images' => 'images/',
+        'script' => 'script/',
+        'static' => './static/',
+    ),
+
+    # 编译器与模板对应关系目录,定义之后,代表可以完全不改动前端的代码,可以为空,为空则一一对应,参考manage
+    'relation' => array
+    (
+        # 首页启动屏幕
+        'home' => 'index',
+        'list_text' => 'list1',
+        'page' => 'intro',
+        'view' => 'article',
+        'magazine' => 'magzine',
+    ),
+    
+);
+return $config;

+ 119 - 0
config/env/localhost/default.php

@@ -0,0 +1,119 @@
+<?php
+
+# 验证dc是否存在,一般在share目录下
+$dc = array();
+$dc_file = '/share/dc/config.php';
+if (is_file($dc_file)) {
+    $dc = include($dc_file);
+}
+
+if (isset($dc['data'])) {
+    $config['base']['data'] = $dc['data'];
+}
+
+$create = -1;
+if (isset($dc['mysql']['create'])) {
+    $create = -1;
+}
+$ip = isset($dc['host']) ? $dc['host'] : '192.168.33.10';
+
+$local = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $ip;
+
+# 数据库配置
+$config['database'] = array
+(
+    'create' => $create,
+	# 默认数据库配置
+	'default' => array
+	(
+		'type' => 'pdo',
+		'host' => array
+		(
+			'read' => isset($dc['mysql']) ? $dc['mysql']['host'] : 'web-mysql:3306',
+			'update' => isset($dc['mysql']) ? $dc['mysql']['host'] : 'web-mysql:3306',
+            'create' => isset($dc['mysql']) ? $dc['mysql']['host_create'] : 'web-mysql:3306',
+		),
+		'database' => 'sknow',
+		'username' => isset($dc['mysql']) ? $dc['mysql']['username'] : 'root',
+		'password' => isset($dc['mysql']) ? $dc['mysql']['password'] : '123456',
+		'charset' => 'utf8mb4',
+	),
+);
+
+# 缓存配置
+$config['cache'] = array
+(
+    # 启用mysql数据库缓存,这个缓存是根据表名自动生成,dever::load形式和service的all、one形式均自动支持,无需手动添加
+    'mysql' => 0,
+    # 启用页面缓存 会根据当前的url来生成缓存,相当于页面静态化。
+    'html' => 0,
+    # 启用数据级别缓存 这个缓存是程序员自定义的:Dever::cache('name', 'value', 3600);
+    'data' => 0,
+    # 启用load加载器缓存,一般不加载
+    'load' => 0,
+    # 启用load加载器的远程加载缓存
+    'curl' => 0,
+    # 启用路由缓存
+    'route' => 0,
+
+    # 缓存精细控制,根据uri来控制,0则无需缓存
+    'routeKey' => array
+    (
+        
+    ),
+
+    # 哪些路由中的参数不参与生成缓存的key
+    'routeNoParam' => array
+    (
+        'uid' => array
+        (
+            
+        ),
+    ),
+    
+    # 缓存清理的参数名,请通过shell=clearcache执行
+    'shell' => 'clearcache',
+
+    # 是否启用key失效时间记录,启用之后,将会记录每个key的失效时间
+    'expire' => true,
+
+    # 缓存类型
+    'type' => 'redis',//memcache、redis
+
+    # 缓存保存方式,支持多个数据源、多台缓存服务器
+    'store' => array
+    (
+        array
+        (
+            'host' => 'server-redis',
+            'port' => '6379',
+            'weight' => 100,
+            'password' => 'dm_redis_123',
+        ),
+    ),
+);
+
+$config['debug'] = array
+(
+	'log' => false
+);
+
+/*
+if (DEVER_APP_NAME == 'source') {
+    $config['debug']['log'] = array('type' => 'file'); 
+}
+*/
+
+
+$host = 'http://'.$local . '/';
+
+$upload = $host . 'sknow/package/';
+$uploadcdn = $host . 'sknow/data/';
+
+$config['host'] = array
+(
+    'upload'=> $upload . 'upload/?save',
+    'uploadRes'     => isset($dc['res']) && $dc['res'] ? $dc['res'] : $uploadcdn . 'upload/',
+);
+
+return $config;

+ 6 - 0
config/route.php

@@ -0,0 +1,6 @@
+<?php
+return array
+(
+	'home' => 'home',
+	'c=v(.*?)_(.*?)' => 'view.get?type=$1&id=$2',
+);

+ 323 - 0
data/compile/sknow/manage/layadmin/console.cmp.php

@@ -0,0 +1,323 @@
+<?php $data['manage/auth.notice']=Dever::load('manage/auth.notice') ?>
+<!DOCTYPE html>
+<!--power by dever--><html>
+<head>
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/head.cmp.php' ?>
+</head>
+<body>
+  
+  <div class="layui-fluid">
+    <div class="layui-row layui-col-space15">
+    <blockquote class="layui-elem-quote layui-quote-nm" id="content">欢迎光临本系统,控制台功能迭代优化中</blockquote>
+    </div>
+    <div class="layui-row layui-col-space15" style="display:none;">
+      <div class="layui-col-md8">
+        <div class="layui-row layui-col-space15">
+          <div class="layui-col-md6">
+            <div class="layui-card">
+              <div class="layui-card-header">快捷方式</div>
+              <div class="layui-card-body">
+                
+                <div class="layui-carousel layadmin-carousel layadmin-shortcut">
+                  <div carousel-item>
+                    <ul class="layui-row layui-col-space10">
+                      <li class="layui-col-xs3">
+                        <a lay-href="home/homepage1.html">
+                          <i class="layui-icon layui-icon-console"></i>
+                          <cite>主页一</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="home/homepage2.html">
+                          <i class="layui-icon layui-icon-chart"></i>
+                          <cite>主页二</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="component/layer/list.html">
+                          <i class="layui-icon layui-icon-template-1"></i>
+                          <cite>弹层</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a layadmin-event="im">
+                          <i class="layui-icon layui-icon-chat"></i>
+                          <cite>聊天</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="component/progress/index.html">
+                          <i class="layui-icon layui-icon-find-fill"></i>
+                          <cite>进度条</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="app/workorder/list.html">
+                          <i class="layui-icon layui-icon-survey"></i>
+                          <cite>工单</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="user/user/list.html">
+                          <i class="layui-icon layui-icon-user"></i>
+                          <cite>用户</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="set/system/website.html">
+                          <i class="layui-icon layui-icon-set"></i>
+                          <cite>设置</cite>
+                        </a>
+                      </li>
+                    </ul>
+                    <ul class="layui-row layui-col-space10">
+                      <li class="layui-col-xs3">
+                        <a lay-href="set/user/info.html">
+                          <i class="layui-icon layui-icon-set"></i>
+                          <cite>我的资料</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="set/user/info.html">
+                          <i class="layui-icon layui-icon-set"></i>
+                          <cite>我的资料</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="set/user/info.html">
+                          <i class="layui-icon layui-icon-set"></i>
+                          <cite>我的资料</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="set/user/info.html">
+                          <i class="layui-icon layui-icon-set"></i>
+                          <cite>我的资料</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="set/user/info.html">
+                          <i class="layui-icon layui-icon-set"></i>
+                          <cite>我的资料</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="set/user/info.html">
+                          <i class="layui-icon layui-icon-set"></i>
+                          <cite>我的资料</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="set/user/info.html">
+                          <i class="layui-icon layui-icon-set"></i>
+                          <cite>我的资料</cite>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs3">
+                        <a lay-href="set/user/info.html">
+                          <i class="layui-icon layui-icon-set"></i>
+                          <cite>我的资料</cite>
+                        </a>
+                      </li>
+                    </ul>
+                    
+                  </div>
+                </div>
+                
+              </div>
+            </div>
+          </div>
+          <div class="layui-col-md6">
+            <div class="layui-card">
+              <div class="layui-card-header">待办事项</div>
+              <div class="layui-card-body">
+
+                <div class="layui-carousel layadmin-carousel layadmin-backlog">
+                  <div carousel-item>
+                    <ul class="layui-row layui-col-space10">
+                      <li class="layui-col-xs6">
+                        <a lay-href="app/content/comment.html" class="layadmin-backlog-body">
+                          <h3>待审评论</h3>
+                          <p><cite>66</cite></p>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs6">
+                        <a lay-href="app/forum/list.html" class="layadmin-backlog-body">
+                          <h3>待审帖子</h3>
+                          <p><cite>12</cite></p>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs6">
+                        <a lay-href="template/goodslist.html" class="layadmin-backlog-body">
+                          <h3>待审商品</h3>
+                          <p><cite>99</cite></p>
+                        </a>
+                      </li>
+                      <li class="layui-col-xs6">
+                        <a href="javascript:;" onclick="layer.tips('不跳转', this, {tips: 3});" class="layadmin-backlog-body">
+                          <h3>待发货</h3>
+                          <p><cite>20</cite></p>
+                        </a>
+                      </li>
+                    </ul>
+                    <ul class="layui-row layui-col-space10">
+                      <li class="layui-col-xs6">
+                        <a href="javascript:;" class="layadmin-backlog-body">
+                          <h3>待审友情链接</h3>
+                          <p><cite style="color: #FF5722;">5</cite></p>
+                        </a>
+                      </li>
+                    </ul>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="layui-col-md12">
+            <div class="layui-card">
+              <div class="layui-card-header">数据概览</div>
+              <div class="layui-card-body">
+                
+                <div class="layui-carousel layadmin-carousel layadmin-dataview" data-anim="fade" lay-filter="LAY-index-dataview">
+                  <div carousel-item id="LAY-index-dataview">
+                    <div><i class="layui-icon layui-icon-loading1 layadmin-loading"></i></div>
+                    <div></div>
+                    <div></div>
+                  </div>
+                </div>
+                
+              </div>
+            </div>
+            <div class="layui-card">
+              <div class="layui-tab layui-tab-brief layadmin-latestData">
+                <ul class="layui-tab-title">
+                  <li class="layui-this">今日热搜</li>
+                  <li>今日热帖</li>
+                </ul>
+                <div class="layui-tab-content">
+                  <div class="layui-tab-item layui-show">
+                    <table id="LAY-index-topSearch"></table>
+                  </div>
+                  <div class="layui-tab-item">
+                    <table id="LAY-index-topCard"></table>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      
+      <div class="layui-col-md4">
+
+        <div class="layui-card dever-notice" style="<?php if(!(Dever::load('manage/auth.notice'))): ?>display:none;<?php endif; ?>">
+          <div class="layui-card-header">系统公告</div>
+          <div class="layui-card-body">
+            <div class="layui-carousel layadmin-carousel layadmin-news" data-autoplay="true" data-anim="fade" lay-filter="news">
+              <div carousel-item id="dever-notice">
+                <?php if(isset($data['manage/auth.notice']) && is_array($data['manage/auth.notice'])): ?><?php $t=count($data['manage/auth.notice'])-1 ?><?php $i=0 ?><?php foreach($data['manage/auth.notice'] as $k => $v): ?><div><a href="<?php  echo Dever::url("notice?where_id=".$v['id']."&where_config=".$v['config']) ?>" target="_blank" class="layui-bg-red" title="<?php echo isset($v['name']) ? $v['name'] : "" ?>" style="background-color: #FF5722!important;"><?php echo isset($v['name']) ? $v['name'] : "" ?></a></div><?php $i=$i+1 ?><?php endforeach; ?><?php else: ?><?php echo $data['manage/auth.notice'] ?><?php endif; ?>
+                 
+                
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <div class="layui-card">
+          <div class="layui-card-header">版本信息</div>
+          <div class="layui-card-body layui-text">
+            <table class="layui-table">
+              <colgroup>
+                <col width="100">
+                <col>
+              </colgroup>
+              <tbody>
+                <tr>
+                  <td>当前版本</td>
+                  <td>
+                    <script type="text/html" template>
+                      v{{ layui.admin.v }}
+                    </script>
+                  </td>
+                </tr>
+                <tr>
+                  <td>基于框架</td>
+                  <td>
+                    <script type="text/html" template>
+                      layui-v{{ layui.v }}
+                    </script>
+                 </td>
+                </tr>
+                <tr>
+                  <td>主要特色</td>
+                  <td>零门槛 / 响应式 / 清爽 / 极简</td>
+                </tr>
+                <tr>
+                  <td>获取渠道</td>
+                  <td style="padding-bottom: 0;">
+                    <div class="layui-btn-container">
+                      <a href="http://www.layui.com/admin/" target="_blank" class="layui-btn layui-btn-danger">获取授权</a>
+                      <a href="http://fly.layui.com/download/layuiAdmin/" target="_blank" class="layui-btn">立即下载</a>
+                    </div>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
+        </div>
+        
+        <div class="layui-card">
+          <div class="layui-card-header">效果报告</div>
+          <div class="layui-card-body layadmin-takerates">
+            <div class="layui-progress" lay-showpercent="yes">
+              <h3>转化率(日同比 28% <span class="layui-edge layui-edge-top" lay-tips="增长" lay-offset="-15"></span>)</h3>
+              <div class="layui-progress-bar" lay-percent="65%"></div>
+            </div>
+            <div class="layui-progress" lay-showpercent="yes">
+              <h3>签到率(日同比 11% <span class="layui-edge layui-edge-bottom" lay-tips="下降" lay-offset="-15"></span>)</h3>
+              <div class="layui-progress-bar" lay-percent="32%"></div>
+            </div>
+          </div>
+        </div>
+        
+        <div class="layui-card">
+          <div class="layui-card-header">实时监控</div>
+          <div class="layui-card-body layadmin-takerates">
+            <div class="layui-progress" lay-showpercent="yes">
+              <h3>CPU使用率</h3>
+              <div class="layui-progress-bar" lay-percent="58%"></div>
+            </div>
+            <div class="layui-progress" lay-showpercent="yes">
+              <h3>内存占用率</h3>
+              <div class="layui-progress-bar layui-bg-red" lay-percent="90%"></div>
+            </div>
+          </div>
+        </div>
+
+        <div class="layui-card">
+          <div class="layui-card-header">
+            作者心语
+            <i class="layui-icon layui-icon-tips" lay-tips="要支持的噢" lay-offset="5"></i>
+          </div>
+          <div class="layui-card-body layui-text layadmin-text">
+            <p>一直以来,layui 秉承无偿开源的初心,虔诚致力于服务各层次前后端 Web 开发者,在商业横飞的当今时代,这一信念从未动摇。即便身单力薄,仍然重拾决心,埋头造轮,以尽可能地填补产品本身的缺口。</p>
+            <p>在过去的一段的时间,我一直在寻求持久之道,已维持你眼前所见的一切。而 layuiAdmin 是我们尝试解决的手段之一。我相信真正有爱于 layui 生态的你,定然不会错过这一拥抱吧。</p>
+            <p>子曰:君子不用防,小人防不住。请务必通过官网正规渠道,获得 <a href="http://www.layui.com/admin/" target="_blank">layuiAdmin</a>!</p>
+            <p>—— 贤心(<a href="http://www.layui.com/" target="_blank">layui.com</a>)</p>
+          </div>
+        </div>
+      </div>
+      
+    </div>
+  </div>
+
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/script.cmp.php' ?>
+  <script>
+    layui.config({
+        base: '<?php echo Dever::config("host")->script ?>lib/layui/admin/' //静态资源所在路径
+    }).extend({
+        index: 'lib/index' //主入口模块
+    }).use(['index', 'console']);
+</script>
+</body>
+</html>

+ 62 - 0
data/compile/sknow/manage/layadmin/home.cmp.php

@@ -0,0 +1,62 @@
+<?php $data['manage/database.cookie']=Dever::load('manage/database.cookie') ?>
+<?php $data['manage/menu.link']=Dever::load('manage/menu.link') ?>
+<!DOCTYPE html>
+<!--power by dever--><html>
+<head>
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/head.cmp.php' ?>
+</head>
+<body class="theme-<?php  echo Dever::load("manage/auth.config#template") ?>" test="公告">
+
+  <div id="LAY_app" class="<?php echo $data['manage/database.cookie']['wrapper'] ?>">
+    <div class="layui-layout layui-layout-admin">
+
+      <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/nav.cmp.php' ?>
+
+      <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/menu.cmp.php' ?>
+
+      
+      <div class="layadmin-pagetabs" id="LAY_app_tabs">
+        <div class="layui-icon layadmin-tabs-control layui-icon-prev" layadmin-event="leftPage"></div>
+        <div class="layui-icon layadmin-tabs-control layui-icon-next" layadmin-event="rightPage"></div>
+        <div class="layui-icon layadmin-tabs-control layui-icon-down">
+          <ul class="layui-nav layadmin-tabs-select" lay-filter="layadmin-pagetabs-nav">
+            <li class="layui-nav-item" lay-unselect>
+              <a href="javascript:;"></a>
+              <dl class="layui-nav-child layui-anim-fadein">
+                <dd layadmin-event="closeThisTabs"><a href="javascript:;">关闭当前标签页</a></dd>
+                <dd layadmin-event="closeOtherTabs"><a href="javascript:;">关闭其它标签页</a></dd>
+                <dd layadmin-event="closeAllTabs"><a href="javascript:;">关闭全部标签页</a></dd>
+              </dl>
+            </li>
+          </ul>
+        </div>
+        <div class="layui-tab" lay-unauto lay-allowclose="true" lay-filter="layadmin-layout-tabs">
+          <ul class="layui-tab-title" id="LAY_app_tabsheader">
+            <li lay-id="<?php echo $data['manage/menu.link']['console'] ?>" lay-attr="<?php echo $data['manage/menu.link']['console'] ?>" class="layui-this"><i class="layui-icon layui-icon-home"></i></li>
+          </ul>
+        </div>
+      </div>
+      
+      
+      
+      <div class="layui-body" id="LAY_app_body">
+        <div class="layadmin-tabsbody-item layui-show">
+          <iframe src="<?php echo $data['manage/menu.link']['console'] ?>" frameborder="0" class="layadmin-iframe"></iframe>
+        </div>
+      </div>
+      
+      
+      <div class="layadmin-body-shade" layadmin-event="shade"></div>
+    </div>
+  </div>
+
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/script.cmp.php' ?>
+  <script>
+    layui.config({
+        base: '<?php echo Dever::config("host")->script ?>lib/layui/admin/' //静态资源所在路径
+    }).extend({
+        index: 'lib/index' //主入口模块
+    }).use('index');
+</script>
+</body>
+</html>

+ 27 - 0
data/compile/sknow/manage/layadmin/inc/head.cmp.php

@@ -0,0 +1,27 @@
+<?php $data['manage/auth.config']=Dever::load('manage/auth.config') ?>
+<meta charset="utf-8">
+<title><?php echo $data['manage/auth.config']['title'] ?></title>
+<meta name="keywords" content="<?php echo $data['manage/auth.config']['title'] ?>">
+<meta name="description" content="<?php echo $data['manage/auth.config']['title'] ?>">
+<meta name="apple-mobile-web-app-title" content="<?php echo $data['manage/auth.config']['title'] ?>" />
+<meta name="author" content="rabin">
+<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<link rel="stylesheet" type="text/css" href="<?php echo Dever::config("host")->script ?>lib/layui/css/layui.css" />
+<link rel="stylesheet" href="<?php echo Dever::config("host")->script ?>lib/layui/admin/style/admin.css?v3" media="all">
+
+
+<link rel="stylesheet" type="text/css" href="<?php echo Dever::config("host")->script ?>lib/color/colpick.css">
+<link rel="stylesheet" type="text/css" href="<?php echo Dever::config("host")->script ?>lib/kindeditor/themes/default/default.css?v1" />
+<link rel="stylesheet" type="text/css" href="<?php echo Dever::config("host")->script ?>lib/valid/validationEngine.jquery.css">
+
+<link rel="stylesheet" type="text/css" href="<?php echo Dever::config("host")->script ?>lib/fancybox/jquery.fancybox.css">
+<link rel="stylesheet" type="text/css" href="<?php echo Dever::config("host")->script ?>lib/highlight/highlight.min.css">
+<link rel="stylesheet" type="text/css" href="<?php echo Dever::config("host")->script ?>lib/datetime/jquery.datetimepicker.css">
+
+<link rel="stylesheet" type="text/css" href="<?php echo Dever::config("host")->script ?>lib/ui/ui.min.css">
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/jquery/jquery.min.js"></script>
+<script id="script"><?php  echo Dever::script() ?>config.template="<?php  echo $data["manage/auth.config"]["template"] ?>";config.lib="<?php  echo Dever::config("host")->public ?>"</script>
+<style type="text/css" id="style"><?php  echo Dever::load("manage/auth.loading") ? ".content,.content-page{margin-left: 0px;min-height:auto}" : "" ?></style>

+ 13 - 0
data/compile/sknow/manage/layadmin/inc/menu.cmp.php

@@ -0,0 +1,13 @@
+<?php $data['manage/auth.config']=Dever::load('manage/auth.config') ?>
+<?php $data['manage/menu.link']=Dever::load('manage/menu.link') ?>
+<?php $data['manage/menu.getHtml']=Dever::load('manage/menu.getHtml') ?>
+
+      <div class="layui-side layui-side-menu">
+        <div class="layui-side-scroll">
+          <div class="layui-logo" id="console-url" lay-href="<?php echo $data['manage/menu.link']['console'] ?>">
+            <span id="dever-name"><?php echo $data['manage/auth.config']['title'] ?></span>
+          </div>
+          
+          <ul class="layui-nav layui-nav-tree" lay-shrink="all" id="LAY-system-side-menu" lay-filter="layadmin-system-side-menu"><?php echo $data['manage/menu.getHtml'] ?></ul>
+        </div>
+      </div>

+ 64 - 0
data/compile/sknow/manage/layadmin/inc/nav.cmp.php

@@ -0,0 +1,64 @@
+<?php $data['manage/menu.getTop']=Dever::load('manage/menu.getTop') ?>
+<?php $data['manage/database.res']=Dever::load('manage/database.res') ?>
+<?php $data['manage/auth.config']=Dever::load('manage/auth.config') ?>
+<?php $data['manage/auth.info']=Dever::load('manage/auth.info') ?>
+<?php $data['manage/menu.link']=Dever::load('manage/menu.link') ?>
+<div id="load_style" style="display:none;"><?php echo $data['manage/database.res']['css'] ?></div>
+<div id="dever-name" style="display:none;"><?php echo $data['manage/auth.config']['title'] ?></div>
+<div class="layui-header" id="nav" style="<?php  echo Dever::load("manage/auth.loading") ? "display:none;" : "" ?>">
+
+<ul class="layui-nav layui-layout-left" id="top"><?php echo $data['manage/menu.getTop'] ?></ul>
+
+<ul class="layui-nav layui-layout-right" lay-filter="layadmin-layout-right">
+
+  <li class="layui-nav-item auth-top" lay-unselect style="display:none;">
+    <a href="javascript:;">
+      <cite><span></span></cite>
+    </a>
+    <ul class="layui-nav-child">
+      <li><a lay-href="set/user/info.html">基本资料</a></li>
+    </ul>
+  </li>
+
+  <li class="layui-nav-item" lay-unselect style="display:none;">
+    <a lay-href="app/message/index.html" layadmin-event="message" lay-text="消息中心">
+      <i class="layui-icon layui-icon-notice"></i>  
+      
+      
+      <span class="layui-badge-dot"></span>
+    </a>
+  </li>
+  <li class="layui-nav-item layui-hide-xs" lay-unselect>
+    <a href="javascript:;" layadmin-event="theme">
+      <i class="layui-icon layui-icon-theme"></i>
+    </a>
+  </li>
+  <li class="layui-nav-item layui-hide-xs" lay-unselect style="display:none;">
+    <a href="javascript:;" layadmin-event="note">
+      <i class="layui-icon layui-icon-note"></i>
+    </a>
+  </li>
+  <li class="layui-nav-item layui-hide-xs" lay-unselect style="display:none;">
+    <a href="javascript:;" layadmin-event="fullscreen">
+      <i class="layui-icon layui-icon-screen-full"></i>
+    </a>
+  </li>
+  <li class="layui-nav-item" lay-unselect>
+    <a href="javascript:;">
+      <cite id="manage-name"><?php echo $data['manage/auth.info']['username'] ?></cite>
+    </a>
+    <dl class="layui-nav-child">
+      <dd><a id="edit_password" onclick="pass($(this));" style="cursor: pointer;">修改密码</a></dd>
+      <hr>
+      <dd style="text-align: center;"><a id="logout-url" href="<?php echo $data['manage/menu.link']['logout'] ?>">退出</a></dd>
+    </dl>
+  </li>
+  
+  <li class="layui-nav-item layui-hide-xs" lay-unselect style="display:none;">
+    <a href="javascript:;" layadmin-event="about"><i class="layui-icon layui-icon-more-vertical"></i></a>
+  </li>
+  <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-unselect>
+    <a href="javascript:;" layadmin-event="more"><i class="layui-icon layui-icon-more-vertical"></i></a>
+  </li>
+</ul>
+</div>

+ 49 - 0
data/compile/sknow/manage/layadmin/inc/script.cmp.php

@@ -0,0 +1,49 @@
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/pic/webp.js"></script>
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/jquery/store.js"></script>
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/bootstrap/js/bootstrap.min.js"></script>
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/pjax/pjax.js"></script>
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/pjax/nprogress.js"></script>
+
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/color/colpick.js"></script>
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/datetime/jquery.datetimepicker.min.js"></script>
+
+
+
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/fancybox/jquery.fancybox.js"></script>
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/echarts/echarts.common.min.js?v1"></script>
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/highlight/highlight.min.js"></script>
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/valid/jquery.validationEngine.min.js?v3"></script>
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/kindeditor/kindeditor-all-min.js?v9"></script>
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/kindeditor/lang/zh-CN.js?v7"></script>
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/ui/ui.min.js"></script>
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/qiniu/upload/plupload.full.min.js"></script>
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/qiniu/qiniu.upload.js"></script>
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/tool/md5.js"></script>
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/layui/upload.js?v6"></script>
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/layui/layui.js"></script>
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/clipboard/clipboard.js"></script>
+
+
+<script type="text/javascript" src="<?php echo Dever::config("host")->script ?>lib/manage/main.js?v31"></script>

+ 79 - 0
data/compile/sknow/manage/layadmin/login.cmp.php

@@ -0,0 +1,79 @@
+<?php $data['manage/auth.set']=Dever::load('manage/auth.set') ?>
+<!DOCTYPE html>
+<!--power by dever--><html>
+<head>
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/head.cmp.php' ?>
+  <link rel="stylesheet" href="<?php echo Dever::config("host")->script ?>lib/layui/admin/style/login.css" media="all">
+</head>
+<body>
+
+  <div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login">
+    <form action="<?php  echo Dever::url("auth.login") ?>" method="post" target="f1" class="form-horizontal m-t-20" id="login">
+    <input type="hidden" name="function" id="function" value="msg">
+    <input type="hidden" name="refer" id="refer" value="<?php echo $data['manage/auth.set']['refer'] ?>">
+    <iframe id="f1" name="f1" style="display:none;"></iframe>
+    <div class="layadmin-user-login-main">
+      <div class="layadmin-user-login-box layadmin-user-login-header">
+        <h2 id="name"><?php  echo Dever::load("manage/auth.config#title") ?></h2>
+      </div>
+      <div class="layadmin-user-login-box layadmin-user-login-body layui-form">
+        <div class="layui-form-item">
+          <label class="layadmin-user-login-icon layui-icon layui-icon-username" for="LAY-user-login-username"></label>
+          <input type="text" name="username" id="username" lay-verify="required" placeholder="账号" class="layui-input">
+        </div>
+        <div class="layui-form-item">
+          <label class="layadmin-user-login-icon layui-icon layui-icon-password" for="LAY-user-login-password"></label>
+          <input name="password" id="password" type="password" lay-verify="required" placeholder="密码" class="layui-input">
+        </div>
+        <div class="layui-form-item">
+          <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="LAY-user-login-submit">登 入</button>
+        </div>
+      </div>
+    </div>
+    
+    <div class="layui-trans layadmin-user-login-footer">
+      <p id="footer" style="<?php if(!(Dever::config("base")->copyright)): ?>display:none;<?php endif; ?>"><?php  echo Dever::config("base")->copyright ?></p>
+    </div>
+    
+    <div class="ladmin-user-login-theme" style="display:none;">
+      <script type="text/html" template>
+        <ul>
+          <li data-theme=""><img src="{{ layui.setter.base }}style/res/bg-none.jpg"></li>
+          <li data-theme="#03152A" style="background-color: #03152A;"></li>
+          <li data-theme="#2E241B" style="background-color: #2E241B;"></li>
+          <li data-theme="#50314F" style="background-color: #50314F;"></li>
+          <li data-theme="#344058" style="background-color: #344058;"></li>
+          <li data-theme="#20222A" style="background-color: #20222A;"></li>
+        </ul>
+      </script>
+    </div>
+    </form> 
+  </div>
+
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/script.cmp.php' ?>
+  <script>
+  $(function()
+  {
+    $("#login").bind("keydown",function(e){
+      var theEvent = e || window.event;    
+      var code = theEvent.keyCode || theEvent.which || theEvent.charCode;    
+      if (code == 13) {    
+              $("#login").submit();
+          }
+     });
+  });
+
+  </script>
+  <script>
+  layui.config({
+    base: '<?php echo Dever::config("host")->script ?>lib/layui/admin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index' //主入口模块
+  }).use(['index', 'user'], function(){
+    var $ = layui.$
+    ,setter = layui.setter
+    ,admin = layui.admin
+  });
+  </script>
+</body>
+</html>

+ 155 - 0
data/compile/sknow/manage/layadmin/project/database/list.cmp.php

@@ -0,0 +1,155 @@
+<?php $data['manage/database.page_list']=Dever::load('manage/database.page_list') ?>
+<?php $data['manage/database.info']=Dever::load('manage/database.info') ?>
+<?php $data['manage/database.res']=Dever::load('manage/database.res') ?>
+<?php $data['manage/database.listStyle']=Dever::load('manage/database.listStyle') ?>
+<?php $data['manage/database.page_list_table']=Dever::load('manage/database.page_list_table') ?>
+<?php $data['manage/database.list_search']=Dever::load('manage/database.list_search') ?>
+<?php $data['manage/database.list_thead']=Dever::load('manage/database.list_thead') ?>
+<?php $data['manage/database.list_tbody']=Dever::load('manage/database.list_tbody') ?>
+<?php $data['manage/database.list_button']=Dever::load('manage/database.list_button') ?>
+<?php $data['manage/database.list_mul']=Dever::load('manage/database.list_mul') ?>
+<?php $data['manage/auth.config']=Dever::load('manage/auth.config') ?>
+<?php $data['manage/top.get']=Dever::load('manage/top.get') ?>
+<!DOCTYPE html>
+<!--power by dever--><html>
+<head>
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/head.cmp.php' ?>
+  <link rel="stylesheet" href="<?php echo Dever::config("host")->script ?>lib/layui/admin/modules/plugin/formselects/formselects.css" media="all" />
+</head>
+<body class="theme-<?php  echo Dever::load("/auth.config#template") ?>">
+<style id="addstyle"><?php echo $data['manage/database.listStyle'] ?></style>
+<style>
+.layui-table-cell .layui-select,.layui-table-cell .layui-input
+{
+    height: 25px;
+}
+.layui-table-cell {
+    height: auto;
+}
+
+.table th,.table td {
+  min-width: 70px;
+}
+#table_2,#table_1 {
+  overflow: auto;
+}
+.layui-btn-xs
+{
+  margin-top:1px;
+}
+.dever-emoji img {
+  width:16px;
+}
+.layui-tab-title {
+  height: 100%;
+  white-space: inherit;
+}
+</style>
+<div id="load_style" style="display:none;"><?php echo $data['manage/database.res']['css'] ?></div>
+<span id="dever-name" style="display:none;"><?php echo $data['manage/auth.config']['title'] ?></span>
+<div class="topbar">
+    <div class="banner dever-layout" style="display:none;">
+        <a target="_blank"><img src="#"></a>
+        <span>项目名称</span>
+    </div>
+</div>
+
+<div id="content_1" style="<?php echo $data['manage/database.page_list']['s1'] ?>"><?php echo $data['manage/database.page_list']['content'] ?></div>
+<div id="content_2" style="<?php echo $data['manage/database.page_list']['s2'] ?>">
+  <div class="layui-fluid">
+    <div class="layui-card">
+      <input type="hidden" name="url1" id="url" value="<?php echo $data['manage/database.info']['mul'] ?>"/>
+
+      <form id="form1" name="form1" method="get" target="f1" action="<?php echo $data['manage/database.info']['list'] ?>">
+      <input type="hidden" name="l" id="l" value="<?php echo $data['manage/database.info']['l'] ?>"/>
+      <input type="hidden" name="project" id="project" value="<?php echo $data['manage/database.info']['project'] ?>"/>
+      <input type="hidden" name="table" id="tables" value="<?php echo $data['manage/database.info']['table'] ?>"/>
+      <input type="hidden" name="menu" id="menu" value="<?php echo $data['manage/database.info']['menu'] ?>"/>
+      <?php if(isset($data['manage/top.get']) && is_array($data['manage/top.get'])): ?><?php $t=count($data['manage/top.get'])-1 ?><?php $i=0 ?><?php foreach($data['manage/top.get'] as $k => $v): ?><input type="hidden" name="menu_id" id="menu_id" value="<?php echo $data['manage/database.info']['menu_id'] ?>" style="display:none"/><?php $i=$i+1 ?><?php endforeach; ?><?php else: ?><?php echo $data['manage/top.get'] ?><?php endif; ?>
+      <input type="hidden" name="search_option_state" id="search_option_state" value="<?php echo $data['manage/database.info']['state'] ?>"/>
+
+      <input type="hidden" name="function" id="function" value="msg"/>
+      <input type="hidden" name="method" id="method" value="search"/>
+      <div id="search_param"><?php echo $data['manage/database.info']['search_param'] ?></div> 
+      <iframe id="f1" name="f1" style="display:none;"></iframe>
+      <div class="layui-card-header" style="display:none;"><span id="list-name"><?php echo isset($v['name']) ? $v['name'] : "" ?></span> > <span id="list-project"><?php echo $data['manage/database.info']['project_name'] ?></span></div>
+        <div class="layui-card-body" id="search_content" style="<?php if(!(Dever::load('manage/database.list_search'))): ?>display:none;<?php endif; ?>">
+
+          <div class="layui-form layui-card-header layuiadmin-card-header-auto">
+            <div class="layui-form-item">
+              <div id="search"><?php echo $data['manage/database.list_search'] ?></div>
+            </div>
+          </div>
+        </div>
+      <div class="layui-card-body">
+        <div style="padding-bottom: 10px;">
+          <a class="layui-btn layuiadmin-btn-list" data-type="add" id="list-parent" style="<?php echo $data['manage/database.info']['parent_state'] ?>" href="<?php echo $data['manage/database.info']['parent'] ?>">返回上一页</a>
+
+          <a class="layui-btn layuiadmin-btn-list" data-type="add" id="list-add" href="<?php echo $data['manage/database.info']['add'] ?>" style="<?php echo $data['manage/database.info']['add_state'] ?>">新增</a>
+
+          <span id="list-button"><?php echo $data['manage/database.list_button'] ?></span>
+        </div>
+        <div id="table_1" style="<?php echo $data['manage/database.page_list_table']['s1'] ?>"><?php echo $data['manage/database.page_list_table']['content'] ?></div>
+        <div id="table_2" style="<?php echo $data['manage/database.page_list_table']['s2'] ?>"> 
+          <table class="table layui-table layui-table-body" id="table">
+          <thead id="list-thead">
+              <tr><?php if(isset($data['manage/database.list_thead']) && is_array($data['manage/database.list_thead'])): ?><?php $t=count($data['manage/database.list_thead'])-1 ?><?php $i=0 ?><?php foreach($data['manage/database.list_thead'] as $k => $v): ?><?php echo $v ?><?php $i=$i+1 ?><?php endforeach; ?><?php else: ?><?php echo $data['manage/database.list_thead'] ?><?php endif; ?></tr>
+          </thead>
+          <tbody id="list-tbody"><?php if(isset($data['manage/database.list_tbody']) && is_array($data['manage/database.list_tbody'])): ?><?php $t=count($data['manage/database.list_tbody'])-1 ?><?php $i=0 ?><?php foreach($data['manage/database.list_tbody'] as $k => $v): ?><?php echo $v ?><?php $i=$i+1 ?><?php endforeach; ?><?php else: ?><?php echo $data['manage/database.list_tbody'] ?><?php endif; ?></tbody>
+      </table>
+
+      <div id="mul"><?php echo $data['manage/database.list_mul'] ?></div>
+      <div id="page"><?php  echo Dever::page("current") ?></div>
+      <div class="dever_desc" id="desc" style="<?php if(!(Dever::load('manage/database.info#listDesc'))): ?>display:none;<?php endif; ?>"><?php echo $data['manage/database.info']['listDesc'] ?></div>
+        </div>
+      </div>
+       </div>
+        </div>
+      </form>
+      <form id="form2" name="form2" method="get" style="display: none;"></form>
+      <div id="struct" style="display:none;"><?php echo $data['manage/database.info']['struct'] ?></div>
+    </div>
+  </div>
+</div>
+
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/script.cmp.php' ?>
+  <script id="list-thead-data">
+    config.table = {};
+    config.table.cols = [];
+  </script>
+  <script id="list-tbody-data">
+    config.table.data = [];
+  </script>
+  <script>
+  layui.config({
+    base: '<?php echo Dever::config("host")->script ?>lib/layui/admin/' //静态资源所在路径
+  }).extend({
+    formSelects: 'plugin/formselects/formselects',
+    index: 'lib/index' //主入口模块
+  }).use(['index', 'contlist', 'table', 'form', 'formSelects'], function(){
+    var table = layui.table;
+    var form = layui.form; 
+    var formSelects = layui.formSelects;
+
+    /*
+    table.render({
+      elem: '#table'
+      ,page: false
+      ,limit:20
+      ,cols: config.table.cols
+      ,data: config.table.data
+    });
+    */
+
+    init();
+
+    if ($('.dever-manage').length) {
+      $('.dever-manage').click(function()
+      {
+        showMsg('数据结构', $(this), '#struct');
+      })
+    }
+  });
+  </script>
+</body>
+</html>

+ 112 - 0
data/compile/sknow/manage/layadmin/project/database/update.cmp.php

@@ -0,0 +1,112 @@
+<?php $data['manage/database.page_update']=Dever::load('manage/database.page_update') ?>
+<?php $data['manage/database.info']=Dever::load('manage/database.info') ?>
+<?php $data['manage/database.res']=Dever::load('manage/database.res') ?>
+<?php $data['manage/database.update']=Dever::load('manage/database.update') ?>
+<?php $data['/database.info']=Dever::load('/database.info') ?>
+<?php $data['manage/database.valid']=Dever::load('manage/database.valid') ?>
+<?php $data['manage/database.save']=Dever::load('manage/database.save') ?>
+<?php $data['manage/database.update_button']=Dever::load('manage/database.update_button') ?>
+<?php $data['/database.layui_card']=Dever::load('/database.layui_card') ?>
+<?php $data['/database.card']=Dever::load('/database.card') ?>
+<!DOCTYPE html>
+<!--power by dever--><html>
+<head>
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/head.cmp.php' ?>
+<link rel="stylesheet" href="<?php echo Dever::config("host")->script ?>lib/layui/admin/modules/plugin/formselects/formselects.css" media="all" />
+  <style>
+    .layui-input,.xm-select-parent
+    {
+      width: 50%;
+    }
+
+    textarea{
+      padding-top: 5px;
+    }
+
+    .dever-color {
+      width: 100%;
+    }
+
+    .dever_form_add_child {
+      padding:15px;
+    }
+    .dever_form_delete {
+      float: right;
+      margin-right: 10px;
+      color: red;
+    }
+    .dever_score_child {
+      margin: 15px;
+    }
+    .layui-tab-title {
+      height: 100%;
+      white-space: inherit;
+    }
+    </style>
+</head>
+<body class="theme-<?php  echo Dever::load("/auth.config#template") ?>">
+  <div id="load_style" style="display:none;"><?php echo $data['manage/database.res']['css'] ?></div>
+<div class="topbar">
+    <div class="banner dever-layout" style="display:none;">
+        <a target="_blank"><img src="#"></a>
+        <span>项目名称</span>
+    </div>
+</div>
+<div id="content_1" style="<?php echo $data['manage/database.page_update']['s1'] ?>"><?php echo $data['manage/database.page_update']['content'] ?></div>
+<div id="content_2" style="<?php echo $data['manage/database.page_update']['s2'] ?>">
+  <div class="layui-fluid">
+    <div style="display:none;"><span id="list-name"><?php echo $data['manage/database.info']['update_header'] ?></span> > <span id="list-project"><?php echo $data['manage/database.info']['project_name'] ?></span></div>
+    <form method="post" target="f1" class="form1" role="form" autocomplete="off" action="<?php echo $data['manage/database.info']['action'] ?>">
+    <input type="hidden" name="function" id="function" value="msg"/>
+    <input type="hidden" name="url" id="url" value="<?php echo $data['manage/database.info']['list'] ?>" />
+    <input type="hidden" name="project" id="project" value="<?php echo $data['manage/database.info']['project'] ?>" />
+    <input type="hidden" name="table" id="table" value="<?php echo $data['manage/database.info']['table'] ?>" />
+    <input type="hidden" name="update_where_id" id="update_where_id" value="<?php echo $data['manage/database.info']['id'] ?>"/>
+    <input type="hidden" name="copy_num" id="copy_num" value="0"/>
+    <iframe id="f1" name="f1" style="display:none;"></iframe>
+
+    <div class="layui-row layui-col-space15">
+      <div class="<?php echo $data['/database.card'] ?>">
+        <div class="layui-card" style="<?php if(!(Dever::load('/database.layui_card'))): ?>display:none;<?php endif; ?>">
+          <div class="layui-card-header" style="display:none;">响应式组合</div>
+          <div class="layui-card-body" id="content"><?php if(isset($data['manage/database.update']) && is_array($data['manage/database.update'])): ?><?php $t=count($data['manage/database.update'])-1 ?><?php $i=0 ?><?php foreach($data['manage/database.update'] as $k => $v): ?><?php echo $v ?><?php $i=$i+1 ?><?php endforeach; ?><?php else: ?><?php echo $data['manage/database.update'] ?><?php endif; ?></div>
+          <div class="layui-card-body">
+            <div class="layui-form-item">
+                <div id="update_button" submit="<?php  echo Dever::submit() ?>"><?php echo $data['manage/database.update_button'] ?></div>
+              </div>
+            </div>
+        </div>
+      </div>
+    </div>
+    <div id="valid"><?php echo $data['manage/database.valid'] ?></div>
+    <div id="struct" style="display:none;" save="<?php echo $data['manage/database.save'] ?>"><?php echo $data['/database.info']['struct'] ?></div>
+    </form>
+  </div>
+</div>
+
+  
+  <?php require Dever::config("base")->data . 'compile/sknow/manage/layadmin/inc/script.cmp.php' ?>
+  <script id="update_script">
+  layui.config({
+    base: '<?php echo Dever::config("host")->script ?>lib/layui/admin/' //静态资源所在路径
+  }).extend({
+    index: 'lib/index', //主入口模块
+    formSelects: 'plugin/formselects/formselects'
+  }).use(['index', 'contlist', 'table', 'form', 'formSelects'], function(){
+    var table = layui.table;
+    var form = layui.form; 
+    var formSelects = layui.formSelects;
+
+    /*
+    $('select').each(function() {
+        if ($(this).attr('xm-value')) {
+          formSelects.value($(this).attr('xm-select'), $(this).attr('xm-value'));
+        }
+    });
+    */
+
+    init();
+  });
+  </script>
+</body>
+</html>

+ 1 - 0
data/readme

@@ -0,0 +1 @@
+readme

+ 3 - 0
package.json

@@ -0,0 +1,3 @@
+{
+	"rely": "manage,passport,email"
+}

+ 1 - 0
package/aliyun

@@ -0,0 +1 @@
+Subproject commit 7d53de8475ef3fcc5d8672a1f65b186cb2231c39

+ 7 - 0
package/area/daemon/import.php

@@ -0,0 +1,7 @@
+<?php
+
+define('DEVER_DAEMON', true);
+
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../index.php');
+
+Dever::load('area/import.load');

+ 4 - 0
package/area/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'area');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/attr/index.php

@@ -0,0 +1,4 @@
+<?php 
+define('DEVER_PACKAGE', 'attr');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 2 - 0
package/boot.php

@@ -0,0 +1,2 @@
+<?php
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/category/index.php

@@ -0,0 +1,4 @@
+<?php 
+define('DEVER_PACKAGE', 'category');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/excel/index.php

@@ -0,0 +1,4 @@
+<?php 
+define('DEVER_PACKAGE', 'excel');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/invite/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'invite');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 88 - 0
package/manage/config/base.php

@@ -0,0 +1,88 @@
+<?php
+
+$url = function()
+{
+	$url = Dever::input('loading') ? 'loading=1' : '';
+	$url .= Dever::input('ms') ? '&ms=' . Dever::input('ms') : '';
+
+	return $url;
+};
+
+# 一些基本配置
+$config['base'] = array
+(
+	'url' => $url(),
+
+	# 针对管理系统的配置,开启这个则每次刷新都读取admin的最新数据,测试功能
+	'getAdmin' => true,
+
+	# 开启批量更新
+	'mul_type' => 1,
+
+	# 地图配置
+	'map' => array
+	(
+		'url' => 'https://webapi.amap.com/maps?v=1.4.8&key=b51a0d5f8f977726eeaa070a30bcf3cd',
+	),
+
+	# 后台管理的数据执行权限的设置
+	//'manageAuthData' => 'journal/lib/manage.getManageData',
+
+	# 后台左侧主菜单,定义了这个之后,所有deverapp中的project建立主菜单功能将失效
+	/*
+	'menu' => array
+	(
+		'demand' => array
+		(
+			# 菜单名称
+			'name' => '需求管理',
+			# 哪些项目包含进来,多个用逗号隔开,直接把该项目中的database放到该菜单下
+			'project' => 'demand,service',
+			# 菜单图标 直接使用哪个project的图标
+			'icon' => 'demand',
+			# 排序
+			'order' => 100,
+		),
+
+		'main' => array
+		(
+			# 菜单名称
+			'name' => '系统设置',
+			# 哪些项目包含进来,多个用逗号隔开,直接把该项目中的database放到该菜单下
+			'project' => 'main,score,attr,category',
+			# 菜单图标 直接使用哪个project的图标
+			'icon' => 'main',
+			# 排序
+			'order' => 99,
+		),
+	)
+	*/
+);
+
+# 模板配置
+$config['template'] = array
+(
+	# 使用的模板 注意:定义这个之后,将会强制将本项目模板变成这个
+	'assets' => 'layadmin',
+	'template' => 'layadmin',
+
+	'replace' => array
+	(
+		'css' => '../css/',
+		'lib' => '../lib/',
+		'img' => '../img/',
+		'images' => '../images/',
+		'js' => '../js/',
+		'script' => '../script/',
+
+		# 以下的替换主要用于合并操作(host里的merge项)
+		'font' => '../fonts/',
+	),
+
+	'path' => 'html',
+	'layout' => '',
+
+	'relation' => array(),
+);
+
+return $config;

+ 7 - 0
package/manage/daemon/loop.php

@@ -0,0 +1,7 @@
+<?php
+
+define('DEVER_DAEMON', true);
+
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../index.php');
+
+Dever::load('manage/project.loop');

+ 7 - 0
package/manage/daemon/main.php

@@ -0,0 +1,7 @@
+<?php
+
+define('DEVER_DAEMON', true);
+
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../index.php');
+
+Dever::load('manage/project.cron');

+ 4 - 0
package/manage/index.php

@@ -0,0 +1,4 @@
+<?php 
+define('DEVER_PACKAGE', 'manage');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/message/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'message');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/oauth/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'oauth');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 14 - 0
package/passport/LICENSE

@@ -0,0 +1,14 @@
+Apache License
+Copyright 2016-2017 Dever(dever.cc)
+
+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
package/passport/README.md

@@ -0,0 +1,2 @@
+# passport
+

+ 42 - 0
package/passport/api/main.php

@@ -0,0 +1,42 @@
+<?php
+# 注册api,这里是为了安全考虑,否则可以不用在此注册,注册之后
+# api仅有三种类型:get、update、delete
+
+return array
+(
+	'reg.getMCode' => array
+	(
+		'name' => '获取验证码:手机号未注册',
+		'request' => array
+		(
+			'sid' => '临时id',
+			'skin' => '模板',
+		),
+		'response' => array
+		(
+			'info' => '响应信息',
+		),
+		'order' => 100,
+		'type' => 2,
+		# 安全加密
+		'secure' => true,
+	),
+
+	'reg.getMCodeLogin' => array
+	(
+		'name' => '获取验证码:手机号已注册',
+		'request' => array
+		(
+			'sid' => '临时id',
+			'skin' => '模板',
+		),
+		'response' => array
+		(
+			'info' => '响应信息',
+		),
+		'order' => 99,
+		'type' => 2,
+		# 安全加密
+		'secure' => true,
+	),
+);

+ 93 - 0
package/passport/config/base.php

@@ -0,0 +1,93 @@
+<?php
+
+# 一些基本配置
+$config['base'] = array
+(
+	# 小程序appid 后续直接使用applet组件
+	'applet' => array
+	(
+		'appid' => '',
+		'secret' => '',
+		'url' => 'https://api.weixin.qq.com/sns/jscode2session',
+	),
+	# 第三方登录的直接用oauth组件即可
+
+	# 站点使用邮箱还是手机作为主账号,如果是手机,请填写手机验证码的配置接口
+	'account' => 'email',
+	# 不需要验证码
+	//'nocode' => false,
+	# 发送邮件的配置
+	'email' => array
+	(
+		'pop' => 'pop3.sina.net',
+		'smtp' => 'smtp.sina.net',
+		'imap' => 'imap.sina.net',
+		'username' => '',
+		'password' => '',
+		'from' => array('test@dever.cc', 'dever'),
+		# 找回密码
+		'forget' => array
+		(
+			'title' => '精品网密码重置',
+			'link' => '精品网密码重置',
+			'content' => '尊敬的精品网用户:
+
+您好!
+
+请点击下方链接进行密码重置
+
+【{link}】
+
+如果上面的链接无法点击,您也可以复制链接到您的浏览器内打开,完成密码重置(链接有效期一天)。',
+		),
+	),
+	# 性别转换 passport里1为男、2为女 3为未知,如果前端定义与这个不同,请做好转换
+	'sex' => array
+	(
+		# 前面的索引为前端传过来的值
+		1 => 1,
+		2 => 2,
+		3 => 3,
+	),
+
+	# 后续直接使用sms组件,暂时先放这里吧
+	'mobileCode' => array
+	(
+		# debug模式
+		'debug' => true,
+		# 发送短信的接口
+		'url' => '',
+		# 发送方法 get、post
+		'method' => 'get',
+		# 是否json编码
+		'json' => false,
+		# header信息
+		'header' => '',
+		# body信息
+		'body' => 'param={code}&phone={mobile}&sign={sign}&skin={skin}',
+		# 短信模板 发送短信时,请加上参数skin=1
+		'skin' => array
+		(
+			1 => '{sign}您好,您的验证码为{code},十分钟之内有效。',
+		),
+		# 短信签名
+		'sign' => '【DEVER】',
+		# 验证码有效期 默认10分钟
+		'timeout' => 600,
+		# 一天之内的最大发送次数,默认为10次
+		'total' => 10,
+		# 不允许多久之内重复发送,默认为60秒
+		'time' => 60,
+		# 验证码长度
+		'length' => 4,
+	),
+	# 注册成功后,调取的接口
+	'regAction' => '',
+
+	'passport_list_button' => array
+	(
+		
+	),
+);
+
+return $config;

+ 125 - 0
package/passport/database/app.php

@@ -0,0 +1,125 @@
+<?php
+
+$source_type = array (
+	'ios' => 'ios',
+	'android' => 'android',
+);
+
+return array
+(
+	# 表名
+	'name' => 'app',
+	# 显示给用户看的名称
+	'lang' => 'app用户列表',
+	'order' => 9,
+	'menu' => false,
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			//'search'	=> 'order',
+			'order'		=> 'desc',
+			'list'		=> true,
+		),
+
+		'uid'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			//'update'	=> 'select',
+			'search'	=> 'fulltext',
+			'list'		=> '{uid} > 0 ? Dever::load("passport/user-one#username", {uid}) . "(" . Dever::load("passport/user-one#mobile", {uid}). "-{uid})": "未知用户"',
+			//'list'		=> true,
+			//'edit'		=> true,
+		),
+
+		'source_type'		=> array
+		(
+			'type' 		=> 'varchar-100',
+			'name' 		=> '用户来源',
+			'default' 	=> '1',
+			'desc' 		=> '请选择用户来源',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'select',
+			'option'	=> $source_type,
+			'search'	=> 'select',
+			'list'		=> true,
+		),
+
+		'system_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '所属项目',
+			'default' 	=> '1',
+			'desc' 		=> '所属项目',
+			'match' 	=> 'is_numeric',
+			//'option' 	=> $level,
+			//'update'	=> 'select',
+			//'list'		=> true,
+		),
+
+		'uuid'       => array
+        (
+            'type'      => 'varchar-300',
+            'name'      => 'uuid',
+            'default'   => '',
+            'desc'      => 'uuid',
+            'match'     => 'is_string',
+            //'update'  => 'text',
+            'list'		=> true,
+        ),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'search'	=> 'date',
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+	
+	'manage' => array
+	(
+		'insert' => false,
+		'edit' => false,
+		'delete' => false,
+	),
+	
+	# request 请求接口定义
+	'request' => array
+	(
+		# 此处定义是为跳出auth
+		'getAllByUids' => array
+		(
+			'option' => array
+			(
+				'uid' => array('yes', 'in'),
+				'state' => 1,
+			),
+			'type' => 'all',
+			'col' => '*',
+		),
+	),
+);

+ 94 - 0
package/passport/database/code.php

@@ -0,0 +1,94 @@
+<?php
+
+# 定义几个常用的选项
+$option = array
+(
+	1 => '发送中',
+	2 => '已发送',
+);
+
+$mobile = Dever::rule('mobile');
+
+return array
+(
+	# 表名
+	'name' => 'code',
+	# 显示给用户看的名称
+	'lang' => '短信记录表',
+	'menu' => false,
+	# 数据结构
+	'struct' => array
+	(
+	
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order',
+			//'list'		=> true,
+		),
+
+		'mobile'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '手机号',
+			'default' 	=> '',
+			'desc' 		=> '请输入用户手机号',
+			'match' 	=> $mobile,
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'code'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '验证码',
+			'default' 	=> '',
+			'desc' 		=> '验证码',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'day'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '申请时间',
+			'default' 	=> '',
+			'desc' 		=> '申请时间',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+			'option' 	=> $option,
+			//'update'	=> 'radio',
+			'list'		=> true,
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '申请时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'search'	=> 'date',
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+);

+ 85 - 0
package/passport/database/combine.php

@@ -0,0 +1,85 @@
+<?php
+$status = array
+(
+	1 => '未执行',
+	2 => '已执行',
+);
+return array
+(
+	# 表名
+	'name' => 'combine',
+	# 显示给用户看的名称
+	'lang' => '合并管理',
+	# 后台菜单排序
+	'order' => 1,
+	'menu'	=> false,
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order',
+			'list'		=> true,
+			'order'		=> 'desc',
+		),
+		
+		'old_uid'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '旧的uid',
+			'default' 	=> '',
+			'desc' 		=> '旧的uid',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'text',
+			'list'		=> true,
+		),
+		
+		'new_uid'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '新的uid',
+			'default' 	=> '',
+			'desc' 		=> '新的uid',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'text',
+			'list'		=> true,
+		),
+
+		'status'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '合并任务执行状态',
+			'default' 	=> '2',
+			'desc' 		=> '合并任务执行状态',
+			'match' 	=> 'is_numeric',
+			'option' 	=> $status,
+			'update'	=> 'radio',
+			'list'		=> true,
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+);

+ 138 - 0
package/passport/database/profession.php

@@ -0,0 +1,138 @@
+<?php
+
+$system = function()
+{
+	$array = array();
+	$info = Dever::db('passport/system')->state();
+	if($info)
+	{
+		$array += $info;
+	}
+	return $array;
+};
+
+return array
+(
+	# 表名
+	'name' => 'profession',
+	# 显示给用户看的名称
+	'lang' => '职业设置',
+	# 后台菜单排序
+	'order' => 1,
+	'end' => array
+	(
+		'insert' => array
+		(
+			'manage/top.sync',
+		),
+		'update' => array
+		(
+			'manage/top.sync',
+		),
+	),
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order',
+			'list'		=> true,
+			'order'		=> 'desc',
+		),
+		
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '职业名称',
+			'default' 	=> '',
+			'desc' 		=> '职业名称',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'system_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '所属项目',
+			'default' 	=> '1',
+			'desc' 		=> '所属项目',
+			'match' 	=> 'is_numeric',
+			'option' 	=> $system,
+			//'update'	=> 'select',
+			//'list'		=> true,
+		),
+
+		'reorder'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '排序(数值越大越靠前)',
+			'default' 	=> '1',
+			'desc' 		=> '请输入排序',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'search'	=> 'order',
+			'list'		=> true,
+			'order'		=> 'desc',
+			'edit'		=> true,
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+
+	'manage' => array
+	(
+		'insert' => false,
+		'edit' => false,
+
+		# 自定义快捷新增和编辑
+		'button' => array
+		(
+			'新增' => array('fast'),
+		),
+		# 快捷更新
+		'list_button' => array
+		(
+			'edit' => array('编辑'),
+		),
+	),
+
+	'request' => array
+	(
+		'getAll' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'state' => 1,
+			),
+			'type' => 'all',
+			'order' => array('reorder' => 'desc','id' => 'desc'),
+			'col' => '*',
+		),
+	),
+);

+ 165 - 0
package/passport/database/system.php

@@ -0,0 +1,165 @@
+<?php
+
+return array
+(
+	# 表名
+	'name' => 'system',
+	# 显示给用户看的名称
+	'lang' => '项目管理',
+	# 后台菜单排序
+	'order' => 1,
+	'end' => array
+	(
+		'insert' => array
+		(
+			'manage/top.sync',
+		),
+		'update' => array
+		(
+			'manage/top.sync',
+		),
+	),
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order',
+			'list'		=> true,
+			'order'		=> 'desc',
+		),
+		
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '项目名称',
+			'default' 	=> '',
+			'desc' 		=> '项目名称',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'appid'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '微信appid',
+			'default' 	=> '',
+			'desc' 		=> '请输入微信appid',
+			'match' 	=> 'option',
+			'search'	=> 'order,fulltext',
+			'update'	=> 'text',
+			'list'		=> 'table',
+			'modal' 	=> '详细信息',
+		),
+
+		'secret'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '微信secret',
+			'default' 	=> '',
+			'desc' 		=> '请输入微信secret',
+			'match' 	=> 'option',
+			'search'	=> 'order,fulltext',
+			'update'	=> 'text',
+			//'list'		=> 'table',
+			//'modal' 	=> '详细信息',
+		),
+		
+		'reorder'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '排序(数值越大越靠前)',
+			'default' 	=> '1',
+			'desc' 		=> '请输入排序',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'search'	=> 'order',
+			'list'		=> true,
+			'order'		=> 'desc',
+			'edit'		=> true,
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+
+	# 默认值
+	'default' => array
+	(
+		'col' => 'name,state,cdate',
+		'value' => array
+		(
+			'"默认项目",1,' . time(),
+		),
+	),
+
+	'manage' => array
+	(
+		'insert' => false,
+		'edit' => false,
+
+		# 自定义快捷新增和编辑
+		'button' => array
+		(
+			'新增' => array('fast'),
+		),
+		# 快捷更新
+		'list_button' => array
+		(
+			'edit' => array('编辑'),
+		),
+	),
+
+	'top' => array
+	(
+		# 数据来源
+		'data' => 'state',
+		# 菜单名
+		'name' => '项目选择',
+		# 默认值
+		'value' => 1,
+		# 对应的字段值,设置这个之后,所有设置等于这个值的字段,都要遵循这个权限的控制
+		'key' => Dever::config('base')->top,
+		# 本表中代表名称的字段
+		'col' => 'name',
+	),
+
+	'request' => array
+	(
+		'getAll' => array
+		(
+			# 匹配的正则或函数 选填项
+			'option' => array
+			(
+				'state' => 1,
+			),
+			'type' => 'all',
+			'order' => array('reorder' => 'desc','id' => 'desc'),
+			'col' => '*',
+		),
+	),
+);

+ 494 - 0
package/passport/database/user.php

@@ -0,0 +1,494 @@
+<?php
+
+# 定义几个常用的选项
+$option = array
+(
+	1 => '正常',
+	2 => '冻结',
+);
+
+$button = array();
+$list_button = Dever::config('base', 'project')->passport_list_button;
+
+if (Dever::project('score')) {
+	$button += array
+	(
+		'用户积分列表' => array('list', 'user&project=score&oper_parent=user&oper_project=passport'),
+		'用户等级列表' => array('list', 'user_level&project=score&oper_parent=user&oper_project=passport'),
+	);
+
+	if (!$list_button) {
+		$list_button = array();
+	}
+
+	$list_button += array
+	(
+		'list100' => array('积分', '"user&project=score&search_option_uid={id}&oper_parent=user&oper_project=passport"'),
+		'list101' => array('等级', '"user_level&project=score&search_option_uid={id}&oper_parent=user&oper_project=passport"'),
+	);
+}
+
+/*
+$level = function()
+{
+	return Dever::db('passport/level')->state();
+};
+*/
+$system = function()
+{
+	$array = array();
+	$info = Dever::db('passport/system')->state();
+	if ($info) {
+		$array += $info;
+	}
+	return $array;
+};
+
+$profession = function()
+{
+	$array = array();
+	$info = Dever::db('passport/profession')->state();
+	if ($info) {
+		$array += $info;
+	}
+	return $array;
+};
+
+$sex = array
+(
+	1 => '男',
+	2 => '女',
+	3 => '未知',
+);
+
+
+$weixin = array
+(
+	1 => '已关注',
+	2 => '未关注',
+);
+
+$temp = array
+(
+	1 => '临时用户',
+	2 => '正式用户',
+);
+
+$bind = array
+(
+	1 => '已绑定',
+	2 => '未绑定',
+);
+
+$source_type = array (
+	'ios' => 'ios',
+	'android' => 'android',
+	'h5' => 'h5',
+	'applet' => '小程序',
+	'pc' => '网站',
+	'service' => '公众号',
+);
+
+$email = Dever::rule('email');
+$email = 'option';
+$mobile = Dever::rule('mobile');
+$mobile = 'option';
+
+
+return array
+(
+	'email' => $email,
+	'mobile' => $mobile,
+	'source_type' => $source_type,
+	'sex' => $sex,
+	# 表名
+	'name' => 'user',
+	# 显示给用户看的名称
+	'lang' => '用户管理',
+	'order' => 10,
+	# 数据结构
+	'struct' => array
+	(
+	
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order,fulltext',
+			'list'		=> true,
+		),
+		
+		'username'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> '用户名',
+			'default' 	=> '',
+			'desc' 		=> '请输入用户名',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'truename'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> '姓名',
+			'default' 	=> '',
+			'desc' 		=> '请输入姓名',
+			'match' 	=> 'option',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> '"{truename}" ? "{truename}" : "点此编辑"',
+			'edit'		=> true,
+		),
+
+		'mobile'		=> array
+		(
+			'type' 		=> 'varchar-32',
+			'name' 		=> '手机号',
+			'default' 	=> '',
+			'desc' 		=> '请输入用户手机号',
+			'match' 	=> $mobile,
+			'update'	=> 'text',
+			'search'	=> 'fulltext,exist',
+			'exist'		=> array
+			(
+				'yes' => '有值',
+				//'no' => '没有值',
+			),
+			'list'		=> true,
+		),
+
+		'system_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '所属项目',
+			'default' 	=> '1',
+			'desc' 		=> '所属项目',
+			'match' 	=> 'is_numeric',
+			'option' 	=> $system,
+			//'update'	=> 'select',
+			//'list'		=> true,
+		),
+
+		'profession'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '职业',
+			'default' 	=> '1',
+			'desc' 		=> '职业',
+			'match' 	=> 'is_numeric',
+			'option' 	=> $profession,
+			//'update'	=> 'select',
+			//'list'		=> true,
+		),
+
+		'wechat'		=> array
+		(
+			'type' 		=> 'varchar-100',
+			'name' 		=> '微信号',
+			'default' 	=> '',
+			'desc' 		=> '微信号',
+			'match' 	=> 'is_string',
+			//'update'	=> 'select',
+			//'list'		=> true,
+		),
+
+		'source_type'		=> array
+		(
+			'type' 		=> 'varchar-100',
+			'name' 		=> '用户来源',
+			'default' 	=> '',
+			'desc' 		=> '请选择用户来源',
+			'match' 	=> 'is_string',
+			'update'	=> 'select',
+			'option'	=> $source_type,
+			'search'	=> 'select',
+			//'list'		=> true,
+		),
+
+		'email'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '邮箱',
+			'default' 	=> '',
+			'desc' 		=> '请输入邮箱',
+			'match' 	=> $email,
+			'update'	=> 'text',
+			//'search'	=> 'fulltext',
+			//'list'		=> true,
+		),
+		
+		'password'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> '密码',
+			'default' 	=> '',
+			'desc' 		=> '请输入密码',
+			'match' 	=> 'option',
+			'update'	=> 'password',
+			'callback'	=> 'sha1',
+		),
+		
+		//search_exist_avatar=yes
+		'avatar'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> '头像',
+			'default' 	=> '',
+			'desc' 		=> '请选择头像',
+			'match' 	=> 'option',
+			'update'	=> 'image',
+			'key' 		=> '1',
+			'place'		=> '150',
+			'list_name'	=> '详细信息',
+			//'list'		=> '"{avatar}" ? "<img src=\'{avatar}\' width=\'150\'>": ""',
+			'list'		=> 'Dever::load("passport/lib/manage.show", {id})',
+		),
+
+		'country'		=> array
+		(
+			'type' 		=> 'varchar-100',
+			'name' 		=> '国家',
+			'default' 	=> '',
+			'desc' 		=> '国家',
+			'match' 	=> 'option',
+			//'update'	=> 'text',
+		),
+
+		'province'		=> array
+		(
+			'type' 		=> 'varchar-100',
+			'name' 		=> '省份',
+			'default' 	=> '',
+			'desc' 		=> '省份',
+			'match' 	=> 'option',
+			//'update'	=> 'text',
+		),
+
+		'city'		=> array
+		(
+			'type' 		=> 'varchar-100',
+			'name' 		=> '城市',
+			'default' 	=> '',
+			'desc' 		=> '城市',
+			'match' 	=> 'option',
+			//'update'	=> 'text',
+		),
+
+		'area'		=> array
+		(
+			'type' 		=> 'varchar-800',
+			'name' 		=> '地区',
+			'default' 	=> '',
+			'desc' 		=> '地区',
+			'match' 	=> 'option',
+			//'update'	=> 'text',
+			//'list'		=> true,
+		),
+
+		'area_id'		=> array
+		(
+			'type' 		=> 'varchar-800',
+			'name' 		=> '地区',
+			'default' 	=> '',
+			'desc' 		=> '地区',
+			'match' 	=> 'option',
+			//'update'	=> 'text',
+			//'list'		=> true,
+		),
+
+		'address'		=> array
+		(
+			'type' 		=> 'varchar-1000',
+			'name' 		=> '详细地址',
+			'default' 	=> '',
+			'desc' 		=> '详细地址',
+			'match' 	=> 'option',
+			//'update'	=> 'text',
+			//'list'		=> true,
+		),
+		
+		'info'		=> array
+		(
+			'type' 		=> 'varchar-255',
+			'name' 		=> '介绍-选填,如果想清空该介绍,请输入null。',
+			'default' 	=> '',
+			'desc' 		=> '请输入介绍',
+			'match' 	=> 'option',
+			'update'	=> 'editor',
+		),
+
+		'score'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> '积分',
+			'default' 	=> '',
+			'desc' 		=> '请输入积分',
+			'match' 	=> 'option',
+			//'update'	=> 'text',
+			//'list'		=> true,
+		),
+
+		'sex'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '用户性别',
+			'default' 	=> '3',
+			'desc' 		=> '用户性别',
+			'match' 	=> 'is_numeric',
+			'option' 	=> $sex,
+			'update'	=> 'radio',
+			//'list'		=> true,
+		),
+
+		'level'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户等级',
+			'default' 	=> '1',
+			'desc' 		=> '请选择用户等级',
+			'match' 	=> 'is_numeric',
+			//'option' 	=> $level,
+			//'update'	=> 'select',
+			//'list'		=> true,
+		),
+
+		'temp'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '是否临时用户',
+			'default' 	=> '1',
+			'desc' 		=> '是否临时用户',
+			'match' 	=> 'is_numeric',
+			//'search'	=> 'select',
+			'option' 	=> $temp,
+			//'update'	=> 'select',
+			//'list'		=> true,
+		),
+
+		'login_date'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '最近登录',
+			//'match' 	=> array('is_numeric', time()),
+			'match' 	=> 'is_numeric',
+			'desc' 		=> '',
+			'default' 	=> '0',
+			//'list'		=> 'date("Y-m-d H:i:s", {login_date})',
+		),
+
+		'bind'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '是否绑定手机',
+			'default' 	=> '2',
+			'desc' 		=> '请选择是否绑定手机',
+			'match' 	=> 'is_numeric',
+			//'option' 	=> $bind,
+			//'update'	=> 'radio',
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+			'option' 	=> $option,
+			'update'	=> 'radio',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '注册时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+
+	'manage' => array
+	(
+		'excel' => true,
+
+		'button' => $button,
+
+		# 列表
+		'list_button' => $list_button,
+	),
+
+	# 更新表结构
+	/*
+	'alter' => array
+	(
+		1 => array
+		(
+			array('add', 'bind', 'bind', 'tinyint-1 2 是否绑定手机'),
+		),
+		'version' => 1,
+	),
+	*/
+	# 索引
+	'index' => array
+	(
+		1 => array
+		(
+			'mobile' => 'mobile',
+		),
+		
+		# 版本号 更改版本号会更新当前表的索引
+		'version' => 1,
+	),
+	
+	# request 请求接口定义
+	'request' => array
+	(
+		# 此处定义是为跳出auth
+		'login' => array
+		(
+			'option' => array
+			(
+				'username' => 'yes',
+				'mobile' => 'yes',
+				'email' => 'yes',
+				'password' => 'yes',
+			),
+			'type' => 'one',
+		),
+
+		# 验证手机号是否被使用 
+		'checkMobile' => array
+		(
+			# 匹配的正则或函数 选填项
+			'where' => array
+			(
+				'mobile' => 'yes',
+				'id' => array('yes', '!='),
+			),
+			'type' => 'one',
+		),
+
+		# 此处定义是为跳出auth
+		'updates' => array
+		(
+			'set' => array
+			(
+				'state' => 'yes',
+			),
+			'where' => array
+			(
+				'id' => array('yes', 'in'),
+			),
+			'type' => 'update',
+		),
+	),
+);

+ 216 - 0
package/passport/database/wechat.php

@@ -0,0 +1,216 @@
+<?php
+
+$type = array
+(
+	1 => '小程序',
+	2 => '微信公众号',
+	3 => 'IOS微信客户端',
+	4 => '安卓微信客户端',
+);
+return array
+(
+	# 表名
+	'name' => 'wechat',
+	# 显示给用户看的名称
+	'lang' => '微信绑定列表',
+	'order' => 10,
+	'menu' => false,
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			//'search'	=> 'order',
+			'order'		=> 'desc',
+			'list'		=> true,
+		),
+
+		'system_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '所属项目',
+			'default' 	=> '1',
+			'desc' 		=> '所属项目',
+			'match' 	=> 'is_numeric',
+			//'option' 	=> $level,
+			//'update'	=> 'select',
+			//'list'		=> true,
+		),
+
+		'uid'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			//'update'	=> 'select',
+			'search'	=> 'fulltext',
+			'list'		=> '{uid} > 0 ? Dever::load("passport/user-one#username", {uid}) : "未知用户"',
+			'list'		=> true,
+			//'edit'		=> true,
+		),
+
+		'type'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '类型',
+			'default' 	=> '1',
+			'desc' 		=> '类型',
+			'match' 	=> 'is_numeric',
+			'option' 	=> $type,
+			'update'	=> 'radio',
+			'list'		=> true,
+		),
+
+		'openid'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> 'openid-微信的唯一用户id',
+			'default' 	=> '',
+			'desc' 		=> 'openid',
+			'match' 	=> 'is_string',
+			//'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'unionid'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> 'unionid-微信的唯一用户id',
+			'default' 	=> '',
+			'desc' 		=> 'unionid',
+			'match' 	=> 'is_string',
+			//'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'session_key'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> 'session_key',
+			'default' 	=> '',
+			'desc' 		=> 'session_key',
+			'match' 	=> 'is_string',
+			//'update'	=> 'text',
+		),
+
+		'access_token'       => array
+        (
+            'type'      => 'varchar-200',
+            'name'      => 'access_token',
+            'default'   => '',
+            'desc'      => 'access_token',
+            'match'     => 'is_string',
+            //'update'  => 'text',
+        ),
+
+        'refresh_token'       => array
+        (
+            'type'      => 'varchar-200',
+            'name'      => 'refresh_token',
+            'default'   => '',
+            'desc'      => 'refresh_token',
+            'match'     => 'is_string',
+            //'update'  => 'text',
+        ),
+
+        'expires_in'       => array
+        (
+            'type'      => 'varchar-100',
+            'name'      => 'expires_in',
+            'default'   => '',
+            'desc'      => 'expires_in',
+            'match'     => 'is_string',
+            //'update'  => 'text',
+        ),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'search'	=> 'date',
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+	
+	'manage' => array
+	(
+		'insert' => false,
+		'edit' => false,
+		'delete' => false,
+	),
+
+	# 索引
+	'index' => array
+	(
+		11 => array
+		(
+			'openid' => 'uid,openid,unionid',
+		),
+		
+		# 版本号 更改版本号会更新当前表的索引
+		'version' => 11,
+	),
+	
+	# request 请求接口定义
+	'request' => array
+	(
+		'getByUnionid' => array
+		(
+			'option' => array
+			(
+				'unionid' => 'yes',
+			),
+			'type' => 'all',
+			'order' => array('id' => 'asc'),
+			'col' => '*',
+		),
+
+		'updates' => array
+		(
+			'set' => array
+			(
+				'uid' => 'yes',
+			),
+			'where' => array
+			(
+				'uid' => array('yes', 'in'),
+			),
+			'type' => 'update',
+		),
+
+		'updateByOpenid' => array
+		(
+			'set' => array
+			(
+				'session_key' => 'yes',
+			),
+			'where' => array
+			(
+				'openid' => 'yes',
+			),
+			'type' => 'update',
+		),
+	),
+);

+ 8 - 0
package/passport/index.php

@@ -0,0 +1,8 @@
+<?php
+
+define('DEVER_APP_NAME', 'passport');
+define('DEVER_APP_LANG', '用户管理');
+define('DEVER_APP_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+define('DEVER_MANAGE_ORDER', -10);
+define('DEVER_MANAGE_ICON', 'glyphicon glyphicon-user layui-icon-username');
+include(DEVER_APP_PATH . '../boot.php');

+ 680 - 0
package/passport/lib/Base.php

@@ -0,0 +1,680 @@
+<?php
+namespace Passport\Lib;
+
+use Dever;
+use Upload\Src\Lib\Img;
+use Dever\Routing\Uri;
+use Dever\Session\Oper as Save;
+use Dever\String\Encrypt;
+
+class Base
+{
+    const NAME = 'passportv1';
+
+    const CODE = 'code';
+
+    const MCODE = 'mcode';
+
+    protected $save;
+
+    public function __construct()
+    {
+        //$this->save = new Save(false, 'cookie');
+        $this->save = new Save(false, 'session');
+    }
+
+    # 注册用户
+    public function reg($type, $data)
+    {
+        $user = $this->getUserExtInfo($data);
+
+        $user['source_type'] = $type;
+        $user['system_id'] = isset($data['system']) ? $data['system'] : 1;
+
+        if (isset($data['username'])) {
+            $user['temp'] = 2;
+            $user['username'] = $data['username'];
+        } else {
+            $user['temp'] = 1;
+            $user['username'] = '临时用户';
+        }
+
+        if (isset($data['mobile'])) {
+            $user['bind'] = 1;
+            $user['mobile'] = $data['mobile'];
+        } else {
+            $user['bind'] = 2;
+            $user['mobile'] = '';
+        }
+
+        $uid = Dever::db('passport/user')->insert($user);
+
+        $this->createUsername($uid, $user['username'], true);
+
+        return $uid;
+    }
+
+    # 更新用户
+    public function updateUser($uid, $data)
+    {
+        $user = $this->getUserExtInfo($data);
+        $user['username'] = $this->createUsername($uid, $data['username']);
+        if (isset($user) && $user) {
+            $update['where_id'] = $uid;
+            Dever::db('passport/user')->update($update);
+        }
+        return $uid;
+    }
+
+    private function getUserExtInfo($data)
+    {
+        $user = array();
+        if (isset($data['sex'])) {
+            $user['sex'] = $data['sex'];
+        }
+        if (isset($data['avatar'])) {
+            //$update['avatar'] = $this->saveAvatar($pic);
+            $user['avatar'] = $data['avatar'];
+        }
+        if (isset($data['city'])) {
+            $user['city'] = $data['city'];
+        }
+        if (isset($data['province'])) {
+            $user['province'] = $data['province'];
+        }
+        if (isset($data['country'])) {
+            $user['country'] = $data['country'];
+        }
+        if (isset($user['country']) && isset($user['province']) && isset($user['city'])) {
+            $user['set_area'] = $user['country'] .','. $user['province'] .','. $user['city'];
+        }
+
+        return $user;
+    }
+
+    public function wechat($data, $user = array(), $account, $system, $source_type, $source = false)
+    {
+        $uid = false;
+
+        if (!$data['openid']) {
+            Dever::alert('错误的openid');
+        }
+
+        if (!isset($user['username'])) {
+            Dever::alert('用户名错误');
+        }
+
+        if (isset($user['sex'])) {
+            if ($user['sex'] != 1 && $user['sex'] != 2) {
+                $user['sex'] = 3;
+            }
+        }
+
+        if (isset($user['country']) && $user['country'] && isset($user['province']) && $user['province'] && isset($user['city']) && $user['city']) {
+            $user['area'] = $user['country'] .','. $user['province'] .','. $user['city'];
+        }
+        
+        $info = Dever::db('passport/wechat')->one(array('openid' => $data['openid']));
+
+        if (!$info) {
+            if (isset($data['unionid']) && $data['unionid']) {
+                $info = Dever::db('passport/wechat')->one(array('unionid' => $data['unionid']));
+                if (!$info) {
+                    $uid = false;
+                } else {
+                    $uid = $info['uid'];
+                }
+                $wechat['unionid'] = $data['unionid'];
+            }
+            if (!$uid) {
+                $user['source_type'] = 'service';
+                if ($system) {
+                    $user['system_id'] = $system;
+                }
+                if ($source_type) {
+                    $user['source_type'] = $source_type;
+                }
+                $uid = Dever::db('passport/user')->insert($user);
+            } else {
+                $user['where_id'] = $uid;
+                Dever::db('passport/user')->update($user);
+            }
+
+            $wechat['access_token'] = $data['access_token'];
+            $wechat['openid'] = $data['openid'];
+            $wechat['expires_in'] = $data['expires_in'];
+            $wechat['refresh_token'] = $data['refresh_token'];
+            $wechat['account_id'] = $account;
+            if ($system) {
+                $wechat['system_id'] = $system;
+            }
+            
+            $wechat['uid'] = $uid;
+            $wechat['type'] = 2;
+            if ($source_type == 'applet') {
+                $wechat['type'] = 1;
+            } elseif ($source_type == 'ios') {
+                $wechat['type'] = 3;
+            } elseif ($source_type == 'android') {
+                $wechat['type'] = 4;
+            }
+            $id = Dever::db('passport/wechat')->insert($wechat);
+
+            if (Dever::project('source') && isset($source) && $source && $source > 0) {
+                Dever::load('source/lib/core')->saveUser($id, $uid, $source, 'oauth', $account);
+            }
+        } else {
+            $uid = $info['uid'];
+            if (isset($data['unionid']) && $data['unionid']) {
+                $wechat['unionid'] = $data['unionid'];
+                # 判断用户是否存在,是否需要合并
+                //$wechat['uid'] = $this->combine($uid, $data['unionid']);
+            }
+            
+            $wechat['access_token'] = $data['access_token'];
+            $wechat['openid'] = $data['openid'];
+            $wechat['expires_in'] = $data['expires_in'];
+            $wechat['refresh_token'] = $data['refresh_token'];
+            $wechat['where_id'] = $info['id'];
+            $wechat['account_id'] = $account;
+            if ($system) {
+                $wechat['system_id'] = $system;
+            }
+            $id = $info['id'];
+            //Dever::db('passport/wechat')->update($wechat);
+
+            $user['where_id'] = $uid;
+            //Dever::load('passport/user-update', $user);
+        }
+
+        $this->createUsername($uid, $user['username']);
+
+        $user = Dever::load('passport/user-one', $uid);
+
+        $this->save($user);
+
+        $user['uid'] = $user['id'];
+        $user['signature'] = Dever::login($user['id']);
+
+        return $user;
+    }
+
+    /**
+     * 更新用户信息 绑定用户手机号
+     *
+     * @return mixed
+     */
+    public function bind_mobile()
+    {
+        $uid = $this->check();
+        //$code = Dever::input('mcode');
+        $mobile = Dever::load('passport/reg')->checkMobileExists();
+        //$mobile = Dever::input('mobile');
+        if ($mobile && $uid) {
+            $info = Dever::load('passport/user-one', array('mobile' => $mobile));
+            if ($info && $info['bind'] == 1) {
+                Dever::alert('该手机号已绑定');
+            }
+            $uid = $this->combine($uid, $mobile, 'mobile');
+            $info = Dever::load('passport/user-one', $uid);
+            $result['mobile'] = $mobile;
+            if ($info) {
+                $update['set_mobile'] = $mobile;
+                $update['set_bind'] = 1;
+                $update['where_id'] = $uid;
+                Dever::load('passport/user-update', $update);
+
+                $state = Dever::config('base', 'project')->regSendSms;
+                if ($state) {
+                    Dever::setInput('skin', $state);
+                    $this->send($mobile, $uid);
+                }
+            } else {
+                Dever::alert('无效的用户id,请重新登录');
+            }
+        }
+
+        if (!$info['mobile']) {
+            Dever::score($uid, 'bind_mobile', '绑定手机号');
+        }
+
+        $result['uid'] = $uid;
+        $result['signature'] = Dever::login($uid);
+
+        return $result;
+    }
+
+    public function createUsername($uid, $username, $update = false)
+    {
+        if (!$username || $username == '临时用户') {
+            $username = $uid + 100000;
+            $username = 'JM' . $username;
+
+            if ($update) {
+                Dever::db('passport/user')->update(array('where_id' => $uid, 'username' => $username));
+            }
+        }
+        
+        return $username;
+    }
+
+    # 合并用户
+    public function combine($uid, $unionid, $col = 'unionid')
+    {
+        $cur = $uid;
+        if ($col == 'mobile' || $col == 'id') {
+            $user_wechat = Dever::load('passport/user-all', array($col => $unionid));
+        } else {
+            $user_wechat = Dever::load('passport/wechat-getByUnionid', array($col => $unionid));
+        }
+
+        if ($user_wechat) {
+            # 合并去
+            $drop = array();
+            $total = count($user_wechat);
+            if ($total <= 1) {
+                return $cur;
+            }
+
+            $new = false;
+            foreach ($user_wechat as $k => $v) {
+                if (!isset($v['uid'])) {
+                    $v['uid'] = $v['id'];
+                    $user = $v;
+                } else {
+                    $user = Dever::db('passport/user')->one($v['uid']);
+                    $user['uid'] = $user['id'];
+                }
+
+                if (!$new) {
+                    if ($user['bind'] == 1 && !strstr($user['username'], '****')) {
+                        $new = $user;
+                    } elseif ($user['temp'] == 2 && $user['source_type'] == 'applet') {
+                        $new = $user;
+                    } elseif ($user['avatar']) {
+                        $new = $user;
+                    } elseif ($user['mobile']) {
+                        $new = $user;
+                    } else {
+                        $drop[$user['uid']] = $user;
+                    }
+                } else {
+                    $drop[$user['uid']] = $user;
+                }
+            }
+            $cur = $new;
+
+            if (Dever::input('test') == 1) {
+                print_r($user_wechat);
+                print_r($cur);
+                print_r($drop);die;
+            }
+
+            # 异步处理
+            $this->updateCombine($cur, $drop);
+
+            $cur = $new['uid'];
+        }
+
+        return $cur;
+    }
+
+    private function updateCombine($new, $drop)
+    {
+        # 队列
+        //Dever::queue();
+        if (isset($drop[$new['uid']])) {
+            unset($drop[$new['uid']]);
+        }
+        $drops = array();
+        if ($drop) {
+            foreach ($drop as $k => $v) {
+                $drops[] = $k;
+                $update = array();
+                if (!$new['username'] && $v['username']) {
+                    $update['username'] = $v['username'];
+                } elseif (strstr($new['username'], '****') && $v['username']) {
+                    $update['username'] = $v['username'];
+                }
+
+                if (!$new['avatar'] && $v['avatar']) {
+                    $update['avatar'] = $v['avatar'];
+                }
+
+                if (!$new['mobile'] && $v['mobile']) {
+                    $update['mobile'] = $v['mobile'];
+                }
+
+                if (!$new['area'] && $v['area']) {
+                    $update['area'] = $v['area'];
+                }
+
+                if (isset($update) && $update) {
+                    $update['where_id'] = $new['uid'];
+                    Dever::load('passport/user-update', $update);
+                }
+            }
+
+            if ($drops) {
+                asort($drops);
+                $drop_uid = implode(',', $drops);
+                //Dever::load('passport/lib/base.handleCombine?new_uid=' . $new['uid'] . '&old_uid=' . $drop_uid);
+                Dever::daemon('lib/base.handleCombine?new_uid=' . $new['uid'] . '&old_uid=' . $drop_uid, 'passport');
+            }
+        }
+    }
+
+    public function handleCombine()
+    {
+        $combine = array();
+        $combine['status'] = 1;
+        $combine['new_uid'] = Dever::input('new_uid');
+        $combine['old_uid'] = Dever::input('old_uid');
+
+        $info = Dever::db('passport/combine')->one($combine);
+        if (!$info) {
+            Dever::db('passport/combine')->insert($combine);
+        }
+
+        Dever::load('passport/user-updates', array('set_state' => 2, 'where_id' => $combine['old_uid']));
+
+        Dever::load('passport/wechat-updates', array('set_uid' => $combine['new_uid'], 'where_uid' => $combine['old_uid']));
+    }
+
+    /**
+     * 检测用户有效性
+     *
+     * @return mixed
+     */
+    public function check($state = true)
+    {
+        $signature = Dever::input('signature');
+        $user = Dever::checkLogin($signature, $state);
+        if ($state && !isset($user['uid'])) {
+            Dever::alert('user error');
+        }
+        if (isset($user['uid']) && $user['uid']) {
+            return $user['uid'];
+        }
+        return -1;
+    }
+
+    public function getToken($request = array())
+    {
+        return http_build_query(Dever::token($request));
+    }
+
+    public function getUrl($method, $request = array())
+    {
+        return Dever::proxy($method, $this->getToken($request));
+    }
+
+    protected function info()
+    {
+        $data = $this->save->get(self::NAME);
+        return $data;
+    }
+
+    public function code($code = false, $image = true)
+    {
+        if ($code) {
+            $save = $this->save->get(self::CODE);
+            $state = $code == $save;
+            if ($state) {
+                //$this->save->un(self::CODE);
+            }
+            return $state;
+        }
+
+        if ($image) {
+            $code = new Code();
+            $code->create();
+            $code = $code->code;
+        } else {
+            $code = Dever::code();
+        }
+
+        $this->save->add(self::CODE, $code, 86400);
+
+        return $code;
+    }
+
+    protected function mcode($mobile, $code = false)
+    {
+        if ($code) {
+            $save = $this->save->get(self::MCODE);
+            return $mobile . '_' . $code == $save;
+        }
+
+        $day = date('Ymd', time());
+
+        # 检测当前手机号最新一次发送时间,不允许一分钟之内发送
+        $param['option_day'] = $day;
+        $param['option_mobile'] = $mobile;
+
+        # 检测当前手机号今天已经发送多少验证码了
+        $info = Dever::load('passport/code-total', $param);
+
+        if ($info >= 1) {
+            $check = Dever::load('passport/code-one', $param);
+
+            if ($check) {
+                if (time() - $check['cdate'] < Dever::config('base', 'project')->mobileCode['time']) {
+                    Dever::alert('请不要在一分钟之内申请多次验证码,请您稍后再试');
+                }
+            }
+        }
+
+        $total = Dever::config('base', 'project')->mobileCode['total'];
+        if ($info >= $total) {
+            Dever::alert('很抱歉,您已经申请获取验证码超过' . $total . '次,今天您已经无法获取验证码了,请您明天再来');
+        }
+
+        $code = new Code();
+        $code->createM();
+
+        # 记录当前的验证码
+        $insert['add_mobile'] = $mobile;
+        $insert['add_day'] = $day;
+        $insert['add_code'] = $code->mcode;
+        $id = Dever::load('passport/code-insert', $insert);
+
+        # 启动发送
+        $this->send($mobile, $insert['add_code'], $id);
+
+        $this->save->add(self::MCODE, $mobile . '_' . $code->mcode, Dever::config('base', 'project')->mobileCode['timeout']);
+
+        return $code->mcode;
+    }
+
+    public function send($mobile, $code, $id = false)
+    {
+        if (Dever::project('sms')) {
+            $send['skin'] = 'code';
+            $send['mobile'] = $mobile;
+            $send['param'] = array
+            (
+                'code' => $code
+            );
+            $send['param'] = Dever::json_encode($send['param']);
+            return Dever::load('sms/api.send', $send);
+        }
+        $url = Dever::config('base', 'project')->mobileCode['url'];
+
+        if (!$url) {
+            return;
+        }
+
+        $content = Dever::config('base', 'project')->mobileCode['body'];
+
+        $content = $this->replace($content, $mobile, $code);
+
+        parse_str($content, $param);
+
+        $type = Dever::config('base', 'project')->mobileCode['method'];
+        $json = Dever::config('base', 'project')->mobileCode['json'];
+        $header = Dever::config('base', 'project')->mobileCode['header'];
+
+        return Dever::curl($url, $param, $type, $json, $header);
+    }
+
+    private function replace($content, $mobile = '', $code = '')
+    {
+        $skin = Dever::config('base', 'project')->mobileCode['skin'];
+        $skin_key = Dever::input('skin', 'code');
+        if (isset($skin[$skin_key])) {
+            $skin = $skin[$skin_key];
+        } else {
+            $skin = array_shift($skin);
+        }
+
+        $config = array('{code}', '{mobile}', '{sign}', '{skin}', '{param}');
+        $replace = array($code, $mobile, Dever::config('base', 'project')->mobileCode['sign'], $skin);
+        return str_replace($config, $replace, $content);
+    }
+
+    protected function refer($state = false)
+    {
+        $refer = Dever::input('refer');
+
+        $project = 'main';
+
+        if ($refer) {
+            if (!strstr($refer, 'http://')) {
+                $refer = Encrypt::decode($refer);
+            }
+            
+            /*
+            $url = parse_url(Encrypt::decode($refer));
+            $url['path'] = preg_replace('/^\//', '', $url['path']);
+            if (!isset($url['query'])) {
+                $url['query'] = '';
+            }
+
+            if (Uri::$type == '?') {
+                $refer = Dever::url(str_replace($url['path'] . Uri::$type, '', $url['query']), $project);
+            } else {
+                $refer = Dever::url($url['path'] . '?' . $url['query'], $project);
+            }
+            */
+            
+        } else {
+            $refer = Dever::url('home', $project);
+        }
+
+        $param = Dever::input('param');
+
+        if ($param) {
+            $refer .= '&' . $param;
+        }
+
+        if ($state) {
+            return $refer;
+        }
+        Dever::out($refer);
+    }
+
+    protected function save($user)
+    {
+        if (is_numeric($user)) {
+            $user = Dever::load('passport/user-one', $user);
+        }
+
+        if ($user && is_array($user)) {
+            if (Dever::mobile()) {
+                $time = 30;
+            } else {
+                $time = 7;
+            }
+            $this->save->add(self::NAME, $user, 3600 * 24 * $time);
+
+            $user['signature'] = Dever::login($user['id']);
+
+            if (Dever::config('base', 'project')->regAction) {
+                Dever::load(Dever::config('base', 'project')->regAction, $user);
+            }
+
+            return $user;
+        }
+    }
+
+    public function createRefer()
+    {
+        return 'refer=' . Encrypt::encode(Dever::url(false, 'main'));
+    }
+
+    protected function saveSex($sex)
+    {
+        if ($sex || $sex == 0) {
+            $config_sex = Dever::config('base', 'project')->sex;
+            if (isset($config_sex[$sex])) {
+                $sex = $config_sex[$sex];
+            } else {
+                if ($sex == '男') {
+                    $sex = 1;
+                } elseif ($sex == '女') {
+                    $sex = 2;
+                } elseif ($sex == '未知') {
+                    $sex = 3;
+                }
+            }
+        }
+        return $sex;
+    }
+
+    protected function saveAvatar($value)
+    {
+        if (!$value) {
+            return '';
+        }
+        $value = Dever::pic($value);
+        $base = Dever::data();
+        $date = explode('-', date("Y-m-d"));
+        if (is_array($value)) {
+            $user = $value[1];
+            $value = $value[0];
+
+            if (is_array($value)) {
+                $name = md5($value['tmp_name'] . rand(0, 100) . microtime());
+                $path = 'avatar/' . $date[0] . '/' . $date[1] . '/' . $date[2] . '/';
+                $ext = '.jpg';
+                $temp = Dever::path($base, $path . $name . $ext);
+
+                move_uploaded_file($value['tmp_name'], $temp);
+
+                $value = $temp;
+            }
+        }
+        //$result = Dever::$global['host']['img'] . 'chead.jpg';
+        if ($value) {
+            # 裁图
+            $handle = new Img();
+
+            $size = '200_200_2';
+
+            $user = isset($user) && $user ? $user : $this->init();
+            if ($user && isset($user['id']) && $user['id']) {
+                $name = md5($user['id']);
+            } else {
+                $name = md5($value . rand(0, 100) . microtime());
+            }
+
+            $path = 'avatar/' . $date[0] . '/' . $date[1] . '/' . $date[2] . '/';
+            $ext = '.jpg';
+            $file = Dever::path($base, $path . $name . $ext);
+            $temp = $file . '.temp.jpg';
+
+            //$value = Dever::curl($value);
+            //file_put_contents($temp, file_get_contents($value));
+
+            $file = $handle->thumb($value, $size, true, $file);
+            if ($file) {
+                $result = str_replace('/upload/', '/', Dever::config('host')->uploadRes . $path . $name . $ext);
+            } else {
+                $result = $value;
+            }
+        }
+
+        return $result;
+    }
+}

+ 107 - 0
package/passport/lib/Code.php

@@ -0,0 +1,107 @@
+<?php
+namespace Passport\Lib;
+
+use Dever;
+
+class Code
+{
+    private $width;
+
+    private $height;
+
+    public $code;
+
+    public $mcode;
+
+    public $string;
+
+    private $image;
+
+    public function __construct($width = '160', $height = '30')
+    {
+        $this->width = $width;
+        $this->height = $height;
+    }
+
+    public function create()
+    {
+        header("Content-type: image/png");
+        $this->createCode();
+        $this->createImage();
+        $this->createPix();
+        $this->write();
+        imagepng($this->image);
+        imagedestroy($this->image);
+    }
+
+    public function createM()
+    {
+        $len = isset(Dever::config('base', 'project')->mobileCode['length']) ? Dever::config('base', 'project')->mobileCode['length'] : 4;
+        $this->createRand($len);
+    }
+
+    private function createImage()
+    {
+        $this->image = @imagecreate($this->width, $this->height);
+        $back = imagecolorallocate($this->image, 255, 255, 255);
+        $border = imagecolorallocate($this->image, 0, 0, 0);
+        imagefilledrectangle($this->image, 0, 0, $this->width - 1, $this->height - 1, $back);
+        imagerectangle($this->image, 0, 0, $this->width - 1, $this->height - 1, $border);
+    }
+
+    private function createPix()
+    {
+        for ($i = 0; $i <= 200; $i++) {
+            imagesetpixel($this->image, rand(2, $this->width), rand(2, $this->height), imagecolorallocate($this->image, rand(0, 255), rand(0, 255), rand(0, 255)));
+        }
+    }
+
+    public function createRand($length)
+    {
+        $this->mcode = null;
+        $str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
+        $str = '0123456789';
+        $max = strlen($str) - 1;
+
+        for ($i = 0; $i < $length; $i++) {
+            $this->mcode .= $str[rand(0, $max)]; //rand($min,$max)生成介于min和max两个数之间的一个随机整数
+        }
+    }
+
+    private function createCode()
+    {
+        $cal = array
+            (
+            array('+', '+'),
+            array('-', '-'),
+            //array('*', '乘以'),
+            //array('/', '除以'),
+        );
+        $index = array_rand($cal);
+
+        $m1 = rand(1, 100);
+        $m2 = rand(1, 100);
+
+        $this->string = $m1 . $cal[$index][1] . $m2 . '';
+
+        $this->code = '$this->code = ' . $m1 . $cal[$index][0] . $m2 . ';';
+
+        eval($this->code);
+    }
+
+    private function write()
+    {
+        $length = strlen($this->string);
+        for ($i = 0; $i < $length; $i++) {
+            $bg_color = imagecolorallocate($this->image, rand(0, 255), rand(0, 128), rand(0, 255));
+            $x = floor($this->width / $length) * $i;
+            $y = rand(0, $this->height - 15);
+            imagechar($this->image, rand(5, 5), $x + 5, $y, $this->string[$i], $bg_color);
+        }
+    }
+
+    public function __destruct()
+    {
+        unset($this->width, $this->height, $this->image);
+    }
+}

+ 35 - 0
package/passport/lib/Cron.php

@@ -0,0 +1,35 @@
+<?php
+namespace Passport\Lib;
+
+use Dever;
+
+class Cron
+{
+    public function combine_api()
+    {
+
+    }
+	# 定时合并
+    public function combine()
+    {
+        $combine = Dever::project('combine');
+        if ($combine) {
+        	$where['status'] = 1;
+        	$data = Dever::db('passport/combine')->state($where);
+
+        	if ($data) {
+        		foreach ($data as $k => $v) {
+        			//$drop = implode(',', $v['old_uid']);
+                    $drop = $v['old_uid'];
+            		Dever::load('combine/lib/core.handle?uid=' . $v['new_uid'] . '&drop=' . $drop);
+
+            		$update['where_id'] = $v['id'];
+            		$update['status'] = 2;
+            		Dever::db('passport/combine')->update($update);
+        		}
+        	}
+            //Dever::daemon('lib/core.handle?uid=' . $cur . '&drop=' . $drop, 'combine');
+        }
+        return 'ok';
+    }
+}

+ 58 - 0
package/passport/lib/Email.php

@@ -0,0 +1,58 @@
+<?php
+namespace Passport\Lib;
+
+use Dever;
+use Dever\Session\Oper as Save;
+
+class Email
+{
+	public function forget()
+	{
+		$email = Dever::input('email');
+		$code = Dever::input('code');
+		$email = base64_decode($email);
+		$config = Dever::config('base', 'project')->email['forget'];
+		$title = $config['title'];
+		$content = $config['content'];
+
+		$signature = Dever::encode($email . '|||' . $code);
+
+		$link = Dever::url($config['link'] . '?email='.$email . '&signature=' . $signature);
+		$content = str_replace('{link}', $link, $content);
+		$this->send($email, $title, $content);
+	}
+
+	public function send($email, $title, $content)
+    {
+        $user = Dever::db('passport/user')->one(array('email' => $email));
+        if (!$user) {
+        	Dever::alert('该邮箱还未注册');
+        }
+        $config = Dever::config('base', 'project')->email;
+
+        Dever::apply('src/PHPMailer', 'email');
+        Dever::apply('src/Exception', 'email');
+        Dever::apply('src/SMTP', 'email');
+        $mail = new \PHPMailer\PHPMailer\PHPMailer();
+
+        $mail->isSMTP();
+        //$mail->SMTPDebug = 2;
+        $mail->CharSet = 'UTF-8';
+        $mail->Host = $config['smtp'];
+        $mail->Port = 465;
+        $mail->SMTPSecure = 'ssl';
+        $mail->SMTPAuth = true;
+        $mail->Username = $config['username'];
+        $mail->Password = $config['password'];
+        $mail->setFrom($config['from'][0], $config['from'][1]);
+        $mail->addAddress($user['email'], $user['username']);
+        $mail->Subject = "=?utf-8?B?" . base64_encode($title) . "?=";
+        $mail->Body = $content;
+        //$mail->addAttachment($file);
+        if (!$mail->send()) {
+            Dever::alert("Mailer Error: " . $mail->ErrorInfo);
+        } else {
+            return 'ok';
+        }
+    }
+}

+ 76 - 0
package/passport/lib/Manage.php

@@ -0,0 +1,76 @@
+<?php
+namespace Passport\Lib;
+
+use Dever;
+
+class Manage
+{
+	# 同步将其他地方的分类更新为system
+    public function updateSystem($id, $name, $param)
+    {
+    	$name = Dever::param('name', $param);
+    	$data['name'] = $name;
+        $info = Dever::db('passport/system')->one($id);
+        if (!$info) {
+        	Dever::db('passport/system')->insert($data);
+        } else {
+        	$data['where_id'] = $info['id'];
+            $data['state'] = Dever::param('state', $param);
+            if (!$name) {
+                unset($data['name']);
+            };
+        	Dever::db('passport/system')->update($data);
+        }
+        return $info;
+    }
+
+    public function show($id)
+    {
+        $db = Dever::db('passport/user');
+        $user = $db->one($id);
+
+        $config = $db->config;
+
+        if ($user['avatar']) {
+            $table['头像'] = '<img src="'.$user['avatar'].'" width="150" />';
+        }
+
+        if ($user['area']) {
+            $table['地区'] = $user['area'];
+        }
+
+        if ($user['address']) {
+            $table['详细地址'] = $user['address'];
+        }
+
+        if ($user['source_type']) {
+            $table['来源'] = $config['source_type'][$user['source_type']];
+        }
+
+        if ($user['profession']) {
+            $profession = Dever::db('passport/profession')->one($user['profession']);
+            $table['职业'] = $profession['name'];
+        }
+
+        if ($user['sex']) {
+            $table['性别'] = $config['sex'][$user['sex']];
+        }
+
+        if ($user['wechat']) {
+            $table['微信号'] = $user['wechat'];
+        }
+
+        if ($user['email']) {
+            $table['邮箱'] = $user['email'];
+        }
+
+        if (Dever::project('invite')) {
+            $invite = Dever::db('invite/code')->one(array('uid' => $user['id']));
+            if ($invite) {
+                $table['邀请码'] = $invite['value'];
+            }
+        }
+
+        return Dever::table($table);
+    }
+}

+ 38 - 0
package/passport/src/Api.php

@@ -0,0 +1,38 @@
+<?php
+namespace Passport\Src;
+
+use Dever;
+use Passport\Lib\Base;
+
+class Api
+{
+    private $user;
+
+    public function info($uid)
+    {
+        $info = Dever::db('passport/user')->one($uid);
+        if ($info) {
+        	$info['name'] = '';
+        	if ($info['truename']) {
+	        	$info['name'] = $info['truename'];
+	        } elseif ($info['username']) {
+	        	$info['name'] = $info['username'];
+	        }
+
+            if ($info['area']) {
+                $info['add'] = $info['name'] . '('.$info['area'].')';
+            } else {
+                $info['add'] = $info['name'] . '(未知)';
+            }
+        }
+        
+        return $info;
+    }
+
+    # 测试合并
+    public function test_combine()
+    {
+        $base = new Base;
+        $base->combine(3, 321313);
+    }
+}

+ 209 - 0
package/passport/src/App.php

@@ -0,0 +1,209 @@
+<?php
+namespace Passport\Src;
+
+use Dever;
+use Passport\Lib\Base;
+
+class App extends Base
+{
+    /**
+     * 更新用户信息
+     *
+     * @return mixed
+     */
+    public function update()
+    {
+        $uid = $this->check();
+        $name = Dever::input('username');
+        $avatar = Dever::input('avatar');
+        $sex = Dever::input('gender');
+        $city = Dever::input('city');
+        $mobile = Dever::input('mobile');
+        $province = Dever::input('province');
+        $country = Dever::input('country');
+
+        $info = Dever::load('passport/user-one', $uid);
+        if ($info) {
+            $update['set_username'] = $name;
+            $update['set_avatar'] = $avatar;
+            $update['set_sex'] = $sex;
+            $update['set_city'] = $city;
+            $update['set_province'] = $province;
+            $update['set_country'] = $country;
+            if ($country && $province && $city) {
+            	$update['set_area'] = $country . ',' . $province . ',' . $city;
+            }
+            
+            $update['where_id'] = $uid;
+            Dever::load('passport/user-update', $update);
+        } else {
+            Dever::alert('无效的用户id,请重新登录');
+        }
+
+        $result = Dever::db('passport/user')->one($uid);
+        if ($name) {
+            $result['username'] = $name;
+        }
+        if ($avatar) {
+            $result['avatar'] = $avatar;
+        }
+        if ($sex) {
+            $result['sex'] = $sex;
+        }
+        if ($city) {
+            $result['city'] = $city;
+        }
+        if ($province) {
+            $result['province'] = $province;
+        }
+        if ($country) {
+            $result['country'] = $country;
+        }
+        if ($country && $province && $city) {
+            $result['area'] = $update['set_area'];
+        }
+        
+        $result['uid'] = $uid;
+        $result['signature'] = Dever::login($uid);
+
+        return $result;
+    }
+
+    /**
+     * 注册用户信息:app端已经拿到了openid了
+     *
+     * @return mixed
+     */
+    public function wechat_reg()
+    {
+        $user = array();
+        $user['temp'] = 2;
+        $user['username'] = Dever::input('username');
+        $user['avatar'] = Dever::input('avatar');
+        $user['sex'] = Dever::input('gender');
+        $user['city'] = Dever::input('city');
+        $user['province'] = Dever::input('province');
+        $user['country'] = Dever::input('country');
+        
+
+        $data = array();
+        $data['openid'] = Dever::input('openid');
+        $data['unionid'] = Dever::input('unionid');
+        $data['access_token'] = Dever::input('access_token');
+        $data['refresh_token'] = Dever::input('refresh_token');
+        $data['expires_in'] = Dever::input('expires_in');
+
+        $account = Dever::input('account', 1);
+        $system = Dever::input('system', 1);
+        $source_type = Dever::input('source_type');
+        $source = Dever::input('source');
+
+        $result = $this->wechat($data, $user, $account, $system, $source_type, $source);
+
+        if (isset($result['uid']) && $result['uid']) {
+            # 记录app登录日志
+            $appData = array('uid' => $result['uid'], 'source_type' => $source_type);
+            $app = Dever::db('passport/app')->one($appData);
+            if (!$app) {
+                $appData['system_id'] = $system;
+                Dever::db('passport/app')->insert($appData);
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * 生成用户或者登录
+     *
+     * @return int
+     */
+    public function login()
+    {
+    	$mobile = Dever::input('mobile');
+    	$code = Dever::input('mcode');
+        $system = Dever::input('system', 1);
+    	$source_type = Dever::input('source_type', 'ios');
+
+        # 添加测试账号
+        if ($mobile == '18710005124') {
+            
+        } else {
+            $mobile = Dever::load('passport/reg')->checkMobileExists(false, -1);
+        }
+    	
+
+        $uid = false;
+        $info = Dever::load('passport/user-one', array('mobile' => $mobile));
+        if (!$info) {
+            $data['username'] = Dever::hide($mobile);
+            $data['mobile'] = $mobile;
+            $data['system'] = $system;
+            $data['source_type'] = $source_type;
+            $uid = $this->reg($source_type, $data);
+
+            Dever::score($uid, 'mobile_reg', '手机号注册');
+        } else {
+            $uid = $this->combine($info['id'], $mobile, 'mobile');
+        }
+
+        # 记录app登录日志
+        $appData = array('uid' => $uid, 'source_type' => $source_type);
+        $app = Dever::db('passport/app')->one($appData);
+        if (!$app) {
+            $appData['system_id'] = $system;
+        	Dever::db('passport/app')->insert($appData);
+        }
+
+        $result = Dever::db('passport/user')->one($uid);
+        $result['uid'] = $uid;
+        $result['signature'] = Dever::login($uid);
+        return $result;
+    }
+
+    /**
+     * uuid登录
+     *
+     * @return int
+     */
+    public function login_uuid()
+    {
+        # 这里后续要加密
+        $uuid = Dever::input('uuid');
+        $system = Dever::input('system', 1);
+        $source_type = Dever::input('source_type', 'applet');
+
+        $appData = array('uuid' => $uuid, 'source_type' => $source_type);
+        $app = Dever::db('passport/app')->one($appData);
+        if (!$app) {
+            $user['add_username'] = '';
+            $user['add_bind'] = 2;
+            $user['add_temp'] = 1;
+            $user['add_source_type'] = $source_type;
+            $user['add_system_id'] = $system;
+            $uid = Dever::load('passport/user-insert', $user);
+            $this->createUsername($uid, '', true);
+
+            $appData['uid'] = $uid;
+            $appData['system_id'] = $system;
+            Dever::db('passport/app')->insert($appData);
+        } else {
+            $uid = $app['uid'];
+        }
+
+        $result = Dever::db('passport/user')->one($uid);
+        $result['uid'] = $uid;
+        $result['signature'] = Dever::login($uid);
+        return $result;
+    }
+
+    //获取用户信息
+    public function user() {
+        $uid = $this->check();
+        $data=Dever::db('passport/user')->one($uid);
+        if(!$data['pic']){
+                $data['pic']=DEVER_APP_HOST . '../data/upload/pic.png';
+        }
+        return $data;
+    }
+}

+ 382 - 0
package/passport/src/Applet.php

@@ -0,0 +1,382 @@
+<?php
+namespace Passport\Src;
+
+use Dever;
+use Passport\Lib\Base;
+
+# 小程序
+
+class Applet extends Base
+{
+    private $cache = 'applet_sessionKey_';
+
+    public function init()
+    {
+        $uid = $this->check();
+        $user = Dever::load('passport/user-one', $uid);
+
+        return $user;
+    }
+
+    /**
+     * 用户绑定 生成用户信息
+     *
+     * @return mixed
+     */
+    public function bind()
+    {
+        $create = Dever::input('create', 2);
+        $data = $this->getLoginInfo();
+
+        if ($create == 1) {
+            # 未授权,生成临时用户,针对有的项目,不需要授权,但是还要生成用户
+            $data = $this->create($data, false);
+        }
+
+        return $data;
+    }
+
+    /**
+     * 一次性登录:通过code或者openid、sessionkey来注册用户,此时已经授权,可以直接拿到unioinid
+     *
+     * @return mixed
+     */
+    public function login()
+    {
+        $data = $this->getLoginInfo();
+
+        $data += $this->getWechatData($data['session_key']);
+
+        $data['username'] = Dever::input('nickname');
+        $data['avatar'] = Dever::input('avatarurl');
+        $data['sex'] = Dever::input('gender');
+        $data['city'] = Dever::input('city');
+        //$data['mobile'] = Dever::input('mobile');
+        $data['province'] = Dever::input('province');
+        $data['country'] = Dever::input('country');
+
+        $result = $this->create($data);
+
+        return $result;
+    }
+
+    /**
+     * 更新用户信息
+     *
+     * @return mixed
+     */
+    public function update()
+    {
+        $uid = $this->check();
+        $vid = Dever::input('vid');
+        $info = Dever::db('passport/user')->one($uid);
+        if ($info) {
+            if ($info['temp'] == 1) {
+                # 针对未授权,生成临时用户的用户进行设置积分
+                Dever::score($uid, 'bind_wechat', '用户微信授权');
+            }
+            $data['temp'] = 2;
+            $data['username'] = Dever::input('nickname');
+            $data['avatar'] = Dever::input('avatarurl');
+            $data['sex'] = Dever::input('gender');
+            $data['city'] = Dever::input('city');
+            $data['province'] = Dever::input('province');
+            $data['country'] = Dever::input('country');
+
+            if ($data['sex'] == 1) {
+                $data['sex'] = 1;
+            } elseif ($data['sex'] == 2) {
+                $data['sex'] = 2;
+            } else {
+                $data['sex'] = 3;
+            }
+            $this->updateUser($uid, $data);
+        } else {
+            Dever::alert('无效的用户id,请重新登录');
+        }
+
+        $result['vid'] = $vid;
+        $result['uid'] = $uid;
+        $result['signature'] = Dever::login($uid);
+
+        return $result;
+    }
+
+    /**
+     * 更新用户信息 手机号
+     *
+     * @return mixed
+     */
+    public function mobile()
+    {
+        $uid = $this->check();
+        $vid = Dever::input('vid');
+        $result = array();
+        $mobile = $phoneNumber = '';
+
+        $iv = Dever::input('iv');
+        $encryptedData = Dever::input('encryptedData');
+        
+        if ($iv && $encryptedData) {
+            $key = $this->cache . $vid;
+            $session_key = Dever::cache($key);
+            if (!$session_key) {
+                $vinfo = Dever::db('passport/wechat')->one($vid);
+                $session_key = $vinfo['session_key'];
+            }
+            
+            $data = $this->getWechatData($session_key);
+            if ($data && $data['mobile']) {
+                $mobile = $data['mobile'];
+                $phoneNumber = $data['phone'];
+            }
+        }
+
+        if ($mobile && $phoneNumber && $uid) {
+            $uid = $this->combine($uid, $mobile, 'mobile');
+
+            $info = Dever::load('passport/user-one', $uid);
+            $result['mobile'] = $mobile;
+            if ($info) {
+                if (!$info['mobile']) {
+                    Dever::score($uid, 'bind_mobile', '绑定手机号');
+                }
+                $update['mobile'] = $mobile;
+                $update['bind'] = 1;
+                $update['where_id'] = $uid;
+                Dever::db('passport/user')->update($update);
+
+                $state = Dever::config('base', 'project')->regSendSms;
+                if ($state) {
+                    Dever::setInput('skin', $state);
+                    $this->send($mobile, $uid);
+                }
+            } else {
+                Dever::alert('无效的用户id,请重新登录');
+            }
+        }
+
+        $result['vid'] = $vid;
+        $result['uid'] = $uid;
+        $result['signature'] = Dever::login($uid);
+
+        return $result;
+    }
+
+    /**
+     * 生成用户,返回uid
+     *
+     * @return int
+     */
+    public function create($data, $state = true)
+    {
+        $uid = false;
+        $data['system'] = Dever::input('system', 1);
+        $info = Dever::db('passport/wechat')->one(array('openid' => $data['openid']));
+
+        $wechat = array();
+        if (!$info) {
+            if (isset($data['unionid']) && $data['unionid']) {
+                $info = Dever::db('passport/wechat')->one(array('unionid' => $data['unionid']));
+                if (!$info) {
+                    $uid = false;
+                } else {
+                    # 判断用户是否存在,是否需要合并
+                    //$uid = $this->combine($info['uid'], $data['unionid']);
+                    $uid = $info['uid'];
+                }
+                $wechat['unionid'] = $data['unionid'];
+            }
+            if (!$uid) {
+                $uid = $this->reg('applet', $data);
+                if ($state) {
+                    Dever::score($info['id'], 'bind_wechat', '用户微信授权');
+                }
+            }
+             
+            $wechat['openid'] = $data['openid'];
+            $wechat['session_key'] = $data['session_key'];
+            $wechat['uid'] = $uid;
+            $wechat['type'] = 1;
+            $wechat['system_id'] = $data['system'];
+            $id = Dever::db('passport/wechat')->insert($wechat);
+
+            $key = $this->cache . $id;
+            $cache = Dever::cache($key, $data['session_key']);
+        } else {
+            $uid = $info['uid'];
+            $id = $info['id'];
+            /*
+            if (isset($data['unionid']) && $data['unionid']) {
+                # 判断用户是否存在,是否需要合并
+                $wechat['uid'] = $this->combine($uid, $data['unionid']);
+
+                if ($wechat['uid'] != $uid) {
+                    $uid = $wechat['uid'];
+                }
+            }
+            */
+
+            $key = $this->cache . $id;
+            $cache = Dever::cache($key, $data['session_key']);
+
+            if (!$cache) {
+                $wechat['session_key'] = $data['session_key'];
+            }
+
+            if ($wechat) {
+                $wechat['where_id'] = $id;
+                Dever::db('passport/wechat')->update($wechat);
+            }
+        }
+
+        $user = Dever::db('passport/user')->one($uid);
+
+        $result['vid'] = $id;
+        $result['uid'] = $uid;
+        $result['signature'] = Dever::login($uid);
+      
+        if (isset($user['mobile']) && $user['mobile']) {
+            $result['mobile'] = $user['mobile'];
+        }
+
+        return $result;
+    }
+
+    private function unionid($session_key)
+    {
+        $data = $this->decryptData($session_key);
+        if ($data && isset($data->unionId)) {
+            return $data->unionId;
+        }
+        
+        return false;
+    }
+
+    private function getWechatData($session_key)
+    {
+        $result = array();
+        $data = $this->decryptData($session_key);
+
+        $result['openid'] = '';
+        $result['unionid'] = '';
+        $result['mobile'] = '';
+        $result['phone'] = '';
+        if ($data && isset($data->openId)) {
+            $result['openid'] = $data->openId;
+            if (isset($data->unionId)) {
+                $result['unionid'] = $data->unionId;
+            }
+        }
+
+        if ($data && isset($data->phoneNumber)) {
+            if (isset($data->phoneNumber)) {
+                $result['phone'] = $data->phoneNumber;
+            }
+        }
+
+        if ($data && isset($data->purePhoneNumber)) {  
+            if (isset($data->purePhoneNumber)) {
+                $result['mobile'] = $data->purePhoneNumber;
+            }
+        }
+        
+        return $result;
+    }
+
+    private function decryptData($session_key)
+    {
+        $iv = Dever::input('iv');
+        $encryptedData = Dever::input('encryptedData');
+
+        if (!$iv || !$encryptedData) {
+            return false;
+        }
+        if (strlen($session_key) != 24) {
+            return false;
+        }
+        if (strlen($iv) != 24) {
+            return false;
+        }
+
+        $aesKey = base64_decode($session_key);
+
+        $aesIV = base64_decode($iv);
+
+        $aesCipher = base64_decode($encryptedData);
+
+        $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
+
+        $dataObj = json_decode($result);
+        if ($dataObj  == NULL) {
+            return false;
+        }
+        /*
+        $applet = Dever::config('base', 'project')->applet;
+        $appid = $applet['appid'];
+        if($dataObj->watermark->appid != $appid) {
+            return false;
+        }*/
+        return $dataObj;
+    }
+
+    private function getApplet()
+    {
+        $applet = Dever::config('base', 'project')->applet;
+        $project = false;
+        $system = Dever::input('system', 1);
+        if (Dever::project('token')) {
+            $project = Dever::db('token/project')->one($system);
+        }
+
+        if (!$project) {
+            if (isset($applet['project']) && $applet['project']) {
+                $project = Dever::db($applet['project'])->one($system);
+            }
+        }
+
+        if ($project) {
+            $applet['appid'] = $project['appid'];
+            $applet['secret'] = $project['secret'];
+        }
+
+        if (!$applet || !$applet['appid'] || !$applet['secret']) {
+            Dever::alert('错误的appid');
+        }
+
+        return $applet;
+    }
+
+    private function getLoginInfo()
+    {
+        $session_key = Dever::input('session_key');
+        if ($session_key) {
+            return array('session_key' => $session_key, 'openid' => $openid);
+        }
+        $applet = $this->getApplet();
+        $appid = $applet['appid'];
+        $secret = $applet['secret'];
+        $url = $applet['url'];
+        $code = Dever::input('code');
+        if (!$applet || !$applet['appid'] || !$applet['secret']) {
+            Dever::alert('错误的appid');
+        }
+
+        $url .= '?appid=' . $appid;
+        $url .= '&secret=' . $secret;
+        $url .= '&js_code=' . $code;
+        $url .= '&grant_type=authorization_code';
+
+        $data = Dever::curl($url);
+        Dever::log($data, 'passport_applet');
+        if (strstr($data, 'errcode')) {
+            Dever::alert($data);
+        }
+
+        //YzJkOThpRFhwZ1lQTF9mZl9hLVZjZnFXemJVenlYcDQ3d3JWekk0b1I4NjBBQ0Naejg4a0VQa0U=
+        //$data = '{"session_key":"aNAXk7nG\/DRYI\/G0KzJRsw==","openid":"oIZ895RZs2ZkywasoZIv6WavPZlQ"}';
+        $data = Dever::json_decode($data);
+
+        return $data;
+    }
+}

+ 75 - 0
package/passport/src/Login.php

@@ -0,0 +1,75 @@
+<?php
+namespace Passport\Src;
+
+use Dever;
+use Passport\Lib\Base;
+
+class Login extends Base
+{
+    public function test()
+    {
+        return Dever::login(-1);
+    }
+
+    public function quit()
+    {
+        if ($this->info()) {
+            $this->save->un(self::NAME);
+        }
+
+        $refer = Dever::input('refer', 1);
+
+        $home = Dever::url('home', 'main');
+        if ($refer == 2) {
+            $refer = $home;
+        } else {
+            $refer = isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] ? $_SERVER['HTTP_REFERER'] : Dever::url('home', 'main');
+        }
+
+        Dever::location($refer);
+    }
+
+    public function action()
+    {
+        $account = Dever::config('base', 'project')->account;
+
+        $param['option_' . $account] = Dever::input($account);
+
+        $password = sha1(Dever::input('password'));
+
+        $user = Dever::load('passport/user-login', $param);
+
+        if ($user && $password == $user['password']) {
+            $this->save($user);
+
+            $this->refer();
+        } else {
+            Dever::alert('您的账号或密码错误');
+        }
+    }
+
+    public function get()
+    {
+        return $this->info();
+    }
+
+    public function url()
+    {
+        return Dever::url('login?' . $this->createRefer(), 'main');
+    }
+
+    public function location()
+    {
+        return Dever::location($this->url());
+    }
+
+    public function oauth($url = false)
+    {
+        if (!$url) {
+            $url = Dever::url();
+        }
+        $link = Dever::url('get.request?refer=' . urlencode($url), 'oauth');
+
+        return $link;
+    }
+}

+ 392 - 0
package/passport/src/Reg.php

@@ -0,0 +1,392 @@
+<?php
+namespace Passport\Src;
+
+use Dever;
+use Passport\Lib\Base;
+
+# 所有手机发送短信操作,后续要独立成一个组件
+
+class Reg extends Base
+{
+    /**
+     * 获取图形验证码
+     * @return mixed
+     */
+    public function getCode()
+    {
+        return $this->code();
+    }
+
+    /**
+     * 获取手机随机验证码
+     * @return mixed
+     */
+    public function getMCode()
+    {
+        $mobile = $this->checkMobileExists(1, -1);
+
+        $msg = $this->getMcode_action($mobile);
+        return $msg;
+    }
+
+    private function getMcode_action($mobile)
+    {
+        $code = $this->mcode($mobile);
+        $msg = '验证码已发送至您的手机,请注意查收,十分钟之内有效';
+        $debug = Dever::config('base', 'project')->mobileCode['debug'];
+        if ($debug) {
+            $msg .= ':' . $code;
+        }
+        return $msg;
+    }
+
+    /**
+     * 获取手机随机验证码:未登录
+     * @return mixed
+     */
+    public function getMCodeReg()
+    {
+        $mobile = $this->checkMobileExists(1);
+
+        $msg = $this->getMcode_action($mobile);
+        return $msg;
+    }
+
+    /**
+     * 获取手机随机验证码:已经登录状态
+     * @return mixed
+     */
+    public function getMCodeLogin()
+    {
+        $mobile = $this->checkMobileExists(1, true);
+
+        $type = Dever::input('type', 'code');
+
+        if ($type == 'code') {
+            $msg = $this->getMcode_action($mobile);
+        } else {
+            $content = Dever::input('content');
+            $msg = $this->send($mobile, $content);
+        }
+        
+        return $msg;
+    }
+
+    /**
+     * 检测手机号是否注册
+     * @return mixed
+     */
+    public function checkMobileExist()
+    {
+        $param['option_mobile'] = $this->checkMobile();
+
+        $user = Dever::db('passport/user')->one($param);
+
+        if (!$user) {
+            Dever::alert('该手机号未注册');
+        }
+
+        return 'ok';
+    }
+
+    /**
+     * 检测图形验证码
+     * @return mixed
+     */
+    private function checkCode()
+    {
+        $code = Dever::input('code');
+        $code = $this->code($code);
+        if (!$code) {
+            Dever::alert('验证码输入错误');
+        }
+    }
+
+    /**
+     * 检测手机验证码
+     * @return mixed
+     */
+    private function checkMCode($mobile)
+    {
+        $code = Dever::input('mcode');
+        if (!$code) {
+            Dever::alert('请输入验证码');
+        }
+        $code = $this->mcode($mobile, $code);
+        if (!$code) {
+            Dever::alert('验证码输入错误');
+        }
+    }
+
+    /**
+     * 验证手机号
+     * @return mixed
+     */
+    private function checkMobile()
+    {
+        $rule = Dever::rule('mobile');
+
+        $mobile = Dever::input('mobile');
+
+        if (!$mobile) {
+            Dever::alert('手机号不能为空');
+        }
+        if (!preg_match($rule, $mobile)) {
+            Dever::alert('请填写正确的手机号');
+        }
+
+        return $mobile;
+    }
+
+    /**
+     * 验证手机号是否注册
+     * @return mixed
+     */
+    public function checkMobileExists($state = false, $login = false, $table = 'passport/user')
+    {
+        $param['option_mobile'] = $this->checkMobile();
+
+        if ($state && $state == 1) {
+
+        } else {
+            $this->checkMCode($param['option_mobile']);
+        }
+
+        if ($login != -1) {
+            $user = Dever::db($table)->one($param);
+            if ($login == false && $user) {
+                Dever::alert('该手机号已经注册');
+            } elseif ($login == true && !$user) {
+                Dever::alert('该手机号未注册');
+            }
+        }
+
+        return $param['option_mobile'];
+    }
+
+    /**
+     * 验证邮箱
+     * @return mixed
+     */
+    private function checkEmail()
+    {
+        $rule = Dever::rule('email');
+
+        $email = Dever::input('email');
+
+        if (!$email) {
+            Dever::alert('邮箱不能为空');
+        }
+        if (!preg_match($rule, $email)) {
+            Dever::alert('请填写正确的邮箱');
+        }
+
+        $check = Dever::config('base', 'project')->passportCheckEmail;
+
+        if ($check && !strstr($email, $check[0])) {
+            Dever::alert($check[1]);
+        }
+
+        return $email;
+    }
+
+    /**
+     * 验证邮箱是否注册
+     * @return mixed
+     */
+    public function checkEmailExists($state = false, $login = false, $table = 'passport/user')
+    {
+        $param['option_email'] = $this->checkEmail();
+
+        if ($state && $state == 1) {
+
+        } else {
+            $this->checkCode($param['option_email']);
+        }
+
+        if ($login != -1) {
+            $user = Dever::db($table)->one($param);
+            if ($login == false && $user) {
+                Dever::alert('该邮箱已经注册');
+            } elseif ($login == true && !$user) {
+                Dever::alert('该邮箱未注册');
+            }
+        }
+
+        return $param['option_email'];
+    }
+
+    public function action()
+    {
+        $account = Dever::config('base', 'project')->account;
+        $code = Dever::config('base', 'project')->nocode ? Dever::config('base', 'project')->nocode : state;
+        $baccount = ucfirst($account);
+        $method = 'check' . $baccount . 'Exists';
+
+        $param['option_' . $account] = $this->$method($code);
+
+        if ($param['option_' . $account]) {
+            $param['add_' . $account] = $param['option_' . $account];
+            $param['add_username'] = Dever::input('username');
+            $param['add_password'] = Dever::input('password');
+            $sex = Dever::input('sex');
+            $wechat = Dever::input('wechat');
+            $profession = Dever::input('profession');
+            $truename = Dever::input('truename');
+            $area_id = Dever::input('area_id');
+            $area = Dever::input('area');
+
+            if ($sex) {
+                $param['add_sex'] = Dever::input('sex');
+            }
+
+            if ($wechat) {
+                $param['add_wechat'] = Dever::input('wechat');
+            }
+
+            if ($profession) {
+                $param['add_profession'] = Dever::input('profession');
+            }
+
+            if ($truename) {
+                $param['add_truename'] = Dever::input('truename');
+            }
+
+            if ($area) {
+                $param['add_area'] = Dever::input('area');
+            }
+
+            if ($area_id) {
+                $param['add_area_id'] = Dever::input('area_id');
+            }
+            
+            $cpassword = Dever::input('cpassword');
+
+            if (!$param['add_username']) {
+                Dever::alert('昵称不能为空');
+            }
+
+            if (!$param['add_password']) {
+                Dever::alert('密码不能为空');
+            }
+
+            if ($cpassword != $param['add_password']) {
+                Dever::alert('确认密码不正确');
+            }
+
+            if ($param['add_sex']) {
+                $config_sex = Dever::config('base', 'project')->sex;
+                if (isset($config_sex[$param['add_sex']])) {
+                    $param['add_sex'] = $config_sex[$param['add_sex']];
+                } else {
+                    if ($sex == '男') {
+                        $param['add_sex'] = 1;
+                    } elseif ($sex == '女') {
+                        $param['add_sex'] = 2;
+                    } elseif ($sex == '未知') {
+                        $param['add_sex'] = 3;
+                    }
+                }
+            }
+
+            if ($param['add_username'] == $param['add_' . $account]) {
+                $param['add_username'] = substr_replace($param['add_username'],'****',3,4);
+            }
+
+            $id = Dever::load('passport/user-insert', $param);
+
+            if ($id > 0) {
+                $this->save($id);
+                $this->refer();
+            } else {
+                Dever::alert('注册失败');
+            }
+        }
+    }
+
+    public function forget_email()
+    {
+        #发送邮件
+        $email = Dever::input('email');
+        if ($email) {
+            if (!preg_match(Dever::rule('email'), $email)) {
+                Dever::alert('请输入正确的邮箱');
+            }
+
+            $method = 'checkEmailExists';
+
+            $this->$method(1, 1);
+
+            $code = $this->code(false, false);
+
+            $email = base64_encode($email);
+            //return Dever::load('passport/lib/email')->forget($email, $code);
+            Dever::daemon('lib/email.forget?email=' . $email . '&code=' . $code, 'passport');
+
+            $refer = $this->refer(true);
+            return $refer . '||邮件已经发送成功!请到您的邮箱里查看。';
+        } else {
+            Dever::alert('请输入邮箱');
+        }
+    }
+
+    public function forget()
+    {
+        $signature = Dever::input('signature');
+        if (!$signature) {
+            Dever::alert('您的验证信息已失效,请重新发送验证邮件');
+        }
+
+        $signature = Dever::decode($signature);
+        $temp = explode('|||', $signature);
+        $code = $temp[1];
+
+        $state = $this->code($code);
+        if (!$state) {
+            Dever::alert('您的验证信息已失效,请重新发送验证邮件');
+        }
+        $account = Dever::config('base', 'project')->account;
+        $code = Dever::config('base', 'project')->nocode ? Dever::config('base', 'project')->nocode : state;
+        $baccount = ucfirst($account);
+        $method = 'check' . $baccount . 'Exists';
+
+        $param['option_' . $account] = $this->$method($code, true);
+
+
+        $user = Dever::load('passport/user-one', $param);
+
+        if (!$user) {
+            Dever::alert('该账号还未注册,请先注册');
+        } else {
+            $param['set_password'] = Dever::input('password');
+            $cpassword = Dever::input('cpassword');
+
+            if (sha1($param['set_password']) == $user['password']) {
+                Dever::alert('您的新密码和旧密码相同');
+            }
+
+            if (!$param['set_password']) {
+                Dever::alert('新密码不能为空');
+            }
+
+            if ($param['set_password'] != $cpassword) {
+                Dever::alert('确认密码不正确');
+            }
+            $id = $param['where_id'] = $user['id'];
+
+            Dever::load('passport/user-update', $param);
+
+            if ($id > 0) {
+                $refer = $this->refer(true);
+                return $refer . '||您已经成功修改密码';
+            } else {
+                Dever::alert('修改失败');
+            }
+        }
+    }
+
+    public function url()
+    {
+        return Dever::url('reg?' . $this->createRefer(), 'main');
+    }
+}

+ 86 - 0
package/passport/src/User.php

@@ -0,0 +1,86 @@
+<?php
+namespace Passport\Src;
+
+use Dever;
+use Passport\Lib\Base;
+
+class User extends Base
+{
+    private $user;
+    public function __construct()
+    {
+        parent::__construct();
+        $this->init();
+    }
+
+    public function init()
+    {
+        if (!$this->user) {
+            $this->user = $this->info();
+        }
+
+        return $this->user;
+    }
+
+    public function data()
+    {
+        if ($this->user) {
+            $this->user['link'] = Dever::url('user/info', 'main');
+            $this->user['link'] = Dever::url('forum/list?uid=' . $this->user['id'], 'main');
+        }
+        return $this->user;
+    }
+
+    public function checkLogin()
+    {
+        if (!$this->user) {
+            Dever::alert('请先登录', true);
+        }
+    }
+
+    public function updateInfo()
+    {
+        $this->checkLogin();
+
+        //$update['set_mobile'] = Dever::input('mobile');
+        $update['set_username'] = Dever::input('username');
+        $update['set_avatar'] = Dever::input('avatar') ? Dever::input('avatar') . '?v=' . time() : false;
+        $update['where_id'] = $this->user['id'];
+        $sex = Dever::input('sex', 0);
+        $update['set_sex'] = $this->saveSex($sex);
+        $update['set_avatar'] = $this->saveAvatar($update['set_avatar']);
+
+        Dever::load('passport/user-update', $update);
+
+        $this->user = $this->save($this->user['id']);
+
+        return true;
+    }
+
+    public function updateAvatar()
+    {
+        $this->checkLogin();
+
+        $update['set_avatar'] = Dever::input('avatar') ? Dever::input('avatar') . '?v=' . time() : false;
+        $update['where_id'] = $this->user['id'];
+
+        if ($update['set_avatar']) {
+            $update['set_avatar'] = $this->saveAvatar($update['set_avatar']);
+
+            Dever::load('passport/user-update', $update);
+
+            $this->user = $this->save($this->user['id']);
+        }
+
+        return true;
+    }
+
+    public function updateWeixin()
+    {
+        $this->checkLogin();
+
+        Dever::load('passport/user-update', array('where_id' => $this->user['id'], 'set_weixin' => 1));
+
+        return true;
+    }
+}

+ 4 - 0
package/pay/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'pay');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/qrcode/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'qrcode');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/score/index.php

@@ -0,0 +1,4 @@
+<?php 
+define('DEVER_PACKAGE', 'score');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/share/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'share');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/sms/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'sms');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/token/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'token');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');

+ 4 - 0
package/upload/index.php

@@ -0,0 +1,4 @@
+<?php
+define('DEVER_PACKAGE',  'upload');
+define('DEVER_APP_SETUP', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '../boot.php');