<?php
|
|
namespace app\api\model\user;
|
|
use app\common\model\page\CenterMenu as CenterMenuModel;
|
use think\facade\Cache;
|
use app\common\exception\BaseException;
|
use app\common\model\user\User as UserModel;
|
use app\api\model\plus\agent\Referee as RefereeModel;
|
use app\common\library\easywechat\AppWx;
|
use app\common\model\user\Grade as GradeModel;
|
use app\common\library\wechat\WxBizDataCrypt;
|
use app\common\model\settings\Setting as SettingModel;
|
use app\common\model\user\BalanceLog as BalanceLogModel;
|
use app\common\enum\user\balanceLog\BalanceLogSceneEnum;
|
use app\shop\model\user\PointsLog as PointsLogModel; // by lyzflash
|
use app\api\model\plus\team\Referee as TeamRefereeModel; // by lyzflash
|
use app\api\model\user\Card as CardModel;
|
use app\api\model\plus\coupon\UserCoupon as UserCouponModel;
|
use app\api\model\user\CardRecord as CardRecordModel;
|
use app\common\model\takeout\Commander as CommanderModel;
|
use app\common\model\takeout\Deliveryman as DeliverymanModel;
|
|
/**
|
* 用户模型类
|
*/
|
class User extends UserModel
|
{
|
private $token;
|
private $qy_access_token;
|
|
/**
|
* 隐藏字段
|
*/
|
protected $hidden = [
|
'open_id',
|
'is_delete',
|
'app_id',
|
'create_time',
|
'update_time'
|
];
|
|
/**
|
* 获取用户信息
|
*/
|
public static function getUser($token)
|
{
|
$userId = Cache::get($token);
|
return (new static())->where(['user_id' => $userId])->with(['address', 'addressDefault', 'grade', 'supplierUser', 'clerkUser'])->find();
|
}
|
|
/**
|
* 用户登录
|
*/
|
public function login($post)
|
{
|
// 微信登录 获取session_key
|
$app = AppWx::getApp();
|
$session = $app->auth->session($post['code']);
|
// 自动注册用户
|
$refereeId = isset($post['referee_id']) ? $post['referee_id'] : null;
|
$userInfo = json_decode(htmlspecialchars_decode($post['user_info']), true);
|
|
$reg_source = $post['source'];
|
$user_id = $this->register($session['openid'], $userInfo, $refereeId, $session, $reg_source);
|
// 生成token (session3rd)
|
$this->token = $this->token($session['openid']);
|
// 记录缓存, 7天
|
Cache::tag('cache')->set($this->token, $user_id, 86400 * 7);
|
return $user_id;
|
}
|
|
/**
|
* 企业微信
|
*/
|
public function qyLogin($post)
|
{
|
$AccessToken = $this->getAccessToken($post["app_id"]);//获取企业微信的AccessToken
|
if(empty($AccessToken)){
|
$this->error = '获取企业微信的AccessToken失败,请重试';
|
return false;
|
}
|
$url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_follow_user_list?access_token=".$AccessToken;
|
$result = curlPost($url);
|
$data = json_decode($result,true);
|
if(!empty($data) && $data["errcode"] == 0 && !empty($data["follow_user"])){
|
$follow_user = $data["follow_user"];
|
$url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user?access_token=".$AccessToken;
|
$senddata=[
|
"userid_list"=>$follow_user,
|
"cursor"=>'',
|
"limit"=>100,
|
];
|
$result_user = curlPost($url,json_encode($senddata));
|
$data_user = json_decode($result_user,true);
|
if(!empty($data_user) && $data_user["errcode"] == 0 && !empty($data_user["external_contact_list"])){
|
foreach ($data_user["external_contact_list"] as $val){
|
if(!empty($post["union_id"]) && !empty($val["external_contact"]["unionid"]) && $post["union_id"] == $val["external_contact"]["unionid"]){
|
$external_userid=$val["external_contact"]["unionid"];
|
break;
|
}
|
|
}
|
}
|
}
|
return empty($external_userid) ? '' : $external_userid;
|
}
|
|
/**
|
* 用户登录
|
*/
|
public function bindMobile($post)
|
{
|
try {
|
// 微信登录 获取session_key
|
$app = AppWx::getApp();
|
$iv = $post['iv'];
|
$encrypted_data = $post['encrypted_data'];
|
$pc = new WxBizDataCrypt($app['config']['app_id'], $post['session_key']);
|
$errCode = $pc->decryptData($encrypted_data, $iv, $data);
|
if ($errCode == 0) {
|
$data = json_decode($data, true);
|
$this->save([
|
'mobile' => $data['phoneNumber']
|
]);
|
return $data['phoneNumber'];
|
} else {
|
log_write('$errCode' . $errCode);
|
return false;
|
}
|
} catch (\Exception $e) {
|
$this->error = '获取手机号失败,请重试';
|
return false;
|
}
|
}
|
|
/**
|
* 获取token
|
*/
|
public function getToken()
|
{
|
return $this->token;
|
}
|
|
|
/**
|
* 生成用户认证的token
|
*/
|
private function token($openid)
|
{
|
$app_id = self::$app_id;
|
// 生成一个不会重复的随机字符串
|
$guid = \getGuidV4();
|
// 当前时间戳 (精确到毫秒)
|
$timeStamp = microtime(true);
|
// 自定义一个盐
|
$salt = 'token_salt';
|
return md5("{$app_id}_{$timeStamp}_{$openid}_{$guid}_{$salt}");
|
}
|
|
/**
|
* 获取企业微信的access_token
|
*/
|
private function qyAccessToken($name)
|
{
|
$corpid = "ww961c3c7eea2ee833";//企业ID
|
$corpsecret = "p8YF1yOSstdl1NkuYOIM6kM6PB4sjN5oGS9S5_2ILKY";//应用密钥
|
$url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=".$corpid."&corpsecret=".$corpsecret;
|
$result = curl($url);
|
$data = json_decode($result,true);
|
if(!empty($data) && $data["errcode"] == 0){
|
$qy_access_token = $data["access_token"];
|
// 记录缓存, 2个小时
|
Cache::tag('cache')->set($name, $qy_access_token, 7100);
|
return $qy_access_token;
|
}
|
return false;
|
}
|
/**
|
* 获取token
|
*/
|
public function getAccessToken($app_id)
|
{
|
$name = "access_token_".$app_id;
|
$AccessToken = Cache::get($name);//获取缓存
|
if(empty($AccessToken)){
|
$AccessToken = $this->qyAccessToken($name);//缓存过期重新获取
|
}
|
return $AccessToken;
|
}
|
|
/**
|
* 自动注册用户
|
*/
|
private function register($open_id, $data, $refereeId = null, $decryptedData = [], $reg_source = '')
|
{
|
//通过unionid查询用户是否存在
|
$user = null;
|
$data['union_id'] = '';
|
if (isset($decryptedData['unionid']) && !empty($decryptedData['unionid'])) {
|
$data['union_id'] = $decryptedData['unionid'];
|
$user = self::detailByUnionid($decryptedData['unionid']);
|
}
|
if (!$user) {
|
// 通过open_id查询用户是否已存在
|
$user = self::detail(['open_id' => $open_id]);
|
}
|
if ($user) {
|
$model = $user;
|
// 只修改union_id
|
$data = [
|
'union_id' => $data['union_id'],
|
];
|
} else {
|
$model = $this;
|
if($data['nickName'] == '微信用户'){
|
// 截取openid前8位
|
$data['nickName'] = substr($open_id, 0, 8);
|
}
|
$data['referee_id'] = $refereeId;
|
$data['reg_source'] = 'wx';
|
//默认等级
|
$data['grade_id'] = GradeModel::getDefaultGradeId();
|
}
|
$this->startTrans();
|
try {
|
// 保存/更新用户记录
|
if (!$model->save(array_merge($data, [
|
'open_id' => $open_id,
|
'app_id' => self::$app_id
|
]))
|
) {
|
throw new BaseException(['msg' => '用户注册失败']);
|
}
|
// if (!$user) {
|
// // 团队分红队员占位
|
// TeamRefereeModel::createRelation($model['user_id'], $refereeId);
|
// }
|
if (!$user && $refereeId > 0) {
|
// 记录推荐人关系
|
RefereeModel::createRelation($model['user_id'], $refereeId);
|
//更新用户邀请数量
|
(new UserModel())->setIncInvite($refereeId);
|
}
|
// 瑞和购物同步积分 by lyzflash
|
if (self::$app_id == 10027 && !$user) {
|
(new UserModel())->syncPoints($open_id);
|
}
|
$this->commit();
|
} catch (\Exception $e) {
|
$this->rollback();
|
throw new BaseException(['msg' => $e->getMessage()]);
|
}
|
return $model['user_id'];
|
}
|
|
/**
|
*统计被邀请人数
|
*/
|
public function getCountInv($user_id)
|
{
|
return $this->where('referee_id', '=', $user_id)->count('user_id');
|
}
|
|
/**
|
* 签到更新用户积分
|
*/
|
public function setPoints($user_id, $days, $sign_conf, $sign_date)
|
{
|
$rank = $sign_conf['ever_sign'];
|
if ($sign_conf['is_increase'] == 'true') {
|
if ($days >= $sign_conf['no_increase']) {
|
$days = $sign_conf['no_increase'] - 1;
|
}
|
$rank = ($days - 1) * $sign_conf['increase_reward'] + $rank;
|
}
|
//是否奖励
|
if (isset($sign_conf['reward_data'])) {
|
$arr = array_column($sign_conf['reward_data'], 'day');
|
if (in_array($days, $arr)) {
|
$key = array_search($days, $arr);
|
if ($sign_conf['reward_data'][$key]['is_point'] == 'true') {
|
$rank = $sign_conf['reward_data'][$key]['point'] + $rank;
|
}
|
}
|
}
|
// 新增积分变动明细
|
$this->setIncPoints($rank, '用户签到:签到日期' . $sign_date);
|
return $rank;
|
}
|
|
/**
|
* 个人中心菜单列表
|
*/
|
public static function getMenus($user, $source)
|
{
|
// 系统菜单
|
$sys_menus = CenterMenuModel::getSysMenu();
|
// 查询用户菜单
|
$model = new CenterMenuModel();
|
$user_menus = $model->getAll();
|
$user_menu_tags = [];
|
foreach ($user_menus as $menu) {
|
$menu['sys_tag'] != '' && array_push($user_menu_tags, $menu['sys_tag']);
|
}
|
$save_data = [];
|
foreach ($sys_menus as $menu) {
|
if ($menu['sys_tag'] != '' && !in_array($menu['sys_tag'], $user_menu_tags)) {
|
$save_data[] = array_merge($sys_menus[$menu['sys_tag']], [
|
'sort' => 100,
|
'app_id' => self::$app_id
|
]);
|
}
|
}
|
if (count($save_data) > 0) {
|
$model->saveAll($save_data);
|
Cache::delete('center_menu_' . self::$app_id);
|
$user_menus = $model->getAll();
|
}
|
//判断是否入住店铺
|
$noShow = [];
|
if ($user['user_type'] == 1) {
|
array_push($noShow, 'my_shop', 'app_shop');
|
} else if ($user['user_type'] == 2) {
|
// 申请中或者已入驻成功
|
array_push($noShow, 'shop');
|
// 入驻成功
|
if (UserModel::isSupplier($user['user_id'])) {
|
array_push($noShow, 'app_shop');
|
} else {
|
array_push($noShow, 'my_shop');
|
}
|
}
|
|
//判断是否配送点,配送员
|
if (!UserModel::isStoreClerk($user['user_id'])) {
|
array_push($noShow, 'deliveryclerk');
|
}
|
if (!UserModel::isStoreClerkGly($user['user_id'])) {
|
array_push($noShow, 'delivery');
|
}
|
if (!UserModel::isStoreClerk($user['user_id'])) {
|
array_push($noShow, 'storeorder');
|
array_push($noShow, 'couponorder');
|
}
|
|
//判断是否团长,外卖配送员
|
if (!CommanderModel::isCommander($user['user_id'])) {
|
array_push($noShow, 'commander');
|
}
|
if (!DeliverymanModel::isDeliveryman($user['user_id'])) {
|
array_push($noShow, 'deliveryman');
|
}
|
|
$menus_arr = [];
|
foreach ($user_menus as $menu) {
|
if ($menu['status'] == 1 && !in_array($menu['sys_tag'], $noShow)) {
|
array_push($menus_arr, $menu);
|
}
|
}
|
$sign_conf = SettingModel::getItem('sign');
|
foreach ($menus_arr as $key => $menus) {
|
if ($menus['sys_tag'] == "signin" && !$sign_conf['is_open']) {
|
unset($menus_arr[$key]);
|
}
|
if (strpos($menus['image_url'], 'http') !== 0) {
|
$menus['image_url'] = self::$base_url . $menus['image_url'];
|
}
|
}
|
return $menus_arr;
|
}
|
|
/**
|
* 修改会员信息
|
*/
|
public function edit($data)
|
{
|
//完成成长任务
|
if ($this['nickName'] != $data['nickName']) {
|
$data['task_type'] = "base";
|
$data['user_id'] = $this['user_id'];
|
event('UserTask', $data);
|
} elseif ($this['avatarUrl'] != $data['avatarUrl']) {
|
$data['task_type'] = "image";
|
$data['user_id'] = $this['user_id'];
|
event('UserTask', $data);
|
}
|
return $this->save($data);
|
}
|
|
/**
|
* 积分转换余额
|
*/
|
public function transPoints($points)
|
{
|
$setting = SettingModel::getItem('points');
|
$ratio = $setting['discount']['discount_ratio'];
|
if (!$setting['is_trans_balance']) {
|
$this->error = "暂未开启积分转换余额";
|
return false;
|
}
|
if ($points <= 0) {
|
$this->error = "转换积分不能小于0";
|
return false;
|
}
|
if ($this['points'] < $points) {
|
$this->error = "不能大于当前积分";
|
return false;
|
}
|
$this->startTrans();
|
try {
|
$balance = round($ratio * $points, 2);
|
//添加积分记录
|
$describe = "积分转换余额";
|
$this->setIncPoints(-$points, $describe);
|
//添加余额记录
|
$balance > 0 && BalanceLogModel::add(BalanceLogSceneEnum::POINTS, [
|
'user_id' => $this['user_id'],
|
'money' => $balance,
|
'app_id' => self::$app_id
|
], '');
|
$this->save(['points' => $this['points'] - $points, 'balance' => $this['balance'] + $balance]);
|
$this->commit();
|
return true;
|
} catch (\Exception $e) {
|
$this->error = $e->getMessage();
|
$this->rollback();
|
return false;
|
}
|
}
|
|
/**
|
* 资金冻结
|
*/
|
public function freezeMoney($money)
|
{
|
return $this->save([
|
'balance' => $this['balance'] - $money,
|
'freeze_money' => $this['freeze_money'] + $money,
|
]);
|
}
|
|
/**
|
* 会员码相关操作处理 by lyzflash
|
*/
|
public function recharge($clerkRealName, $data)
|
{
|
if ($data['source'] == 'points') {
|
return $this->storeToPoints($clerkRealName, $data);
|
}
|
return false;
|
}
|
|
/**
|
* 小票商家积分
|
*/
|
private function storeToPoints($clerkRealName, $data)
|
{
|
if (!isset($data['value']) || $data['value'] === '' || $data['value'] < 0) {
|
$this->error = '请输入正确的积分数量';
|
return false;
|
}
|
$points = 0;
|
// 判断充值方式,计算最终积分
|
if ($data['mode'] === 'inc') {
|
$diffMoney = $this['points'] + $data['value'];
|
$points = $data['value'];
|
} elseif ($data['mode'] === 'dec') {
|
$diffMoney = $this['points'] - $data['value'] <= 0 ? 0 : $this['points'] - $data['value'];
|
$points = -$data['value'];
|
} else {
|
$diffMoney = $data['value'];
|
$points = $data['value'] - $this['points'];
|
}
|
// 更新记录
|
$this->transaction(function () use ($clerkRealName, $data, $diffMoney, $points) {
|
$totalPoints = $this['total_points'] + $points <= 0? 0 : $this['total_points'] + $points;
|
// 更新账户积分
|
$this->where('user_id', '=', $this['user_id'])->update([
|
'points' => $diffMoney,
|
'total_points' => $totalPoints
|
]);
|
// 新增积分变动记录
|
PointsLogModel::add([
|
'user_id' => $this['user_id'],
|
'value' => $points,
|
'describe' => "平台核销员 [{$clerkRealName}] 操作",
|
'remark' => $data['remark'],
|
'shop_supplier_id' => $data['shop_supplier_id'],
|
'store_id' => $data['store_id']
|
]);
|
});
|
event('UserGrade', $this['user_id']);
|
return true;
|
}
|
|
/**
|
* 修改会员信息
|
*/
|
public function saveRegister($data)
|
{
|
//完成成长任务
|
if (empty($data["real_name"]) || empty($data["mobile"])) {
|
$this->error = '请输入填写完整信息再提交';
|
return false;
|
}
|
// 事务处理
|
$this->transaction(function () use ($data) {
|
//更新会员卡数据
|
$this->updateCard();
|
$this->save($data);
|
});
|
return true;
|
}
|
|
/**
|
* 更新会员卡数据
|
*/
|
private function updateCard()
|
{
|
//获取商城设置的会员卡
|
$setting = SettingModel::getItem('store');
|
// print_r($setting);exit;
|
if(empty($setting) || empty($setting["open_card"]) || empty($setting["card_id"])){
|
//没有设置注册送会员卡,则不操作
|
return true;
|
}
|
// 获取用户信息
|
$user = self::detail($this['user_id']);
|
$model = CardModel::detail($setting["card_id"]);
|
//生成会员卡记录
|
$CardRecordModel = new CardRecordModel();
|
$model['money'] = 0;//赠送则为0
|
$record = [
|
'user_id' => $user['user_id'],
|
'card_id' => $model['card_id'],
|
'order_no' => $CardRecordModel->orderNo(),
|
'expire_time' => $model['expire'] ? (time() + $model['expire'] * 86400 * 30) : 0,
|
'money' => $model['money'],
|
'discount' => $model['is_discount'] ? $model['discount'] : 0,
|
'open_points' => $model['open_points'],
|
'open_points_num' => $model['open_points_num'],
|
'open_coupon' => $model['open_coupon'],
|
'open_coupons' => $model['open_coupons'],
|
'open_product' => $model['open_product'],
|
'open_products' => $model['open_products'],
|
'open_money' => $model['open_money'],
|
'open_money_num' => $model['open_money_num'],
|
'pay_type' => 10,
|
'pay_time' => time(),
|
'app_id' => self::$app_id,
|
];
|
$status = $CardRecordModel->save($record);
|
if($status){
|
$CardRecordModel->onPaymentByBalance($record['order_no']);
|
}
|
//走支付完成流程 注释以下
|
/* CardModel::where('card_id', '=', $model['card_id'])->inc('receive_num', 1)->update();
|
//赠送积分
|
if ($model['open_points'] && $model['open_points_num']) {
|
$user->setIncPoints($model['open_points_num'], '注册成功发会员卡获取积分');
|
}
|
//赠送优惠券
|
if ($model['open_coupon'] && $model['open_coupons']) {
|
(new UserCouponModel)->addUserCardCoupon($model['open_coupons'], $user,0);
|
}
|
//赠送余额
|
if ($model['open_money'] && $model['open_money_num']) {
|
(new UserModel)->where('user_id', '=', $user['user_id'])
|
->inc('balance', $model['open_money_num'])
|
->update();
|
BalanceLogModel::add(BalanceLogSceneEnum::ADMIN, [
|
'user_id' => $user['user_id'],
|
'money' => $model['open_money_num'],
|
], ['order_no' => '注册成功发放会员卡赠送']);
|
}*/
|
}
|
}
|