jh-admin/addon/saas/api/controller/Site.php

670 lines
29 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace addon\saas\api\controller;
use addon\aliapp\model\AliPayApplet;
use addon\aliapp\model\CloudPay;
use addon\aliapp\model\OpenPay;
use addon\aliapp\model\MinCode;
use addon\saas\model\AlipayCategory;
use addon\saas\model\Config as ConfigModel;
use addon\saas\model\PayShop;
use app\api\controller\BaseApi;
use app\model\image\ImageService;
use app\model\system\SiteGroup;
use app\model\upload\Upload as UploadModel;
class Site extends BaseApi
{
protected $mime = [
'image/jpeg' => '.jpg',
'image/png' => '.png',
'image/gif' => '.gif',
'image/bmp' => '.bmp',
'image/webp' => '.webp',
];
public function config()
{
$model = new ConfigModel();
$info = $model->getConfig($this->site_id);
return $this->response($this->success([
'is_set_separateLedgerRate' => 0, //$info['data']['value']['is_set_separateLedgerRate'] ?? 0, //是否允许自定义分佣比例
'default_separateLedgerRate' => 5 //默认开户佣金
]));
}
/***
* 商户列表
* @return array|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function list()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$page = input('page', 1);
$page_size = input('page_size', PAGE_LIST_ROWS);
$search_text = input('search_text', '');
$states = input('states', 'all');
$condition = [];
$condition[] = ['a.member_id', '=', $this->member_id];
if ($states != 'all') {
$condition[] = ['a.states', '=', $states];
}
if ($search_text) {
$condition[] = ['a.merchant_name|a.contacts_name|a.contacts_phone', 'like', '%' . $search_text . '%'];
}
$pat_model = new PayShop();
$res = $pat_model->getPageList($condition, $page, $page_size, 'a.*,al.status as miniapp_status', 'a.create_time desc', [
['applet_reg al', 'a.site_id=al.site_id', 'left']]
, 'a.shop_id', 'a'
);
foreach ($res['data']['list'] as $key => $item) {
if ($item['miniapp_status']) {
$res['data']['list'][$key]['appinfo'] = [
'isNewest' => (new AliPayApplet($item['site_id']))->isNewestVersion(),
'is_baseinfo' => (new AliPayApplet($item['site_id']))->isNewestVersion(),
];
} else {
$ver = (new AliPayApplet($item['site_id']))->getNewVersionInfo();
if ($ver && in_array($ver['version_status'], ['AUDIT_REJECT', 'RELEASE'])) {
$res['data']['list'][$key]['miniapp_status'] = 'AGREED';
}
$res['data']['list'][$key]['appinfo'] = [
'isNewest' => false,
'is_baseinfo' => false,
];
}
}
return $this->response($res);
}
/***
* 刷新进件状态
* @return false|string
*/
public function refresh()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
return $this->response([]);
}
/***
* 商家注册信息
* @return mixed|void
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function info()
{
$token = $this->checkToken();
if ($token['code'] < 0) return $this->response($token);
$shop_id = input('shop_id', 0);
$myopensite = input('myopensite', 0);
$payShop = new PayShop();
$nextStep = 1;
if ($shop_id || $myopensite) {
$where = [
['a.shop_id', '=', $shop_id],
];
if ($myopensite) {
$member_id = $token['data']['member_id'];
$where = [
['a.member_id', '=', $member_id],
];
}
$regInfo = $payShop->alias('a')
->where($where)
->field('a.*,s.username,reg.status as miniapp_status,app.value')
->join('site s', 's.site_id = a.site_id', 'left')
->join('uni_account app', 'app.site_id = a.site_id', 'left')
->join('applet_reg reg', 'reg.site_id = a.site_id', 'left')
->find();
if (empty($regInfo) && $myopensite) {
$payInfo['business_code'] = date('YmdHis') . rand(1000, 9999);
$payInfo['outdoor_store_images'] = '';
$payInfo['indoor_store_image'] = '';
$isnew = 1;
$nextStep = 1;
$res = [
'isNew' => $isnew,
'info' => $payInfo,
'nextStep' => $nextStep,
];
return $this->response($this->success($res));
} elseif ($regInfo['site_id'] > 0) {
$nextStep = 2;
}
$payInfo = $regInfo['alipay_value'];
$value = json_decode($regInfo['value'], true);
$zm = $regInfo['zmalipay_value'];
$payInfo['app_logo'] = $zm['app_logo'] ?? $value['app_logo'] ?? '';
if (empty($payInfo['app_logo']) && $value) {
$payInfo['app_logo'] = $value['app_logo'] ?? '';
}
$payInfo['shop_site_id'] = $regInfo['site_id'];
$payInfo['username'] = $regInfo['username'];
$payInfo['business_code'] = $regInfo['business_code'];
$payInfo['apply_desc'] = $regInfo['apply_desc'] ?? '';
$payInfo['shop_id'] = $regInfo['shop_id'];
unset($payInfo['site_id']);
if (!isset($payInfo['contacts_name'])) {
$payInfo['contacts_name'] = $regInfo['contacts_name'];
$payInfo['contacts_mobile'] = $regInfo['contacts_phone'];
$payInfo['separateLedgerRate'] = $regInfo['separateLedgerRate'] ?? $zm['separateLedgerRate'] ?? '';
}
$isnew = 0;
if ($regInfo['merchant_smid'] != '') {
$nextStep = 3;
}
if ($regInfo['miniapp_status'] && $regInfo['miniapp_status'] == 'SUCCESS') { //小程序注册状态
$nextStep = 4;
} elseif ($regInfo['miniapp_status'] && $regInfo['miniapp_status'] == 'reg') {
$nextStep = 3;
}
if ($regInfo['is_zmpay'] == 1) {
$nextStep = 4;
}
} else {
$payInfo['business_code'] = date('YmdHis') . rand(1000, 9999);
$payInfo['outdoor_store_images'] = '';
$payInfo['indoor_store_image'] = '';
$isnew = 1;
$nextStep = 1;
}
unset($payInfo['password']);
$res = [
'isNew' => $isnew,
'info' => $payInfo,
'nextStep' => $nextStep,
];
return $this->response($this->success($res));
}
/***
* 添加商户
* @return false|string
* @throws \app\exception\ApiException
* @throws \think\db\exception\DbException
*/
public function add()
{
$token = $this->checkToken();
$data = request()->post();
if ($token['code'] < 0) return $this->response($token);
unset($data['token'], $data['app_type'], $data['app_type_name'], $data['area'], $data['site_id']);
//直通商户
$shop_id = input('shop_id', 0);
$myopensite = input('myopensite', 0);
$step = input('step', 1);
$payShop = new PayShop();
$shop_info = [];
$arr_info = [];
$saveData = [];
if ($shop_id) {
$shop_info = model('pay_shop')->getInfo([['shop_id', '=', $shop_id]]);
}
if (empty($data['business_code'])) {
$data['business_code'] = date('YmdHis') . rand(1000, 9999);
}
$error = '';
switch ($step) {
case 1:
//创建商家
$data['username'] = trim(input("username", ''));//账户
$data['password'] = trim(input("password", ''));//密码
$group_id = input('group_id', 0);
$expire_time = input('expire_time', 0);
$mangaeinfo = model('manage_user')->getInfo(['site_id' => $this->site_id, 'member_id' => $this->member_id], 'id,my_site_id,real_name,use_settle_number,is_settle_limit');
if ($mangaeinfo['use_settle_number'] == 1 && $mangaeinfo['use_settle_number'] <= 0 && !$myopensite) return $this->response(error(-1, '创建数量达到上限'));
$is_edit = false;
if ($myopensite && $mangaeinfo['my_site_id'] > 0) {
$is_edit = true;
}
//店铺信息
$shop_data = [
'site_name' => input('site_name', ''), //店铺名称
'contacts_name' => input('contacts_name', ''), //联系人
'contacts_mobile' => input('contacts_mobile', ''), //联系电话
'agent_id' => $this->site_id, //所属代理
'manage_id' => $mangaeinfo['id'] ?? 0, //所属代理
'manage_name' => $mangaeinfo['real_name'] ?? '', //所属代理
'group_id' => $group_id,
'expire_time' => $expire_time,
'is_try' => 0, //是否体验用户
'is_operated' => 1, //是代营运
'province_id' => input('province_id', 0),//所在省份
'city_id' => input('city_id', 0),//所在城市
'district_id' => input('district_id', 0),//所在地区
'address' => input('address'), //具体地址
'full_address' => input('business_address_address'), //具体地址
];
$user_info = [
'username' => input('username', ''),
'password' => data_md5(input('password', '')),
];
$site_model = new \app\model\system\Site();
if ($is_edit || (input('shop_id') && $mangaeinfo['my_site_id'])) {
$site_model->editSite($shop_data, [['site_id', '=', $mangaeinfo['my_site_id']]]);
} else {
$result = $site_model->addSite($shop_data, $user_info);
if ($result['code'] != 0) {
return $this->response($result);
}
$log = array(
"uid" => $mangaeinfo['id'] ?? $this->site_id,
"username" => $mangaeinfo['real_name'] ?? $this->site_id,
"site_id" => $this->site_id,
"url" => '',
"ip" => request()->ip(),
"data" => json_encode($shop_data),
"action_name" => $mangaeinfo['real_name'] . '新增店铺',
"create_time" => time(),
);
model("user_log")->add($log);
if (empty($data['business_code'])) {
$data['business_code'] = date('YmdHis') . rand(1000, 9999);
}
if ($myopensite) {//绑定自营店铺
model('manage_user')->update(['my_site_id' => $result['data']], ['id' => $mangaeinfo['id']]);
}
$saveData['states'] = 0;
$saveData['is_zmapply'] = 1;
$saveData['member_id'] = $token['data']['member_id'];
$saveData['isDrafts'] = 1;
$data['reg_money'] = 0; //默认0元判断代理商是否需要费用
$data['subject_type'] = '';//q企业类型
$data['manage_id'] = $shop_data['manage_id'];
$data['nextStep'] = 2;
$data['site_id'] = $result['data'];
$data['shop_site_id'] = $result['data'];
}
if ($myopensite) {
$data['my_openshop_id'] = $token['data']['member_id'];
}
unset($data['password']);
$payInfo = $data;
$nextStep = 2;
break;
case 2:
$payInfo = $data;
$business_info = model('pay_shop')->getInfo([
['alipay_value', 'like', '%' . $data['cert_no'] . '%'],
], 'business_code,states,alipay_value,shop_id,isDrafts');
$alipay_value = '';
if ($business_info) {
$alipay_value = json_decode($business_info['alipay_value'], true);
}
if ($business_info && $business_info['states'] == 1) {
$nextStep = 3;
$payInfo['states'] = 0;
$saveData['states'] = 1;
} elseif ($business_info && $business_info['states'] == 0 && $data['isDrafts'] == 1) {
$payInfo['states'] = 0;
$nextStep = 3;
} else {
$create = true;
if ($alipay_value && isset($alipay_value['order_id'])) {
$CloudPay = new OpenPay();
$res = $CloudPay->query('', $alipay_value['order_id']);
$res = $res['orders'][0];
if (isset($res['sub_confirm'])) {
switch ($res['sub_confirm']) {
case 'CREATE' :
$error = '待商户确认,请商户在支付宝确认签约';
$create = false;
break;
case 'NOT_CONFIRM' :
$error = '商户超时未确认';
break;
case 'FAIL' :
$error = '进件失败';
break;
}
if ($res['status'] == 99) {
$create = false;
$nextStep = 3;
}
}
}
if ($create) {
$payInfo = $this->AlipayCreate($data);//注册支付商户
$data['states'] = $shop_info['states'];
$data['subject_type'] = '';//q企业类型
$data['reg_money'] = 0;//q企业类型
$saveData['states'] = 0;
$saveData['is_zmapply'] = 1;
$saveData['isDrafts'] = 0;
if ($payInfo['code'] == '10000') {
$nextStep = 3;
} else {
$error = $payInfo['message'];
}
}
}
break;
case 3:
$payInfo = $data;
$business_code = $data['business_code'];
$where = [['site_id', '=', $shop_info['site_id']], ['business_code', '=', $business_code]];
$miniStatus = model('applet_reg')->getValue($where, 'status');
if (empty($miniStatus) || in_array($miniStatus, ['TIMEOUT', 'REJECTED', 'Drafts'])) {
$res = $this->miniappCreate($data, $shop_info);
if ($res['code'] == '10000') {
$nextStep = 4;
} else {
$error = $payInfo['message'];
}
} else if ($miniStatus && $miniStatus == 'reg') {
$error = '待商户确认,请商户在支付宝确认注册';
$nextStep = 4;
} else if ($miniStatus && in_array($miniStatus, ['AGREED', 'SUCCESS'])) {
$error = '';
$nextStep = 4;
} else {
$error = '已注册或待确认';
$nextStep = 4;
}
break;
case 4://先享注册待完成
$payInfo = $data;
if ($shop_info['merchant_smid'] == '') return $this->response(error(-1, '支付进件未完成'));
$config_model = new \addon\aliapp\model\Config();
$config_info = $config_model->getAppConfig($shop_info['site_id'])['data']['value'];
if (empty($config_info['appid'])) return $this->response(error(-1, '小程序未配置或未上架'));
$nextStep = 4;
$res = $this->zmCloudCreate($data, $shop_info, $config_info['appid']);//注册支付商户
if ($res['code'] < 0) {
return $this->response($res);
} else {
$saveData = [
'zmalipay_value' => $res['zmalipay_value'],
'service_commission' => $res['service_commission'],
'settleAccountList' => $res['settleAccountList'],
];
}
break;
}
$payInfo['area'] = [
'district_id' => $data['district_id'],
'city_id' => $data['city_id'],
'province_id' => $data['province_id'],
];
$data['site_id'] = $data['shop_site_id'];
$info = $payShop->AlipaySave($data, $payInfo, $this->site_id, $this->member_id, 0.6, $saveData);
if ($error) {
return $this->response(error(-1, $error));
}
$success = [
'nextStep' => $nextStep,
'shop_id' => $info['data'],
];
return $this->response($this->success(array_merge($success, $arr_info)));
}
/***
* 进件二级支付
* @param array $info
* @return array|false|string
*/
private function AlipayCreate($info = [])
{
$payInfo = $info;
$sites = $payInfo['sites'];
$payInfo['sites'] = array_values($sites);
if ($info['code_type'] == 'individual') {
$name = $info['contact_infos']['name'];
} else {
$name = $info['name'];
}
//创建直通商户
$data = [
'binding_alipay_logon_id' => $info['binding_alipay_logon_id'],
'alipay_logon_id' => $info['binding_alipay_logon_id'],
'external_id' => $info['business_code'],
'alias_name' => $info['alias_name'],
'service_phone' => $info['service_phone'],
'contact_infos' => $info['contact_infos'],
'service' => $info['service'],
'name' => $name,
'default_settle_rule' => [
'default_settle_type' => 'alipayAccount',
'default_settle_target' => $info['binding_alipay_logon_id']
],
'zft_withholding_info'=>[
'withholding_service_feature_name'=>'GENERAL_WITHHOLDING_P',
'sign_scene'=>'INDUSTRY|PAY_ORDER_MODEL',
],
'business_address' => $info['business_address'],
'out_door_images' => $info['out_door_images'],
'in_door_images' => $info['in_door_images'],
'sites' => $info['sites'],
'mcc' => $info['mcc'],
'additional_cert_type' => 201,
'additional_cert_no' => $info['cert_no'],
'additional_cert_image' => $info['cert_image'],
];
$data['business_address']['province_code'] = $info['province_id'];
$data['business_address']['city_code'] = $info['city_id'];
$data['business_address']['district_code'] = $info['district_id'];
$CloudPay = new OpenPay();
$res = $CloudPay->simpleCreate($data);
if ($res['code'] != 10000) {
$payInfo['message'] = $res['sub_msg'];
$payInfo['states'] = 2;
$payInfo['apply_desc'] = $res['sub_msg'];
} elseif ($res['code'] == 10000) {
$payInfo['order_id'] = $res['order_id'];
$payInfo['states'] = 0;
}
$payInfo['code'] = $res['code'];
return array_merge($payInfo, $data);
}
/**
* 注册小程序
* @param $info
* @return mixed|string|void
* @throws \think\db\exception\DbException
*/
private function miniappCreate($info = [], $shop_info)
{
if (!isset($info['business_code']) || $info['business_code'] == '') {
$business_code = date('YmdHis') . rand(1000, 9999);
} else {
$business_code = $info['business_code'];
}
if (strpos($info['cert_image_show_image'], 'http') !== false || strpos($info['cert_image_show_image'], 'https') !== false) {
$license_pic = base64_encode(file_get_contents($info['cert_image_show_image']));
} else {
$license_pic = base64_encode(file_get_contents(root_path() . $info['cert_image_show_image']));
}
$bizParams = [
'create_mini_request' => [
'out_order_no' => $business_code, // 开发者外部订单号
'alipay_account' => $info['binding_alipay_logon_id'], // 商家登录支付宝的邮箱帐号或手机号
'legal_personal_name' => $info['legal_name'],// 商家法人名称
'cert_name' => $info['cert_name'],// 营业执照企业名称,如果是“无主体名称个体工商户”则填“个体户+法人姓名”,例如“个体户张三”
'cert_no' => $info['cert_no'],// 营业执照编码
'app_name' => $info['sites'][1]['site_name'], // 小程序名称
'contact_phone' => $info['contacts_mobile'], // 商家联系人手机电话
'contact_name' => $info['contacts_name'], // 商家联系人名称
'is_individual' => true, //是否支持个体工商户的账号类型
'license_pic' => $license_pic, // 营业执照图片的Base64编码字符串图片大小不能超过2M。
]
];
$mininfo = model('applet_reg')->getInfo(['site_id' => $shop_info['site_id'], 'business_code' => $business_code]);
if ($mininfo && $mininfo['status'] == 'AGREED') {
$info['code'] = 10000;
$info['message'] = '注册成功';
return $info;
}
$miapp = new \addon\saas\model\AppletReg();
$miniModel = new MinCode();
$res = $miniModel->MiniCreate($bizParams); //创建小程序
$data['code'] = $res['code'];
if ($res['code'] == '10000') {
$bizParams['order_no'] = $res['order_no'];
$info['message'] = '注册成功';
} else {
$info['message'] = $res['sub_msg'] ?? '未知错误';
}
if (empty($mininfo)) {
$miappdata['business_code'] = $business_code;
$miappdata['site_id'] = $shop_info['site_id'];
$miappdata['ag_site_id'] = $this->site_id;
$miappdata['app_type'] = 'aliapp';
$miappdata['corporate_name'] = input('contacts_name');
$miappdata['legal_persona_name'] = input('contacts_mobile');
$miappdata['contact_phone'] = input('contacts_mobile');
$miappdata['app_name'] = input('sites_02_name');
$miappdata['status'] = 'reg';
$miappdata['value'] = json_encode($bizParams);
$miapp->save($miappdata);
} else {
$miappdata['status'] = 'reg';
$miappdata['value'] = json_encode($bizParams);
model('applet_reg')->update($miappdata, ['site_id' => $shop_info['site_id'], 'business_code' => $business_code]);
}
return array_merge($info, $data);
}
/***
* 添加芝麻商户
* @param $info
* @param $shop_info
* @param $appid
* @return array
*/
private function zmCloudCreate($info, $shop_info, $appid)
{
$agentInfo = model('website')->getInfo(['site_id' => $shop_info['ag_site_id']], 'platform_offlinecommission_rate,alipay_account,alipay_account_name');
$data['separateLedgerRate'] = $agentInfo['platform_offlinecommission_rate'] ?: config('accounts.aliapp.fee_commission');//平台佣金
$data['merchantLoginName'] = $info['binding_alipay_logon_id'];
$data['merchantName'] = mb_substr($info['alias_name'], 0, 8, 'UTF-8');
$data['smid'] = $shop_info['merchant_smid'];
$data['phone'] = $info['contacts_mobile'];
$data['merchantAppId'] = $appid;//小程序APPID
$data['comment'] = '';
$settleAccountList = [ //渠道佣金
[
'settleAccount' => $agentInfo['alipay_account'],
'separateLedgerRate' => $info['separateLedgerRate'],
'payeeRealName' => $agentInfo['alipay_account_name'],
]
];
$pay = new CloudPay();
if ($info['app_logo']) {
$driver = config('upload')['driver'] ?? 'gd';
$image_service = new ImageService($driver);
//图片处理
if (strpos($info['app_logo'], 'aliyuncs') == false) {
$image = $image_service->open(img($info['app_logo']))->thumb(160, 160);
$file = root_path() . 'runtime/temp/' . md5($info['app_logo']) . $this->mime[$image->image->mime];
$image->save($file, 100);
$img = UrlimgBase64($file);
$logo = $pay->logoUpload($img);
if ($logo['code'] == '10000') {
$data['logoUrl'] = $logo['pictureUrl'];
} else {
return error(-1, '请保证尺寸160*160像素尺寸不得大于2M');
}
} else {
$data['logoUrl'] = $info['app_logo'];
}
} else if (!isset($info['logoUrl'])) {
return error(-1, '请保证尺寸160*160像素尺寸不得大于2M');
}
if ($info['separateLedgerRate'] == 0) {
$settleAccountList = [];
}
$res = $pay->upAlipayUser($data, $settleAccountList);
if ($res['code'] == '10000') {
$updata = [
'zmalipay_value' => $data,
'service_commission' => $info['separateLedgerRate'],
'settleAccountList' => json_encode($settleAccountList),
];
$updata['message'] = $res['sub_msg'] ?? $res['msg'];
$updata['code'] = 10000;
return $updata;
} else {
return error(-1, $res['sub_msg'] ?? $res['msg']);
}
}
/***
* 获取套餐分组
* @return false|string
*/
public function getSiteGroupList()
{
$site_group_model = new SiteGroup();
//应用套餐
$site_group_list = $site_group_model->getSiteGroupList([['site_id', '=', $this->site_id]], 'group_id,group_name,fee,remark', 'fee asc');
return $this->response($this->success($site_group_list));
}
/***
* 获取支付宝MCC分类
* @return false|string
*/
public function getalicategory()
{
$AlipayCategory = new AlipayCategory();
$name = input('name');
$res = $AlipayCategory->getCategory($name);
$data = $res['data']['商业生活服务'];
return $this->response($this->success($data));
}
/***
* 上传图片
* @return array|bool|mixed|\multitype|string
*/
public function image()
{
$upload_model = new UploadModel($this->site_id, $this->app_module);
$watermark = input('watermark', 0); // 是否需生成水印
$param = array(
'thumb_type' => '',
'name' => 'file',
'watermark' => $watermark,
'cloud' => 0,
);
$path = 'common/images/' . date('Ymd') . '/';
$result = $upload_model->setPath($path)->image($param);
if ($result['code'] == 0) {
$CloudPay = new OpenPay();
$file = request()->file($param["name"]);
$ext = $file->getOriginalExtension();
$res = $CloudPay->upload($ext, $result['data']['pic_path']);//上传阿里
if (isset($res['image_id'])) {
$result['data']['image_id'] = $res['image_id'];
$pic_path = $upload_model->setPath($path)->fileCloud($result['data']['pic_path']);
$result['data']['pic_path'] = $pic_path['data'];
}
}
return $this->response($result);
}
/**
* 生成UUID
*/
public function uuid()
{
$chars = md5(uniqid(mt_rand(), true));
$uuid = substr($chars, 0, 8)
. substr($chars, 8, 4)
. substr($chars, 12, 4)
. substr($chars, 16, 4)
. substr($chars, 20, 12);
return $uuid;
}
}