初始化项目:添加后端代码、ThinkPHP框架、前端资源

This commit is contained in:
amb
2026-09-03 12:42:39 +08:00
commit 482bece22e
3726 changed files with 416708 additions and 0 deletions
@@ -0,0 +1,616 @@
<?php
namespace app\admin\model\app\coupon;
use think\Model;
use app\admin\model\app\coupon\CouponUser as CouponUserModel;
use app\admin\model\app\coupon\CouponGoods;
class Coupon extends Model
{
// use SoftDelete;
protected $deleteTime = 'deletetime';
protected $name = 'app_coupon';
protected $type = [
// 'use_start_time' => 'timestamp',
// 'use_end_time' => 'timestamp',
];
// 追加属性
protected $append = [
'type_text',
'use_num',
'get_num',
'status_text',
'use_scope_text',
'amount_text',
'use_time_status',
'use_time_text',
'stock_all',
'stock_prop',
'received',
'goods_bind_ids'
];
/**
* 默认类型列表
*
* @return array
*/
public function getTypeList()
{
return [
'reduce' => '满减券',
'discount' => '折扣券'
];
}
/**
* 可用范围列表
*
* @return array
*/
public function useScopeList()
{
return [
'all_use' => '全场通用',
'goods' => '指定商品可用',
'disabled_goods' => '指定商品不可用'
];
}
/**
* 优惠券领取状态
*
* @return void
*/
public function getStatusList()
{
return [
'1'=>'进行中',
'2'=>'已停止',
'3'=>'已作废',
'4'=>'未开始',
'5'=>'已结束'
];
}
/**
* 优惠券领取状态
*
* @return void
*/
public function getGetStatusList()
{
return [
'ing'=>'立即领取',
'cannot_get'=>'已达最大领取次数',
'get_stop'=>'已停止',
'get_destroy'=>'已作废',
'ended'=>'已结束',
'get_over'=>'已领完'
];
}
public function scopeCanGet($query)
{
// 当use_time_type=range代表可用时间区间, use_start_time代表开始时间,use_end_time代表结束时间。获取可用区间内的优惠券
// 当use_time_type=days代表可用天数
//获取有效期内'deletetime'=>NULL'status'=>1的优惠券
//获取use_time_type=days,'deletetime'=>NULL'status'=>1的优惠券
return $query->where([
'deletetime'=>NULL,
'status'=>1
])->where(function ($query) {
$query->where(function ($query) {
$query->where('use_time_type', 'range')
->where('use_start_time', '<=', time())
->where('use_end_time', '>=', time());
})->whereOr(function ($query) {
$query->where('use_time_type', 'days');
});
});
}
public function scopePublicShow($query)
{
return $query->where([
'public_status'=>1
]);
}
/**
* 查询指定商品满足的优惠券
* @param [type] $query
* @param [type] $goods
* @return void
*/
public function scopeGoods($query, $goods)
{
$goods_id = $goods['goods_id'];
$goods_type = $goods['goods_type'];
// 查询符合商品的优惠券
return $query->where(function ($query) use ($goods_id,$goods_type) {
$query->where('use_scope', 'all_use')
->whereOr(function ($query) use ($goods_id,$goods_type) {
$query->where('use_scope', 'goods')
->whereExists(function ($subQuery) use ($goods_id,$goods_type) {
$subQuery->table(CouponGoods::getTable())
->whereRaw('`coupon_id` = `'.self::getTable().'`.`id`')
->where('goods_id', $goods_id)
->where('goods_type', $goods_type);
});
})
->whereOr(function ($query) use ($goods_id,$goods_type) {
$query->where('use_scope', 'disabled_goods')
->whereNotExists(function ($subQuery) use ($goods_id,$goods_type) {
$subQuery->table(CouponGoods::getTable())
->whereRaw('`coupon_id` = `'.self::getTable().'`.`id`')
->where('goods_id', $goods_id)
->where('goods_type', $goods_type);
});
});
});
}
/**
* 可用范围获取器
*
* @param string $value
* @param array $data
* @return string
*/
public function getUseScopeTextAttr($value, $data)
{
$value = $value ?: ($data['use_scope'] ?? null);
$list = $this->useScopeList();
return isset($list[$value]) ? $list[$value] : '';
}
/**
* 类型
* @param string $value
* @param array $data
* @return string
*/
public function getTypeTextAttr($value, $data)
{
$value = $value ?: ($data['type'] ?? null);
$list = $this->getTypeList();
return isset($list[$value]) ? $list[$value] : '';
}
/**
* 状态
* @param string $value
* @param array $data
* @return string
*/
public function getStatusTextAttr($value, $data)
{
$value = $value ?: ($data['status'] ?? null);
$list = $this->getStatusList();
return isset($list[$value]) ? $list[$value] : '';
}
public function getAmountTextAttr($value, $data)
{
return '满' . $data['enough'] . '元,' . ($data['type'] == 'reduce' ? '减' . floatval($data['amount']) . '元' : '打' . floatval($data['discount']) . '折');
}
public function getGoodsValueAttr($value, $data)
{
$goods_value = [];
if (in_array($data['use_scope'], ['goods', 'disabled_goods'])) {
$query = \app\common\model\goods\Handle::getGoodsQuery();
$goods = CouponGoods::where([
'coupon_id'=>$data['id']
])->field(['goods_type','goods_id'])->select();
if($goods){
foreach ($goods as $item){
$query->whereOr(function ($query) use ($item){
$query->where([
'id'=>$item['goods_id'],
'type'=>$item['goods_type']
]);
});
}
$goods_value = $query->select();
$goods_value = collection($goods_value);
}
}
return $goods_value ?? [];
}
/**
* 通过优惠券 ids 集合获取可正常展示的优惠券
* @param $ids
* @return void
*/
public function idsGetCoupon($ids,$limit=0){
$user = user_info();
$coupons = self::canGet()
->publicShow()
->where([
'id'=>['in',$ids]
]) // 符合指定商品,并且检测商品所属分类
->order('id', 'desc');
if($limit){
$coupons = $coupons->limit($limit);
}
if ($user) {
// 关联用户优惠券
$coupons = $coupons->with(['userCoupons']);
}
$coupons = $coupons->select();
$coupons = collection($coupons)->each(function ($coupon) {
$coupon->get_status = $coupon->get_status;
$coupon->get_status_text = $coupon->get_status_text;
});
return $coupons;
}
/**
* 通过优惠券 ids 集合获取可正常展示的优惠券
* @param $ids
* @return void
*/
public function getNewCoupon($limit=0){
$user = user_info();
$coupons = self::canGet()
->publicShow()
->order('id', 'desc');
if($limit){
$coupons->limit($limit);
}
if ($user) {
// 关联用户优惠券
$coupons = $coupons->with(['userCoupons']);
}
$coupons = $coupons->select();
$coupons = collection($coupons)->each(function ($coupon) {
$coupon->get_status = $coupon->get_status;
$coupon->get_status_text = $coupon->get_status_text;
});
return $coupons;
}
/**
* 获取优惠券绑定的商品列表
* @param $value
* @param $data
* @return array
*/
public function getGoodsBindIdsAttr($value, $data)
{
$goods_value = [];
if (in_array($data['use_scope'], ['goods', 'disabled_goods'])) {
$goods = CouponGoods::where([
'coupon_id'=>$data['id']
])->field(['goods_type','goods_id'])->select();
if($goods){
foreach ($goods as $item){
$goods_value[] = $item['goods_id']."_".$item['goods_type'];
}
}
}
return $goods_value ?? [];
}
/**
* 优惠券可使用的商品列表
* @param $value
* @param $data
* @return array
*/
public function getCanUseGoodsValueAttr($value, $data)
{
$query = \app\common\model\goods\Handle::getGoodsQuery();
$queryCondition = [
'pay_type'=>'pay',
'status'=>1
];
$excludeTypes = ['test'];
if (\app\common\library\Platform::getPlatform() === 'wxMiniProgram') {
$virtualPayConfig = \app\common\model\config\System::getConfig('virtual_pay');
if ($virtualPayConfig && ($virtualPayConfig['status'] ?? 'close') === 'open') {
$virtualGoodsTypes = $virtualPayConfig['virtual_goods_types'] ?? [];
if (!empty($virtualGoodsTypes)) {
$excludeTypes = array_merge($excludeTypes, $virtualGoodsTypes);
}
}
}
if (in_array($data['use_scope'], ['goods', 'disabled_goods'])) {
$goods = CouponGoods::where([
'coupon_id'=>$data['id']
])->field(['goods_type','goods_id'])->select();
if($data['use_scope'] == 'goods'){
if(!$goods){
return [];
}
foreach ($goods as $item){
if (in_array($item['goods_type'], $excludeTypes, true)) {
continue;
}
$query->whereOr(function ($query) use ($item,$queryCondition){
$query->where([
'id'=>$item['goods_id'],
'type'=>$item['goods_type']
])->where($queryCondition);
});
}
}else{
if($goods){
$filteredGoods = [];
foreach ($goods as $item) {
if (in_array($item['goods_type'], $excludeTypes, true)) {
continue;
}
$filteredGoods[] = $item;
}
if (!empty($filteredGoods)) {
$subQuery = \app\common\model\goods\Handle::getGoodsQuery()->where(function ($query) use ($filteredGoods,$queryCondition) {
foreach ($filteredGoods as $item) {
$query->whereOr(function ($q) use ($item,$queryCondition) {
$q->where([
'id'=>$item['goods_id'],
'type'=>$item['goods_type']
])->where($queryCondition);
});
}
})->buildSql();
// 查询不满足条件的数据
$query->where('id', 'not in', function ($query) use ($subQuery) {
$query->table($subQuery . ' temp')->field('id');
});
}
}
}
}else{
$query = $query->where($queryCondition);
if (!empty($excludeTypes)) {
$query->where('type', 'not in', $excludeTypes);
}
}
$goods_value = $query->limit(100)->order('goods.id',"desc")->select();
$goods_value = collection($goods_value);
return $goods_value ?? [];
}
/**
* 判断是否已领取
* @param $value
* @param $data
* @return void
*/
public function getReceivedAttr($value, $data)
{
$user = user_info();
if(!$user){
return false;
}
$canUse = CouponUserModel::where('user_id', $user->id)
->where('coupon_id', $data['id'])
->find();
if(!$canUse){
return false;
}
return true;
}
public function getGetStatusAttr($value, $data)
{
if($data['status'] == 2){
return 'get_stop'; // 已停止
}
if($data['status'] == 3){
return 'get_destroy'; // 已作废
}
$limit_num = $data['limit_status'] == 1 ? 10000 : ($data['limit_num'] ?? 0);
// 不限制领取次数,或者限制次数,领取数量还没达到最大值
$get_status = (!$limit_num || ($limit_num && $limit_num > count($this->user_coupons))) ? 'can_get' : 'cannot_get';
if ($get_status == 'can_get' && $data['stock'] <= 0) {
$get_status = 'get_over'; // 已领完
}
// $user_coupon_id = request()->param('ucid', 0);
// if ($user_coupon_id) {
// // 从我领取的优惠券进详情,覆盖 状态
// $user = user_info();
// $userCoupon = CouponUserModel::where('user_id', ($user ? $user->id : 0))->find($user_coupon_id);
// if ($userCoupon) {
// $get_status = $userCoupon->status;
// }
// }
return $get_status;
}
public function getGetStatusTextAttr($value, $data)
{
$list = $this->getGetStatusList();
return isset($list[$this->get_status]) ? $list[$this->get_status] : '';
}
/**
* 后端发放状态
*
* @return string
*/
public function getUseTimeStatusAttr($value, $data) {
if($data['use_time_type'] == 'days'){
return 'ing';
}
if ($data['use_start_time'] > time()) {
$time_text = 'nostart'; // 未开始
} else if ($data['use_start_time'] <= time() && $data['use_end_time'] >= time()) {
$time_text = 'ing';
} else if ($data['use_end_time'] < time()) {
$time_text = 'ended';
}
return $time_text;
}
/**
* 后端发放状态
*
* @return string
*/
public function getUseTimeTextAttr($value, $data)
{
if ($this->use_time_status == 'nostart') {
$time_text = '未开始'; // 未开始
} else if ($this->use_time_status == 'ing') {
$time_text = '发放中';
} else if ($this->use_time_status == 'ended') {
$time_text = '已结束';
}
return $time_text;
}
/**
* 获取所有库存
* @param $value
* @param $data
* @return mixed
*/
public function getStockAllAttr($value, $data)
{
$useCount = CouponUserModel::where('coupon_id', $data['id'])->count();
return $data['stock'] + $useCount;
}
/**
* 获取所有库存
* @param $value
* @param $data
* @return mixed
*/
public function getStockPropAttr($value, $data)
{
$useCount = CouponUserModel::where('coupon_id', $data['id'])->count();
$stock = (int) $data['stock'];
$total = $stock + $useCount;
// 防止除以零
if ($total <= 0) {
return 0;
}
return floor($stock / $total * 100);
}
public function getGetNumAttr($value, $data)
{
return CouponUserModel::where('coupon_id', $data['id'])->count();
}
public function getUseNumAttr($value, $data)
{
return CouponUserModel::where('coupon_id', $data['id'])->whereNotNull('use_time')->count();
}
public function getUseStartTimeAttr($value, $data)
{
$use_start_time = $value ? date('Y-m-d H:i', $value) : null;
$user_coupon_id = request()->param('ucid', 0);
if ($user_coupon_id && $data['use_time_type'] == 'days') {
// 从我领取的优惠券进详情,覆盖 状态
$user = user_info();
$userCoupon = CouponUserModel::cache(60)->where('user_id', ($user ? $user->id : 0))->find($user_coupon_id);
if ($userCoupon) {
$use_start_time = date('Y-m-d H:i', $userCoupon->getData('createtime') + ($this->start_days * 86400));
}
}
return $use_start_time;
}
public function getUseEndTimeAttr($value, $data)
{
$use_end_time = $value ? date('Y-m-d H:i', $value) : null;
$user_coupon_id = request()->param('ucid', 0);
if ($user_coupon_id && $data['use_time_type'] == 'days') {
// 从我领取的优惠券进详情,覆盖 状态
$user = user_info();
$userCoupon = CouponUserModel::cache(60)->where('user_id', ($user ? $user->id : 0))->find($user_coupon_id);
if ($userCoupon) {
$use_end_time = date('Y-m-d H:i', $userCoupon->getData('createtime') + (($this->start_days + $this->days) * 86400));
}
}
return $use_end_time;
}
public function userCoupons()
{
$user = user_info();
return $this->hasMany(CouponUserModel::class, 'coupon_id')->where('user_id', ($user ? $user->id : 0));
}
}