liziyu 发布的文章

修改数据库

ALTER DATABASE your_database_name 
CHARACTER SET = utf8mb4 
COLLATE = utf8mb4_general_ci;

修改表

ALTER TABLE your_table_name 
CONVERT TO CHARACTER SET utf8mb4 
COLLATE utf8mb4_general_ci;

修改字段

ALTER TABLE your_table_name 
CHANGE COLUMN your_column_name your_column_name VARCHAR(255) 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_general_ci;

public function notify(Request $request): Response
    {
        try {
            $app = $this->getEasyApp($request);
            $server = $app->getServer();

            //1、使用微信平台证书,验证签名
            try {
                $app->getValidator()->validate($app->getRequest());
            } catch (\Exception|\Throwable $e) {
                throw new InvalidArgumentException('验证签名失败');
            }

            //2、循环接收验证信息
            //$server->getRequestMessage()
            $server->handlePaid(function (Message $message, \Closure $next) use ($app) {
                //2.1、获取商户订单号
                $msgArray = $message->toArray();
                //2.2、订单查询结果
                $result = $app->getClient()->get("v3/pay/transactions/out-trade-no/{$msgArray['out_trade_no']}", [
                    'query'=>[
                        'mchid' =>  $app->getMerchant()->getMerchantId()
                    ]
                ])->toArray();

                //2.3、支付成功处理业务
                if ($result['trade_state'] === 'SUCCESS') {
                    Db::transaction(function () use ($msgArray) {
                        //2.3.1、 更新订单状态为已支付
                        .....

                        //2.3.2、记录支付成功信息
                        ....

                        //2.3.3、写入缓存,备前端轮循
                        Cache::set($msgArray['out_trade_no'], '', 120);
                    }, 3);
                }
                //2.4、未收到成功消息继续下一个循环接收
                return $next($message);
            });

            // 默认返回 ['code' => 'SUCCESS', 'message' => '成功']
            $response = $server->serve();
            return new Response(
                $response->getStatusCode(),
                $response->getHeaders(),
                $response->getBody()->getContents()
            );
        } catch (\Throwable $throwable) {
            Log::error('[' . __METHOD__ . '][微信支付回调通知] 异常:' . $throwable->getMessage() . PHP_EOL . $throwable->getTraceAsString());
            $data = ['code' => 'FAIL', 'message' => $throwable->getMessage()];

            return new Response(
                400,
                ['Content-Type' => 'application/json'],
                json_encode($data, JSON_UNESCAPED_UNICODE)
            );
        }
    }

使用 ~ 约束符锁定小版本的方式

~1.1.15
是指>= 1.1.15 并且 < 1.2.0的版本
~1.1 表示可以为 大于等于 1.1 的任何版本,比如 1.1.0、1.2.0、1.3.5 、1.99.9999、 1.9999.999999 都可以安装,但是不能安装 2.0.0,

使用^ 锁定不允许变的第一位,即大版本不能变。
^1.2 表示任意大于等于 1.2 的 1.x.x 版本,但是小于2.xx。比如 1.2.0、1.2.1、1.3.0、1.9.99999 等。只要前面的 1 并且大于 ^ 后面指定的 1.2 都满足条件。

使用>=锁定版本范围
有时候我们的使用场景要求只能安装某些版本范围内的时候,可以使用 >、<、>=、<=、| 这些符号来组合,比如:>= 1.3 <1.6、>=1.3 | >=1.7 、3.0|4.0 等。这样的使用场景并不多,根据你的情况来调整用法就好。如果在composer中有多个条件可以使用,隔开,相当于and
例如 >1.3,即只要比1.3版本大即可,如1.4,1.4.9 ,2.0,3.0,4.9.1等

=
使用具体版本号
使用 =1.2.34 或者 1.2.34 都是指定了具体的版本号, composer 不会考虑检查新版本来安装。

一、使用Eloquent ORM法:

在 Laravel 中,您可以使用 Eloquent ORM 来查询数据库表中的数据。假设您要从 Contract 表中查询某个月、某个季度或某年的数据记录,您可以使用 Eloquent 的 where 方法结合 Carbon 库来处理日期。

以下是一些示例代码,展示如何查询特定时间段的数据记录。

1. 查询某个月的数据记录

假设您想查询 2023 年 3 月的数据记录:

use App\Models\Contract;
use Carbon\Carbon;

$month = 3; // 3 月
$year = 2023; // 2023 年

$contractsForMonth = Contract::whereYear('create_time', $year)
    ->whereMonth('create_time', $month)
    ->get();

2. 查询某个季度的数据记录

假设您想查询 2023 年第一季度(1 月至 3 月)的数据记录:

use App\Models\Contract;
use Carbon\Carbon;

