init
- 框架初始化 - 安装插件 - 修复PHP8.4报错
This commit is contained in:
32
application/admin/model/Admin.php
Normal file
32
application/admin/model/Admin.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
use think\Session;
|
||||
|
||||
class Admin extends Model
|
||||
{
|
||||
|
||||
// 开启自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'salt'
|
||||
];
|
||||
|
||||
public static function init()
|
||||
{
|
||||
self::beforeWrite(function ($row) {
|
||||
$changed = $row->getChangedData();
|
||||
//如果修改了用户或或密码则需要重新登录
|
||||
if (isset($changed['username']) || isset($changed['password']) || isset($changed['salt'])) {
|
||||
$row->token = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
117
application/admin/model/AdminLog.php
Normal file
117
application/admin/model/AdminLog.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\admin\library\Auth;
|
||||
use think\Model;
|
||||
use think\Loader;
|
||||
|
||||
class AdminLog extends Model
|
||||
{
|
||||
|
||||
// 开启自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = '';
|
||||
//自定义日志标题
|
||||
protected static $title = '';
|
||||
//自定义日志内容
|
||||
protected static $content = '';
|
||||
//忽略的链接正则列表
|
||||
protected static $ignoreRegex = [
|
||||
'/^(.*)\/(selectpage|index)$/i',
|
||||
];
|
||||
|
||||
public static function setTitle($title)
|
||||
{
|
||||
self::$title = $title;
|
||||
}
|
||||
|
||||
public static function setContent($content)
|
||||
{
|
||||
self::$content = $content;
|
||||
}
|
||||
|
||||
public static function setIgnoreRegex($regex = [])
|
||||
{
|
||||
$regex = is_array($regex) ? $regex : [$regex];
|
||||
self::$ignoreRegex = array_merge(self::$ignoreRegex, $regex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录日志
|
||||
* @param string $title 日志标题
|
||||
* @param string $content 日志内容
|
||||
*/
|
||||
public static function record($title = '', $content = '')
|
||||
{
|
||||
$auth = Auth::instance();
|
||||
$admin_id = $auth->isLogin() ? $auth->id : 0;
|
||||
$username = $auth->isLogin() ? $auth->username : __('Unknown');
|
||||
|
||||
// 设置过滤函数
|
||||
request()->filter('trim,strip_tags,htmlspecialchars');
|
||||
|
||||
$controllername = Loader::parseName(request()->controller());
|
||||
$actionname = strtolower(request()->action());
|
||||
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
|
||||
if (self::$ignoreRegex) {
|
||||
foreach (self::$ignoreRegex as $index => $item) {
|
||||
if (preg_match($item, $path)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$content = $content ?: self::$content;
|
||||
if (!$content) {
|
||||
$content = request()->param('') ?: file_get_contents("php://input");
|
||||
$content = self::getPureContent($content);
|
||||
}
|
||||
$title = $title ?: self::$title;
|
||||
if (!$title) {
|
||||
$title = [];
|
||||
$breadcrumb = Auth::instance()->getBreadcrumb($path);
|
||||
foreach ($breadcrumb as $k => $v) {
|
||||
$title[] = $v['title'];
|
||||
}
|
||||
$title = implode(' / ', $title);
|
||||
}
|
||||
self::create([
|
||||
'title' => $title,
|
||||
'content' => !is_scalar($content) ? json_encode($content, JSON_UNESCAPED_UNICODE) : $content,
|
||||
'url' => substr(xss_clean(strip_tags(request()->url())), 0, 1500),
|
||||
'admin_id' => $admin_id,
|
||||
'username' => $username,
|
||||
'useragent' => substr(request()->server('HTTP_USER_AGENT'), 0, 255),
|
||||
'ip' => xss_clean(strip_tags(request()->ip()))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已屏蔽关键信息的数据
|
||||
* @param $content
|
||||
* @return array
|
||||
*/
|
||||
protected static function getPureContent($content)
|
||||
{
|
||||
if (!is_array($content)) {
|
||||
return $content;
|
||||
}
|
||||
foreach ($content as $index => &$item) {
|
||||
if (preg_match("/(password|salt|token)/i", $index)) {
|
||||
$item = "***";
|
||||
} else {
|
||||
if (is_array($item)) {
|
||||
$item = self::getPureContent($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function admin()
|
||||
{
|
||||
return $this->belongsTo('Admin', 'admin_id')->setEagerlyType(0);
|
||||
}
|
||||
}
|
||||
21
application/admin/model/AuthGroup.php
Normal file
21
application/admin/model/AuthGroup.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class AuthGroup extends Model
|
||||
{
|
||||
|
||||
// 开启自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
|
||||
public function getNameAttr($value, $data)
|
||||
{
|
||||
return __($value);
|
||||
}
|
||||
|
||||
}
|
||||
10
application/admin/model/AuthGroupAccess.php
Normal file
10
application/admin/model/AuthGroupAccess.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class AuthGroupAccess extends Model
|
||||
{
|
||||
//
|
||||
}
|
||||
62
application/admin/model/AuthRule.php
Normal file
62
application/admin/model/AuthRule.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Cache;
|
||||
use think\Model;
|
||||
|
||||
class AuthRule extends Model
|
||||
{
|
||||
|
||||
// 开启自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
// 数据自动完成字段
|
||||
protected $insert = ['py', 'pinyin'];
|
||||
protected $update = ['py', 'pinyin'];
|
||||
// 拼音对象
|
||||
protected static $pinyin = null;
|
||||
|
||||
protected static function init()
|
||||
{
|
||||
self::$pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
|
||||
|
||||
self::beforeWrite(function ($row) {
|
||||
if (isset($_POST['row']) && is_array($_POST['row']) && isset($_POST['row']['condition'])) {
|
||||
$originRow = $_POST['row'];
|
||||
$row['condition'] = $originRow['condition'] ?? '';
|
||||
}
|
||||
});
|
||||
self::afterWrite(function ($row) {
|
||||
Cache::rm('__menu__');
|
||||
});
|
||||
}
|
||||
|
||||
public function getTitleAttr($value, $data)
|
||||
{
|
||||
return __($value);
|
||||
}
|
||||
|
||||
public function getMenutypeList()
|
||||
{
|
||||
return ['addtabs' => __('Addtabs'), 'dialog' => __('Dialog'), 'ajax' => __('Ajax'), 'blank' => __('Blank')];
|
||||
}
|
||||
|
||||
public function setPyAttr($value, $data)
|
||||
{
|
||||
if (isset($data['title']) && $data['title']) {
|
||||
return self::$pinyin->abbr(__($data['title']));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public function setPinyinAttr($value, $data)
|
||||
{
|
||||
if (isset($data['title']) && $data['title']) {
|
||||
return self::$pinyin->permalink(__($data['title']), '');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
59
application/admin/model/Command.php
Normal file
59
application/admin/model/Command.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class Command extends Model
|
||||
{
|
||||
// 表名
|
||||
protected $name = 'command';
|
||||
|
||||
// 自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'executetime_text',
|
||||
'type_text',
|
||||
'status_text'
|
||||
];
|
||||
|
||||
|
||||
public function getStatusList()
|
||||
{
|
||||
return ['successed' => __('Successed'), 'failured' => __('Failured')];
|
||||
}
|
||||
|
||||
|
||||
public function getExecutetimeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ? $value : $data['executetime'];
|
||||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||||
}
|
||||
|
||||
public function getTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ? $value : $data['type'];
|
||||
$list = ['crud' => '一键生成CRUD', 'menu' => '一键生成菜单', 'min' => '一键压缩打包', 'api' => '一键生成文档'];
|
||||
return $list[$value] ?? '';
|
||||
}
|
||||
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ? $value : $data['status'];
|
||||
$list = $this->getStatusList();
|
||||
return $list[$value] ?? '';
|
||||
}
|
||||
|
||||
protected function setExecutetimeAttr($value)
|
||||
{
|
||||
return $value && !is_numeric($value) ? strtotime($value) : $value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
114
application/admin/model/User.php
Normal file
114
application/admin/model/User.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\model\MoneyLog;
|
||||
use app\common\model\ScoreLog;
|
||||
use think\Model;
|
||||
|
||||
class User extends Model
|
||||
{
|
||||
|
||||
// 表名
|
||||
protected $name = 'user';
|
||||
// 自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'prevtime_text',
|
||||
'logintime_text',
|
||||
'jointime_text'
|
||||
];
|
||||
|
||||
public function getOriginData()
|
||||
{
|
||||
return $this->origin;
|
||||
}
|
||||
|
||||
protected static function init()
|
||||
{
|
||||
self::beforeUpdate(function ($row) {
|
||||
$changed = $row->getChangedData();
|
||||
//如果有修改密码
|
||||
if (isset($changed['password'])) {
|
||||
if ($changed['password']) {
|
||||
$salt = \fast\Random::alnum();
|
||||
$row->password = \app\common\library\Auth::instance()->getEncryptPassword($changed['password'], $salt);
|
||||
$row->salt = $salt;
|
||||
} else {
|
||||
unset($row->password);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
self::beforeUpdate(function ($row) {
|
||||
$changedata = $row->getChangedData();
|
||||
$origin = $row->getOriginData();
|
||||
if (isset($changedata['money']) && (function_exists('bccomp') ? bccomp($changedata['money'], $origin['money'], 2) !== 0 : (double)$changedata['money'] !== (double)$origin['money'])) {
|
||||
MoneyLog::create(['user_id' => $row['id'], 'money' => $changedata['money'] - $origin['money'], 'before' => $origin['money'], 'after' => $changedata['money'], 'memo' => '管理员变更金额']);
|
||||
}
|
||||
if (isset($changedata['score']) && (int)$changedata['score'] !== (int)$origin['score']) {
|
||||
ScoreLog::create(['user_id' => $row['id'], 'score' => $changedata['score'] - $origin['score'], 'before' => $origin['score'], 'after' => $changedata['score'], 'memo' => '管理员变更积分']);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getGenderList()
|
||||
{
|
||||
return ['1' => __('Male'), '0' => __('Female')];
|
||||
}
|
||||
|
||||
public function getStatusList()
|
||||
{
|
||||
return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
|
||||
}
|
||||
|
||||
|
||||
public function getPrevtimeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ? $value : ($data['prevtime'] ?? "");
|
||||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||||
}
|
||||
|
||||
public function getLogintimeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ? $value : ($data['logintime'] ?? "");
|
||||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||||
}
|
||||
|
||||
public function getJointimeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ? $value : ($data['jointime'] ?? "");
|
||||
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
|
||||
}
|
||||
|
||||
protected function setPrevtimeAttr($value)
|
||||
{
|
||||
return $value && !is_numeric($value) ? strtotime($value) : $value;
|
||||
}
|
||||
|
||||
protected function setLogintimeAttr($value)
|
||||
{
|
||||
return $value && !is_numeric($value) ? strtotime($value) : $value;
|
||||
}
|
||||
|
||||
protected function setJointimeAttr($value)
|
||||
{
|
||||
return $value && !is_numeric($value) ? strtotime($value) : $value;
|
||||
}
|
||||
|
||||
protected function setBirthdayAttr($value)
|
||||
{
|
||||
return $value ? $value : null;
|
||||
}
|
||||
|
||||
public function group()
|
||||
{
|
||||
return $this->belongsTo('UserGroup', 'group_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
||||
}
|
||||
|
||||
}
|
||||
34
application/admin/model/UserGroup.php
Normal file
34
application/admin/model/UserGroup.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class UserGroup extends Model
|
||||
{
|
||||
|
||||
// 表名
|
||||
protected $name = 'user_group';
|
||||
// 自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
public function getStatusList()
|
||||
{
|
||||
return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
|
||||
}
|
||||
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ? $value : $data['status'];
|
||||
$list = $this->getStatusList();
|
||||
return $list[$value] ?? '';
|
||||
}
|
||||
|
||||
}
|
||||
69
application/admin/model/UserRule.php
Normal file
69
application/admin/model/UserRule.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use fast\Tree;
|
||||
use think\Model;
|
||||
|
||||
class UserRule extends Model
|
||||
{
|
||||
|
||||
// 表名
|
||||
protected $name = 'user_rule';
|
||||
// 自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = 'int';
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
protected static function init()
|
||||
{
|
||||
self::afterInsert(function ($row) {
|
||||
if (!$row['weigh']) {
|
||||
$pk = $row->getPk();
|
||||
$row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getTitleAttr($value, $data)
|
||||
{
|
||||
return __($value);
|
||||
}
|
||||
|
||||
public function getStatusList()
|
||||
{
|
||||
return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
|
||||
}
|
||||
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ? $value : $data['status'];
|
||||
$list = $this->getStatusList();
|
||||
return $list[$value] ?? '';
|
||||
}
|
||||
|
||||
public static function getTreeList($selected = [])
|
||||
{
|
||||
$ruleList = collection(self::where('status', 'normal')->order('weigh desc,id desc')->select())->toArray();
|
||||
$nodeList = [];
|
||||
Tree::instance()->init($ruleList);
|
||||
$ruleList = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'name');
|
||||
$hasChildrens = [];
|
||||
foreach ($ruleList as $k => $v)
|
||||
{
|
||||
if ($v['haschild'])
|
||||
$hasChildrens[] = $v['id'];
|
||||
}
|
||||
foreach ($ruleList as $k => $v) {
|
||||
$state = array('selected' => in_array($v['id'], $selected) && !in_array($v['id'], $hasChildrens));
|
||||
$nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
|
||||
}
|
||||
return $nodeList;
|
||||
}
|
||||
|
||||
}
|
||||
53
application/admin/model/shopro/Admin.php
Normal file
53
application/admin/model/shopro/Admin.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\Admin as BaseAdmin;
|
||||
use addons\shopro\library\notify\traits\Notifiable;
|
||||
|
||||
class Admin extends BaseAdmin
|
||||
{
|
||||
use Notifiable;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 判断管理员是否由特定权限
|
||||
*
|
||||
* @param \think\Model $admin
|
||||
* @param array $rules
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasAccess(\think\Model $admin, ?array $rules = [])
|
||||
{
|
||||
$auth = \app\admin\library\Auth::instance();
|
||||
$RuleIds = $auth->getRuleIds($admin->id);
|
||||
$is_super = in_array('*', $RuleIds) ? 1 : 0;
|
||||
if ($is_super) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($auth->check(implode(',', $rules), $admin->id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否是超级管理员
|
||||
*
|
||||
* @param \think\Model $admin
|
||||
* @return boolean
|
||||
*/
|
||||
public function isSuper(\think\Model $admin)
|
||||
{
|
||||
$auth = \app\admin\library\Auth::instance();
|
||||
$RuleIds = $auth->getRuleIds($admin->id);
|
||||
|
||||
$is_super = in_array('*', $RuleIds) ? 1 : 0;
|
||||
|
||||
return $is_super;
|
||||
}
|
||||
}
|
||||
77
application/admin/model/shopro/Cart.php
Normal file
77
application/admin/model/shopro/Cart.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\goods\Goods;
|
||||
use app\admin\model\shopro\goods\SkuPrice;
|
||||
use addons\shopro\facade\Activity as ActivityFacade;
|
||||
|
||||
class Cart extends Common
|
||||
{
|
||||
protected $name = 'shopro_cart';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 获取器获取所有活动
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getActivitiesAttr($value, $data)
|
||||
{
|
||||
$activities = ActivityFacade::getGoodsActivitys($data['id']);
|
||||
|
||||
return $activities;
|
||||
}
|
||||
|
||||
|
||||
public function getStatusAttr($value, $data)
|
||||
{
|
||||
$status = 'normal';
|
||||
if (!$this->goods || !is_null($this->goods->deletetime) || !$this->sku_price) {
|
||||
$status = 'deleted'; // 已删除
|
||||
} else if ($this->goods->status == 'down' || $this->sku_price->status == 'down') {
|
||||
$status = 'down'; // 已下架
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
|
||||
public function getTagsAttr($value, $data)
|
||||
{
|
||||
$tags = [
|
||||
'activity' => [],
|
||||
];
|
||||
|
||||
$activities = $this->activities;
|
||||
foreach ($activities as $activity) {
|
||||
$tags['activity'][] = $activity['type_text'] . $activity['status_text'];
|
||||
}
|
||||
|
||||
if ($this->sku_price && $this->sku_price->price < $data['snapshot_price']) {
|
||||
// 当前规格价格,低于加入购物车时候的价格,则提示商品比加入时降价
|
||||
$tags['price'] = '距加入降 ¥ ' . bcsub($data['snapshot_price'], $this->sku_price->price, 2);
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
|
||||
public function goods()
|
||||
{
|
||||
return $this->belongsTo(Goods::class, 'goods_id');
|
||||
}
|
||||
|
||||
|
||||
public function skuPrice()
|
||||
{
|
||||
return $this->belongsTo(SkuPrice::class, 'goods_sku_price_id');
|
||||
}
|
||||
}
|
||||
35
application/admin/model/shopro/Category.php
Normal file
35
application/admin/model/shopro/Category.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Category extends Common
|
||||
{
|
||||
protected $name = 'shopro_category';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text',
|
||||
];
|
||||
|
||||
|
||||
public function getChildrenString($category)
|
||||
{
|
||||
$style = $category->style;
|
||||
$string = 'children';
|
||||
if (strpos($style, 'second') === 0) {
|
||||
$string .= '.children';
|
||||
} else if (strpos($style, 'third') === 0) {
|
||||
$string .= '.children.children';
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(self::class, 'parent_id', 'id')->normal()->order('weigh', 'desc')->order('id', 'asc');
|
||||
}
|
||||
}
|
||||
80
application/admin/model/shopro/Common.php
Normal file
80
application/admin/model/shopro/Common.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use think\Model;
|
||||
use addons\shopro\filter\BaseFilter;
|
||||
use think\db\Query;
|
||||
use app\admin\model\shopro\traits\ModelAttr;
|
||||
|
||||
class Common extends Model
|
||||
{
|
||||
|
||||
// 自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = 'integer';
|
||||
|
||||
protected $dateFormat = 'Y-m-d H:i:s';
|
||||
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
protected $deleteTime = false;
|
||||
|
||||
use ModelAttr;
|
||||
|
||||
/**
|
||||
* 当前 model 对应的 filter 实例
|
||||
*
|
||||
* @return BaseFilter
|
||||
*/
|
||||
public function filterInstance()
|
||||
{
|
||||
$filter_class = static::class;
|
||||
|
||||
$class = str_replace('app\admin\model\shopro', 'addons\shopro\filter', $filter_class) . 'Filter';
|
||||
|
||||
if (!class_exists($class)) {
|
||||
return new BaseFilter();
|
||||
}
|
||||
return new $class();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询范围 filter 搜索入口
|
||||
*
|
||||
* @param Query $query
|
||||
* @return void
|
||||
*/
|
||||
public function scopeSheepFilter($query, $sort = true, $filters = null)
|
||||
{
|
||||
$instance = $this->filterInstance();
|
||||
$query = $instance->apply($query, $filters);
|
||||
if ($sort) {
|
||||
$query = $instance->filterOrder($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取模型中文名
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
// public function getModelName()
|
||||
// {
|
||||
// if (isset($this->modelName)) {
|
||||
// $model_name = $this->modelName;
|
||||
// } else {
|
||||
// $tableComment = $this->tableComment();
|
||||
// $table_name = $this->getQuery()->getTable();
|
||||
// $model_name = $tableComment[$table_name] ?? null;
|
||||
// }
|
||||
|
||||
// return $model_name;
|
||||
// }
|
||||
}
|
||||
192
application/admin/model/shopro/Config.php
Normal file
192
application/admin/model/shopro/Config.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
class Config extends Common
|
||||
{
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
protected $pk = 'code';
|
||||
|
||||
protected $name = 'shopro_config';
|
||||
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
/**
|
||||
* 获取配置组
|
||||
*
|
||||
* @param string $code
|
||||
* @param boolean $cache
|
||||
* @return array
|
||||
*/
|
||||
public static function getConfigs($code, $cache = true)
|
||||
{
|
||||
// 从缓存中获取
|
||||
if ($cache) {
|
||||
$config = operate_disabled(false) ? cache("config:{$code}") : null;
|
||||
if (empty($config)) {
|
||||
$config = self::getConfigs($code, false);
|
||||
}
|
||||
}
|
||||
|
||||
// 从数据库中查找
|
||||
if (!$cache) {
|
||||
$row = self::where('code', $code)->find();
|
||||
if(!$row) return null;
|
||||
if($row['type'] !== 'group') {
|
||||
$config = $row->value;
|
||||
}else {
|
||||
$config = [];
|
||||
$list = self::where('parent_code', $code)->select();
|
||||
foreach ($list as &$row) {
|
||||
if ($row['type'] === 'group') {
|
||||
$row->value = self::getConfigs($row->code, false);
|
||||
} else {
|
||||
cache("config:{$row->code}", $row->value);
|
||||
}
|
||||
$config[self::getShortCode($row)] = $row->value;
|
||||
}
|
||||
}
|
||||
// 设置配置缓存
|
||||
cache("config:{$code}", $config);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单一配置项
|
||||
*
|
||||
* @param string $code
|
||||
* @param boolean $cache
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getConfigField($code, $cache = true)
|
||||
{
|
||||
// 从缓存中获取
|
||||
if ($cache) {
|
||||
$config = cache("config:{$code}");
|
||||
if (empty($config)) {
|
||||
$config = self::getConfigField($code, false);
|
||||
}
|
||||
}
|
||||
|
||||
// 从数据库中查找
|
||||
if (!$cache) {
|
||||
$config = self::where('code', $code)->value('value');
|
||||
// 设置配置缓存
|
||||
cache("config:{$code}", $config);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
private static function getShortCode($config)
|
||||
{
|
||||
if (!empty($config['parent_code'])) {
|
||||
return str_replace("{$config['parent_code']}.", "", $config['code']);
|
||||
}
|
||||
return $config['code'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配置
|
||||
*
|
||||
* @param string $code
|
||||
* @param array $configParams
|
||||
* @return void
|
||||
*/
|
||||
public static function setConfigs(string $code, ?array $configParams)
|
||||
{
|
||||
operate_filter();
|
||||
foreach ($configParams as $configKey => $configValue) {
|
||||
self::setConfigField($code . '.' . $configKey, $configValue);
|
||||
}
|
||||
|
||||
self::getConfigs(explode('.', $code)[0], false);
|
||||
return self::getConfigs($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配置项
|
||||
*/
|
||||
private static function setConfigField($code, $value)
|
||||
{
|
||||
$config = self::where('code', $code)->find();
|
||||
|
||||
if ($config) {
|
||||
if ($config['type'] === 'group') {
|
||||
foreach ($value as $k => $v) {
|
||||
self::setConfigField($code . '.' . $k, $v);
|
||||
}
|
||||
} else {
|
||||
$config->value = $value;
|
||||
$config->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改器 数据的保存格式
|
||||
*
|
||||
* @param string|array $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function setValueAttr($value, $data)
|
||||
{
|
||||
switch ($data['type']) {
|
||||
case 'array':
|
||||
$value = is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value;
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取器,选项
|
||||
*
|
||||
* @param string|array $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getStoreRangeAttr($value, $data)
|
||||
{
|
||||
return $this->attrFormatJson($value, $data, 'store_range');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取器,返回的格式
|
||||
*
|
||||
* @param string|array $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getValueAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['value'] ?? null);
|
||||
|
||||
switch ($data['type']) {
|
||||
case 'array':
|
||||
$value = $this->attrFormatJson($value, $data, 'value', true);
|
||||
break;
|
||||
case 'boolean':
|
||||
$value = intval($value) ? 1 : 0;
|
||||
break;
|
||||
case 'int':
|
||||
$value = intval($value);
|
||||
break;
|
||||
case 'float':
|
||||
$value = floatval($value);
|
||||
break;
|
||||
}
|
||||
|
||||
return config_show($value, $data);
|
||||
}
|
||||
}
|
||||
320
application/admin/model/shopro/Coupon.php
Normal file
320
application/admin/model/shopro/Coupon.php
Normal file
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\Coupon as UserCouponModel;
|
||||
use app\admin\model\shopro\goods\Goods;
|
||||
use app\admin\model\shopro\Category;
|
||||
use traits\model\SoftDelete;
|
||||
|
||||
class Coupon extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $name = 'shopro_coupon';
|
||||
|
||||
protected $type = [
|
||||
'get_start_time' => 'timestamp',
|
||||
'get_end_time' => 'timestamp',
|
||||
// 'use_start_time' => 'timestamp',
|
||||
// 'use_end_time' => 'timestamp',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text',
|
||||
'status_text',
|
||||
'use_scope_text',
|
||||
'amount_text',
|
||||
'get_time_status',
|
||||
'get_time_text'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 默认类型列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'reduce' => '满减券',
|
||||
'discount' => '折扣券'
|
||||
];
|
||||
}
|
||||
/**
|
||||
* 可用范围列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function useScopeList()
|
||||
{
|
||||
return [
|
||||
'all_use' => '全场通用',
|
||||
'goods' => '指定商品可用',
|
||||
'disabled_goods' => '指定商品不可用',
|
||||
'category' => '指定分类可用',
|
||||
];
|
||||
}
|
||||
/**
|
||||
* 默认状态列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'normal' => '公开发放',
|
||||
'hidden' => '后台发放',
|
||||
'disabled' => '禁止使用',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 优惠券领取状态
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getStatusList()
|
||||
{
|
||||
return [
|
||||
'can_get' => '立即领取',
|
||||
'cannot_get' => '已领取',
|
||||
'get_over' => '已领完',
|
||||
|
||||
// 用户优惠券的状态
|
||||
'used' => '已使用',
|
||||
'can_use' => '立即使用',
|
||||
'expired' => '已过期',
|
||||
'cannot_use' => '暂不可用'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function scopeCanGet($query)
|
||||
{
|
||||
return $query->where('get_start_time', '<=', time())
|
||||
->where('get_end_time', '>=', time());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询指定商品满足的优惠券
|
||||
*
|
||||
* @param [type] $query
|
||||
* @param [type] $goods
|
||||
* @return void
|
||||
*/
|
||||
public function scopeGoods($query, $goods)
|
||||
{
|
||||
$goods_id = $goods['id'];
|
||||
$category_ids = $goods['category_ids'];
|
||||
|
||||
// 查询符合商品的优惠券
|
||||
return $query->where(function ($query) use ($goods_id, $category_ids) {
|
||||
$query->where('use_scope', 'all_use')
|
||||
->whereOr(function ($query) use ($goods_id) {
|
||||
$query->where('use_scope', 'goods')->whereRaw("find_in_set($goods_id, items)");
|
||||
})
|
||||
->whereOr(function ($query) use ($goods_id) {
|
||||
$query->where('use_scope', 'disabled_goods')->whereRaw("not find_in_set($goods_id, items)");
|
||||
})
|
||||
->whereOr(function ($query) use ($goods_id, $category_ids) {
|
||||
$query->where('use_scope', 'category')->where(function ($query) use ($category_ids) {
|
||||
$category_ids = array_filter(array_map('intval', explode(',', $category_ids)));
|
||||
foreach ($category_ids as $key => $category_id) {
|
||||
$query->whereOrRaw("find_in_set($category_id, items)");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 开始使用时间获取器
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return int
|
||||
*/
|
||||
public function setUseStartTimeAttr($value, $data)
|
||||
{
|
||||
return $value ? strtotime($value) : (isset($data['use_start_time']) ? strtotime($data['use_start_time']) : 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 结束使用时间获取器
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return int
|
||||
*/
|
||||
public function setUseEndTimeAttr($value, $data)
|
||||
{
|
||||
return $value ? strtotime($value) : (isset($data['use_end_time']) ? strtotime($data['use_end_time']) : 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 可用范围获取器
|
||||
*
|
||||
* @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] : '';
|
||||
}
|
||||
|
||||
|
||||
public function getAmountTextAttr($value, $data)
|
||||
{
|
||||
return '满' . $data['enough'] . '元,' . ($data['type'] == 'reduce' ? '减' . floatval($data['amount']) . '元' : '打' . floatval($data['amount']) . '折');
|
||||
}
|
||||
|
||||
public function getItemsValueAttr($value, $data)
|
||||
{
|
||||
if (in_array($data['use_scope'], ['goods', 'disabled_goods'])) {
|
||||
$items_value = Goods::whereIn('id', $data['items'])->select();
|
||||
$items_value = collection($items_value);
|
||||
$items_value = $items_value->each(function ($goods) {
|
||||
// 前端要显示活动标签
|
||||
$goods->promos = $goods->promos;
|
||||
});
|
||||
} else {
|
||||
$items_value = Category::whereIn('id', $data['items'])->select();
|
||||
}
|
||||
|
||||
return $items_value ?? [];
|
||||
}
|
||||
|
||||
public function getGetStatusAttr($value, $data)
|
||||
{
|
||||
$limit_num = $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('user_coupon_id', 0);
|
||||
if ($user_coupon_id) {
|
||||
// 从我领取的优惠券进详情,覆盖 状态
|
||||
$user = auth_user();
|
||||
$userCoupon = UserCouponModel::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->getStatusList();
|
||||
return isset($list[$this->get_status]) ? $list[$this->get_status] : '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 后端发放状态
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGetTimeStatusAttr($value, $data) {
|
||||
if ($data['get_start_time'] > time()) {
|
||||
$time_text = 'nostart'; // 未开始
|
||||
} else if ($data['get_start_time'] <= time() && $data['get_end_time'] >= time()) {
|
||||
$time_text = 'ing';
|
||||
} else if ($data['get_end_time'] < time()) {
|
||||
$time_text = 'ended';
|
||||
}
|
||||
|
||||
return $time_text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 后端发放状态
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGetTimeTextAttr($value, $data)
|
||||
{
|
||||
if ($this->get_time_status == 'nostart') {
|
||||
$time_text = '未开始'; // 未开始
|
||||
} else if ($this->get_time_status == 'ing') {
|
||||
$time_text = '发放中';
|
||||
} else if ($this->get_time_status == 'ended') {
|
||||
$time_text = '已结束';
|
||||
}
|
||||
|
||||
return $time_text;
|
||||
}
|
||||
|
||||
|
||||
public function getGetNumAttr($value, $data)
|
||||
{
|
||||
return UserCouponModel::where('coupon_id', $data['id'])->count();
|
||||
}
|
||||
|
||||
|
||||
public function getUseNumAttr($value, $data)
|
||||
{
|
||||
return UserCouponModel::where('coupon_id', $data['id'])->whereNotNull('use_time')->count();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getUseStartTimeAttr($value, $data)
|
||||
{
|
||||
$use_start_time = $value ? date('Y-m-d H:i:s', $value) : null;
|
||||
$user_coupon_id = request()->param('user_coupon_id', 0);
|
||||
if ($user_coupon_id && $data['use_time_type'] == 'days') {
|
||||
// 从我领取的优惠券进详情,覆盖 状态
|
||||
$user = auth_user();
|
||||
$userCoupon = UserCouponModel::cache(60)->where('user_id', ($user ? $user->id : 0))->find($user_coupon_id);
|
||||
if ($userCoupon) {
|
||||
$use_start_time = date('Y-m-d H:i:s', $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:s', $value) : null;
|
||||
$user_coupon_id = request()->param('user_coupon_id', 0);
|
||||
if ($user_coupon_id && $data['use_time_type'] == 'days') {
|
||||
// 从我领取的优惠券进详情,覆盖 状态
|
||||
$user = auth_user();
|
||||
$userCoupon = UserCouponModel::cache(60)->where('user_id', ($user ? $user->id : 0))->find($user_coupon_id);
|
||||
if ($userCoupon) {
|
||||
$use_end_time = date('Y-m-d H:i:s', $userCoupon->getData('createtime') + (($this->start_days + $this->days) * 86400));
|
||||
}
|
||||
}
|
||||
|
||||
return $use_end_time;
|
||||
}
|
||||
|
||||
|
||||
public function userCoupons()
|
||||
{
|
||||
$user = auth_user();
|
||||
return $this->hasMany(UserCouponModel::class, 'coupon_id')->where('user_id', ($user ? $user->id : 0));
|
||||
}
|
||||
}
|
||||
36
application/admin/model/shopro/Feedback.php
Normal file
36
application/admin/model/shopro/Feedback.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User;
|
||||
|
||||
class Feedback extends Common
|
||||
{
|
||||
protected $name = 'shopro_feedback';
|
||||
|
||||
protected $type = [
|
||||
'images' => 'json'
|
||||
];
|
||||
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 类型列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function statusList()
|
||||
{
|
||||
return ['0' => '待处理', '1' => '已处理'];
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id', 'id')->field('id, nickname, avatar, mobile');
|
||||
}
|
||||
|
||||
}
|
||||
81
application/admin/model/shopro/Pay.php
Normal file
81
application/admin/model/shopro/Pay.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Pay extends Common
|
||||
{
|
||||
protected $name = 'shopro_pay';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'pay_type_text',
|
||||
'status_text'
|
||||
];
|
||||
|
||||
const PAY_STATUS_UNPAID = 'unpaid';
|
||||
const PAY_STATUS_PAID = 'paid';
|
||||
const PAY_STATUS_REFUND = 'refund';
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
self::PAY_STATUS_UNPAID => '未支付',
|
||||
self::PAY_STATUS_PAID => '已支付',
|
||||
self::PAY_STATUS_REFUND => '已退款'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function payTypeList()
|
||||
{
|
||||
return [
|
||||
'wechat' => '微信支付',
|
||||
'alipay' => '支付宝',
|
||||
'money' => '钱包支付',
|
||||
'score' => '积分支付',
|
||||
'offline' => '货到付款',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function scopeTypeOrder($query) // scopeOrder 调用时候,和 order 排序方法冲突了
|
||||
{
|
||||
return $query->where('order_type', 'order');
|
||||
}
|
||||
|
||||
|
||||
public function scopeTypeTradeOrder($query)
|
||||
{
|
||||
return $query->where('order_type', 'trade_order');
|
||||
}
|
||||
|
||||
|
||||
public function scopePaid($query)
|
||||
{
|
||||
return $query->where('status', self::PAY_STATUS_PAID);
|
||||
}
|
||||
|
||||
|
||||
public function scopeIsMoney($query)
|
||||
{
|
||||
return $query->whereIn('pay_type', ['wechat', 'alipay', 'money']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通用类型获取器
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getPayTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['pay_type'] ?? null);
|
||||
|
||||
$list = $this->payTypeList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
}
|
||||
46
application/admin/model/shopro/PayConfig.php
Normal file
46
application/admin/model/shopro/PayConfig.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
|
||||
class PayConfig extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $name = 'shopro_pay_config';
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $type = [
|
||||
'params' => 'json',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text',
|
||||
'status_text'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'params'
|
||||
];
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'normal' => '正常',
|
||||
'disabled' => '禁用',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'wechat' => '微信支付',
|
||||
'alipay' => '支付宝支付',
|
||||
];
|
||||
}
|
||||
}
|
||||
38
application/admin/model/shopro/Refund.php
Normal file
38
application/admin/model/shopro/Refund.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Refund extends Common
|
||||
{
|
||||
protected $name = 'shopro_refund';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
const STATUS_ING = 'ing';
|
||||
const STATUS_COMPLETED = 'completed';
|
||||
const STATUS_FAIL = 'fail';
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
self::STATUS_ING => '退款中',
|
||||
self::STATUS_COMPLETED => '退款完成',
|
||||
self::STATUS_FAIL => '退款失败'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function refundTypeList()
|
||||
{
|
||||
return [
|
||||
'back' => '原路退回',
|
||||
'money' => '退回到余额'
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
15
application/admin/model/shopro/SearchHistory.php
Normal file
15
application/admin/model/shopro/SearchHistory.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class SearchHistory extends Common
|
||||
{
|
||||
protected $name = 'shopro_search_history';
|
||||
protected $type = [
|
||||
];
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
];
|
||||
}
|
||||
142
application/admin/model/shopro/Share.php
Normal file
142
application/admin/model/shopro/Share.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User as UserModel;
|
||||
use app\admin\model\shopro\goods\Goods as GoodsModel;
|
||||
|
||||
class Share extends Common
|
||||
{
|
||||
protected $updateTime = false;
|
||||
|
||||
protected $name = 'shopro_share';
|
||||
|
||||
protected $type = [
|
||||
'ext' => 'json'
|
||||
];
|
||||
|
||||
protected $append = [
|
||||
'platform_text',
|
||||
'from_text'
|
||||
];
|
||||
|
||||
const FROM = ['forward' => '直接转发', 'poster' => '识别海报', 'link' => '分享链接'];
|
||||
|
||||
const PLATFORM = ['H5' => 'H5网页', 'WechatOfficialAccount' => '微信公众号网页', 'WechatMiniProgram' => '微信小程序', 'App' => 'APP'];
|
||||
|
||||
public function getPlatformTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['platform'] ?? null);
|
||||
|
||||
return (self::PLATFORM)[$value] ?? $value;
|
||||
}
|
||||
|
||||
public function getFromTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['from'] ?? null);
|
||||
|
||||
return (self::FROM)[$value] ?? $value;
|
||||
}
|
||||
|
||||
public static function log(Object $user, $params)
|
||||
{
|
||||
|
||||
// 错误的分享参数
|
||||
if (empty($params['spm'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$shareId = $params['shareId'];
|
||||
// 分享用户为空
|
||||
if ($shareId <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 不能分享给本人
|
||||
if ($shareId == $user->id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 新用户不能分享给老用户 按需打开
|
||||
// if($user->id < $shareId) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
$shareUser = UserModel::where('id', $shareId)->find();
|
||||
// 分享人不存在
|
||||
if (!$shareUser) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 5分钟内相同的分享信息不保存,防止冗余数据
|
||||
$lastShareLog = self::where([
|
||||
'user_id' => $user->id
|
||||
])->where('createtime', '>', time() - 300)->order('id desc')->find();
|
||||
|
||||
if ($lastShareLog && $lastShareLog->spm === $params['spm']) {
|
||||
return $lastShareLog;
|
||||
}
|
||||
|
||||
$memoText = '通过' . (self::FROM)[$params['from']] . '访问了';
|
||||
if ($params['page'] == '/pages/index/index') {
|
||||
$memoText .= '首页';
|
||||
}
|
||||
if ($params['page'] === '/pages/goods/index') {
|
||||
$memoText .= '商品';
|
||||
$goodsId = $params['query']['id'];
|
||||
}
|
||||
if ($params['page'] === '/pages/goods/groupon') {
|
||||
$memoText .= '拼团商品';
|
||||
$goodsId = $params['query']['id'];
|
||||
}
|
||||
if ($params['page'] === '/pages/goods/seckill') {
|
||||
$memoText .= '秒杀商品';
|
||||
$goodsId = $params['query']['id'];
|
||||
}
|
||||
if ($params['page'] === '/pages/activity/groupon/detail') {
|
||||
$memoText .= '拼团活动';
|
||||
}
|
||||
|
||||
if (!empty($goodsId)) {
|
||||
$goods = GoodsModel::find($goodsId);
|
||||
if ($goods) {
|
||||
$memoText .= "[{$goods->title}]";
|
||||
}
|
||||
}
|
||||
|
||||
$ext = [
|
||||
'image' => $goods->image ?? "",
|
||||
'memo' => $memoText
|
||||
];
|
||||
|
||||
$shareInfo = self::create([
|
||||
'user_id' => $user->id,
|
||||
'share_id' => $shareId,
|
||||
'spm' => $params['spm'],
|
||||
'page' => $params['page'],
|
||||
'query' => http_build_query($params['query']),
|
||||
'platform' => $params['platform'],
|
||||
'from' => $params['from'],
|
||||
'ext' => $ext
|
||||
]);
|
||||
|
||||
$data = ['shareInfo' => $shareInfo];
|
||||
\think\Hook::listen('user_share_after', $data);
|
||||
|
||||
return $shareInfo;
|
||||
}
|
||||
|
||||
|
||||
// -- commission code start --
|
||||
public function agent()
|
||||
{
|
||||
return $this->belongsTo(\app\admin\model\shopro\commission\Agent::class, 'share_id', 'user_id');
|
||||
}
|
||||
// -- commission code end --
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(UserModel::class, 'user_id', 'id');
|
||||
}
|
||||
}
|
||||
9
application/admin/model/shopro/ThirdOauth.php
Normal file
9
application/admin/model/shopro/ThirdOauth.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
class ThirdOauth extends Common
|
||||
{
|
||||
protected $name = 'shopro_third_oauth';
|
||||
|
||||
}
|
||||
83
application/admin/model/shopro/Withdraw.php
Normal file
83
application/admin/model/shopro/Withdraw.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User;
|
||||
|
||||
class Withdraw extends Common
|
||||
{
|
||||
protected $name = 'shopro_withdraw';
|
||||
protected $type = [
|
||||
'withdraw_info' => 'json'
|
||||
];
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'charge_rate_format',
|
||||
'withdraw_info_hidden',
|
||||
'withdraw_type_text'
|
||||
];
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
-1 => '已拒绝',
|
||||
0 => '待审核',
|
||||
1 => '处理中',
|
||||
2 => '已处理'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function withdrawTypeList()
|
||||
{
|
||||
return [
|
||||
'wechat' => '微信零钱',
|
||||
'alipay' => '支付包账户',
|
||||
'back' => '银行卡',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 类型获取器
|
||||
*/
|
||||
public function getWithdrawTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['withdraw_type'] ?? null);
|
||||
|
||||
$list = $this->withdrawTypeList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getChargeRateFormatAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['charge_rate'] ?? null);
|
||||
|
||||
return bcmul((string)$value, '100', 1) . '%';
|
||||
}
|
||||
|
||||
public function getWithdrawInfoHiddenAttr($value, $data)
|
||||
{
|
||||
$withdraw_info = $value ?: ($this->withdraw_info ?? null);
|
||||
|
||||
foreach ($withdraw_info as $key => &$info) {
|
||||
if (in_array($key, ['微信用户', '真实姓名'])) {
|
||||
$info = string_hide($info, 2);
|
||||
} elseif (in_array($key, ['银行卡号', '支付宝账户', '微信ID'])) {
|
||||
$info = account_hide($info);
|
||||
}
|
||||
}
|
||||
|
||||
return $withdraw_info;
|
||||
}
|
||||
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id', 'id')->field('id, nickname, avatar, total_consume');
|
||||
}
|
||||
}
|
||||
13
application/admin/model/shopro/WithdrawLog.php
Normal file
13
application/admin/model/shopro/WithdrawLog.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
|
||||
class WithdrawLog extends Common
|
||||
{
|
||||
protected $name = 'shopro_withdraw_log';
|
||||
|
||||
|
||||
}
|
||||
407
application/admin/model/shopro/activity/Activity.php
Normal file
407
application/admin/model/shopro/activity/Activity.php
Normal file
@@ -0,0 +1,407 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\activity;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
use app\admin\model\shopro\goods\Goods;
|
||||
use addons\shopro\facade\Activity as ActivityFacade;
|
||||
use app\admin\model\shopro\activity\SkuPrice as ActivitySkuPriceModel;
|
||||
|
||||
class Activity extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $name = 'shopro_activity';
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $type = [
|
||||
'rules' => 'json',
|
||||
'prehead_time' => 'timestamp',
|
||||
'start_time' => 'timestamp',
|
||||
'end_time' => 'timestamp',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status',
|
||||
'status_text',
|
||||
'type_text',
|
||||
// 'end_time_unix' // 不需要了
|
||||
];
|
||||
|
||||
|
||||
public function classifies()
|
||||
{
|
||||
return [
|
||||
'activity' => [
|
||||
'groupon' => '拼团',
|
||||
'groupon_ladder' => '阶梯拼团',
|
||||
// 'groupon_lucky' => '幸运拼团',
|
||||
'seckill' => '秒杀',
|
||||
],
|
||||
'promo' => [
|
||||
'full_reduce' => '满减',
|
||||
'full_discount' => '满折',
|
||||
'full_gift' => '满赠',
|
||||
'free_shipping' => '满邮',
|
||||
],
|
||||
'app' => [
|
||||
'signin' => '签到'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'groupon' => '拼团',
|
||||
'groupon_ladder' => '阶梯拼团',
|
||||
// 'groupon_lucky' => '幸运拼团',
|
||||
'seckill' => '秒杀',
|
||||
'full_reduce' => '满减',
|
||||
'full_discount' => '满折',
|
||||
'full_gift' => '满赠',
|
||||
'free_shipping' => '满邮',
|
||||
'signin' => '签到',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取活动的互斥活动
|
||||
*
|
||||
* @param string $current_activity_type
|
||||
* @return array
|
||||
*/
|
||||
public function getMutexActivityTypes($current_activity_type)
|
||||
{
|
||||
$activityTypes = [];
|
||||
switch ($current_activity_type) {
|
||||
case 'groupon':
|
||||
$activityTypes = ['groupon'];
|
||||
break;
|
||||
case 'groupon_ladder':
|
||||
$activityTypes = ['groupon_ladder'];
|
||||
break;
|
||||
case 'groupon_lucky':
|
||||
$activityTypes = ['groupon_lucky'];
|
||||
break;
|
||||
case 'seckill':
|
||||
$activityTypes = ['seckill'];
|
||||
break;
|
||||
case 'full_reduce':
|
||||
$activityTypes = ['full_reduce', 'full_discount'];
|
||||
break;
|
||||
case 'full_discount':
|
||||
$activityTypes = ['full_reduce', 'full_discount'];
|
||||
break;
|
||||
case 'free_shipping':
|
||||
$activityTypes = ['free_shipping'];
|
||||
break;
|
||||
case 'full_gift':
|
||||
$activityTypes = ['full_gift'];
|
||||
break;
|
||||
case 'signin':
|
||||
$activityTypes = ['signin'];
|
||||
break;
|
||||
}
|
||||
|
||||
return $activityTypes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据类型获取 classify
|
||||
*
|
||||
* @param string $type
|
||||
* @return string
|
||||
*/
|
||||
public function getClassify($type)
|
||||
{
|
||||
$classifys = $this->classifies();
|
||||
$activitys = array_keys($classifys['activity']);
|
||||
$promos = array_keys($classifys['promo']);
|
||||
$apps = array_keys($classifys['app']);
|
||||
|
||||
$classify = null;
|
||||
if (in_array($type, $activitys)) {
|
||||
$classify = 'activity';
|
||||
} else if (in_array($type, $promos)) {
|
||||
$classify = 'promo';
|
||||
} else if (in_array($type, $apps)) {
|
||||
$classify = 'app';
|
||||
}
|
||||
|
||||
return $classify;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* status 组合 (在thinkphp5 where Closure 中,不能直接使用 scope,特殊场景下用来代替下面的 scopeNostart scopePrehead 等)
|
||||
*
|
||||
* @param [type] $query
|
||||
* @param [type] $status
|
||||
* @return void
|
||||
*/
|
||||
public function scopeStatusComb($query, $status)
|
||||
{
|
||||
return $query->where(function ($query) use ($status) {
|
||||
foreach ($status as $st) {
|
||||
$query->whereOr(function ($query) use ($st) {
|
||||
switch($st) {
|
||||
case 'nostart':
|
||||
$query->where('start_time', '>', time());
|
||||
break;
|
||||
case 'prehead':
|
||||
$query->where('prehead_time', '<=', time())->where('start_time', '>', time());
|
||||
break;
|
||||
case 'ing':
|
||||
$query->where('start_time', '<=', time())->where('end_time', '>=', time());
|
||||
break;
|
||||
case 'show':
|
||||
$query->where('prehead_time', '<=', time())->where('end_time', '>=', time());
|
||||
break;
|
||||
case 'ended':
|
||||
$query->where('end_time', '<', time());
|
||||
break;
|
||||
default:
|
||||
error_stop('status 状态错误');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 未开始的活动
|
||||
*
|
||||
* @param think\query\Query $query
|
||||
* @return void
|
||||
*/
|
||||
public function scopeNostart($query)
|
||||
{
|
||||
return $query->where('start_time', '>', time());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 预售的活动
|
||||
*
|
||||
* @param think\query\Query $query
|
||||
* @return void
|
||||
*/
|
||||
public function scopePrehead($query)
|
||||
{
|
||||
return $query->where('prehead_time', '<=', time())->where('start_time', '>', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* 进行中的活动
|
||||
*
|
||||
* @param think\query\Query $query
|
||||
* @return void
|
||||
*/
|
||||
public function scopeIng($query)
|
||||
{
|
||||
return $query->where('start_time', '<=', time())->where('end_time', '>=', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* 已经开始预售,并且没有结束的活动
|
||||
*
|
||||
* @param think\query\Query $query
|
||||
* @return void
|
||||
*/
|
||||
public function scopeShow($query)
|
||||
{
|
||||
return $query->where('prehead_time', '<=', time())->where('end_time', '>=', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* 已经结束的活动
|
||||
*
|
||||
* @param think\query\Query $query
|
||||
* @return void
|
||||
*/
|
||||
public function scopeEnded($query)
|
||||
{
|
||||
return $query->where('end_time', '<', time());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 修改器 classify
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return integer|null
|
||||
*/
|
||||
public function setClassifyAttr($value, $data)
|
||||
{
|
||||
$classify = $value ?: ($data['classify'] ?? null);
|
||||
if (!$classify) {
|
||||
$type = $data['type'] ?? null; // 活动类型
|
||||
|
||||
$classify = $this->getClassify($type);
|
||||
}
|
||||
|
||||
return $classify;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改器 预热时间
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return integer|null
|
||||
*/
|
||||
public function setPreheadTimeAttr($value, $data)
|
||||
{
|
||||
// promo 类型 prehead_time 永远等于 start_time
|
||||
$value = (isset($data['classify']) && $data['classify'] == 'promo') ? $data['start_time'] : ($value ?: $data['start_time']);
|
||||
return $this->attrFormatUnix($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改器 开始时间
|
||||
*
|
||||
* @param string $value
|
||||
* @return integer|null
|
||||
*/
|
||||
public function setStartTimeAttr($value)
|
||||
{
|
||||
return $this->attrFormatUnix($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改器 结束时间
|
||||
*
|
||||
* @param string $value
|
||||
* @return integer|null
|
||||
*/
|
||||
public function setEndTimeAttr($value)
|
||||
{
|
||||
return $this->attrFormatUnix($value);
|
||||
}
|
||||
|
||||
|
||||
public function getStatusAttr($value, $data)
|
||||
{
|
||||
return $this->getStatusCode($data['prehead_time'], $data['start_time'], $data['end_time']);
|
||||
}
|
||||
|
||||
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
return $this->getStatusText($this->status);
|
||||
}
|
||||
|
||||
|
||||
public function getGoodsListAttr($value, $data)
|
||||
{
|
||||
if ($data['goods_ids']) {
|
||||
|
||||
$goods = Goods::field('id,title,price,sales,image,status')->whereIn('id', $data['goods_ids'])->select();
|
||||
$goods = collection($goods)->toArray(); // 全部转数组
|
||||
|
||||
$goodsIds = array_column($goods, 'id');
|
||||
$activitySkuPrices = ActivitySkuPriceModel::where('activity_id', $data['id'])->whereIn('goods_id', $goodsIds)->order('id', 'asc')->select();
|
||||
$activitySkuPrices = collection($activitySkuPrices)->toArray();
|
||||
|
||||
// 后台编辑活动时,防止不编辑规格无法提交问题
|
||||
foreach ($goods as &$gd) {
|
||||
// 处理 $gd['activity_sku_prices']
|
||||
$gd['activity_sku_prices'] = [];
|
||||
foreach ($activitySkuPrices as $skuPrice) {
|
||||
if ($skuPrice['goods_id'] == $gd['id']) {
|
||||
$gd['activity_sku_prices'][] = $skuPrice;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理活动规格,数据
|
||||
foreach ($gd['activity_sku_prices'] as $key => $skuPrice) {
|
||||
$skuPrice = ActivityFacade::showSkuPrice($data['type'], $skuPrice);
|
||||
$gd['activity_sku_prices'][$key] = $skuPrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $goods ?? [];
|
||||
}
|
||||
|
||||
|
||||
public function getRulesAttr($value, $data)
|
||||
{
|
||||
$rules = $data['rules'] ? json_decode($data['rules'], true) : [];
|
||||
$type = $data['type'];
|
||||
|
||||
// 获取各个活动规则相关的特殊数据
|
||||
$rules = ActivityFacade::rulesInfo($type, $rules);
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过时间判断活动状态
|
||||
*
|
||||
* @param integer $prehead_time 预热时间
|
||||
* @param integer $start_time 开始时间
|
||||
* @param integer $end_time 结束时间
|
||||
* @return string
|
||||
*/
|
||||
public static function getStatusCode($prehead_time, $start_time, $end_time)
|
||||
{
|
||||
// 转为时间戳,(从 redis 中取出来的是 时间格式)
|
||||
if (($prehead_time && $prehead_time > time()) || (!$prehead_time && $start_time > time())) {
|
||||
$status = 'nostart'; // 未开始
|
||||
} else if ($prehead_time && $prehead_time < time() && $start_time > time()) {
|
||||
$status = 'prehead'; // 预热
|
||||
} else if ($start_time < time() && $end_time > time()) {
|
||||
$status = 'ing';
|
||||
} else if ($end_time < time()) {
|
||||
$status = 'ended';
|
||||
}
|
||||
|
||||
return $status ?? 'ended';
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断活动状态中文
|
||||
*
|
||||
* @param string $status 活动状态
|
||||
* @return string
|
||||
*/
|
||||
public static function getStatusText($status)
|
||||
{
|
||||
if ($status == 'nostart') {
|
||||
$status_text = '未开始';
|
||||
} elseif ($status == 'prehead') {
|
||||
$status_text = '预热中';
|
||||
} elseif ($status == 'ing') {
|
||||
$status_text = '进行中';
|
||||
} elseif ($status == 'ended') {
|
||||
$status_text = '已结束';
|
||||
}
|
||||
|
||||
return $status_text ?? '已结束';
|
||||
}
|
||||
|
||||
|
||||
public function getEndTimeUnixAttr($value, $data)
|
||||
{
|
||||
return isset($data['end_time']) ? $this->getData('end_time') : 0;
|
||||
}
|
||||
|
||||
|
||||
public function activitySkuPrices()
|
||||
{
|
||||
return $this->hasMany(SkuPrice::class, 'activity_id');
|
||||
}
|
||||
}
|
||||
73
application/admin/model/shopro/activity/GiftLog.php
Normal file
73
application/admin/model/shopro/activity/GiftLog.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\activity;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class GiftLog extends Common
|
||||
{
|
||||
protected $name = 'shopro_activity_gift_log';
|
||||
|
||||
protected $type = [
|
||||
'rules' => 'json',
|
||||
'errors' => 'json'
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text',
|
||||
'status_text'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 默认状态列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'coupon' => '优惠券',
|
||||
'score' => '积分',
|
||||
'money' => '余额',
|
||||
'goods' => '商品',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 默认状态列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'waiting' => '等待赠送',
|
||||
'finish' => '赠送完成',
|
||||
'fail' => '赠送失败',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function scopeWaiting($query)
|
||||
{
|
||||
return $query->where('status', 'waiting');
|
||||
}
|
||||
|
||||
public function scopeOpered($query)
|
||||
{
|
||||
return $query->whereIn('status', ['finish', 'fail']);
|
||||
}
|
||||
|
||||
public function scopeFinish($query)
|
||||
{
|
||||
return $query->where('status', 'finish');
|
||||
}
|
||||
|
||||
public function scopeFail($query)
|
||||
{
|
||||
return $query->where('status', 'fail');
|
||||
}
|
||||
}
|
||||
98
application/admin/model/shopro/activity/Groupon.php
Normal file
98
application/admin/model/shopro/activity/Groupon.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\activity;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User;
|
||||
use app\admin\model\shopro\goods\Goods;
|
||||
use app\admin\model\shopro\order\OrderItem;
|
||||
|
||||
class Groupon extends Common
|
||||
{
|
||||
protected $name = 'shopro_activity_groupon';
|
||||
|
||||
protected $type = [
|
||||
'finish_time' => 'timestamp',
|
||||
'expire_time' => 'timestamp'
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text',
|
||||
];
|
||||
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'invalid' => '拼团失败',
|
||||
'ing' => '进行中',
|
||||
'finish' => '已成团',
|
||||
'finish_fictitious' => '虚拟成团',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询正在进行中的团
|
||||
*/
|
||||
public function scopeIng($query)
|
||||
{
|
||||
return $query->where('status', 'ing');
|
||||
}
|
||||
|
||||
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['status'] ?? '');
|
||||
|
||||
$list = $this->statusList();
|
||||
$value = ($value == 'finish_fictitious' && strpos(request()->url(), 'addons/shopro') !== false) ? 'finish' : $value;
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
public function getExpireTimeUnixAttr($value, $data)
|
||||
{
|
||||
return isset($data['expire_time']) ? $this->getData('expire_time') : 0;
|
||||
}
|
||||
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function goods()
|
||||
{
|
||||
return $this->belongsTo(Goods::class, 'goods_id', 'id');
|
||||
}
|
||||
|
||||
public function activity()
|
||||
{
|
||||
return $this->belongsTo(Activity::class, 'activity_id', 'id');
|
||||
}
|
||||
|
||||
public function grouponLogs()
|
||||
{
|
||||
return $this->hasMany(GrouponLog::class, 'groupon_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function leader()
|
||||
{
|
||||
return $this->hasOne(GrouponLog::class, 'groupon_id', 'id')->where('is_leader', 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 前端拼团详情用
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function my()
|
||||
{
|
||||
$user = auth_user();
|
||||
return $this->hasOne(GrouponLog::class, 'groupon_id', 'id')->where('user_id', ($user ? $user->id : 0))->where('is_fictitious', 0);
|
||||
}
|
||||
}
|
||||
43
application/admin/model/shopro/activity/GrouponLog.php
Normal file
43
application/admin/model/shopro/activity/GrouponLog.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\activity;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User;
|
||||
use app\admin\model\shopro\goods\Goods;
|
||||
use app\admin\model\shopro\order\Order;
|
||||
use app\admin\model\shopro\order\OrderItem;
|
||||
|
||||
class GrouponLog extends Common
|
||||
{
|
||||
protected $name = 'shopro_activity_groupon_log';
|
||||
|
||||
public function getNicknameAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['nickname'] ?? '');
|
||||
return $value ? string_hide($value, 2) : $value;
|
||||
}
|
||||
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'order_id');
|
||||
}
|
||||
|
||||
|
||||
public function groupon()
|
||||
{
|
||||
return $this->belongsTo(Groupon::class, 'groupon_id');
|
||||
}
|
||||
|
||||
public function goods()
|
||||
{
|
||||
return $this->belongsTo(Goods::class, 'goods_id');
|
||||
}
|
||||
|
||||
|
||||
public function orderItem()
|
||||
{
|
||||
return $this->hasOne(OrderItem::class, 'order_id', 'order_id');
|
||||
}
|
||||
}
|
||||
93
application/admin/model/shopro/activity/Order.php
Normal file
93
application/admin/model/shopro/activity/Order.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\activity;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use addons\shopro\facade\Activity as ActivityFacade;
|
||||
|
||||
class Order extends Common
|
||||
{
|
||||
|
||||
protected $name = 'shopro_activity_order';
|
||||
|
||||
protected $type = [
|
||||
'ext' => 'json',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'activity_type_text',
|
||||
'discount_text'
|
||||
];
|
||||
|
||||
const STATUS_UNPAID = 'unpaid';
|
||||
const STATUS_PAID = 'paid';
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'unpaid' => '未支付',
|
||||
'paid' => '已支付',
|
||||
];
|
||||
}
|
||||
|
||||
// 未支付
|
||||
public function scopeUnpaid($query)
|
||||
{
|
||||
return $query->where('status', self::STATUS_UNPAID);
|
||||
}
|
||||
|
||||
// 已支付
|
||||
public function scopePaid($query)
|
||||
{
|
||||
return $query->whereIn('status', [self::STATUS_PAID]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getActivityTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['activity_type'] ?? null);
|
||||
$ext = $this->ext;
|
||||
|
||||
$list = (new Activity)->typeList();
|
||||
$text = isset($list[$value]) ? $list[$value] : '';
|
||||
|
||||
if (in_array($value, ['groupon', 'groupon_ladder'])) {
|
||||
if (in_array($data['status'], [self::STATUS_PAID]) && (!isset($ext['groupon_id']) || !$ext['groupon_id'])) {
|
||||
// 已支付,并且没有团 id,就是单独购买
|
||||
$text .= '-单独购买';
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
public function getDiscountTextAttr($value, $data)
|
||||
{
|
||||
$ext = $this->ext;
|
||||
$discount_text = '';
|
||||
if ($ext && isset($ext['rules']) && $ext['rules']) {
|
||||
$tags = ActivityFacade::formatRuleTags([
|
||||
'type' => $ext['rules']['rule_type'],
|
||||
'discounts' => [$ext['rules']['discount_rule']]
|
||||
], $data['activity_type']);
|
||||
|
||||
$discount_text = $tags[0] ?? '';
|
||||
}
|
||||
|
||||
return $discount_text ?: $this->activity_type_text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getGoodsIdsAttr($value, $data)
|
||||
{
|
||||
return $this->attrFormatComma($value, $data, 'goods_ids', true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
21
application/admin/model/shopro/activity/Signin.php
Normal file
21
application/admin/model/shopro/activity/Signin.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\activity;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Signin extends Common
|
||||
{
|
||||
|
||||
protected $name = 'shopro_activity_signin';
|
||||
|
||||
protected $type = [
|
||||
'rules' => 'json'
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
128
application/admin/model/shopro/activity/SkuPrice.php
Normal file
128
application/admin/model/shopro/activity/SkuPrice.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\activity;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class SkuPrice extends Common
|
||||
{
|
||||
protected $name = 'shopro_activity_sku_price';
|
||||
|
||||
protected $type = [
|
||||
'ext' => 'json',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 普通拼团,团长价
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getLeaderPriceAttr($value, $data)
|
||||
{
|
||||
$ext = $data['ext'];
|
||||
$is_leader_discount = $ext['is_leader_discount'] ?? 0;
|
||||
$leader_price = $ext['leader_price'] ?? 0;
|
||||
|
||||
$leader_price = $is_leader_discount ? $leader_price : $data['price'];
|
||||
return $leader_price;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function currentLadder($data, $level, $is_leader = false)
|
||||
{
|
||||
$ext = $data['ext'];
|
||||
$is_leader_discount = $ext['is_leader_discount'] ?? 0;
|
||||
$ladders = $ext['ladders'] ?? [];
|
||||
$ladders = array_column($ladders, null, 'ladder_level');
|
||||
$currentLadder = $ladders[$level] ?? []; // 当前阶梯的 价格数据
|
||||
|
||||
$key = ($is_leader && $is_leader_discount) ? 'leader_ladder_price' : 'ladder_price';
|
||||
return $currentLadder[$key] ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 阶梯拼团,第一阶梯价
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getLadderOneAttr($value, $data)
|
||||
{
|
||||
return $this->currentLadder($data, 'ladder_one');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 阶梯拼团,第二阶梯价
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getLadderTwoAttr($value, $data)
|
||||
{
|
||||
return $this->currentLadder($data, 'ladder_two');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 阶梯拼团,第二阶梯价
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getLadderThreeAttr($value, $data)
|
||||
{
|
||||
return $this->currentLadder($data, 'ladder_three');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 阶梯拼团,第一阶梯团长价
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getLadderOneLeaderAttr($value, $data)
|
||||
{
|
||||
return $this->currentLadder($data, 'ladder_one', true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 阶梯拼团,第二阶团长梯价
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getLadderTwoLeaderAttr($value, $data)
|
||||
{
|
||||
return $this->currentLadder($data, 'ladder_two', true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 阶梯拼团,第二阶团长梯价
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getLadderThreeLeaderAttr($value, $data)
|
||||
{
|
||||
return $this->currentLadder($data, 'ladder_three', true);
|
||||
}
|
||||
}
|
||||
63
application/admin/model/shopro/app/ScoreSkuPrice.php
Normal file
63
application/admin/model/shopro/app/ScoreSkuPrice.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\app;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
use app\admin\model\shopro\goods\SkuPrice;
|
||||
|
||||
class ScoreSkuPrice extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
protected $name = 'shopro_score_sku_price';
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $type = [
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
|
||||
];
|
||||
|
||||
public function getGoodsSkuIdsAttr($value, $data)
|
||||
{
|
||||
$skuPrice = $this->sku_price;
|
||||
return $skuPrice ? $skuPrice->goods_sku_ids : '';
|
||||
}
|
||||
|
||||
|
||||
public function getGoodsSkuTextAttr($value, $data)
|
||||
{
|
||||
$skuPrice = $this->sku_price;
|
||||
return $skuPrice ? $skuPrice->goods_sku_text : '';
|
||||
}
|
||||
|
||||
public function getImageAttr($value, $data)
|
||||
{
|
||||
$skuPrice = $this->sku_price;
|
||||
return $skuPrice ? $skuPrice->image : '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 积分加现金
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getScorePriceAttr($value, $data)
|
||||
{
|
||||
$score = $data['score'] ?? 0;
|
||||
$price = $data['price'] ?? 0;
|
||||
|
||||
return $score . '积分' . ($price ? '+¥' . $price : '');
|
||||
}
|
||||
|
||||
|
||||
public function skuPrice() {
|
||||
return $this->belongsTo(SkuPrice::class, 'goods_sku_price_id');
|
||||
}
|
||||
}
|
||||
53
application/admin/model/shopro/app/mplive/Goods.php
Normal file
53
application/admin/model/shopro/app/mplive/Goods.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\app\mplive;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Goods extends Common
|
||||
{
|
||||
|
||||
protected $name = 'shopro_mplive_goods';
|
||||
|
||||
protected $append = [
|
||||
'audit_status_text',
|
||||
'type_text',
|
||||
'price_type_text',
|
||||
];
|
||||
|
||||
/**
|
||||
* 类型列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function typeList()
|
||||
{
|
||||
return [0 => '我的小程序', 1 => '其他小程序'];
|
||||
}
|
||||
|
||||
public function auditStatusList()
|
||||
{
|
||||
return [0 => '未审核', 1 => '审核中', 2 => '审核通过', 3 => '审核失败'];
|
||||
}
|
||||
|
||||
public function priceTypeList()
|
||||
{
|
||||
return [1 => '一口价', 2 => '价格区间', 3 => '折扣价'];
|
||||
}
|
||||
|
||||
public function getPriceTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['price_type'] ?? null);
|
||||
|
||||
$list = $this->priceTypeList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
public function getAuditStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['audit_status'] ?? null);
|
||||
|
||||
$list = $this->auditStatusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
}
|
||||
99
application/admin/model/shopro/app/mplive/Room.php
Normal file
99
application/admin/model/shopro/app/mplive/Room.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\app\mplive;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Room extends Common
|
||||
{
|
||||
|
||||
protected $name = 'shopro_mplive_room';
|
||||
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'type_text',
|
||||
];
|
||||
|
||||
const ERR_CODE = [
|
||||
-1 => '系统错误',
|
||||
1 => '未创建直播间',
|
||||
1003 => '商品 id 不存在',
|
||||
47001 => '入参格式不符合规范',
|
||||
200002 => '入参错误',
|
||||
300001 => '禁止创建/更新商品 或 禁止编辑/更新房间',
|
||||
300002 => '名称长度不符合规则',
|
||||
300003 => '价格输入不合规(如:现价比原价大、传入价格非数字等)',
|
||||
300004 => '商品名称存在违规违法内容',
|
||||
300005 => '商品图片存在违规违法内容',
|
||||
300006 => ' 图片上传失败(如:mediaID过期)',
|
||||
300007 => '线上小程序版本不存在该链接',
|
||||
300008 => '添加商品失败',
|
||||
300009 => '商品审核撤回失败',
|
||||
300010 => '商品审核状态不对(如:商品审核中)',
|
||||
300011 => '操作非法(API不允许操作非 API 创建的商品)',
|
||||
300012 => '没有提审额度(每天500次提审额度)',
|
||||
300013 => '提审失败',
|
||||
300014 => '审核中,无法删除(非零代表失败)',
|
||||
300017 => '商品未提审',
|
||||
300018 => '商品图片尺寸过大',
|
||||
300021 => '商品添加成功,审核失败',
|
||||
300022 => '此房间号不存在',
|
||||
300023 => '房间状态 拦截(当前房间状态不允许此操作)',
|
||||
300024 => '商品不存在',
|
||||
300025 => '商品审核未通过',
|
||||
300026 => '房间商品数量已经满额',
|
||||
300027 => '导入商品失败',
|
||||
300028 => '房间名称违规',
|
||||
300029 => '主播昵称违规',
|
||||
300030 => '主播微信号不合法',
|
||||
300031 => '直播间封面图不合规',
|
||||
300032 => '直播间分享图违规',
|
||||
300033 => '添加商品超过直播间上限',
|
||||
300034 => '主播微信昵称长度不符合要求',
|
||||
300035 => '主播微信号不存在',
|
||||
300036 => '主播微信号未实名认证',
|
||||
300037 => '购物直播频道封面图不合规',
|
||||
300038 => '未在小程序管理后台配置客服',
|
||||
300039 => '主播副号微信号不合法',
|
||||
300040 => '名称含有非限定字符(含有特殊字符)',
|
||||
300041 => '创建者微信号不合法',
|
||||
300042 => '推流中禁止编辑房间',
|
||||
300043 => '每天只允许一场直播开启关注',
|
||||
300044 => '商品没有讲解视频',
|
||||
300045 => '讲解视频未生成',
|
||||
300046 => '讲解视频生成失败',
|
||||
300047 => '已有商品正在推送,请稍后再试',
|
||||
300048 => '拉取商品列表失败',
|
||||
300049 => '商品推送过程中不允许上下架',
|
||||
300050 => '排序商品列表为空',
|
||||
300051 => '解析 JSON 出错',
|
||||
300052 => '已下架的商品无法推送',
|
||||
300053 => '直播间未添加此商品',
|
||||
500001 => '副号不合规',
|
||||
500002 => '副号未实名',
|
||||
500003 => '已经设置过副号了,不能重复设置',
|
||||
500004 => '不能设置重复的副号',
|
||||
500005 => '副号不能和主号重复',
|
||||
600001 => '用户已被添加为小助手',
|
||||
600002 => '找不到用户',
|
||||
9410000 => '直播间列表为空',
|
||||
9410001 => '获取房间失败',
|
||||
9410002 => '获取商品失败',
|
||||
9410003 => '获取回放失败',
|
||||
];
|
||||
|
||||
/**
|
||||
* 类型列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function typeList()
|
||||
{
|
||||
return [0 => '手机直播', 1 => '推流'];
|
||||
}
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [101 => '直播中', 102 => '未开始', 103 => '已结束', 104 => '禁播', 105 => '暂停', 106 => '异常', 107 => '已过期'];
|
||||
}
|
||||
}
|
||||
23
application/admin/model/shopro/chat/CommonWord.php
Normal file
23
application/admin/model/shopro/chat/CommonWord.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\chat;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\chat\traits\ChatCommon;
|
||||
|
||||
class CommonWord extends Common
|
||||
{
|
||||
use ChatCommon;
|
||||
|
||||
protected $name = 'shopro_chat_common_word';
|
||||
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'room_name'
|
||||
];
|
||||
|
||||
public function scopeRoomId($query, $room_id)
|
||||
{
|
||||
return $query->where('room_id', $room_id);
|
||||
}
|
||||
}
|
||||
57
application/admin/model/shopro/chat/CustomerService.php
Normal file
57
application/admin/model/shopro/chat/CustomerService.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\chat;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\chat\Record;
|
||||
use app\admin\model\shopro\chat\CustomerServiceUser;
|
||||
use app\admin\model\shopro\chat\traits\ChatCommon;
|
||||
|
||||
class CustomerService extends Common
|
||||
{
|
||||
use ChatCommon;
|
||||
|
||||
protected $name = 'shopro_chat_customer_service';
|
||||
|
||||
protected $append = [
|
||||
'auth_model',
|
||||
'auth_text',
|
||||
'status_text',
|
||||
'room_name'
|
||||
];
|
||||
|
||||
// 自动数据类型转换
|
||||
protected $type = [
|
||||
'last_time' => 'timestamp',
|
||||
];
|
||||
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return ['offline' => '离线', 'online' => '在线', 'busy' => '忙碌'];
|
||||
}
|
||||
|
||||
|
||||
public function getAuthModelAttr($value, $data)
|
||||
{
|
||||
return $this->customer_service_user['auth_model'] ?? null;
|
||||
}
|
||||
|
||||
public function getAuthTextAttr($value, $data)
|
||||
{
|
||||
return $this->customer_service_user['auth_text'] ?? null;
|
||||
}
|
||||
|
||||
|
||||
public function customerService()
|
||||
{
|
||||
return $this->morphMany(Record::class, ['sender_identify', 'sender_id'], 'customer_service');
|
||||
}
|
||||
|
||||
public function customerServiceUser()
|
||||
{
|
||||
return $this->HasOne(CustomerServiceUser::class, 'customer_service_id');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
62
application/admin/model/shopro/chat/CustomerServiceUser.php
Normal file
62
application/admin/model/shopro/chat/CustomerServiceUser.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\chat;
|
||||
|
||||
use app\admin\model\Admin;
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\chat\CustomerService;
|
||||
use app\admin\model\shopro\user\User as ShopUser;
|
||||
|
||||
class CustomerServiceUser extends Common
|
||||
{
|
||||
protected $name = 'shopro_chat_customer_service_user';
|
||||
|
||||
|
||||
protected $append = [
|
||||
'auth_model',
|
||||
'auth_text'
|
||||
];
|
||||
|
||||
public static $authType = [
|
||||
'admin' => ['name' => '管理员', 'value' => 'admin'],
|
||||
'user' => ['name' => '用户', 'value' => 'user'],
|
||||
];
|
||||
|
||||
public function scopeAuthAdmin($query, $admin_id)
|
||||
{
|
||||
return $query->where('auth', 'admin')->where('auth_id', $admin_id);
|
||||
}
|
||||
|
||||
|
||||
public function scopeAuthUser($query, $user_id)
|
||||
{
|
||||
return $query->where('auth', 'user')->where('auth_id', $user_id);
|
||||
}
|
||||
|
||||
|
||||
public function getAuthModelAttr($value, $data)
|
||||
{
|
||||
return $this->{$data['auth']};
|
||||
}
|
||||
|
||||
public function getAuthTextAttr($value, $data)
|
||||
{
|
||||
return self::$authType[$data['auth']]['name'] ?? '';
|
||||
}
|
||||
|
||||
|
||||
public function admin()
|
||||
{
|
||||
return $this->belongsTo(Admin::class, 'auth_id');
|
||||
}
|
||||
|
||||
public function customerService()
|
||||
{
|
||||
return $this->belongsTo(CustomerService::class, 'customer_service_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(ShopUser::class, 'auth_id');
|
||||
}
|
||||
}
|
||||
23
application/admin/model/shopro/chat/Question.php
Normal file
23
application/admin/model/shopro/chat/Question.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\chat;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\chat\traits\ChatCommon;
|
||||
|
||||
class Question extends Common
|
||||
{
|
||||
use ChatCommon;
|
||||
|
||||
protected $name = 'shopro_chat_question';
|
||||
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'room_name'
|
||||
];
|
||||
|
||||
public function scopeRoomId($query, $room_id)
|
||||
{
|
||||
return $query->where('room_id', $room_id);
|
||||
}
|
||||
}
|
||||
94
application/admin/model/shopro/chat/Record.php
Normal file
94
application/admin/model/shopro/chat/Record.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\chat;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\chat\traits\ChatCommon;
|
||||
|
||||
class Record extends Common
|
||||
{
|
||||
use ChatCommon;
|
||||
|
||||
protected $name = 'shopro_chat_record';
|
||||
|
||||
protected $append = [
|
||||
'room_name'
|
||||
];
|
||||
|
||||
// 不格式化创建更新时间
|
||||
protected $dateFormat = false;
|
||||
|
||||
public function scopeCustomer($query)
|
||||
{
|
||||
return $query->where('sender_identify', 'customer');
|
||||
}
|
||||
|
||||
|
||||
public function scopeCustomerService($query)
|
||||
{
|
||||
return $query->where('sender_identify', 'customer_service');
|
||||
}
|
||||
|
||||
public function scopeNoRead($query)
|
||||
{
|
||||
return $query->whereNull('read_time');
|
||||
}
|
||||
|
||||
|
||||
public function setMessageAttr($value, $data)
|
||||
{
|
||||
switch ($data['message_type']) {
|
||||
case 'order':
|
||||
case 'goods':
|
||||
$value = is_array($value) ? json_encode($value) : $value;
|
||||
break;
|
||||
default :
|
||||
$value = $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理消息
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getMessageAttr($value, $data)
|
||||
{
|
||||
switch($data['message_type']) {
|
||||
case 'order':
|
||||
case 'goods':
|
||||
$message = json_decode($value, true);
|
||||
|
||||
break;
|
||||
default :
|
||||
$message = $value;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// if ($data['message_type'] == 'image') {
|
||||
// $message = Online::cdnurl($value);
|
||||
// } else if (in_array($data['message_type'], ['order', 'goods'])) {
|
||||
// $messageArr = json_decode($value, true);
|
||||
// if (isset($messageArr['image']) && $messageArr['image']) {
|
||||
// $messageArr['image'] = Online::cdnurl($messageArr['image']);
|
||||
// }
|
||||
|
||||
// $message = json_encode($messageArr);
|
||||
// } else if ($data['message_type'] == 'text') {
|
||||
// // 全文匹配图片拼接 cdnurl
|
||||
// $url = Online::cdnurl('/uploads');
|
||||
// $message = str_replace("<img src=\"/uploads", "<img style=\"width: 100%;!important\" src=\"" . $url, $value);
|
||||
// } else {
|
||||
// $message = $value;
|
||||
// }
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
}
|
||||
22
application/admin/model/shopro/chat/ServiceLog.php
Normal file
22
application/admin/model/shopro/chat/ServiceLog.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\chat;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\chat\traits\ChatCommon;
|
||||
|
||||
class ServiceLog extends Common
|
||||
{
|
||||
use ChatCommon;
|
||||
|
||||
protected $name = 'shopro_chat_service_log';
|
||||
|
||||
protected $append = [
|
||||
'room_name'
|
||||
];
|
||||
|
||||
public function chatUser()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'chat_user_id');
|
||||
}
|
||||
}
|
||||
33
application/admin/model/shopro/chat/User.php
Normal file
33
application/admin/model/shopro/chat/User.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\chat;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User as ShopUser;
|
||||
|
||||
|
||||
class User extends Common
|
||||
{
|
||||
protected $name = 'shopro_chat_user';
|
||||
|
||||
// 自动数据类型转换
|
||||
protected $type = [
|
||||
'last_time' => 'timestamp',
|
||||
];
|
||||
|
||||
public function customer()
|
||||
{
|
||||
return $this->morphMany(Record::class, ['sender_identify', 'sender_id'], 'customer');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(ShopUser::class, 'auth_id');
|
||||
}
|
||||
|
||||
|
||||
public function customerService()
|
||||
{
|
||||
return $this->belongsTo(CustomerService::class, 'customer_service_id');
|
||||
}
|
||||
}
|
||||
31
application/admin/model/shopro/chat/traits/ChatCommon.php
Normal file
31
application/admin/model/shopro/chat/traits/ChatCommon.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\chat\traits;
|
||||
|
||||
trait ChatCommon
|
||||
{
|
||||
|
||||
/**
|
||||
* 默认房间
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static function defaultRooms()
|
||||
{
|
||||
return [
|
||||
['name' => '总后台', 'value' => 'admin'],
|
||||
// ['name' => '官网', 'value' => 'official'],
|
||||
// ['name' => '商城', 'value' => 'shop']
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function getRoomNameAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['room_id'] ?? null);
|
||||
|
||||
$list = array_column(self::defaultRooms(), null, 'value');
|
||||
return isset($list[$value]) ? $list[$value]['name'] : $value;
|
||||
}
|
||||
|
||||
}
|
||||
83
application/admin/model/shopro/commission/Agent.php
Normal file
83
application/admin/model/shopro/commission/Agent.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\commission;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User;
|
||||
|
||||
class Agent extends Common
|
||||
{
|
||||
protected $pk = 'user_id';
|
||||
|
||||
protected $name = 'shopro_commission_agent';
|
||||
|
||||
protected $type = [
|
||||
'become_time' => 'timestamp',
|
||||
'apply_info' => 'json',
|
||||
'child_agent_level_1' => 'json',
|
||||
'child_agent_level_all' => 'json',
|
||||
];
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'pending_reward'
|
||||
];
|
||||
|
||||
// 分销商状态 AGENT_STATUS
|
||||
const AGENT_STATUS_NORMAL = 'normal'; // 正常
|
||||
const AGENT_STATUS_PENDING = 'pending'; // 审核中 不分佣、不打款、没有团队信息
|
||||
const AGENT_STATUS_FREEZE = 'freeze'; // 冻结 正常记录分佣、不打款,记录业绩和团队信息 冻结解除后立即打款
|
||||
const AGENT_STATUS_FORBIDDEN = 'forbidden'; // 禁用 不分佣、不记录业绩和团队信息
|
||||
const AGENT_STATUS_NEEDINFO = 'needinfo'; // 需要完善表单资料 临时状态
|
||||
const AGENT_STATUS_REJECT = 'reject'; // 审核驳回, 重新修改 临时状态
|
||||
const AGENT_STATUS_NULL = NULL; // 未满足成为分销商条件
|
||||
|
||||
|
||||
// 分销商升级锁 UPGRADE_LOCK
|
||||
const UPGRADE_LOCK_OPEN = 1; // 禁止分销商升级
|
||||
const UPGRADE_LOCK_CLOSE = 0; // 允许分销商升级
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'normal' => '正常',
|
||||
'pending' => '审核中',
|
||||
'freeze' => '冻结',
|
||||
'forbidden' => '禁用',
|
||||
'reject' => '拒绝'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 可用分销商
|
||||
*/
|
||||
public function scopeAvaliable($query)
|
||||
{
|
||||
return $query->where('status', 'in', [self::AGENT_STATUS_NORMAL, self::AGENT_STATUS_FREEZE]);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id', 'id')->field('id, nickname, avatar, mobile, total_consume, parent_user_id');
|
||||
}
|
||||
|
||||
public function levelInfo()
|
||||
{
|
||||
return $this->belongsTo(Level::class, 'level', 'level')->field(['level', 'name', 'image', 'commission_rules']);
|
||||
}
|
||||
|
||||
public function getPendingRewardAttr($value, $data)
|
||||
{
|
||||
$amount = Reward::pending()->where('agent_id', $data['user_id'])->sum('commission');
|
||||
return number_format($amount, 2, '.', '');
|
||||
}
|
||||
|
||||
public function levelStatusInfo()
|
||||
{
|
||||
return $this->belongsTo(Level::class, 'level_status', 'level');
|
||||
}
|
||||
|
||||
public function upgradeLevel()
|
||||
{
|
||||
return $this->belongsTo(Level::class, 'level_status', 'level');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\commission;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\goods\Goods as GoodsModel;
|
||||
|
||||
class CommissionGoods extends Common
|
||||
{
|
||||
protected $pk = 'goods_id';
|
||||
|
||||
protected $name = 'shopro_commission_goods';
|
||||
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
// 分销状态
|
||||
const GOODS_COMMISSION_STATUS_OFF = 0; // 商品不参与分佣
|
||||
const GOODS_COMMISSION_STATUS_ON = 1; // 商品参与分佣
|
||||
const GOODS_COMMISSION_RULES_DEFAULT = 0; // 默认分销规则 只看系统分销商等级规则
|
||||
const GOODS_COMMISSION_RULES_SELF = 1; // 独立分销规则 等级规则对应多种规格规则
|
||||
const GOODS_COMMISSION_RULES_BATCH = 2; // 批量分销规则 只看保存的各分销商等级规则
|
||||
|
||||
protected $type = [
|
||||
'commission_rules' => 'json'
|
||||
];
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
0 => '不参与',
|
||||
1 => '参与中'
|
||||
];
|
||||
}
|
||||
|
||||
public function getCommissionConfigAttr($value, $data)
|
||||
{
|
||||
return json_decode($value, true);
|
||||
}
|
||||
|
||||
public function goods()
|
||||
{
|
||||
return $this->belongsTo(GoodsModel::class, 'goods_id', 'id');
|
||||
}
|
||||
}
|
||||
20
application/admin/model/shopro/commission/Level.php
Normal file
20
application/admin/model/shopro/commission/Level.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\commission;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Level extends Common
|
||||
{
|
||||
protected $pk = 'level';
|
||||
|
||||
protected $name = 'shopro_commission_level';
|
||||
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
protected $type = [
|
||||
'commission_rules' => 'json',
|
||||
'upgrade_rules' => 'json'
|
||||
];
|
||||
|
||||
}
|
||||
232
application/admin/model/shopro/commission/Log.php
Normal file
232
application/admin/model/shopro/commission/Log.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\commission;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use addons\shopro\library\Operator;
|
||||
use app\admin\model\shopro\user\User as UserModel;
|
||||
|
||||
class Log extends Common
|
||||
{
|
||||
protected $name = 'shopro_commission_log';
|
||||
|
||||
protected $updateTime = false;
|
||||
|
||||
protected $append = [
|
||||
'event_text',
|
||||
'oper_type_text'
|
||||
];
|
||||
|
||||
/**
|
||||
* 添加分销记录
|
||||
*
|
||||
* @param object $agentId 分销商ID
|
||||
* @param string $event 事件类型
|
||||
* @param array $ext 扩展信息
|
||||
* @param object $oper 操作人
|
||||
* @param string $remark 自定义备注
|
||||
*
|
||||
*/
|
||||
public static function add($agentId, $event, $ext = [], $oper = NULL, $remark = '')
|
||||
{
|
||||
if ($remark === '') {
|
||||
switch ($event) {
|
||||
case 'agent':
|
||||
$remark = self::setAgentEvent($ext);
|
||||
break;
|
||||
case 'share':
|
||||
$remark = self::setShareEvent($ext);
|
||||
break;
|
||||
case 'bind':
|
||||
$remark = self::setBindEvent($ext);
|
||||
break;
|
||||
case 'order':
|
||||
$remark = self::setOrderEvent($ext);
|
||||
break;
|
||||
case 'reward':
|
||||
$remark = self::setRewardEvent($ext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($remark !== '') {
|
||||
$oper = Operator::get($oper);
|
||||
$log = [
|
||||
'agent_id' => $agentId,
|
||||
'event' => $event,
|
||||
'remark' => $remark,
|
||||
'oper_type' => $oper['type'],
|
||||
'oper_id' => $oper['id'],
|
||||
'createtime' => time()
|
||||
];
|
||||
return self::create($log);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public static function setAgentEvent($ext)
|
||||
{
|
||||
switch ($ext['type']) {
|
||||
case 'status': // 变更状态
|
||||
switch ($ext['value']) {
|
||||
case Agent::AGENT_STATUS_PENDING:
|
||||
$remark = "您的资料已提交,等待管理员审核";
|
||||
break;
|
||||
case Agent::AGENT_STATUS_FORBIDDEN:
|
||||
$remark = "您的账户已被禁用";
|
||||
break;
|
||||
case Agent::AGENT_STATUS_NORMAL:
|
||||
$remark = "恭喜您成为分销商";
|
||||
break;
|
||||
case Agent::AGENT_STATUS_FREEZE:
|
||||
$remark = "您的账户已被冻结";
|
||||
break;
|
||||
case Agent::AGENT_STATUS_REJECT:
|
||||
$remark = "您的申请已被拒绝,请重新申请";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'level': // 变更等级
|
||||
$remark = "您的等级已变更为[{$ext['level']['name']}]";
|
||||
break;
|
||||
case 'apply_info':
|
||||
$remark = '您的分销商资料信息已更新';
|
||||
break;
|
||||
}
|
||||
return $remark ?? "";
|
||||
}
|
||||
|
||||
public static function setShareEvent($ext)
|
||||
{
|
||||
$remark = "您已成为用户[{$ext['user']['nickname']}]的推荐人";
|
||||
return $remark;
|
||||
}
|
||||
|
||||
public static function setBindEvent($ext)
|
||||
{
|
||||
$remark = "";
|
||||
if ($ext['user']) {
|
||||
$remark = "用户[{$ext['user']['nickname']}]已绑定为您的推荐人";
|
||||
}
|
||||
return $remark;
|
||||
}
|
||||
|
||||
public static function setOrderEvent($ext)
|
||||
{
|
||||
switch ($ext['type']) {
|
||||
case 'paid':
|
||||
$goodsName = $ext['item']['goods_title'];
|
||||
if (mb_strlen($goodsName) > 9) {
|
||||
$goodsName = mb_substr($goodsName, 0, 5) . '...' . mb_substr($goodsName, -3);
|
||||
}
|
||||
if ($ext['order']['self_buy'] == 1) {
|
||||
$remark = "您购买了{$goodsName},为您新增业绩{$ext['order']['amount']}元, +1分销订单";
|
||||
} else {
|
||||
$remark = "用户{$ext['buyer']['nickname']}购买了{$goodsName},为您新增业绩{$ext['order']['amount']}元, +1分销订单";
|
||||
}
|
||||
break;
|
||||
case 'refund':
|
||||
$remark = "用户{$ext['buyer']['nickname']}已退款,扣除业绩{$ext['order']['amount']}元, -1分销订单";
|
||||
break;
|
||||
case 'admin':
|
||||
$remark = "扣除业绩{$ext['order']['amount']}元, -1分销订单";
|
||||
break;
|
||||
}
|
||||
return $remark;
|
||||
}
|
||||
|
||||
public static function setRewardEvent($ext)
|
||||
{
|
||||
$actionStr = '';
|
||||
$remark = '';
|
||||
switch ($ext['type']) {
|
||||
case 'paid':
|
||||
$actionStr = '支付成功';
|
||||
break;
|
||||
case 'confirm':
|
||||
$actionStr = '已确认收货';
|
||||
break;
|
||||
case 'finish':
|
||||
$actionStr = '已完成订单';
|
||||
break;
|
||||
}
|
||||
if ($actionStr !== '') {
|
||||
$remark = "用户{$actionStr}, ";
|
||||
}
|
||||
switch ($ext['reward']['status']) {
|
||||
case Reward::COMMISSION_REWARD_STATUS_PENDING:
|
||||
$rewardStatus = '待入账';
|
||||
break;
|
||||
case Reward::COMMISSION_REWARD_STATUS_ACCOUNTED:
|
||||
$rewardStatus = '已入账';
|
||||
break;
|
||||
case Reward::COMMISSION_REWARD_STATUS_BACK:
|
||||
$rewardStatus = '已扣除';
|
||||
break;
|
||||
case Reward::COMMISSION_REWARD_STATUS_CANCEL:
|
||||
$rewardStatus = '已取消';
|
||||
break;
|
||||
}
|
||||
$remark .= "您有{$ext['reward']['commission']}元佣金{$rewardStatus}";
|
||||
|
||||
return $remark;
|
||||
}
|
||||
|
||||
|
||||
public function eventList()
|
||||
{
|
||||
return [
|
||||
'agent' => '分销商',
|
||||
'order' => '订单',
|
||||
'reward' => '佣金',
|
||||
'share' => '推荐',
|
||||
'bind' => '绑定',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function operTypeList()
|
||||
{
|
||||
return [
|
||||
'user' => '用户',
|
||||
'admin' => '管理员',
|
||||
'system' => '系统',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 事件类型
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getEventTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['event'] ?? null);
|
||||
|
||||
$list = $this->eventList();
|
||||
return isset($list[$value]) ? $list[$value] : '-';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 操作人类型
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getOperTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['oper_type'] ?? null);
|
||||
|
||||
$list = $this->operTypeList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
public function agent()
|
||||
{
|
||||
return $this->belongsTo(UserModel::class, 'agent_id', 'id')->field('id, username, nickname, avatar, gender');
|
||||
}
|
||||
}
|
||||
116
application/admin/model/shopro/commission/Order.php
Normal file
116
application/admin/model/shopro/commission/Order.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\commission;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User as UserModel;
|
||||
use app\admin\model\shopro\order\Order as OrderModel;
|
||||
use app\admin\model\shopro\order\OrderItem as OrderItemModel;
|
||||
|
||||
class Order extends Common
|
||||
{
|
||||
const COMMISSION_ORDER_STATUS_NO = 0; // 不计入
|
||||
const COMMISSION_ORDER_STATUS_YES = 1; // 已计入
|
||||
const COMMISSION_ORDER_STATUS_CANCEL = -1; // 已取消
|
||||
const COMMISSION_ORDER_STATUS_BACK = -2; // 已扣除
|
||||
|
||||
protected $name = 'shopro_commission_order';
|
||||
|
||||
protected $type = [
|
||||
'commission_rules' => 'json',
|
||||
'commission_time' => 'timestamp'
|
||||
];
|
||||
|
||||
protected $append = [
|
||||
'reward_event_text',
|
||||
'reward_type_text',
|
||||
'commission_order_status_text',
|
||||
'commission_reward_status_text'
|
||||
];
|
||||
|
||||
public function getRewardEventTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['reward_event'] ?? '');
|
||||
$eventMap = [
|
||||
'paid' => '支付后结算',
|
||||
'confirm' => '收货后结算',
|
||||
'finish' => '订单完成结算',
|
||||
'admin' => '手动结算'
|
||||
];
|
||||
return isset($eventMap[$value]) ? $eventMap[$value] : '-';
|
||||
}
|
||||
|
||||
public function getRewardTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['reward_type'] ?? '');
|
||||
$eventMap = [
|
||||
'goods_price' => '商品价',
|
||||
'pay_price' => '实际支付价'
|
||||
];
|
||||
return isset($eventMap[$value]) ? $eventMap[$value] : '-';
|
||||
}
|
||||
|
||||
public function getCommissionOrderStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['commission_order_status'] ?? '');
|
||||
$eventMap = [
|
||||
-2 => '已扣除',
|
||||
-1 => '已取消',
|
||||
0 => '不计入',
|
||||
1 => '已计入'
|
||||
];
|
||||
return isset($eventMap[$value]) ? $eventMap[$value] : '-';
|
||||
}
|
||||
|
||||
public function getCommissionRewardStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['commission_reward_status'] ?? '');
|
||||
$eventMap = [
|
||||
-2 => '已退回',
|
||||
-1 => '已取消',
|
||||
0 => '未结算',
|
||||
1 => '已结算'
|
||||
];
|
||||
return isset($eventMap[$value]) ? $eventMap[$value] : '-';
|
||||
}
|
||||
|
||||
public function scopeBack($query)
|
||||
{
|
||||
return $query->where('commission_order_status', self::COMMISSION_ORDER_STATUS_BACK);
|
||||
}
|
||||
|
||||
public function scopeYes($query)
|
||||
{
|
||||
return $query->where('commission_order_status', self::COMMISSION_ORDER_STATUS_YES);
|
||||
}
|
||||
|
||||
public function scopeCancel($query)
|
||||
{
|
||||
return $query->where('commission_order_status', self::COMMISSION_ORDER_STATUS_CANCEL);
|
||||
}
|
||||
|
||||
public function buyer()
|
||||
{
|
||||
return $this->belongsTo(UserModel::class, 'buyer_id', 'id')->field('id, nickname, avatar, mobile');
|
||||
}
|
||||
|
||||
public function agent()
|
||||
{
|
||||
return $this->belongsTo(UserModel::class, 'agent_id', 'id')->field('id, nickname, avatar, mobile');
|
||||
}
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(OrderModel::class, 'order_id', 'id');
|
||||
}
|
||||
|
||||
public function orderItem()
|
||||
{
|
||||
return $this->belongsTo(OrderItemModel::class, 'order_item_id', 'id');
|
||||
}
|
||||
|
||||
public function rewards()
|
||||
{
|
||||
return $this->hasMany(Reward::class, 'commission_order_id', 'id');
|
||||
}
|
||||
}
|
||||
112
application/admin/model/shopro/commission/Reward.php
Normal file
112
application/admin/model/shopro/commission/Reward.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\commission;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User as UserModel;
|
||||
use app\admin\model\shopro\order\Order as OrderModel;
|
||||
use app\admin\model\shopro\order\OrderItem as OrderItemModel;
|
||||
|
||||
class Reward extends Common
|
||||
{
|
||||
|
||||
const COMMISSION_REWARD_STATUS_PENDING = 0; // 未结算、待入账
|
||||
const COMMISSION_REWARD_STATUS_ACCOUNTED = 1; // 已结算、已入账
|
||||
const COMMISSION_REWARD_STATUS_CANCEL = -1; // 已取消
|
||||
const COMMISSION_REWARD_STATUS_BACK = -2; // 已退回
|
||||
|
||||
protected $name = 'shopro_commission_reward';
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'createtime';
|
||||
protected $updateTime = 'updatetime';
|
||||
protected $type = [
|
||||
'commission_rules' => 'json',
|
||||
'commission_time' => 'timestamp'
|
||||
];
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'type_text'
|
||||
];
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
-2 => '已退回',
|
||||
-1 => '已取消',
|
||||
0 => '未结算',
|
||||
1 => '已结算'
|
||||
];
|
||||
}
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'commission' => '佣金钱包',
|
||||
'money' => '余额钱包',
|
||||
'score' => '积分钱包',
|
||||
'bank' => '企业付款到银行卡',
|
||||
'change' => '企业付款到零钱'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 待入账
|
||||
*/
|
||||
public function scopePending($query)
|
||||
{
|
||||
return $query->where('status', self::COMMISSION_REWARD_STATUS_PENDING);
|
||||
}
|
||||
/**
|
||||
* 已退回
|
||||
*/
|
||||
public function scopeBack($query)
|
||||
{
|
||||
return $query->where('status', self::COMMISSION_REWARD_STATUS_BACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* 已入账
|
||||
*/
|
||||
public function scopeAccounted($query)
|
||||
{
|
||||
return $query->where('status', self::COMMISSION_REWARD_STATUS_ACCOUNTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* 已取消
|
||||
*/
|
||||
public function scopeCancel($query)
|
||||
{
|
||||
return $query->where('status', self::COMMISSION_REWARD_STATUS_CANCEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 待入账和已入账
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function scopeIncome($query)
|
||||
{
|
||||
return $query->where('status', 'in', [self::COMMISSION_REWARD_STATUS_ACCOUNTED, self::COMMISSION_REWARD_STATUS_PENDING]);
|
||||
}
|
||||
|
||||
public function buyer()
|
||||
{
|
||||
return $this->belongsTo(UserModel::class, 'buyer_id', 'id')->field('id, nickname, avatar, mobile');
|
||||
}
|
||||
|
||||
public function agent()
|
||||
{
|
||||
return $this->belongsTo(UserModel::class, 'agent_id', 'id')->field('id, nickname, avatar, mobile');
|
||||
}
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(OrderModel::class, 'order_id', 'id');
|
||||
}
|
||||
|
||||
public function orderItem()
|
||||
{
|
||||
return $this->belongsTo(OrderItemModel::class, 'order_item_id', 'id');
|
||||
}
|
||||
}
|
||||
19
application/admin/model/shopro/data/Area.php
Normal file
19
application/admin/model/shopro/data/Area.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\data;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Area extends Common
|
||||
{
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
// 表名
|
||||
protected $name = 'shopro_data_area';
|
||||
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(self::class, 'pid', 'id');
|
||||
}
|
||||
}
|
||||
15
application/admin/model/shopro/data/Express.php
Normal file
15
application/admin/model/shopro/data/Express.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\data;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Express extends Common
|
||||
{
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
// 表名
|
||||
protected $name = 'shopro_data_express';
|
||||
|
||||
|
||||
}
|
||||
54
application/admin/model/shopro/data/FakeUser.php
Normal file
54
application/admin/model/shopro/data/FakeUser.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\data;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class FakeUser extends Common
|
||||
{
|
||||
|
||||
|
||||
// 表名
|
||||
protected $name = 'shopro_data_fake_user';
|
||||
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'gender_text'
|
||||
];
|
||||
|
||||
/**
|
||||
* 设置密码
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
public function setPasswordAttr($value)
|
||||
{
|
||||
$value = md5(md5($value) . mt_rand(1000, 9999));
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
public function getNicknameHideAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['nickname'] ?? '');
|
||||
return $value ? string_hide($value, 2) : $value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取性别文字
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return object
|
||||
*/
|
||||
public function getGenderTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['gender'] ?? 0);
|
||||
|
||||
$list = ['1' => __('Male'), '0' => __('Female')];
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
}
|
||||
20
application/admin/model/shopro/data/Faq.php
Normal file
20
application/admin/model/shopro/data/Faq.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\data;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Faq extends Common
|
||||
{
|
||||
|
||||
|
||||
// 表名
|
||||
protected $name = 'shopro_data_faq';
|
||||
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
}
|
||||
21
application/admin/model/shopro/data/Page.php
Normal file
21
application/admin/model/shopro/data/Page.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\data;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Page extends Common
|
||||
{
|
||||
|
||||
// 表名
|
||||
protected $name = 'shopro_data_page';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
];
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(self::class, 'group', 'group')->order('id asc');
|
||||
}
|
||||
}
|
||||
18
application/admin/model/shopro/data/Richtext.php
Normal file
18
application/admin/model/shopro/data/Richtext.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\data;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Richtext extends Common
|
||||
{
|
||||
|
||||
// 表名
|
||||
protected $name = 'shopro_data_richtext';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
15
application/admin/model/shopro/data/WechatExpress.php
Normal file
15
application/admin/model/shopro/data/WechatExpress.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\data;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class WechatExpress extends Common
|
||||
{
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
// 表名
|
||||
protected $name = 'shopro_data_wechat_express';
|
||||
|
||||
|
||||
}
|
||||
75
application/admin/model/shopro/decorate/Decorate.php
Normal file
75
application/admin/model/shopro/decorate/Decorate.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\decorate;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
|
||||
class Decorate extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $name = 'shopro_decorate';
|
||||
|
||||
protected $type = [
|
||||
];
|
||||
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'type_text'
|
||||
];
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'template' => '店铺模板',
|
||||
'diypage' => '自定义页面'
|
||||
];
|
||||
}
|
||||
|
||||
public function scopeTemplate($query)
|
||||
{
|
||||
return $query->where('type', 'template');
|
||||
}
|
||||
|
||||
|
||||
public function scopeTypeDiypage($query)
|
||||
{
|
||||
return $query->where('type', 'diypage');
|
||||
}
|
||||
|
||||
public function scopeDesigner($query)
|
||||
{
|
||||
return $query->where('type', 'designer');
|
||||
}
|
||||
|
||||
public function page()
|
||||
{
|
||||
return $this->hasMany(Page::class, 'decorate_id', 'id');
|
||||
}
|
||||
|
||||
public function diypage()
|
||||
{
|
||||
return $this->hasOne(Page::class, 'decorate_id', 'id')->where('type', 'diypage');
|
||||
}
|
||||
|
||||
public function getPlatformAttr($value, $data)
|
||||
{
|
||||
if($value) {
|
||||
return explode(',', $value);
|
||||
}else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public function setPlatformAttr($value, $data)
|
||||
{
|
||||
if($value) {
|
||||
return implode(',', $value);
|
||||
}else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
37
application/admin/model/shopro/decorate/Page.php
Normal file
37
application/admin/model/shopro/decorate/Page.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\decorate;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Page extends Common
|
||||
{
|
||||
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
protected $name = 'shopro_decorate_page';
|
||||
|
||||
protected $append = [
|
||||
// 'type_text'
|
||||
];
|
||||
|
||||
public function getPageAttr($value, $data)
|
||||
{
|
||||
// 图片默认存本地,使用接口域名
|
||||
// $value = str_replace("\"/storage/", "\"" . request()->domain() . "/storage/", $value);
|
||||
// $value = str_replace("\"\/storage\/", "\"" . request()->domain() . "/storage/", $value);
|
||||
|
||||
return json_decode($value, true);
|
||||
}
|
||||
|
||||
public static function buildData($template)
|
||||
{
|
||||
foreach ($template['home']['data'] as $data) {
|
||||
switch ($data['type']) {
|
||||
case 'goodsCard':
|
||||
break;
|
||||
}
|
||||
}
|
||||
// exit();
|
||||
}
|
||||
}
|
||||
31
application/admin/model/shopro/dispatch/Dispatch.php
Normal file
31
application/admin/model/shopro/dispatch/Dispatch.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\dispatch;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Dispatch extends Common
|
||||
{
|
||||
protected $name = 'shopro_dispatch';
|
||||
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
|
||||
public function scopeShow($query)
|
||||
{
|
||||
return $query->where('status', 'normal');
|
||||
}
|
||||
|
||||
public function express()
|
||||
{
|
||||
return $this->hasMany(DispatchExpress::class, 'dispatch_id')->order('weigh', 'desc')->order('id', 'asc');
|
||||
}
|
||||
|
||||
|
||||
public function autosend()
|
||||
{
|
||||
return $this->hasOne(DispatchAutosend::class, 'dispatch_id');
|
||||
}
|
||||
}
|
||||
35
application/admin/model/shopro/dispatch/DispatchAutosend.php
Normal file
35
application/admin/model/shopro/dispatch/DispatchAutosend.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\dispatch;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class DispatchAutosend extends Common
|
||||
{
|
||||
protected $name = 'shopro_dispatch_autosend';
|
||||
|
||||
protected $append = [
|
||||
];
|
||||
|
||||
|
||||
public function getContentAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['content'] ?? '');
|
||||
$type = $data['type'] ?? 'text';
|
||||
if ($type === 'params') {
|
||||
$value = json_decode($value, true);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
public function setContentAttr($value, $data)
|
||||
{
|
||||
$type = $data['type'] ?? 'text';
|
||||
if ($type == 'params') {
|
||||
$value = json_encode($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
28
application/admin/model/shopro/dispatch/DispatchExpress.php
Normal file
28
application/admin/model/shopro/dispatch/DispatchExpress.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\dispatch;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\data\Area;
|
||||
|
||||
class DispatchExpress extends Common
|
||||
{
|
||||
protected $name = 'shopro_dispatch_express';
|
||||
|
||||
protected $append = [
|
||||
'district_text'
|
||||
];
|
||||
|
||||
|
||||
public function getDistrictTextAttr($value, $data)
|
||||
{
|
||||
$province_ids = $data['province_ids'] ? explode(',', $data['province_ids']) : [];
|
||||
$city_ids = $data['city_ids'] ? explode(',', $data['city_ids']) : [];
|
||||
$district_ids = $data['district_ids'] ? explode(',', $data['district_ids']) : [];
|
||||
$ids = array_merge($province_ids, $city_ids, $district_ids);
|
||||
$districtText = Area::where('id', 'in', $ids)->field('name')->select();
|
||||
$districtText = collection($districtText)->column('name');
|
||||
return implode(',', $districtText);
|
||||
}
|
||||
|
||||
}
|
||||
94
application/admin/model/shopro/goods/Comment.php
Normal file
94
application/admin/model/shopro/goods/Comment.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\goods;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
|
||||
class Comment extends Common
|
||||
{
|
||||
|
||||
use SoftDelete;
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
// 表名
|
||||
protected $name = 'shopro_goods_comment';
|
||||
|
||||
protected $type = [
|
||||
'images' => 'json',
|
||||
'reply_time' => 'timestamp',
|
||||
];
|
||||
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'user_type'
|
||||
];
|
||||
|
||||
public static $typeAll = [
|
||||
'all' => ['code' => 'all', 'name' => '全部'],
|
||||
'images' => ['code' => 'images', 'name' => '有图'],
|
||||
'good' => ['code' => 'good', 'name' => '好评'],
|
||||
'moderate' => ['code' => 'moderate', 'name' => '中评'],
|
||||
'bad' => ['code' => 'bad', 'name' => '差评'],
|
||||
];
|
||||
|
||||
public function scopeImages($query)
|
||||
{
|
||||
return $query->whereNotNull('images')->where('images', '<>', '')->where('images', '<>', '[]');
|
||||
}
|
||||
|
||||
public function scopeGood($query)
|
||||
{
|
||||
return $query->where('level', 'in', [5, 4]);
|
||||
}
|
||||
|
||||
public function scopeModerate($query)
|
||||
{
|
||||
return $query->where('level', 'in', [3, 2]);
|
||||
}
|
||||
|
||||
public function scopeBad($query)
|
||||
{
|
||||
return $query->where('level', 1);
|
||||
}
|
||||
|
||||
public function scopeNoReply($query)
|
||||
{
|
||||
return $query->whereNull('reply_time');
|
||||
}
|
||||
|
||||
|
||||
public function getUserNicknameAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['user_nickname'] ?? '');
|
||||
|
||||
return $value ? string_hide($value, 2) : $value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function admin()
|
||||
{
|
||||
return $this->belongsTo(\app\admin\model\Admin::class, 'admin_id', 'id')->field('id,username,nickname,avatar');
|
||||
}
|
||||
|
||||
public function goods()
|
||||
{
|
||||
return $this->belongsTo(\app\admin\model\shopro\goods\Goods::class, 'goods_id', 'id');
|
||||
}
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(\app\admin\model\shopro\order\Order::class, 'order_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function orderItem()
|
||||
{
|
||||
return $this->belongsTo(\app\admin\model\shopro\order\OrderItem::class, 'order_item_id', 'id');
|
||||
}
|
||||
}
|
||||
535
application/admin/model/shopro/goods/Goods.php
Normal file
535
application/admin/model/shopro/goods/Goods.php
Normal file
@@ -0,0 +1,535 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\goods;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
use addons\shopro\library\Tree;
|
||||
use app\admin\model\shopro\Category;
|
||||
use app\admin\model\shopro\activity\Activity as ActivityModel;
|
||||
use app\admin\model\shopro\activity\SkuPrice as ActivitySkuPriceModel;
|
||||
use app\admin\model\shopro\app\ScoreSkuPrice;
|
||||
use app\admin\model\shopro\user\GoodsLog;
|
||||
use app\admin\model\shopro\order\Order;
|
||||
use app\admin\model\shopro\order\OrderItem;
|
||||
use addons\shopro\facade\Activity as ActivityFacade;
|
||||
|
||||
|
||||
class Goods extends Common
|
||||
{
|
||||
|
||||
use SoftDelete;
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
// 表名
|
||||
protected $name = 'shopro_goods';
|
||||
|
||||
protected $type = [
|
||||
'images' => 'json',
|
||||
'image_wh' => 'json',
|
||||
'params' => 'json',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'type_text',
|
||||
'dispatch_type_text'
|
||||
];
|
||||
|
||||
|
||||
protected $hidden = [
|
||||
'content',
|
||||
'max_sku_price',
|
||||
'score_sku_prices',
|
||||
'activity_sku_prices',
|
||||
'total_sales' // 商品列表,销量排序会用到
|
||||
];
|
||||
|
||||
/**
|
||||
* type 中文
|
||||
*/
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'normal' => '实体商品',
|
||||
'virtual' => '虚拟商品',
|
||||
'card' => '电子卡密',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* status 中文
|
||||
*/
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'up' => '上架中',
|
||||
'down' => '已下架',
|
||||
'hidden' => '已隐藏',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* status 中文
|
||||
*/
|
||||
public function dispatchTypeList()
|
||||
{
|
||||
return [
|
||||
'express' => '快递物流',
|
||||
'autosend' => '自动发货',
|
||||
'custom' => '商家发货'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改器 service_ids
|
||||
*
|
||||
* @param array|string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function setServiceIdsAttr($value, $data)
|
||||
{
|
||||
$service_ids = is_array($value) ? join(',', $value) : $value;
|
||||
return $service_ids;
|
||||
}
|
||||
|
||||
|
||||
public function setIsOfflineAttr($value, $data)
|
||||
{
|
||||
// 除了实体商品,其他都是 0
|
||||
return $data['type'] == 'normal' ? $value : 0;
|
||||
}
|
||||
|
||||
|
||||
public function scopeShow($query)
|
||||
{
|
||||
return $query->whereIn('status', ['up', 'hidden']);
|
||||
}
|
||||
|
||||
|
||||
public function getDispatchTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['dispatch_type'] ?? null);
|
||||
|
||||
$list = $this->dispatchTypeList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
public function getPriceAttr($value, $data)
|
||||
{
|
||||
// 前端传入的 session_id
|
||||
$activity_id = session('goods-activity_id:' . $data['id']);
|
||||
if ($activity_id && $this->activity) {
|
||||
// 活动商品的价格
|
||||
$skuPrices = $data['new_sku_prices'] ?? [];
|
||||
$prices = $skuPrices instanceof \think\Collection ? $skuPrices->column('min_price') : array_column($skuPrices, 'min_price');
|
||||
$maxPrices = $skuPrices instanceof \think\Collection ? $skuPrices->column('max_price') : array_column($skuPrices, 'max_price');
|
||||
$min_price = $prices ? min($prices) : $data['price'];
|
||||
$max_price = $maxPrices ? max($maxPrices) : $data['price'];
|
||||
$priceArr[] = $min_price;
|
||||
if ($min_price < $max_price) {
|
||||
$priceArr[] = $max_price;
|
||||
}
|
||||
} else if (isset($data['show_score_shop'])) {
|
||||
// 积分商品价格
|
||||
$skuPrices = $data['new_sku_prices'] ?? [];
|
||||
$skuPrices = $skuPrices instanceof \think\Collection ? $skuPrices->column(null, 'score') : array_column($skuPrices, null, 'score');
|
||||
ksort($skuPrices);
|
||||
$skuPrice = current($skuPrices); // 需要积分最少的规格
|
||||
if ($skuPrice) {
|
||||
// 不自动拼接积分
|
||||
// $price = $skuPrice['score'] . '积分';
|
||||
// if ($skuPrice['price'] > 0) {
|
||||
// $price .= '+¥' . $skuPrice['price'];
|
||||
// }
|
||||
// $priceArr[] = $price;
|
||||
$priceArr[] = $skuPrice['price'];
|
||||
} else {
|
||||
// 防止没有规格
|
||||
$priceArr[] = $data['price'];
|
||||
}
|
||||
} else {
|
||||
// 普通商品的价格区间
|
||||
$price = $value ? $value : ($data['price'] ?? 0);
|
||||
$priceArr = [$price];
|
||||
if ($price && isset($data['is_sku']) && $data['is_sku']) {
|
||||
$max_price = $this->max_sku_price->price;
|
||||
if ($price < $max_price) {
|
||||
$priceArr[] = $max_price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $priceArr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 这个目前只有拼团单独购买要使用
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getOriginalGoodsPriceAttr($value, $data)
|
||||
{
|
||||
$activity_id = session('goods-activity_id:' . $data['id']);
|
||||
$priceArr = [];
|
||||
if ($activity_id && $this->activity) {
|
||||
// 活动商品的价格
|
||||
$skuPrices = $data['new_sku_prices'] ?? [];
|
||||
$prices = $skuPrices instanceof \think\Collection ? $skuPrices->column('old_price') : array_column($skuPrices, 'old_price');
|
||||
$min_price = $prices ? min($prices) : $data['price'];
|
||||
$max_price = $prices ? max($prices) : $data['price'];
|
||||
$priceArr[] = $min_price;
|
||||
if ($min_price < $max_price) {
|
||||
$priceArr[] = $max_price;
|
||||
}
|
||||
}
|
||||
|
||||
return $priceArr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 前端积分商城列表,获取默认所需积分(价格不自动拼接积分了,所以这里单独设置一个属性)
|
||||
*/
|
||||
public function getScoreAttr($value, $data)
|
||||
{
|
||||
// 积分商品价格
|
||||
$skuPrices = $data['new_sku_prices'] ?? [];
|
||||
$skuPrices = $skuPrices instanceof \think\Collection ? $skuPrices->column(null, 'score') : array_column($skuPrices, null, 'score');
|
||||
ksort($skuPrices);
|
||||
$skuPrice = current($skuPrices); // 需要积分最少的规格
|
||||
if ($skuPrice) {
|
||||
$scoreAmount = $skuPrice['score'] ?? 0;
|
||||
} else {
|
||||
// 防止没有规格
|
||||
$scoreAmount = 0;
|
||||
}
|
||||
|
||||
return $scoreAmount;
|
||||
}
|
||||
|
||||
|
||||
public function getSalesAttr($value, $data)
|
||||
{
|
||||
// 前端传入的 session_id
|
||||
$activity_id = session('goods-activity_id:' . $data['id']);
|
||||
$sales = $data['sales'] ?? 0;
|
||||
$sales += ($data['show_sales'] ?? 0);
|
||||
if ($activity_id && $this->activity) {
|
||||
if ($this->activity['rules'] && isset($this->activity['rules']['sales_show_type']) && $this->activity['rules']['sales_show_type'] == 'real') {
|
||||
// 活动设置显示真实销量
|
||||
$skuPrices = $data['new_sku_prices'] ?? [];
|
||||
$sales = array_sum($skuPrices instanceof \think\Collection ? $skuPrices->column('sales') : array_column($skuPrices, 'sales'));
|
||||
}
|
||||
} else if (isset($data['show_score_shop'])) {
|
||||
// 积分商城显示真实销量
|
||||
$skuPrices = $data['new_sku_prices'] ?? [];
|
||||
$sales = array_sum($skuPrices instanceof \think\Collection ? $skuPrices->column('sales') : array_column($skuPrices, 'sales'));
|
||||
}
|
||||
|
||||
return $sales;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 真实销量
|
||||
*/
|
||||
public function getRealSalesAttr($value, $data)
|
||||
{
|
||||
$sales = $data['sales'] ?? 0;
|
||||
return $sales;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 相关商品(包含活动)购买用户,只查三个
|
||||
*
|
||||
* @param [type] $value
|
||||
* @param [type] $data
|
||||
* @return void
|
||||
*/
|
||||
public function getBuyersAttr($value, $data)
|
||||
{
|
||||
// 查询活动正在购买的人Goods
|
||||
$activity_id = session('goods-activity_id:' . $data['id']);
|
||||
$orderItems = OrderItem::with(['user' => function ($query) {
|
||||
return $query->field('id,nickname,avatar');
|
||||
}])->whereExists(function ($query) {
|
||||
$order_name = (new Order())->getQuery()->getTable();
|
||||
$order_item_name = (new OrderItem())->getQuery()->getTable();
|
||||
|
||||
$query->table($order_name)->where($order_item_name . '.order_id=' . $order_name . '.id')->whereIn('status', [Order::STATUS_PAID, Order::STATUS_COMPLETED, Order::STATUS_PENDING]);
|
||||
});
|
||||
|
||||
if ($activity_id) {
|
||||
$orderItems = $orderItems->where('activity_id', $activity_id);
|
||||
}
|
||||
|
||||
$orderItems = $orderItems->fieldRaw('max(id),user_id')->where('goods_id', $data['id'])->group('user_id')->limit(3)->select();
|
||||
|
||||
$user = [];
|
||||
foreach ($orderItems as $item) {
|
||||
if ($item['user']) {
|
||||
$user[] = $item['user'];
|
||||
}
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
public function getIsScoreShopAttr($value, $data)
|
||||
{
|
||||
$scoreGoodsIds = ScoreSkuPrice::group('goods_id')->cache(20)->column('goods_id');
|
||||
|
||||
return in_array($data['id'], $scoreGoodsIds) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前商品所属分类的所有上级
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getCategoryIdsArrAttr($value, $data)
|
||||
{
|
||||
$categoryIds = $data['category_ids'] ? explode(',', $data['category_ids']) : [];
|
||||
|
||||
$categoryIdsArr = [];
|
||||
$category = new Category();
|
||||
|
||||
foreach ($categoryIds as $key => $category_id) {
|
||||
$currentCategoryIds = (new Tree($category))->getParentFields($category_id);
|
||||
if ($currentCategoryIds) {
|
||||
$categoryIdsArr[] = $currentCategoryIds;
|
||||
}
|
||||
}
|
||||
|
||||
return $categoryIdsArr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取服务ids数组
|
||||
*
|
||||
* @param [type] $value
|
||||
* @param [type] $data
|
||||
* @return void
|
||||
*/
|
||||
public function getServiceIdsAttr($value, $data)
|
||||
{
|
||||
$serviceIds = $this->attrFormatComma($value, $data, 'service_ids', true);
|
||||
|
||||
return $serviceIds ? array_values(array_filter(array_map("intval", $serviceIds))) : $serviceIds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有服务列表
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getServiceAttr($value, $data)
|
||||
{
|
||||
$serviceIds = $this->attrFormatComma($value, $data, 'service_ids');
|
||||
|
||||
$serviceData = [];
|
||||
if ($serviceIds) {
|
||||
$serviceData = Service::whereIn('id', $serviceIds)->select();
|
||||
}
|
||||
return $serviceData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取规格列表
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getSkusAttr($value, $data)
|
||||
{
|
||||
$sku = Sku::with('children')->where('goods_id', $data['id'])->where('parent_id', 0)->select();
|
||||
return $sku;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取规格项列表
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getSkuPricesAttr($value, $data)
|
||||
{
|
||||
$skuPrices = collection(SkuPrice::where('goods_id', $data['id'])->cache(100 + mt_rand(0, 100))->select());
|
||||
return $skuPrices;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取器获取所有活动
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getActivitiesAttr($value, $data)
|
||||
{
|
||||
$activities = ActivityFacade::getGoodsActivitys($data['id']);
|
||||
|
||||
return $activities;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取器获取指定活动
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getActivityAttr($value, $data)
|
||||
{
|
||||
$activity_id = session('goods-activity_id:' . $data['id']);
|
||||
$activities = ActivityFacade::getGoodsActivityByActivity($data['id'], $activity_id);
|
||||
|
||||
return $activities;
|
||||
}
|
||||
|
||||
|
||||
public function getPromosAttr($value, $data)
|
||||
{
|
||||
$promos = ActivityFacade::getGoodsPromos($data['id']);
|
||||
|
||||
foreach ($promos as $key => $promo) {
|
||||
$rules = $promo['rules'];
|
||||
$rules['simple'] = true;
|
||||
$tags = ActivityFacade::formatRuleTags($rules, $promo['type']);
|
||||
|
||||
$promo['tag'] = $tags[0] ?? '';
|
||||
$promo['tags'] = $tags;
|
||||
|
||||
$texts = ActivityFacade::formatRuleTexts($rules, $promo['type']);
|
||||
$promo['texts'] = $texts;
|
||||
|
||||
$promos[$key] = $promo;
|
||||
}
|
||||
|
||||
return $promos ?? [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 积分商城价格,积分商城的属性
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getScorePriceAttr($value, $data)
|
||||
{
|
||||
$scoreSkuPrices = collection($this->score_sku_prices)->column(null, 'score');
|
||||
ksort($scoreSkuPrices);
|
||||
$scoreSkuPrice = current($scoreSkuPrices); // 需要积分最少的规格
|
||||
// print_r($scoreSkuPrices);exit;
|
||||
if ($scoreSkuPrice) {
|
||||
$price['score'] = $scoreSkuPrice['score'] ?? 0;
|
||||
$price['price'] = $scoreSkuPrice['price'] ?? 0;
|
||||
return $price;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
// return $score . '积分' . ($price > 0 ? '+¥' . $price : '');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 积分商城销量
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getScoreSalesAttr($value, $data)
|
||||
{
|
||||
$scoreSkuPrices = $this->score_sku_prices;
|
||||
|
||||
return array_sum(collection($scoreSkuPrices)->column('sales'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 积分商城库存
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getScoreStockAttr($value, $data)
|
||||
{
|
||||
$scoreSkuPrices = $this->score_sku_prices;
|
||||
|
||||
return array_sum(collection($scoreSkuPrices)->column('stock'));
|
||||
}
|
||||
|
||||
|
||||
public function maxSkuPrice()
|
||||
{
|
||||
return $this->hasOne(SkuPrice::class, 'goods_id')->order('price', 'desc');
|
||||
}
|
||||
|
||||
public function favorite()
|
||||
{
|
||||
$user = auth_user();
|
||||
$user_id = empty($user) ? 0 : $user->id;
|
||||
return $this->hasOne(GoodsLog::class, 'goods_id', 'id')->where('user_id', $user_id)->favorite();
|
||||
}
|
||||
|
||||
public function activitySkuPrices()
|
||||
{
|
||||
return $this->hasMany(ActivitySkuPriceModel::class, 'goods_id');
|
||||
}
|
||||
|
||||
public function scoreSkuPrices()
|
||||
{
|
||||
return $this->hasMany(ScoreSkuPrice::class, 'goods_id')->up();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 包含下架的积分规格
|
||||
*/
|
||||
public function allScoreSkuPrices()
|
||||
{
|
||||
return $this->hasMany(ScoreSkuPrice::class, 'goods_id');
|
||||
}
|
||||
|
||||
public function delScoreSkuPrices()
|
||||
{
|
||||
return $this->hasMany(ScoreSkuPrice::class, 'goods_id')->removeOption('soft_delete')->whereNotNull('deletetime'); // 只查被删除的记录,这里使用 onlyTrashed 报错
|
||||
}
|
||||
|
||||
// -- commission code start --
|
||||
public function commissionGoods()
|
||||
{
|
||||
return $this->hasOne(\app\admin\model\shopro\commission\CommissionGoods::class, 'goods_id');
|
||||
}
|
||||
// -- commission code end --
|
||||
}
|
||||
13
application/admin/model/shopro/goods/Service.php
Normal file
13
application/admin/model/shopro/goods/Service.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\goods;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Service extends Common
|
||||
{
|
||||
protected $name = 'shopro_goods_service';
|
||||
|
||||
protected $append = [
|
||||
];
|
||||
}
|
||||
21
application/admin/model/shopro/goods/Sku.php
Normal file
21
application/admin/model/shopro/goods/Sku.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\goods;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Sku extends Common
|
||||
{
|
||||
protected $name = 'shopro_goods_sku';
|
||||
|
||||
// 自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
protected $append = [
|
||||
];
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(self::class, 'parent_id');
|
||||
}
|
||||
}
|
||||
38
application/admin/model/shopro/goods/SkuPrice.php
Normal file
38
application/admin/model/shopro/goods/SkuPrice.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\goods;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\activity\SkuPrice as ActivitySkuPriceModel;
|
||||
use app\admin\model\shopro\app\ScoreSkuPrice;
|
||||
|
||||
class SkuPrice extends Common
|
||||
{
|
||||
protected $name = 'shopro_goods_sku_price';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'goods_sku_text',
|
||||
'status_text'
|
||||
];
|
||||
|
||||
|
||||
public function getGoodsSkuTextAttr($value, $data)
|
||||
{
|
||||
$arr = $this->attrFormatComma($value, $data, 'goods_sku_text', true);
|
||||
return $arr ? array_values(array_filter($arr)) : $arr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function activitySkuPrice()
|
||||
{
|
||||
return $this->hasOne(ActivitySkuPriceModel::class, 'goods_sku_price_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function scoreSkuPrice()
|
||||
{
|
||||
return $this->hasOne(ScoreSkuPrice::class, 'goods_sku_price_id', 'id');
|
||||
}
|
||||
}
|
||||
33
application/admin/model/shopro/goods/StockLog.php
Normal file
33
application/admin/model/shopro/goods/StockLog.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\goods;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\Admin;
|
||||
|
||||
class StockLog extends Common
|
||||
{
|
||||
protected $name = 'shopro_goods_stock_log';
|
||||
|
||||
protected $append = [
|
||||
];
|
||||
|
||||
|
||||
public function goods()
|
||||
{
|
||||
return $this->belongsTo(Goods::class, 'goods_id', 'id')->field('id,title,image,is_sku');
|
||||
}
|
||||
|
||||
|
||||
public function skuPrice()
|
||||
{
|
||||
return $this->belongsTo(SkuPrice::class, 'goods_sku_price_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function oper()
|
||||
{
|
||||
return $this->belongsTo(Admin::class, 'admin_id', 'id');
|
||||
}
|
||||
|
||||
}
|
||||
34
application/admin/model/shopro/goods/StockWarning.php
Normal file
34
application/admin/model/shopro/goods/StockWarning.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\goods;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
|
||||
class StockWarning extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $name = 'shopro_goods_stock_warning';
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $type = [
|
||||
];
|
||||
|
||||
protected $append = [
|
||||
];
|
||||
|
||||
|
||||
public function goods()
|
||||
{
|
||||
return $this->belongsTo(Goods::class, 'goods_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function skuPrice()
|
||||
{
|
||||
return $this->belongsTo(SkuPrice::class, 'goods_sku_price_id', 'id');
|
||||
}
|
||||
|
||||
}
|
||||
20
application/admin/model/shopro/notification/Config.php
Normal file
20
application/admin/model/shopro/notification/Config.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\notification;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Config extends Common
|
||||
{
|
||||
|
||||
protected $name = 'shopro_notification_config';
|
||||
|
||||
protected $type = [
|
||||
'content' => 'json',
|
||||
];
|
||||
|
||||
|
||||
protected $append = [
|
||||
'status_text',
|
||||
];
|
||||
}
|
||||
66
application/admin/model/shopro/notification/Notification.php
Normal file
66
application/admin/model/shopro/notification/Notification.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\notification;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use think\Collection;
|
||||
|
||||
class Notification extends Common
|
||||
{
|
||||
|
||||
protected $pk = 'id';
|
||||
|
||||
protected $name = 'shopro_notification';
|
||||
|
||||
protected $type = [
|
||||
'read_time' => 'timestamp',
|
||||
'data' => 'array',
|
||||
];
|
||||
|
||||
public static $notificationType = [
|
||||
'system' => '系统消息',
|
||||
'shop' => '商城消息',
|
||||
// 'site' => '网站消息'
|
||||
];
|
||||
|
||||
|
||||
public function scopeNotificationType($query, $type)
|
||||
{
|
||||
if ($type) {
|
||||
$query = $query->where('notification_type', $type);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据转换成可以显示成键值对的格式
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getDataAttr($value, $data)
|
||||
{
|
||||
$data = json_decode($data['data'], true);
|
||||
if (isset($data['message_type']) && $data['message_type'] == 'notification') {
|
||||
$messageData = $data['data'];
|
||||
$class = new $data['class_name']();
|
||||
$fields = $class->returnField['fields'] ?? [];
|
||||
$fields = array_column($fields, null, 'field');
|
||||
|
||||
$newData = [];
|
||||
foreach ($messageData as $k => $d) {
|
||||
$da = $fields[$k] ?? [];
|
||||
if ($da) {
|
||||
$da['value'] = $d;
|
||||
$newData[] = $da;
|
||||
}
|
||||
}
|
||||
|
||||
$data['data'] = $newData;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
40
application/admin/model/shopro/order/Action.php
Normal file
40
application/admin/model/shopro/order/Action.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\Admin;
|
||||
use app\admin\model\shopro\user\User;
|
||||
|
||||
class Action extends Common
|
||||
{
|
||||
protected $name = 'shopro_order_action';
|
||||
|
||||
protected $type = [
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'oper'
|
||||
];
|
||||
|
||||
|
||||
public static function add($order, $item = null, $oper = null, $type = 'user', $remark = '')
|
||||
{
|
||||
$oper_id = $oper ? $oper['id'] : 0;
|
||||
$self = new self();
|
||||
$self->order_id = $order->id;
|
||||
$self->order_item_id = is_null($item) ? 0 : $item->id;
|
||||
$self->oper_type = $type;
|
||||
$self->oper_id = $oper_id;
|
||||
$self->order_status = $order->status;
|
||||
$self->dispatch_status = is_null($item) ? 0 : $item->dispatch_status;
|
||||
$self->comment_status = is_null($item) ? 0 : $item->comment_status;
|
||||
$self->aftersale_status = is_null($item) ? 0 : $item->aftersale_status;
|
||||
$self->refund_status = is_null($item) ? 0 : $item->refund_status;
|
||||
$self->remark = $remark;
|
||||
$self->save();
|
||||
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
19
application/admin/model/shopro/order/Address.php
Normal file
19
application/admin/model/shopro/order/Address.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Address extends Common
|
||||
{
|
||||
protected $name = 'shopro_order_address';
|
||||
|
||||
protected $type = [
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
286
application/admin/model/shopro/order/Aftersale.php
Normal file
286
application/admin/model/shopro/order/Aftersale.php
Normal file
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order;
|
||||
|
||||
use traits\model\SoftDelete;
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User;
|
||||
|
||||
class Aftersale extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $name = 'shopro_order_aftersale';
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text',
|
||||
'btns',
|
||||
'dispatch_status_text',
|
||||
'aftersale_status_text',
|
||||
'aftersale_status_desc',
|
||||
'refund_status_text'
|
||||
];
|
||||
|
||||
|
||||
// 发货状态
|
||||
const DISPATCH_STATUS_REFUSE = -1; // 拒收
|
||||
const DISPATCH_STATUS_NOSEND = 0; // 未发货
|
||||
const DISPATCH_STATUS_SENDED = 1; // 已发货
|
||||
const DISPATCH_STATUS_GETED = 2; // 已收货
|
||||
|
||||
|
||||
// 售后状态
|
||||
const AFTERSALE_STATUS_CANCEL = -2; // 已取消
|
||||
const AFTERSALE_STATUS_REFUSE = -1; // 拒绝
|
||||
const AFTERSALE_STATUS_NOOPER = 0; // 未处理
|
||||
const AFTERSALE_STATUS_ING = 1; // 申请售后
|
||||
const AFTERSALE_STATUS_COMPLETED = 2; // 售后完成
|
||||
|
||||
|
||||
// 退款状态
|
||||
const REFUND_STATUS_NOREFUND = 0; // 未退款
|
||||
const REFUND_STATUS_AGREE = 1; // 已同意
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'refund' => '仅退款',
|
||||
'return' => '退货退款',
|
||||
'other' => '其他'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function dispatchStatusList()
|
||||
{
|
||||
return [
|
||||
self::DISPATCH_STATUS_REFUSE => '已拒收',
|
||||
self::DISPATCH_STATUS_NOSEND => '未发货',
|
||||
self::DISPATCH_STATUS_SENDED => '已发货',
|
||||
self::DISPATCH_STATUS_GETED => '已收货'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function aftersaleStatusList()
|
||||
{
|
||||
return [
|
||||
self::AFTERSALE_STATUS_CANCEL => '已取消',
|
||||
self::AFTERSALE_STATUS_REFUSE => '拒绝',
|
||||
self::AFTERSALE_STATUS_NOOPER => '未处理',
|
||||
self::AFTERSALE_STATUS_ING => '申请售后',
|
||||
self::AFTERSALE_STATUS_COMPLETED => '售后完成'
|
||||
];
|
||||
}
|
||||
|
||||
public function aftersaleStatusDescList()
|
||||
{
|
||||
return [
|
||||
self::AFTERSALE_STATUS_CANCEL => '买家取消了售后申请',
|
||||
self::AFTERSALE_STATUS_REFUSE => '卖家拒绝了售后申请',
|
||||
self::AFTERSALE_STATUS_NOOPER => '买家申请了售后,请及时处理',
|
||||
self::AFTERSALE_STATUS_ING => '售后正在处理中',
|
||||
self::AFTERSALE_STATUS_COMPLETED => '售后已完成'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function refundStatusList()
|
||||
{
|
||||
return [
|
||||
self::REFUND_STATUS_NOREFUND => '未退款',
|
||||
self::REFUND_STATUS_AGREE => '同意退款',
|
||||
];
|
||||
}
|
||||
|
||||
// 已取消
|
||||
public function scopeCancel($query)
|
||||
{
|
||||
return $query->where('aftersale_status', self::AFTERSALE_STATUS_CANCEL);
|
||||
}
|
||||
|
||||
// 已拒绝
|
||||
public function scopeRefuse($query)
|
||||
{
|
||||
return $query->where('aftersale_status', self::AFTERSALE_STATUS_REFUSE);
|
||||
}
|
||||
|
||||
public function scopeNoOper($query)
|
||||
{
|
||||
return $query->where('aftersale_status', self::AFTERSALE_STATUS_NOOPER);
|
||||
}
|
||||
|
||||
// 处理中
|
||||
public function scopeIng($query)
|
||||
{
|
||||
return $query->where('aftersale_status', self::AFTERSALE_STATUS_ING);
|
||||
}
|
||||
|
||||
|
||||
// 处理完成
|
||||
public function scopeCompleted($query)
|
||||
{
|
||||
return $query->where('aftersale_status', self::AFTERSALE_STATUS_COMPLETED);
|
||||
}
|
||||
|
||||
// 需要处理的,包含未处理,和处理中的,个人中心显示售后数量
|
||||
public function scopeNeedOper($query)
|
||||
{
|
||||
return $query->whereIn('aftersale_status', [self::AFTERSALE_STATUS_NOOPER, self::AFTERSALE_STATUS_ING]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台售后列表,主表是 order 表时不用用 scope 了
|
||||
*
|
||||
* @param [type] $scope
|
||||
* @return void
|
||||
*/
|
||||
public static function getScopeWhere($scope)
|
||||
{
|
||||
$where = [];
|
||||
switch ($scope) {
|
||||
case 'cancel':
|
||||
$where['aftersale_status'] = self::AFTERSALE_STATUS_CANCEL;
|
||||
break;
|
||||
case 'refuse':
|
||||
$where['aftersale_status'] = self::AFTERSALE_STATUS_REFUSE;
|
||||
break;
|
||||
case 'nooper':
|
||||
$where['aftersale_status'] = self::AFTERSALE_STATUS_NOOPER;
|
||||
break;
|
||||
case 'ing':
|
||||
$where['aftersale_status'] = self::AFTERSALE_STATUS_ING;
|
||||
break;
|
||||
case 'completed':
|
||||
$where['aftersale_status'] = self::AFTERSALE_STATUS_COMPLETED;
|
||||
break;
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
// 可以取消
|
||||
public function scopeCanCancel($query)
|
||||
{
|
||||
// 未处理,处理中,可以取消
|
||||
return $query->where('aftersale_status', 'in', [
|
||||
self::AFTERSALE_STATUS_NOOPER,
|
||||
self::AFTERSALE_STATUS_ING
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
// 可以操作
|
||||
public function scopeCanOper($query)
|
||||
{
|
||||
// 未处理,处理中,可以 操作退款,拒绝,完成
|
||||
return $query->where('aftersale_status', 'in', [
|
||||
self::AFTERSALE_STATUS_NOOPER,
|
||||
self::AFTERSALE_STATUS_ING
|
||||
]);
|
||||
}
|
||||
|
||||
// 可以删除
|
||||
public function scopeCanDelete($query)
|
||||
{
|
||||
// 取消,拒绝,完成可以删除
|
||||
return $query->where('aftersale_status', 'in', [
|
||||
self::AFTERSALE_STATUS_CANCEL,
|
||||
self::AFTERSALE_STATUS_REFUSE,
|
||||
self::AFTERSALE_STATUS_COMPLETED
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function getDispatchStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['dispatch_status'] ?? null);
|
||||
|
||||
$list = $this->dispatchStatusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
public function getBtnsAttr($value, $data)
|
||||
{
|
||||
$btns = [];
|
||||
switch ($data['aftersale_status']) {
|
||||
case self::AFTERSALE_STATUS_NOOPER:
|
||||
case self::AFTERSALE_STATUS_ING:
|
||||
$btns[] = 'cancel';
|
||||
break;
|
||||
case self::AFTERSALE_STATUS_CANCEL:
|
||||
case self::AFTERSALE_STATUS_REFUSE:
|
||||
case self::AFTERSALE_STATUS_COMPLETED:
|
||||
$btns[] = 'delete';
|
||||
break;
|
||||
}
|
||||
|
||||
return $btns;
|
||||
}
|
||||
|
||||
|
||||
public function getAftersaleStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['aftersale_status'] ?? null);
|
||||
|
||||
$list = $this->aftersaleStatusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
public function getAftersaleStatusDescAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['aftersale_status'] ?? null);
|
||||
|
||||
$list = $this->aftersaleStatusDescList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function getRefundStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['refund_status'] ?? null);
|
||||
|
||||
$list = $this->refundStatusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取建议退款金额,不考虑剩余可退款金额是否够退
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getSuggestRefundFeeAttr($value, $data)
|
||||
{
|
||||
$current_goods_amount = bcmul($data['goods_price'], (string)$data['goods_num'], 2);
|
||||
$total_amount = bcadd($current_goods_amount, $data['dispatch_fee'], 2);
|
||||
$suggest_refund_fee = bcsub($total_amount, $data['discount_fee'], 2); // (商品金额 + 运费金额) - 总优惠(活动,优惠券,包邮优惠)
|
||||
|
||||
return $suggest_refund_fee;
|
||||
}
|
||||
|
||||
public function logs()
|
||||
{
|
||||
return $this->hasMany(AftersaleLog::class, 'order_aftersale_id', 'id')->order('id', 'desc');
|
||||
}
|
||||
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'order_id');
|
||||
}
|
||||
}
|
||||
78
application/admin/model/shopro/order/AftersaleLog.php
Normal file
78
application/admin/model/shopro/order/AftersaleLog.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\Admin;
|
||||
use app\admin\model\shopro\user\User;
|
||||
|
||||
class AftersaleLog extends Common
|
||||
{
|
||||
protected $name = 'shopro_order_aftersale_log';
|
||||
|
||||
protected $type = [
|
||||
'images' => 'json',
|
||||
];
|
||||
|
||||
protected $append = [
|
||||
'log_type_text'
|
||||
];
|
||||
|
||||
public function logTypeList()
|
||||
{
|
||||
return [
|
||||
'apply_aftersale' => '售后服务单申请成功,等待售后处理',
|
||||
'cancel' => '用户取消申请售后',
|
||||
'delete' => '用户删除售后单',
|
||||
'completed' => '售后订单已完成',
|
||||
'refuse' => '卖家拒绝售后',
|
||||
'refund' => '卖家同意退款',
|
||||
'add_log' => '卖家留言'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static function add($order = null, $aftersale = null, $oper = null, $type = 'user', $data = [])
|
||||
{
|
||||
$oper_id = $oper ? $oper['id'] : 0;
|
||||
$images = $data['images'] ?? [];
|
||||
|
||||
$self = new self();
|
||||
$self->order_id = $order ? $order->id : ($aftersale ? $aftersale->id : 0);
|
||||
$self->order_aftersale_id = $aftersale ? $aftersale->id : 0;
|
||||
$self->oper_type = $type;
|
||||
$self->oper_id = $oper_id;
|
||||
$self->dispatch_status = $aftersale ? $aftersale->dispatch_status : 0;
|
||||
$self->aftersale_status = $aftersale ? $aftersale->aftersale_status : 0;
|
||||
$self->refund_status = $aftersale ? $aftersale->refund_status : 0;
|
||||
$self->log_type = $data['log_type'];
|
||||
$self->content = $data['content'] ?? '';
|
||||
$self->images = $images;
|
||||
$self->save();
|
||||
|
||||
// 售后单变动行为
|
||||
$data = ['aftersale' => $aftersale, 'order' => $order, 'aftersaleLog' => $self];
|
||||
\think\Hook::listen('order_aftersale_change', $data);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* log 类型获取器
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getLogTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['log_type'] ?? null);
|
||||
|
||||
$list = $this->logTypeList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
}
|
||||
49
application/admin/model/shopro/order/Express.php
Normal file
49
application/admin/model/shopro/order/Express.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Express extends Common
|
||||
{
|
||||
protected $name = 'shopro_order_express';
|
||||
|
||||
protected $type = [
|
||||
'ext' => 'json'
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'noinfo' => '暂无信息',
|
||||
'collect' => '已揽件',
|
||||
'transport' => '运输中',
|
||||
'delivery' => '派送中',
|
||||
'signfor' => '已签收',
|
||||
'refuse' => '用户拒收',
|
||||
'difficulty' => '问题件',
|
||||
'invalid' => '无效件',
|
||||
'timeout' => '超时单',
|
||||
'fail' => '签收失败',
|
||||
'back' => '退回',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany(OrderItem::class, 'order_express_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function logs()
|
||||
{
|
||||
return $this->hasMany(ExpressLog::class, 'order_express_id', 'id')->order('id', 'desc');
|
||||
}
|
||||
}
|
||||
37
application/admin/model/shopro/order/ExpressLog.php
Normal file
37
application/admin/model/shopro/order/ExpressLog.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class ExpressLog extends Common
|
||||
{
|
||||
protected $name = 'shopro_order_express_log';
|
||||
|
||||
protected $type = [
|
||||
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'noinfo' => '',
|
||||
'collect' => '已揽件',
|
||||
'transport' => '运输中',
|
||||
'delivery' => '派送中',
|
||||
'signfor' => '已签收',
|
||||
'refuse' => '用户拒收',
|
||||
'difficulty' => '问题件',
|
||||
'invalid' => '无效件',
|
||||
'timeout' => '超时单',
|
||||
'fail' => '签收失败',
|
||||
'back' => '退回',
|
||||
];
|
||||
}
|
||||
}
|
||||
184
application/admin/model/shopro/order/Invoice.php
Normal file
184
application/admin/model/shopro/order/Invoice.php
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\user\User;
|
||||
use app\admin\model\shopro\user\Invoice as UserInvoiceModel;
|
||||
|
||||
class Invoice extends Common
|
||||
{
|
||||
protected $name = 'shopro_order_invoice';
|
||||
|
||||
protected $type = [
|
||||
'download_urls' => 'array',
|
||||
'finish_time' => 'timestamp'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'order_items'
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text',
|
||||
'status_text'
|
||||
];
|
||||
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return (new UserInvoiceModel)->typeList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'cancel' => '已取消',
|
||||
'unpaid' => '未支付',
|
||||
'waiting' => '等待开票',
|
||||
'finish' => '已开具',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function getOrderStatusAttr($value, $data)
|
||||
{
|
||||
$order = $this->order;
|
||||
$order_status = 'normal';
|
||||
|
||||
if (!$order) {
|
||||
$order_status = 'order_deleted';
|
||||
} else if (in_array($order->status, [Order::STATUS_PAID, Order::STATUS_COMPLETED])) {
|
||||
$items = $this->order_items;
|
||||
$refund_num = 0;
|
||||
$aftersale_num = 0;
|
||||
foreach ($items as $item) {
|
||||
if (in_array($item->refund_status, [
|
||||
OrderItem::REFUND_STATUS_AGREE,
|
||||
OrderItem::REFUND_STATUS_COMPLETED
|
||||
])) {
|
||||
$refund_num += 1;
|
||||
}
|
||||
|
||||
if (in_array($item->aftersale_status, [
|
||||
OrderItem::AFTERSALE_STATUS_REFUSE,
|
||||
OrderItem::AFTERSALE_STATUS_ING,
|
||||
OrderItem::AFTERSALE_STATUS_COMPLETED
|
||||
])) {
|
||||
$aftersale_num += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($refund_num) {
|
||||
$order_status = 'refund';
|
||||
if ($refund_num == count($items)) {
|
||||
$order_status = 'refund_all';
|
||||
}
|
||||
} else if ($aftersale_num) {
|
||||
$order_status = 'aftersale';
|
||||
}
|
||||
} else if ($order->isOffline($order)) {
|
||||
$order_status = 'offline_unpaid';
|
||||
}
|
||||
|
||||
return $order_status;
|
||||
}
|
||||
|
||||
|
||||
public function getOrderStatusTextAttr($value, $data)
|
||||
{
|
||||
$order_status = $this->order_status;
|
||||
|
||||
switch($order_status) {
|
||||
case 'order_deleted':
|
||||
$order_status_text = '该订单已被删除';
|
||||
break;
|
||||
case 'refund_all':
|
||||
$order_status_text = '该订单已全部退款';
|
||||
break;
|
||||
case 'refund':
|
||||
$order_status_text = '该订单已部分退款';
|
||||
break;
|
||||
case 'aftersale':
|
||||
$order_status_text = '该订单已申请售后';
|
||||
break;
|
||||
case 'offline_unpaid':
|
||||
$order_status_text = '该订单货到付款-未付款';
|
||||
break;
|
||||
default :
|
||||
$order_status_text = '';
|
||||
}
|
||||
|
||||
return $order_status_text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getOrderFeeAttr($value, $data)
|
||||
{
|
||||
$order = $this->order;
|
||||
|
||||
if ($order && $order->pay_fee != $order->original_pay_fee) {
|
||||
return [
|
||||
'pay_fee' => $order->pay_fee,
|
||||
'original_pay_fee' => $order->original_pay_fee,
|
||||
];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function scopeCancel($query)
|
||||
{
|
||||
return $query->where('status', 'cancel');
|
||||
}
|
||||
|
||||
|
||||
public function scopeWaiting($query)
|
||||
{
|
||||
return $query->where('status', 'waiting');
|
||||
}
|
||||
|
||||
|
||||
public function scopeFinish($query)
|
||||
{
|
||||
return $query->where('status', 'finish');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 不展示 未支付的
|
||||
*/
|
||||
public function scopeShow($query)
|
||||
{
|
||||
return $query->whereIn('status', ['cancel', 'waiting', 'finish']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'order_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function orderItems()
|
||||
{
|
||||
return $this->hasMany(OrderItem::class, 'order_id', 'order_id');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
361
application/admin/model/shopro/order/Order.php
Normal file
361
application/admin/model/shopro/order/Order.php
Normal file
@@ -0,0 +1,361 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
use app\admin\model\shopro\user\User;
|
||||
use app\admin\model\shopro\Pay as PayModel;
|
||||
use app\admin\model\shopro\activity\Activity;
|
||||
use app\admin\model\shopro\order\traits\OrderScope;
|
||||
use app\admin\model\shopro\order\traits\OrderStatus;
|
||||
use app\admin\model\shopro\activity\Order as ActivityOrder;
|
||||
|
||||
class Order extends Common
|
||||
{
|
||||
use SoftDelete, OrderScope, OrderStatus;
|
||||
|
||||
protected $name = 'shopro_order';
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $type = [
|
||||
'ext' => 'json',
|
||||
'paid_time' => 'timestamp',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text',
|
||||
'status_code',
|
||||
'status_text',
|
||||
'status_desc',
|
||||
'apply_refund_status_text',
|
||||
'btns',
|
||||
'platform_text',
|
||||
'activity_type_text',
|
||||
'promo_types_text',
|
||||
'wechat_extra_data'
|
||||
];
|
||||
|
||||
|
||||
// 订单状态
|
||||
const STATUS_CLOSED = 'closed';
|
||||
const STATUS_CANCEL = 'cancel';
|
||||
const STATUS_UNPAID = 'unpaid';
|
||||
const STATUS_PAID = 'paid';
|
||||
const STATUS_COMPLETED = 'completed';
|
||||
const STATUS_PENDING = 'pending'; // 待定 后付款
|
||||
|
||||
|
||||
const APPLY_REFUND_STATUS_NOAPPLY = 0;
|
||||
const APPLY_REFUND_STATUS_APPLY = 1;
|
||||
const APPLY_REFUND_STATUS_FINISH = 2;
|
||||
const APPLY_REFUND_STATUS_REFUSE = -1;
|
||||
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'closed' => '交易关闭',
|
||||
'cancel' => '已取消',
|
||||
'unpaid' => '未支付',
|
||||
'pending' => '待定', // 货到付款未付款状态
|
||||
'paid' => '已支付',
|
||||
'completed' => '已完成'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function applyRefundStatusList()
|
||||
{
|
||||
return [
|
||||
self::APPLY_REFUND_STATUS_NOAPPLY => '未申请',
|
||||
self::APPLY_REFUND_STATUS_APPLY => '申请退款',
|
||||
self::APPLY_REFUND_STATUS_FINISH => '退款完成',
|
||||
self::APPLY_REFUND_STATUS_REFUSE => '拒绝申请'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 订单列表状态搜索
|
||||
*/
|
||||
public function searchStatusList()
|
||||
{
|
||||
return [
|
||||
'unpaid' => '待付款',
|
||||
'paid' => '已支付', // 包括刚支付的,发货中,和已退款的,以及已完成的所有付过款的订单,不包含货到付款还未真实付款的订单
|
||||
'nosend' => '待发货',
|
||||
'noget' => '待收货',
|
||||
'refuse' => '已拒收',
|
||||
'nocomment' => '待评价',
|
||||
'completed' => '已完成',
|
||||
'aftersale' => '售后',
|
||||
'applyRefundIng' => '申请退款',
|
||||
'refund' => '已退款',
|
||||
'cancel' => '已取消',
|
||||
'closed' => '交易关闭', // 包含货到付款,拒收的商品
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'goods' => '商城订单',
|
||||
'score' => '积分订单'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function platformList()
|
||||
{
|
||||
return [
|
||||
'H5' => 'H5',
|
||||
'WechatOfficialAccount' => '微信公众号',
|
||||
'WechatMiniProgram' => '微信小程序',
|
||||
'App' => 'App',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function getExtAttr($value, $data)
|
||||
{
|
||||
$ext = (isset($data['ext']) && $data['ext']) ? json_decode($data['ext'], true) : [];
|
||||
|
||||
// 每类活动优惠金额聚合(可能订单购买多个商品,然后同时参与了两种满减,金额累加)
|
||||
$ext['promo_discounts'] = [
|
||||
'full_reduce' => 0,
|
||||
'full_discount' => 0,
|
||||
'free_shipping' => 0,
|
||||
'full_gift' => 0
|
||||
];
|
||||
if ($ext && isset($ext['promo_infos']) && $ext['promo_infos']) {
|
||||
foreach ($ext['promo_infos'] as $key => $info) {
|
||||
if ($info['activity_type'] == 'full_gift') {
|
||||
$ext['promo_discounts']['full_gift'] = 1;
|
||||
continue;
|
||||
}
|
||||
$ext['promo_discounts'][$info['activity_type']] = bcadd((string)$ext['promo_discounts'][$info['activity_type']], (string)$info['promo_discount_money'], 2);
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化
|
||||
$ext['promo_discounts'] = array_map(function ($value) {
|
||||
return number_format(floatval($value), 2, '.', '');
|
||||
}, $ext['promo_discounts']);
|
||||
|
||||
// 处理时间
|
||||
if (isset($ext['closed_time']) && $ext['closed_time']) {
|
||||
$ext['closed_date'] = date('Y-m-d H:i:s', $ext['closed_time']);
|
||||
}
|
||||
if (isset($ext['cancel_time']) && $ext['cancel_time']) {
|
||||
$ext['cancel_date'] = date('Y-m-d H:i:s', $ext['cancel_time']);
|
||||
}
|
||||
if (isset($ext['pending_time']) && $ext['pending_time']) {
|
||||
$ext['pending_date'] = date('Y-m-d H:i:s', $ext['pending_time']);
|
||||
}
|
||||
if (isset($ext['apply_refund_time']) && $ext['apply_refund_time']) {
|
||||
$ext['apply_refund_date'] = date('Y-m-d H:i:s', $ext['apply_refund_time']);
|
||||
}
|
||||
if (isset($ext['send_time']) && $ext['send_time']) {
|
||||
$ext['send_date'] = date('Y-m-d H:i:s', $ext['send_time']);
|
||||
}
|
||||
if (isset($ext['confirm_time']) && $ext['confirm_time']) {
|
||||
$ext['confirm_date'] = date('Y-m-d H:i:s', $ext['confirm_time']);
|
||||
}
|
||||
if (isset($ext['comment_time']) && $ext['comment_time']) {
|
||||
$ext['comment_date'] = date('Y-m-d H:i:s', $ext['comment_time']);
|
||||
}
|
||||
if (isset($ext['completed_time']) && $ext['completed_time']) {
|
||||
$ext['completed_date'] = date('Y-m-d H:i:s', $ext['completed_time']);
|
||||
}
|
||||
if (isset($ext['refund_time']) && $ext['refund_time']) {
|
||||
$ext['refund_date'] = date('Y-m-d H:i:s', $ext['refund_time']);
|
||||
}
|
||||
return $ext;
|
||||
}
|
||||
|
||||
|
||||
public function getPlatformTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['platform'] ?? null);
|
||||
|
||||
$list = $this->platformList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 微信小程序发货信息管理所需参数
|
||||
*
|
||||
* @param string|null $value
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getWechatExtraDataAttr($value, $data)
|
||||
{
|
||||
$extraData = [];
|
||||
|
||||
if (strpos(request()->url(), 'addons/shopro') !== false && $data['platform'] == 'WechatMiniProgram') {
|
||||
// 前端接口,并且是 微信小程序订单,才返这个参数
|
||||
$pays = $this->pays;
|
||||
foreach ($pays as $pay) {
|
||||
if ($pay->status != PayModel::PAY_STATUS_UNPAID && $pay->pay_type == 'wechat') {
|
||||
$extraData['merchant_trade_no'] = $pay->pay_sn;
|
||||
$extraData['transaction_id'] = $pay->transaction_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $extraData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 申请退款状态
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getApplyRefundStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['apply_refund_status'] ?? null);
|
||||
|
||||
$list = $this->applyRefundStatusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
public function getActivityTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['activity_type'] ?? null);
|
||||
$ext = $this->ext;
|
||||
|
||||
$list = (new Activity)->typeList();
|
||||
$text = isset($list[$value]) ? $list[$value] : '';
|
||||
|
||||
if (in_array($value, ['groupon', 'groupon_ladder'])) {
|
||||
// 订单已支付的,或者线下支付(货到付款)的
|
||||
if ((in_array($data['status'], [self::STATUS_PAID, self::STATUS_COMPLETED]) || $this->isOffline($data))
|
||||
&& (!isset($ext['groupon_id']) || !$ext['groupon_id']))
|
||||
{
|
||||
// 已支付,并且没有团 id,就是单独购买
|
||||
$text .= '-单独购买';
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
public function getPromoTypesTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['promo_types'] ?? null);
|
||||
|
||||
$promoTypes = array_filter(explode(',', $value));
|
||||
$texts = [];
|
||||
$list = (new Activity)->typeList();
|
||||
foreach ($promoTypes as $type) {
|
||||
$text = isset($list[$type]) ? $list[$type] : '';
|
||||
if ($text) {
|
||||
$texts[] = $text;
|
||||
}
|
||||
}
|
||||
return $texts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 已支付订单,支付类型
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function getPayTypesAttr($value, $data)
|
||||
{
|
||||
$status = $data['status'] ?? '';
|
||||
$payTypes = [];
|
||||
// 订单已支付的,或者线下支付(货到付款)的
|
||||
if (in_array($status, [self::STATUS_PAID, self::STATUS_COMPLETED]) || $this->isOffline($data)) {
|
||||
$payTypes = PayModel::typeOrder()->where('order_id', $data['id'])->where('status', '<>', PayModel::PAY_STATUS_UNPAID)->group('pay_type')->column('pay_type');
|
||||
}
|
||||
|
||||
return $payTypes;
|
||||
}
|
||||
/**
|
||||
* 已支付订单,支付类型文字
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function getPayTypesTextAttr($value, $data)
|
||||
{
|
||||
$payTypes = $this->pay_types;
|
||||
$list = (new PayModel)->payTypeList();
|
||||
|
||||
$texts = [];
|
||||
foreach ($payTypes as $pay_type) {
|
||||
$text = isset($list[$pay_type]) ? $list[$pay_type] : '';
|
||||
|
||||
if ($text) {
|
||||
$texts[] = $text;
|
||||
}
|
||||
}
|
||||
|
||||
return $texts;
|
||||
}
|
||||
|
||||
|
||||
public function getExpressAttr($value, $data)
|
||||
{
|
||||
return Express::with(['items', 'logs'])->where('order_id', $data['id'])->select();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany(OrderItem::class, 'order_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id', 'id');
|
||||
}
|
||||
|
||||
public function aftersales()
|
||||
{
|
||||
return $this->hasMany(Aftersale::class, 'order_id')->order('id', 'desc');
|
||||
}
|
||||
|
||||
|
||||
public function address()
|
||||
{
|
||||
return $this->hasOne(Address::class, 'order_id', 'id');
|
||||
}
|
||||
|
||||
public function invoice()
|
||||
{
|
||||
return $this->hasOne(Invoice::class, 'order_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
public function pays()
|
||||
{
|
||||
return $this->hasMany(PayModel::class, 'order_id', 'id')->typeOrder()->order('id', 'desc');
|
||||
}
|
||||
|
||||
|
||||
public function activityOrders()
|
||||
{
|
||||
return $this->hasMany(ActivityOrder::class, 'order_id');
|
||||
}
|
||||
}
|
||||
227
application/admin/model/shopro/order/OrderItem.php
Normal file
227
application/admin/model/shopro/order/OrderItem.php
Normal file
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\order\traits\OrderItemStatus;
|
||||
use app\admin\model\shopro\activity\Activity;
|
||||
use app\admin\model\shopro\user\User;
|
||||
|
||||
class OrderItem extends Common
|
||||
{
|
||||
use OrderItemStatus;
|
||||
|
||||
protected $name = 'shopro_order_item';
|
||||
|
||||
protected $type = [
|
||||
'ext' => 'json'
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'dispatch_status_text',
|
||||
'dispatch_type_text',
|
||||
'aftersale_status_text',
|
||||
'refund_status_text',
|
||||
'comment_status_text',
|
||||
'status_code',
|
||||
'status_text',
|
||||
'status_desc',
|
||||
'btns',
|
||||
'activity_type_text',
|
||||
'promo_types_text'
|
||||
];
|
||||
|
||||
// 发货状态
|
||||
const DISPATCH_STATUS_REFUSE = -1; // 已拒收
|
||||
const DISPATCH_STATUS_NOSEND = 0; // 未发货
|
||||
const DISPATCH_STATUS_SENDED = 1; // 已发货
|
||||
const DISPATCH_STATUS_GETED = 2; // 已收货
|
||||
|
||||
|
||||
// 售后状态
|
||||
const AFTERSALE_STATUS_REFUSE = -1; // 拒绝
|
||||
const AFTERSALE_STATUS_NOAFTER = 0; // 未申请
|
||||
const AFTERSALE_STATUS_ING = 1; // 申请售后
|
||||
const AFTERSALE_STATUS_COMPLETED = 2; // 售后完成
|
||||
|
||||
|
||||
// 退款状态
|
||||
const REFUND_STATUS_NOREFUND = 0; // 退款状态 未申请
|
||||
const REFUND_STATUS_AGREE = 1; // 已同意
|
||||
const REFUND_STATUS_COMPLETED = 2; // 退款完成
|
||||
|
||||
// 评价状态
|
||||
const COMMENT_STATUS_NO = 0; // 待评价
|
||||
const COMMENT_STATUS_OK = 1; // 已评价
|
||||
|
||||
|
||||
public function dispatchStatusList()
|
||||
{
|
||||
return [
|
||||
self::DISPATCH_STATUS_REFUSE => '已拒收',
|
||||
self::DISPATCH_STATUS_NOSEND => '待发货',
|
||||
self::DISPATCH_STATUS_SENDED => '待收货',
|
||||
self::DISPATCH_STATUS_GETED => '已收货'
|
||||
];
|
||||
}
|
||||
|
||||
public function dispatchTypeList()
|
||||
{
|
||||
return [
|
||||
'express' => '快递物流',
|
||||
'autosend' => '自动发货',
|
||||
'custom' => '手动发货'
|
||||
];
|
||||
}
|
||||
|
||||
public function aftersaleStatusList()
|
||||
{
|
||||
return [
|
||||
self::AFTERSALE_STATUS_REFUSE => '售后驳回',
|
||||
self::AFTERSALE_STATUS_NOAFTER => '未申请',
|
||||
self::AFTERSALE_STATUS_ING => '申请售后',
|
||||
self::AFTERSALE_STATUS_COMPLETED => '已完成'
|
||||
];
|
||||
}
|
||||
|
||||
public function refundStatusList()
|
||||
{
|
||||
return [
|
||||
self::REFUND_STATUS_NOREFUND => '未退款',
|
||||
self::REFUND_STATUS_AGREE => '退款完成',
|
||||
self::REFUND_STATUS_COMPLETED => '退款完成',
|
||||
];
|
||||
}
|
||||
|
||||
public function commentStatusList()
|
||||
{
|
||||
return [
|
||||
self::COMMENT_STATUS_NO => '待评价',
|
||||
self::COMMENT_STATUS_OK => '已评价',
|
||||
];
|
||||
}
|
||||
|
||||
public function getActivityTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['activity_type'] ?? null);
|
||||
|
||||
$list = (new Activity)->typeList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
public function getDispatchTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['dispatch_type'] ?? null);
|
||||
|
||||
$list = $this->dispatchTypeList();
|
||||
if (strpos(request()->url(), 'addons/shopro') !== false) {
|
||||
$list['custom'] = '商家发货';
|
||||
}
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
public function getPromoTypesTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['promo_types'] ?? null);
|
||||
|
||||
$promoTypes = array_filter(explode(',', $value));
|
||||
$texts = [];
|
||||
$list = (new Activity)->typeList();
|
||||
foreach ($promoTypes as $type) {
|
||||
$text = isset($list[$type]) ? $list[$type] : '';
|
||||
if ($text) {
|
||||
$texts[] = $text;
|
||||
}
|
||||
}
|
||||
return $texts;
|
||||
}
|
||||
|
||||
public function getDispatchStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['dispatch_status'] ?? null);
|
||||
|
||||
$list = $this->dispatchStatusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
public function getAftersaleStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['aftersale_status'] ?? null);
|
||||
|
||||
$list = $this->aftersaleStatusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
public function getRefundStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['refund_status'] ?? null);
|
||||
|
||||
$list = $this->refundStatusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
public function getCommentStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['comment_status'] ?? null);
|
||||
|
||||
$list = $this->commentStatusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取建议退款金额,不考虑剩余可退款金额是否够退
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getSuggestRefundFeeAttr($value, $data)
|
||||
{
|
||||
$current_goods_amount = bcmul($data['goods_price'], (string)$data['goods_num'], 2);
|
||||
$total_amount = bcadd($current_goods_amount, $data['dispatch_fee'], 2);
|
||||
$suggest_refund_fee = bcsub($total_amount, $data['discount_fee'], 2); // (商品金额 + 运费金额) - 总优惠(活动,优惠券,包邮优惠)
|
||||
|
||||
return $suggest_refund_fee;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 可以确认收货
|
||||
*
|
||||
* @param \think\db\Query $query
|
||||
* @return void
|
||||
*/
|
||||
public function scopeCanConfirm($query)
|
||||
{
|
||||
return $query->where('dispatch_status', OrderItem::DISPATCH_STATUS_SENDED) // 已发货
|
||||
->whereNotIn('refund_status', [OrderItem::REFUND_STATUS_AGREE, OrderItem::REFUND_STATUS_COMPLETED]); // 没有退款完成
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 可以评价
|
||||
*
|
||||
* @param \think\db\Query $query
|
||||
* @return void
|
||||
*/
|
||||
public function scopeCanComment($query)
|
||||
{
|
||||
return $query->where('dispatch_status', OrderItem::DISPATCH_STATUS_GETED) // 已收货
|
||||
->where('comment_status', OrderItem::COMMENT_STATUS_NO) // 未评价
|
||||
->whereNotIn('refund_status', [OrderItem::REFUND_STATUS_AGREE, OrderItem::REFUND_STATUS_COMPLETED]); // 没有退款完成
|
||||
}
|
||||
|
||||
public function express()
|
||||
{
|
||||
return $this->belongsTo(Express::class, 'order_express_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
}
|
||||
268
application/admin/model/shopro/order/traits/OrderItemStatus.php
Normal file
268
application/admin/model/shopro/order/traits/OrderItemStatus.php
Normal file
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order\traits;
|
||||
|
||||
use app\admin\model\shopro\order\OrderItem;
|
||||
|
||||
trait OrderItemStatus
|
||||
{
|
||||
|
||||
public function getStatus($data, $type)
|
||||
{
|
||||
$btns = [];
|
||||
$backendBtns = [];
|
||||
$status_text = '';
|
||||
$status_desc = '';
|
||||
$ext = $this->ext;
|
||||
$aftersale_id = (isset($ext['aftersale_id']) && !empty($ext['aftersale_id'])) ? $ext['aftersale_id'] : 0;
|
||||
|
||||
$status_code = $this->status_code;
|
||||
|
||||
$item_code = 'null'; // 有售后的时候,第二状态
|
||||
if (strpos($status_code, '|') !== false) {
|
||||
$codes = explode('|', $status_code);
|
||||
$status_code = $codes[0] ?? 'null';
|
||||
$item_code = $codes[1] ?? 'null';
|
||||
}
|
||||
|
||||
switch ($status_code) {
|
||||
case 'null':
|
||||
case 'cancel':
|
||||
case 'closed':
|
||||
case 'unpaid':
|
||||
// 未支付的返回空
|
||||
break;
|
||||
case 'refuse': // 拒收
|
||||
$status_text = '已拒收';
|
||||
$status_desc = '用户拒绝收货';
|
||||
break;
|
||||
case 'nosend':
|
||||
$status_text = '待发货';
|
||||
$status_desc = '等待卖家发货';
|
||||
$backendBtns[] = 'send';
|
||||
$backendBtns[] = 'refund'; // 退款
|
||||
// $btns[] = $aftersale_id ? 're_aftersale' : 'aftersale'; // 售后,售后取消会有 aftersale_id , 待发货商品,不用申请售后,直接用订单退款
|
||||
break;
|
||||
case 'noget':
|
||||
$status_text = '待收货';
|
||||
$status_desc = '等待买家收货';
|
||||
// $btns[] = 'get'; // 确认收货,总订单上才有
|
||||
$btns[] = $aftersale_id ? 're_aftersale' : 'aftersale'; // 售后,售后取消会有 aftersale_id
|
||||
$backendBtns[] = 'send_cancel'; // 取消发货
|
||||
$backendBtns[] = 'refund';
|
||||
break;
|
||||
case 'nocomment':
|
||||
$status_text = '待评价';
|
||||
$status_desc = '等待买家评价';
|
||||
$btns[] = 'comment'; // 评价,总订单上才有(前端通过这个判断待评价商品)
|
||||
$btns[] = $aftersale_id ? 're_aftersale' : 'aftersale'; // 售后,售后取消会有 aftersale_id
|
||||
$backendBtns[] = 'refund'; // 退款
|
||||
break;
|
||||
case 'commented':
|
||||
$status_text = '已评价';
|
||||
$status_desc = '订单已评价';
|
||||
$btns[] = 'buy_again';
|
||||
$backendBtns[] = 'refund'; // 退款
|
||||
$backendBtns[] = 'comment_view'; // 查看评价
|
||||
break;
|
||||
case 'refund_completed':
|
||||
$status_text = '退款完成';
|
||||
$status_desc = '订单退款完成';
|
||||
break;
|
||||
case 'refund_agree': // 不需要申请退款(状态不会出现)
|
||||
$status_text = '退款完成';
|
||||
$status_desc = '卖家已同意退款';
|
||||
break;
|
||||
case 'aftersale_ing':
|
||||
$status_text = '售后中';
|
||||
$status_desc = '售后处理中';
|
||||
|
||||
if ($item_code == 'noget') {
|
||||
if (in_array($data['dispatch_type'], ['express'])) { // 除了 自提扫码核销外,都可确认收货
|
||||
$backendBtns[] = 'send_cancel'; // 取消发货
|
||||
}
|
||||
} else if ($item_code == 'nocomment') {
|
||||
// 售后中也可以评价订单
|
||||
$btns[] = 'comment'; // 评价,总订单上才有(前端通过这个判断待评价商品)
|
||||
}
|
||||
break;
|
||||
case 'aftersale_refuse':
|
||||
case 'aftersale_completed':
|
||||
switch ($status_code) {
|
||||
case 'aftersale_refuse':
|
||||
$status_text = '售后拒绝';
|
||||
$status_desc = '售后申请拒绝';
|
||||
if ($item_code != 'commented') {
|
||||
$btns[] = 're_aftersale'; // 售后
|
||||
}
|
||||
break;
|
||||
case 'aftersale_completed':
|
||||
$status_text = '售后完成';
|
||||
$status_desc = '售后完成';
|
||||
break;
|
||||
}
|
||||
|
||||
// 售后拒绝,或者完成的时候,还可以继续操作订单
|
||||
switch ($item_code) {
|
||||
case 'nosend':
|
||||
if (in_array($data['dispatch_type'], ['express'])) { // 除了 自提扫码核销外,都可确认收货
|
||||
$backendBtns[] = 'send'; // 发货
|
||||
}
|
||||
break;
|
||||
case 'noget':
|
||||
if (in_array($data['dispatch_type'], ['express'])) { // 除了 自提扫码核销外,都可确认收货
|
||||
// $btns[] = 'get'; // 确认收货,总订单上才有
|
||||
$backendBtns[] = 'send_cancel'; // 取消发货
|
||||
}
|
||||
break;
|
||||
case 'nocomment':
|
||||
$btns[] = 'comment'; // 评价,总订单上才有(前端通过这个判断待评价商品)
|
||||
break;
|
||||
case 'commented':
|
||||
$btns[] = 'buy_again';
|
||||
$backendBtns[] = 'comment_view'; // 查看评价
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果有售后id 就显示售后详情按钮,退款中可能是售后退的款
|
||||
if ($aftersale_id) {
|
||||
$btns[] = 'aftersale_info';
|
||||
$backendBtns[] = 'aftersale_info';
|
||||
}
|
||||
|
||||
$return = null;
|
||||
switch($type) {
|
||||
case 'status_text':
|
||||
$return = $status_text;
|
||||
break;
|
||||
case 'btns':
|
||||
$return = $btns;
|
||||
break;
|
||||
case 'status_desc':
|
||||
$return = $status_desc;
|
||||
break;
|
||||
case 'backend_btns':
|
||||
$return = $backendBtns;
|
||||
break;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
return $this->getStatus($data, 'status_text');
|
||||
}
|
||||
|
||||
public function getStatusDescAttr($value, $data)
|
||||
{
|
||||
return $this->getStatus($data, 'status_desc');
|
||||
}
|
||||
|
||||
public function getBtnsAttr($value, $data)
|
||||
{
|
||||
$btn_name = strpos(request()->url(), 'addons/shopro') !== false ? 'btns' : 'backend_btns';
|
||||
|
||||
return $this->getStatus($data, $btn_name);
|
||||
}
|
||||
|
||||
|
||||
// 获取订单 item status_code 状态,不进行订单是否支付判断,在这里查询数据库特别慢,
|
||||
// 需要处理情况,订单列表:要正确显示item 状态,直接获取 item 的状态
|
||||
public function getStatusCodeAttr($value, $data)
|
||||
{
|
||||
// $status_code = 'null';
|
||||
|
||||
// $order = Order::withTrashed()->where('id', $data['order_id'])->find();
|
||||
// if (!$order) {
|
||||
// return $status_code;
|
||||
// }
|
||||
|
||||
// // 判断是否支付
|
||||
// if (!in_array($order->status, [Order::STATUS_PAYED, Order::STATUS_FINISH])) {
|
||||
// return $order->status_code;
|
||||
// }
|
||||
|
||||
// 获取 item status_code
|
||||
return $this->getBaseStatusCode($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* $data 当前 item 数据
|
||||
* $from 当前 model 调用,还是 order 调用
|
||||
*/
|
||||
public function getBaseStatusCode($data, $from = 'item')
|
||||
{
|
||||
$status_code = 'null';
|
||||
|
||||
if ($data['refund_status'] == OrderItem::REFUND_STATUS_AGREE) {
|
||||
// 退款已同意
|
||||
return 'refund_agree';
|
||||
}
|
||||
if ($data['refund_status'] == OrderItem::REFUND_STATUS_COMPLETED) {
|
||||
// 退款完成
|
||||
return 'refund_completed';
|
||||
}
|
||||
|
||||
if ($data['aftersale_status']) {
|
||||
// 只申请了售后,没有退款
|
||||
// status_code
|
||||
$status_code = $this->getNormalStatusCode($data);
|
||||
|
||||
// item 要原始状态,总订单还要原来的未退款状态
|
||||
if ($from == 'item') {
|
||||
switch ($data['aftersale_status']) {
|
||||
case OrderItem::AFTERSALE_STATUS_REFUSE:
|
||||
$status_code = 'aftersale_refuse' . '|' . $status_code;
|
||||
break;
|
||||
case OrderItem::AFTERSALE_STATUS_ING:
|
||||
$status_code = 'aftersale_ing' . '|' . $status_code;
|
||||
break;
|
||||
case OrderItem::AFTERSALE_STATUS_COMPLETED:
|
||||
$status_code = 'aftersale_completed' . '|' . $status_code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// status_code
|
||||
$status_code = $this->getNormalStatusCode($data);
|
||||
}
|
||||
|
||||
return $status_code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getNormalStatusCode($data)
|
||||
{
|
||||
// 获取未申请售后和退款时候的 status_code
|
||||
$status_code = 'null';
|
||||
|
||||
switch ($data['dispatch_status']) {
|
||||
case OrderItem::DISPATCH_STATUS_REFUSE:
|
||||
$status_code = 'refuse';
|
||||
break;
|
||||
case OrderItem::DISPATCH_STATUS_NOSEND:
|
||||
$status_code = 'nosend';
|
||||
break;
|
||||
case OrderItem::DISPATCH_STATUS_SENDED:
|
||||
$status_code = 'noget';
|
||||
break;
|
||||
case OrderItem::DISPATCH_STATUS_GETED:
|
||||
if ($data['comment_status'] == OrderItem::COMMENT_STATUS_NO) {
|
||||
$status_code = 'nocomment';
|
||||
} else {
|
||||
$status_code = 'commented';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $status_code; // status_code
|
||||
}
|
||||
}
|
||||
211
application/admin/model/shopro/order/traits/OrderScope.php
Normal file
211
application/admin/model/shopro/order/traits/OrderScope.php
Normal file
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order\traits;
|
||||
|
||||
use app\admin\model\shopro\order\Order;
|
||||
use app\admin\model\shopro\order\OrderItem;
|
||||
|
||||
trait OrderScope
|
||||
{
|
||||
// 已关闭
|
||||
public function scopeClosed($query)
|
||||
{
|
||||
return $query->where('status', Order::STATUS_CLOSED);
|
||||
}
|
||||
|
||||
// 已取消
|
||||
public function scopeCancel($query)
|
||||
{
|
||||
return $query->where('status', Order::STATUS_CANCEL);
|
||||
}
|
||||
|
||||
// 未支付
|
||||
public function scopeUnpaid($query)
|
||||
{
|
||||
return $query->where('status', Order::STATUS_UNPAID);
|
||||
}
|
||||
|
||||
|
||||
// 可以取消,未支付&货到付款未发货的订单
|
||||
public function scopeCanCancel($query)
|
||||
{
|
||||
return $query->where(function ($query) {
|
||||
$query->where('status', Order::STATUS_UNPAID)->whereOr(function ($query) {
|
||||
$self_name = (new Order())->getQuery()->getTable();
|
||||
$item_name = (new OrderItem())->getQuery()->getTable();
|
||||
|
||||
$query->where('pay_mode', 'offline')->where('status', Order::STATUS_PENDING)->whereExists(function ($query) use ($self_name, $item_name) {
|
||||
// 货到付款订单,未发货未退款,可以申请售后
|
||||
$query->table($item_name)->where('order_id=' . $self_name . '.id')
|
||||
->where('dispatch_status', OrderItem::DISPATCH_STATUS_NOSEND) // 未发货
|
||||
->where('refund_status', OrderItem::REFUND_STATUS_NOREFUND); // 没有退款完成;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 已支付
|
||||
public function scopePaid($query)
|
||||
{
|
||||
return $query->whereIn('status', [Order::STATUS_PAID, Order::STATUS_COMPLETED]);
|
||||
}
|
||||
|
||||
|
||||
// 线下支付(货到付款) pending 时
|
||||
public function scopeOffline($query)
|
||||
{
|
||||
return $query->where('pay_mode', 'offline')->where('status', Order::STATUS_PENDING);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否线下支付(货到付款),暂未付款
|
||||
*
|
||||
* @param object|array $order
|
||||
* @return boolean
|
||||
*/
|
||||
public function isOffline($order)
|
||||
{
|
||||
return ($order['status'] == Order::STATUS_PENDING && $order['pay_mode'] == 'offline') ? true : false;
|
||||
}
|
||||
|
||||
|
||||
// 已支付的,或者是线下付款的未支付订单,后续可以,发货,收货,评价
|
||||
public function scopePretendPaid($query)
|
||||
{
|
||||
return $query->where(function ($query) {
|
||||
$query->whereIn('status', [Order::STATUS_PAID, Order::STATUS_COMPLETED])->whereOr(function($query) {
|
||||
$query->where('pay_mode', 'offline')->where('status', Order::STATUS_PENDING);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 已完成
|
||||
public function scopeCompleted($query)
|
||||
{
|
||||
return $query->where('status', Order::STATUS_COMPLETED);
|
||||
}
|
||||
|
||||
// 未申请全额退款,或者已拒绝
|
||||
public function scopeNoApplyRefund($query)
|
||||
{
|
||||
return $query->whereIn('apply_refund_status', [
|
||||
Order::APPLY_REFUND_STATUS_NOAPPLY,
|
||||
Order::APPLY_REFUND_STATUS_REFUSE
|
||||
]);
|
||||
}
|
||||
|
||||
// 申请全额退款中
|
||||
public function scopeApplyRefundIng($query)
|
||||
{
|
||||
return $query->where('apply_refund_status', Order::APPLY_REFUND_STATUS_APPLY);
|
||||
}
|
||||
|
||||
|
||||
// 未发货
|
||||
public function scopeNosend($query)
|
||||
{
|
||||
$self_name = (new Order())->getQuery()->getTable();
|
||||
$item_name = (new OrderItem())->getQuery()->getTable();
|
||||
|
||||
$is_express = (request()->action() == 'exportdelivery') ? 1 : 0; // 是否是 express,将只查快递物流的代发货
|
||||
|
||||
return $query->noApplyRefund()->whereExists(function ($query) use ($self_name, $item_name, $is_express) {
|
||||
$query->table($item_name)->where('order_id=' . $self_name . '.id')
|
||||
->where('dispatch_status', OrderItem::DISPATCH_STATUS_NOSEND) // 未发货
|
||||
->where('refund_status', OrderItem::REFUND_STATUS_NOREFUND); // 没有退款完成
|
||||
if ($is_express) { // 只查快递物流的代发货
|
||||
$query->where('dispatch_type', 'express');
|
||||
}
|
||||
})->whereNotExists(function ($query) use ($self_name, $item_name, $is_express) {
|
||||
// 不是 正在售后的商品
|
||||
$query->table($item_name)->where('order_id=' . $self_name . '.id')
|
||||
->where('aftersale_status', OrderItem::AFTERSALE_STATUS_ING) // 但是售后中
|
||||
->where('dispatch_status', OrderItem::DISPATCH_STATUS_NOSEND) // 未发货
|
||||
->where('refund_status', OrderItem::REFUND_STATUS_NOREFUND); // 没有退款完成;
|
||||
|
||||
if ($is_express) { // 只查快递物流的代发货
|
||||
$query->where('dispatch_type', 'express');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 待收货
|
||||
public function scopeNoget($query)
|
||||
{
|
||||
return $query->whereExists(function ($query) {
|
||||
$self_name = (new Order())->getQuery()->getTable();
|
||||
$item_name = (new OrderItem())->getQuery()->getTable();
|
||||
|
||||
$query->table($item_name)->where('order_id=' . $self_name . '.id')
|
||||
->where('dispatch_status', OrderItem::DISPATCH_STATUS_SENDED) // 已发货
|
||||
->where('refund_status', OrderItem::REFUND_STATUS_NOREFUND); // 没有退款完成
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 已拒收
|
||||
public function scopeRefuse($query)
|
||||
{
|
||||
return $query->whereExists(function ($query) {
|
||||
$self_name = (new Order())->getQuery()->getTable();
|
||||
$item_name = (new OrderItem())->getQuery()->getTable();
|
||||
|
||||
$query->table($item_name)->where('order_id=' . $self_name . '.id')
|
||||
->where('dispatch_status', OrderItem::DISPATCH_STATUS_REFUSE) // 已拒收
|
||||
->where('refund_status', OrderItem::REFUND_STATUS_NOREFUND); // 没有退款完成
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 待评价
|
||||
public function scopeNocomment($query)
|
||||
{
|
||||
return $query->whereExists(function ($query) {
|
||||
$self_name = (new Order())->getQuery()->getTable();
|
||||
$item_name = (new OrderItem())->getQuery()->getTable();
|
||||
|
||||
$query->table($item_name)->where('order_id=' . $self_name . '.id')
|
||||
->where('dispatch_status', OrderItem::DISPATCH_STATUS_GETED) // 已收货
|
||||
->where('refund_status', OrderItem::REFUND_STATUS_NOREFUND) // 没有退款完成
|
||||
->where('comment_status', OrderItem::COMMENT_STATUS_NO); // 未评价
|
||||
});
|
||||
}
|
||||
|
||||
// 售后 (后台要用,虽然有专门的售后单列表)
|
||||
public function scopeAftersale($query)
|
||||
{
|
||||
return $query->whereExists(function ($query) {
|
||||
$self_name = (new Order())->getQuery()->getTable();
|
||||
$item_name = (new OrderItem())->getQuery()->getTable();
|
||||
$query->table($item_name)->where('order_id=' . $self_name . '.id')
|
||||
->where('aftersale_status', '<>', OrderItem::AFTERSALE_STATUS_NOAFTER);
|
||||
});
|
||||
}
|
||||
|
||||
// 退款
|
||||
public function scopeRefund($query)
|
||||
{
|
||||
return $query->whereExists(function ($query) {
|
||||
$self_name = (new Order())->getQuery()->getTable();
|
||||
$item_name = (new OrderItem())->getQuery()->getTable();
|
||||
$query->table($item_name)->where('order_id=' . $self_name . '.id')
|
||||
->where('refund_status', '<>', OrderItem::REFUND_STATUS_NOREFUND);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public function scopeCanAftersale($query)
|
||||
{
|
||||
return $query->where('status', 'in', [Order::STATUS_PAID, Order::STATUS_COMPLETED]);
|
||||
}
|
||||
|
||||
public function scopeCanDelete($query)
|
||||
{
|
||||
return $query->where('status', 'in', [
|
||||
Order::STATUS_CANCEL,
|
||||
Order::STATUS_CLOSED,
|
||||
Order::STATUS_COMPLETED
|
||||
]);
|
||||
}
|
||||
}
|
||||
417
application/admin/model/shopro/order/traits/OrderStatus.php
Normal file
417
application/admin/model/shopro/order/traits/OrderStatus.php
Normal file
@@ -0,0 +1,417 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\order\traits;
|
||||
|
||||
use app\admin\model\shopro\order\Order;
|
||||
use app\admin\model\shopro\order\OrderItem;
|
||||
use app\admin\model\shopro\activity\Groupon;
|
||||
use app\admin\model\shopro\Config;
|
||||
|
||||
|
||||
trait OrderStatus
|
||||
{
|
||||
|
||||
protected function getStatus($data, $type)
|
||||
{
|
||||
$btns = []; // 前端订单操作按钮
|
||||
$backendBtns = [];
|
||||
$status_text = '';
|
||||
$status_desc = '';
|
||||
$ext = $this->ext;
|
||||
|
||||
switch ($this->status_code) {
|
||||
case 'cancel':
|
||||
$status_text = '已取消';
|
||||
$status_desc = '买家已取消';
|
||||
$btns[] = 'delete'; // 删除订单
|
||||
break;
|
||||
case 'closed':
|
||||
$status_text = '交易关闭';
|
||||
if (isset($ext['closed_type']) && $ext['closed_type'] == 'refuse') {
|
||||
$status_desc = '买家拒绝收货';
|
||||
} else {
|
||||
$status_desc = '买家未在规定时间内付款';
|
||||
}
|
||||
$btns[] = 'delete'; // 删除订单
|
||||
break;
|
||||
case 'unpaid':
|
||||
$status_text = '待付款';
|
||||
$status_desc = '等待买家付款';
|
||||
$btns[] = 'cancel'; // 取消订单
|
||||
$btns[] = 'pay'; // 支付
|
||||
$backendBtns[] = 'change_fee'; // 订单改价
|
||||
break;
|
||||
// 已支付的
|
||||
case 'apply_refund':
|
||||
$status_text = '申请退款中';
|
||||
$status_desc = '等待卖家处理退款';
|
||||
$backendBtns[] = 'apply_refund_oper'; // 处理申请退款按钮
|
||||
$backendBtns[] = 'refund'; // 只能退款,或者在列表上拒绝申请退款
|
||||
break;
|
||||
case 'commented':
|
||||
$status_text = '已评价';
|
||||
$status_desc = '订单已评价';
|
||||
|
||||
$dispatchType = $this->getItemDispatchTypes();
|
||||
if (in_array('express', $dispatchType)) {
|
||||
$btns[] = 'express'; // 查看物流
|
||||
}
|
||||
$backendBtns[] = 'refund';
|
||||
break;
|
||||
case 'nocomment':
|
||||
$status_text = '待评价';
|
||||
$status_desc = '等待买家评价';
|
||||
|
||||
$dispatchType = $this->getItemDispatchTypes();
|
||||
if (in_array('express', $dispatchType)) {
|
||||
$btns[] = 'express'; // 查看物流
|
||||
}
|
||||
$btns[] = 'comment';
|
||||
$backendBtns[] = 'refund';
|
||||
break;
|
||||
case 'noget':
|
||||
$status_text = '待收货';
|
||||
$status_desc = '等待买家收货';
|
||||
|
||||
$dispatchType = $this->getItemDispatchTypes();
|
||||
if (in_array('express', $dispatchType)) {
|
||||
$btns[] = 'express'; // 查看物流
|
||||
}
|
||||
|
||||
if ($this->isOffline($data)) {
|
||||
$status_desc = '卖家已发货,等待包裹运达';
|
||||
|
||||
// 用户可以拒收,后台确认收货
|
||||
$btns[] = 'refuse'; // 用户拒收
|
||||
$backendBtns[] = 'confirm';
|
||||
}else {
|
||||
// 计算自动确认收货时间
|
||||
$send_time = $ext['send_time'] ?? 0;
|
||||
$auto_confirm = Config::getConfigField('shop.order.auto_confirm');
|
||||
$auto_confirm_unix = $auto_confirm * 86400;
|
||||
if ($send_time && $auto_confirm_unix) {
|
||||
$auto_confirm_time = $send_time + $auto_confirm_unix;
|
||||
|
||||
if ($auto_confirm_time > time()) {
|
||||
$status_desc .= ',还剩' . diff_in_time($auto_confirm_time, null, true, true) . '自动确认';
|
||||
}
|
||||
}
|
||||
|
||||
$btns[] = 'confirm'; // 确认收货
|
||||
$backendBtns[] = 'refund';
|
||||
}
|
||||
|
||||
break;
|
||||
case 'nosend':
|
||||
$status_text = '待发货';
|
||||
$status_desc = '等待卖家发货';
|
||||
$statusCodes = $this->getItemStatusCode();
|
||||
if (in_array('noget', $statusCodes)) { // 只要存在待收货的item
|
||||
$btns[] = 'confirm'; // 确认收货 (部分发货时也可以收货)
|
||||
}
|
||||
|
||||
if ($this->isOffline($data)) {
|
||||
// 发货之前用户可以取消
|
||||
$btns[] = 'cancel'; // 用户取消订单
|
||||
} else {
|
||||
$backendBtns[] = 'refund';
|
||||
}
|
||||
$backendBtns[] = 'send';
|
||||
if (!isset($ext['need_address']) || $ext['need_address']) { // 自动发货这些不需要收货地址的,没有 edit_consignee
|
||||
$backendBtns[] = 'edit_consignee'; //修改收货地址
|
||||
}
|
||||
|
||||
break;
|
||||
case 'refund_completed':
|
||||
$status_text = '退款完成';
|
||||
$status_desc = '订单退款完成';
|
||||
break;
|
||||
case 'refund_agree':
|
||||
$status_text = '退款完成';
|
||||
$status_desc = '订单退款完成';
|
||||
break;
|
||||
case 'groupon_ing':
|
||||
$status_text = '等待成团';
|
||||
$status_desc = '等待拼团成功';
|
||||
if ($this->isOffline($data)) {
|
||||
// 货到付款未付款,不能退款,等待拼团时还未发货,用户可取消订单
|
||||
$btns[] = 'cancel'; // 用户取消订单
|
||||
} else {
|
||||
$backendBtns[] = 'refund'; // 全部退款 直接不申请退款
|
||||
}
|
||||
break;
|
||||
case 'groupon_invalid':
|
||||
$status_text = '拼团失败';
|
||||
$status_desc = '拼团失败';
|
||||
break;
|
||||
// 已支付的结束
|
||||
case 'completed':
|
||||
$status_text = '交易完成';
|
||||
$status_desc = '交易已完成';
|
||||
$btns[] = 'delete'; // 删除订单
|
||||
break;
|
||||
}
|
||||
|
||||
// 有活动
|
||||
if (in_array($data['activity_type'], ['groupon', 'groupon_ladder', 'groupon_lucky'])) {
|
||||
// 是拼团订单
|
||||
if (isset($ext['groupon_id']) && $ext['groupon_id']) {
|
||||
$btns[] = 'groupon'; // 拼团详情
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($this->status_code, ['nosend', 'groupon_ing']) && !$this->isOffline($data)) { // 线下付款订单,不可申请全额退款
|
||||
if (in_array($data['apply_refund_status'], [Order::APPLY_REFUND_STATUS_NOAPPLY, Order::APPLY_REFUND_STATUS_REFUSE])) {
|
||||
// 获取所有的 item 状态
|
||||
$statusCodes = $this->getItemStatusCode();
|
||||
if (count($statusCodes) == 1 && current($statusCodes) == 'nosend') {
|
||||
// items 只有 未发货,就显示 申请退款按钮
|
||||
if ($data['apply_refund_status'] == Order::APPLY_REFUND_STATUS_REFUSE) {
|
||||
$btns[] = 're_apply_refund'; // 重新申请退款
|
||||
} else {
|
||||
$btns[] = 'apply_refund'; // 申请退款
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($data['invoice_status'] == 1) {
|
||||
$btns[] = 'invoice'; // 查看发票
|
||||
} else if ($data['invoice_status'] == 0) {
|
||||
if (in_array($this->status_code, ['commented', 'nocomment', 'noget', 'nosend', 'completed'])) {
|
||||
$btns[] = 'apply_invoice'; // 申请发票
|
||||
}
|
||||
}
|
||||
|
||||
$return = null;
|
||||
switch ($type) {
|
||||
case 'status_text':
|
||||
$return = $status_text;
|
||||
break;
|
||||
case 'btns':
|
||||
$return = $btns;
|
||||
break;
|
||||
case 'status_desc':
|
||||
$return = $status_desc;
|
||||
break;
|
||||
case 'backend_btns':
|
||||
if (in_array('refund', $backendBtns)) {
|
||||
// 判断是否有退款,如果存在退款就移除 refund 按钮
|
||||
$refundCount = OrderItem::where('order_id', $data['id'])->where('refund_status', '<>', OrderItem::REFUND_STATUS_NOREFUND)->count();
|
||||
if ($refundCount && ($key = array_search('refund', $backendBtns))) {
|
||||
unset($backendBtns[$key]);
|
||||
}
|
||||
|
||||
$backendBtns = array_values($backendBtns);
|
||||
}
|
||||
|
||||
$return = $backendBtns;
|
||||
break;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取支付成功之后的子状态
|
||||
*/
|
||||
public function getPayedStatusCode($data)
|
||||
{
|
||||
$status_code = '';
|
||||
|
||||
// 获取所有的 item 状态
|
||||
$statusCodes = $this->getItemStatusCode();
|
||||
|
||||
if (in_array('nosend', $statusCodes)) {
|
||||
// 存在待发货就是待发货
|
||||
$status_code = 'nosend';
|
||||
} else if (in_array('noget', $statusCodes)) {
|
||||
// 存在待收货,就是待收货
|
||||
$status_code = 'noget';
|
||||
} else if (in_array('nocomment', $statusCodes)) {
|
||||
// 存在待评价,就是待评价
|
||||
$status_code = 'nocomment';
|
||||
} else if (in_array('commented', $statusCodes)) {
|
||||
// 存在已评价,就是已评价
|
||||
$status_code = 'commented';
|
||||
} else if (in_array('refund_completed', $statusCodes)) {
|
||||
// 所有商品退款完成,或者退款中(不可能存在待发货或者收货的商品,上面已判断过)
|
||||
$status_code = 'refund_completed';
|
||||
} else if (in_array('refund_agree', $statusCodes)) {
|
||||
// 所有商品都同意退款了 (不可能存在待发货或者收货的商品,上面已判断过)
|
||||
$status_code = 'refund_agree';
|
||||
} // 售后都不在总状态显示
|
||||
|
||||
if ($data['apply_refund_status'] == Order::APPLY_REFUND_STATUS_APPLY && !in_array($status_code, ['refund_completed', 'refund_agree'])) {
|
||||
return $status_code = 'apply_refund'; // 申请退款中,并且还没退款
|
||||
}
|
||||
|
||||
$ext = $this->ext;
|
||||
// 是拼团订单
|
||||
if (
|
||||
in_array($data['activity_type'], ['groupon', 'groupon_ladder', 'groupon_lucky']) &&
|
||||
isset($ext['groupon_id']) && $ext['groupon_id']
|
||||
) {
|
||||
$groupon = Groupon::where('id', $ext['groupon_id'])->find();
|
||||
if ($groupon) {
|
||||
if ($groupon['status'] == 'ing') {
|
||||
// 尚未成团
|
||||
$status_code = $statusCodes[0] ?? ''; // 拼团订单只能有一个商品
|
||||
$status_code = in_array($status_code, ['refund_agree', 'refund_completed']) ? $status_code : 'groupon_ing'; // 如果订单已退款,则是退款状态,不显示拼团中
|
||||
} else if ($groupon['status'] == 'invalid') {
|
||||
$status_code = 'groupon_invalid';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $status_code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取订单items状态
|
||||
*
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
private function getItemStatusCode($type = 'order')
|
||||
{
|
||||
// 循环判断 item 状态
|
||||
$itemStatusCode = [];
|
||||
foreach ($this->items as $key => $item) {
|
||||
// 获取 item status
|
||||
$itemStatusCode[] = (new OrderItem)->getBaseStatusCode($item, $type);
|
||||
}
|
||||
|
||||
// 取出不重复不为空的 status_code
|
||||
$statusCodes = array_values(array_unique(array_filter($itemStatusCode)));
|
||||
|
||||
return $statusCodes;
|
||||
}
|
||||
|
||||
|
||||
private function getItemDispatchTypes()
|
||||
{
|
||||
$dispatchType = [];
|
||||
foreach ($this->items as $key => $item) {
|
||||
// 获取 item status
|
||||
$dispatchType[] = $item['dispatch_type'];
|
||||
}
|
||||
$dispatchType = array_unique(array_filter($dispatchType)); // 过滤重复,过滤空值
|
||||
return $dispatchType;
|
||||
}
|
||||
|
||||
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
return $this->getStatus($data, 'status_text');
|
||||
}
|
||||
|
||||
public function getStatusDescAttr($value, $data)
|
||||
{
|
||||
return $this->getStatus($data, 'status_desc');
|
||||
}
|
||||
|
||||
|
||||
public function getBtnsAttr($value, $data)
|
||||
{
|
||||
$btn_name = strpos(request()->url(), 'addons/shopro') !== false ? 'btns' : 'backend_btns';
|
||||
|
||||
return $this->getStatus($data, $btn_name);
|
||||
}
|
||||
|
||||
|
||||
// 获取订单状态
|
||||
public function getStatusCodeAttr($value, $data)
|
||||
{
|
||||
$status_code = '';
|
||||
|
||||
switch ($data['status']) {
|
||||
case Order::STATUS_CLOSED:
|
||||
$status_code = 'closed'; // 订单交易关闭
|
||||
break;
|
||||
case Order::STATUS_CANCEL:
|
||||
$status_code = 'cancel'; // 订单已取消
|
||||
break;
|
||||
case Order::STATUS_UNPAID:
|
||||
$status_code = 'unpaid'; // 订单等待支付
|
||||
break;
|
||||
case Order::STATUS_PENDING:
|
||||
$status_code = $this->getPayedStatusCode($data); // 订单线下付款
|
||||
break;
|
||||
case Order::STATUS_PAID:
|
||||
// 根据 item 获取支付后的状态信息
|
||||
$status_code = $this->getPayedStatusCode($data);
|
||||
break;
|
||||
case Order::STATUS_COMPLETED:
|
||||
$status_code = 'completed';
|
||||
break;
|
||||
}
|
||||
|
||||
return $status_code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理未支付 item status_code
|
||||
* 查询列表 item status_code 不关联订单表,使用这个方法进行处理
|
||||
*/
|
||||
public function setOrderItemStatusByOrder($order)
|
||||
{
|
||||
$order = $order instanceof \think\Model ? $order->toArray() : $order;
|
||||
|
||||
foreach ($order['items'] as $key => &$item) {
|
||||
if ((!in_array($order['status'], [Order::STATUS_PAID, Order::STATUS_COMPLETED]) && !$this->isOffline($order)) // 没有支付,并且也不是货到付款
|
||||
|| $order['apply_refund_status'] == Order::APPLY_REFUND_STATUS_APPLY) {
|
||||
// 未支付,status_code = 订单的 status_code
|
||||
$item['status_code'] = $order['status_code'];
|
||||
$item['status_text'] = '';
|
||||
$item['status_desc'] = '';
|
||||
$item['btns'] = [];
|
||||
} else {
|
||||
if (strpos(request()->url(), 'addons/shopro') !== false) {
|
||||
// 前端
|
||||
if (strpos($item['status_code'], 'nosend') !== false) {
|
||||
if (!$this->isOffline($order) && !array_intersect(['re_apply_refund', 'apply_refund'], $order['btns'])) {
|
||||
// 不能申请全额退款了(有部分发货,或者退款)的待发货的 item 要显示申请售后的按钮
|
||||
$aftersale_id = (isset($item['ext']['aftersale_id']) && !empty($item['ext']['aftersale_id'])) ? $item['ext']['aftersale_id'] : 0;
|
||||
|
||||
if (strpos($item['status_code'], 'aftersale_ing') === false && strpos($item['status_code'], 'aftersale_completed') === false) {
|
||||
// 不是售后中,也不是售后完成
|
||||
if (strpos($item['status_code'], 'aftersale_refuse') !== false && $aftersale_id) {
|
||||
// 如果申请过退款,被拒绝了,则为重新申请售后
|
||||
$item['btns'][] = 're_aftersale';
|
||||
} else {
|
||||
// 取消售后是 re_aftersale ,未申请过是 aftersale
|
||||
$item['btns'][] = $aftersale_id ? 're_aftersale' : 'aftersale'; // 售后,售后取消会有 aftersale_id
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (strpos($item['status_code'], 'noget') !== false) {
|
||||
// 如果是货到付款的 待收货
|
||||
if ($this->isOffline($order)) {
|
||||
foreach($item['btns'] as $btnk => $btn) {
|
||||
if (in_array($btn, ['re_aftersale', 'aftersale'])) {
|
||||
unset($item['btns'][$btnk]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 后端,如果是货到付款, 并且还没收货,不显示退款按钮
|
||||
if ($this->isOffline($order) && (strpos($item['status_code'], 'nosend') !== false || strpos($item['status_code'], 'noget') !== false)) {
|
||||
$refund_key = array_search('refund', $item['btns']);
|
||||
if ($refund_key !== false) {
|
||||
unset($item['btns'][$refund_key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
}
|
||||
176
application/admin/model/shopro/trade/Order.php
Normal file
176
application/admin/model/shopro/trade/Order.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\trade;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
use app\admin\model\shopro\user\User;
|
||||
use app\admin\model\shopro\Pay as PayModel;
|
||||
|
||||
class Order extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $name = 'shopro_trade_order';
|
||||
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $type = [
|
||||
'ext' => 'json',
|
||||
'paid_time' => 'timestamp',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text',
|
||||
'status_text',
|
||||
'platform_text',
|
||||
];
|
||||
|
||||
|
||||
// 订单状态
|
||||
const STATUS_CLOSED = 'closed';
|
||||
const STATUS_CANCEL = 'cancel';
|
||||
const STATUS_UNPAID = 'unpaid';
|
||||
const STATUS_PAID = 'paid';
|
||||
const STATUS_COMPLETED = 'completed';
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'closed' => '交易关闭',
|
||||
'cancel' => '已取消',
|
||||
'unpaid' => '未支付',
|
||||
'paid' => '已支付',
|
||||
'completed' => '已完成'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 订单列表状态搜索
|
||||
*/
|
||||
public function searchStatusList()
|
||||
{
|
||||
return [
|
||||
'unpaid' => '待付款',
|
||||
'paid' => '已支付', // 包括刚支付的,以及已完成的所有付过款的订单
|
||||
'completed' => '已完成',
|
||||
'cancel' => '已取消',
|
||||
'closed' => '交易关闭',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'recharge' => '充值订单',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function platformList()
|
||||
{
|
||||
return [
|
||||
'H5' => 'H5',
|
||||
'WechatOfficialAccount' => '微信公众号',
|
||||
'WechatMiniProgram' => '微信小程序',
|
||||
'App' => 'App',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function getPlatformTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['platform'] ?? null);
|
||||
|
||||
$list = $this->platformList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 已支付订单,支付类型
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function getPayTypeAttr($value, $data)
|
||||
{
|
||||
$status = $data['status'] ?? '';
|
||||
$payTypes = [];
|
||||
if (in_array($status, [self::STATUS_PAID, self::STATUS_COMPLETED])) {
|
||||
$payTypes = PayModel::typeTradeOrder()->where('order_id', $data['id'])->where('status', '<>', PayModel::PAY_STATUS_UNPAID)->group('pay_type')->column('pay_type');
|
||||
}
|
||||
|
||||
return $payTypes[0] ?? '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 已支付订单,支付类型文字
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function getPayTypeTextAttr($value, $data)
|
||||
{
|
||||
$pay_types = $this->pay_type;
|
||||
$list = (new PayModel)->payTypeList();
|
||||
|
||||
return isset($list[$pay_types]) ? $list[$pay_types] : '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 已关闭
|
||||
public function scopeClosed($query)
|
||||
{
|
||||
return $query->where('status', Order::STATUS_CLOSED);
|
||||
}
|
||||
|
||||
// 已取消
|
||||
public function scopeCancel($query)
|
||||
{
|
||||
return $query->where('status', Order::STATUS_CANCEL);
|
||||
}
|
||||
|
||||
// 未支付
|
||||
public function scopeUnpaid($query)
|
||||
{
|
||||
return $query->where('status', Order::STATUS_UNPAID);
|
||||
}
|
||||
|
||||
// 已支付
|
||||
public function scopePaid($query)
|
||||
{
|
||||
return $query->whereIn('status', [Order::STATUS_PAID, Order::STATUS_COMPLETED]);
|
||||
}
|
||||
|
||||
// 已完成
|
||||
public function scopeCompleted($query)
|
||||
{
|
||||
return $query->where('status', Order::STATUS_COMPLETED);
|
||||
}
|
||||
|
||||
|
||||
public function scopeRecharge($query)
|
||||
{
|
||||
return $query->where('type', 'recharge');
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id', 'id');
|
||||
}
|
||||
|
||||
public function pays()
|
||||
{
|
||||
return $this->hasMany(PayModel::class, 'order_id', 'id')->typeTradeOrder();
|
||||
}
|
||||
}
|
||||
222
application/admin/model/shopro/traits/ModelAttr.php
Normal file
222
application/admin/model/shopro/traits/ModelAttr.php
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\traits;
|
||||
|
||||
trait ModelAttr
|
||||
{
|
||||
/**
|
||||
* 默认类型列表,子类重写
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function typeList()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 默认状态列表,子类可重写
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'normal' => '正常',
|
||||
'hidden' => '隐藏',
|
||||
'enable' => '启用中',
|
||||
'disabled' => '已禁用',
|
||||
'up' => '上架',
|
||||
'down' => '下架',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* (查询范围)正常
|
||||
*/
|
||||
public function scopeNormal($query)
|
||||
{
|
||||
return $query->where('status', 'normal');
|
||||
}
|
||||
|
||||
/**
|
||||
* (查询范围)启用
|
||||
*/
|
||||
public function scopeEnable($query)
|
||||
{
|
||||
return $query->where('status', 'enable');
|
||||
}
|
||||
|
||||
/**
|
||||
* (查询范围)禁用
|
||||
*/
|
||||
public function scopeDisabled($query)
|
||||
{
|
||||
return $query->where('status', 'disabled');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* (查询范围)隐藏 hidden 和框架底层 hidden 冲突了
|
||||
*/
|
||||
public function scopeStatusHidden($query)
|
||||
{
|
||||
return $query->where('status', 'hidden');
|
||||
}
|
||||
|
||||
/**
|
||||
* (查询范围)上架
|
||||
*/
|
||||
public function scopeUp($query)
|
||||
{
|
||||
return $query->where('status', 'up');
|
||||
}
|
||||
|
||||
/**
|
||||
* (查询范围)下架
|
||||
*/
|
||||
public function scopeDown($query)
|
||||
{
|
||||
return $query->where('status', 'down');
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 创建时间格式化
|
||||
// *
|
||||
// * @param string $value
|
||||
// * @param array $data
|
||||
// * @return string
|
||||
// */
|
||||
// public function getCreatetimeAttr($value, $data)
|
||||
// {
|
||||
// return $this->attrTimeFormat($value, $data, 'createtime');
|
||||
// }
|
||||
|
||||
|
||||
// /**
|
||||
// * 更新时间格式化
|
||||
// *
|
||||
// * @param string $value
|
||||
// * @param array $data
|
||||
// * @return string
|
||||
// */
|
||||
// public function getUpdatetimeAttr($value, $data)
|
||||
// {
|
||||
// return $this->attrTimeFormat($value, $data, 'updatetime');
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 更新时间格式化
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getDeletetimeAttr($value, $data)
|
||||
{
|
||||
return $this->attrTimeFormat($value, $data, 'deletetime');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 通用类型获取器
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getTypeTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['type'] ?? null);
|
||||
|
||||
$list = $this->typeList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通用状态获取器
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['status'] ?? '');
|
||||
|
||||
$list = $this->statusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 时间格式化
|
||||
*
|
||||
* @param mix $value
|
||||
* @param array $data
|
||||
* @param string $field
|
||||
* @return string
|
||||
*/
|
||||
protected function attrTimeFormat($value, $data, $field)
|
||||
{
|
||||
$value = $value ?: ($data[$field] ?? null);
|
||||
|
||||
return $value ? (is_string($value) ? $value : date('Y-m-d H:i:s', $value)) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取器格式化 json
|
||||
*
|
||||
* @param mix $value
|
||||
* @param array $data
|
||||
* @param string $field
|
||||
* @param bool $return_array
|
||||
* @return array|null
|
||||
*/
|
||||
protected function attrFormatJson($value, $data, $field, $return_array = false)
|
||||
{
|
||||
$value = $value ?: ($data[$field] ?? null);
|
||||
|
||||
$value = $value ? json_decode($value, true) : ($return_array ? [] : $value);
|
||||
return $value === false ? $data[$field] : $value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取器格式化 , 隔开的数据
|
||||
*
|
||||
* @param mix $value
|
||||
* @param array $data
|
||||
* @param string $field
|
||||
* @param bool $return_array
|
||||
* @return array|null
|
||||
*/
|
||||
protected function attrFormatComma($value, $data, $field, $return_array = false)
|
||||
{
|
||||
$value = $value ?: ($data[$field] ?? null);
|
||||
|
||||
$value = $value ? explode(',', $value) : ($return_array ? [] : $value);
|
||||
return $value === false ? $data[$field] : $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将时间格式化为时间戳
|
||||
*
|
||||
* @param [type] $time
|
||||
* @return void
|
||||
*/
|
||||
protected function attrFormatUnix($time)
|
||||
{
|
||||
return $time ? (!is_numeric($time) ? strtotime($time) : $time) : null;
|
||||
}
|
||||
}
|
||||
26
application/admin/model/shopro/user/Account.php
Normal file
26
application/admin/model/shopro/user/Account.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\user;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Account extends Common
|
||||
{
|
||||
protected $name = 'shopro_user_account';
|
||||
protected $type = [];
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text'
|
||||
];
|
||||
|
||||
protected $typeMap = [
|
||||
'wechat' => '微信零钱',
|
||||
'alipay' => '支付宝账户',
|
||||
'bank' => '银行卡转账'
|
||||
];
|
||||
|
||||
public function getTypeTextAttr($value, $data)
|
||||
{
|
||||
return $this->typeMap[$data['type']];
|
||||
}
|
||||
}
|
||||
24
application/admin/model/shopro/user/Address.php
Normal file
24
application/admin/model/shopro/user/Address.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\user;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Address extends Common
|
||||
{
|
||||
protected $name = 'shopro_user_address';
|
||||
|
||||
protected $type = [
|
||||
'is_default' => 'boolean'
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [];
|
||||
|
||||
|
||||
public function scopeDefault($query)
|
||||
{
|
||||
return $query->where('is_default', 1);
|
||||
}
|
||||
|
||||
}
|
||||
308
application/admin/model/shopro/user/Coupon.php
Normal file
308
application/admin/model/shopro/user/Coupon.php
Normal file
@@ -0,0 +1,308 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\user;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\Coupon as CouponModel;
|
||||
use app\admin\model\shopro\user\User as UserModel;
|
||||
use app\admin\model\shopro\order\Order as OrderModel;
|
||||
|
||||
class Coupon extends Common
|
||||
{
|
||||
protected $name = 'shopro_user_coupon';
|
||||
|
||||
protected $type = [
|
||||
'use_time' => 'timestamp'
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'name',
|
||||
'type',
|
||||
'type_text',
|
||||
'use_scope',
|
||||
'use_scope_text',
|
||||
'items',
|
||||
'amount',
|
||||
'amount_text',
|
||||
'enough',
|
||||
'limit_num',
|
||||
'use_start_time',
|
||||
'use_end_time',
|
||||
'max_amount',
|
||||
'is_double_discount',
|
||||
'description',
|
||||
'status',
|
||||
'status_text',
|
||||
];
|
||||
|
||||
|
||||
public function statusList()
|
||||
{
|
||||
return [
|
||||
'used' => '已使用',
|
||||
'can_use' => '立即使用',
|
||||
'expired' => '已过期',
|
||||
'cannot_use' => '暂不可用',
|
||||
|
||||
'geted' => '未使用' // 包括 can_use 和 cannot_use
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function scopeGeted($query)
|
||||
{
|
||||
return $query->whereNull('use_time')->whereExists(function ($query) {
|
||||
$table_name = (new CouponModel)->getQuery()->getTable();
|
||||
$user_coupon_name = (new self)->getQuery()->getTable();
|
||||
|
||||
$query->table($table_name)->whereNull('deletetime')->whereIn('status', ['normal', 'hidden'])
|
||||
->where($user_coupon_name . '.coupon_id=' . $table_name . '.id')
|
||||
->where(function ($query) use ($user_coupon_name) {
|
||||
$query->where(function ($query) {
|
||||
$query->where('use_time_type', 'range')->where('use_end_time', '>=', time()); // 可用结束时间,大于当前时间,已经可用,或者暂不可用都算
|
||||
})->whereOr(function ($query) use ($user_coupon_name) {
|
||||
$query->where('use_time_type', 'days')
|
||||
->whereRaw($user_coupon_name . '.createtime + ((start_days + days) * 86400) >= ' . time()); // 可用结束结束时间大于当前时间
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 可以使用
|
||||
public function scopeCanUse($query)
|
||||
{
|
||||
return $query->whereNull('use_time')->whereExists(function ($query) {
|
||||
$table_name = (new CouponModel)->getQuery()->getTable();
|
||||
$user_coupon_name = (new self)->getQuery()->getTable();
|
||||
|
||||
$query->table($table_name)->whereNull('deletetime')->whereIn('status', ['normal', 'hidden'])
|
||||
->where($user_coupon_name . '.coupon_id=' . $table_name . '.id')
|
||||
->where(function ($query) use ($user_coupon_name) {
|
||||
$query->where(function ($query) {
|
||||
$query->where('use_time_type', 'range')->where('use_start_time', '<=', time())->where('use_end_time', '>=', time());
|
||||
})->whereOr(function ($query) use ($user_coupon_name) {
|
||||
$query->where('use_time_type', 'days')
|
||||
->whereRaw($user_coupon_name . '.createtime + (start_days * 86400) <= ' . time())
|
||||
->whereRaw($user_coupon_name . '.createtime + ((start_days + days) * 86400) >= ' . time());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 暂不可用,还没到可使用日期
|
||||
public function scopeCannotUse($query)
|
||||
{
|
||||
return $query->whereNull('use_time')->whereExists(function ($query) {
|
||||
$table_name = (new CouponModel)->getQuery()->getTable();
|
||||
$user_coupon_name = (new self)->getQuery()->getTable();
|
||||
|
||||
$query->table($table_name)->whereNull('deletetime')->whereIn('status', ['normal', 'hidden'])
|
||||
->where($user_coupon_name . '.coupon_id=' . $table_name . '.id')
|
||||
->where(function ($query) use ($user_coupon_name) {
|
||||
$query->where(function ($query) {
|
||||
$query->where('use_time_type', 'range')->where('use_start_time', '>', time());
|
||||
})->whereOr(function ($query) use ($user_coupon_name) {
|
||||
$query->where('use_time_type', 'days')
|
||||
->whereRaw($user_coupon_name . '.createtime + (start_days * 86400) > ' . time());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 已使用
|
||||
public function scopeUsed($query)
|
||||
{
|
||||
return $query->whereNotNull('use_time');
|
||||
}
|
||||
|
||||
// 未使用,但已过期
|
||||
public function scopeExpired($query)
|
||||
{
|
||||
return $query->whereNull('use_time')->whereExists(function ($query) {
|
||||
$table_name = (new CouponModel)->getQuery()->getTable();
|
||||
$user_coupon_name = (new self)->getQuery()->getTable();
|
||||
|
||||
$query->table($table_name)->whereNull('deletetime')->whereIn('status', ['normal', 'hidden'])
|
||||
->where($user_coupon_name . '.coupon_id=' . $table_name . '.id')
|
||||
->where(function ($query) use ($user_coupon_name) {
|
||||
$query->where(function ($query) {
|
||||
$query->where('use_time_type', 'range')->where('use_end_time', '<', time());
|
||||
})->whereOr(function ($query) use ($user_coupon_name) {
|
||||
$query->where('use_time_type', 'days')
|
||||
->whereRaw($user_coupon_name . '.createtime + ((start_days + days) * 86400) < ' . time());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 未使用,但已过期,或者已使用
|
||||
public function scopeInvalid($query)
|
||||
{
|
||||
return $query->where(function ($query) {
|
||||
$query->whereNotNull('use_time')->whereOr(function ($query) {
|
||||
$query->whereNull('use_time')->whereExists(function ($query) {
|
||||
$table_name = (new CouponModel)->getQuery()->getTable();
|
||||
$user_coupon_name = (new self)->getQuery()->getTable();
|
||||
|
||||
$query->table($table_name)->whereNull('deletetime')->whereIn('status', ['normal', 'hidden'])
|
||||
->where($user_coupon_name . '.coupon_id=' . $table_name . '.id')
|
||||
->where(function ($query) use ($user_coupon_name) {
|
||||
$query->where(function ($query) {
|
||||
$query->where('use_time_type', 'range')->where('use_end_time', '<', time());
|
||||
})->whereOr(function ($query) use ($user_coupon_name) {
|
||||
$query->where('use_time_type', 'days')
|
||||
->whereRaw($user_coupon_name . '.createtime + ((start_days + days) * 86400) < ' . time());
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public function getNameAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->name : '';
|
||||
}
|
||||
|
||||
public function getTypeAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->type : '';
|
||||
}
|
||||
|
||||
public function getUseScopeAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->use_scope : '';
|
||||
}
|
||||
|
||||
public function getItemsAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->items : '';
|
||||
}
|
||||
|
||||
public function getAmountAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->amount : '';
|
||||
}
|
||||
|
||||
|
||||
public function getEnoughAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->enough : '';
|
||||
}
|
||||
|
||||
public function getLimitNumAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->limit_num : '';
|
||||
}
|
||||
|
||||
public function getUseStartTimeAttr($value, $data)
|
||||
{
|
||||
if ($this->coupon) {
|
||||
if ($this->coupon->use_time_type == 'days') {
|
||||
return date('Y-m-d H:i:s', $data['createtime'] + ($this->coupon->start_days * 86400));
|
||||
}
|
||||
|
||||
return $this->coupon->use_start_time;
|
||||
}
|
||||
}
|
||||
|
||||
public function getUseEndTimeAttr($value, $data)
|
||||
{
|
||||
if ($this->coupon) {
|
||||
if ($this->coupon->use_time_type == 'days') {
|
||||
return date('Y-m-d H:i:s', $data['createtime'] + (($this->coupon->start_days + $this->coupon->days) * 86400));
|
||||
}
|
||||
|
||||
return $this->coupon->use_end_time;
|
||||
}
|
||||
}
|
||||
|
||||
public function getMaxAmountAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->max_amount : 0;
|
||||
}
|
||||
|
||||
public function getIsDoubleDiscountAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->is_double_discount : 0;
|
||||
}
|
||||
|
||||
public function getDescriptionAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->description : '';
|
||||
}
|
||||
|
||||
public function getUseScopeTextAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->use_scope : 0;
|
||||
}
|
||||
|
||||
public function getAmountTextAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->amount_text : 0;
|
||||
}
|
||||
|
||||
public function getItemsValueAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->items_value : 0;
|
||||
}
|
||||
|
||||
public function getTypeTextAttr($value, $data)
|
||||
{
|
||||
return $this->coupon ? $this->coupon->type_text : 0;
|
||||
}
|
||||
|
||||
|
||||
// 我的优惠券使用状态
|
||||
public function getStatusAttr($value, $data)
|
||||
{
|
||||
if ($data['use_time']) {
|
||||
$status = 'used';
|
||||
} else {
|
||||
if ($this->use_start_time <= date('Y-m-d H:i:s') && $this->use_end_time >= date('Y-m-d H:i:s')) {
|
||||
$status = 'can_use';
|
||||
} else if ($this->use_end_time <= date('Y-m-d H:i:s')) {
|
||||
$status = 'expired';
|
||||
} else {
|
||||
// 未到使用日期
|
||||
$status = 'cannot_use';
|
||||
}
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($this->status ?? '');
|
||||
|
||||
if (strpos(request()->url(), 'addons/shopro') === false) {
|
||||
$value = in_array($value, ['can_use', 'cannot_use']) ? 'geted' : $value; // 后台,可以使用和咱不可用 合并
|
||||
}
|
||||
|
||||
$list = $this->statusList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
|
||||
public function coupon()
|
||||
{
|
||||
return $this->belongsTo(CouponModel::class, 'coupon_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(OrderModel::class, 'use_order_id');
|
||||
}
|
||||
}
|
||||
62
application/admin/model/shopro/user/GoodsLog.php
Normal file
62
application/admin/model/shopro/user/GoodsLog.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\user;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\goods\Goods;
|
||||
|
||||
class GoodsLog extends Common
|
||||
{
|
||||
protected $name = 'shopro_user_goods_log';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 添加浏览记录
|
||||
*
|
||||
* @param object $user
|
||||
* @param object $goods
|
||||
* @return void
|
||||
*/
|
||||
public static function addView($user, $goods)
|
||||
{
|
||||
if ($user) {
|
||||
$view = self::views()->where('user_id', $user->id)->where('goods_id', $goods->id)->find();
|
||||
if ($view) {
|
||||
$view->updatetime = time();
|
||||
$view->save();
|
||||
} else {
|
||||
$view = new self();
|
||||
$data = [
|
||||
'goods_id' => $goods->id,
|
||||
'user_id' => $user->id,
|
||||
'type' => 'views'
|
||||
];
|
||||
$view->save($data);
|
||||
}
|
||||
}
|
||||
// 增加商品浏览量
|
||||
Goods::where('id', $goods['id'])->update(['views' => \think\Db::raw('views+1')]);
|
||||
}
|
||||
|
||||
public function scopeFavorite($query)
|
||||
{
|
||||
return $query->where('type', 'favorite');
|
||||
}
|
||||
|
||||
|
||||
public function scopeViews($query) // view 和底层方法冲突了
|
||||
{
|
||||
return $query->where('type', 'views');
|
||||
}
|
||||
|
||||
|
||||
public function goods()
|
||||
{
|
||||
return $this->belongsTo(Goods::class, 'goods_id');
|
||||
}
|
||||
}
|
||||
25
application/admin/model/shopro/user/Invoice.php
Normal file
25
application/admin/model/shopro/user/Invoice.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\user;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class Invoice extends Common
|
||||
{
|
||||
protected $name = 'shopro_user_invoice';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text',
|
||||
];
|
||||
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return [
|
||||
'person' => '个人',
|
||||
'company' => '企/事业单位',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
136
application/admin/model/shopro/user/User.php
Normal file
136
application/admin/model/shopro/user/User.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\user;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use app\admin\model\shopro\Coupon as CouponModel;
|
||||
use app\admin\model\shopro\ThirdOauth;
|
||||
use addons\shopro\library\notify\traits\Notifiable;
|
||||
use fast\Random;
|
||||
|
||||
class User extends Common
|
||||
{
|
||||
use Notifiable;
|
||||
|
||||
protected $name = 'user';
|
||||
|
||||
protected $type = [
|
||||
'logintime' => 'timestamp',
|
||||
'jointime' => 'timestamp',
|
||||
'prevtime' => 'timestamp',
|
||||
];
|
||||
|
||||
protected $hidden = ['password', 'salt'];
|
||||
|
||||
protected $append = [
|
||||
'status_text',
|
||||
'gender_text'
|
||||
];
|
||||
|
||||
|
||||
public function getGenderList()
|
||||
{
|
||||
return ['1' => __('Male'), '0' => __('Female')];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取性别文字
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return object
|
||||
*/
|
||||
public function getGenderTextAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['gender'] ?? 0);
|
||||
|
||||
$list = $this->getGenderList();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
|
||||
public function setMobileAttr($value, $data)
|
||||
{
|
||||
if ($value !== "") {
|
||||
return $value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setUsernameAttr($value, $data)
|
||||
{
|
||||
if ($value !== "") {
|
||||
return $value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAvatarAttr($value, $data)
|
||||
{
|
||||
if (empty($value)) {
|
||||
$config = sheep_config('shop.user');
|
||||
$value = $config['avatar'];
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function setEmailAttr($value, $data)
|
||||
{
|
||||
if ($value !== "") {
|
||||
return $value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setPasswordAttr($value, $data)
|
||||
{
|
||||
$salt = Random::alnum();
|
||||
$this->salt = $salt;
|
||||
return \app\common\library\Auth::instance()->getEncryptPassword($value, $salt);
|
||||
}
|
||||
|
||||
public function getNicknameHideAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['nickname'] ?? '');
|
||||
|
||||
return $value ? string_hide($value, 2) : $value;
|
||||
}
|
||||
|
||||
|
||||
public function getMobileAttr($value, $data)
|
||||
{
|
||||
$value = $value ?: ($data['mobile'] ?? '');
|
||||
|
||||
return $value ? (operate_filter(false) ? $value : account_hide($value, 3, 3)) : $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取验证字段数组值
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return object
|
||||
*/
|
||||
public function getVerificationAttr($value, $data)
|
||||
{
|
||||
$value = array_filter((array)json_decode($value, true));
|
||||
$value = array_merge(['username' => 0, 'password' => 0, 'mobile' => 0], $value);
|
||||
return (object)$value;
|
||||
}
|
||||
|
||||
public function parentUser()
|
||||
{
|
||||
return $this->hasOne(User::class, 'id', 'parent_user_id')->field(['id', 'avatar', 'nickname', 'gender']);
|
||||
}
|
||||
|
||||
public function thirdOauth()
|
||||
{
|
||||
return $this->hasMany(ThirdOauth::class, 'user_id', 'id');
|
||||
}
|
||||
|
||||
|
||||
// -- commission code start --
|
||||
public function agent()
|
||||
{
|
||||
return $this->hasOne(\app\admin\model\shopro\commission\Agent::class, 'user_id', 'id');
|
||||
}
|
||||
// -- commission code end --
|
||||
}
|
||||
79
application/admin/model/shopro/user/WalletLog.php
Normal file
79
application/admin/model/shopro/user/WalletLog.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\user;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
|
||||
class WalletLog extends Common
|
||||
{
|
||||
protected $name = 'shopro_user_wallet_log';
|
||||
|
||||
protected $updateTime = false;
|
||||
|
||||
protected $type = [
|
||||
'ext' => 'json'
|
||||
];
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'event_text'
|
||||
];
|
||||
|
||||
const TYPE_MAP = [
|
||||
'money' => '余额',
|
||||
'score' => '积分',
|
||||
'commission' => '佣金'
|
||||
];
|
||||
|
||||
protected $eventMap = [
|
||||
'score' => [
|
||||
'signin' => '签到-赠送积分',
|
||||
'replenish_signin' => '签到-补签',
|
||||
'activity_gift' => '活动-赠送积分',
|
||||
'score_shop_pay' => '积分商城-积分支付',
|
||||
'order_pay' => '商城订单-积分抵扣',
|
||||
'order_refund' => '订单退款-退还积分',
|
||||
'admin_recharge' => '后台-积分充值',
|
||||
'recharge_gift' => '线上充值-赠送积分'
|
||||
],
|
||||
'money' => [
|
||||
'order_pay' => '商城订单-余额支付',
|
||||
'order_recharge' => '线上充值',
|
||||
'admin_recharge' => '后台-余额充值',
|
||||
'recharge_gift' => '线上充值-赠送余额',
|
||||
'activity_gift' => '活动-赠送余额',
|
||||
'order_refund' => '订单退款-退还余额',
|
||||
'transfer_by_commission' => '佣金-转入到余额'
|
||||
],
|
||||
'commission' => [
|
||||
'withdraw' => '提现',
|
||||
'withdraw_error' => '提现失败-返还佣金',
|
||||
'reward_income' => '佣金-收益',
|
||||
'reward_back' => '佣金-退还',
|
||||
'transfer_to_money' => '佣金-转出到余额'
|
||||
]
|
||||
];
|
||||
|
||||
public function getEventMap() {
|
||||
return $this->eventMap;
|
||||
}
|
||||
|
||||
public function scopeMoney($query)
|
||||
{
|
||||
return $query->where('type', 'money');
|
||||
}
|
||||
|
||||
public function scopeCommission($query)
|
||||
{
|
||||
return $query->where('type', 'commission');
|
||||
}
|
||||
|
||||
public function scopeScore($query)
|
||||
{
|
||||
return $query->where('type', 'score');
|
||||
}
|
||||
|
||||
public function getEventTextAttr($value, $data)
|
||||
{
|
||||
return $this->eventMap[$data['type']][$data['event']] ?? '';
|
||||
}
|
||||
}
|
||||
28
application/admin/model/shopro/wechat/Material.php
Normal file
28
application/admin/model/shopro/wechat/Material.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\wechat;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
|
||||
class Material extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $name = 'shopro_wechat_material';
|
||||
|
||||
protected $type = [
|
||||
'content' => 'json',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text'
|
||||
];
|
||||
|
||||
public function typeList()
|
||||
{
|
||||
return ['text' => '文字', 'link' => '链接'];
|
||||
}
|
||||
}
|
||||
31
application/admin/model/shopro/wechat/Menu.php
Normal file
31
application/admin/model/shopro/wechat/Menu.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\wechat;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
|
||||
class Menu extends Common
|
||||
{
|
||||
protected $name = 'shopro_wechat_menu';
|
||||
|
||||
protected $type = [
|
||||
'rules' => 'json',
|
||||
'publishtime' => 'timestamp',
|
||||
];
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'status_text'
|
||||
];
|
||||
|
||||
/**
|
||||
* 状态列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function statusList()
|
||||
{
|
||||
return [0 => '未发布', 1 => '已发布'];
|
||||
}
|
||||
}
|
||||
63
application/admin/model/shopro/wechat/Reply.php
Normal file
63
application/admin/model/shopro/wechat/Reply.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model\shopro\wechat;
|
||||
|
||||
use app\admin\model\shopro\Common;
|
||||
use traits\model\SoftDelete;
|
||||
|
||||
class Reply extends Common
|
||||
{
|
||||
use SoftDelete;
|
||||
protected $deleteTime = 'deletetime';
|
||||
|
||||
protected $name = 'shopro_wechat_reply';
|
||||
|
||||
// 追加属性
|
||||
protected $append = [
|
||||
'type_text',
|
||||
'group_text',
|
||||
'status_text',
|
||||
];
|
||||
|
||||
|
||||
public function getKeywordsAttr($value, $data)
|
||||
{
|
||||
if (!empty($value)) {
|
||||
return explode(',', $value);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public function setKeywordsAttr($value, $data)
|
||||
{
|
||||
if (!empty($value)) {
|
||||
return implode(',', $value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 状态列表
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function typeList()
|
||||
{
|
||||
return ['text' => '文字', 'link' => '链接', 'image' => '图片', 'voice' => '语音', 'video' => '视频', 'news' => '图文消息'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用类型获取器
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getGroupTextAttr($value, $data)
|
||||
{
|
||||
$list = ['keywords' => '关键词回复', 'subscribe' => '关注回复', 'default' => '默认回复'];
|
||||
|
||||
$value = $value ?: ($data['group'] ?? null);
|
||||
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user