一个基于Yii2高级框架的快速开发应用引擎

Overview

RageFrame 2.0

重量级全栖框架,为二次开发而生

前言

这是一款现代化、快速、高效、便捷、灵活、方便扩展的应用开发骨架。

RageFrame 创建于 2016 年 4 月 16 日,一个基于 Yii2 高级框架的快速开发引擎,目前正在成长中,目的是为了集成更多的基础功能,不再为相同的基础功能重复制造轮子,开箱即用,让开发变得更加简单。
2018 年 9 月 10 日 2.0 版本正式上线,经过 1.0 版本一年多的开源反馈磨合,以更加优秀的形态出现。对 1.0 的版本进行了重构优化完善,更好的面向开发者进行二次开发。2.3.x 版本更是优化了底层突出了服务层,分离业务逻辑,支持多商户。

特色

  • 极强的可扩展性,应用化,模块化,插件化机制敏捷开发。
  • 极致的插件机制,微核架构,良好的功能延伸性,功能之间是隔离,可定制性高,可以渐进式地开发,逐步增加功能,安装和卸载不会对原来的系统产生影响,强大的功能完全满足各阶段的需求,支持用户多端访问(后台、微信、Api、前台等)。
  • 极完善的 RBAC 权限控制管理、无限父子级权限分组、可自由分配子级权限,且按钮/链接/自定义内容/插件等都可加入权限控制。
  • 只做基础底层内容,不会在上面开发过多的业务内容,满足绝大多数的系统二次开发。
  • 多入口模式,多入口分为 Backend (后台)、Merchant (商户端)、Frontend (PC前端)、Html5 (手机端)、Console (控制台)、Api (对内接口)、OAuth2 Server (对外接口)、MerApi (商户接口)、Storage (静态资源),不同的业务,不同的设备,进入不同的入口。
  • 对接微信公众号且支持小程序,使用了一款优秀的微信非官方 SDK Easywechat 4.x,开箱即用,预置了绝大部分功能,大幅度的提升了微信开发效率。
  • 整合了第三方登录,目前有 QQ、微信、微博、GitHub 等等。
  • 整合了第三方支付,目前有微信支付、支付宝支付、银联支付,二次封装为网关多个支付一个入口一个出口。
  • 整合了 RESTful API,支持前后端分离接口开发和 App 接口开发,可直接上手开发业务。
  • 一键切换云存储,本地存储、腾讯 COS、阿里云 OSS、七牛云存储都可一键切换,且增加其他第三方存储也非常方便。
  • 全面监控系统报错,报错日志写入数据库,方便定位错误信息。支持直接钉钉提醒。
  • 快速高效的 Servises (服务层),遵循 Yii2 的懒加载方式,只初始化使用到的组件服务。
  • 丰富的表单控件(时间、日期、时间日期、日期范围选择、颜色选择器、省市区三级联动、省市区勾选、单图上传、多图上传、单文件上传、多文件上传、百度编辑器、百度图表、多文本编辑框、地图经纬度选择器、图片裁剪上传、TreeGrid、JsTree、Markdown 编辑器)和组件(二维码生成、Curl、IP地址转地区),快速开发,不必再为基础组件而担忧。
  • 快速生成 CURD ,无需编写代码,只需创建表设置路径就能出现一个完善的 CURD ,其中所需表单控件也是勾选即可直接生成。
  • 正常开发只需要开发商户端,没有 Saas 的时候商户端就是总后台,有了 Saas,商户端就是子后台
  • 完善的文档和辅助类,方便二次开发与集成。

思维导图

image

应用架构流程

image

系统快照

【系统 - 首页】 image 【系统 - 配置管理】 image 【系统 - 角色编辑】 image 【系统 - 日志统计】 image 【会员 - 信息】 image 【微信 - 自定义菜单】 image 【插件模块 - 列表】 image 【插件模块 - 文章模块】 image 【插件模块 - 系统监控】 image

开始之前

  • 具备 PHP 基础知识
  • 具备 Yii2 基础开发知识
  • 具备 开发环境的搭建
  • 仔细阅读文档,一般常见的报错可以自行先解决,解决不了再来提问
  • 如果要做小程序或微信开发需要明白微信接口的组成,自有服务器、微信服务器、公众号(还有其它各种号)、测试号、以及通信原理(交互过程)
  • 如果需要做接口开发(RESTful API)了解基本的 HTTP 协议,Header 头、请求方式(GET\POST\PUT\PATCH\DELETE)等
  • 能查看日志和 Debug 技能
  • 一定要仔细走一遍文档

Demo

地址:http://demo2.rageframe.com/backend
账号:demo
密码:123456

官网

http://www.rageframe.com

文档

安装文档 · 本地文档 · 更新历史 · 常见问题

插件

问题反馈