$quarter = 1; // 第一季度
$year = 2023; // 2023 年

$startMonth = ($quarter - 1) * 3 + 1; // 计算开始月份
$endMonth = $startMonth + 2; // 计算结束月份(包括3个月)

$contractsForQuarter = Contract::whereYear('create_time', $year)
    ->whereBetween('create_time', [
        Carbon::createFromDate($year, $startMonth, 1)->startOfMonth(),
        Carbon::createFromDate($year, $endMonth, 1)->endOfMonth()
    ])
    ->get();

3. 查询某年的数据记录

假设您想查询 2023 年的数据记录:

use App\Models\Contract;

$year = 2023; // 2023 年

$contractsForYear = Contract::whereYear('create_time', $year)
    ->get();

代码解释

  • whereYear:用于查询指定年份的数据记录。
  • whereMonth:用于查询指定月份的数据记录。
  • whereBetween:用于查询在两个日期之间的数据记录。这里我们使用 Carbon 库来创建开始和结束日期。
  • get():执行查询并获取结果。

使用 Carbon

Carbon 是 Laravel 默认集成的日期处理库,您可以轻松地进行日期计算和格式化。在上述示例中,我们使用 Carbon::createFromDate 方法来创建日期,并使用 startOfMonthendOfMonth 方法来获取月份的开始和结束日期。

总结

通过以上示例,您可以根据需要查询 Contract 表中某个月、某个季度或某年的数据记录。根据您的具体需求,可以进一步调整查询条件。

二、使用Laravel DB门面法:

如果您想在 Laravel 中使用原始的 MySQL 查询语句而不是 Eloquent ORM,可以使用 DB 门面来执行 SQL 查询。以下是如何使用原始 SQL 查询来获取某个月、某个季度和某年的数据记录的示例。

1. 查询某个月的数据记录

假设您想查询 2023 年 3 月的数据记录:

use Illuminate\Support\Facades\DB;

$month = 3; // 3 月
$year = 2023; // 2023 年

$contractsForMonth = DB::select("
    SELECT * FROM contracts 
    WHERE YEAR(create_time) = ? AND MONTH(create_time) = ?", [$year, $month]);

2. 查询某个季度的数据记录

假设您想查询 2023 年第一季度(1 月至 3 月)的数据记录:

use Illuminate\Support\Facades\DB;

$quarter = 1; // 第一季度
$year = 2023; // 2023 年

$startMonth = ($quarter - 1) * 3 + 1; // 计算开始月份
$endMonth = $startMonth + 2; // 计算结束月份(包括3个月)

$contractsForQuarter = DB::select("
    SELECT * FROM contracts 
    WHERE create_time BETWEEN ? AND ?", [
        "{$year}-{$startMonth}-01",
        "{$year}-{$endMonth}-31"
    ]);

3. 查询某年的数据记录

假设您想查询 2023 年的数据记录:

use Illuminate\Support\Facades\DB;

$year = 2023; // 2023 年

