SubPotential – 一站式在线购买、管理您的产品和订阅

SubPotential 具有潜力的一站式在线购买、管理订阅系统

欢迎您使用SubPotential!

目前SubPotential 刚刚开发完毕,程序本身可能仍有BUG和不足,也欢迎您向我提出意见和建议。

SubPotential 分为 Public(大众免费版) 和 Pro (专业版),Pro版仍在积极准备和完善中。

Public 最新版本:V1.0.1 您可以在 这里 获取该项目的最新版本

哦对了,欢迎您来群里一起装逼!交流群号码:838624017

功能和特性

1、快速将您的产品或服务作为产品发布至首页,仅需简单几步信息填写。
2、为方便对接QQ机器人,支持产品绑定QQ群号码。
3、为每个产品设置不同的价格和期限方案。
4、支持添加优惠券,对您的产品进行“打折”。
5、在线扫码充值。
6、全平台响应式布局。
7、前台使用精美的Material UI风格。
8、用户组基础权限管理。
9、完善的工单系统(支持添加指定用户为客服,可处理工单,支持工单评价)。

ToDo List
For Pro:
□ 邀请链接返利功能。
For Public:
○ 修复和完善。

演示站

您可以点击这里快速移步到演示站进行查看!

关于 Pro 许可证

对于public 版本,您可以随意无限制的免费使用,分享,修改,但必须遵循MIT许可协议的相关规定

针对于想要拥有更多个性化功能的客户,我们有 Pro (专业版) 可供您选择。

专业版将为您提供:

长期稳定的更新(包括漏洞修复,新功能新特性等)

完善的售后(对于产品的任何问题都可以为您处理)

直接与作者交谈(聆听每个客户的意见,您的意见将直达作者)

Pro用户专属交流群

购买 Pro 许可证

由于目前仍处于完善阶段,还有很多问题需要解决,暂不发放 Pro 版本许可证。您可以先使用我们的Public版本。

相信我会为大家带来一个最棒的专业产品体验!

反馈

您在使用Public版本时遇到任何BUG,或使用中认为有可以优化、修改或发现错别字等各种问题,均可以直接在QQ群内联系或直接发表工单说明。我们将对做出过贡献的客户进行记录,未来在购买Pro许可证时可以获得优惠哦!

ThinkPHP5错误解析之variable type error:array

在TP5的post提交方式中,有一个坑爹的bug就是post提交数据不能提交数组。
请注意是不能提交数组形式的数据,而不是单纯的数据。举个例子:注意以下2种格式数据的比较:
第一种:普通的数据提交,这种格式的数据在TP5中用post提交,$request->post(‘参数’);可以接受数据。

//js,
{
    'data':123,
    'id':1,
    'name':'user'
}

下面看坑爹的第二种:

{
'data':[1,2,3,4,5],
'id':1,
'name':'user'
}

这种形式的数据同过POST提交数据在TP5框架内通过$request->post(‘参数’);去接收就会报错。
variable type error:array
这是因为tp5不能用post去接收数组‘data’:[1,2,3,4,5]这种数据。在通过request的post方法取获取时,post方法不能分辨它是否是数组。
所以在想不改变post提交方式的情况下,解决办法之一就是用/a。(这里的/a就相当于告诉解析器我要获取一个数组。)
将原来的接收方式参数修改为:

$data = $request->post('data/a');
// $data是任意定义的变量。

同时,如果是表单直接提交,也需要把name的值改为数组,也就是加个[]

<select name="sid[]" id="sid" placeholder="必须选择适用产品" data-am-selected="{searchBox: 1}" multiple required>
//部分属性是AmazeUI框架带的,各位读者只需要注意name属性即可

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3hoxr13jt4g0o

php生成唯一订单号的5种方法

这篇文章主要介绍了关于php生成唯一订单号的方法,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

第一种

