feat(fsgx): 完成全部24项开发任务 Phase1-7
Phase1 后端核心:
- 新增 fsgx_v1.sql 迁移脚本(is_queue_goods/frozen_points/available_points/no_assess)
- SystemConfigServices 返佣设置扩展(周期人数/分档比例/范围/时机)
- StoreOrderCreateServices 周期循环佣金计算
- StoreOrderTakeServices 佣金发放后同步冻结积分
- StoreProductServices/StoreProduct 保存 is_queue_goods
Phase2 后端接口:
- GET /api/hjf/brokerage/progress 佣金周期进度
- GET /api/hjf/assets/overview 资产总览
- HjfPointsServices 每日 frozen_points 0.4‰ 释放定时任务
- PUT /adminapi/hjf/member/{uid}/no_assess 不考核接口
- GET /adminapi/hjf/points/release_log 积分日志接口
Phase3 前端清理:
- hjfCustom.js 路由精简(仅保留 points/log)
- hjfQueue.js/hjfMember.js API 清理/重定向至 CRMEB 原生接口
- pages.json 公排→推荐佣金/佣金记录/佣金规则
Phase4-5 前端改造:
- queue/status.vue 推荐佣金进度页整体重写
- 商品详情/订单确认/支付结果页文案与逻辑改造
- 个人中心/资产页/引导页/规则页文案改造
- HjfQueueProgress/HjfRefundNotice/HjfAssetCard 组件改造
- 推广中心嵌入佣金进度摘要
- hjfMockData.js 全量更新(公排字段→佣金字段)
Phase6 Admin 增强:
- 用户列表新增 frozen_points/available_points 列及不考核操作按钮
- hjfPoints.js USE_MOCK=false 对接真实积分日志接口
Phase7 配置文档:
- docs/fsgx-phase7-config-checklist.md 后台配置与全链路验收清单
Made-with: Cursor
This commit is contained in:
88
pro_v3.5.1_副本/app/services/pc/CartServices.php
Normal file
88
pro_v3.5.1_副本/app/services/pc/CartServices.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\services\pc;
|
||||
|
||||
|
||||
use app\services\BaseServices;
|
||||
use app\services\order\StoreCartServices;
|
||||
use app\services\product\product\StoreProductServices;
|
||||
use app\services\user\level\SystemUserLevelServices;
|
||||
use app\services\user\member\MemberCardServices;
|
||||
use app\services\user\UserServices;
|
||||
|
||||
class CartServices extends BaseServices
|
||||
{
|
||||
/**
|
||||
* PC端购物车列表
|
||||
* @param int $uid
|
||||
* @return array[]
|
||||
*/
|
||||
public function getCartList(int $uid)
|
||||
{
|
||||
/** @var StoreCartServices $storeCartServices */
|
||||
$storeCartServices = app()->make(StoreCartServices::class);
|
||||
/** @var StoreProductServices $productServices */
|
||||
$productServices = app()->make(StoreProductServices::class);
|
||||
$list = $storeCartServices->getCartList(['uid' => $uid, 'is_pay' => 0, 'is_new' => 0, 'is_del' => 0, 'type' => 0], 0, 0, ['productInfo', 'attrInfo']);
|
||||
/** @var MemberCardServices $memberCardService */
|
||||
$memberCardService = app()->make(MemberCardServices::class);
|
||||
$vipStatus = $memberCardService->isOpenMemberCardCache('vip_price', false);
|
||||
/** @var UserServices $user */
|
||||
$user = app()->make(UserServices::class);
|
||||
$userInfo = $user->getUserInfo($uid);
|
||||
|
||||
//用户等级是否开启
|
||||
$discount = 100;
|
||||
if (sys_config('member_func_status', 1)) {
|
||||
/** @var SystemUserLevelServices $systemLevel */
|
||||
$systemLevel = app()->make(SystemUserLevelServices::class);
|
||||
$discount = $systemLevel->getDiscount($uid, (int)$userInfo['level']);
|
||||
}
|
||||
|
||||
$valid = $invalid = [];
|
||||
foreach ($list as &$item) {
|
||||
$is_valid = $item['attrInfo']['suk'] ?? 0;
|
||||
$item['productInfo']['attrInfo'] = $item['attrInfo'] ?? [];
|
||||
$item['productInfo']['attrInfo']['image'] = $item['attrInfo']['image'] ?? $item['productInfo']['image'];
|
||||
if (isset($item['productInfo']['attrInfo'])) {
|
||||
$item['productInfo']['attrInfo'] = get_thumb_water($item['productInfo']['attrInfo']);
|
||||
}
|
||||
$item['productInfo'] = get_thumb_water($item['productInfo']);
|
||||
$productInfo = $item['productInfo'];
|
||||
$item['vip_truePrice'] = 0;
|
||||
if (isset($productInfo['attrInfo']['product_id']) && $item['product_attr_unique']) {
|
||||
$item['costPrice'] = $productInfo['attrInfo']['cost'] ?? 0;
|
||||
$item['trueStock'] = $productInfo['attrInfo']['stock'] ?? 0;
|
||||
$item['truePrice'] = $productInfo['attrInfo']['price'] ?? 0;
|
||||
$item['sum_price'] = $productInfo['attrInfo']['price'] ?? 0;
|
||||
[$truePrice, $vip_truePrice, $type] = $productServices->setLevelPrice($productInfo['attrInfo']['price'] ?? 0, $uid, $userInfo, $vipStatus, $discount, $productInfo['attrInfo']['vip_price'] ?? 0, $productInfo['is_vip'] ?? 0, true,['level_type'=>$productInfo['level_type'] ?? 1,'level_price'=>$productInfo['attrInfo']['level_price'] ?? '']);
|
||||
} else {
|
||||
$item['costPrice'] = $item['productInfo']['cost'] ?? 0;
|
||||
$item['trueStock'] = $item['productInfo']['stock'] ?? 0;
|
||||
$item['truePrice'] = $item['productInfo']['price'] ?? 0;
|
||||
$item['sum_price'] = $item['productInfo']['price'] ?? 0;
|
||||
[$truePrice, $vip_truePrice, $type] = $productServices->setLevelPrice($item['productInfo']['price'] ?? 0, $uid, $userInfo, $vipStatus, $discount, $item['productInfo']['vip_price'] ?? 0, $item['productInfo']['is_vip'] ?? 0);
|
||||
}
|
||||
$item['truePrice'] = $truePrice;
|
||||
$item['vip_truePrice'] = $vip_truePrice;
|
||||
$item['price_type'] = $type;
|
||||
unset($item['attrInfo']);
|
||||
if ($item['status'] == 1 && $is_valid && $item['trueStock'] > 0) {
|
||||
$valid[] = $item;
|
||||
} else {
|
||||
$invalid[] = $item;
|
||||
}
|
||||
}
|
||||
return ['valid' => $valid, 'invalid' => $invalid];
|
||||
}
|
||||
}
|
||||
145
pro_v3.5.1_副本/app/services/pc/LoginServices.php
Normal file
145
pro_v3.5.1_副本/app/services/pc/LoginServices.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\services\pc;
|
||||
|
||||
|
||||
use app\services\BaseServices;
|
||||
use app\services\user\UserServices;
|
||||
use app\services\wechat\WechatUserServices;
|
||||
use crmeb\services\CacheService;
|
||||
use crmeb\services\wechat\OfficialAccount;
|
||||
use think\exception\ValidateException;
|
||||
|
||||
class LoginServices extends BaseServices
|
||||
{
|
||||
/**
|
||||
* 扫码登陆
|
||||
* @param string $key
|
||||
* @return array|int[]
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public function scanLogin(string $key)
|
||||
{
|
||||
$hasKey = CacheService::has($key);
|
||||
if ($hasKey === false) {
|
||||
$status = 0;//不存在需要刷新二维码
|
||||
} else {
|
||||
$keyValue = CacheService::get($key);
|
||||
if ($keyValue === 0) {
|
||||
$status = 1;//正在扫描中
|
||||
/** @var UserServices $user */
|
||||
$user = app()->make(UserServices::class);
|
||||
$userInfo = $user->get(['uniqid' => $key], ['account', 'uniqid']);
|
||||
if ($userInfo) {
|
||||
$tokenInfo = $this->authLogin($userInfo->account);
|
||||
$tokenInfo['status'] = 3;
|
||||
$userInfo->uniqid = '';
|
||||
$userInfo->save();
|
||||
CacheService::delete($key);
|
||||
return $tokenInfo;
|
||||
}
|
||||
} else {
|
||||
$status = 2;//没有扫描
|
||||
}
|
||||
}
|
||||
return ['status' => $status];
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码登陆
|
||||
* @param string $account
|
||||
* @param string|null $password
|
||||
* @return array
|
||||
*/
|
||||
public function authLogin(string $account, string $password = null)
|
||||
{
|
||||
/** @var UserServices $user */
|
||||
$user = app()->make(UserServices::class);
|
||||
|
||||
$userInfo = $user->get(['account' => $account]);
|
||||
if (!$userInfo) {
|
||||
throw new ValidateException('没有此用户');
|
||||
}
|
||||
if ($password && !password_verify($password, $userInfo->pwd)) {
|
||||
throw new ValidateException('账号或密码错误');
|
||||
}
|
||||
if (!$userInfo->status) {
|
||||
throw new ValidateException('您已被禁止登录');
|
||||
}
|
||||
$uid = (int)$userInfo->uid;
|
||||
$token = $this->createToken($uid, 'api', $userInfo->pwd ?? '');
|
||||
$userInfo->update_time = time();
|
||||
$userInfo->ip = request()->ip();
|
||||
$userInfo->save();
|
||||
|
||||
// 用户登录成功事件
|
||||
event('user.login', [$uid, app('request')->ip()]);
|
||||
return [
|
||||
'token' => $token['token'],
|
||||
'exp_time' => $token['params']['exp'],
|
||||
'userInfo' => $userInfo->toArray()
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function wechatAuth()
|
||||
{
|
||||
/** @var OfficialAccount $service */
|
||||
$service = app()->make(OfficialAccount::class);
|
||||
$info = $service->setAccessEnd(OfficialAccount::PC)->userFromCode();
|
||||
if (!$info) {
|
||||
throw new ValidateException('授权失败');
|
||||
}
|
||||
$wechatInfo = $info;
|
||||
if (!isset($wechatInfo['unionid'])) {
|
||||
throw new ValidateException('unionid不存在');
|
||||
}
|
||||
if (!isset($wechatInfo['nickname'])) {
|
||||
$wechatInfo = OfficialAccount::instance()->user()->get($wechatInfo['openid'])->toArray();
|
||||
if (!isset($wechatInfo['nickname']))
|
||||
throw new ValidateException('授权失败');
|
||||
if (isset($wechatInfo['tagid_list']))
|
||||
$wechatInfo['tagid_list'] = implode(',', $wechatInfo['tagid_list']);
|
||||
} else {
|
||||
if (isset($wechatInfo['privilege'])) unset($wechatInfo['privilege']);
|
||||
/** @var WechatUserServices $wechatUser */
|
||||
$wechatUser = app()->make(WechatUserServices::class);
|
||||
if (!$wechatUser->getOne(['openid' => $wechatInfo['openid']])) {
|
||||
$wechatInfo['subscribe'] = 0;
|
||||
}
|
||||
}
|
||||
$wechatInfo['user_type'] = 'pc';
|
||||
$openid = $wechatInfo['openid'];
|
||||
/** @var WechatUserServices $wechatUserServices */
|
||||
$wechatUserServices = app()->make(WechatUserServices::class);
|
||||
$user = $wechatUserServices->getAuthUserInfo($openid, 'pc');
|
||||
$createData = [$openid, $wechatInfo, 0, 'pc', 'pc'];
|
||||
if (!$user) {
|
||||
$user = $wechatUserServices->wechatOauthAfter($createData);
|
||||
} else {
|
||||
//更新用户信息
|
||||
$wechatUserServices->wechatUpdata([$user['uid'], $wechatInfo]);
|
||||
}
|
||||
$token = $this->createToken((int)$user->uid, 'api', $user->pwd ?? '');
|
||||
return [
|
||||
'token' => $token['token'],
|
||||
'exp_time' => $token['params']['exp']
|
||||
];
|
||||
}
|
||||
}
|
||||
53
pro_v3.5.1_副本/app/services/pc/OrderServices.php
Normal file
53
pro_v3.5.1_副本/app/services/pc/OrderServices.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\services\pc;
|
||||
|
||||
|
||||
use app\services\BaseServices;
|
||||
use app\services\order\StoreOrderServices;
|
||||
|
||||
class OrderServices extends BaseServices
|
||||
{
|
||||
/**
|
||||
* 轮询订单状态
|
||||
* @param string $order_id
|
||||
* @return bool
|
||||
*/
|
||||
public function checkOrderStatus(string $order_id)
|
||||
{
|
||||
/** @var StoreOrderServices $order */
|
||||
$order = app()->make(StoreOrderServices::class);
|
||||
$res = $order->count(['order_id' => $order_id, 'paid' => 1]);
|
||||
if ($res) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
* @param array $where
|
||||
* @param array|string[] $field
|
||||
* @param array $with
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getOrderList(array $where, array $field = ['*'], array $with = [])
|
||||
{
|
||||
/** @var StoreOrderServices $order */
|
||||
$order = app()->make(StoreOrderServices::class);
|
||||
$data['list'] = $order->getOrderApiList($where, $field, $with);
|
||||
$data['count'] = $order->count($where);
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
106
pro_v3.5.1_副本/app/services/pc/ProductServices.php
Normal file
106
pro_v3.5.1_副本/app/services/pc/ProductServices.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\services\pc;
|
||||
|
||||
use app\services\BaseServices;
|
||||
use app\services\other\QrcodeServices;
|
||||
use app\services\product\category\StoreProductCategoryServices;
|
||||
use app\services\product\product\StoreProductServices;
|
||||
use app\services\user\UserServices;
|
||||
|
||||
/**
|
||||
* Class ProductServices
|
||||
* @package app\services\pc
|
||||
*/
|
||||
class ProductServices extends BaseServices
|
||||
{
|
||||
|
||||
/**
|
||||
* PC端获取商品列表
|
||||
* @param array $where
|
||||
* @param int $uid
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProductList(array $where, int $uid)
|
||||
{
|
||||
/** @var StoreProductServices $product */
|
||||
$product = app()->make(StoreProductServices::class);
|
||||
|
||||
$where['is_show'] = 1;
|
||||
$where['is_del'] = 0;
|
||||
$where['is_general_product'] = 1;
|
||||
$where['is_vip_product'] = 0;
|
||||
$where['product_type'] = [0, 1, 2, 3];
|
||||
if ($uid) {
|
||||
/** @var UserServices $userServices */
|
||||
$userServices = app()->make(UserServices::class);
|
||||
$where['is_vip_product'] = $userServices->checkUserIsSvip($uid) ? -1 : 0;
|
||||
}
|
||||
$data['count'] = $product->getCount($where);
|
||||
[$page, $limit] = $this->getPageValue();
|
||||
$list = $product->getSearchList($where, $page, $limit, ['id,store_name,cate_id,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,stock,activity,ot_price,spec_type,recommend_image,unit_name,star'], '', ['couponId']);
|
||||
foreach ($list as &$item) {
|
||||
$item['presale_pay_status'] = $product->checkPresaleProductPay((int)$item['id'], $item);
|
||||
}
|
||||
$list = $product->getActivityList($list);
|
||||
$data['list'] = get_thumb_water($product->getProduceOtherList($list, $uid, !!$where['status']), 'mid');
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* PC端商品详情小程序码
|
||||
* @param int $product_id
|
||||
* @return bool|int|mixed|string
|
||||
*/
|
||||
public function getProductRoutineCode(int $product_id)
|
||||
{
|
||||
try {
|
||||
$namePath = 'routine_product_' . $product_id . '.jpg';
|
||||
/** @var QrcodeServices $QrcodeService */
|
||||
$QrcodeService = app()->make(QrcodeServices::class);
|
||||
//生成小程序地址
|
||||
return $QrcodeService->getRoutineQrcodePath($product_id, 0, 0, $namePath);
|
||||
} catch (\Exception $e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pc首页分类商品
|
||||
* @param int $uid
|
||||
* @return array
|
||||
*/
|
||||
public function getCategoryProduct(int $uid = 0)
|
||||
{
|
||||
/** @var StoreProductCategoryServices $category */
|
||||
$category = app()->make(StoreProductCategoryServices::class);
|
||||
/** @var StoreProductServices $product */
|
||||
$product = app()->make(StoreProductServices::class);
|
||||
[$page, $limit] = $this->getPageValue();
|
||||
$list = $category->getCid($page, $limit);
|
||||
$where = ['is_vip_product' => 0, 'is_general_product' => 1,'is_show' => 1, 'is_del' => 0, 'is_verify' => 1, 'product_type' => [0, 1, 2, 3]];
|
||||
if ($uid) {
|
||||
/** @var UserServices $userServices */
|
||||
$userServices = app()->make(UserServices::class);
|
||||
$where['is_vip_product'] = $userServices->checkUserIsSvip($uid) ? -1 : 0;
|
||||
}
|
||||
$where['pid'] = 0;
|
||||
foreach ($list as &$info) {
|
||||
$productList = $product->getSearchList($where + ['cid' => $info['id']], 1, 8, ['id,store_name,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,ot_price,star']);
|
||||
$info['productList'] = get_thumb_water($productList, 'mid');
|
||||
}
|
||||
$data['list'] = $list;
|
||||
$data['count'] = $category->getCidCount();
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user