$contractsForYear = DB::select("
    SELECT * FROM contracts 
    WHERE YEAR(create_time) = ?", [$year]);

代码解释

  • DB::select:用于执行原始 SQL 查询并返回结果。
  • ? 占位符:用于绑定参数,防止 SQL 注入攻击。
  • [$year, $month]:这是一个数组,包含了要绑定到 SQL 查询中的参数。

注意事项

  • 确保您的数据库表名(如 contracts)与实际数据库中的表名一致。
  • 如果您的 create_time 字段使用了不同的名称或类型,请相应调整 SQL 查询。
  • 使用原始 SQL 查询时,请注意 SQL 注入风险,确保使用参数绑定。

总结

通过以上示例,您可以使用原始 MySQL 查询语句在 Laravel 中查询特定时间段的数据记录,而不依赖于 Eloquent ORM。这在某些情况下可能会更灵活,特别是当您需要执行复杂的查询时。

_)1)@ISS145VH{7)I7CDHTP.png
(M@9@2@~{VX{STI5K$IJ79Q.png
G8QNXEFJ1`K~MX2Q4[M4%FP.png
O058[(D}7(WLHM4~2J{$6PF.png
XV5Z{2IF2EC7C[WF_L}2$TT.png

绕过序列号认证。

function decodeCode(encrypt: string): string {
    const format = (encrypt: string, length: number, offset: number) => {
      const content = ((array, offset) => {
        const max = array.length - offset;
        if (max <= 0) {
          return array;
        }
        const result = new Array(array.length);
        for (let i = 0; i < array.length; i++) {
          if (i < offset) {
            result[i] = array[max + i];
          } else {
            result[i] = array[i - offset];
          }
        }
        return result;
      })(encrypt.split(''), offset).join('');
      const sb: string[] = [];
      let start = 0;
      while (start < content.length) {
        let end = start + length;
        if (end > content.length) {
          end = content.length;
        }
        const item = content.substring(start, end);
        sb.push(item.split('').reverse().join(''));
        start = end;
      }
      return sb.join('');
    };
    const KEY_ENCRYPT =
      'BAFEDIHGLKJONMRQPUTSXWVaZYdcbgfejihmlkponsrqvutyxw10z432765+98/C';
    const index = encrypt.indexOf('=');
    const body = index === -1 ? encrypt : encrypt.substring(0, index);
    const suffix = index === -1 ? '' : encrypt.substring(index);
    const temp = format(body, 12, 3) + suffix;
    const input = temp.replace(/[^A-Za-z0-9\+\/\=]/g, '');
    const KEYS = format(KEY_ENCRYPT, 3, 1) + '=';
    let output = '';
    let chr1: number, chr2: number, chr3: number;
    let enc1: number, enc2: number, enc3: number, enc4: number;
    let i = 0;
    while (i < input.length) {
      enc1 = KEYS.indexOf(input.charAt(i++));
      enc2 = KEYS.indexOf(input.charAt(i++));
      enc3 = KEYS.indexOf(input.charAt(i++));
      enc4 = KEYS.indexOf(input.charAt(i++));
      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;
      output = output + String.fromCharCode(chr1);
      if (enc3 != 64) {
        output = output + String.fromCharCode(chr2);
      }
      if (enc4 != 64) {
        output = output + String.fromCharCode(chr3);
      }
    }
    output = ((utftext) => {
      let string = '';
      let i = 0;
      let c = 0;
      let c2 = 0;
      let c3 = 0;
      while (i < utftext.length) {
        c = utftext.charCodeAt(i);
        if (c < 128) {
          string += String.fromCharCode(c);
          i++;
        } else if (c > 191 && c < 224) {
          c2 = utftext.charCodeAt(i + 1);
          string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
          i += 2;
        } else {
          c2 = utftext.charCodeAt(i + 1);
          c3 = utftext.charCodeAt(i + 2);
          string += String.fromCharCode(
            ((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
          );
          i += 3;
        }
      }
      return string;
    })(output);
    return output;
  }

var addresses []model.Address
if ret := s.db.WithContext(ctx).Model(&model.Address{}).
    Where("member_id = ?", memberId).Find(&addresses); ret.Error != nil {
    return
}
if len(addresses) > 0 {
    defineAddressIndex := 0
    for i, address := range addresses {
        if address.IsDefault == 1 {
            defineAddressIndex = i
            break
        }
    }
    result.Address = addresses[defineAddressIndex]
}

代码

package utils

import (
    "crypto/rand"
    "encoding/hex"
    "fmt"
)

func New() string {
    uuid, _ := GenerateUUID()
    return uuid
}

// GenerateRandomBytes is used to generate random bytes of given size.
func GenerateRandomBytes(size int) ([]byte, error) {
    buf := make([]byte, size)
    if _, err := rand.Read(buf); err != nil {
        return nil, fmt.Errorf("failed to read random bytes: %v", err)
    }
    return buf, nil
}

const uuidLen = 16

// GenerateUUID is used to generate a random UUID
func GenerateUUID() (string, error) {
    buf, err := GenerateRandomBytes(uuidLen)
    if err != nil {
        return "", err
    }
    return FormatUUID(buf)
}

func FormatUUID(buf []byte) (string, error) {
    if buflen := len(buf); buflen != uuidLen {
        return "", fmt.Errorf("wrong length byte slice (%d)", buflen)
    }

    return fmt.Sprintf("%x-%x-%x-%x-%x",
        buf[0:4],
        buf[4:6],
        buf[6:8],
        buf[8:10],
        buf[10:16]), nil
}

func ParseUUID(uuid string) ([]byte, error) {
    if len(uuid) != 2*uuidLen+4 {
        return nil, fmt.Errorf("uuid string is wrong length")
    }

    if uuid[8] != '-' ||
        uuid[13] != '-' ||
        uuid[18] != '-' ||
        uuid[23] != '-' {
        return nil, fmt.Errorf("uuid is improperly formatted")
    }

    hexStr := uuid[0:8] + uuid[9:13] + uuid[14:18] + uuid[19:23] + uuid[24:36]

    ret, err := hex.DecodeString(hexStr)
    if err != nil {
        return nil, err
    }
    if len(ret) != uuidLen {
        return nil, fmt.Errorf("decoded hex is the wrong length")
    }

    return ret, nil
}

使用

uud := utils.New()
fmt.Println(uud)
//9a317a2c-b5d1-ae15-7d76-27f2b48d539a