private function doCreateOrderNumber($time){

          $i=1;

          $dd = date('Ymd',$time);

          $aa = 'OH'.$dd;

          $res = $this->orderModel->query("select sn from sr_order_list where sn like '$aa%' order by id limit 1");

          if(!isset($res[0]['sn'])){

                $i = 1;

          }else{

                $i = (int)substr($res[0]['sn'],9,10) + 1;

          }

          while(true){

                $nsn = 'OH'.$dd.$i;

                $exist = $this->orderModel->query("select id from sr_order_list where sn = '$nsn' ");

                if($exist){

                      $i++;

                }else{

                      return $nsn;

                }

          }

    }

第二种

$osn = date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);

echo $osn; //2018070462577

第三种

$osn = date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);

echo $osn; //2018070499495653

第四种

$order_id_main = date('YmdHis') . rand(10000000,99999999);

  $order_id_len = strlen($order_id_main);

  $order_id_sum = 0;

  for($i=0; $i<$order_id_len; $i++){

  $order_id_sum += (int)(substr($order_id_main,$i,1));

  }

  $osn = $order_id_main . str_pad((100 - $order_id_sum % 100) % 100,2,'0',STR_PAD_LEFT);

echo $osn; //201807041332258742313727

第五种

$code = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');

$osn = $code[intval(date('Y')) - 2011] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));

echo $osn; //H704764673624352

 

ThinkPHP5 另类方法实现分页功能

前言

当然是自己需要这个功能啦。。。

准备

我所用的前端框架是老外用BootStrap4二开的主题,叫MaterialPro(以下简称MP),我会在本文末附上压缩包。非常好用哦。

传统的分页是使用ul li来做,但是最大的问题就是如果没有正好的样式,那么你还得费大半天时间去写样式,烦得很。所以我这次使用的是MP的按钮组,美观也好看。

实现方法

分页实现是用的TP5自带的paginate方法,在Model里查询数据的时候直接使用该方法进行分页。然后将对象返回过来就好。

注意:官方文档写的是使用render方法来分页,但是在这里我们不用这个方法,因为他在我这有各种BUG。

将数据对象返回过来之后,var_dump之后结构是这样的(这里只发出来跟分页有关的数据结构)

protected 'currentPage' => int 1
  protected 'lastPage' => int 1
  protected 'total' => int 4
  protected 'listRows' => int 10
  protected 'hasMore' => boolean false
  protected 'options' =>
    array (size=6)
      'var_page' => string 'page' (length=4)
      'path' => string '/index/index/charge' (length=19)
      'query' =>
        array (size=0)
          empty
      'fragment' => string '' (length=0)
      'type' => string 'bootstrap' (length=9)
      'list_rows' => int 15
  protected 'nextItem' => null

提示:这里很多人会误认为total是总页数,其实是错误的,total是数据总条数。

接下来就是前端了,很easy,我直接把代码贴上来你们读一下就懂了

<div class="float-right">
{if $record->currentPage()>1}
<button id="pre" type="button" class="btn btn-secondary" data-page="/index/index/charge?page={$record->currentPage()-1}">上一页</button>
{/if}
<div class="btn-group" role="group">
{for start="1" end="$record->lastPage()+1" name="page"}
<button type="button" class="pages btn {if $page==$record->currentPage()}btn-info{else /}btn-secondary{/if}" data-page="/index/index/charge?page={$page}">{$page}</button>
{/for}
</div>
{if $record->currentPage()<$record->lastPage()}
<button id="af" type="button" class="btn btn-secondary" data-page="/index/index/charge?page={$record->currentPage()+1}">下一页</button>
{/if}
</div>
<!--这里写分页代码-->

以及js代码

$('#pre').on('click',function () {
window.location.href = $(this).attr('data-page');
});
$('#af').on('click',function () {
window.location.href = $(this).attr('data-page');
});
$('.pages').on('click',function () {
window.location.href = $(this).attr('data-page');
});

最终效果图:

第一页的时候上一页会隐藏,最后一页的时候下一页会隐藏。很NICE

结尾

怎么样,是不是非常easy……