Zory 2 days ago
parent
commit
bac67e66d5

+ 0 - 1
app/controller/merchant/Renew.php

@@ -46,7 +46,6 @@ class Renew extends Base
                     return $data['f_old_money'] - $data['f_money'];
                 }])->select();
             $privacy = htmlspecialchars_decode(sConf("service.privacy"));
-            print_r($privacy);
             return success('ok',compact("shop",'combo','privacy'));
         } catch (\Throwable $throwable) {
             return error($throwable->getMessage());

+ 10 - 0
app/controller/wap/Common.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace app\controller\wap;
+
+use app\extra\basic\Base;
+
+class Common extends Base
+{
+
+}

+ 208 - 0
app/controller/wap/Login.php

@@ -0,0 +1,208 @@
+<?php
+
+namespace app\controller\wap;
+
+use app\extra\basic\Base;
+use app\extra\wechat\WechatService;
+use app\middleware\WxMiddleware;
+use app\model\system\SystemUser;
+use app\model\system\SystemUserOpen;
+use LinFly\Annotation\Route\Controller;
+use LinFly\Annotation\Route\Middleware;
+use LinFly\Annotation\Route\Route;
+use Shopwwi\WebmanAuth\Auth;
+use support\Request;
+use support\Response;
+
+
+#[Controller(prefix: "/wap/login"),Middleware(WxMiddleware::class)]
+class Login extends Base
+{
+
+    protected array $noNeedLogin = ["checkLogin"];
+
+
+    #[Route(path: "check",methods: "post")]
+    public function checkLogin(Request $request): Response
+    {
+        try {
+            $source = $request->header("referer");
+//            $userInfo = WechatService::getWebOauthInfo($source,1,false);
+            $userInfo['openid'] = 123;
+            if (empty($userInfo['openid'])) {
+                return success("ok",['url' => $userInfo['url'],'type' => 1]); // 跳转
+            } else {
+                $user = (new SystemUserOpen)->where(['openid' => $userInfo['openid']])->findOrEmpty();
+                if ($user->isEmpty())
+                {
+                    return success("ok",['url' => '','type' => 2,'token' => ['access_token' => $userInfo['openid']]]); // 跳到绑定用户
+                }
+                $loginUser = (new SystemUser)->where(['id' => $user['uid']])->findOrEmpty();
+                return success("ok",['url' => '','type' => 3,'menu' => $this->getMenu(),'token' => get_object_vars((new Auth)->guard("admin")->login($loginUser))]); // 正常登陆进入
+            }
+        } catch (\Throwable $th) {
+            return error($th->getMessage());
+        }
+    }
+
+    /**
+     * @return array[]
+     */
+    protected function getMenu(): array
+    {
+        return [
+            [
+                "path"  => "/dashboard",
+                "name"  => "dashboard",
+                "component" => "dashboard",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "总揽",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/shop/detail",
+                "name"  => "shop/detail",
+                "component" => "shop/detail",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "店铺详情",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/print",
+                "name"  => "print/index",
+                "component" => "print/index",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "打印机",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/print/price",
+                "name"  => "print/price",
+                "component" => "print/price",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "价格设置",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/print/discount",
+                "name"  => "print/discount",
+                "component" => "print/discount",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "折扣设置",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/order",
+                "name"  => "order/index",
+                "component" => "order/index",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "实时订单",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/turnover/index",
+                "name"  => "turnover/index",
+                "component" => "turnover/index",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "营业额",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/member/index",
+                "name"  => "member/index",
+                "component" => "member/index",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "会员卡",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/wallet/index",
+                "name"  => "wallet/index",
+                "component" => "wallet/index",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "我的钱包",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/shop/bind",
+                "name"  => "shop/bind",
+                "component" => "shop/bind",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "绑定门店",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/shop/change",
+                "name"  => "shop/change",
+                "component" => "shop/change",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "切换门店",
+                    "type"  => "menu"
+                ]
+            ],[
+                "path"  => "/shop/msg",
+                "name"  => "shop/msg",
+                "component" => "shop/msg",
+                "meta"  => [
+                    "icon"  => "",
+                    "title" => "消息开关",
+                    "type"  => "menu"
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * 获取当前请求的完整 URL
+     * @param bool $withQuery 是否包含查询参数
+     * @return string
+     */
+    protected function getFullUrl($withQuery = true) {
+        // 1. 获取协议(支持代理)
+        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
+        || (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)
+            ? 'https' : 'http';
+
+        // 2. 获取主机名(支持代理)
+        $host = $_SERVER['HTTP_X_FORWARDED_HOST']
+            ?? $_SERVER['HTTP_HOST']
+            ?? $_SERVER['SERVER_NAME']
+            ?? 'localhost';
+
+        // 3. 获取端口(支持代理)
+        $port = $_SERVER['HTTP_X_FORWARDED_PORT']
+            ?? $_SERVER['SERVER_PORT']
+            ?? 80;
+
+        // 4. 获取请求URI(包含路径和查询参数)
+        $requestUri = $_SERVER['REQUEST_URI'] ?? '/';
+
+        // 5. 构建基础URL
+        $baseUrl = $protocol . '://' . $host;
+
+        // 6. 如果不是标准端口,添加端口号
+        $isStandardPort = ($protocol === 'http' && $port == 80)
+            || ($protocol === 'https' && $port == 443);
+
+        if (!$isStandardPort) {
+            $baseUrl .= ':' . $port;
+        }
+
+        // 7. 返回完整URL
+        return $baseUrl . $requestUri;
+    }
+
+
+
+}

+ 160 - 0
app/extra/wechat/WechatService.php

@@ -0,0 +1,160 @@
+<?php
+
+namespace app\extra\wechat;
+
+/**
+ * 微信接口调度服务
+ * @package app\extra\wechat
+ * @method \WeChat\Oauth WeChatOauth() static 微信网页授权
+ */
+class WechatService
+{
+
+
+    /**
+     * 静态初始化对象
+     * @param string $name
+     * @param array $arguments
+     * @return mixed
+     * @throws \think\admin\Exception
+     */
+    public static function __callStatic(string $name, array $arguments)
+    {
+        [$type, $base, $class] = static::parseName($name);
+        if ("{$type}{$base}" !== $name) {
+            throw new \Exception("抱歉,实例 {$name} 不符合规则!");
+        }
+        if (class_exists($class)) {
+            return new $class(static::getConfig());
+        } else {
+            throw new \Exception("抱歉,接口模式无法实例 {$class} 对象!");
+        }
+    }
+
+    /**
+     * 解析调用对象名称
+     * @param string $name
+     * @return array
+     */
+    private static function parseName(string $name): array
+    {
+        foreach (['WeChat', 'WeMini', 'WeOpen', 'WePayV3', 'WePay', 'ThinkService'] as $type) {
+            if (strpos($name, $type) === 0) {
+                [, $base] = explode($type, $name);
+                return [$type, $base, "\\{$type}\\{$base}"];
+            }
+        }
+        return ['-', '-', $name];
+    }
+
+    /**
+     * 获取当前微信APPID
+     * @return string
+     */
+    public static function getAppid(): string
+    {
+        return sConf('wechat.appid');
+    }
+
+    /**
+     * 获取接口授权模式
+     * @return string
+     */
+    public static function getType(): string
+    {
+        $type = strtolower(sConf('wechat.type'));
+        if (in_array($type, ['api', 'thr'])) return $type;
+        throw new \Exception('请在后台配置微信对接授权模式');
+    }
+    /**
+     * 获取公众号配置参数
+     * @return array
+     */
+    public static function getConfig(): array
+    {
+        return [
+            'appid'          => static::getAppid(),
+            'token'          => sConf('wechat.token'),
+            'appsecret'      => sConf('wechat.secret'),
+            'encodingaeskey' => sConf('wechat.aeskey'),
+            'mch_id'         => sConf('wechat.mch_id'),
+            'mch_key'        => sConf('wechat.mch_key')
+        ];
+    }
+
+    /**
+     * 通过网页授权获取粉丝信息
+     * @param string $source 回跳URL地址
+     * @param integer $isfull 获取资料模式
+     * @param boolean $redirect 是否直接跳转
+     * @return array
+     */
+    public static function getWebOauthInfo(string $source, int $isfull = 0, bool $redirect = true): array
+    {
+        try {
+            $appid = static::getAppid();
+            $openid = request()->session()->get("{$appid}_openid");
+            $userinfo = request()->session()->get("{$appid}_fansinfo");
+            if ((empty($isfull) && !empty($openid)) || (!empty($isfull) && !empty($openid) && !empty($userinfo))) {
+                return ['openid' => $openid,"url" => "", 'fansinfo' => $userinfo];
+            }
+            // 解析 GET 参数
+            $queryString = parse_url($source, PHP_URL_QUERY);
+            // 初始化参数数组
+            $params = [];
+            // 只有当有查询字符串时才解析
+            if ($queryString !== null && $queryString !== '') {
+                parse_str($queryString, $params);
+            }
+//        parse_str(parse_url($source, PHP_URL_QUERY), $params);
+            $getVars = [
+                'code'  => $params['code'] ?? input('code', ''),
+                'rcode' => $params['rcode'] ?? input('rcode', ''),
+                'state' => $params['state'] ?? input('state', ''),
+            ];
+            $wechat = static::WeChatOauth();
+            if ($getVars['state'] !== $appid || empty($getVars['code'])) {
+                $params['rcode'] = enbase64url($source);
+                $location = strstr("{$source}?", '?', true) . '?' . http_build_query($params);
+                $oauthurl = $wechat->getOauthRedirect($location, $appid, $isfull ? 'snsapi_userinfo' : 'snsapi_base');
+                return ['openid' => "","url" => $oauthurl ,"fansinfo" => ""];
+            } elseif (($token = $wechat->getOauthAccessToken($getVars['code'])) && isset($token['openid'])) {
+                request()->session()->set("{$appid}_openid", $openid = $token['openid']);
+                if ($isfull && isset($token['access_token'])) {
+                    $userinfo = $wechat->getUserInfo($token['access_token'], $openid);
+                    request()->session()->set("{$appid}_fansinfo", $userinfo);
+                }
+            }
+            if ($getVars['rcode']) {
+                $location = debase64url($getVars['rcode']);
+                return ['openid' => "","url" => $location ,"fansinfo" => ""];
+            } elseif ((empty($isfull) && !empty($openid)) || (!empty($isfull) && !empty($openid) && !empty($userinfo))) {
+                return ['openid' => $openid, 'url' => '', 'fansinfo' => $userinfo];
+            } else {
+                throw new \Exception('Query params [rcode] not find.');
+            }
+        } catch (\Throwable $th) {
+            echo $th->getMessage();
+        }
+    }
+//
+//    /**
+//     * 获取微信网页JSSDK签名参数
+//     * @param null|string $location 签名地址
+//     * @return array
+//     * @throws \WeChat\Exceptions\InvalidResponseException
+//     * @throws \WeChat\Exceptions\LocalCacheException
+//     * @throws \think\admin\Exception
+//     */
+//    public static function getWebJssdkSign(?string $location = null): array
+//    {
+//        $location = $location ?: Library::$sapp->request->url(true);
+//        if (static::getType() === 'api') {
+//            return static::WeChatScript()->getJsSign($location);
+//        } else {
+//            return static::ThinkServiceConfig()->jsSign($location);
+//        }
+//    }
+
+
+}

+ 25 - 0
app/functions.php

@@ -2,6 +2,7 @@
 
 
 use app\extra\service\system\SystemService;
+use app\extra\tools\CodeExtend;
 use support\Response;
 use Webman\Event\Event;
 
@@ -492,4 +493,28 @@ if (!function_exists("strToUniqueNumberV4"))
         }
         return str_pad($number, 12, '0', STR_PAD_LEFT);
     }
+}
+
+
+if (!function_exists('enbase64url')) {
+    /**
+     * Base64安全URL编码
+     * @param string $string
+     * @return string
+     */
+    function enbase64url(string $string): string
+    {
+        return CodeExtend::enSafe64($string);
+    }
+}
+if (!function_exists('debase64url')) {
+    /**
+     * Base64安全URL解码
+     * @param string $string
+     * @return string
+     */
+    function debase64url(string $string): string
+    {
+        return CodeExtend::deSafe64($string);
+    }
 }

+ 49 - 0
app/model/system/SystemUserOpen.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace app\model\system;
+
+use app\extra\basic\Model;
+
+
+/**
+ * @property integer $id (主键)
+ * @property mixed $openid 
+ * @property string $shop_name 
+ * @property string $nickname 
+ * @property string $headimg 
+ * @property integer $shop_id 门店ID
+ * @property integer $is_msg 1接收
+ * @property mixed $create_at
+ */
+class SystemUserOpen extends Model
+{
+    /**
+     * The connection name for the model.
+     *
+     * @var string|null
+     */
+    protected $connection = 'mysql';
+    
+    /**
+     * The table associated with the model.
+     *
+     * @var string
+     */
+    protected string $table = "system_user_open";
+    
+    /**
+     * The primary key associated with the table.
+     *
+     * @var string
+     */
+    protected string $primaryKey = "id";
+    
+    /**
+     * Indicates if the model should be timestamped.
+     *
+     * @var bool
+     */
+    public bool $timestamps = false;
+
+
+}

BIN
public/uploads/card/1220637573959186-pay.jpg