dever 4 年之前
当前提交
deec542d3c
共有 23 个文件被更改,包括 3661 次插入0 次删除
  1. 14 0
      LICENSE
  2. 2 0
      README.md
  3. 42 0
      api/main.php
  4. 93 0
      config/base.php
  5. 125 0
      database/app.php
  6. 94 0
      database/code.php
  7. 85 0
      database/combine.php
  8. 138 0
      database/profession.php
  9. 165 0
      database/system.php
  10. 494 0
      database/user.php
  11. 230 0
      database/wechat.php
  12. 8 0
      index.php
  13. 702 0
      lib/Base.php
  14. 107 0
      lib/Code.php
  15. 35 0
      lib/Cron.php
  16. 58 0
      lib/Email.php
  17. 76 0
      lib/Manage.php
  18. 38 0
      src/Api.php
  19. 209 0
      src/App.php
  20. 393 0
      src/Applet.php
  21. 75 0
      src/Login.php
  22. 392 0
      src/Reg.php
  23. 86 0
      src/User.php

+ 14 - 0
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
README.md

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

+ 42 - 0
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
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
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
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
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
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
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
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',
+		),
+	),
+);

+ 230 - 0
database/wechat.php

@@ -0,0 +1,230 @@
+<?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',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'account_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '所属账户',
+			'default' 	=> '1',
+			'desc' 		=> '所属账户',
+			'match' 	=> 'is_numeric',
+			//'option' 	=> $level,
+			//'update'	=> 'select',
+			'search'	=> 'fulltext',
+			'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
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');

+ 702 - 0
lib/Base.php

@@ -0,0 +1,702 @@
+<?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 = 'passportv6';
+
+    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 getSign($uid, $vid = false, $mobile = false)
+    {
+        if ($vid) {
+            $data['vid'] = $vid;
+        }
+
+        if ($mobile) {
+            $data['mobile'] = $mobile;
+        }
+        
+        $data['uid'] = $uid;
+        $data['signature'] = Dever::login($uid);
+
+        return $data;
+    }
+
+    # 注册用户
+    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'];
+            if ($account) {
+                $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'];
+            if ($account) {
+                $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
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
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
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
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 (isset($user['address']) && $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
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
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;
+    }
+}

+ 393 - 0
src/Applet.php

@@ -0,0 +1,393 @@
+<?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', 3);
+        $data = $this->getLoginInfo();
+
+        if ($create == 1) {
+            # 直接返回用户信息
+            $info = Dever::db('passport/wechat')->one(array('openid' => $data['openid']));
+            $data = array('uid' => false);
+            if ($info) {
+                //$user = Dever::db('passport/user')->one($uid);
+                $data = $this->getSign($info['uid'], $info['id']);
+            }
+        } elseif ($create == 2) {
+            # 未授权,会生成临时用户,针对有的项目,不需要授权,但是还要生成用户
+            $data = $this->create($data, false);
+        }
+
+        return $data;
+    }
+
+    /**
+     * 一次性登录:通过code或者openid、sessionkey来注册用户,此时已经授权,可以直接拿到unioinid
+     *
+     * @return mixed
+     */
+    public function login()
+    {
+        $data = array();
+        $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 = $this->getSign($uid, $vid);
+
+        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);
+
+        //$result = $this->getSign($uid, $vid);
+
+        if (isset($update['mobile']) && $update['mobile']) {
+            $result['mobile'] = $update['mobile'];
+        }
+
+        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 = $this->getSign($uid, $id);
+      
+        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
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
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
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;
+    }
+}