在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

QQ群1:655084090 (2000人快满)
QQ群2:1148015133 (新群)

GitHub:https://github.com/jianyan74/rageframe2/issues

特别鸣谢

感谢以下的项目,排名不分先后

Yii:http://www.yiiframework.com

EasyWechat:https://www.easywechat.com

Bootstrap:http://getbootstrap.com

AdminLTE:https://adminlte.io

...

版权信息

RageFrame 遵循 Apache2 开源协议发布,并提供免费使用。

本项目包含的第三方源码和二进制文件之版权信息另行标注。

版权所有Copyright © 2016-2020 by RageFrame www.rageframe.com

All rights reserved。

Comments
  • 在你这个微信开发到底是在后台配置参数还是在配置文件里配置

    在你这个微信开发到底是在后台配置参数还是在配置文件里配置

    1.在你这个微信开发到底是在后台配置参数还是在配置文件里配置? 2.代码有点凌乱,搞个微信开发,各种问题层出不穷,session是用_wechatUser获取微信用户参数,还是wechatUser? 3.你这边微信这个你自己试过了么,如果你自己都没有把握,那我还是不用你这个项目了,我找其他项目做微信开发

    opened by codetown 9
  • 执行这一步php ./yii migrate/up

    执行这一步php ./yii migrate/up

    PHP Warning: require(/www/wwwroot/mall.baisoft.co/rageframe2/vendor/autoload.php): failed to open stream: No such file or directory in /www/wwwroot/mall.baisoft.co/rageframe2/yii on line 10

    Warning: require(/www/wwwroot/mall.baisoft.co/rageframe2/vendor/autoload.php): failed to open stream: No such file or directory in /www/wwwroot/mall.baisoft.co/rageframe2/yii on line 10 PHP Fatal error: require(): Failed opening required '/www/wwwroot/mall.baisoft.co/rageframe2/vendor/autoload.php' (include_path='.:/www/server/php/55/lib/php') in /www/wwwroot/mall.baisoft.co/rageframe2/y ii on line 10

    Fatal error: require(): Failed opening required '/www/wwwroot/mall.baisoft.co/rageframe2/vendor/autoload.php' (include_path='.:/www/server/php/55/lib/php') in /www/wwwroot/mall.baisoft.co/rageframe2/yii on line 10

    发现没有这个目录:vendor

    opened by Baiqu 5
  • Who to contact for security issues

    Who to contact for security issues

    Hey there!

    I belong to an open source security research community, and a member (@asura-n) has found an issue, but doesn’t know the best way to disclose it.

    If not a hassle, might you kindly add a SECURITY.md file with an email, or another contact method? GitHub recommends this best practice to ensure security issues are responsibly disclosed, and it would serve as a simple instruction for security researchers in the future.

    Thank you for your consideration, and I look forward to hearing from you!

    (cc @huntr-helper)

    opened by zidingz 3
  • 关于微信公众号插件获取用户列表的问题

    关于微信公众号插件获取用户列表的问题

    公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。

    目前设计没有考虑到, 单次拉取只能是10000个关注者, 当关注者超过2万个时, 后面一个关注者数据无法获取.

    opened by uutan 3
  • 你好,非常感謝你提供的代碼,有以下問題

    你好,非常感謝你提供的代碼,有以下問題

    1、後臺有沒有幫助說明 2、找不到說明,研究了一下,裝好了商戶,打開商戶註冊,但註冊進來的用戶,是未授權的狀態,如果在後臺裏增加用戶,就可以選擇角色。(這一點,也不確定是不是後臺創建的角色,如果沒有角色就是不行的,但如果沒有角色,是否讓註冊) 3、後臺也沒有對用戶,設定角色的功能。 4、商戶的用戶登陸進來,沒有微商城的入口,找到商家配置裏有,但不知道如何增加微商城的功能,同時也不知道,是不是每個商戶增加的商品是屬該商戶自己所有。 暫時發現這時問題,希望這個系統能用進來。

    opened by Baiqu 3
  • 支付回调的demo和文档里写的不一致,我测了两种方式都不能正常执行代码

    支付回调的demo和文档里写的不一致,我测了两种方式都不能正常执行代码

    $response = Yii::$app->wechat->payment->handlePaidNotify(function ($message, $fail) { // 你的逻辑 return true; // 或者错误消息 $fail('Order not exists.'); }); $response->send();

    $response = Yii::$app->pay->wechat->notify(); //var_dump($response);exit; if ($response->isPaid())//一直返回false,支付是成功的 { //pay success 注意微信会发二次消息过来 需要判断是通知还是回调 var_dump($response->getRequestData());

            // 成功通知
            return PayHelper::notifyWechatSuccess();
        }
        else
        {
            // 失败通知
            return PayHelper::notifyWechatFail();
        }
    
    opened by codetown 3
  • 基于此项目开发的平台和线下机器交互报错 mb_strlen() expects parameter 1 to be string, array given

    基于此项目开发的平台和线下机器交互报错 mb_strlen() expects parameter 1 to be string, array given

    使用rageframe2框架加swoole开发的平台和线下机器交互,线下机器会向服务器推送数据。线下机器在每天会在夜里2点钟定时重启,重启之后就无法与服务器连接,报错 “mb_strlen() expects parameter 1 to be string, array given”,必须手动重启swoole。以下是错误日志:
    

    2020-09-27 02:01:10 修改fd信息:-----mb_strlen() expects parameter 1 to be string, array given^M 2020-09-27 02:01:10 修改fd信息:-----mb_strlen() expects parameter 1 to be string, array given^M 2020-09-27 02:01:10 修改fd信息:-----mb_strlen() expects parameter 1 to be string, array given^M 2020-09-27 02:01:10 yii\db\Exception Object ( [errorInfo] => Array ( )

    [message:protected] => Received illegal data from redis: ated_at
    

    Redis command was: EVAL local allpks=redis.call('LRANGE','cabinet_fd',0,-1) local pks={} local n=0 local v=nil local i=0 local key='cabinet_fd' for k,pk in ipairs(allpks) do local cfd0=redis.call('HGET','cabinet_fd' .. ':a:' .. pk, 'fd')

    if cfd0=='146' then
      i=i+1
      if i>0 then
        do return redis.call('HGETALL','cabinet_fd:a:' .. pk) end
      end
    end
    

    end return pks 0 [string:Exception:private] => [code:protected] => 0 [file:protected] => /www/wwwroot/power/vendor/yiisoft/yii2-redis/src/Connection.php [line:protected] => 856 [trace:Exception:private] => Array ( [0] => Array ( [file] => /www/wwwroot/power/vendor/yiisoft/yii2-redis/src/Connection.php [line] => 851 [function] => parseResponse [class] => yii\redis\Connection [type] => -> [args] => Array ( [0] => Array ( [0] => EVAL [1] => local allpks=redis.call('LRANGE','cabinet_fd',0,-1) local pks={} local n=0 local v=nil local i=0 local key='cabinet_fd' for k,pk in ipairs(allpks) do local cfd0=redis.call('HGET','cabinet_fd' .. ':a:' .. pk, 'fd')

    if cfd0=='146' then
      i=i+1
      if i>0 then
        do return redis.call('HGETALL','cabinet_fd:a:' .. pk) end
      end
    end
    

    end return pks [2] => 0 )

                        )
    
                )
    
            [1] => Array
                (
                    [file] => /www/wwwroot/power/vendor/yiisoft/yii2-redis/src/Connection.php
                    [line] => 851
                    [function] => parseResponse
                    [class] => yii\redis\Connection
                    [type] => ->
                    [args] => Array
                        (
                            [0] => Array
                                (
                                    [0] => EVAL
                                    [1] => local allpks=redis.call('LRANGE','cabinet_fd',0,-1)
    

    local pks={} local n=0 local v=nil local i=0 local key='cabinet_fd' for k,pk in ipairs(allpks) do local cfd0=redis.call('HGET','cabinet_fd' .. ':a:' .. pk, 'fd')

    if cfd0=='146' then
      i=i+1
      if i>0 then
        do return redis.call('HGETALL','cabinet_fd:a:' .. pk) end
      end
    end
    

    end return pks [2] => 0 )

                        )
    
                )
    
            [2] => Array
                (
                    [file] => /www/wwwroot/power/vendor/yiisoft/yii2-redis/src/Connection.php
                    [line] => 796
                    [function] => parseResponse
                    [class] => yii\redis\Connection
                    [type] => ->
                    [args] => Array
                        (
                            [0] => Array
                                (
                                    [0] => EVAL
                                    [1] => local allpks=redis.call('LRANGE','cabinet_fd',0,-1)
    

    local pks={} local n=0 local v=nil local v=nil local i=0 local key='cabinet_fd' for k,pk in ipairs(allpks) do local cfd0=redis.call('HGET','cabinet_fd' .. ':a:' .. pk, 'fd')

    if cfd0=='146' then
      i=i+1
      if i>0 then
        do return redis.call('HGETALL','cabinet_fd:a:' .. pk) end
      end
    end
    

    end return pks [2] => 0 )

                        )
    
                )
    
            [2] => Array
                (
                    [file] => /www/wwwroot/power/vendor/yiisoft/yii2-redis/src/Connection.php
                    [line] => 796
                    [function] => parseResponse
                    [class] => yii\redis\Connection
                    [type] => ->
                    [args] => Array
                        (
                            [0] => Array
                                (
                                    [0] => EVAL
                                    [1] => local allpks=redis.call('LRANGE','cabinet_fd',0,-1)
    

    local pks={} local n=0 local v=nil local i=0 local key='cabinet_fd' for k,pk in ipairs(allpks) do local cfd0=redis.call('HGET','cabinet_fd' .. ':a:' .. pk, 'fd')

    if cfd0=='146' then
      i=i+1
      if i>0 then
        do return redis.call('HGETALL','cabinet_fd:a:' .. pk) end
      end
    end
    

    end return pks [2] => 0 )

                            [1] => *3^M
    

    $4^M EVAL^M $371^M

    opened by zhaobing45 2
  • 执行 php composer.phar install时卡死

    执行 php composer.phar install时卡死

    当我按照文档git clone下载完项目,进入项目目录,命令行执行php composer.phar install,命令行一个小时都没有变化,只有两行提示语 Loading composer repositories with package information Updating dependencies (including require-dev)

    我百度试了很多方法都没啥用,如 更新composer,清理composer缓存,更换composer源...

    请问该如何才能快速的下载项目所依赖的包呢?

    opened by allenE1 2
  • 用gii生成model和CRUD碰到的几个坑

    用gii生成model和CRUD碰到的几个坑

    gii可以正常生成文件,但是访问的时候会报错

    1、主键名称必须是“id”,其他的比如“xxx_id”会报错; 2、表里面必须包含字段“status”,否则需要改index视图文件; 3、common/components/Curd.php#161里面有一个查询条件andFilterWhere(['merchant_id' => $this->getMerchantId()]),不太懂加这个判断条件的作用是什么。

    opened by han-dong 2
  • 执行`php ./yii migrate/up`报错

    执行`php ./yii migrate/up`报错

    PHP Warning: require(/opt/rageframe2/vendor/autoload.php): failed to open stream: No such file or directory in /opt/rageframe2/yii on line 10 PHP Fatal error: require(): Failed opening required '/opt/rageframe2/vendor/autoload.php' (include_path='.:/usr/share/pear:/usr/share/php') in /opt/rageframe2/yii on line 10

    opened by jroxn 1
  • Reflective Cross Site Scripting at info.php

    Reflective Cross Site Scripting at info.php

    Reflective Cross Site Scripting at info.php

    1. I found that at line 50 of backend/common/system/info.php, Receive parameters without any filtering at $_SERVER['HTTP_USER_AGENT'].

    image

    1. This is an official demo site http://demo2.rageframe.com/backend [login:demo/123456], I use it directly to verify this vulnerability. Request info.php via route backend/common/system/info,Capture packets through burpsuit and modify user agent. The payload is as follows:
    GET /backend/common/system/info HTTP/1.1
    Host: demo2.rageframe.com
    User-Agent: <script>alert('xss')</script>
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    Accept-Encoding: gzip, deflate
    Connection: close
    Cookie: advanced-backend=q7hbabkafnfrp83q3j27282koj; _csrf-backend=f21cf822806330da09d827f33031aed2057badeedb2cb7e9d27b061ef13e3b1fa%3A2%3A%7Bi%3A0%3Bs%3A13%3A%22_csrf-backend%22%3Bi%3A1%3Bs%3A32%3A%227bTiShE-5nCefANCrKRocM2TRpdPfsMW%22%3B%7D; _identity-backend=1abd9d20c81548f5bc6855b17d7f3892911371c4f3840ed0f4bee73e640ac5c1a%3A2%3A%7Bi%3A0%3Bs%3A17%3A%22_identity-backend%22%3Bi%3A1%3Bs%3A46%3A%22%5B2%2C%22xk29SFJDfewTmzBAObyXkpPZ30myMQr5%22%2C2592000%5D%22%3B%7D
    Upgrade-Insecure-Requests: 1
    
    1. Request url http://demo2.rageframe.com/backend/common/system/info, modify user agent to .

    image

    image

    opened by chasingboy 4
  • 在后台端和商户端生成的HTML5地址时URL美化规则未生效

    在后台端和商户端生成的HTML5地址时URL美化规则未生效

    在后台端和商户端生成的HTML5地址时URL美化规则未生效.

    插件名: ad

    在后台端和商户端生成Html5地址:

    $model->id,'agent_id'=>$item->id])?>

    生成地址为: http://a.com/html5/ad/qrcode/view?merchant_id=1&id=3 在html5端设置URL美化时: 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'suffix' => '.html', 'rules' => [ 'q/<merchant_id:\d+>-<id:\d+>' => 'ad/qrcode/view', ], ], 生成的地址为: http://a.com/html5/q/1-3.html // 已成功. 后台生成html5网址时, 应该是返回重写地址.

    opened by uutan 0
Owner
简言
好好学习,天天向上
简言