chore: 添加静态资源文件和版本配置文件

添加大量图片、字体、音频等静态资源文件,包括用户界面图片、模板文件和安装界面素材
添加系统版本配置文件(.version)和常量定义文件(.constant)
更新供应商依赖文件,包括Symfony VarDumper组件和相关许可证文件
添加验证码配置文件(captcha.php)和.gitignore规则
This commit is contained in:
2026-03-06 20:14:23 +08:00
commit c9a98f342c
4485 changed files with 490986 additions and 0 deletions

71
app/AppService.php Normal file
View File

@@ -0,0 +1,71 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app;
use app\listener\wechat\OffcialAccountListener;
use app\listener\wechat\RoutineListener;
use app\listener\wechat\WorkListener;
use crmeb\services\SystemConfigService;
use app\services\work\WorkConfigServices;
use crmeb\services\GroupDataService;
use crmeb\services\wechat\config\HttpCommonConfig;
use crmeb\services\wechat\MiniProgram;
use crmeb\services\wechat\OfficialAccount;
use crmeb\services\wechat\Work;
use crmeb\utils\Json;
use think\Service;
use app\services\system\config\SystemConfigServices;
/**
* Class AppService
* @package app
*/
class AppService extends Service
{
public $bind = [
'json' => Json::class,
'sysConfig' => SystemConfigService::class,
'sysGroupData' => GroupDataService::class
];
public function boot()
{
defined('DS') || define('DS', DIRECTORY_SEPARATOR);
}
/**
* 注册
*/
public function register()
{
//http配置服务
$this->app->bind(HttpCommonConfig::class, function () {
return (new HttpCommonConfig())->setServe(SystemConfigServices::class);
});
//公众号
$this->app->bind(OfficialAccount::class, function () {
return (new OfficialAccount)->setPushMessageHandler(OffcialAccountListener::class);
});
//小程序
$this->app->bind(MiniProgram::class, function () {
return (new MiniProgram)->setPushMessageHandler(RoutineListener::class);
});
//企业微信
$this->app->bind(Work::class, function () {
return (new Work)->setPushMessageHandler(WorkListener::class)
->setConfigHandler(WorkConfigServices::class);
});
}
}

111
app/ExceptionHandle.php Normal file
View File

@@ -0,0 +1,111 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app;
use crmeb\exceptions\AdminException;
use crmeb\exceptions\ApiException;
use crmeb\exceptions\AuthException;
use crmeb\exceptions\PayException;
use crmeb\exceptions\TemplateException;
use crmeb\exceptions\UploadException;
use crmeb\exceptions\WechatReplyException;
use crmeb\services\wechat\WechatException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\facade\Env;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
AdminException::class,
UploadException::class,
PayException::class,
ApiException::class,
TemplateException::class,
AuthException::class
];
/**
* 记录异常信息(包括日志或者其它方式记录)
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
if (!$this->isIgnoreReport($exception)) {
$data = [
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'message' => $this->getMessage($exception),
'code' => $this->getCode($exception),
];
response_log_write($data);
}
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
$massageData = Env::get('app_debug', false) ? [
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTrace(),
'previous' => $e->getPrevious(),
] : [];
// 添加自定义异常处理机制
if ($e instanceof DbException) {
return app('json')->fail('数据获取失败:' . $e->getMessage(), $massageData);
} elseif ($e instanceof AuthException ||
$e instanceof ValidateException ||
$e instanceof ApiException ||
$e instanceof PayException ||
$e instanceof TemplateException ||
$e instanceof UploadException ||
$e instanceof WechatReplyException ||
$e instanceof AdminException ||
$e instanceof WechatException
) {
return app('json')->make($e->getCode() ?: 400, $e->getMessage(), $massageData);
} else {
return app('json')->code(500)->make(400, $e->getMessage(), $massageData);
}
}
}

277
app/Request.php Normal file
View File

@@ -0,0 +1,277 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app;
use crmeb\traits\Macroable;
/**
* Class Request
* @package app
* @method tokenData() 获取token信息
* @method user(string $key = null) 获取用户信息
* @method uid() 获取用户uid
* @method isAdminLogin() 后台登陆状态
* @method adminId() 后台管理员id
* @method adminInfo() 后台管理信息
* @method adminType() 后台管理类型
* @method kefuId() 客服id
* @method kefuInfo() 客服信息
* @method outId() 对外接口用户id
* @method outInfo() 对外接口用户id
* @method storeId() 门店ID
* @method storeStaffId() 门店管理员id
* @method storeStaffInfo() 门店管理员信息
* @method cashierId() 门店收银员id
* @method cashierInfo() 门店收银员信息
* @method clientInfo() 企业微信客户信息
* @method userid() 企业微信客户userid
* @method supplierId() 供应商id
* @method supplierInfo() 供应商信息
*/
class Request extends \think\Request
{
public $tokenData; //获取token信息
public $user; //获取用户信息
public $uid; //获取用户uid
public $isLogin;
public $isAdminLogin; //后台登陆状态
public $adminId; //后台管理员id
public $adminInfo; //后台管理信息
public $adminType; //后台管理类型
public $kefuId; //客服id
public $kefuInfo; //客服信息
public $outId; //对外接口用户id
public $outInfo; //对外接口用户id
public $storeId; //门店ID
public $storeStaffId; //门店管理员id
public $storeStaffInfo; //门店管理员信息
public $cashierId; //门店收银员id
public $cashierInfo; //门店收银员信息
public $clientInfo; //企业微信客户信息
public $userid; //企业微信客户userid
public $supplierId; //供应商id
public $supplierInfo; //供应商信息
/**
* 登录保存参数
* @var array
*/
protected $loginParam = [
'tokenData', 'user', 'uid', 'isLogin',
'isAdminLogin', 'adminId', 'adminInfo',
'kefuId', 'kefuInfo',
'outId', 'outInfo',
'storeId', 'storeStaffId', 'storeStaffInfo',
'cashierId', 'cashierInfo',
'clientInfo', 'userid',
'supplierId', 'supplierInfo', 'adminType'
];
/**
* 不过滤变量名
* @var array
*/
protected array $except = [
'menu_path', 'api_url', 'unique_auth',
'description', 'custom_form', 'product_detail_diy', 'member', 'product_category_diy', 'value','val'
];
/**
* 获取请求的数据
* @param array $params
* @param bool $suffix
* @param bool $filter
* @return array
*/
public function more(array $params, bool $suffix = false, bool $filter = true): array
{
$p = [];
$i = 0;
foreach ($params as $param) {
if (!is_array($param)) {
$p[$suffix == true ? $i++ : $param] = $this->param($param);
} else {
if (!isset($param[1])) $param[1] = null;
if (!isset($param[2])) $param[2] = '';
if (is_array($param[0])) {
$name = is_array($param[1]) ? $param[0][0] . '/a' : $param[0][0] . '/' . $param[0][1];
$keyName = $param[0][0];
} else {
$name = is_array($param[1]) ? $param[0] . '/a' : $param[0];
$keyName = $param[0];
}
$p[$suffix == true ? $i++ : ($param[3] ?? $keyName)] = $this->param($name, $param[1], $param[2]);
}
}
if ($filter && $p) {
$p = $this->filterArrayValues($p);
}
return $p;
}
/**
* @param $array
* @return array
*/
public function filterArrayValues($array)
{
$result = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
// 如果值是数组,递归调用 filterArrayValues
$result[$key] = in_array($key, $this->except) ? $value : $this->filterArrayValues($value);
} else {
if (in_array($key, $this->except) || is_int($value) || is_null($value)) {
$result[$key] = $value;
} else {
// 如果值是字符串,过滤特殊字符
$result[$key] = filter_str($value);
}
}
}
return $result;
}
/**
* 获取get参数
* @param array $params
* @param bool $suffix
* @param bool $filter
* @return array
*/
public function getMore(array $params, bool $suffix = false, bool $filter = true): array
{
return $this->more($params, $suffix, $filter);
}
/**
* 获取post参数
* @param array $params
* @param bool $suffix
* @param bool $filter
* @return array
*/
public function postMore(array $params, bool $suffix = false, bool $filter = true): array
{
return $this->more($params, $suffix, $filter);
}
/**
* 获取用户访问端
* @return array|string|null
*/
public function getFromType()
{
return $this->header('Form-type', '');
}
/**
* 当前访问端
* @param string $terminal
* @return bool
*/
public function isTerminal(string $terminal)
{
return strtolower($this->getFromType()) === $terminal;
}
/**
* 是否是H5端
* @return bool
*/
public function isH5()
{
return $this->isTerminal('h5');
}
/**
* 是否是微信端
* @return bool
*/
public function isWechat()
{
return $this->isTerminal('wechat');
}
/**
* 是否是小程序端
* @return bool
*/
public function isRoutine()
{
return $this->isTerminal('routine');
}
/**
* 是否是app端
* @return bool
*/
public function isApp()
{
return $this->isTerminal('app');
}
/**
* 是否是app端
* @return bool
*/
public function isPc()
{
return $this->isTerminal('pc');
}
/**
* 获取ip
* @return string
*/
public function ip(): string
{
if ($this->server('HTTP_CLIENT_IP', '')) {
$ip = $this->server('HTTP_CLIENT_IP', '');
} elseif ($this->server('HTTP_X_REAL_IP', '')) {
$ip = $this->server('HTTP_X_REAL_IP', '');
} elseif ($this->server('HTTP_X_FORWARDED_FOR', '')) {
$ip = $this->server('HTTP_X_FORWARDED_FOR', '');
$ips = explode(',', $ip);
$ip = $ips[0];
} elseif ($this->server('REMOTE_ADDR', '')) {
$ip = $this->server('REMOTE_ADDR', '');
} else {
$ip = '0.0.0.0';
}
return $ip;
}
public function hasMacro(string $name): bool
{
return !!$this->{$name};
}
public function __call($method, $parameters)
{
if (in_array($method, $this->loginParam)) {
$result = $this->{$method};
if (is_callable($result)) {
return call_user_func_array($result, $parameters);
} else {
return $result;
}
}
return null;
}
}

View File

@@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Log;
use think\facade\Cache;
use crmeb\services\CacheService;
use crmeb\services\FileService;
class ClearCache extends Command
{
protected function configure()
{
// 指令配置
$this->setName('clear:cache')
->setDescription('已删除缓存');
}
protected function execute(Input $input, Output $output)
{
try {
FileService::delDir(root_path() . 'runtime');
Cache::clear();
} catch (\Exception $e) {
Log::info('删除缓存错误:' . $e->getMessage());
}
$output->info('执行成功:已删除缓存');
}
}

View File

@@ -0,0 +1,64 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Argument;
use think\console\input\Option;
use app\services\system\admin\SystemAdminServices;
/**
* 重置密码
* Class ResetAdminPwd
* @package app\command
*/
class ResetAdminPwd extends Command
{
protected function configure()
{
// 指令配置
$this->setName('reset:password')
->addArgument('root', Argument::OPTIONAL, '管理员账号', 'admin')
->addOption('pwd', null, Option::VALUE_REQUIRED, '重置密码', '123456')
->setDescription('the update resetPwd command');
}
/**
* @param Input $input
* @param Output $output
* @return int|void|null
*/
protected function execute(Input $input, Output $output)
{
$account = $input->getArgument('root');
if ($input->hasOption('pwd')) {
$pwd = $input->getOption('pwd');
}
/** @var SystemAdminServices $systemAdminServices */
$systemAdminServices = app()->make(SystemAdminServices::class);
$admin = $systemAdminServices->get(['account' => $account, 'status' => 1, 'is_del' => 0]);
if (!$admin) {
$output->warning('管理员账号不存在');
} else {
$pwd_ = $systemAdminServices->passwordHash($pwd);
$admin->pwd = $pwd_;
$admin->save();
$output->info('账号:' . $account . ';密码已重置:' . $pwd);
}
}
}

83
app/command/Timer.php Normal file
View File

@@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Db;
/**
* 定时任务基类
* Class Timer
* @package app\command
*/
class Timer extends Command
{
/**
* 配置指令
*/
protected function configure()
{
// 指令配置
$this->setName('timer')
->setDescription('定时任务');
}
/**
* 执行指令
* @param Input $input
* @param Output $output
* @return int
*/
protected function execute(Input $input, Output $output)
{
$this->task($output);
return 0;
}
/**
* 定时任务
* @param Output $output
*/
protected function task(Output $output)
{
$time = time();
$prefix = config('database.connections.' . config('database.default') . '.prefix');
$list = Db::name('system_timer')->where('is_open', 1)->select();
if (!$list) return;
foreach ($list as $item) {
if ($time < $item['last_execution_time'] + $item['execution_cycle']) {
continue;
}
$output->writeln('执行定时任务:' . $item['name']);
$this->runTimer($item['command'], $output);
Db::name('system_timer')->where('id', $item['id'])->update(['last_execution_time' => time()]);
}
}
/**
* 执行定时任务
* @param string $command
* @param Output $output
*/
protected function runTimer(string $command, Output $output)
{
$class = '\\app\\command\\' . $command;
if (class_exists($class)) {
try {
/** @var Command $instance */
$instance = app()->make($class);
$instance->run(new Input([]), $output);
} catch (\Throwable $e) {
$output->writeln('执行定时任务失败:' . $e->getMessage());
}
} else {
$output->writeln('定时任务不存在:' . $command);
}
}
}

847
app/common.php Normal file
View File

@@ -0,0 +1,847 @@
<?php
use app\Request;
use crmeb\services\SystemConfigService;
use crmeb\services\UploadService;
use Fastknife\Service\BlockPuzzleCaptchaService;
use Fastknife\Service\ClickWordCaptchaService;
use think\exception\ValidateException;
use think\facade\Config;
use think\facade\Log;
if (!function_exists('get_tree_value')) {
/**
* 获取
* @param array $data
* @param int|string $value
* @return array
*/
function get_tree_value(array $data, $value, array &$childrenValue = [])
{
foreach ($data as &$item) {
if ($item['value'] == $value) {
$childrenValue[] = $item['value'];
if ($item['pid']) {
$value = $item['pid'];
unset($item);
return get_tree_value($data, $value, $childrenValue);
}
}
}
return $childrenValue;
}
}
if (!function_exists('is_brokerage_statu')) {
/**
* 是否能成为推广人
* @param float $price
* @return bool
*/
function is_brokerage_statu(float $price)
{
if (!sys_config('brokerage_func_status')) {
return false;
}
$storeBrokerageStatus = sys_config('store_brokerage_statu', 1);
if ($storeBrokerageStatus == 1) {
return false;
} else if ($storeBrokerageStatus == 2) {
return false;
} else {
$storeBrokeragePrice = sys_config('store_brokerage_price', 0);
return $price >= $storeBrokeragePrice;
}
}
}
if (!function_exists('time_tran')) {
/**
* 时间戳人性化转化
* @param $time
* @return string
*/
function time_tran($time)
{
$t = time() - $time;
$f = array(
'31536000' => '年',
'2592000' => '个月',
'604800' => '星期',
'86400' => '天',
'3600' => '小时',
'60' => '分钟',
'1' => '秒'
);
foreach ($f as $k => $v) {
if (0 != $c = floor($t / (int)$k)) {
return $c . $v . '前';
}
}
}
}
if (!function_exists('url_to_path')) {
/**
* url转换路径
* @param $url
* @return string
*/
function url_to_path($url)
{
$path = trim(str_replace('/', DS, $url), DS);
if (0 !== strripos($path, 'public'))
$path = 'public' . DS . $path;
return app()->getRootPath() . $path;
}
}
if (!function_exists('path_to_url')) {
/**
* 路径转url路径
* @param $path
* @return string
*/
function path_to_url($path)
{
return trim(str_replace(DS, '/', $path), '.');
}
}
if (!function_exists('get_image_thumb')) {
/**
* 获取缩略图
* @param $filePath
* @param string $type all|big|mid|small
* @param bool $is_remote_down
* @return mixed|string|string[]
*/
function get_image_thumb($filePath, string $type = 'all', bool $is_remote_down = false)
{
if (!sys_config('image_thumb_status')) return $filePath;
if (!$filePath || !is_string($filePath) || strpos($filePath, '?') !== false) return $filePath;
try {
$upload = UploadService::getOssInit($filePath, $is_remote_down);
$data = $upload->thumb('', $type);
$image = $type == 'all' ? $data : $data[$type] ?? $filePath;
} catch (\Throwable $e) {
$image = $filePath;
// throw new ValidateException($e->getMessage());
\think\facade\Log::error('获取缩略图失败,原因:' . $e->getMessage() . '----' . $e->getFile() . '----' . $e->getLine() . '----' . $filePath);
}
$data = parse_url($image);
if (!isset($data['host']) && (substr($image, 0, 2) == './' || substr($image, 0, 1) == '/')) {//不是完整地址
$image = sys_config('site_url') . $image;
}
//请求是https 图片是http 需要改变图片地址
if (strpos(request()->domain(), 'https:') !== false && strpos($image, 'https:') === false) {
$image = str_replace('http:', 'https:', $image);
}
return $image;
}
}
if (!function_exists('get_thumb_water')) {
/**
* 处理数组获取缩略图、水印
* @param $list
* @param string $type
* @param array|string[] $field 1、['image','images'] type 取值参数:type 2、['small'=>'image','mid'=>'images'] type 取field数组的key
* @param bool $is_remote_down
* @return array|mixed|string|string[]
*/
function get_thumb_water($list, string $type = 'small', array $field = ['image'], bool $is_remote_down = false)
{
if (!$list || !$field) return $list;
$baseType = $type;
$data = $list;
if (is_string($list)) {
$field = [$type => 'image'];
$data = ['image' => $list];
}
if (is_array($data)) {
foreach ($field as $type => $key) {
if (is_integer($type)) {//索引数组,默认type
$type = $baseType;
}
//一维数组
if (isset($data[$key])) {
if (is_array($data[$key])) {
$path_data = [];
foreach ($data[$key] as $k => $path) {
$path_data[] = get_image_thumb($path, $type, $is_remote_down);
}
$data[$key] = $path_data;
} else {
$data[$key] = get_image_thumb($data[$key], $type, $is_remote_down);
}
} else {
foreach ($data as &$item) {
if (!isset($item[$key]))
continue;
if (is_array($item[$key])) {
$path_data = [];
foreach ($item[$key] as $k => $path) {
$path_data[] = get_image_thumb($path, $type, $is_remote_down);
}
$item[$key] = $path_data;
} else {
$item[$key] = get_image_thumb($item[$key], $type, $is_remote_down);
}
}
}
}
}
return is_string($list) ? ($data['image'] ?? '') : $data;
}
}
if (!function_exists('put_image')) {
/**
* 获取图片转为base64
* @param $url
* @param string $filename
* @return bool|string
*/
function put_image($url, string $filename = '')
{
if ($url == '') {
return false;
}
try {
if ($filename == '') {
$ext = pathinfo($url);
if ($ext['extension'] != "jpg" && $ext['extension'] != "png" && $ext['extension'] != "jpeg") {
return false;
}
$filename = time() . "." . $ext['extension'];
}
$pathArr = parse_url($url);
$path = $pathArr['path'] ?? '';
if ($path && file_exists(public_path() . trim($path, '/'))) {
return $path;
} else {
//文件保存路径
ob_start();
$url = str_replace('phar://', '', $url);
readfile($url);
$img = ob_get_contents();
ob_end_clean();
$path = 'uploads/qrcode';
$fp2 = fopen(public_path() . $path . '/' . $filename, 'a');
fwrite($fp2, $img);
fclose($fp2);
return $path . '/' . $filename;
}
} catch (\Exception $e) {
return false;
}
}
}
if (!function_exists('make_path')) {
/**
* 上传路径转化,默认路径
* @param $path
* @param int $type
* @param bool $force
* @return string
* @throws Exception
*/
function make_path($path, int $type = 2, bool $force = false)
{
$path = DS . ltrim(rtrim($path));
switch ($type) {
case 1:
$path .= DS . date('Y');
break;
case 2:
$path .= DS . date('Y') . DS . date('m');
break;
case 3:
$path .= DS . date('Y') . DS . date('m') . DS . date('d');
break;
}
try {
if (is_dir(app()->getRootPath() . 'public' . DS . 'uploads' . $path) == true || mkdir(app()->getRootPath() . 'public' . DS . 'uploads' . $path, 0777, true) == true) {
return trim(str_replace(DS, '/', $path), '.');
} else return '';
} catch (\Exception $e) {
if ($force)
throw new \Exception($e->getMessage());
return '无法创建文件夹,请检查您的上传目录权限:' . app()->getRootPath() . 'public' . DS . 'uploads' . DS . 'attach' . DS;
}
}
}
if (!function_exists('check_phone')) {
/**
* 手机号验证
* @param $phone
* @return false|int
*/
function check_phone($phone)
{
return preg_match("/^1[3456789]\d{9}$/", $phone);
}
}
if (!function_exists('check_mail')) {
/**
* 邮箱验证
* @param $mail
* @return false|int
*/
function check_mail($mail)
{
if (filter_var($mail, FILTER_VALIDATE_EMAIL)) {
return true;
} else {
return false;
}
}
}
if (!function_exists('aj_captcha_check_one')) {
/**
* 验证滑块1次验证
* @param string $captchaType
* @param string $token
* @param string $pointJson
* @return bool
*/
function aj_captcha_check_one(string $captchaType, string $token, string $pointJson)
{
aj_get_serevice($captchaType)->check($token, $pointJson);
return true;
}
}
if (!function_exists('aj_captcha_check_two')) {
/**
* 验证滑块2次验证
* @param string $captchaType
* @param string $captchaVerification
* @return bool
*/
function aj_captcha_check_two(string $captchaType, string $captchaVerification)
{
aj_get_serevice($captchaType)->verificationByEncryptCode($captchaVerification);
return true;
}
}
if (!function_exists('aj_captcha_create')) {
/**
* 创建验证码
* @return array
*/
function aj_captcha_create(string $captchaType)
{
return aj_get_serevice($captchaType)->get();
}
}
if (!function_exists('aj_get_serevice')) {
/**
* @param string $captchaType
* @return ClickWordCaptchaService|BlockPuzzleCaptchaService
*/
function aj_get_serevice(string $captchaType)
{
$config = Config::get('ajcaptcha');
switch ($captchaType) {
case "clickWord":
$service = new ClickWordCaptchaService($config);
break;
case "blockPuzzle":
$service = new BlockPuzzleCaptchaService($config);
break;
default:
throw new ValidateException('captchaType参数不正确!');
}
return $service;
}
}
if (!function_exists('mb_substr_str')) {
/**
* 截取制定长度,并使用填充
* @param string $value
* @param int $length
* @param string $str
* @return string
* @author 等风来
* @email 136327134@qq.com
* @date 2022/12/1
*/
function mb_substr_str(string $value, int $length, string $str = '...', int $type = 0)
{
if (mb_strlen($value) > $length) {
$value = mb_substr($value, 0, $length - mb_strlen($str)) . $str;
}
//等于1时去掉数组
if ($type === 1) {
$value = preg_replace('/[0-9]/', '', $value);
}
return $value;
}
}
if (!function_exists('response_log_write')) {
/**
* 日志写入
* @param mixed $data
* @param string $logType
* @param string $type
* @param mixed $id
* @author 等风来
* @email 136327134@qq.com
* @date 2023/10/8
*/
function response_log_write(mixed $data, string $logType = \think\Log::ERROR, string $type = '', mixed $id = 0)
{
$request = app()->make(Request::class);
try {
if (!$type || !$id) {
foreach ([
'adminId' => 'admin',
'kefuId' => 'kefu',
'uid' => 'user',
'supplierId' => 'supplier',
'cashierId' => 'cashier',
'storeId' => 'store',
'outId' => 'out',
] as $value => $vv) {
if ($request->hasMacro($value)) {
$id = $request->{$value}();
$type = $vv;
}
}
}
//日志内容
$log = [
$id,//管理员ID
$type,
$request->ip(),//客户ip
ceil(msectime() - ($request->time(true) * 1000)),//耗时(毫秒)
$request->method(true),//请求类型
str_replace("/", "", $request->rootUrl()),//应用
$request->baseUrl(),//路由
json_encode($request->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),//请求参数
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),//报错数据
];
Log::write(implode("|", $log), $logType);
} catch (\Throwable $e) {
$data = [
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTrace(),
'previous' => $e->getPrevious(),
];
Log::error(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
}
}
}
if (!function_exists('stringToIntArray')) {
/**
* 处理ids等并过滤参数
* @param $string
* @param string $separator
* @return array
*/
function stringToIntArray(string $string, string $separator = ',')
{
return !empty($string) ? array_unique(array_diff(array_map('intval', explode($separator, $string)), [0])) : [];
}
}
if (!function_exists('image_to_base64')) {
/**
* 获取图片转为base64
* @param string $avatar
* @return bool|string
*/
function image_to_base64($avatar = '', $timeout = 9)
{
try {
if (file_exists($avatar)) {
$app_img_file = $avatar; // 图片路径
$img_info = getimagesize($app_img_file); // 取得图片的大小,类型等
$fp = fopen($app_img_file, "r"); // 图片是否可读权限
$img_base64 = '';
if ($fp) {
$filesize = filesize($app_img_file);
$content = fread($fp, $filesize);
$file_content = chunk_split(base64_encode($content)); // base64编码
switch ($img_info[2]) { //判读图片类型
case 1:
$img_type = "gif";
break;
case 2:
$img_type = "jpg";
break;
case 3:
$img_type = "png";
break;
}
$img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;//合成图片的base64编码
}
fclose($fp);
return $img_base64;
} else {
$avatar = str_replace('https', 'http', $avatar);
$url = parse_url($avatar);
$path = $url['path'] ?? '';
$urlPath = public_path() . $url['path'];
//本地文件直接读取返回
if (is_file($urlPath)) {
$imageType = pathinfo($path)['extension'] ?? 'jpeg';
return 'data:image/' . $imageType . ';base64,' . base64_encode(file_get_contents($urlPath));
}
$url = $url['host'];
$header = [
'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0',
'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Accept-Encoding: gzip, deflate, br',
'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Host:' . $url
];
$dir = pathinfo($url);
$host = $dir['dirname'];
$refer = $host . '/';
$curl = curl_init();
curl_setopt($curl, CURLOPT_REFERER, $refer);
curl_setopt($curl, CURLOPT_URL, $avatar);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
$data = curl_exec($curl);
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($code == 200) {
return "data:image/jpeg;base64," . base64_encode($data);
} else {
return false;
}
}
} catch (\Exception $e) {
return false;
}
}
}
if (!function_exists('supplier_config')) {
/**
* @param int $supplierId
* @param string $name
* @param null $default
* @return array|string|null
*/
function supplier_config(int $supplierId, string $name, $default = null)
{
if (empty($name)) {
return $default;
}
/** @var SystemConfigService $configService */
$configService = app('sysConfig');
$configService->setSupplier($supplierId);
$sysConfig = $configService->get($name);
if (is_array($sysConfig)) {
foreach ($sysConfig as &$item) {
if (strpos($item, '/uploads/system/') !== false) {
$item = set_file_url($item);
}
}
} else {
if (strpos($sysConfig, '/uploads/system/') !== false) {
$sysConfig = set_file_url($sysConfig);
}
}
$config = is_array($sysConfig) ? $sysConfig : trim($sysConfig);
if ($config === '' || $config === false) {
return $default;
} else {
return $config;
}
}
}
if (!function_exists('getFileHeaders')) {
/**
* 获取文件大小头部信息
* @param string $url
* @param $isData
* @return array
*/
function getFileHeaders(string $url, $isData = true)
{
stream_context_set_default(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]);
$header['size'] = 0;
$header['type'] = 'image/jpeg';
if (!$isData) {
return $header;
}
try {
$headerArray = get_headers(str_replace('\\', '/', $url), true);
if (!isset($headerArray['Content-Length'])) {
$header['size'] = 0;
} else {
if (is_array($headerArray['Content-Length']) && count($headerArray['Content-Length']) == 2) {
$header['size'] = $headerArray['Content-Length'][1];
} else {
$header['size'] = $headerArray['Content-Length'] ?? 0;
}
}
if (!isset($headerArray['Content-Type'])) {
$header['type'] = 'image/jpeg';
} else {
if (is_array($headerArray['Content-Type']) && count($headerArray['Content-Type']) == 2) {
$header['type'] = $headerArray['Content-Type'][1];
} else {
$header['type'] = $headerArray['Content-Type'] ?? 'image/jpeg';
}
}
} catch (\Exception $e) {
}
return $header;
}
}
if (!function_exists('formatFileSize')) {
/**
* 格式化文件大小
* @param $size
* @return mixed|string|null
*/
function formatFileSize($size)
{
if (!$size) {
return '0KB';
}
try {
$toKb = 1024;
$toMb = $toKb * 1024;
$toGb = $toMb * 1024;
if ($size >= $toGb) {
return round($size / $toGb, 2) . 'GB';
} elseif ($size >= $toMb) {
return round($size / $toMb, 2) . 'MB';
} elseif ($size >= $toKb) {
return round($size / $toKb, 2) . 'KB';
} else {
return $size . 'B';
}
} catch (\Exception $e) {
return '0KB';
}
}
}
if (!function_exists('secsToStr')) {
/**
* 时间戳转成 n天n时n分
* @param int $secs
* @return string
*/
function secsToStr(int $secs): string
{
$r = '';
if (!$secs) return $r;
if ($secs >= 86400) {
$days = floor($secs / 86400);
$secs = $secs % 86400;
$r = $days . '天';
}
if ($secs >= 3600) {
$hours = floor($secs / 3600);
$secs = $secs % 3600;
$r .= $hours . '小时';
}
if ($secs >= 60) {
$minutes = floor($secs / 60);
$secs = $secs % 60;
$r .= $minutes . '分钟';
}
if ($secs) {
$r .= $secs . '秒';
}
return $r;
}
}
if (!function_exists('filter_str')) {
/**
* 过滤字符串敏感字符
* @param $str
* @return array|mixed|string|string[]|null
* @throws Exception
*/
function filter_str($str)
{
$param_filter_data = sys_config('param_filter_data');
$param_filter_type = sys_config('param_filter_type', 3);
$rules = preg_split('/\r\n|\r|\n/', base64_decode($param_filter_data));
if ($param_filter_data) {
switch ($param_filter_type) {
case 2://报错
foreach ($rules as $rule) {
if (preg_match($rule, $str)) {
throw new \Exception('您的参数存在非要请求,已被拦截');
}
}
break;
case 3://过滤
if (filter_var($str, FILTER_VALIDATE_URL)) {
$url = parse_url($str);
if (!isset($url['scheme'])) return $str;
$host = $url['scheme'] . '://' . $url['host'];
$str = $host . preg_replace($rules, '', str_replace($host, '', $str));
} else {
$str = preg_replace($rules, '', $str);
}
break;
}
}
return $str;
}
}
if (!function_exists('msectime')) {
/**
* 毫秒时间戳
*
* @return float
*/
function msectime()
{
[$mSec, $sec] = explode(' ', microtime());
return (float)sprintf('%.0f', (floatval($mSec) + floatval($sec)) * 1000);
}
}
if (!function_exists('timeConverter')) {
/**
* 一小时内【*分钟前】
* 1天内显示【*小时前】
* 跨天显示【*天前】
* 跨月显示【月份-日期】
* 跨年显示【年份-月份-日期】
* @param int $timestamp
* @return string
*/
function timeConverter(int $timestamp): string
{
$currentTime = time();
$timeDifference = $currentTime - $timestamp;
// 获取当前时间和时间戳对应的时间
$currentYear = date('Y', $currentTime);
$currentMonth = date('m', $currentTime);
$currentDay = date('d', $currentTime);
$timestampYear = date('Y', $timestamp);
$timestampMonth = date('m', $timestamp);
$timestampDay = date('d', $timestamp);
// 刚刚
if ($timeDifference < 60) {
return "刚刚";
}
// 几分钟前
if ($timeDifference < 3600) {
$minutesAgo = floor($timeDifference / 60);
return "{$minutesAgo}分钟前";
}
// 1天内:显示 *小时前
if ($timeDifference < 86400 && $currentDay == $timestampDay) {
$hoursAgo = floor($timeDifference / 3600);
return "{$hoursAgo}小时前";
}
// 跨天但在同一个月内:显示 *天前
if ($currentMonth == $timestampMonth && $currentYear == $timestampYear) {
$daysAgo = floor($timeDifference / 86400);
$daysAgo = $daysAgo > 0 ? $daysAgo : 1;
return "{$daysAgo}天前";
}
// 跨月但在同一年内:显示 月份-日期
if ($currentYear == $timestampYear) {
return date('m-d', $timestamp);
}
// 跨年:显示 年份-月份-日期
return date('Y-m-d', $timestamp);
}
}
if (!function_exists('checkCoordinates')) {
/**
* 检测经纬度数据
* @param $longitude
* @param $latitude
* @return bool
*/
function checkCoordinates($longitude, $latitude)
{
if ($longitude) {
$longitudePattern = '/^(-?\d{1,3}(?:\.\d+)?)$/'; // 经度,允许1到3位整数,后面跟着小数
if (!preg_match($longitudePattern, $longitude)) {
return false; // 经度格式不正确
}
// 检查经纬度是否在有效范围内
if (($longitude < -180) || ($longitude > 180)) {
return false; // 经度超出范围
}
}
if ($latitude) {
$latitudePattern = '/^[-+]?([0-8]?\d(\.\d+)?|90(\.0+)?)$/'; // 纬度,允许-90到90,包括小数部分
if (!preg_match($latitudePattern, $latitude)) {
return false; // 纬度格式不正确
}
if (($latitude < -90) || ($latitude > 90)) {
return false; // 纬度超出范围
}
}
// 如果所有检查都通过,则返回true
return true;
}
}
if (!function_exists('getAdminId')) {
function getAdminId()
{
return app()->request->hasMacro('adminId') ? (int)app()->request->adminId() : 0;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,101 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\common\controller;
use think\Response;
/**
* 退款
* Trait Recharge
* @package app\common\controller
*/
trait Recharge
{
/**
* 显示资源列表
*
* @return Response
*/
public function index(): Response
{
$where = $this->request->getMore([
['data', ''],
['paid', ''],
['nickname', ''],
]);
return $this->success($this->services->getRechargeList($where));
}
/**
* 删除指定资源
*
* @param int $id
* @return Response
*/
public function delete($id)
{
if (!$id || !is_numeric($id)) return $this->fail('缺少参数或参数类型错误');
return $this->success($this->services->delRecharge((int)$id) ? '删除成功' : '删除失败');
}
/**
* 获取用户充值数据
* @return Response
*/
public function user_recharge()
{
$where = $this->request->getMore([
['data', ''],
['paid', ''],
['nickname', ''],
]);
return $this->success($this->services->user_recharge($where));
}
/**
* 退款表单
* @param $id
* @return mixed
*/
public function refund_edit($id)
{
if (!$id || !is_numeric($id)) return $this->fail('数据不存在或参数类型错误');
return $this->success($this->services->refund_edit((int)$id));
}
/**
* 退款操作
* @param $id
* @return Response
*/
public function refund_update($id): Response
{
$data = $this->request->postMore([
'refund_price',
]);
// 类型验证
if (!$id || !is_numeric($id)) return $this->fail('数据不存在或参数类型错误');
if (!is_numeric($data['refund_price'])) return $this->fail('退款金额类型错误');
// 边界条件处理
if ($data['refund_price'] <= 0) return $this->fail('退款金额必须大于0');
try {
return $this->success($this->services->refund_update((int)$id, $data['refund_price']) ? '退款成功' : '退款失败');
} catch (\Exception $e) {
return $this->fail('退款处理异常: ' . $e->getMessage());
}
}
}

909
app/controller/Install.php Normal file
View File

@@ -0,0 +1,909 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller;
use app\Request;
class Install
{
/**
* 系统安装向导主入口
* @param Request $request
* @return string|\think\response\View
*/
public function index(Request $request)
{
$path = app()->getRootPath();
$step = app()->request->param('step') ?? 1;
$testdbpwd = app()->request->param('testdbpwd') ?? 0;
$install = app()->request->param('install') ?? 0;
$n = app()->request->param('n') ?? 0;
if (file_exists($path . 'public/install/install.lock')) {
return '你已经安装过该系统,如果想重新安装,请先删除install目录下的 install.lock 文件,然后再安装。';
}
@set_time_limit(1000);
if (phpversion() < '8.0.0' && '8.2.0' > phpversion()) {
return '您的php版本过低,不能安装本软件,php版本8.0,谢谢!';
}
if (phpversion() > '8.2') {
return '您的php版本太高,不能安装本软件,php版本8.0,谢谢!';
}
date_default_timezone_set('Asia/Shanghai');
error_reporting(E_ALL & ~E_NOTICE);
//数据库
$sqlFile = 'crmeb.sql';
$configFile = '.env';
if (!file_exists($path . 'public/install/' . $sqlFile) || !file_exists($path . 'public/install/' . $configFile)) {
return '缺少必要的安装文件!';
}
$Title = "CRMEB安装向导";
$Powered = "Powered by CRMEB";
switch ($step) {
case '1':
return view('/install/view/step1', [
'title' => $Title,
'powered' => $Powered
]);
case '2':
$phpv = @ phpversion();
$os = PHP_OS;
$tmp = function_exists('gd_info') ? gd_info() : array();
$server = request()->server("SERVER_SOFTWARE");
$safe_mode = (ini_get('safe_mode') ? '<font color=red>[×]On</font>' : '<font color=green>[√]Off</font>');
$err = 0;
if (empty($tmp['GD Version'])) {
$gd = '<font color=red>[×]Off</font>';
$err++;
} else {
$gd = '<font color=green>[√]On</font> ' . $tmp['GD Version'];
}
if (extension_loaded('redis')) {
$redis = '<span class="correct_span">&radic;</span> 已安装';
} else {
$redis = '<a href="http://help.crmeb.net/crmebpro/1702275" target="_blank"><span class="correct_span error_span">&radic;</span> 点击查看帮助</a>';
$err++;
}
if (extension_loaded('swoole_loader')) {
$swoole = '<span class="correct_span">&radic;</span> 已安装';
} else {
$swoole = '<a href="/install/compiler" target="_blank"><span class="correct_span error_span">&radic;</span> 点击查看帮助</a>';
$err++;
}
if (function_exists('mysqli_connect')) {
$mysql = '<span class="correct_span">&radic;</span> 已安装';
} else {
$mysql = '<span class="correct_span error_span">&radic;</span> 请安装mysqli扩展';
$err++;
}
if (ini_get('file_uploads')) {
$uploadSize = '<span class="correct_span">&radic;</span> ' . ini_get('upload_max_filesize');
} else {
$uploadSize = '<span class="correct_span error_span">&radic;</span>禁止上传';
}
if (function_exists('session_start')) {
$session = '<span class="correct_span">&radic;</span> 支持';
} else {
$session = '<span class="correct_span error_span">&radic;</span> 不支持';
$err++;
}
if (function_exists('curl_init')) {
$curl = '<font color=green>[√]支持</font> ';
} else {
$curl = '<font color=red>[×]不支持</font>';
$err++;
}
if (function_exists('bcadd')) {
$bcmath = '<font color=green>[√]支持</font> ';
} else {
$bcmath = '<font color=red>[×]不支持</font>';
$err++;
}
if (function_exists('openssl_encrypt')) {
$openssl = '<font color=green>[√]支持</font> ';
} else {
$openssl = '<font color=red>[×]不支持</font>';
$err++;
}
if (function_exists('finfo_open')) {
$finfo_open = '<font color=green>[√]支持</font> ';
} else {
$finfo_open = '<a href="http://help.crmeb.net/crmebpro/1707557" target="_blank"><span class="correct_span error_span">&radic;</span>点击查看帮助</a>';
$err++;
}
$folder = array(
'public/uploads',
'runtime',
);
$dirStr = '';
foreach ($folder as $dir) {
$Testdir = $path . $dir;
if (!is_file($Testdir)) {
if (!is_dir($Testdir)) {
$this->dir_create($Testdir);
}
}
if ($this->testwrite($Testdir)) {
$w = '<span class="correct_span">&radic;</span>可写 ';
} else {
$w = '<span class="correct_span error_span">&radic;</span>不可写 ';
$err++;
}
if (is_readable($Testdir)) {
$r = '<span class="correct_span">&radic;</span>可读';
} else {
$r = '<span class="correct_span error_span">&radic;</span>不可读';
$err++;
}
$dirStr .= "<tr>
<td>$dir</td>
<td>读写</td>
<td>$w</td>
<td>$r</td>
</tr>";
}
//必须开启函数
if (function_exists('file_put_contents')) {
$file_put_contents = '<font color=green>[√]开启</font> ';
} else {
$file_put_contents = '<font color=red>[×]关闭</font>';
$err++;
}
if (function_exists('imagettftext')) {
$imagettftext = '<font color=green>[√]开启</font> ';
} else {
$imagettftext = '<font color=red>[×]关闭</font>';
$err++;
}
if ($err > 0) {
$next = '<a href="javascript:void(0)" onClick="javascript:alert(\'安装环境检测未通过,请检查\')" class="btn" style="background: gray;">下一步</a>';
} else {
$next = '<a href="?step=3" class="btn">下一步</a>';
}
return view('/install/view/step2', [
'title' => $Title,
'powered' => $Powered,
'os' => $os,
'server' => $server,
'phpv' => $phpv,
'uploadSize' => $uploadSize,
'session' => $session,
'safe_mode' => $safe_mode,
'swoole' => $swoole,
'redis' => $redis,
'mysql' => $mysql,
'curl' => $curl,
'bcmath' => $bcmath,
'openssl' => $openssl,
'finfo_open' => $finfo_open,
'gd' => $gd,
'file_put_contents' => $file_put_contents,
'imagettftext' => $imagettftext,
'dirStr' => $dirStr,
'next' => $next,
]);
case '3':
if ($testdbpwd) {
$post = $request->param(
[
'dbHost',
'dbport',
'dbUser',
'dbPwd',
'dbName',
'rbhost',
'rbport',
'rbselect',
'rbpw',]
);
$conn = @mysqli_connect($post['dbHost'], $post['dbUser'], $post['dbPwd'], NULL, $post['dbport']);
if (mysqli_connect_errno()) {
return 0;
} else {
$result = mysqli_query($conn, "SELECT @@global.sql_mode");
$result = $result->fetch_array();
$version = mysqli_get_server_info($conn);
if ($version >= 5.7 && $version < 8.0) {
if (strstr($result[0], 'STRICT_TRANS_TABLES') || strstr($result[0], 'STRICT_ALL_TABLES') || strstr($result[0], 'TRADITIONAL') || strstr($result[0], 'ANSI'))
return -1;
}
$result = mysqli_query($conn, "select count(table_name) as c from information_schema.`TABLES` where table_schema='$post[dbName]'");
$result = $result->fetch_array();
if ($result['c'] > 0)
return -2;
}
//redis数据库信息
$rbhost = $post['rbhost'] ?? '127.0.0.1';
$rbport = $post['rbport'] ?? 6379;
$rbpw = $post['rbpw'] ?? '';
$rbselect = $post['rbselect'] ?? 0;
try {
$redis = new \Redis();
$redis->connect($rbhost, $rbport);
if ($rbpw) {
$redis->auth($rbpw);
}
if ($rbselect) {
$redis->select($rbselect);
}
$res = $redis->set('install', 1, 10);
if ($res) {
return 1;
} else {
return -3;
}
} catch (\Throwable $e) {
return -3;
}
}
return view('/install/view/step3', [
'title' => $Title,
'powered' => $Powered,
]);
case '4':
$post = $request->param(
['dbhost',
'dbport',
'dbname',
'dbuser',
'dbpw',
'dbprefix',
'rbhost',
'rbport',
'rbselect',
'rbpw',
'manager',
'manager_pwd',
'manager_email',
'demo',
'cache_prefix',
'cache_tag_prefix']
);
if (intval($install)) {
$i = 0;
if ($i == 999999) return false;
$arr = array();
$dbHost = trim($post['dbhost']);
$post['dbport'] = $post['dbport'] ? $post['dbport'] : '3306';
$dbName = strtolower(trim($post['dbname']));
$dbUser = trim($post['dbuser']);
$dbPwd = trim($post['dbpw']);
$dbPrefix = empty($post['dbprefix']) ? 'eb_' : trim($post['dbprefix']);
$username = trim($post['manager']);
if (!function_exists('mysqli_connect')) {
$arr['msg'] = "请安装 mysqli 扩展!";
return $arr;
}
$conn = @mysqli_connect($dbHost, $dbUser, $dbPwd, NULL, $post['dbport']);
if (mysqli_connect_errno()) {
$arr['msg'] = "连接数据库失败!" . mysqli_connect_error($conn);
return $arr;
}
mysqli_set_charset($conn, "utf8"); //,character_set_client=binary,sql_mode='';
$version = mysqli_get_server_info($conn);
if ($version < 5.1) {
$arr['msg'] = '数据库版本太低! 必须5.1以上';
return $arr;
}
if (!mysqli_select_db($conn, $dbName)) {
//创建数据时同时设置编码
if (!mysqli_query($conn, "CREATE DATABASE IF NOT EXISTS `" . $dbName . "` DEFAULT CHARACTER SET utf8;")) {
$arr['msg'] = '数据库 ' . $dbName . ' 不存在,也没权限创建新的数据库!';
return $arr;
}
if ($n == -1) {
$arr['n'] = 0;
$arr['msg'] = "成功创建数据库:{$dbName}<br>";
return $arr;
}
mysqli_select_db($conn, $dbName);
}
//读取数据文件
$sqldata = file_get_contents($path . 'public/install/' . $sqlFile);
$sqlFormat = $this->sql_split($sqldata, $dbPrefix);
//创建写入sql数据库文件到库中 结束
/**
* 执行SQL语句
*/
$counts = count($sqlFormat);
for ($i = $n; $i < $counts; $i++) {
$sql = trim($sqlFormat[$i] ?? '');
if (strstr($sql, 'CREATE TABLE')) {
preg_match('/CREATE TABLE (IF NOT EXISTS)? `eb_([^ ]*)`/is', $sql, $matches);
mysqli_query($conn, "DROP TABLE IF EXISTS `$matches[2]`");
$sql = str_replace('`eb_', '`' . $dbPrefix, $sql);//替换表前缀
$ret = mysqli_query($conn, $sql);
if ($ret) {
$message = '<li><span class="correct_span">&radic;</span>创建数据表[' . $dbPrefix . $matches[2] . ']完成!<span style="float: right;">' . date('Y-m-d H:i:s') . '</span></li> ';
} else {
$err = mysqli_error($conn);
$message = '<li><span class="correct_span error_span">&radic;</span>创建数据表[' . $dbPrefix . $matches[2] . ']失败!失败原因:' . $err . '<span style="float: right;">' . date('Y-m-d H:i:s') . '</span></li>';
}
$i++;
$arr = array('n' => $i, 'msg' => $message, 'count' => $counts);
return $arr;
} else {
if (trim($sql) == '')
continue;
$sql = str_replace('`eb_', '`' . $dbPrefix, $sql);//替换表前缀
$sql = str_replace('demos.crmeb.net', app()->request->host(true), $sql);//替换图片域名
$ret = mysqli_query($conn, $sql);
$message = '';
$i++;
$arr = array('n' => $i, 'msg' => $message, 'count' => $counts);
return $arr;
}
}
// 清空测试数据
// if (!$post['demo']) {
// $result = mysqli_query($conn, "show tables");
// $tables = mysqli_fetch_all($result);//参数MYSQL_ASSOC、MYSQLI_NUM、MYSQLI_BOTH规定产生数组类型
// $bl_table = array('eb_system_admin'
// , 'eb_system_role'
// , 'eb_system_config'
// , 'eb_system_config_tab'
// , 'eb_system_menus'
// , 'eb_system_file'
// , 'eb_express'
// , 'eb_system_group'
// , 'eb_system_group_data'
// , 'eb_template_message'
// , 'eb_shipping_templates'
// , "eb_shipping_templates_region"
// , "eb_shipping_templates_free"
// , 'eb_system_city'
// , 'eb_diy'
// , 'eb_member_ship'
// , 'eb_member_right'
// , 'eb_agreement'
// , 'eb_store_service_speechcraft'
// , 'eb_system_user_level'
// , 'eb_city_area'
// , 'eb_system_notification'
// , 'eb_system_attachment_category'
// , 'eb_system_attachment'
// , 'eb_page_category'
// , 'eb_page_link'
// , 'eb_category'
// , 'eb_store_product_label'
// , 'eb_store_product_ensure'
// , 'eb_cache');
// foreach ($bl_table as $k => $v) {
// $bl_table[$k] = str_replace('eb_', $dbPrefix, $v);
// }
//
// foreach ($tables as $key => $val) {
// if (!in_array($val[0], $bl_table)) {
// mysqli_query($conn, "truncate table " . $val[0]);
// }
// }
//// $this->delFile($path . 'public/uploads'); // 清空测试图片
// }
//读取配置文件,并替换真实配置数据1
$strConfig = file_get_contents($path . 'public/install/' . $configFile);
$app_key = md5(request()->ip() . uniqid() . time());
$strConfig = str_replace('#APP_KEY#', $app_key, $strConfig);
$strConfig = str_replace('#DB_HOST#', $dbHost, $strConfig);
$strConfig = str_replace('#DB_NAME#', $dbName, $strConfig);
$strConfig = str_replace('#DB_USER#', $dbUser, $strConfig);
$strConfig = str_replace('#DB_PWD#', $dbPwd, $strConfig);
$strConfig = str_replace('#DB_PORT#', $post['dbport'], $strConfig);
$strConfig = str_replace('#DB_PREFIX#', $dbPrefix, $strConfig);
$strConfig = str_replace('#DB_CHARSET#', 'utf8', $strConfig);
// $strConfig = str_replace('#DB_DEBUG#', false, $strConfig);
//redis数据库信息
$rbhost = $post['rbhost'] ?? '127.0.0.1';
$rbport = $post['rbport'] ?? '6379';
$rbpw = $post['rbpw'] ?? '';
$rbselect = $post['rbselect'] ?? 0;
$strConfig = str_replace('#RB_HOST#', $rbhost, $strConfig);
$strConfig = str_replace('#RB_PORT#', $rbport, $strConfig);
$strConfig = str_replace('#RB_PWD#', $rbpw, $strConfig);
$strConfig = str_replace('#RB_SELECT#', $rbselect, $strConfig);
//多项目部署配置
$cache_prefix = md5($app_key . uniqid() . time());
$strConfig = str_replace('#CACHE_PREFIX#', $cache_prefix, $strConfig);
@chmod($path . '/.env', 0777); //数据库配置文件的地址
@file_put_contents($path . '/.env', $strConfig); //数据库配置文件的地址
//读取配置文件,并替换换配置
// $strConfig = file_get_contents(SITE_DIR . '/application/config.php');
// $strConfig = str_replace('CRMEB_cache_prefix', $uniqid_str, $strConfig);
// @chmod(SITE_DIR . '/application/config.php',0777); //配置文件的地址
// @file_put_contents(SITE_DIR . '/application/config.php', $strConfig); //配置文件的地址
//更新网站配置信息2
//插入管理员表字段tp_admin表
$time = time();
$ip = request()->ip();
$ip = empty($ip) ? "0.0.0.0" : $ip;
$password = password_hash($post['manager_pwd'], PASSWORD_BCRYPT);
mysqli_query($conn, "truncate table {$dbPrefix}system_admin");
$addadminsql = "INSERT INTO `{$dbPrefix}system_admin` (`id`, `account`, `pwd`, `real_name`, `roles`, `last_ip`, `last_time`, `add_time`, `login_count`, `level`, `status`, `is_del`) VALUES (1, '" . $username . "', '" . $password . "', 'admin', '1', '" . $ip . "',$time , $time, 0, 0, 1, 0)";
$res = mysqli_query($conn, $addadminsql);
$res2 = true;
if (app()->request->host(true)) {
$site_url = '\'"http' . (app()->request->isSsl() ? 's' : '') . '://' . app()->request->host(true) . '"\'';
$res2 = mysqli_query($conn, 'UPDATE `' . $dbPrefix . 'system_config` SET `value`=' . $site_url . ' WHERE `menu_name`="site_url"');
}
if ($res) {
$message = '成功添加管理员<br />成功写入配置文件<br>安装完成.';
$arr = array('n' => 999999, 'msg' => $message);
return $arr;
} else {
$message = '添加管理员失败<br />成功写入配置文件<br>安装完成.';
$arr = array('n' => 999999, 'msg' => $message);
return $arr;
}
}
return view('/install/view/step4', [
'title' => $Title,
'powered' => $Powered,
'data' => json_encode($post)
]);
case '5':
$this->installlog();
@touch($path . 'public/install/install.lock');
return view('/install/view/step5', [
'title' => $Title,
'powered' => $Powered,
'ip' => request()->ip(),
'host' => request()->host(),
'version' => get_crmeb_version(),
'uid' => config('template.stores.wechat.template_id.ADMIN_ORDER_UID')
]);
}
}
/**
* Swoole Compiler Loader 安装助手页面
* @return string
*/
public function swooleCompiler()
{
// Set constants
// Language items
$languages['zh-cn'] = [
'title' => 'Swoole Compiler Loader 安装助手',
];
$languages['en'] = [
'title' => 'Swoole Compiler Loader Wizard',
];
// Set env variable for current environment
$env = [];
// Check os type
$env['os'] = [];
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$env['os']['name'] = "windows";
$env['os']['raw_name'] = php_uname();
} else {
$env['os']['name'] = "unix";
$env['os']['raw_name'] = php_uname();
}
// Check php
$env['php'] = [];
$env['php']['version'] = phpversion();
// Check run mode
$sapi_type = php_sapi_name();
if ("cli" == $sapi_type) {
$env['php']['run_mode'] = "cli";
} else {
$env['php']['run_mode'] = "web";
}
// Check php bit
if (PHP_INT_SIZE == 4) {
$env['php']['bit'] = 32;
} else {
$env['php']['bit'] = 64;
}
$env['php']['sapi'] = $sapi_type;
$env['php']['ini_loaded_file'] = php_ini_loaded_file();
$env['php']['ini_scanned_files'] = php_ini_scanned_files();
$env['php']['loaded_extensions'] = get_loaded_extensions();
$env['php']['incompatible_extensions'] = ['xdebug', 'ionCube', 'zend_loader'];
$env['php']['loaded_incompatible_extensions'] = [];
$env['php']['extension_dir'] = ini_get('extension_dir');
// Check incompatible extensions
if (is_array($env['php']['loaded_extensions'])) {
foreach ($env['php']['loaded_extensions'] as $loaded_extension) {
foreach ($env['php']['incompatible_extensions'] as $incompatible_extension) {
if (strpos(strtolower($loaded_extension), strtolower($incompatible_extension)) !== false) {
$env['php']['loaded_incompatible_extensions'][] = $loaded_extension;
}
}
}
}
$env['php']['loaded_incompatible_extensions'] = array_unique($env['php']['loaded_incompatible_extensions']);
// Parse System Environment Info
$sysInfo = $this->w_getSysInfo($env);
// Check php thread safety
$env['php']['raw_thread_safety'] = isset($sysInfo['thread_safety']) ? $sysInfo['thread_safety'] : false;
if (isset($sysInfo['thread_safety'])) {
$env['php']['thread_safety'] = $sysInfo['thread_safety'] ? '线程安全' : '非线程安全';
} else {
$env['php']['thread_safety'] = '未知';
}
// Check swoole loader installation
if (isset($sysInfo['swoole_loader']) and isset($sysInfo['swoole_loader_version'])) {
$env['php']['swoole_loader']['status'] = $sysInfo['swoole_loader'] ? "<span style='color: #007bff;'>已安装</span>"
: '未安装';
if ($sysInfo['swoole_loader_version'] !== false) {
$env['php']['swoole_loader']['version'] = "<span style='color: #007bff;'>" . $sysInfo['swoole_loader_version'] . "</span>";
} else {
$env['php']['swoole_loader']['version'] = '未知';
}
} else {
$env['php']['swoole_loader']['status'] = '未安装';
$env['php']['swoole_loader']['version'] = '未知';
}
/**
* Web mode
*/
if (true) {
$language = substr(request()->server('HTTP_ACCEPT_LANGUAGE') ?? 'zh-c', 0, 4);
if (preg_match("/zh-c/i", $language)) {
$env['lang'] = "zh-cn";
$wizard_lang = $env['lang'];
} else {
$env['lang'] = "en";
$wizard_lang = $env['lang'];
}
$html = '';
// Header
$html_header = '<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link href="https://lib.baomitu.com/twitter-bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet">
<title>%s</title>
<style>
.list_info {display: inline-block; width: 12rem;}
.bold_text {font-weight: bold;}
.code {color:#007bff;font-size: medium;}
</style>
</head>
<body class="bg-light">
';
$html_header = sprintf($html_header, $languages[$wizard_lang]['title']);
$html_body = '<div class="container">';
$html_body_nav = '<div class="py-5 text-center" style="padding-bottom: 1rem!important;">';
$html_body_nav .= '<h2>CRMEB Swoole Compiler 安装向导</h2>';
$html_body_nav .= '<p class="lead"> Version:2.0.2 Date:2019-01-09</p>';
$html_body_nav .= '</div><hr>';
// Environment information
$html_body_environment = '
<div class="col-12" style="padding-top: 1rem!important;">
<h5 class="text-center">检查当前环境</h5>
<ul class="list-unstyled text-small">';
$html_body_environment .= '<li><span class="list_info">操作系统 : </span>' . $env['os']['raw_name'] . '</li>';
$html_body_environment .= '<li><span class="list_info">PHP版本 : </span>' . $env['php']['version'] . '</li>';
$html_body_environment .= '<li><span class="list_info">PHP运行环境 : </span>' . $env['php']['sapi'] . '</li>';
$html_body_environment .= '<li><span class="list_info">PHP配置文件 : </span>' . $env['php']['ini_loaded_file'] . '</li>';
$html_body_environment .= '<li><span class="list_info">PHP扩展安装目录 : </span>' . $env['php']['extension_dir'] . '</li>';
$html_body_environment .= '<li><span class="list_info">PHP是否线程安全 : </span>' . $env['php']['thread_safety'] . '</li>';
$html_body_environment .= '<li><span class="list_info">是否安装swoole_loader : </span>' . $env['php']['swoole_loader']['status'] . '</li>';
if (isset($sysInfo['swoole_loader']) and $sysInfo['swoole_loader']) {
$html_body_environment .= '<li><span class="list_info">swoole_loader版本 : </span>' . $env['php']['swoole_loader']['version'] . '</li>';
}
if ($env['php']['bit'] == 32) {
$html_body_environment .= '<li><span style="color:red">温馨提示:当前环境使用的PHP为 ' . $env['php']['bit'] . ' 位的PHP,Compiler 目前不支持 Debug 版本或 32 位的PHP,可在 phpinfo() 中查看对应位数,如果误报请忽略此提示</span></li>';
}
$html_body_environment .= ' </ul></div>';
// Error infomation
$html_error = "";
if (!empty($env['php']['loaded_incompatible_extensions'])) {
$html_error = '<hr>
<div class="col-12" style="padding-top: 1rem!important;">
<h5 class="text-center" style="color:red">错误信息</h5>
<p class="text-center" style="color:red">%s</p>
</div>
';
$err_msg = "当前PHP包含与swoole_compiler_loader扩展不兼容的扩展" . implode(',', $env['php']['loaded_incompatible_extensions']) . ",请移除不兼容的扩展。";
$html_error = sprintf($html_error, $err_msg);
}
// Check Loader Status
$html_body_loader = '<hr>';
if (empty($html_error)) {
$html_body_loader .= '<div class="col-12" style="padding-top: 1rem!important;">';
$html_body_loader .= '<h5 class="text-center">安装和配置Swoole Loader</h5>';
$phpversion = substr($env['php']['version'], 0, 3);
$phpversion = str_replace('.', '', $phpversion);
$loaderFileName = '';
if ($env['os']['name'] == "windows") {
$loaderFileName = 'php_swoole_loader_php' . $phpversion;
if ($env['php']['thread_safety'] == '非线程安全') {
$loaderFileName .= '_nzts_x64.dll';
} else {
$loaderFileName .= '_zts_x64.dll';
}
} else {
if ($env['php']['thread_safety'] != '非线程安全') {
$loaderFileName = 'swoole_loader' . $phpversion . '_zts.so';
} else {
$loaderFileName = 'swoole_loader' . $phpversion . '.so';
}
}
$html_body_loader .= '<p><span class="bold_text">1 - 安装Swoole Loader</span></p><p>前往根目录 /help/swoole-loader/' . $loaderFileName . '扩展文件上传到当前PHP的扩展安装目录中:<br/><pre class="code">' . $env['php']['extension_dir'] . '</pre></p>';
$html_body_loader .= '<p><span class="bold_text">2 - 修改php.ini配置</span>(如已修改配置,请忽略此步骤,不必重复添加)</p><p>';
$html_body_loader .= '编辑此PHP配置文件:<span class="code">' . $env['php']['ini_loaded_file'] . '</span>,在此文件底部结尾处加入如下配置<br/>';
$html_body_loader .= '<pre class="code">extension=' . $env['php']['extension_dir'] . DIRECTORY_SEPARATOR . $loaderFileName . '</pre>注意:需要名称和刚才上传到当前PHP的扩展安装目录中的文件名一致';
$html_body_loader .= '</p>';
$html_body_loader .= '<p><span class="bold_text">3 - 重启服务</span></p><p>重启或重载PHP配置</p>';
$html_body_loader .= '</div>';
}
// Body footer
$html_body_footer = '<footer class="my-5 pt-5 text-muted text-center text-small">
<p class="mb-1">CopyRight © 2018 - ' . date('Y') . ' Swoole.com 上海识沃网络科技有限公司</p>
</footer>';
$html_body .= $html_body_nav . '<div class="row">' . $html_body_environment . $html_error . $html_body_loader . '</div>' . $html_body_footer;
$html_body .= '</div>';
// Footer
$html_footer = '
<script src="https://lib.baomitu.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://lib.baomitu.com/axios/0.18.0/axios.min.js"></script>
<script src="https://lib.baomitu.com/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script>
</body>
</html>';
// Make full html
$html = $html_header . $html_body . $html_footer;
echo $html;
}
}
function w_getSysInfo($env)
{
$sysEnv = [];
// Get content of phpinfo
ob_start();
phpinfo();
$sysInfo = ob_get_contents();
ob_end_clean();
// Explode phpinfo content
if ($env['php']['run_mode'] == 'cli') {
$sysInfoList = explode('\n', $sysInfo);
} else {
$sysInfoList = explode('</tr>', $sysInfo);
}
foreach ($sysInfoList as $sysInfoItem) {
if (preg_match('/thread safety/i', $sysInfoItem)) {
$sysEnv['thread_safety'] = (preg_match('/(enabled|yes)/i', $sysInfoItem) != 0);
}
if (preg_match('/swoole_loader support/i', $sysInfoItem)) {
$sysEnv['swoole_loader'] = (preg_match('/(enabled|yes)/i', $sysInfoItem) != 0);
}
if (preg_match('/swoole_loader version/i', $sysInfoItem)) {
preg_match('/\d+.\d+.\d+/s', $sysInfoItem, $match);
$sysEnv['swoole_loader_version'] = isset($match[0]) ? $match[0] : false;
}
}
return $sysEnv;
}
//读取版本号
function getversion()
{
try {
$curent_version = @file(app()->getRootPath() . '.version');
} catch (\Exception $e) {
$curent_version = [];
}
if ($curent_version && is_array($curent_version)) {
foreach ($curent_version as $val) {
[$k, $v] = explode('=', $val);
$version_arr[$k] = $v;
}
}
return $version_arr;
}
//写入安装信息
function installlog()
{
$mt_rand_str = $this->sp_random_string(6);
$str_constant = "<?php" . PHP_EOL . "define('INSTALL_DATE'," . time() . ");" . PHP_EOL . "define('SERIALNUMBER','" . $mt_rand_str . "');";
@file_put_contents(app()->getRootPath() . '.constant', $str_constant);
}
function sp_random_string($len = 8)
{
$chars = array(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
"3", "4", "5", "6", "7", "8", "9"
);
$charsLen = count($chars) - 1;
shuffle($chars); // 将数组打乱
$output = "";
mt_srand();
for ($i = 0; $i < $len; $i++) {
$output .= $chars[mt_rand(0, $charsLen)];
}
return $output;
}
//判断权限
function testwrite($d)
{
if (is_file($d)) {
if (is_writeable($d)) {
return true;
}
return false;
} else {
$tfile = "_test.txt";
$fp = @fopen($d . "/" . $tfile, "w");
if (!$fp) {
return false;
}
fclose($fp);
$rs = @unlink($d . "/" . $tfile);
if ($rs) {
return true;
}
return false;
}
}
// 获取客户端IP地址
function get_client_ip()
{
static $ip = NULL;
if ($ip !== NULL)
return $ip;
if (request()->server('HTTP_X_FORWARDED_FOR')) {
$arr = explode(',', request()->server('HTTP_X_FORWARDED_FOR'));
$pos = array_search('unknown', $arr);
if (false !== $pos)
unset($arr[$pos]);
$ip = trim($arr[0]);
} elseif (request()->server('HTTP_CLIENT_IP')) {
$ip = request()->server('HTTP_CLIENT_IP');
} elseif (request()->server('REMOTE_ADDR')) {
$ip = request()->server('REMOTE_ADDR');
}
// IP地址合法验证
$ip = (false !== ip2long($ip)) ? $ip : '0.0.0.0';
return $ip;
}
//创建目录
function dir_create($path, $mode = 0777)
{
if (is_dir($path))
return TRUE;
$ftp_enable = 0;
$path = $this->dir_path($path);
$temp = explode('/', $path);
$cur_dir = '';
$max = count($temp) - 1;
for ($i = 0; $i < $max; $i++) {
$cur_dir .= $temp[$i] . '/';
if (@is_dir($cur_dir))
continue;
@mkdir($cur_dir, 0777, true);
@chmod($cur_dir, 0777);
}
return is_dir($path);
}
function dir_path($path)
{
$path = str_replace('\\', '/', $path);
if (substr($path, -1) != '/')
$path = $path . '/';
return $path;
}
function sql_split($sql, $tablepre)
{
if ($tablepre != "tp_")
$sql = str_replace("tp_", $tablepre, $sql);
$sql = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=utf8", $sql);
$sql = str_replace("\r", "\n", $sql);
$ret = array();
$num = 0;
$queriesarray = explode(";\n", trim($sql));
unset($sql);
foreach ($queriesarray as $query) {
$ret[$num] = '';
$queries = explode("\n", trim($query));
$queries = array_filter($queries);
foreach ($queries as $query) {
$str1 = substr($query, 0, 1);
if ($str1 != '#' && $str1 != '-')
$ret[$num] .= $query;
}
$num++;
}
return $ret;
}
// 递归删除文件夹
function delFile($dir, $file_type = '')
{
if (is_dir($dir)) {
$files = scandir($dir);
//打开目录 //列出目录中的所有文件并去掉 . 和 ..
foreach ($files as $filename) {
if ($filename != '.' && $filename != '..') {
if (!is_dir($dir . '/' . $filename)) {
if (empty($file_type)) {
unlink($dir . '/' . $filename);
} else {
if (is_array($file_type)) {
//正则匹配指定文件
if (preg_match($file_type[0], $filename)) {
unlink($dir . '/' . $filename);
}
} else {
//指定包含某些字符串的文件
if (false != stristr($filename, $file_type)) {
unlink($dir . '/' . $filename);
}
}
}
} else {
$this->delFile($dir . '/' . $filename);
rmdir($dir . '/' . $filename);
}
}
}
} else {
if (file_exists($dir)) unlink($dir);
}
}
}

1579
app/controller/Upgrade.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,522 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller;
use app\jobs\user\UserBrokerageJob;
use app\Request;
use app\services\community\CommunityCommentServices;
use app\services\order\StoreOrderServices;
use app\services\user\UserBrokerageServices;
use think\facade\Db;
class UpgradeBeta
{
/**
* @param string $field
* @param int $n
* @return bool
*/
public function setIsUpgrade(string $field, int $n = 0)
{
try {
$upgrade = parse_ini_file(app()->getRootPath() . '.upgrade');
} catch (\Throwable $e) {
$upgrade = [];
}
if ($n) {
if (!is_array($upgrade)) {
$upgrade = [];
}
$string = '';
foreach ($upgrade as $key => $item) {
$string .= $key . '=' . $item . "\r\n";
}
$string .= $field . '=' . $n . "\r\n";
try {
file_put_contents(app()->getRootPath() . '.upgrade', $string);
} catch (\Throwable $e) {
}
return true;
} else {
if (!is_array($upgrade)) {
return false;
}
return isset($upgrade[$field]);
}
}
/**
* 获取当前版本号
* @return array
*/
public function getversion($str)
{
$version_arr = [];
$curent_version = @file(app()->getRootPath() . $str);
foreach ($curent_version as $val) {
[$k, $v] = explode('=', $val);
$version_arr[$k] = $v;
}
return $version_arr;
}
public function index(Request $request)
{
$data = $this->upData();
$Title = "CRMEB升级程序";
$Powered = "Powered by CRMEB";
//获取当前版本号
$version_now = $this->getversion('.version')['version'];
$version_new = $data['new_version'];
$isUpgrade = true;
$executeIng = false;
return view('/upgrade/step1', [
'title' => $Title,
'powered' => $Powered,
'version_now' => $version_now,
'version_new' => $version_new,
'isUpgrade' => json_encode($isUpgrade),
'executeIng' => json_encode($executeIng),
'next' => 1,
'action' => 'upgrade'
]);
}
// public function syncOldBrokeragePrice()
// {
// UserBrokerageJob::dispatchDo('syncOldBrokeragePrice');
// }
public function upgrade(Request $request)
{
[$sleep, $page, $prefix] = $request->getMore([
['sleep', 0],
['page', 1],
['prefix', 'eb_'],
], true);
$data = $this->upData();
$code_now = $this->getversion('.version')['version_code'];
$sql_arr = [];
foreach ($data['update_sql'] as $items) {
if ($items['code'] > $code_now) {
$sql_arr[] = $items;
}
}
if (!isset($sql_arr[$sleep])) {
file_put_contents(app()->getRootPath() . '.version', "version=" . $data['new_version'] . "\nversion_code=" . $data['new_code']);
// $this->syncOldBrokeragePrice();
return app('json')->successful(['sleep' => -1]);
}
$sql = $sql_arr[$sleep];
Db::startTrans();
try {
if ($sql['type'] == 1) {
if (isset($sql['findSql']) && $sql['findSql']) {
$table = $prefix . $sql['table'];
$findSql = str_replace('@table', $table, $sql['findSql']);
if (!empty(Db::query($findSql))) {
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表已存在';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
if (isset($sql['sql']) && $sql['sql']) {
$upSql = $sql['sql'];
$upSql = str_replace('@table', $table, $upSql);
Db::execute($upSql);
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表添加成功';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
} elseif ($sql['type'] == 2) {
if (isset($sql['findSql']) && $sql['findSql']) {
$table = $prefix . $sql['table'];
$findSql = str_replace('@table', $table, $sql['findSql']);
if (empty(Db::query($findSql))) {
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表不存在';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
if (isset($sql['sql']) && $sql['sql']) {
$upSql = $sql['sql'];
$upSql = str_replace('@table', $table, $upSql);
Db::execute($upSql);
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表删除成功';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
} elseif ($sql['type'] == 3) {
if (isset($sql['findSql']) && $sql['findSql']) {
$table = $prefix . $sql['table'];
$findSql = str_replace('@table', $table, $sql['findSql']);
if (!empty(Db::query($findSql))) {
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表中' . $sql['field'] . '已存在';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
if (isset($sql['sql']) && $sql['sql']) {
$upSql = $sql['sql'];
$upSql = str_replace('@table', $table, $upSql);
Db::execute($upSql);
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表中' . $sql['field'] . '字段添加成功';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
} elseif ($sql['type'] == 4) {
if (isset($sql['findSql']) && $sql['findSql']) {
$table = $prefix . $sql['table'];
$findSql = str_replace('@table', $table, $sql['findSql']);
if (empty(Db::query($findSql))) {
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表中' . $sql['field'] . '不存在';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
if (isset($sql['sql']) && $sql['sql']) {
$upSql = $sql['sql'];
$upSql = str_replace('@table', $table, $upSql);
Db::execute($upSql);
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表中' . $sql['field'] . '字段修改成功';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
} elseif ($sql['type'] == 5) {
if (isset($sql['findSql']) && $sql['findSql']) {
$table = $prefix . $sql['table'];
$findSql = str_replace('@table', $table, $sql['findSql']);
if (empty(Db::query($findSql))) {
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表中' . $sql['field'] . '不存在';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
if (isset($sql['sql']) && $sql['sql']) {
$upSql = $sql['sql'];
$upSql = str_replace('@table', $table, $upSql);
Db::execute($upSql);
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '表中' . $sql['field'] . '字段删除成功';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
} elseif ($sql['type'] == 6) {
$table = $prefix . $sql['table'] ?? '';
if (isset($sql['findSql']) && $sql['findSql']) {
$findSql = str_replace('@table', $table, $sql['findSql']);
if (!empty(Db::query($findSql))) {
$item['table'] = $prefix . $sql['table'];
$item['status'] = 1;
$item['error'] = $table . '表中此数据已存在';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
if (isset($sql['sql']) && $sql['sql']) {
$upSql = $sql['sql'];
$upSql = str_replace('@table', $table, $upSql);
if (isset($sql['whereSql']) && $sql['whereSql']) {
$whereTable = $prefix . $sql['whereTable'] ?? '';
$whereSql = str_replace('@whereTable', $whereTable, $sql['whereSql']);
$tabId = Db::query($whereSql)[0]['tabId'] ?? 0;
if (!$tabId) {
$item['table'] = $whereTable;
$item['status'] = 1;
$item['error'] = '查询父类ID不存在';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
$upSql = str_replace('@tabId', $tabId, $upSql);
}
if (Db::execute($upSql)) {
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = '数据添加成功';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
} elseif ($sql['type'] == 7) {
$table = $prefix . $sql['table'] ?? '';
$whereTable = $prefix . $sql['whereTable'] ?? '';
if (isset($sql['findSql']) && $sql['findSql']) {
$findSql = str_replace('@table', $table, $sql['findSql']);
if (empty(Db::query($findSql))) {
$item['table'] = $prefix . $sql['table'];
$item['status'] = 1;
$item['error'] = $table . '表中此数据不存在';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
if (isset($sql['sql']) && $sql['sql']) {
$upSql = $sql['sql'];
$upSql = str_replace('@table', $table, $upSql);
if (isset($sql['whereSql']) && $sql['whereSql']) {
$whereSql = str_replace('@whereTable', $whereTable, $sql['whereSql']);
$tabId = Db::query($whereSql)[0]['tabId'] ?? 0;
if (!$tabId) {
$item['table'] = $whereTable;
$item['status'] = 1;
$item['error'] = '查询父类ID不存在';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
$upSql = str_replace('@tabId', $tabId, $upSql);
}
if (Db::execute($upSql)) {
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = '数据修改成功';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
} elseif ($sql['type'] == 8) {
} elseif ($sql['type'] == -1) {
$table = $prefix . $sql['table'];
if (isset($sql['sql']) && $sql['sql']) {
$upSql = $sql['sql'];
$upSql = str_replace('@table', $table, $upSql);
if (isset($sql['new_table']) && $sql['new_table']) {
$new_table = $prefix . $sql['new_table'];
$upSql = str_replace('@new_table', $new_table, $upSql);
}
Db::execute($upSql);
$item['table'] = $table;
$item['status'] = 1;
$item['error'] = $table . '更新sql执行成功';
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
Db::commit();
return app('json')->successful($item);
}
}
} catch (\Throwable $e) {
$item['table'] = $prefix . $sql['table'];
$item['status'] = 0;
$item['sleep'] = $sleep + 1;
$item['add_time'] = date('Y-m-d H:i:s', time());
$item['error'] = $e->getMessage();
Db::rollBack();
return app('json')->successful($item);
}
}
public function upData()
{
$data['new_version'] = 'CRMEB-PRO v3.2.0';
$data['new_code'] = 320;
$data['update_sql'] = [
[
'code' => 320,
'type' => 3,
'table' => "user_extract",
'field' => "order_id",
'findSql' => "show columns from `@table` like 'order_id'",
'sql' => "ALTER TABLE `@table` ADD `order_id` varchar(32) NOT NULL DEFAULT '' COMMENT '订单号' AFTER `id`"
],
[
'code' => 320,
'type' => 3,
'table' => "user_extract",
'field' => "user_name",
'findSql' => "show columns from `@table` like 'user_name'",
'sql' => "ALTER TABLE `@table` ADD `user_name` varchar(64) NOT NULL DEFAULT '' COMMENT '真实姓名' AFTER `qrcode_url`"
],
[
'code' => 320,
'type' => 3,
'table' => "user_extract",
'field' => "wechat_state",
'findSql' => "show columns from `@table` like 'wechat_state'",
'sql' => "ALTER TABLE `@table` ADD `wechat_state` varchar(32) NOT NULL DEFAULT '' COMMENT 'v3转账状态码' AFTER `user_name`"
],
[
'code' => 320,
'type' => 3,
'table' => "user_extract",
'field' => "package_info",
'findSql' => "show columns from `@table` like 'package_info'",
'sql' => "ALTER TABLE `@table` ADD `package_info` varchar(1000) NOT NULL DEFAULT '' COMMENT 'v3转账支付收款页的package' AFTER `wechat_state`"
],
[
'code' => 320,
'type' => 3,
'table' => "user_extract",
'field' => "fail_reason",
'findSql' => "show columns from `@table` like 'fail_reason'",
'sql' => "ALTER TABLE `@table` ADD `fail_reason` varchar(32) NOT NULL DEFAULT '' COMMENT 'v3转账失败原因' AFTER `package_info`"
],
[
'code' => 320,
'type' => 3,
'table' => "user_extract",
'field' => "transfer_bill_no",
'findSql' => "show columns from `@table` like 'transfer_bill_no'",
'sql' => "ALTER TABLE `@table` ADD `transfer_bill_no` varchar(256) NOT NULL DEFAULT '' COMMENT 'v3微信转账单号' AFTER `fail_reason`"
],
[
'code' => 320,
'type' => 3,
'table' => "user_extract",
'field' => "channel_type",
'findSql' => "show columns from `@table` like 'channel_type'",
'sql' => "ALTER TABLE `@table` ADD `channel_type` varchar(10) NOT NULL DEFAULT '' COMMENT '提现渠道(小程序:routine;公众号:h5;app)' AFTER `transfer_bill_no`"
],
[
'code' => 320,
'type' => 3,
'table' => "luck_lottery_record",
'field' => "order_id",
'findSql' => "show columns from `@table` like 'order_id'",
'sql' => "ALTER TABLE `@table` ADD `order_id` varchar(32) NOT NULL DEFAULT '' COMMENT '订单号' AFTER `add_time`"
],
[
'code' => 320,
'type' => 3,
'table' => "luck_lottery_record",
'field' => "wechat_state",
'findSql' => "show columns from `@table` like 'wechat_state'",
'sql' => "ALTER TABLE `@table` ADD `wechat_state` varchar(32) NOT NULL DEFAULT '' COMMENT 'v3转账状态码' AFTER `order_id`"
],
[
'code' => 320,
'type' => 3,
'table' => "luck_lottery_record",
'field' => "package_info",
'findSql' => "show columns from `@table` like 'package_info'",
'sql' => "ALTER TABLE `@table` ADD `package_info` varchar(1000) NOT NULL DEFAULT '' COMMENT 'v3转账支付收款页的package' AFTER `wechat_state`"
],
[
'code' => 320,
'type' => 3,
'table' => "luck_lottery_record",
'field' => "fail_reason",
'findSql' => "show columns from `@table` like 'fail_reason'",
'sql' => "ALTER TABLE `@table` ADD `fail_reason` varchar(32) NOT NULL DEFAULT '' COMMENT 'v3转账失败原因' AFTER `package_info`"
],
[
'code' => 320,
'type' => 3,
'table' => "luck_lottery_record",
'field' => "transfer_bill_no",
'findSql' => "show columns from `@table` like 'transfer_bill_no'",
'sql' => "ALTER TABLE `@table` ADD `transfer_bill_no` varchar(256) NOT NULL DEFAULT '' COMMENT 'v3微信转账单号' AFTER `fail_reason`"
],
[
'code' => 320,
'type' => 3,
'table' => "luck_lottery_record",
'field' => "channel_type",
'findSql' => "show columns from `@table` like 'channel_type'",
'sql' => "ALTER TABLE `@table` ADD `channel_type` varchar(10) NOT NULL DEFAULT '' COMMENT '提现渠道(小程序:routine;公众号:h5;app)' AFTER `transfer_bill_no`"
],
[
'code' => 320,
'type' => 6,
'table' => "system_config",
'whereTable' => "system_config_tab",
'findSql' => "select id from @table where menu_name = 'pay_weixin_scene_id'",
'whereSql' => "select id as tabId from @whereTable where eng_title = 'pay'",
'sql' => "INSERT INTO `@table` VALUES (null, 0, 'pay_weixin_scene_id', 'text', 'number', 4, '', 1, '', 100, 0, '', '转账场景ID', '微信v3支付商家转账的转账场景ID,用于抽奖红包和佣金提现', 0, 1)"
],
[
'code' => 320,
'type' => -1,
'table' => "system_notification",
'sql' => "INSERT INTO `@table` VALUES (null, 'revenue_received', '收益到账通知', '收益到账给用户通知', 0, 0, 1, 1, 0, 0, '收益到账通知', '', 0, '0', '0', '', '', '', '', '', 1, 0)"
],
[
'code' => 320,
'type' => 6,
'table' => "template_message",
'whereTable' => "system_notification",
'findSql' => "select id from @table where tempkey = '1493'",
'whereSql' => "select id as tabId from @whereTable where mark = 'revenue_received'",
'sql' => "INSERT INTO `@table` VALUES (null, '@tabId', 0, '1493', '收益到账通知', '', '收益金额{{amount3.DATA}}\n温馨提醒{{thing4.DATA}}\n时间{{time9.DATA}}', '', '', '1739763519', 1)"
],
[
'code' => 320,
'type' => 6,
'table' => "template_message",
'whereTable' => "system_notification",
'findSql' => "select id from @table where tempkey = '54531'",
'whereSql' => "select id as tabId from @whereTable where mark = 'revenue_received'",
'sql' => "INSERT INTO `@table` VALUES (null, '@tabId', 1, '54531', '提现结果通知', '', '金额{{amount2.DATA}}\n提现结果{{const5.DATA}}\n提现时间{{time3.DATA}}', '', '', '1739763519', 1)"
],
];
return $data;
}
}

View File

@@ -0,0 +1,79 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin;
use app\Request;
use crmeb\basic\BaseController;
use think\Response;
/**
* 基类 所有控制器继承的类
* Class AuthController
* @package app\controller\admin
* @property Request $request
* @method Response success($message = '', array $data = [])
* @method Response fail($message = '', array $data = [])
*/
class AuthController extends BaseController
{
/**
* 当前登陆管理员信息
* @var array
*/
protected $adminInfo = [];
/**
* 当前登陆管理员ID
* @var int
*/
protected $adminId = 0;
protected $supplierId = 0;
/**
* 当前登陆管理员类型 4 是供应商
* @var int
*/
protected $adminType = 1;
/**
* 当前管理员权限
* @var array
*/
protected $auth = [];
/**
* 初始化
*/
protected function initialize()
{
$this->loadAdminInfo();
}
/**
* 加载管理员信息
*/
protected function loadAdminInfo()
{
$this->adminId = $this->request->hasMacro('adminId') ? (int)$this->request->adminId() : 0;
$this->adminInfo = $this->request->hasMacro('adminInfo') ? (array)$this->request->adminInfo() : [];
$this->adminType = $this->adminInfo['admin_type'] ?? 1;
if ($this->adminType == 4) {
$this->supplierId = $this->adminId;
}
$this->auth = $this->adminInfo['rule'] ?? [];
}
}

View File

@@ -0,0 +1,412 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin;
use app\services\agent\DivisionApplyServices;
use app\services\agent\PromoterApplyServices;
use app\services\order\StoreOrderRefundServices;
use app\services\other\CityAreaServices;
use app\services\system\SystemAuthServices;
use app\services\order\StoreOrderServices;
use app\services\product\product\StoreProductServices;
use app\services\product\product\StoreProductReplyServices;
use app\services\system\SystemUserApplyServices;
use app\services\user\channel\ChannelMerchantServices;
use app\services\user\UserExtractServices;
use app\services\system\SystemMenusServices;
use app\services\user\UserServices;
use crmeb\services\CacheService;
use crmeb\services\SystemConfigService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Response;
/**
* 公共接口基类 主要存放公共接口
* Class Common
* @package app\controller\admin
*/
class Common extends AuthController
{
/**
* 获取logo
* @param SystemConfigService $services
* @return Response
*/
public function getLogo(SystemConfigService $services): Response
{
$data = $services->more(['site_logo', 'site_logo_square', 'site_name']);
return $this->success($data);
}
/**
* @return mixed
*/
public function check_auth()
{
return $this->checkAuthDecrypt();
}
/**
* @return mixed
*/
public function auth()
{
return $this->getAuth();
}
/**
* 查询购买版权
* @return Response
*/
public function crmeb_copyright(): Response
{
$this->__6j3nfcwmWqrsDx8F0MjZGeQyWvLsqeFXww();
return $this->success('查询成功');
}
/**
* 保存版权
* @return Response
*/
public function saveCopyright(): Response
{
$copyright = $this->request->post('copyright');
$copyrightImg = $this->request->post('copyright_img');
$this->__qsG71NREI01vix2OkjH($copyright, $copyrightImg);
return $this->success('保存成功');
}
/**
* 获取版权
* @return Response
*/
public function getCopyright(): Response
{
try {
$copyright = $this->__z6uxyJQ4xYa5ee1mx5();
} catch (\Throwable $e) {
$copyright = ['copyrightContext' => '', 'copyrightImage' => ''];
}
$copyright['version'] = get_crmeb_version();
return $this->success($copyright);
}
/**
* 申请授权
* @param SystemAuthServices $services
* @return Response
*/
public function auth_apply(SystemAuthServices $services): Response
{
$version = get_crmeb_version();
$data = $this->request->postMore([
['company_name', ''],
['domain_name', ''],
['order_id', ''],
['phone', ''],
['label', strripos($version, 'min') === false ? 3 : 2],
['captcha', ''],
]);
if (!$data['company_name']) {
return $this->fail('请填写公司名称');
}
if (!$data['domain_name']) {
return $this->fail('请填写授权域名');
}
if (!$data['phone']) {
return $this->fail('请填写手机号码');
}
if (!$data['order_id']) {
return $this->fail('请填写订单id');
}
$datas = explode('.', $data['domain_name']);
$n = count($datas);
$preg = '/[\w].+\.(com|net|org|gov|edu)\.cn$/';
if (($n > 2) && preg_match($preg, $data['domain_name'])) {
//双后缀取后3位
$domain_name = $datas[$n - 3] . '.' . $datas[$n - 2] . '.' . $datas[$n - 1];
} else {
//非双后缀取后两位
$domain_name = $datas[$n - 2] . '.' . $datas[$n - 1];
}
$sec = trim(str_replace($domain_name, '', $data['domain_name']), '.');
if ($sec) {
if ($sec == 'www') {
$data['domain_name'] = $domain_name;
}
}
$header = $this->__k0dUcnKjRUs9lfEllqO9J($data['phone']);
if ($header) {
$headerData = ['Authori-zation:Bearer ' . $this->__k0dUcnKjRUs9lfEllqO9J($data['phone'])];
} else {
$headerData = false;
}
$services->authApply($data, $headerData);
return $this->success("申请授权成功!");
}
/**
* 首页头部统计数据
* @return Response
*/
public function homeStatics(): Response
{
/** @var StoreOrderServices $orderServices */
$orderServices = app()->make(StoreOrderServices::class);
$info = $orderServices->homeStatics();
return $this->success(compact('info'));
}
/**
* 订单图表
* @return Response
* @author 等风来
* @email 136327134@qq.com
* @date 2023/9/28
*/
public function orderChart(): Response
{
$cycle = $this->request->param('cycle') ?: 'thirtyday';//默认30天
/** @var StoreOrderServices $orderServices */
$orderServices = app()->make(StoreOrderServices::class);
$chartdata = $orderServices->orderCharts($cycle);
return $this->success($chartdata);
}
/**
* 用户图表
* @return Response
* @author 等风来
* @email 136327134@qq.com
* @date 2023/9/28
*/
public function userChart(): Response
{
/** @var UserServices $uServices */
$uServices = app()->make(UserServices::class);
$chartdata = $uServices->userChart();
return $this->success($chartdata);
}
/**
* 交易额排行
* @return Response
*/
public function purchaseRanking(): Response
{
// /** @var StoreProductAttrValueServices $valueServices */
// $valueServices = app()->make(StoreProductAttrValueServices::class);
// $list = $valueServices->purchaseRanking();
$list = [];
return $this->success(compact('list'));
}
/**
* 待办事统计
* @return Response
*/
public function jnotice(): Response
{
/** @var StoreOrderServices $orderServices */
$orderServices = app()->make(StoreOrderServices::class);
$orderNum = $orderServices->storeOrderCount();
$store_stock = sys_config('store_stock');
if ($store_stock < 0) $store_stock = 2;
/** @var StoreProductServices $storeServices */
$storeServices = app()->make(StoreProductServices::class);
/** @var StoreProductReplyServices $replyServices */
$replyServices = app()->make(StoreProductReplyServices::class);
$commentNum = $replyServices->replyCount();
/** @var UserExtractServices $extractServices */
$extractServices = app()->make(UserExtractServices::class);
$reflectNum = $extractServices->userExtractCount();//提现
/** @var StoreOrderRefundServices $refundServices */
$refundServices = app()->make(StoreOrderRefundServices::class);
$orderRefundNum = $refundServices->count(['is_cancel' => 0, 'refund_type' => [0, 1, 2, 4, 5]]);
// $orderServices->update(['status' => 1, 'is_remind' => 0], ['is_remind' => 1]);
$promoterApplyNum = app()->make(PromoterApplyServices::class)->count(['status' => 0, 'is_del' => 0]);
$divisionApplyNum = app()->make(DivisionApplyServices::class)->count(['status' => 0, 'is_del' => 0]);
$supplierApplyNum = app()->make(SystemUserApplyServices::class)->count(['status' => 0, 'is_del' => 0, 'type' => 2]);
$channelApplyNum = app()->make(ChannelMerchantServices::class)->count(['verify_status' => 0, 'is_del' => 0, 'is_admin' => 0]);
$value = [];
if ($orderNum) {
$value[] = [
'title' => '您有' . $orderNum . '个待发货的订单',
'type' => 'bulb',
'url' => '/admin/order/list?status=1'
];
}
$inventory = $storeServices->count(['is_police' => 1, 'status' => 5, 'pid' => 0, 'store_stock' => 0]);
if ($inventory) {
$value[] = [
'title' => '您有' . $inventory . '个商品库存预警',
'type' => 'information',
'url' => '/admin/product/product_list?type=5',
];
}
if ($commentNum) {
$value[] = [
'title' => '您有' . $commentNum . '条评论待回复',
'type' => 'bulb',
'url' => '/admin/product/product_reply?is_reply=0'
];
}
if ($reflectNum) {
$value[] = [
'title' => '您有' . $reflectNum . '个提现申请待审核',
'type' => 'information',
'url' => '/admin/finance/user_extract/index?status=0',
];
}
if ($orderRefundNum) {
$value[] = [
'title' => '您有' . $orderRefundNum . '个售后订单待处理',
'type' => 'bulb',
'url' => '/admin/order/refund'
];
}
if ($promoterApplyNum) {
$value[] = [
'title' => '您有' . $promoterApplyNum . '个分销员申请待处理',
'type' => 'people',
'url' => '/admin/agent/promoter/apply'
];
}
if ($divisionApplyNum) {
$value[] = [
'title' => '您有' . $divisionApplyNum . '个代理商申请待处理',
'type' => 'people',
'url' => '/admin/agent/apply_list'
];
}
if ($supplierApplyNum) {
$value[] = [
'title' => '您有' . $supplierApplyNum . '个供应商申请待处理',
'type' => 'people',
'url' => '/admin/supplier/apply'
];
}
if ($channelApplyNum) {
$value[] = [
'title' => '您有' . $channelApplyNum . '个采购商申请待处理',
'type' => 'people',
'url' => '/admin/user/channelMerchant/examine'
];
}
return $this->success($this->noticeData($value));
}
/**
* 消息返回格式
* @param array $data
* @return array
*/
public function noticeData(array $data): array
{
// 消息图标
$iconColor = [
// 邮件 消息
'mail' => [
'icon' => 'md-mail',
'color' => '#3391e5'
],
// 普通 消息
'bulb' => [
'icon' => 'md-bulb',
'color' => '#87d068'
],
// 警告 消息
'information' => [
'icon' => 'md-information',
'color' => '#fe5c57'
],
// 关注 消息
'star' => [
'icon' => 'md-star',
'color' => '#ff9900'
],
// 申请 消息
'people' => [
'icon' => 'md-people',
'color' => '#f06292'
],
];
// 消息类型
$type = array_keys($iconColor);
// 默认数据格式
$default = [
'icon' => 'md-bulb',
'iconColor' => '#87d068',
'title' => '',
'url' => '',
'type' => 'bulb',
'read' => 0,
'time' => 0
];
$value = [];
foreach ($data as $item) {
$val = array_merge($default, $item);
if (isset($item['type']) && in_array($item['type'], $type)) {
$val['type'] = $item['type'];
$val['iconColor'] = $iconColor[$item['type']]['color'] ?? '';
$val['icon'] = $iconColor[$item['type']]['icon'] ?? '';
}
$value[] = $val;
}
return $value;
}
/**
* 格式化菜单
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function menusList(): Response
{
[$keyword] = $this->request->getMore([
['keyword', '']
], true);
$keyword = trim($keyword);
$adminType = $this->adminType;
$cacheKey = $keyword ? md5('admin_common_menu_list_' . $adminType . '_' . $keyword) : md5('admin_common_menu_list_' . $adminType);
$list = CacheService::redisHandler('system_menus')->remember($cacheKey, function () use ($keyword, $adminType) {
/** @var SystemMenusServices $menusServices */
$menusServices = app()->make(SystemMenusServices::class);
return $menusServices->getSelectList($adminType, $keyword);
});
return app('json')->success($list);
}
/**
* @param CityAreaServices $services
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function city(CityAreaServices $services): Response
{
$pid = $this->request->get('pid', 0);
return $this->success($services->getCityTreeList((int)$pid));
}
}

View File

@@ -0,0 +1,314 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin;
use app\Request;
use app\services\user\LoginServices;
use app\validate\api\user\RegisterValidates;
use crmeb\services\CacheService;
use crmeb\utils\Captcha;
use app\services\system\admin\SystemAdminServices;
use Psr\SimpleCache\InvalidArgumentException;
use think\annotation\Inject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Config;
use think\Response;
/**
* 后台登陆
* Class Login
* @package app\controller\admin
*/
class Login
{
/**
* @var SystemAdminServices
*/
#[Inject]
protected SystemAdminServices $services;
/**
* 验证码
* @return Response
*/
public function captcha(): Response
{
return app()->make(Captcha::class)->create();
}
/**
* @param Request $request
* @return Response
* @author 等风来
* @email 136327134@qq.com
* @date 2022/10/11
*/
public function getAjCaptcha(Request $request): Response
{
[$account] = $request->postMore([
'account',
], true);
$key = 'login_captcha_' . $account;
return app('json')->success(['is_captcha' => Cache::get($key) > 2]);
}
/**
* 安全验证
* @param Request $request
* @return Response
* User: liusl
* DateTime: 2024/8/2 10:27
*/
public function secure(Request $request)
{
[$account, $password] = $request->postMore([
'account',
'pwd',
], true);
validate(\app\validate\admin\setting\SystemAdminValidate::class)->scene('get')->check(['account' => $account, 'pwd' => $password]);
$res = $this->services->secure($account, $password);
return app('json')->success($res);
}
/**
* 登陆
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function login(Request $request)
{
[$account, $password, $captchaType, $captchaVerification, $type] = $request->postMore([
'account',
'pwd',
['captchaType', ''],
['captchaVerification', ''],
['type', 'admin'],
], true);
$key = 'login_captcha_' . $account;
if (Cache::has($key) && Cache::get($key) > 2) {
if (!$captchaType || !$captchaVerification) {
return app('json')->fail('请拖动滑块验证');
}
//二次验证
try {
aj_captcha_check_two($captchaType, $captchaVerification);
} catch (\Throwable $e) {
return app('json')->fail($e->getError());
}
}
validate(\app\validate\admin\setting\SystemAdminValidate::class)->scene('get')->check(['account' => $account, 'pwd' => $password]);
try {
$res = $this->services->login($account, $password, $type);
if ($res) {
Cache::delete($key);
}
return app('json')->success($res);
} catch (\Exception $e) {
return app('json')->fail($e->getMessage());
}
}
/**
* 获取短信验证码
* @param Request $request
* @return int|object|Response
* @throws InvalidArgumentException
* User: liusl
* DateTime: 2024/8/2 11:36
*/
public function verify(Request $request, LoginServices $services)
{
[$secure_key, $phone, $type, $key, $captchaType, $captchaVerification] = $request->postMore([
['secure_key', ''],
['phone', 0],
['type', ''],
['key', ''],
['captchaType', ''],
['captchaVerification', ''],
], true);
if (!$phone) {
$phone = CacheService::get($secure_key);
if (!$phone) {
return app('json')->fail('手机号码不存在');
}
}
$keyName = 'sms.key.' . $key;
$nowKey = 'sms.' . date('YmdHi');
if (!CacheService::has($keyName))
return app('json')->make(401, '发送验证码失败,请刷新页面重新获取');
$total = 1;
if (CacheService::has($nowKey)) {
$total = CacheService::get($nowKey);
if ($total > Config::get('sms.maxMinuteCount', 20))
return app('json')->success('已发送');
}
//二次验证
try {
aj_captcha_check_two($captchaType, $captchaVerification);
} catch (\Throwable $e) {
return app('json')->fail($e->getError());
}
try {
validate(RegisterValidates::class)->scene('code')->check(['phone' => $phone]);
} catch (ValidateException $e) {
return app('json')->fail($e->getError());
}
$time = sys_config('verify_expire_time', 1);
$smsCode = $services->verify($phone, $type, $time, app()->request->ip());
if ($smsCode) {
CacheService::set('code_' . $phone, $smsCode, $time * 60);
CacheService::set($nowKey, $total, 61);
event('sms.sendAfter', [$smsCode, $phone]);
return app('json')->success('发送成功');
} else {
return app('json')->fail('发送失败');
}
}
/**
* 短信验证码登录
* @param Request $request
* @return mixed
* @throws InvalidArgumentException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function mobileLogin(Request $request)
{
[$phone, $code, $secure_key,$type] = $request->postMore([
'phone', 'code', 'secure_key','type'
], true);
if (!$code) {
return app('json')->fail('请输入验证码');
}
if (!$phone) {
$phone = CacheService::get($secure_key);
if (!$phone) {
return app('json')->fail('手机号码不存在');
}
}
//验证验证码
$verifyCode = CacheService::get('code_' . $phone);
if (!$verifyCode)
return app('json')->fail('请先获取验证码');
$verifyCode = substr($verifyCode, 0, 6);
if ($verifyCode != $code) {
CacheService::delete('code_' . $phone);
return app('json')->fail('验证码错误');
}
try {
$res = $this->services->login($phone, $code, 1, true);
if ($res) {
CacheService::delete('code_' . $phone);
CacheService::delete($secure_key);
}
return app('json')->success($res);
} catch (\Exception $e) {
return app('json')->fail($e->getMessage());
}
}
/**
* 短信重置密码
* @param Request $request
* @return mixed
* @throws InvalidArgumentException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function resetPwd(Request $request)
{
[$phone, $code, $newPwd] = $request->postMore([
'phone', 'code', 'new_pwd'
], true);
if (!$phone) {
return app('json')->fail('请输入手机号');
}
if (!check_phone($phone)) {
return app('json')->fail('请输入正确的手机号!');
}
if (!$code) {
return app('json')->fail('请输入验证码');
}
if (!$newPwd) {
return app('json')->fail('请输入新密码');
}
//验证验证码
$verifyCode = CacheService::get('code_' . $phone);
if (!$verifyCode)
return app('json')->fail('请先获取验证码');
$verifyCode = substr($verifyCode, 0, 6);
if ($verifyCode != $code) {
CacheService::delete('code_' . $phone);
return app('json')->fail('验证码错误');
}
try {
$this->services->resetPwd($phone, $newPwd);
return app('json')->success('重置成功,请重新登录');
} catch (\Exception $e) {
return app('json')->fail('重置密码处理异常: ' . $e->getMessage());
}
}
/**
* 获取后台登录页轮播图以及LOGO
* @return mixed
*/
public function info()
{
return app('json')->success($this->services->getLoginInfo());
}
/**
* @return mixed
*/
public function ajcaptcha(Request $request)
{
$captchaType = $request->get('captchaType');
return app('json')->success(aj_captcha_create($captchaType));
}
/**
* 一次验证
* @return mixed
*/
public function ajcheck(Request $request)
{
[$token, $pointJson, $captchaType] = $request->postMore([
['token', ''],
['pointJson', ''],
['captchaType', ''],
], true);
try {
aj_captcha_check_one($captchaType, $token, $pointJson);
return app('json')->success();
} catch (\Throwable $e) {
return app('json')->fail(400336);
}
}
}

View File

@@ -0,0 +1,144 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin;
use app\Request;
use app\services\other\CacheServices;
use app\services\system\attachment\SystemAttachmentServices;
use crmeb\services\CacheService;
use Psr\SimpleCache\InvalidArgumentException;
use think\facade\Db;
use think\Response;
use think\response\File;
class PublicController
{
/**
* 下载文件
* @param string $key
* @return Response|File
* @throws InvalidArgumentException
*/
public function download(string $key = '')
{
if (!$key || !is_string($key)) {
return Response::create()->code(500);
}
try {
$fileName = CacheService::get($key);
if (is_array($fileName) && isset($fileName['path']) && isset($fileName['fileName']) && $fileName['path'] && $fileName['fileName'] && file_exists($fileName['path'])) {
CacheService::delete($key);
return download($fileName['path'], $fileName['fileName']);
}
} catch (\Exception $e) {
return Response::create()->code(500);
}
return Response::create()->code(500);
}
/**
* 获取erp开关
* @return mixed
*/
public function getErpConfig()
{
return app('json')->success(['open_erp' => !!sys_config('erp_open')]);
}
/**扫码上传
* @param Request $request
* @param $upload_type
* @return \think\Response
*/
public function scanUpload(Request $request)
{
[$file, $upload_type, $cache, $uploadToken, $type, $relation_id, $pid] = $request->postMore([
['file', 'file'],
['upload_type', 0],
['cache', ''],
['uploadToken', ''],
['type', 0],
['relation_id', 0],
['pid', 0]
], true);
// 类型验证
if (!$cache || !is_string($cache) || !$uploadToken || !is_string($uploadToken)) {
return app('json')->fail('参数有误,无法上传!');
}
$cacheServices = app()->make(CacheServices::class);
$service = app()->make(SystemAttachmentServices::class);
try {
if ($cacheServices->getDbCache($cache, '') == '' || $cacheServices->getDbCache($cache, '') != $uploadToken) {
return app('json')->fail('请重新扫码上传!');
}
$service->storeUpload((int)$pid, $file, $relation_id, $type, $upload_type, $uploadToken);
return app('json')->success('上传成功!');
} catch (\Exception $e) {
return app('json')->fail('上传处理异常: ' . $e->getMessage());
}
}
/**
* 服务器信息
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/9/24
*/
public function getSystemInfo()
{
$SERVER_SOFTWARE = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '无法获取';
$info['server'] = [
['name' => '服务器系统', 'require' => '类UNIX', 'value' => PHP_OS],
['name' => 'WEB环境', 'require' => 'Apache/Nginx/IIS', 'value' => $SERVER_SOFTWARE],
];
$gd_info = function_exists('gd_info') ? gd_info() : array();
$info['environment'] = [
['name' => 'PHP版本', 'require' => '8.0', 'value' => phpversion()],
['name' => 'MySql版本', 'require' => '5.7', 'value' => Db::query("SELECT VERSION()")[0]['VERSION()']],
['name' => 'MySqli', 'require' => '开启', 'value' => function_exists('mysqli_connect')],
['name' => 'Openssl', 'require' => '开启', 'value' => function_exists('openssl_encrypt')],
['name' => 'Session', 'require' => '开启', 'value' => function_exists('session_start')],
['name' => 'Safe_Mode', 'require' => '开启', 'value' => !ini_get('safe_mode')],
['name' => 'GD', 'require' => '开启', 'value' => !empty($gd_info['GD Version'])],
['name' => 'Curl', 'require' => '开启', 'value' => function_exists('curl_init')],
['name' => 'Bcmath', 'require' => '开启', 'value' => function_exists('bcadd')],
['name' => 'Upload', 'require' => '开启', 'value' => (bool)ini_get('file_uploads')],
];
$info['permissions'] = [
['name' => 'backup', 'require' => '读写', 'value' => is_readable(root_path('backup')) && is_writable(root_path('backup'))],
['name' => 'public', 'require' => '读写', 'value' => is_readable(root_path('public')) && is_writable(root_path('public'))],
['name' => 'runtime', 'require' => '读写', 'value' => is_readable(root_path('runtime')) && is_writable(root_path('runtime'))],
['name' => '.env', 'require' => '读写', 'value' => is_readable(root_path() . '.env') && is_writable(root_path() . '.env')],
['name' => '.version', 'require' => '读写', 'value' => is_readable(root_path() . '.version') && is_writable(root_path() . '.version')],
['name' => '.constant', 'require' => '读写', 'value' => is_readable(root_path() . '.constant') && is_writable(root_path() . '.constant')],
];
if (extension_loaded('swoole')) {
$info['process'] = [
['name' => '长链接', 'require' => '开启', 'value' => true],
['name' => '定时任务', 'require' => '开启', 'value' => true],
['name' => '消息队列', 'require' => '开启', 'value' => true],
];
} else {
$info['process'] = [
['name' => '长链接', 'require' => '开启', 'value' => false],
['name' => '定时任务', 'require' => '开启', 'value' => false],
['name' => '消息队列', 'require' => '开启', 'value' => false],
];
}
return app('json')->success($info);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace app\controller\admin;
use app\jobs\order\OrderPayTypeJob;
use app\jobs\user\UserBirthdayFormatJob;
use app\listener\order\Pay;
use app\listener\product\Stock;
use app\services\activity\holiday\HolidayGiftPushServices;
use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderServices;
use crmeb\services\CacheService;
use crmeb\services\wechat\SwooleResponse;
class Test
{
public function index()
{
// try {
// \crmeb\basic\__deoZdLXkdyv3S2MEnVxvEGEZQlM();
// $res = true;
// } catch (\Throwable $e) {
// $res = false;
// }
// return app('json')->success(['res' => $res]);
}
}

View File

@@ -0,0 +1,190 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\agent;
use app\controller\admin\AuthController;
use app\services\agent\AgentLevelServices;
use app\services\agent\AgentLevelTaskServices;
use FormBuilder\Exception\FormBuilderException;
use think\annotation\Inject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Response;
/**
* Class AgentLevel
* @package app\controller\admin\v1\agent
*/
class AgentLevel extends AuthController
{
/**
* @var AgentLevelServices
*/
#[Inject]
protected AgentLevelServices $services;
/**
* 显示资源列表
*
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['status', ''],
['keyword', '']
]);
return $this->success($this->services->getLevelList($where));
}
/**
* 显示创建资源表单页.
*
* @return Response
* @throws FormBuilderException
*/
public function create()
{
return $this->success($this->services->createForm());
}
/**
* 保存新建的资源
*
* @return Response
*/
public function save()
{
$data = $this->request->postMore([
['name', ''],
['grade', 0],
['image', ''],
['color', ''],
['one_brokerage', 0],
['two_brokerage', 0],
['status', 0]]);
$data['name'] = trim($data['name']);
if (!$data['name']) return $this->fail('请输入等级名称');
if (!$data['grade']) return $this->fail('请输入等级');
if (!$data['image']) return $this->fail('请选择等级背景图');
if (!$data['color']) return $this->fail('请选择字体颜色');
if ((int)$data['two_brokerage'] > (int)$data['one_brokerage']) {
return $this->fail('二级上浮整体返佣比例不能大于一级');
}
$grade = $this->services->get(['grade' => $data['grade'], 'is_del' => 0]);
if ($grade) {
return $this->fail('当前等级已存在');
}
$data['add_time'] = time();
$this->services->save($data);
return $this->success('添加等级成功!');
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return Response
* @throws FormBuilderException
*/
public function edit($id)
{
return $this->success($this->services->editForm((int)$id));
}
/**
* 保存更新的资源
*
* @param int $id
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function update($id)
{
$data = $this->request->postMore([
['name', ''],
['grade', 0],
['image', ''],
['color', ''],
['one_brokerage', 0],
['two_brokerage', 0],
['status', 0]]);
$data['name'] = trim($data['name']);
if (!$data['name']) return $this->fail('请输入等级名称');
if (!$data['grade']) return $this->fail('请输入等级');
if (!$data['image']) return $this->fail('请选择等级背景图');
if (!$data['color']) return $this->fail('请选择字体颜色');
if ((int)$data['two_brokerage'] > (int)$data['one_brokerage']) {
return $this->fail('二级上浮整体返佣比例不能大于一级');
}
if (!$levelInfo = $this->services->getLevelInfo((int)$id)) return $this->fail('编辑的等级不存在!');
$grade = $this->services->get(['grade' => $data['grade'], 'is_del' => 0]);
if ($grade && $grade['id'] != $id) {
return $this->fail('当前等级已存在');
}
$levelInfo->name = $data['name'];
$levelInfo->grade = $data['grade'];
$levelInfo->image = $data['image'];
$levelInfo->color = $data['color'];
$levelInfo->one_brokerage = $data['one_brokerage'];
$levelInfo->two_brokerage = $data['two_brokerage'];
$levelInfo->status = $data['status'];
$levelInfo->save();
return $this->success('修改成功!');
}
/**
* 删除指定资源
* @param $id
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function delete($id)
{
if (!$id) return $this->fail('参数错误,请重新打开');
$levelInfo = $this->services->getLevelInfo((int)$id);
if ($levelInfo) {
$res = $this->services->update($id, ['is_del' => 1]);
if (!$res)
return $this->fail('删除失败,请稍候再试!');
/** @var AgentLevelTaskServices $agentLevelTaskServices */
$agentLevelTaskServices = app()->make(AgentLevelTaskServices::class);
$agentLevelTaskServices->update(['level_id' => $id], ['is_del' => 1]);
}
return $this->success('删除成功!');
}
/**
* 修改状态
* @param int $id
* @param string $status
* @return mixed
*/
public function set_status($id = 0, $status = '')
{
if ($status == '' || $id == 0) return $this->fail('参数错误');
$this->services->update($id, ['status' => $status]);
return $this->success($status == 0 ? '隐藏成功' : '显示成功');
}
}

View File

@@ -0,0 +1,181 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\agent;
use app\controller\admin\AuthController;
use app\services\agent\AgentLevelTaskServices;
use FormBuilder\Exception\FormBuilderException;
use think\annotation\Inject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Response;
/**
* Class AgentLevelTask
* @package app\controller\admin\v1\agent
*/
class AgentLevelTask extends AuthController
{
/**
* @var AgentLevelTaskServices
*/
#[Inject]
protected AgentLevelTaskServices $services;
/**
* 显示资源列表
*
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['id', 0],
['status', ''],
['keyword', '']
]);
if (!$where['id']) {
return $this->fail('缺少参数ID');
}
$where['level_id'] = $where['id'];
unset($where['id']);
return $this->success($this->services->getLevelTaskList($where));
}
/**
* 显示创建资源表单页.
*
* @return Response
* @throws FormBuilderException
*/
public function create()
{
[$level_id] = $this->request->postMore([
['level_id', 0]], true);
if (!$level_id) {
return $this->fail('缺少等级ID');
}
return $this->success($this->services->createForm((int)$level_id));
}
/**
* 保存新建的资源
*
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function save()
{
$data = $this->request->postMore([
['level_id', 0],
['name', ''],
['type', ''],
['number', 0],
['desc', 0],
['sort', 0],
['status', 0]]);
if (!$data['level_id']) return $this->fail('缺少等级ID');
if (!$data['name']) return $this->fail('请输入等级名称');
if (!$data['type']) return $this->fail('请选择任务类型');
if (!$data['number']) return $this->fail('请输入限定数量');
$this->services->checkTypeTask(0, $data);
$data['add_time'] = time();
$this->services->save($data);
return $this->success('添加等级任务成功!');
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return Response
* @throws FormBuilderException
*/
public function edit($id)
{
return $this->success($this->services->editForm((int)$id));
}
/**
* 保存更新的资源
*
* @param int $id
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function update($id)
{
$data = $this->request->postMore([
['name', ''],
['type', ''],
['number', 0],
['desc', 0],
['sort', 0],
['status', 0]]);
if (!$data['name']) return $this->fail('请输入等级名称');
if (!$data['type']) return $this->fail('请选择任务类型');
if (!$data['number']) return $this->fail('请输入限定数量');
if (!$levelTaskInfo = $this->services->getLevelTaskInfo((int)$id)) return $this->fail('编辑的任务不存在!');
$this->services->checkTypeTask((int)$id, $data);
$levelTaskInfo->name = $data['name'];
$levelTaskInfo->type = $data['type'];
$levelTaskInfo->number = $data['number'];
$levelTaskInfo->desc = $data['desc'];
$levelTaskInfo->sort = $data['sort'];
$levelTaskInfo->status = $data['status'];
$levelTaskInfo->save();
return $this->success('修改成功!');
}
/**
* 删除指定资源
* @param $id
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function delete($id)
{
if (!$id) return $this->fail('参数错误,请重新打开');
$levelTaskInfo = $this->services->getLevelTaskInfo((int)$id);
if ($levelTaskInfo) {
$res = $this->services->update($id, ['is_del' => 1]);
if (!$res)
return $this->fail('删除失败,请稍候再试!');
}
return $this->success('删除成功!');
}
/**
* 修改状态
* @param int $id
* @param string $status
* @return mixed
*/
public function set_status($id = 0, $status = '')
{
if ($status == '' || $id == 0) return $this->fail('参数错误');
$this->services->update($id, ['status' => $status]);
return $this->success($status == 0 ? '隐藏成功' : '显示成功');
}
}

View File

@@ -0,0 +1,334 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\agent;
use app\controller\admin\AuthController;
use app\jobs\user\UserFriendsJob;
use app\jobs\user\UserSpreadJob;
use app\services\agent\AgentLevelServices;
use app\services\agent\AgentManageServices;
use app\services\other\AgreementServices;
use app\services\user\UserServices;
use think\annotation\Inject;
use function Sodium\compare;
/**
* 分销商管理控制器
* Class AgentManage
* @package app\controller\admin\v1\agent
*/
class AgentManage extends AuthController
{
/**
* @var AgentManageServices
*/
#[Inject]
protected AgentManageServices $services;
/**
* 分销管理列表
* @return mixed
*/
public function index()
{
$where = $this->request->getMore([
['nickname', ''],
['data', ''],
]);
return $this->success($this->services->agentSystemPage($where));
}
/**
* 分销头部统计
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function get_badge()
{
$where = $this->request->getMore([
['data', ''],
['nickname', ''],
]);
return $this->success(['res' => $this->services->getSpreadBadge($where)]);
}
/**
* 推广人列表
* @return mixed
*/
public function get_stair_list()
{
$where = $this->request->getMore([
['uid', 0],
['data', ''],
['nickname', ''],
['type', '']
]);
return $this->success($this->services->getStairList($where));
}
/**
* 推广人列表头部统计
* @return mixed
*/
public function get_stair_badge()
{
$where = $this->request->getMore([
['uid', ''],
['data', ''],
['nickname', ''],
['type', ''],
]);
return $this->success(['res' => $this->services->getSairBadge($where)]);
}
/**
* 统计推广订单列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function get_stair_order_list()
{
$where = $this->request->getMore([
['uid', 0],
['data', ''],
['order_id', ''],
['type', ''],
['nickname', '']
]);
return $this->success($this->services->getStairOrderList((int)$where['uid'], $where));
}
/**
* 统计推广订单头部统计
* @return mixed
*/
public function get_stair_order_badge()
{
return $this->success();
}
/**
* 查看公众号推广二维码
* @param int $uid
* @return json
* */
public function look_code($uid = '', $action = '')
{
if (!$uid || !$action) return $this->fail('缺少参数');
try {
if (method_exists($this, $action)) {
$res = $this->$action($uid);
if ($res)
return $this->success($res);
else
return $this->fail(isset($res['msg']) ? $res['msg'] : '获取失败,请稍后再试!');
} else
return $this->fail('暂无此方法');
} catch (\Exception $e) {
return $this->fail('获取推广二维码失败,请检查您的微信配置', ['line' => $e->getLine(), 'messag' => $e->getMessage()]);
}
}
/**
* 获取公众号二维码
* */
public function wechant_code($uid)
{
$qr_code = $this->services->wechatCode((int)$uid);
if (isset($qr_code['url']))
return ['code_src' => $qr_code['url']];
else
return $this->fail('获取失败,请稍后再试!');
}
/**
* 查看小程序推广二维码
* @param string $uid
*/
public function look_xcx_code($uid = '')
{
if (!strlen(trim($uid))) {
return $this->fail('缺少参数');
}
return $this->success($this->services->lookXcxCode((int)$uid));
}
/**
* 查看H5推广二维码
* @param string $uid
* @return mixed|string
*/
public function look_h5_code($uid = '')
{
if (!strlen(trim($uid))) return $this->fail('缺少参数');
return $this->success($this->services->lookH5Code((int)$uid));
}
/**
* 解除单个用户的推广权限
* @param int $uid
* */
public function delete_spread($uid)
{
if (!$uid) $this->fail('缺少参数');
return $this->success($this->services->delSpread((int)$uid) ? '解除成功' : '解除失败');
}
/**
* 修改上级推广人
* @param UserServices $services
* @return mixed
*/
public function editSpread(UserServices $services)
{
[$uid, $spreadUid] = $this->request->postMore([
[['uid', 'd'], 0],
[['spread_uid', 'd'], 0],
], true);
if (!$uid || !$spreadUid) {
return $this->fail('缺少参数');
}
if ($uid == $spreadUid) {
return $this->fail('上级推广人不能为自己');
}
$userInfo = $services->get($uid);
if (!$userInfo) {
return $this->fail('用户不存在');
}
if (!$services->count(['uid' => $spreadUid])) {
return $this->fail('上级用户不存在');
}
if ($userInfo->spread_uid == $spreadUid) {
return $this->fail('当前推广人已经是所选人');
}
$spreadInfo = $services->get($spreadUid);
if ($spreadInfo->spread_uid == $uid) {
return $this->fail('上级推广人不能为自己下级');
}
$userInfo->spread_uid = $spreadUid;
$userInfo->spread_time = time();
$userInfo->division_id = $spreadInfo->division_id;
$userInfo->agent_id = $spreadInfo->agent_id;
$userInfo->staff_id = $spreadInfo->staff_id;
$userInfo->save();
//记录推广绑定关系
UserSpreadJob::dispatch([(int)$uid, (int)$spreadUid]);
//记录好友关系
UserFriendsJob::dispatch([(int)$uid, (int)$spreadUid]);
return $this->success('修改成功');
}
/**
* 取消推广员推广资格
* @param $uid
* @return mixed
*/
public function delete_system_spread($uid)
{
if (!$uid) $this->fail('缺少参数');
return $this->success($this->services->delSystemSpread((int)$uid) ? '取消成功' : '取消失败');
}
/**
* 获取赠送分销等级表单
* @param $uid
* @return mixed
*/
public function getLevelForm(AgentLevelServices $services, $uid)
{
if (!$uid) $this->fail('缺少参数');
return $this->success($services->levelForm((int)$uid));
}
/**
* 赠送分销等级
* @param AgentLevelServices $services
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function giveAgentLevel(AgentLevelServices $services)
{
[$uid, $id] = $this->request->postMore([
[['uid', 'd'], 0],
[['id', 'd'], 0],
], true);
if (!$uid || !$id) {
return $this->fail('缺少参数');
}
return $this->success($services->givelevel((int)$uid, (int)$id) ? '赠送成功' : '赠送失败');
}
/**
* 保存分销说明
* @param $id
* @param AgreementServices $agreementServices
* @return mixed
*/
public function setAgentAgreement($id, AgreementServices $agreementServices)
{
$data = $this->request->postMore([
['type', 2],
['title', ""],
['content', ''],
['status', ''],
]);
$data['title'] = $data['title'] ?: '分销说明';
return $this->success($agreementServices->saveAgreement($data, (int)$id));
}
/**
* 获取分销说明
* @param AgreementServices $agreementServices
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getAgentAgreement(AgreementServices $agreementServices)
{
$list = $agreementServices->getAgreementBytype(2);
if ($list && isset($list['title'])) $list['title'] = $list['title'] ?: '分销说明';
return $this->success($list);
}
/**
* 分销方式
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/9/5
*/
public function promoterMode($type = 1)
{
$list = [];
$list[] = ['text' => '全部', 'val' => 0];
$list[] = ['text' => '一级推广人', 'val' => 1];
if (sys_config('brokerage_level') == 2) {
$list[] = ['text' => '二级推广人', 'val' => 2];
}
if ($type == 1 && sys_config('division_open') == 1) {
$list[] = ['text' => '事业部', 'val' => 3];
$list[] = ['text' => '代理商', 'val' => 4];
$list[] = ['text' => '员工', 'val' => 5];
}
return $this->success(compact('list'));
}
}

View File

@@ -0,0 +1,374 @@
<?php
namespace app\controller\admin\v1\agent;
use app\controller\admin\AuthController;
use app\services\agent\DivisionApplyServices;
use app\services\agent\DivisionServices;
use think\annotation\Inject;
class Division extends AuthController
{
#[Inject]
protected DivisionServices $services;
/**
* 事业部/代理商/员工列表
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function divisionList()
{
$where = $this->request->getMore([
['division_type', 0],
['keyword', '', '', 'division_name'],
]);
if (!in_array($where['division_type'], [1, 2, 3])) {
return $this->fail('参数错误');
}
$data = $this->services->getDivisionList($where);
return $this->success($data);
}
/**
* 下级代理商/员工列表
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function divisionDownList()
{
$where = $this->request->getMore([
['division_type', 0],
['nickname', ''],
['uid', 0],
]);
if ($where['division_type'] == 2) {
$where['division_id'] = $where['uid'];
} elseif ($where['division_type'] == 3) {
$where['agent_id'] = $where['uid'];
}
unset($where['uid']);
$data = $this->services->getDivisionList($where);
return $this->success($data);
}
/**
* 事业部添加表单
* @param $uid
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function getDivisionForm($uid)
{
return $this->success($this->services->getDivisionForm($uid));
}
/**
* 保存事业部
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function saveDivision()
{
$data = $this->request->postMore([
['uid', 0],
['aid', 0],
['division_percent', 0],
['division_end_time', ''],
['division_status', 1],
['account', ''],
['phone', ''],
['pwd', ''],
['conf_pwd', ''],
['division_name', ''],
['roles', []],
['image', []]
]);
$this->services->saveDivision($data);
return $this->success('保存成功');
}
/**
* 代理商添加表单
* @param $uid
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function getDivisionAgentForm($uid)
{
return $this->success($this->services->getDivisionAgentForm($uid));
}
/**
* 保存代理商
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function saveDivisionAgent()
{
$data = $this->request->postMore([
['division_name', ''],
['division_id', 0],
['uid', 0],
['image', []],
['division_percent', 0],
['division_end_time', ''],
['division_status', 1],
]);
$this->services->saveDivisionAgent($data);
return $this->success('保存成功');
}
/**
* 员工添加表单
* @param $uid
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function getDivisionStaffForm($uid)
{
return $this->success($this->services->getDivisionStaffForm($uid));
}
/**
* 保存员工
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function saveDivisionStaff()
{
$data = $this->request->postMore([
['uid', 0],
['division_percent', 0],
['agent_id', 0],
['image', []],
]);
$this->services->saveDivisionStaff($data);
return $this->success('保存成功');
}
/**
* 删除事业部/代理商/员工
* @param $uid
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function deleteDivision($uid)
{
$this->services->deleteDivision($uid);
return $this->success('删除成功');
}
/**
* 设置状态
* @param $uid
* @param $status
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function setStatus($uid, $status)
{
$this->services->setStatus($uid, $status);
return $this->success('设置成功');
}
/**
* 代理商申请列表
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function applyList()
{
$where = $this->request->getMore([
['status', ''],
['keyword', ''],
]);
$where['division_id'] = $this->adminInfo['division_id'];
return $this->success(app()->make(DivisionApplyServices::class)->applyList($where));
}
/**
* 申请审核表单
* @param $id
* @param $type
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function applyExamine($id, $type)
{
return $this->success(app()->make(DivisionApplyServices::class)->applyExamine($id, $type));
}
/**
* 审核保存
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function applyExamineSave()
{
$data = $this->request->postMore([
['type', 0],
['id', 0],
['division_percent', ''],
['division_end_time', ''],
['division_status', ''],
['refusal_reason', 0]
]);
app()->make(DivisionApplyServices::class)->applyExamineSave($data);
return $this->success($data['type'] == 1 ? '审核通过' : '拒绝成功');
}
/**
* 申请删除
* @param $id
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function applyDelete($id)
{
app()->make(DivisionApplyServices::class)->applyDelete($id);
return $this->success('删除成功');
}
/**
* 事业部订单
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function divisionOrder()
{
$where = $this->request->getMore([
['time', '',],
['field_key', ''],
['real_name', ''],
['division_id', ''],
['division_agent_id', ''],
]);
$adminInfo = $this->request->adminInfo();
return $this->success($this->services->divisionOrder($adminInfo, $where));
}
/**
* 获取事业部选项列表
* @return \think\Response
*/
public function divisionOption()
{
return $this->success($this->services->divisionOption());
}
/**
* 获取代理商选项列表
* @param int $division_id 事业部ID
* @return \think\Response
*/
public function agentOption($division_id)
{
return $this->success($this->services->agentOption($division_id));
}
/**
* 事业部统计基础信息
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function divisionStatistics()
{
$adminInfo = $this->request->adminInfo();
$divisionId = $adminInfo['division_id'];
return $this->success($this->services->divisionStatistics($divisionId));
}
/**
* 事业部统计趋势
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function divisionTrend()
{
[$time] = $this->request->getMore([
['time', '']
], true);
$adminInfo = $this->request->adminInfo();
$divisionId = $adminInfo['division_id'];
return $this->success($this->services->divisionTrend($time, $divisionId));
}
/**
* 事业部统计排行
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/26
*/
public function divisionRanking()
{
$adminInfo = $this->request->adminInfo();
$divisionId = $adminInfo['division_id'];
return $this->success($this->services->divisionRanking($divisionId));
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace app\controller\admin\v1\agent;
use app\controller\admin\AuthController;
use app\services\agent\PromoterApplyServices;
use think\annotation\Inject;
class PromoterApply extends AuthController
{
/**
* @var PromoterApplyServices
*/
#[Inject]
protected PromoterApplyServices $services;
/**
* 分销员申请列表
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function applyList()
{
$where = $this->request->getMore([
['status', ''],
['keyword', ''],
]);
return $this->success($this->services->applyList($where));
}
/**
* 申请审核
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function applyExamine($id)
{
return $this->success($this->services->applyExamine($id));
}
/**
* 申请审核保存
* @param $id
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2025/7/16
*/
public function applyExamineSave($id)
{
$data = $this->request->postMore([
['status', 0],
['refusal_reason', ''],
]);
$this->services->applyExamineSave($id, $data);
return $this->success($data['status'] == 1 ? '审核通过' : '拒绝申请');
}
/**
* 申请删除
* @param $id
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2024/8/21
*/
public function applyDelete($id)
{
$this->services->applyDelete($id);
return $this->success('删除成功');
}
}

View File

@@ -0,0 +1,136 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\cms;
use app\controller\admin\AuthController;
use app\services\article\ArticleServices;
use think\annotation\Inject;
/**
* 文章管理
* Class Article
* @package app\controller\admin\v1\cms
*/
class Article extends AuthController
{
/**
* @var ArticleServices
*/
#[Inject]
protected ArticleServices $service;
/**
* 获取列表
* @return mixed
*/
public function index()
{
$where = $this->request->getMore([
['title', ''],
['pid', 0, '', 'cid'],
]);
$data = $this->service->getList($where);
return $this->success($data);
}
/**
* 保存文章数据
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
['id', 0],
['cid', ''],
['title', ''],
['author', ''],
['image_input', ''],
['synopsis', 0],
['share_title', ''],
['share_synopsis', ''],
['sort', 0],
['url', ''],
['is_banner', 0],
['is_hot', 0],
['status', 1]
]);
$data['content'] = $this->request->param('content', '');
$this->service->save($data);
return $this->success('添加成功!');
}
/**
* 获取单个文章数据
* @param $id
* @return mixed
*/
public function read($id)
{
if ($id) {
$info = $this->service->read($id);
return $this->success($info);
} else {
return $this->fail('参数错误');
}
}
/**
* 删除文章
* @param $id
* @return mixed
* @throws \Exception
*/
public function delete($id)
{
if ($id) {
$this->service->del($id);
return $this->success('删除成功!');
} else {
return $this->fail('参数错误');
}
}
/**
* 文章关联商品
* @param int $id
* @return mixed
*/
public function relation($id)
{
if (!$id) return $this->fail('缺少参数');
[$product_id] = $this->request->postMore([
['product_id', 0]
], true);
$res = $this->service->bindProduct($id, $product_id);
if ($res) {
return $this->success('关联成功');
} else {
return $this->fail('关联失败');
}
}
/**
* 取消商品关联
* @param int $id
* @return mixed
*/
public function unrelation($id)
{
if (!$id) return $this->fail('缺少参数');
$res = $this->service->bindProduct($id);
if ($res) {
return $this->success('取消关联成功!');
} else {
return $this->fail('取消失败');
}
}
}

View File

@@ -0,0 +1,156 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\cms;
use app\controller\admin\AuthController;
use app\services\article\ArticleCategoryServices;
use crmeb\services\CacheService;
use think\annotation\Inject;
/**
* 文章分类管理
* Class ArticleCategory
* @package app\controller\admin\v1\cms
*/
class ArticleCategory extends AuthController
{
/**
* @var ArticleCategoryServices
*/
#[Inject]
protected ArticleCategoryServices $service;
/**
* 获取分类列表
* @return mixed
*/
public function index()
{
$where = $this->request->getMore([
['status', ''],
['title', ''],
['type', 0]
]);
if ($where['status'] == 'all') $where['status'] = '';
$type = $where['type'];
unset($where['type']);
if ($type == 1) {//后台选择分类使用
//过滤下架的
$where['status'] = 1;
$data = $this->service->getList($where);
$data = $data['list'];
} else {
$data = $this->service->getList($where);
}
return $this->success($data);
}
/**
* 创建新增表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function create()
{
return $this->success($this->service->createForm(0));
}
/**
* 保存新建分类
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
['title', ''],
['intr', ''],
['image', ''],
['sort', 0],
['status', 0]
]);
if (!$data['title']) {
return $this->fail('请填写分类名称');
}
$data['add_time'] = time();
$this->service->save($data);
CacheService::delete('ARTICLE_CATEGORY');
return $this->success('添加分类成功!');
}
/**
* 创建修改表单
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function edit($id)
{
return $this->success($this->service->createForm($id));
}
/**
* 保存修改分类
* @param $id
* @return mixed
*/
public function update($id)
{
$data = $this->request->postMore([
['id', 0],
['title', ''],
['intr', ''],
['image', ''],
['sort', 0],
['status', 0]
]);
$this->service->update($data);
CacheService::delete('ARTICLE_CATEGORY');
return $this->success('修改成功!');
}
/**
* 删除文章分类
* @param $id
* @return mixed
*/
public function delete($id)
{
$this->service->del($id);
CacheService::delete('ARTICLE_CATEGORY');
return $this->success('删除成功!');
}
/**
* 修改文章分类状态
* @param int $id
* @param int $status
* @return mixed
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function set_status($id, $status)
{
if ($status == '' || $id == 0) return $this->fail('参数错误');
$this->service->setStatus($id, $status);
CacheService::delete('ARTICLE_CATEGORY');
return $this->success($status == 0 ? '隐藏成功' : '显示成功');
}
/**
* 获取文章分类
* @return mixed
*/
public function categoryList()
{
return $this->success($this->service->getArticleCategory());
}
}

View File

@@ -0,0 +1,255 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\community;
use app\controller\admin\AuthController;
use app\services\community\CommunityCacheServices;
use app\services\community\CommunityServices;
use think\annotation\Inject;
/**
* 社区
* Class StoreCategory
* @package app\admin\controller\v1\marketing\video
*/
class Community extends AuthController
{
/**
* @var CommunityServices
*/
#[Inject]
protected CommunityServices $services;
/**
* 显示资源列表头部
* @return mixed
*/
public function type_header()
{
$where = $this->request->getMore([
['data', '', '', 'time'],//时间
['topic_id', ''],//话题
['star', ''],//推荐指数
['content_type', ''],//内容类型1:图文2视频
['keyword', ''],//关键字搜索
['is_verify', ''],//是否审核
['type', ''],//内容来源
]);
$where['is_del'] = 0;
return $this->success($this->services->getHeader($where));
}
/**
* 社区列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['data', '', '', 'time'],//时间
['topic_id', ''],//话题
['star', ''],//推荐指数
['content_type', ''],//内容类型1:图文2社区内容
['keyword', ''],//关键字搜索
['is_verify', ''],//关键字搜索
['type', ''],//内容来源
]);
$where['is_del'] = 0;
return $this->success($this->services->getList($where, ['topic'], 'id desc'));
}
/**
* 获取社区内容信息
* @param $id
* @return mixed
*/
public function info($id)
{
if (!$id) return $this->fail('缺少参数');
return $this->success($this->services->getDetail((int)$id, 0, true));
}
/**
* 保存新增分类
* @return mixed
*/
public function save($id)
{
$data = $this->request->postMore([
['content_type', 1],//内容类型1:图文2视频
['title', ''],//标题
['content', ''],//内容
['image', ''],//封面
['video_url', ''],//视频地址
['slider_image', []],//图集
['topic_id', []],//关联话题
['topic_name', []],//关联话题
['product_id', []],//关联商品
['status', 1],//状态
['is_recommend', 1],//推荐
['star', 1],//推荐指数
['sort', 0],//排序
]);
if (!$data['title']) {
$this->fail('请输入社区内容标题');
}
if (!$data['topic_id']) {
$this->fail('请至少选择一个话题');
}
$data['image'] = !$data['image'] && $data['slider_image'] ? ($data['slider_image'][0] ?? '') : $data['image'];//封面图
$data['slider_image'] = json_encode($data['slider_image']);
$data['relation_id'] = 0;
$data['is_verify'] = 1;
$data['verify_time'] = time();
$id = $id ?: 0;
$is_admin = true;
if ($id) {
$communityInfo = $this->services->getCommunityInfo($id);
if ($communityInfo['type'] != 0) $is_admin = false;
$data['relation_id'] = $communityInfo['relation_id'];
}
$this->services->saveData($data, $id, $is_admin);
return $this->success('添加社区内容成功!');
}
/**
* 设置推荐星级表单
* @param $id
* @return \think\Response
*/
public function setStarForm($id)
{
if ($id == '') return $this->fail('缺少参数');
return $this->success($this->services->setStarForm($id));
}
/**
* 设置推荐星级
* @param $id
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function setStar($id)
{
[$star] = $this->request->postMore([
['star', 1],
], true);
if ($id == '') return $this->fail('缺少参数');
$this->services->getCommunityInfo((int)$id);
$this->services->update($id, ['star' => $star]);
return $this->success('设置成功');
}
/**
* 修改状态
* @param string $is_show
* @param string $id
*/
public function setStatus($id = '', $status = '')
{
if ($status == '' || $id == '') return $this->fail('缺少参数');
$this->services->update($id, ['status' => $status]);
event('community.operate', [$id]);
return $this->success($status == 1 ? '显示成功' : '隐藏成功');
}
/**
* 审核表单
* @param $id
* @return mixed
*/
public function verifyForm($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
return $this->success($this->services->verifyForm($id));
}
/**
* 强制下架
* @param $id
* @param $recommend
* @return mixed
*/
public function takeDownForm($id)
{
if ($id == '') return $this->fail('缺少参数');
$info = $this->services->get($id);
if (!$info) {
$this->fail('社区内容不存在');
}
return $this->success($this->services->verifyForm((int)$id, 2));
}
/**
* 审核
* @param string $is_show
* @param string $id
* @return mixed
*/
public function setVerify($id = '')
{
if (!$id) {
return $this->fail('缺少参数');
}
$data = $this->request->getMore([
['is_verify', 1],
['refusal', '']
]);
if (in_array($data['is_verify'], [-1, -2]) && !$data['refusal']) {
return $this->fail('请输入原因');
}
$data['verify_time'] = time();
$info = $this->services->get($id);
if (!$info) {
return $this->fail('社区内容不存在');
}
$this->services->update((int)$id, $data);
if ($data['is_verify'] == 1) {
/** @var CommunityCacheServices $communityCacheServices */
$communityCacheServices = app()->make(CommunityCacheServices::class);
$communityCacheServices->setCommunityNewest($info['relation_id'], $id);
}
event('community.operate', [$id, 1]);
return $this->success('操作成功');
}
/**
* 删除社区内容
* @param $id
* @return mixed
*/
public function delete($id)
{
if ($id == '') return $this->fail('缺少参数');
$this->services->communityDelete($id, 0, true);
return $this->success('删除成功!');
}
public function saveAllAiCommunity()
{
[$data] = $this->request->postMore([
['data', []]
], true);
$this->services->saveAllAiCommunity($data);
return $this->success('保存成功');
}
}

View File

@@ -0,0 +1,224 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\community;
use think\annotation\Inject;
use think\db\exception\DbException;
use app\controller\admin\AuthController;
use app\services\community\CommunityCommentServices;
use app\services\community\CommunityServices;
/**
* 社区评论
* Class VideoComment
* @package app\admin\controller\v1\marketing\video
*/
class CommunityComment extends AuthController
{
/**
* @var CommunityCommentServices
*/
#[Inject]
protected CommunityCommentServices $services;
/**
* 显示资源列表
*
* @return \think\Response
* @throws DbException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['is_verify', ''],//审核状态
['keyword', ''],//关键词
['field_key', ''],//关键词key
['time', ''],//时间
['community_id', ''],//社区内容ID
['is_reply', 1],//是否是一级评论
['reply_id', ''],//社区评论 id
]);
$list = $this->services->sysPage($where);
return $this->success($list);
}
/**
* 获取评论回复列表
* @param $id
* @return mixed
* @throws DbException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getCommentReply($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
$time = $this->request->get('data', '');
return $this->success($this->services->getCommentReplyList((int)$id, ['time' => $time]));
}
/**
* 评论回复表单
* @param $id
* @return mixed
*/
public function replyForm($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
return $this->success($this->services->replayForm($id));
}
/**
* 管理员回复评论
* @param $id
* @return mixed
*/
public function setReply($id)
{
$data = $this->request->postMore([
['content', '']
]);
$info = $this->services->get($id);
if (!$info) {
return $this->fail('评论不存在');
}
if (!$data['content']) {
return $this->fail('评价内容不能为空');
}
$community_id = $info['community_id'];
$data['ip'] = $this->request->ip();
$data['is_verify'] = 1;
$data['type'] = 0;
$this->services->saveComment($community_id, $data, $id);
return $this->success('回复成功!');
}
/**
* 审核表单
* @param $id
* @return mixed
*/
public function verifyForm($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
return $this->success($this->services->verifyForm($id));
}
/**
* 屏蔽
* @param $id
* @param $recommend
* @return mixed
*/
public function setStatus($id, $status)
{
if ($id == '') return $this->fail('缺少参数');
$info = $this->services->get($id);
if (!$info) {
$this->fail('社区内容不存在');
}
$info->is_show = $status;
$info->save();
event('community.comment.operate', [$id]);
return $this->success('操作成功');
}
/**
* 审核
* @param string $is_show
* @param string $id
* @return mixed
*/
public function setVerify($id = '')
{
if (!$id) {
return $this->fail('缺少参数');
}
$data = $this->request->getMore([
['is_verify', 1],
['refusal', '']
]);
// if (in_array($data['is_verify'], [-1, -2]) && !$data['refusal']) {
// return $this->fail('请输入原因');
// }
$this->services->update((int)$id, $data);
event('community.comment.operate', [$id, 1]);
return $this->success('操作成功');
}
/**
* 创建虚拟评论表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function fictitiousComment($id)
{
return $this->success($this->services->createForm((int)$id));
}
/**
* 保存虚拟评论
* @return mixed
*/
public function saveFictitiousComment()
{
$data = $this->request->postMore([
['type', 0],
['nickname', ''],
['avatar', ''],
['content', ''],
['community_id', 0],
['add_time', 0]
]);
if (!$data['community_id']) {
return $this->fail('社区内容不能为空');
}
if (!$data['content']) {
return $this->fail('评价内容不能为空');
}
$community_id = (int)$data['community_id'];
unset($data['community_id']);
$data['ip'] = $this->request->ip();
$data['is_verify'] = 1;
$data['is_reply'] = 1;
$this->services->saveComment($community_id, $data);
return $this->success('添加成功!');
}
/**
* 删除评论
* @param $id
* @return \think\Response
* User: liusl
* DateTime: 2024/8/29 10:19
*/
public function delete($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
$id = (int)$id;
$this->services->commentDelete($id, 0, true);
return $this->success('删除成功');
}
}

View File

@@ -0,0 +1,152 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\community;
use app\controller\admin\AuthController;
use app\Request;
use app\services\community\CommunityTopicServices;
use crmeb\exceptions\AdminException;use think\annotation\Inject;
/**
* 社区话题
* Class CommunityTopic
* @package app\controller\admin\v1\community
*/
class CommunityTopic extends AuthController
{
/**
* @var CommunityTopicServices
*/
#[Inject]
protected CommunityTopicServices $services;
/**
* 获取社区话题列表
* @param Request $request
* @return mixed
*/
public function index(Request $request)
{
$where = $request->postMore([
['name', ''],//标题
['is_recommend', ''],//推荐
['status', ''],//状态
]);
$data['type'] = 0;
$data['relation_id'] = 0;
return $this->success($this->services->sysPage($where));
}
/**
* 获取所有话题列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function allTopic()
{
return $this->success($this->services->getAllTopic([],true));
}
/**
* 生成新增表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function create($id = '')
{
return $this->success($this->services->createForm($id));
}
/**
* 保存新增社区话题
* @return mixed
*/
public function save($id)
{
$data = $this->request->postMore([
['name', ''],
['sort', 0],
['is_recommend', 0],
['status', 0],
]);
if (!$data['name']) {
return $this->fail('请输入话题名称');
}
$topic = $this->services->getOne(['name' => $data['name'], 'is_del' => 0]);
if ($topic && (!$id || ($id && $topic['id'] != $id)) ) {
return $this->fail('话题已存在');
}
$data['type'] = 0;
$data['relation_id'] = 0;
if ($id) {
$res = $this->services->update($id, $data);
} else {
$data['add_time'] = time();
$res = $this->services->save($data);
}
if (!$res) return $this->fail('保存失败');
return $this->success('保存成功!');
}
/**
* 设置社区话题是否显示
* @param $id
* @param $status
* @return mixed
*/
public function setStatus($id, $status)
{
($status == '' || $id == '') && $this->fail('缺少参数');
$res = $this->services->update((int)$id, ['status' => (int)$status]);
if ($res) {
return $this->success('设置成功');
} else {
return $this->fail('设置失败');
}
}
/**
* 设置社区话题是否显示
* @param $id
* @param $hot
* @return mixed
*/
public function setHot($id, $hot)
{
($hot == '' || $id == '') && $this->fail('缺少参数');
$res = $this->services->update((int)$id, ['is_recommend' => (int)$hot]);
if ($res) {
return $this->success('设置成功');
} else {
return $this->fail('设置失败');
}
}
/**
* 删除社区话题
* @param $id
* @return mixed
*/
public function delete($id)
{
if (!$id || !$this->services->count(['id' => $id, 'is_del' => 0])) {
return $this->fail('删除的数据不存在');
}
$this->services->update((int)$id, ['is_del' => 1]);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,725 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\diy;
use app\controller\admin\AuthController;
use app\services\activity\newcomer\StoreNewcomerServices;
use app\services\activity\video\VideoServices;
use app\services\article\ArticleServices;
use app\services\diy\DiyServices;
use app\services\other\CacheServices;
use app\services\product\category\StoreProductCategoryServices;
use app\services\product\product\StoreProductServices;
use crmeb\exceptions\AdminException;
use think\annotation\Inject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
/**
* Class Diy
* @package app\controller\admin\v1\diy
*/
class Diy extends AuthController
{
/**
* @var DiyServices
*/
#[Inject]
protected DiyServices $services;
/**
* DIY列表
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getList()
{
$where = $this->request->getMore([
['status', ''],
['type', 1],
['name', ''],
['version', ''],
]);
$data = $this->services->getDiyList($where);
return $this->success($data);
}
/**
* 修改模版名称
* @param int $id
* @return \think\Response
* User: liusl
* DateTime: 2023/12/27 14:43
*/
public function updateName(int $id)
{
[$name] = $this->request->postMore([
['name', '']
], true);
$info = $this->services->get($id);
if (!$info) {
return $this->fail('数据不存在');
}
if ($info['name'] == $name) {
return $this->fail('模版名称无任何修改');
}
$info->name = $name;
$info->save();
return $this->success('修改成功');
}
/**
* 保存资源
* @param int $id
* @return mixed
*/
public function saveData(int $id = 0)
{
$data = $this->request->postMore([
['name', ''],
['title', ''],
['value', ''],
['type', 1],
['cover_image', ''],
['is_show', 0],
['is_bg_color', 0],
['is_bg_pic', 0],
['bg_tab_val', 0],
['color_picker', ''],
['bg_pic', ''],
]);
$value = is_string($data['value']) ? json_decode($data['value'], true) : $data['value'];
$infoDiy = $id ? $this->services->get($id, ['is_diy']) : [];
// if ($infoDiy && $infoDiy['is_diy']) {
foreach ($value as $key => &$item) {
if ($item['name'] === 'goodList') {
if (isset($item['selectConfig']['list'])) {
unset($item['selectConfig']['list']);
}
if (isset($item['goodsList']['list']) && is_array($item['goodsList']['list'])) {
$limitMax = config('database.page.limitMax', 50);
if (isset($item['numConfig']['val']) && isset($item['tabConfig']['tabVal']) && $item['tabConfig']['tabVal'] == 0 && $item['numConfig']['val'] > $limitMax) {
return $this->fail('您设置得商品个数超出系统限制,最大限制' . $limitMax . '个商品');
}
$item['goodsList']['ids'] = array_column($item['goodsList']['list'], 'id');
unset($item['goodsList']['list'], $item['productList']['list']);
}
} elseif ($item['name'] === 'articleList') {
if (isset($item['selectList']['list']) && is_array($item['selectList']['list'])) {
unset($item['selectList']['list']);
}
} elseif ($item['name'] === 'promotionList') {
if (isset($item['tabConfig']['list']) && $item['tabConfig']['list']) {
$list = $item['tabConfig']['list'];
foreach ($list as &$tabValue) {
if (isset($tabValue['goodsList']['list']) && is_array($tabValue['goodsList']['list'])) {
$limitMax = config('database.page.limitMax', 50);
if (isset($tabValue['numConfig']['val']) && isset($tabValue['tabConfig']['tabVal']) && $tabValue['tabConfig']['tabVal'] == 0 && $tabValue['numConfig']['val'] > $limitMax) {
return $this->fail('您设置得商品个数超出系统限制,最大限制' . $limitMax . '个商品');
}
$tabValue['goodsList']['ids'] = array_column($tabValue['goodsList']['list'], 'id');
}
unset($tabValue['goodsList']['list'], $item['productList']['list']);
}
$item['tabConfig']['list'] = $list;
}
} elseif ($item['name'] === 'newVip') {
unset($item['newVipList']['list']);
} elseif ($item['name'] === 'shortVideo') {
unset($item['videoList']);
}
}
$data['value'] = json_encode($value);
$data['version'] = uniqid();
return $this->success($id ? '修改成功' : '保存成功', ['id' => $this->services->saveData($id, $data)]);
}
/**
* 删除模板
* @param $id
* @return mixed
*/
public function del($id)
{
$this->services->del($id);
return $this->success('删除成功');
}
/**
* 使用模板
* @param $id
* @return mixed
*/
public function setStatus($id)
{
return $this->success($this->services->setStatus($id));
}
/**
* 获取一条数据
* @param int $id
* @return mixed
*/
public function getInfo($id, StoreProductServices $services, StoreNewcomerServices $newcomerServices, VideoServices $videoServices)
{
if (!(int)$id) return $this->fail('参数错误');
$info = $this->services->get((int)$id);
if ($info) {
$info = $info->toArray();
} else {
return $this->fail('模板不存在');
}
$info['value'] = json_decode($info['value'], true);
if ($info['value']) {
/** @var ArticleServices $articleServices */
$articleServices = app()->make(ArticleServices::class);
/** @var StoreProductCategoryServices $storeCategoryServices */
$storeCategoryServices = app()->make(StoreProductCategoryServices::class);
if ($info['is_diy']) {
$limitMax = config('database.page.limitMax', 50);
foreach ($info['value'] as &$item) {
switch ($item['name']) {
case 'goodList'://商品列表
$typeConfig = $item['typeConfig']['activeValue'] ?? 0;
$where = [];
$num = $item['numberConfig']['val'] ?? $limitMax;
$sort = $item['goodsSort']['type'] ?? 0;
if ($sort == 1) {
$where['salesOrder'] = 'desc';
} elseif ($sort == 2) {
$where['priceOrder'] = 'desc';
}
$item['goodsList']['list'] = [];
// $where['type'] = [0, 2];
$where['is_show'] = 1;
$where['is_del'] = 0;
$where['is_verify'] = 1;
switch ($typeConfig) {
case 1://指定商品
$where['ids'] = $item['goodsList']['ids'] ?? [];
$item['goodsList']['list'] = $services->getSearchList($where, 0, 0, ['id,store_name,cate_id,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,stock,activity,ot_price,spec_type,recommend_image,unit_name,is_vip,vip_price'], '', []);
break;
case 2://指定品牌
$where['brand_id'] = $item['brandList']['brandVal'] ?? [];
$item['productList']['list'] = $services->getSearchList($where, 0, $num, ['id,store_name,cate_id,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,stock,activity,ot_price,spec_type,recommend_image,unit_name,is_vip,vip_price'], '', []);
break;
case 3://指定分类
$cateIds = $item['classList']['classVal'] ?? [];
if ($cateIds) {
// $ids = $storeCategoryServices->getColumn(['pid' => $cateIds], 'id');
// if ($ids) {
// $cateIds = array_unique(array_merge($cateIds, $ids));
$where['cate_id'] = $cateIds;
// }
}
$item['productList']['list'] = $services->getSearchList($where, 0, $num, ['id,store_name,cate_id,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,stock,activity,ot_price,spec_type,recommend_image,unit_name,is_vip,vip_price'], '', []);
break;
case 4://商品标签
$storeLabelIds = $item['goodsLabel']['activeValue'] ?? [];
if ($storeLabelIds) {
$where['store_label_id'] = $storeLabelIds;
}
$item['productList']['list'] = $services->getSearchList($where, 0, $num, ['id,store_name,cate_id,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,stock,activity,ot_price,spec_type,recommend_image,unit_name,is_vip,vip_price'], '', []);
break;
}
break;
case 'articleList'://文章
$data = [];
if ($item['selectConfig']['activeValue'] ?? 0) {
$data = $articleServices->getList(['cid' => $item['selectConfig']['activeValue'] ?? 0], 0, $item['numConfig']['val'] ?? 0);
}
$item['selectList']['list'] = $data['list'] ?? [];
break;
case 'promotionList'://促销列表
if (isset($item['tabConfig']['list']) && $item['tabConfig']['list']) {
$list = $item['tabConfig']['list'];
if ($list) {
foreach ($list as &$tabValue) {
$where = [];
//选择方式
$selectValue = $tabValue['tabVal'] ?? 0;
$num = $tabValue['numConfig']['val'] ?? $limitMax;
$sort = $tabValue['goodsSort'] ?? 0;
if ($sort == 1) {
$where['salesOrder'] = 'desc';
} elseif ($sort == 2) {
$where['priceOrder'] = 'desc';
}
$tabValue['goodsList']['list'] = [];
if ($selectValue == 1 && isset($tabValue['goodsList']['ids']) && count($tabValue['goodsList']['ids'])) {//手动选商品
$where['ids'] = $tabValue['goodsList']['ids'];
$tabValue['goodsList']['list'] = $services->getSearchList($where, 0, 0, ['id,store_name,cate_id,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,stock,activity,ot_price,spec_type,recommend_image,unit_name,is_vip,vip_price'], '', []);
} elseif ((isset($tabValue['selectConfig']['activeValue']) && $tabValue['selectConfig']['activeValue']) || (isset($tabValue['goodsLabel']['activeValue']) && $tabValue['goodsLabel']['activeValue'])) {//选分类 、标签
$cateIds = $tabValue['selectConfig']['activeValue'] ?? [];
if ($cateIds) {
$ids = $storeCategoryServices->getColumn(['pid' => $cateIds], 'id');
if ($ids) {
$cateIds = array_unique(array_merge($cateIds, $ids));
$where['cate_id'] = $cateIds;
}
}
$storeLabelIds = $tabValue['goodsLabel']['activeValue'] ?? [];
if ($storeLabelIds) {
$where['store_label_id'] = $storeLabelIds;
}
$where['type'] = [0, 2];
$where['is_show'] = 1;
$where['is_del'] = 0;
$where['is_verify'] = 1;
$where['ids'] = '';
$tabValue['productList']['list'] = $services->getSearchList($where, 0, $num, ['id,store_name,cate_id,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,stock,activity,ot_price,spec_type,recommend_image,unit_name,is_vip,vip_price'], '', []);
}
}
$item['tabConfig']['list'] = $list;
}
}
break;
case 'newVip'://新人专享
$item['newVipList']['list'] = $newcomerServices->getDiyNewcomerList();
break;
// case 'shortVideo'://短视频
// $item['videoList'] = $videoServices->getDiyVideoList(0);
// break;
}
}
} else {
if ($info['value']) {
if (isset($info['value']['d_goodList']['goodsList'])) {
$info['value']['d_goodList']['goodsList']['list'] = [];
}
if (isset($info['value']['d_goodList']['goodsList']['ids']) && count($info['value']['d_goodList']['goodsList']['ids'])) {
$info['value']['d_goodList']['goodsList']['list'] = $services->getSearchList(['ids' => $info['value']['d_goodList']['goodsList']['ids']]);
}
}
}
}
return $this->success(compact('info'));
}
/**
* 获取uni-app路径
* @return mixed
*/
public function getUrl()
{
$url = sys_data('uni_app_link');
if ($url) {
foreach ($url as &$link) {
$link['url'] = $link['link'];
$link['parameter'] = trim($link['param']);
}
} else {
/** @var CacheServices $cache */
$cache = app()->make(CacheServices::class);
$url = $cache->getDbCache('uni_app_url', null);
}
return $this->success(compact('url'));
}
/**
* 获取商品分类
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getCategory()
{
/** @var StoreProductCategoryServices $categoryService */
$categoryService = app()->make(StoreProductCategoryServices::class);
return $this->success($categoryService->cascaderList());
}
/**
* 获取商品
* @return mixed
*/
public function getProduct()
{
$where = $this->request->getMore([
['id', ''],//搜索分类
['salesOrder', ''],//销量排序
['priceOrder', ''],//价格排序
['supplier_id', 0],//供应商ID
['store_id', 0],//门店ID
['store_label_id', ''],//标签ID
['ids', ''],//商品ID
['brand_id', ''],//品牌ID
]);
$cateId = $where['id'];
$where['is_show'] = 1;
$where['is_del'] = 0;
$where['is_verify'] = 1;
$where['type'] = [0, 2];
$where['show_type'] = [0, 1];
if ($where['supplier_id']) {
$where['relation_id'] = $where['supplier_id'];
$where['type'] = 2;
} elseif ($where['store_id']) {
$where['relation_id'] = $where['store_id'];
$where['type'] = 1;
} else {
$where['pid'] = 0;
}
unset($where['supplier_id'], $where['store_id']);
unset($where['id']);
/** @var StoreProductCategoryServices $storeCategoryServices */
$storeCategoryServices = app()->make(StoreProductCategoryServices::class);
if ($cateId) {
$cateId = is_string($cateId) ? [$cateId] : $cateId;
// $cateId = array_merge($cateId, $storeCategoryServices->getColumn(['pid' => $cateId], 'id'));
$cateId = array_unique(array_diff($cateId, [0]));
}
$where['cate_id'] = $cateId;
// if ($storeCategoryServices->value(['id' => $id], 'pid')) {
// $where['sid'] = $id;
// } else {
// $where['cid'] = $id;
// }
[$page, $limit] = $this->services->getPageValue();
/** @var StoreProductServices $productService */
$productService = app()->make(StoreProductServices::class);
$list = $productService->getSearchList($where, $page, $limit, ['id,store_name,cate_id,image,IFNULL(sales, 0) + IFNULL(ficti, 0) as sales,price,stock,activity,ot_price,spec_type,recommend_image,unit_name,is_vip,vip_price'], '', []);
return $this->success($list);
}
/**
* 获取提货点自提开启状态
* @return mixed
*/
public function getStoreStatus()
{
$data['store_status'] = 0;
if (sys_config('store_func_status', 1)) {
$data['store_status'] = sys_config('store_self_mention', 0);
}
return $this->success($data);
}
/**
* 设置模版默认数据
* @param $id
* @return mixed
*/
public function setDefaultData($id)
{
if (!$id) return $this->fail('参数错误');
$info = $this->services->get($id);
if ($info) {
$info->default_value = $info->value;
$info->update_time = time();
$info->save();
event('diy.update');
return $this->success('设置成功');
} else {
return $this->fail('模板不存在');
}
}
/**
* 还原模板数据
* @param $id
* @return mixed
*/
public function Recovery($id)
{
if (!$id) return $this->fail('参数错误');
$info = $this->services->get($id);
if ($info) {
$info->value = $info->default_value;
$info->update_time = time();
$info->save();
event('diy.update');
return $this->success('还原成功');
} else {
return $this->fail('模板不存在');
}
}
/**
* 获取二级分类
* @return mixed
*/
public function getByCategory()
{
$where = $this->request->getMore([
['pid', -1],
['name', '']
]);
/** @var StoreProductCategoryServices $categoryServices */
$categoryServices = app()->make(StoreProductCategoryServices::class);
return $this->success($categoryServices->getALlByIndex($where));
}
/**
* 获取首页推荐不同类型商品的轮播图和商品
* @param $type
* @return mixed
*/
public function groom_list($type)
{
$info['list'] = $this->get_groom_list($type);
return $this->success($info);
}
/**
* 实际获取方法
* @param $type
* @return array
*/
protected function get_groom_list($type, int $num = 0)
{
$where = [];
if ($type == 1) {// 精品推荐
$where['is_best'] = 1;
// 精品推荐个数
} else if ($type == 2) {// 热门榜单
$where['is_hot'] = 1;
} else if ($type == 3) {// 首发新品
$where['is_new'] = 1;
} else if ($type == 4) {// 促销单品
$where['is_benefit'] = 1;
} else if ($type == 5) {// 会员商品
$where['is_vip'] = 1;
}
/** @var StoreProductServices $services */
$services = app()->make(StoreProductServices::class);
return $services->getRecommendProduct(0, $where, $num);
}
/**
* 一键换色
* @param $status
* @return mixed
*/
public function colorChange($status, $type)
{
$colorData = $this->request->postMore([
['aux_color', ''],
['gradient_color', ''],
['light_color', ''],
['theme_color', ''],
['theme_type', '']
]);
if (!$status) return $this->fail('参数错误');
$info = $this->services->get(['template_name' => $type, 'type' => 3]);
if ($info) {
$info->value = $status;
$info->color_data = json_encode($colorData);
$info->update_time = time();
$info->save();
event('diy.update');
$this->services->cacheStrUpdate('color_change_' . $type . '_3', $status);
return $this->success('设置成功');
} else {
return $this->fail('模板不存在');
}
}
/**
* 获取颜色选择和分类模板选择
* @param $type
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getColorChange($type)
{
$colorData = $this->services->getColorChange((string)$type);
$status = (int)$colorData['value'];
$color_data = json_decode($colorData['color_data'], true);
return $this->success(compact('status', 'color_data'));
}
/**
* 获取单个diy小程序预览二维码
* @param $id
* @return mixed
*/
public function getRoutineCode($id)
{
$image = $this->services->getRoutineCode((int)$id);
return $this->success(compact('image'));
}
/**
* 获取会员中心数据
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getMember()
{
$data = $this->services->getMemberData();
return $this->success($data);
}
/**
* 保存个人中心数据
* @return mixed
*/
public function memberSaveData()
{
$data = $this->request->postMore([
['member', []],
['routine_my_banner', []],
['routine_my_menus', []]
]);
$this->services->memberSaveData($data);
event('diy.update');
return $this->success('保存成功');
}
/**
* 获取开屏广告
* @return mixed
*/
public function getOpenAdv()
{
/** @var CacheServices $cacheServices */
$cacheServices = app()->make(CacheServices::class);
$data = $cacheServices->getDbCache('open_adv', '');
$data = $data ?: [];
$data['time'] = (float)($data['time'] ?? 3);
$data['interval_time'] = (float)($data['interval_time'] ?? 24);
return app('json')->success($data);
}
/**
* 保存开屏广告
* @return mixed
*/
public function openAdvAdd()
{
$data = $this->request->postMore([
['status', 0],//状态
['time', 0],//广告时间
['interval_time', 24],//再次出现间隔时间
['type', 'pic'],//类型
['value', []],
['video_link', '']
]);
if (!$data['type']) {
$data['type'] = 'pic';
}
/** @var CacheServices $cacheServices */
$cacheServices = app()->make(CacheServices::class);
$cacheServices->setDbCache('open_adv', $data);
event('diy.update');
return app('json')->success('保存成功');
}
/**
* 获取商品详情数据
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getProductDetailDiy()
{
$data = $this->services->getProductDetailDiy();
return $this->success($data);
}
/**
* 保存商品详情数据
* @return mixed
*/
public function saveProductDetailDiy()
{
[$content] = $this->request->postMore([
['product_detail_diy', []],
], true);
$this->services->saveProductDetailDiy($content);
event('diy.update');
return $this->success('保存成功');
}
/**
* 获取商品分类数据
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getProductCategoryDiy()
{
$data = $this->services->getProductCategoryDiy();
return $this->success($data);
}
/**
* 保存商品分类数据
* @return mixed
*/
public function saveProductCategoryDiy()
{
[$content] = $this->request->postMore([
['product_category_diy', []],
], true);
$this->services->saveProductCategoryDiy($content);
event('diy.update');
return $this->success('保存成功');
}
/**
* 获取新人礼商品
* @param StoreNewcomerServices $newcomerServices
* @return mixed
*/
public function newcomerList(StoreNewcomerServices $newcomerServices)
{
$where = $this->request->getMore([
['priceOrder', ''],
['salesOrder', ''],
]);
return app('json')->success($newcomerServices->getDiyNewcomerList(0, $where));
}
/**
* 获取悬浮窗数据
* @return \think\Response
* User: liusl
* DateTime: 2024/9/6 10:11
*/
public function getSuspendedDiy()
{
$data = $this->services->getSuspendedDiy();
return $this->success($data);
}
/**
* 保存悬浮窗数据
* @return \think\Response
* User: liusl
* DateTime: 2024/9/6 10:11
*/
public function saveSuspendedDiy()
{
[$content] = $this->request->postMore([
['suspended_window_diy', []],
], true);
$this->services->saveSuspendedDiy($content);
event('diy.update');
return $this->success('保存成功');
}
}

View File

@@ -0,0 +1,115 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\diy;
use app\controller\admin\AuthController;
use app\services\diy\DiyServices;
use app\services\diy\PageCategoryServices;
use app\services\diy\PageLinkServices;
use app\services\product\category\StoreProductCategoryServices;
use think\annotation\Inject;
use think\facade\App;
/**
* Class PageLink
* @package app\controller\admin\v1\diy
*/
class PageLink extends AuthController
{
/**
* @var PageLinkServices
*/
#[Inject]
protected PageLinkServices $services;
/**
* 获取页面链接分类
* @return mixed
*/
public function getCategory(PageCategoryServices $services)
{
return $this->success($services->getCategroyList());
}
/**
* 获取页面链接
* @param $cate_id
* @return mixed
*/
public function getLinks($cate_id, PageCategoryServices $pageCategoryServices)
{
if (!$cate_id) return $this->fail('缺少参数');
$category = $pageCategoryServices->get((int)$cate_id);
if (!$category) {
return $this->fail('页面分类不存在');
}
switch ($category['type']) {
case 'special':
/** @var DiyServices $diyServices */
$diyServices = app()->make(DiyServices::class);
$data = $diyServices->getDiyList(['type' => [1, 2]]);
break;
case 'product_category':
[$pid] = $this->request->getMore([
['pid', 0]
], true);
/** @var StoreProductCategoryServices $storeCategoryServices */
$storeCategoryServices = app()->make(StoreProductCategoryServices::class);
$data = $storeCategoryServices->getList(['pid' => $pid, 'is_show' => 1]);
break;
default:
$data = $this->services->getLinkList(['cate_id' => $cate_id]);
break;
}
return $this->success($data);
}
/**
* 保存链接
* @param $cate_id
* @param PageCategoryServices $pageCategoryServices
* @return mixed
*/
public function saveLink($cate_id, PageCategoryServices $pageCategoryServices)
{
$data = $this->request->getMore([
['name', ''],
['url', '']
]);
if (!$cate_id || !$data['name'] || !$data['url']) return $this->fail('缺少参数');
$category = $pageCategoryServices->get((int)$cate_id);
if (!$category) {
return $this->fail('页面分类不存在');
}
$data['cate_id'] = $cate_id;
$data['add_time'] = time();
if (!$this->services->save($data)) {
return $this->fail('添加失败');
}
return $this->success('添加成功');
}
/**
* 删除链接
* @param $id
* @return mixed
*/
public function del($id)
{
if (!$id) return $this->fail('参数错误');
$this->services->del($id);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace app\controller\admin\v1\finance;
use app\controller\admin\AuthController;
use app\services\system\CapitalFlowServices;
use think\annotation\Inject;
class CapitalFlow extends AuthController
{
/**
* @var CapitalFlowServices
*/
#[Inject]
protected CapitalFlowServices $services;
/**
* 资金流水
* @return mixed
*/
public function getFlowList()
{
$where = $this->request->getMore([
['time', ''],
['trading_type', 0],
['keywords', ''],
['ids', ''],
['export', 0]
]);
$date = $this->services->getFlowList($where);
return app('json')->success($date);
}
/**
* 资金流水备注
* @param $id
* @return mixed
*/
public function setMark($id)
{
$data = $this->request->postMore([
['mark', '']
]);
$this->services->setMark($id, $data);
return app('json')->success('备注成功!');
}
/**
* 账单记录
* @return mixed
*/
public function getFlowRecord()
{
$where = $this->request->getMore([
['type', 'day'],
['time', '']
]);
$data = $this->services->getFlowRecord($where);
return app('json')->success($data);
}
}

View File

@@ -0,0 +1,102 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\finance;
use app\services\user\UserBillServices;
use app\services\user\UserBrokerageServices;
use app\services\user\UserMoneyServices;
use think\annotation\Inject;
use app\controller\admin\AuthController;
/**
* Class Finance
* @package app\controller\admin\v1\finance
*/
class Finance extends AuthController
{
/**
* @var UserBillServices
*/
#[Inject]
protected UserBillServices $services;
/**
* 筛选类型
*/
public function bill_type(UserMoneyServices $services)
{
return $this->success($services->bill_type());
}
/**
* 资金记录
*/
public function list(UserMoneyServices $services)
{
$where = $this->request->getMore([
['start_time', ''],
['end_time', ''],
['nickname', ''],
['limit', 20],
['page', 1],
['type', ''],
]);
return $this->success($services->getMoneyList($where));
}
/**
* 用户佣金记录(用户列表)
* @return mixed
*/
public function get_commission_list(UserBrokerageServices $services)
{
$where = $this->request->getMore([
['nickname', ''],
['price_max', ''],
['price_min', ''],
['sum_number', 'normal'],
['brokerage_price', 'normal'],
['date', '', '', 'time']
]);
return $this->success($services->getCommissionList($where));
}
/**
* 佣金详情用户信息
* @param $id
* @return mixed
*/
public function user_info(UserBrokerageServices $services, $id)
{
return $this->success($services->user_info((int)$id));
}
/**
* 获取用户佣金列表
* @param UserBrokerageServices $services
* @param string $id
* @return mixed
*/
public function getUserBrokeragelist(UserBrokerageServices $services, $id = '')
{
if ($id == '') return $this->fail('缺少参数');
$where = $this->request->getMore([
['start_time', ''],
['end_time', ''],
['nickname', '']
]);
$where['uid'] = (int)$id;
return $this->success($services->getBrokerageList($where));
}
}

View File

@@ -0,0 +1,166 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\finance;
use app\controller\admin\AuthController;
use app\services\user\UserExtractServices;
use think\annotation\Inject;
use think\Request;
/**
* Class UserExtract
* @package app\controller\admin\v1\finance
*/
class UserExtract extends AuthController
{
/**
* @var UserExtractServices
*/
#[Inject]
protected UserExtractServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['status', ''],
['extract_type', ''],
['nireid', '', '', 'like'],
['data', '', '', 'time'],
]);
if (isset($where['extract_type']) && $where['extract_type'] == 'wx') {
$where['extract_type'] = 'weixin';
}
return $this->success($this->services->index($where));
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
if (!$id) return $this->fail('数据不存在');
return $this->success($this->services->edit((int)$id));
}
/**
* 保存更新的资源
*
* @param \think\Request $request
* @param int $id
* @return \think\Response
*/
public function update(Request $request, $id)
{
if (!$id) return $this->fail('缺少参数!');
$id = (int)$id;
$UserExtract = $this->services->getExtract($id);
if (!$UserExtract) $this->fail('数据不存在');
if ($UserExtract['extract_type'] == 'alipay') {
$data = $this->request->postMore([
'real_name',
'mark',
'extract_price',
'alipay_code',
]);
if (!$data['real_name']) return $this->fail('请输入姓名');
if ($data['extract_price'] <= -1) return $this->fail('请输入提现金额');
if (!$data['alipay_code']) return $this->fail('请输入支付宝账号');
} else if ($UserExtract['extract_type'] == 'weixin') {
$data = $this->request->postMore([
'real_name',
'mark',
'extract_price',
'wechat',
]);
if ($data['extract_price'] <= -1) return $this->fail('请输入提现金额');
if (!$data['wechat']) return $this->fail('请输入微信账号');
} else {
$data = $this->request->postMore([
'real_name',
'extract_price',
'mark',
'bank_code',
'bank_address',
]);
if (!$data['real_name']) return $this->fail('请输入姓名');
if ($data['extract_price'] <= -1) return $this->fail('请输入提现金额');
if (!$data['bank_code']) return $this->fail('请输入银行卡号');
if (!$data['bank_address']) return $this->fail('请输入开户行');
}
return $this->success($this->services->update($id, $data) ? '修改成功' : '修改失败');
}
/**
* 拒绝
* @param $id
* @return mixed
*/
public function refuse($id)
{
if (!$id) $this->fail('缺少参数');
$data = $this->request->postMore([
['message', '']
]);
return $this->success($this->services->refuse((int)$id, $data['message']) ? '操作成功' : '操作失败');
}
/**
* 通过
* @param $id
* @return mixed
*/
public function adopt($id)
{
if (!$id) $this->fail('缺少参数');
return $this->success($this->services->adopt((int)$id) ? '操作成功' : '操作失败');
}
/**
* 备注表单
* @param $id
* @return \think\Response
* User: liusl
* DateTime: 2024/9/12 10:47
*/
public function remarkForm($id)
{
if (!$id) return $this->fail('数据不存在');
return $this->success($this->services->remarkForm((int)$id));
}
/**
* 备注
* @param $id
* @return \think\Response
* User: liusl
* DateTime: 2024/9/12 10:47
*/
public function remarkUpdate($id)
{
if (!$id) $this->fail('缺少参数');
[$make] = $this->request->postMore([
['mark', '']
], true);
if (!$make) return $this->fail('请输入备注');
$res = $this->services->update($id, ['mark' => $make]);
return $this->success($res ? '操作成功' : '操作失败');
}
}

View File

@@ -0,0 +1,34 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\finance;
use app\common\controller\Recharge;
use app\controller\admin\AuthController;
use app\services\user\UserRechargeServices;
use think\annotation\Inject;
/**
* Class UserRecharge
* @package app\controller\admin\v1\finance
*/
class UserRecharge extends AuthController
{
use Recharge;
/**
* @var UserRechargeServices
*/
#[Inject]
protected UserRechargeServices $services;
}

View File

@@ -0,0 +1,134 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\activityBackground;
use app\controller\admin\AuthController;
use app\services\activity\activityBackground\ActivityBackgroundServices;
use think\annotation\Inject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Response;
/**
* 活动背景图
* Class ActivityBackground
* @package app\controller\admin\v1\marketing\activityBackground
*/
class ActivityBackground extends AuthController
{
/**
* @var ActivityBackgroundServices
*/
#[Inject]
protected ActivityBackgroundServices $services;
/**
* 显示资源列表
*
* @return Response
*/
public function index(): Response
{
$where = $this->request->getMore([
['time', '', '', 'activity_time'],
[['status', 's'], '', '', 'start_status'],
[['name', 's'], ''],
['create_time', '', '', 'time']
]);
$where['promotions_type'] = 6;
$where['type'] = 1;
$where['store_id'] = 0;
$where['pid'] = 0;
$where['is_del'] = 0;
return $this->success($this->services->systemPage($where));
}
/**
* 详情
* @param $id
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getInfo($id): Response
{
$info = $this->services->getInfo((int)$id);
return $this->success(compact('info'));
}
/**
* 保存促销活动
* @param $id
* @return mixed
*/
public function save($id)
{
$data = $this->request->postMore([
[['name', 's'], ''],//名称
['image', ''],//活动图
[['product_partake_type', 'd'], 1],//商品参与类型
['product_id', []],//关联商品
['brand_id', []],//关联品牌ID
['store_label_id', []],//关联商品标签ID
['section_time', []],//时间
['status', 1],//状态
[['sort', 'd'], 0],//排序
]);
$data['promotions_type'] = 6;
if (!$data['name']) {
return $this->fail('请输入活动名称');
}
if (!$data['image']) {
return $this->fail('请选择活动图');
}
if ($data['product_partake_type'] == 2 && !$data['product_id']) {
return $this->fail('请选择要参与活动的商品');
}
if ($data['product_partake_type'] == 4 && !$data['brand_id']) {
return $this->fail('请选择要参与活动的商品品牌');
}
if ($data['product_partake_type'] == 5 && !$data['store_label_id']) {
return $this->fail('请选择要参与活动的商品标签');
}
$this->services->saveData((int)$id, $data);
return $this->success('保存成功');
}
/**
* 删除指定资源
*
* @param int $id
* @return Response
*/
public function delete($id)
{
if (!$id) return $this->fail('缺少参数');
$this->services->update(['id|pid' => $id], ['is_del' => 1]);
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function setStatus($id, $status)
{
$this->services->update($id, ['status' => $status, 'update_time' => time()]);
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
}

View File

@@ -0,0 +1,127 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\activityFrame;
use app\controller\admin\AuthController;
use app\services\activity\activityFrame\ActivityFrameServices;
use think\annotation\Inject;
/**
* 活动边框
* Class ActivityFrame
* @package app\controller\admin\v1\marketing\activityFrame
*/
class ActivityFrame extends AuthController
{
/**
* @var ActivityFrameServices
*/
#[Inject]
protected ActivityFrameServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['time', '', '', 'activity_time'],
[['status', 's'], '', '', 'start_status'],
[['name', 's'], ''],
['create_time', '', '', 'time']
]);
$where['promotions_type'] = 5;
$where['type'] = 1;
$where['store_id'] = 0;
$where['pid'] = 0;
$where['is_del'] = 0;
return $this->success($this->services->systemPage($where));
}
/**
* 详情
* @param $id
* @return mixed
*/
public function getInfo($id)
{
$info = $this->services->getInfo((int)$id);
return $this->success(compact('info'));
}
/**
* 保存活动边框
* @param $id
* @return mixed
*/
public function save($id)
{
$data = $this->request->postMore([
[['name', 's'], ''],//名称
['image', ''],//活动图
[['product_partake_type', 'd'], 1],//商品参与类型
['product_id', []],//关联商品
['brand_id', []],//关联品牌ID
['store_label_id', []],//关联商品标签ID
['section_time', []],//时间
['status', 1],//状态
[['sort', 'd'], 0],//排序
]);
$data['promotions_type'] = 5;
if (!$data['name']) {
return $this->fail('请输入活动名称');
}
if (!$data['image']) {
return $this->fail('请选择活动图');
}
if ($data['product_partake_type'] == 2 && !$data['product_id']) {
return $this->fail('请选择要参与活动的商品');
}
if ($data['product_partake_type'] == 4 && !$data['brand_id']) {
return $this->fail('请选择要参与活动的商品品牌');
}
if ($data['product_partake_type'] == 5 && !$data['store_label_id']) {
return $this->fail('请选择要参与活动的商品标签');
}
$this->services->saveData((int)$id, $data);
return $this->success('保存成功');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id) return $this->fail('缺少参数');
$this->services->update(['id|pid' => $id], ['is_del' => 1]);
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function setStatus($id, $status)
{
$this->services->update($id, ['status' => $status, 'update_time' => time()]);
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
}

View File

@@ -0,0 +1,232 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\bargain;
use app\controller\admin\AuthController;
use app\services\activity\bargain\StoreBargainServices;
use app\services\activity\bargain\StoreBargainUserHelpServices;
use app\services\activity\bargain\StoreBargainUserServices;
use think\annotation\Inject;
/**
* 砍价管理
* Class StoreBargain
* @package app\controller\admin\v1\marketing
*/
class StoreBargain extends AuthController
{
/**
* @var StoreBargainServices
*/
#[Inject]
protected StoreBargainServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['start_status', ''],
['status', ''],
['store_name', ''],
]);
$where['is_del'] = 0;
$list = $this->services->getStoreBargainList($where);
return $this->success($list);
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return \think\Response
*/
public function save($id)
{
$data = $this->request->postMore([
['title', ''],
['info', ''],
['unit_name', ''],
['section_time', []],
['images', []],
['bargain_max_price', 0],
['bargain_min_price', 0],
['sort', 0],
['give_integral', 0],
['is_hot', 0],
['status', 0],
['product_id', 0],
['description', ''],
['attrs', []],
['items', []],
['temp_id', 0],
['rule', ''],
['num', 1],
['copy', 0],
['bargain_num', 1],
['people_num', 1],
['is_support_refund', 1],//是否支持退款
['delivery_type', []],//物流方式
['freight', 1],//运费设置
['postage', 0],//邮费
['custom_form', ''],//自定义表单
['system_form_id', 0],//系统表单ID
['product_type', 0],//商品类型
['is_commission', 0],//是否参与返佣
]);
$this->validate($data, \app\validate\admin\marketing\StoreBargainValidate::class, 'save');
if ($data['section_time']) {
[$start_time, $end_time] = $data['section_time'];
if (strtotime($end_time) < time()) {
return $this->fail('活动结束时间不能小于当前时间');
}
}
$bragain = [];
if ($id) {
$bragain = $this->services->get((int)$id);
if (!$bragain) {
return $this->fail('数据不存在');
}
}
//限制编辑
if ($data['copy'] == 0 && $bragain) {
if ($bragain['stop_time'] < time()) {
return $this->fail('活动已结束,请重新添加或复制');
}
}
if ($data['copy'] == 1) {
$id = 0;
unset($data['copy']);
}
$this->services->saveData($id, $data);
return $this->success('保存成功');
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
$info = $this->services->getInfo($id);
return $this->success(compact('info'));
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
$this->services->update($id, ['is_del' => 1]);
$this->services->cacheTag()->clear();
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_status($id, $status)
{
$info = $this->services->get((int)$id);
if ($info['stop_time'] < time() && $status == 1) {
return $this->fail('活动已结束,不能修改状态');
}
$this->services->update($id, ['status' => $status]);
$this->services->cacheTag()->clear();
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
/**
* 砍价列表
* @return mixed
*/
public function bargainList()
{
$where = $this->request->getMore([
['status', ''],
['data', '', '', 'time'],
]);
/** @var StoreBargainUserServices $bargainUserService */
$bargainUserService = app()->make(StoreBargainUserServices::class);
$list = $bargainUserService->bargainUserList($where);
return $this->success($list);
}
/**
* 砍价信息
* @param $id
* @return mixed
*/
public function bargainListInfo($id)
{
/** @var StoreBargainUserHelpServices $bargainUserHelpService */
$bargainUserHelpService = app()->make(StoreBargainUserHelpServices::class);
$list = $bargainUserHelpService->getHelpList($id);
return $this->success(compact('list'));
}
/**
* 砍价统计
* @param $id
* @return mixed
*/
public function bargainStatistics($id)
{
$data = $this->services->bargainStatistics((int)$id);
return app('json')->success($data);
}
/**
* 砍价统计列表
* @param $id
* @return mixed
*/
public function bargainStatisticsList($id)
{
$where = $this->request->getMore([
['real_name', ''],
]);
$data = $this->services->bargainStatisticsList((int)$id, $where);
return app('json')->success($data);
}
/**
* 砍价统计订单
* @param $id
* @return mixed
*/
public function bargainStatisticsOrder($id)
{
$where = $this->request->getMore([
['real_name', ''],
['status', '']
]);
return app('json')->success($this->services->bargainStatisticsOrder((int)$id, $where));
}
}

View File

@@ -0,0 +1,132 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\card;
use app\controller\admin\AuthController;
use app\services\activity\card\CardBatchServices;
use app\validate\admin\marketing\card\CardBatchValidate;
use think\annotation\Inject;
/**
* 卡次
* Class CardBatch
* @package app\admin\controller\card
*/
class CardBatch extends AuthController
{
/**
* @var CardBatchServices
*/
#[Inject]
protected CardBatchServices $services;
public function index()
{
$where = $this->request->getMore([
['name', ''],
['time', ''],
]);
return app('json')->success($this->services->getList($where));
}
/**
* 保存卡批次信息
*
* 该方法用于处理卡批次的创建请求它从请求中获取必要的数据,
* 进行数据验证,检查卡号前缀和后缀的唯一性,并保存数据
* @return \think\Response
* User: liusl
* DateTime: 2025/5/9 12:18
*/
public function save()
{
// 获取请求数据,包括卡次名称、卡号前缀、卡号后缀、总数量、卡密内容和卡密位数
$data = $this->request->postMore([
['name', ''],//卡次名称
['card_prefix', ''],//卡号前缀
['card_suffix', ''],//卡号后缀
['total_num', ''],//卡密数量
['pwd_type', []],//卡密内容
['pwd_num', 0],//卡密位数
]);
// 验证请求数据,确保数据的合法性
validate(CardBatchValidate::class)->check($data);
$this->validate($data, CardBatchValidate::class, 'save');
// 组合卡号前缀和后缀,以便进行唯一性检查
$data['prefix'] = $data['card_prefix'] . $data['card_suffix'];
// 检查数据库中是否已存在相同的卡号前缀和后缀组合,以确保卡号的唯一性
if ($this->services->get(['prefix' => $data['prefix'], 'is_del' => 0])) {
return app('json')->fail('卡号已存在');
}
// 调用服务层方法保存卡批次数据,并返回保存结果
$res = $this->services->saveData($data);
// 返回成功响应,通知用户卡批次已成功添加
return app('json')->success('添加成功');
}
/**
* 更新卡次信息
*
* 该方法用于更新特定卡次的名称它首先检查是否提供了有效的ID,然后获取当前的卡次信息,
* 并尝试更新名称如果更新成功,它会返回一个成功的响应,否则返回一个失败的响应
* @param $id
* @return \think\Response
* User: liusl
* DateTime: 2025/5/9 12:18
*/
public function update($id)
{
[$name] = $this->request->postMore([
['name', ''],//卡次名称
], true);
if (!$id) {
return app('json')->fail('缺少参数');
}
$info = $this->services->get($id);
if (!$info) {
return app('json')->fail('数据不存在');
}
$info->name = $name;
if ($info->save()) {
return app('json')->success('修改成功');
} else {
return app('json')->fail('修改失败');
}
}
public function delete($id)
{
if (!$id) {
return app('json')->fail('缺少参数');
}
$info = $this->services->get($id);
if (!$info) {
return app('json')->fail('数据不存在');
}
if ($this->services->del($id)) {
return app('json')->success('删除成功');
} else {
return app('json')->fail('删除失败');
}
}
public function tree()
{
return app('json')->success($this->services->getTree());
}
}

View File

@@ -0,0 +1,71 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\card;
use app\controller\admin\AuthController;
use app\services\activity\card\CardCodeServices;
use think\annotation\Inject;
/**
* 卡密
* Class CardCode
* @package app\admin\controller\card
*/
class CardCode extends AuthController
{
/**
* @var CardCodeServices
*/
#[Inject]
protected CardCodeServices $services;
public function index()
{
$where = $this->request->getMore([
['field_key', ''],//卡号card_number,用户名nickname,uid
['keyword', ''],//关键字
['card_id', ''],//礼品卡 id
['batch_id', ''],//批次id
['status', ''],//状态: 0-未使用 1-已使用 2-已过期
['active_time', ''],//active_time
]);
return $this->success($this->services->getList($where));
}
public function formRemark($id)
{
return $this->success($this->services->formRemark($id));
}
public function setRemark($id)
{
[$remark] = $this->request->postMore([
['remark', '']
], true);
if (!$remark) {
return $this->fail('请输入备注');
}
$info = $this->services->get($id);
if (!$info) {
return $this->fail('数据不存在');
}
$info->remark = $remark;
if ($info->save()) {
return $this->success('修改成功');
} else {
return $this->fail('修改失败');
}
}
}

View File

@@ -0,0 +1,213 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\card;
use app\controller\admin\AuthController;
use app\services\activity\card\CardGiftRecordServices;
use app\services\activity\card\CardGiftServices;
use app\validate\admin\marketing\card\CardBatchValidate;
use app\validate\admin\marketing\card\CardGiftValidate;
use think\annotation\Inject;
/**
* 礼品卡
* Class CardGift
* @package app\admin\controller\card
*/
class CardGift extends AuthController
{
/**
* @var CardGiftServices
*/
#[Inject]
protected CardGiftServices $services;
/**
* 列表
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* User: liusl
* DateTime: 2025/5/12 09:37
*/
public function index()
{
$where = $this->request->getMore([
['name', ''],//礼品卡名称
['type', ''],//礼品卡类型 1-储值卡 2-兑换卡
['status', ''],//礼品卡状态 0-禁用 1-启用
['time', '']//添加时间
]);
return $this->success($this->services->getList($where));
}
public function save()
{
$data = $this->request->postMore([
['name', ''],//礼品卡名称
['type', 0],//礼品卡类型 1-储值卡 2-兑换卡
['batch_id', 0],//关联卡密
['total_num', 0],//总数量
['instructions', ''],//使用须知
['cover_image', ''],//封面图
['valid_type', 0],//有效期类型 0-永久有效 1-天数 2-固定时间
['fixed_time', []],//有效期
['status', 0],//礼品卡状态 0-禁用 1-启用
['sort', 0],//排序
['balance', 0],//储值金额
['exchange_type', 0],//兑换商品类型 1-固定商品打包 2-任选N件商品
['gift_num', 0],//任选 N 件
['product', []],//兑换商品
[['description', 's'], ''],//详情
]);
// 验证请求数据,确保数据的合法性
$this->validate($data, CardGiftValidate::class, 'save');
$res = $this->services->saveData($data, 0, $this->adminId);
if ($res) {
return $this->success('添加成功');
} else {
return $this->fail('添加失败');
}
}
public function read($id)
{
if (!$id) {
return $this->fail('参数错误');
}
return $this->success($this->services->getInfo($id));
}
public function update($id)
{
$data = $this->request->postMore([
['name', ''],//礼品卡名称
['type', 0],//礼品卡类型 1-储值卡 2-兑换卡
['instructions', ''],//使用须知
['cover_image', ''],//封面图
['valid_type', 0],//有效期类型 0-永久有效 1-固定时间
['fixed_time', []],//有效期
['status', 0],//礼品卡状态 0-禁用 1-启用
['sort', 0],//排序
['balance', 0],//储值金额
['exchange_type', 0],//兑换商品类型 1-固定商品打包 2-任选N件商品
['gift_num', 0],//任选 N 件
['product', []],//兑换商品
[['description', 's'], ''],//详情
]);
$this->validate($data, CardGiftValidate::class, 'update');
$res = $this->services->saveData($data, $id, $this->adminId);
if ($res) {
return $this->success('修改成功');
} else {
return $this->fail('修改失败');
}
}
public function otherForm($id)
{
if (!$id) {
return $this->fail('参数错误');
}
return $this->success($this->services->otherForm($id));
}
public function updateOther($id)
{
[$type, $number] = $this->request->postMore([
['type', 0],
['number', 0],
], true);
if (!$id) {
return $this->fail('参数错误');
}
if ($number <= 0) {
return $this->fail('数量必须大于0');
}
if ($this->services->updateOther($id, $type, $number, $this->adminId)) {
return $this->success('修改成功');
} else {
return $this->fail('修改失败');
}
}
/**
* 修改状态
* @param $id
* @param $status
* @return \think\Response
* User: liusl
* DateTime: 2025/5/12 09:38
*/
public function setStatus($id, $status)
{
$info = $this->services->get($id);
if (!$info) {
return $this->fail('礼品卡不存在');
}
$res = $this->services->update($id, ['status' => $status]);
if ($res) {
return $this->success('修改成功');
} else {
return $this->fail('修改失败');
}
}
/**
* 删除
* @param $id
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* User: liusl
* DateTime: 2025/6/3 10:49
*/
public function delete($id)
{
$this->services->delete($id);
return $this->success('删除成功');
}
/**
* 树列表
* @return \think\Response
* User: liusl
* DateTime: 2025/6/3 10:48
*/
public function tree()
{
return $this->success($this->services->getTree());
}
/**
* 记录
* @param $id
* @param CardGiftRecordServices $services
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* User: liusl
* DateTime: 2025/6/3 10:48
*/
public function giftRecordList($id, CardGiftRecordServices $services)
{
if (!$id) {
return $this->fail('参数错误');
}
return $this->success($services->getList(['gift_id' => $id]));
}
}

View File

@@ -0,0 +1,247 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\combination;
use app\controller\admin\AuthController;
use app\services\activity\combination\StoreCombinationServices;
use app\services\activity\combination\StorePinkServices;
use think\annotation\Inject;
/**
* 拼团管理
* Class StoreCombination
* @package app\admin\controller\store
*/
class StoreCombination extends AuthController
{
/**
* @var StoreCombinationServices
*/
#[Inject]
protected StoreCombinationServices $services;
/**
* 拼团列表
* @return mixed
*/
public function index()
{
$where = $this->request->getMore([
['start_status', ''],
['is_show', ''],
['store_name', '']
]);
$where['is_del'] = 0;
$list = $this->services->systemPage($where);
return $this->success($list);
}
/**
* 拼团统计
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function statistics()
{
/** @var StorePinkServices $storePinkServices */
$storePinkServices = app()->make(StorePinkServices::class);
$info = $storePinkServices->getStatistics();
return $this->success($info);
}
/**
* 详情
* @param $id
* @return mixed
*/
public function read($id)
{
$info = $info = $this->services->getInfo((int)$id);
return $this->success(compact('info'));
}
/**
* 保存新建的资源
* @param int $id
*/
public function save($id = 0)
{
$data = $this->request->postMore([
[['product_id', 'd'], 0],
[['title', 's'], ''],
[['info', 's'], ''],
[['unit_name', 's'], ''],
['images', []],
['section_time', []],
[['is_host', 'd'], 0],
[['is_show', 'd'], 0],
[['num', 'd'], 0],
[['temp_id', 'd'], 0],
[['effective_time', 'd'], 0],
[['people', 'd'], 0],
[['description', 's'], ''],
['attrs', []],
['items', []],
['num', 1],
['once_num', 1],
['sort', 0],
['copy', 0],
['virtual', 100],
['is_support_refund', 1],//是否支持退款
['delivery_type', []],//物流方式
['freight', 1],//运费设置
['postage', 0],//邮费
['custom_form', ''],//自定义表单
['system_form_id', 0],//系统表单ID
['product_type', 0],//商品类型
['is_commission', 0],//是否参与返佣
]);
$this->validate($data, \app\validate\admin\marketing\StoreCombinationValidate::class, 'save');
if ($data['section_time']) {
[$start_time, $end_time] = $data['section_time'];
if (strtotime($end_time) < time()) {
return $this->fail('活动结束时间不能小于当前时间');
}
}
$bragain = [];
if ($id) {
$bragain = $this->services->get((int)$id);
if (!$bragain) {
return $this->fail('数据不存在');
}
}
//限制编辑
if ($data['copy'] == 0 && $bragain) {
if ($bragain['stop_time'] < time()) {
return $this->fail('活动已结束,请重新添加或复制');
}
}
if ($data['num'] < $data['once_num']) {
return $this->fail('限制单次购买数量不能大于总购买数量');
}
if ($data['copy'] == 1) {
$id = 0;
unset($data['copy']);
}
$this->services->saveData($id, $data);
return $this->success('保存成功');
}
/**
* 删除指定资源
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
$this->services->update($id, ['is_del' => 1]);
$this->services->cacheTag()->clear();
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_status($id, $status)
{
$info = $this->services->get((int)$id);
if ($info['stop_time'] < time() && $status == 1) {
return $this->fail('活动已结束,不能修改状态');
}
$this->services->update($id, ['is_show' => $status]);
// 下架拼团活动,将当前拼团商品所有的拼团订单的到期时间改为当前时间,自动成团或者退款
if ($status == 0) {
app()->make(StorePinkServices::class)->update(['cid' => $id, 'status' => 1], ['stop_time' => time()]);
}
$this->services->cacheTag()->clear();
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
/**
* 拼团列表
* @return mixed
*/
public function combine_list()
{
$where = $this->request->getMore([
['status', ''],
['data', '', '', 'time'],
]);
/** @var StorePinkServices $storePinkServices */
$storePinkServices = app()->make(StorePinkServices::class);
$list = $storePinkServices->systemPage($where);
return $this->success($list);
}
/**
* 拼团人列表
* @return mixed
*/
public function order_pink($id)
{
/** @var StorePinkServices $storePinkServices */
$storePinkServices = app()->make(StorePinkServices::class);
$list = $storePinkServices->getPinkMember($id);
return $this->success(compact('list'));
}
/**
* 拼团统计
* @param $id
* @return mixed
*/
public function combinationStatistics($id)
{
$data = $this->services->combinationStatistics((int)$id);
return app('json')->success($data);
}
/**
* 活动参与人
* @param $id
* @return mixed
*/
public function combinationStatisticsList($id)
{
/** @var StorePinkServices $storePinkServices */
$storePinkServices = app()->make(StorePinkServices::class);
$list = $storePinkServices->systemPage(['cid' => $id]);
return app('json')->success($list);
}
/**
* 拼团订单
* @param $id
* @return mixed
*/
public function combinationStatisticsOrder($id)
{
$where = $this->request->getMore([
['real_name', ''],
['status', '']
]);
return app('json')->success($this->services->combinationStatisticsOrder((int)$id, $where));
}
}

View File

@@ -0,0 +1,148 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\coupon;
use app\controller\admin\AuthController;
use app\services\activity\coupon\StoreCouponProductServices;
use app\services\activity\coupon\StoreCouponService;
use think\annotation\Inject;
/**
* 优惠券制作
* Class StoreCoupon
* @package app\controller\admin\v1\marketing
*/
class StoreCoupon extends AuthController
{
/**
* @var StoreCouponService
*/
#[Inject]
protected StoreCouponService $services;
/**
* 优惠券模板列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['status', 1],
['title', ''],
]);
$data = $this->services->getList($where);
return $this->success($data);
}
/**
* 创建添加模板表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function create()
{
[$type] = $this->request->getMore(['type'], true);
return $this->success($this->services->createForm($type));
}
/**
* 保存优惠券模板
* @return mixed
*/
public function save(StoreCouponProductServices $services)
{
$data = $this->request->postMore([
['title', ''],
['image', ''],
['category_id', ''],
['coupon_price', ''],
['use_min_price', ''],
['coupon_time', ''],
['sort', ''],
['status', 0],
['type', 0]
]);
$data['product_id'] = '';
if ($data['type'] == 1) {
$this->validate($data, \app\validate\admin\marketing\StoreCouponValidate::class, 'type');
} elseif ($data['type'] == 2) {
$this->validate($data, \app\validate\admin\marketing\StoreCouponValidate::class, 'product');
$productIds = array_column($data['image'], 'product_id');
$data['product_id'] = implode(',', $productIds);
} else {
$this->validate($data, \app\validate\admin\marketing\StoreCouponValidate::class, 'save');
}
$data['add_time'] = time();
$this->services->save($data);
return $this->success('添加优惠券成功!');
}
/**
* 删除优惠券模板
* @param $id
* @return mixed
*/
public function delete($id)
{
$data['is_del'] = 1;
$this->services->update($id, $data);
return $this->success('删除成功!');
}
/**
* 立即失效优惠券模板
* @param $id
* @return mixed
*/
public function status($id)
{
$this->services->invalid($id);
return $this->success('修改成功!');
}
/**
* 发布优惠券表单
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function issue($id)
{
return $this->success($this->services->createIssue($id));
}
/**
* 保存发布优惠券信息
* @param $id
* @return mixed
*/
public function update_issue($id)
{
[$_id, $coupon_title, $rangeTime, $count, $status, $is_permanent, $full_reduction, $is_give_subscribe, $is_full_give, $is_type] = $this->request->postMore([
'id',
['coupon_title', ''],
['range_date', ['', '']],
['count', 0],
['status', 0],
['is_permanent', 0],
['full_reduction', 0],
['is_give_subscribe', 0],
['is_full_give', 0],
['is_type', 0]
], true);
$this->services->upIssue($id, $_id, $coupon_title, $rangeTime, $count, $status, $is_permanent, $full_reduction, $is_give_subscribe, $is_full_give, $is_type);
return $this->success('发布优惠劵成功!');
}
}

View File

@@ -0,0 +1,247 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\coupon;
use app\controller\admin\AuthController;
use app\services\activity\coupon\StoreCouponIssueServices;
use app\services\activity\coupon\StoreCouponProductServices;
use app\services\product\brand\StoreBrandServices;
use app\services\product\category\StoreProductCategoryServices;
use app\services\product\product\StoreProductCouponServices;
use app\services\product\product\StoreProductServices;
use think\annotation\Inject;
/**
* 已发布优惠券管理
* Class StoreCouponIssue
* @package app\controller\admin\v1\marketing
*/
class StoreCouponIssue extends AuthController
{
/**
* @var StoreCouponIssueServices
*/
#[Inject]
protected StoreCouponIssueServices $services;
/**
* 获取优惠券列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['status', 1],
['coupon_title', ''],
['receive_type', ''],
['coupon_type', ''],
['type', '', '' , 'receive'],
]);
$list = $this->services->getCouponIssueList($where);
return $this->success($list);
}
/**
* 添加优惠券
* @return mixed
*/
public function saveCoupon()
{
$data = $this->request->postMore([
['coupon_title', ''],
['coupon_price', 0.00],
['use_min_price', 0.00],
['coupon_time', 0],
['start_use_time', 0],
['end_use_time', 0],
['start_time', 0],
['end_time', 0],
['receive_type', 0],
['is_permanent', 0],
['total_count', 0],
['product_id', ''],
['category_id', []],
['brand_id', []],
['type', 0],
['sort', 0],
['status', 0],
['coupon_type', 1],
['rule', ''],
['category', 1], // 优惠券种类:1 普通券,2会员券
['receive_limit', 1],
['id', 0],
]);
if ($data['category_id']) {
$data['category_id'] = end($data['category_id']);
}
if ($data['brand_id']) {
$data['brand_id'] = end($data['brand_id']);
}
if ($data['start_time'] && $data['start_use_time']) {
if ($data['start_use_time'] < $data['start_time']) {
return $this->fail('使用开始时间不能小于领取开始时间');
}
}
if ($data['end_time'] && $data['end_use_time']) {
if ($data['end_use_time'] < $data['end_time']) {
return $this->fail('使用结束时间不能小于领取结束时间');
}
}
//复制优惠券,清空其他数据
switch ($data['type']) {
case 0://通用
$data['product_id'] = '';
$data['category_id'] = 0;
$data['brand_id'] = 0;
break;
case 1://分类
$data['product_id'] = '';
$data['brand_id'] = 0;
break;
case 2://商品
$data['category_id'] = 0;
$data['brand_id'] = 0;
break;
case 3://品牌
$data['product_id'] = '';
$data['category_id'] = 0;
break;
}
//新人券不限量
if ($data['receive_type'] == 2) {
$data['is_permanent'] = 1;
$data['total_count'] = 0;
}
if (!$data['coupon_price']) {
return $this->fail($data['coupon_type'] == 1 ? '请输入优惠券金额' : '请输入优惠券折扣');
}
if ($data['coupon_type'] == 2 && ($data['coupon_price'] < 0 || $data['coupon_price'] > 100)) {
return $this->fail('优惠券折扣为0~100数字');
}
if ($data['is_permanent'] != 1 && $data['receive_limit'] > $data['total_count']) {
return $this->fail('用户领取数量不能大于发布数量');
}
$res = $this->services->saveCoupon($data);
if ($res) return $this->success('保存成功!');
}
/**
* 修改优惠券状态
* @param $id
* @param $status
* @return mixed
*/
public function status($id, $status)
{
$this->services->update($id, ['status' => $status]);
return $this->success('修改成功');
}
/**
* 复制优惠券获取优惠券详情
* @param int $id
* @return mixed
*/
public function copy($id = 0)
{
if (!$id) return $this->fail('参数错误');
$info = $this->services->get($id);
if ($info) $info = $info->toArray();
if ($info['product_id'] != '') {
$productIds = explode(',', $info['product_id']);
/** @var StoreProductServices $product */
$product = app()->make(StoreProductServices::class);
$productImages = $product->getColumn([['id', 'in', $productIds]], 'image', 'id');
foreach ($productIds as $item) {
$info['productInfo'][] = [
'product_id' => $item,
'image' => $productImages[$item]
];
}
}
if ($info['category_id'] != '') {
/** @var StoreProductCategoryServices $categoryServices */
$categoryServices = app()->make(StoreProductCategoryServices::class);
$category = $categoryServices->get($info['category_id']);
if ($category && $category['pid']) {
$categoryPid = $categoryServices->get($category['pid']);
if ($categoryPid && $categoryPid['pid']) {
$info['category_id'] = [$categoryPid['pid'], $category['pid'], $info['category_id']];
} else {
$info['category_id'] = [$category['pid'], $info['category_id']];
}
} else {
$info['category_id'] = [$info['category_id']];
}
}
if ($info['brand_id'] != '') {
/** @var StoreBrandServices $brandServices */
$brandServices = app()->make(StoreBrandServices::class);
$brand = $brandServices->get($info['brand_id']);
if ($brand && $brand['pid']) {
$brandPid = $brandServices->get($brand['pid']);
if ($brandPid && $brandPid['pid']) {
$info['brand_id'] = [$brandPid['pid'], $brand['pid'], $info['brand_id']];
} else {
$info['brand_id'] = [$brand['pid'], $info['brand_id']];
}
} else {
$info['brand_id'] = [$info['brand_id']];
}
}
return $this->success($info);
}
/**
* 删除
* @param string $id
* @return mixed
*/
public function delete($id)
{
$this->services->update($id, ['is_del' => 1]);
/** @var StoreProductCouponServices $storeProductService */
$storeProductService = app()->make(StoreProductCouponServices::class);
//删除商品关联这个优惠券
$storeProductService->delete(['issue_coupon_id' => $id]);
/** @var StoreCouponProductServices $storeCouponProductService */
$storeCouponProductService = app()->make(StoreCouponProductServices::class);
//删除商品券辅助信息
$storeCouponProductService->delete(['coupon_id' => $id]);
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function edit($id)
{
return $this->success($this->services->createForm($id));
}
/**
* 领取记录
* @param string $id
* @return mixed|string
*/
public function issue_log($id)
{
$list = $this->services->issueLog($id);
return $this->success($list);
}
}

View File

@@ -0,0 +1,82 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\coupon;
use app\controller\admin\AuthController;
use app\jobs\BatchHandleJob;
use app\services\activity\coupon\StoreCouponIssueServices;
use app\services\activity\coupon\StoreCouponUserServices;
use app\services\other\queue\QueueServices;
use think\annotation\Inject;
/**
* 优惠券发放记录控制器
* Class StoreCategory
* @package app\admin\controller\system
*/
class StoreCouponUser extends AuthController
{
/**
* @var StoreCouponUserServices
*/
#[Inject]
protected StoreCouponUserServices $services;
/**
* 发放列表
* @return mixed
*/
public function index()
{
$where = $this->request->getMore([
['status', ''],
['coupon_title', ''],
['nickname', ''],
]);
$list = $this->services->systemPage($where);
return $this->success($list);
}
/**
* 批量发券
* @return mixed
*/
public function grant()
{
$data = $this->request->postMore([
['id', 0],
['uid', ''],
['all', 0],
['where', []],
]);
if (!$data['id']) return $this->fail('数据不存在!');
if (!$data['uid'] && $data['all'] == 0) return $this->fail('缺少参数');
/** @var StoreCouponIssueServices $issueService */
$issueService = app()->make(StoreCouponIssueServices::class);
$coupon = $issueService->get($data['id']);
if (!$coupon) {
return $this->fail('数据不存在!');
} else {
$coupon = $coupon->toArray();
}
$type = 1;//代表发放优惠券
if ($data['all'] == 0) $user = stringToIntArray($data['uid']);
if ($data['all'] == 1) $user = [];
/** @var QueueServices $queueService */
$queueService = app()->make(QueueServices::class);
$queueService->setQueueData($data['where'], 'uid', $user, $type);
//加入队列
BatchHandleJob::dispatch([$coupon, $type]);
return $this->success('后台程序已执行发放优惠券任务!');
}
}

View File

@@ -0,0 +1,152 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\discounts;
use app\controller\admin\AuthController;
use app\services\activity\discounts\StoreDiscountsServices;
use think\annotation\Inject;
/**
* 优惠套餐
* Class StoreDiscounts
* @package app\controller\admin\v1\marketing\discounts
*/
class StoreDiscounts extends AuthController
{
/**
* @var StoreDiscountsServices
*/
#[Inject]
protected StoreDiscountsServices $services;
/**
* 新增修改优惠
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function save()
{
$data = $this->request->getMore([
['id', 0],
['title', ''],
['image', ''],
['type', 0],
['is_limit', 0],
['limit_num', 0],
['link_ids', ''],
['is_time', 0],
['time', []],
['sort', 0],
['free_shipping', 0],
['status', 0],
['products', []],
['delivery_type', []],//物流方式
['freight', 1],//运费设置
['postage', 0],//邮费
['custom_form', ''],//自定义表单
['system_form_id', 0],//系统表单ID
]);
if ($data['title'] == '') return $this->fail('请填写套餐名称');
if ($data['image'] == '') return $this->fail('请选择套餐主图');
if ($data['is_limit'] && !$data['limit_num']) return $this->fail('套餐限量不能为0');
if (!count($data['products'])) $this->fail('请添加套餐商品');
foreach ($data['products'] as $item) {
if (!isset($item['items'])) $this->fail('请选择' . $item['store_name'] . '的规格');
}
if ($data['is_time'] && is_array($data['is_time'])) {
[$start, $end] = $data['is_time'];
$start = strtotime($start);
$end = strtotime($end);
if ($start > $end) {
return $this->fail('开始时间必须小于结束时间');
}
if ($start < time() || $end < time()) {
return $this->fail('套餐时间不能小于当前时间');
}
}
$msg = $data['id'] ? '编辑' : '添加';
$res = $this->services->saveDiscounts($data);
if ($res) {
return $this->success($msg . '成功');
} else {
return $this->fail($msg . '失败');
}
}
/**
* 获取优惠商品列表
* @return mixed
*/
public function getList()
{
$where = $this->request->getMore([
['type', ''],
['status', ''],
['title', '']
]);
$info = $this->services->getList($where);
return $this->success($info);
}
/**
* 获取优惠商品数据
* @param int $id
* @return mixed
*/
public function getInfo($id = 0)
{
if (!$id) return $this->fail('参数错误');
$info = $this->services->getInfo($id);
if ($info) {
return $this->success($info);
} else {
return $this->fail('获取失败');
}
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function setStatus($id, $status)
{
if (!$id) return $this->fail('参数错误');
$res = $this->services->setStatus($id, $status);
if ($res) {
return $this->success('设置成功');
} else {
return $this->fail('设置失败');
}
}
/**
* 删除优惠套餐
* @param $id
* @return mixed
*/
public function del($id)
{
if (!$id) return $this->fail('参数错误');
$res = $this->services->del($id);
if ($res) {
return $this->success('删除成功');
} else {
return $this->fail('删除失败');
}
}
}

View File

@@ -0,0 +1,376 @@
<?php
declare (strict_types=1);
namespace app\controller\admin\v1\marketing\holiday;
use app\controller\admin\AuthController;
use app\services\activity\holiday\HolidayGiftServices;
use app\services\activity\holiday\HolidayGiftRecordServices;
use app\services\activity\holiday\HolidayGiftPushServices;
use think\annotation\Inject;
/**
* 节日有礼控制器
* Class HolidayGift
* @package app\adminapi\controller\v1\activity
*/
class HolidayGift extends AuthController
{
/**
* @var HolidayGiftServices
*/
#[Inject]
protected HolidayGiftServices $services;
/**
* 节日有礼列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['name', ''],
['status', ''],
['task_type', ''],
['time', '', '', 'gift_time'],
['is_del', 0],
['push_channels', ''],
]);
return app('json')->success($this->services->getHolidayGiftList($where));
}
/**
* 获取节日有礼详情
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function detail($id)
{
if (!$id) {
return app('json')->fail('参数错误');
}
$info = $this->services->getHolidayGiftInfo((int)$id);
return app('json')->success($info);
}
/**
* 获取并处理节日有礼数据
* 从请求中获取节日有礼活动的所有参数,并进行数据处理和验证
* @return array|mixed 成功返回处理后的数据数组,失败返回错误响应
* @throws \Exception 当活动时间范围错误时抛出异常
*/
private function getHolidayGiftData()
{
$data = $this->request->postMore([
['name', ''], // 活动名称
['is_permanent', 0], // 是否永久:0-否,1-是
['start_time', []], // 活动时间范围数组[开始时间, 结束时间]
['task_type', 0], // 任务类型:1-用户生日,2-活动日期
['birthday_type', 0], // 生日类型:1-生日当天,2-生日当周,3-生日当月,0-无
['activity_date_type', 0], // 生日类型:活动日期类型:1-自定义日期,2-每月,3-每周
['activity_date', []], // 自定义活动开始结束时间
['activity_month_days', []], // 每月活动日期,多个用逗号分隔,如:1,2,4,12,27
['activity_week_days', []], // 每周活动日期,多个用逗号分隔:1-7表示周一到周日
['advance_push', 0], // 是否提前推送:0-否,1-是
['advance_days', 0], // 提前推送天数
['day_num', 0], // 天数(备用字段)
['push_time_type', 1], // 推送时段类型:1-全时段,2-指定时段
['push_start_time', ''], // 推送开始时间,格式:HH:mm
['push_end_time', ''], // 推送结束时间,格式:HH:mm
['push_user_type', 1], // 推送人群类型:1-全部人群,2-指定人群
['user_level', 0], // 用户等级数组,多个等级ID
['user_label', []], // 用户标签数组,多个标签ID
['user_tag', []], // 客户标签数组,多个标签ID
['condition_type', 1], // 条件满足类型:1-满足任一条件,2-满足全部条件
['gift_type', ''], // 赠送内容类型,多个用逗号分隔:1-优惠券,2-积分,3-多倍积分,4-余额,5-全场包邮
['coupon_ids', []], // 优惠券ID数组,多个优惠券ID
['couponName', []], // 优惠券名称数组(临时字段,后续会移除)
['integral', 0], // 赠送积分数量
['integral_multiple', 0], // 积分倍数
['balance', 0], // 赠送余额
['push_channel', []], // 推送渠道数组:1-短信,2-公众号,3-弹框广告
['wechat_image', []], // 公众号推送图片链接数组
['push_frequency', 0], // 推送频次:1-永久一次,2-每次进入,3-每天,4-每月,5-每周
['push_week_days', []], // 每周推送星期几数组:1-7表示周一到周日
['show_page', []], // 应用界面数组:1-商城首页,2-分类页,3-购物车,4-个人中心,5-支付成功,6-专题页面
['topic_ids', []], // 专题页面ID数组,多个专题ID
['status', 0], // 状态:0-关闭,1-开启
]);
// 处理时间范围
$start_time = $data['start_time'];
if ($start_time && is_array($data['start_time']) && count($data['start_time']) == 2) {
$data['start_time'] = strtotime($start_time[0]);
$data['end_time'] = strtotime($start_time[1]);
}
if (isset($data['activity_date']) && is_array($data['activity_date']) && count($data['activity_date']) == 2) {
$data['activity_start_date'] = strtotime($data['activity_date'][0]);
$data['activity_end_date'] = strtotime($data['activity_date'][1]);
}
// 处理推送频率
if (isset($data['push_frequency']) && !is_numeric($data['push_frequency'])) {
$data['push_frequency'] = intval($data['push_frequency']);
}
// 处理余额
if (isset($data['balance']) && !is_numeric($data['balance'])) {
$data['balance'] = floatval($data['balance']);
}
// 移除不需要的字段
unset($data['couponName']);
return $data;
}
/**
* 保存节日有礼
* @return mixed
*/
public function save()
{
$data = $this->getHolidayGiftData();
if (!is_array($data)) {
return $data; // 返回错误信息
}
$this->services->saveHolidayGift($data);
return app('json')->success('添加成功');
}
/**
* 修改节日有礼
* @param $id
* @return mixed
*/
public function update($id)
{
if (!$id) {
return app('json')->fail('参数错误');
}
$data = $this->getHolidayGiftData();
if (!is_array($data)) {
return $data; // 返回错误信息
}
$this->services->updateHolidayGift((int)$id, $data);
return app('json')->success('修改成功');
}
/**
* 删除节日有礼
* @param $id
* @return mixed
*/
public function delete($id)
{
if (!$id) {
return app('json')->fail('参数错误');
}
$this->services->deleteHolidayGift((int)$id);
return app('json')->success('删除成功');
}
/**
* 修改节日有礼状态
* @param $id
* @param $status
* @return mixed
*/
public function setStatus($id, $status)
{
if (!$id) {
return app('json')->fail('参数错误');
}
$this->services->setStatus((int)$id, (int)$status);
return app('json')->success($status == 1 ? '启用成功' : '关闭成功');
}
/**
* 获取节日有礼领取记录列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function recordList()
{
$where = $this->request->getMore([
['gift_id', 0],
['uid', 0],
['status', ''],
['receive_time', ''],
['is_del', 0],
]);
/** @var HolidayGiftRecordServices $service */
$service = app()->make(HolidayGiftRecordServices::class);
return app('json')->success($service->getHolidayGiftRecordList($where));
}
/**
* 获取节日有礼领取记录详情
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function recordDetail($id)
{
if (!$id) {
return app('json')->fail('参数错误');
}
/** @var HolidayGiftRecordServices $service */
$service = app()->make(HolidayGiftRecordServices::class);
$info = $service->getHolidayGiftRecordInfo((int)$id);
return app('json')->success($info);
}
/**
* 删除节日有礼领取记录
* @param $id
* @return mixed
*/
public function deleteRecord($id)
{
if (!$id) {
return app('json')->fail('参数错误');
}
/** @var HolidayGiftRecordServices $service */
$service = app()->make(HolidayGiftRecordServices::class);
$service->deleteRecord((int)$id);
return app('json')->success('删除成功');
}
/**
* 批量删除节日有礼领取记录
* @return mixed
*/
public function batchDeleteRecord()
{
$ids = $this->request->post('ids');
if (!$ids || !is_array($ids)) {
return app('json')->fail('参数错误');
}
/** @var HolidayGiftRecordServices $service */
$service = app()->make(HolidayGiftRecordServices::class);
$service->batchDeleteRecord($ids);
return app('json')->success('删除成功');
}
/**
* 获取节日有礼领取统计数据
* @return mixed
*/
public function recordStatistics()
{
$where = $this->request->getMore([
['gift_id', 0],
['is_del', 0],
]);
/** @var HolidayGiftRecordServices $service */
$service = app()->make(HolidayGiftRecordServices::class);
$statistics = $service->getRecordStatistics($where);
return app('json')->success($statistics);
}
/**
* 获取节日有礼推送记录列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function pushList()
{
$where = $this->request->getMore([
['gift_id', 0],
['uid', 0],
['push_type', ''],
['status', ''],
['push_time', ''],
['is_del', 0],
]);
/** @var HolidayGiftPushServices $service */
$service = app()->make(HolidayGiftPushServices::class);
return app('json')->success($service->getHolidayGiftPushList($where));
}
/**
* 获取节日有礼推送记录详情
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function pushDetail($id)
{
if (!$id) {
return app('json')->fail('参数错误');
}
/** @var HolidayGiftPushServices $service */
$service = app()->make(HolidayGiftPushServices::class);
$info = $service->getHolidayGiftPushInfo((int)$id);
return app('json')->success($info);
}
/**
* 删除节日有礼推送记录
* @param $id
* @return mixed
*/
public function deletePush($id)
{
if (!$id) {
return app('json')->fail('参数错误');
}
/** @var HolidayGiftPushServices $service */
$service = app()->make(HolidayGiftPushServices::class);
$service->deletePush((int)$id);
return app('json')->success('删除成功');
}
/**
* 批量删除节日有礼推送记录
* @return mixed
*/
public function batchDeletePush()
{
$ids = $this->request->post('ids');
if (!$ids || !is_array($ids)) {
return app('json')->fail('参数错误');
}
/** @var HolidayGiftPushServices $service */
$service = app()->make(HolidayGiftPushServices::class);
$service->batchDeletePush($ids);
return app('json')->success('删除成功');
}
/**
* 获取节日有礼推送统计数据
* @return mixed
*/
public function pushStatistics()
{
$where = $this->request->getMore([
['gift_id', 0],
['is_del', 0],
]);
/** @var HolidayGiftPushServices $service */
$service = app()->make(HolidayGiftPushServices::class);
$statistics = $service->getPushStatistics($where);
return app('json')->success($statistics);
}
}

View File

@@ -0,0 +1,148 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\integral;
use app\controller\admin\AuthController;
use app\services\activity\integral\StoreIntegralServices;
use think\annotation\Inject;
/**
* 积分商城管理
* Class StoreCombination
* @package app\admin\controller\store
*/
class StoreIntegral extends AuthController
{
/**
* @var StoreIntegralServices
*/
#[Inject]
protected StoreIntegralServices $services;
/**
* 积分商品列表
* @return mixed
*/
public function index()
{
$where = $this->request->getMore([
['integral_time', ''],
['is_show', ''],
['store_name', '']
]);
$where['is_del'] = 0;
$list = $this->services->systemPage($where);
return $this->success($list);
}
/**
* 保存商品
* @param int $id
*/
public function save($id)
{
$data = $this->request->postMore([
[['product_id', 'd'], 0],
[['title', 's'], ''],
[['unit_name', 's'], ''],
['image', ''],
['images', []],
[['num', 'd'], 0],
[['is_host', 'd'], 0],
[['is_show', 'd'], 0],
[['once_num', 'd'], 0],
[['sort', 'd'], 0],
[['description', 's'], ''],
['attrs', []],
['items', []],
['copy', 0],
['delivery_type', []],//物流方式
['freight', 1],//运费设置
['postage', 0],//邮费
[['temp_id', 'd'], 0],
['custom_form', ''],//自定义表单
['system_form_id', 0],//系统表单ID
['product_type', 0],//商品类型
]);
$this->validate($data, \app\validate\admin\marketing\StoreIntegralValidate::class, 'save');
$bragain = [];
if ($id) {
$bragain = $this->services->get((int)$id);
if (!$bragain) {
return $this->fail('数据不存在');
}
}
if ($data['num'] < $data['once_num']) {
return $this->fail('限制单次购买数量不能大于总购买数量');
}
if ($data['copy'] == 1) {
$id = 0;
unset($data['copy']);
}
$this->services->saveData($id, $data);
return $this->success('保存成功');
}
/**
* 批量添加商品
* @return mixed
*/
public function batch_add()
{
$data = $this->request->postMore([
['attrs', []],
[['is_show', 'd'], 0]
]);
if (!$data['attrs']) return $this->fail('请选择提交的商品');
$this->services->saveBatchData($data);
return $this->success('保存成功');
}
/**
* 详情
* @param $id
* @return mixed
*/
public function read($id)
{
$info = $this->services->getInfo($id);
return $this->success(compact('info'));
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_show($id, $is_show)
{
$this->services->update($id, ['is_show' => $is_show]);
return $this->success($is_show == 0 ? '下架成功' : '上架成功');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id) return $this->fail('缺少参数');
$this->services->update($id, ['is_del' => 1]);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,177 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\integral;
use app\controller\admin\AuthController;
use app\Request;
use app\services\activity\integral\StoreIntegralCategoryServices;
use app\services\other\CategoryServices;
use app\services\product\category\StoreProductCategoryServices;
use app\services\product\label\StoreProductLabelCateServices;
use app\services\product\label\StoreProductLabelServices;
use think\annotation\Inject;
use think\facade\App;
/**
* 积分商品分类
* Class StoreProductLabelCate
* @package app\controller\admin\v1\product\label
*/
class StoreIntegralCategory extends AuthController
{
/**
* @var StoreIntegralCategoryServices
*/
#[Inject]
protected StoreIntegralCategoryServices $services;
/**
* 获取列表
* @param Request $request
* @return mixed
*/
public function index(Request $request)
{
$where = $request->postMore([
['name', ''],
['is_show', '']
]);
$where['group'] = CategoryServices::INTEGRAL_CATEGORY_GROUP;
return $this->success($this->services->getList($where));
}
/**
* 生成新增表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function create()
{
return $this->success($this->services->createForm());
}
/**
* 保存
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
['name', ''],
['integral_min', 0],
['integral_max', 0],
['sort', 0],
['is_show', 0],
]);
if ($data['integral_min'] >= $data['integral_max']) {
return $this->fail('积分最低值不能大于积分最大值');
}
if (!trim($data['name'])) {
return $this->fail('请输入积分商品分类名称');
}
if ($this->services->getOne(['name' => $data['name'], 'group' => CategoryServices::INTEGRAL_CATEGORY_GROUP])) {
return $this->fail('积分商品分类已存在');
}
$integralNum = $this->services->search(['group' => CategoryServices::INTEGRAL_CATEGORY_GROUP])->field(['integral_min','integral_max'])->select();
if ($integralNum) {
foreach ($integralNum as $item) {
if (($item['integral_min'] <= $data['integral_min'] && $item['integral_max'] >= $data['integral_min']) || ($item['integral_min'] <= $data['integral_max'] && $item['integral_max'] >= $data['integral_max'])) {
return $this->fail('积分商品分类积分范围不可重叠');
}
}
}
$data['type'] = 0;
$data['relation_id'] = 0;
$data['group'] = CategoryServices::INTEGRAL_CATEGORY_GROUP;
$data['add_time'] = time();
$this->services->save($data);
return $this->success('添加积分商品分类成功!');
}
/**
* 生成更新表单
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function edit($id)
{
return $this->success($this->services->editForm((int)$id));
}
/**
* 更新
* @param $id
* @return mixed
*/
public function update($id)
{
$data = $this->request->postMore([
['name', ''],
['integral_min', 0],
['integral_max', 0],
['sort', 0],
['is_show', 0],
]);
if ($data['integral_min'] >= $data['integral_max']) {
return $this->fail('积分最低值不能大于积分最大值');
}
if (!$data['name']) {
return $this->fail('请输入积分商品分类名称');
}
$cate = $this->services->getOne(['name' => $data['name'], 'group' => CategoryServices::INTEGRAL_CATEGORY_GROUP]);
if ($cate && $cate['id'] != $id) {
return $this->fail('积分商品分类已存在');
}
$integralNum = $this->services->search(['not_id' => $id, 'group' => CategoryServices::INTEGRAL_CATEGORY_GROUP])->field(['integral_min','integral_max'])->select();
if ($integralNum) {
foreach ($integralNum as $item) {
if (($item['integral_min'] <= $data['integral_min'] && $item['integral_max'] >= $data['integral_min']) || ($item['integral_min'] <= $data['integral_max'] && $item['integral_max'] >= $data['integral_max'])) {
return $this->fail('积分商品分类积分范围不可重叠');
}
}
}
$this->services->update($id, $data);
return $this->success('修改积分商品分类成功!');
}
/**
* 显示隐藏
* @param $is_show
* @param $id
* @return \think\Response
* User: liusl
* DateTime: 2023/11/13 12:19
*/
public function set_show($is_show = '', $id = '')
{
if ($is_show == '' || $id == '') return $this->fail('缺少参数');
$this->services->update($id, compact('is_show'));
return $this->success($is_show == 1 ? '显示成功' : '隐藏成功');
}
/**
* 删除
* @param $id
* @return \think\Response
* User: liusl
* DateTime: 2023/11/13 12:21
*/
public function delete($id)
{
if (!$id || !$this->services->count(['id' => $id])) {
return $this->fail('删除的数据不存在');
}
$this->services->delete((int)$id);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,378 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\integral;
use app\controller\admin\AuthController;
use app\services\order\StoreOrderServices;use app\services\serve\ServeServices;
use crmeb\services\SystemConfigService;
use app\services\activity\integral\{
StoreIntegralOrderServices,
StoreIntegralOrderStatusServices
};
use app\services\order\StoreOrderDeliveryServices;
use app\services\other\ExpressServices;
use app\services\user\UserServices;
use think\annotation\Inject;
/**
* 订单管理
* Class StoreOrder
* @package app\controller\admin\v1\order
*/
class StoreIntegralOrder extends AuthController
{
/**
* @var StoreOrderServices
*/
#[Inject]
protected StoreOrderServices $services;
/**
* 获取订单类型数量
* @return mixed
*/
public function chart()
{
$where = $this->request->getMore([
['status', ''],
['real_name', ''],
['data', '', '', 'time'],
['type', ''],
['plat_type', 0],
['pay_type', ''],
['field_key', ''],
['store_id', 0],
['supplier_id', 0]
]);
if (!in_array($where['status'], [-1, -2, -3])) {
$where['pid'] = [0, -1];
}
$where['type'] = 4;
$data = $this->services->orderCount($where);
return $this->success($data);
}
/**
* 获取订单列表
* @return mixed
*/
public function lst()
{
$where = $this->request->getMore([
['status', ''],
['real_name', ''],
['data', '', '', 'time'],
['type', ''],
['plat_type', 0],
['pay_type', ''],
['field_key', ''],
['store_id', 0],
['supplier_id', 0]
]);
if (!in_array($where['status'], [-1, -2, -3])) {
$where['pid'] = [0, -1];
}
$where['type'] = 4;
return $this->success($this->services->getOrderList($where, ['*']));
}
/**
* 获取快递公司
* @return mixed
*/
public function express(ExpressServices $services)
{
[$status] = $this->request->getMore([
['status', ''],
], true);
if ($status != '') $data['status'] = $status;
$data['is_show'] = 1;
return $this->success($services->express($data));
}
/**
* 批量删除用户已经删除的订单
* @return mixed
*/
public function del_orders()
{
[$ids, $all, $where] = $this->request->postMore([
['ids', []],
['where', []],
], true);
if (!count($ids)) return $this->fail('请选择需要删除的订单');
if ($this->services->getOrderIdsCount($ids)) return $this->fail('您选择的的订单存在用户未删除的订单');
if ($this->services->batchUpdate($ids, ['is_system_del' => 1])) {
return $this->success('删除成功');
}
return $this->fail('删除失败');
}
/**
* 删除订单
* @param $id
* @return mixed
*/
public function del($id)
{
if (!$id || !($orderInfo = $this->services->get($id)))
return $this->fail('订单不存在');
if (!$orderInfo->is_del)
return $this->fail('订单用户未删除无法删除');
$orderInfo->is_system_del = 1;
if ($orderInfo->save())
return $this->success('SUCCESS');
else
return $this->fail('ERROR');
}
/**
* 订单发送货
* @param $id 订单id
* @return mixed
*/
public function update_delivery($id)
{
$data = $this->request->postMore([
['type', 1],
['delivery_name', ''],//快递公司名称
['delivery_id', ''],//快递单号
['delivery_code', ''],//快递公司编码
['express_record_type', 2],//发货记录类型
['express_temp_id', ""],//电子面单模板
['to_name', ''],//寄件人姓名
['to_tel', ''],//寄件人电话
['to_addr', ''],//寄件人地址
['sh_delivery_name', ''],//送货人姓名
['sh_delivery_id', ''],//送货人电话
['sh_delivery_uid', ''],//送货人ID
['fictitious_content', '']//虚拟发货内容
]);
return $this->success('SUCCESS', $this->services->delivery((int)$id, $data));
}
/**
* 确认收货
* @param $id 订单id
* @return mixed
* @throws \Exception
*/
public function take_delivery($id)
{
if (!$id) return $this->fail('缺少参数');
$order = $this->services->get($id);
if (!$order)
return $this->fail('Data does not exist!');
if ($order['status'] == 3)
return $this->fail('不能重复收货!');
if ($order['status'] == 2)
$data['status'] = 3;
else
return $this->fail('请先发货或者送货!');
if (!$this->services->update($id, $data)) {
return $this->fail('收货失败,请稍候再试!');
} else {
//增加收货订单状态
/** @var StoreIntegralOrderStatusServices $statusService */
$statusService = app()->make(StoreIntegralOrderStatusServices::class);
$statusService->save([
'oid' => $order['id'],
'change_type' => 'take_delivery',
'change_message' => '已收货',
'change_time' => time()
]);
return $this->success('收货成功');
}
}
/**
* 订单详情
* @param $id 订单id
* @return mixed
*/
public function order_info($id)
{
if (!$id || !($orderInfo = $this->services->get($id, ['*'], ['virtual']))) {
return $this->fail('订单不存在');
}
/** @var UserServices $services */
$services = app()->make(UserServices::class);
$userInfo = $services->getUserWithTrashedInfo((int)$orderInfo['uid']);
if ($userInfo) {
$userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
$userInfo = $userInfo->toArray();
} else {
$userInfo = [];
}
$orderInfo = $this->services->tidyOrder($orderInfo->toArray());
return $this->success(compact('orderInfo', 'userInfo'));
}
/**
* 查询物流信息
* @param $id 订单id
* @return mixed
*/
public function get_express($id, ExpressServices $services)
{
if (!$id || !($orderInfo = $this->services->get($id)))
return $this->fail('订单不存在');
if ($orderInfo['delivery_type'] != 'express')
return app('json')->fail('该订单不是快递发货,无法查询物流信息');
if (!$orderInfo['delivery_id'])
return $this->fail('该订单不存在快递单号');
$cacheName = 'integral' . $orderInfo['order_id'] . $orderInfo['delivery_id'];
$data['delivery_name'] = $orderInfo['delivery_name'];
$data['delivery_id'] = $orderInfo['delivery_id'];
$data['result'] = $services->query($cacheName, $orderInfo['delivery_id']);
return $this->success($data);
}
/**
* 获取修改配送信息表单结构
* @param $id 订单id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function distribution($id)
{
if (!$id) {
return $this->fail('订单不存在');
}
return $this->success($this->services->distributionForm((int)$id));
}
/**
* 修改配送信息
* @param $id 订单id
* @return mixed
*/
public function update_distribution($id)
{
$data = $this->request->postMore([['delivery_name', ''], ['delivery_id', '']]);
if (!$id) return $this->fail('Data does not exist!');
$this->services->updateDistribution($id, $data);
return $this->success('Modified success');
}
/**
* 修改备注
* @param $id
* @return mixed
*/
public function remark($id)
{
$data = $this->request->postMore([['remark', '']]);
if (!$data['remark'])
return $this->fail('请输入要备注的内容');
if (!$id)
return $this->fail('缺少参数');
if (!$order = $this->services->get($id)) {
return $this->fail('修改的订单不存在!');
}
$order->remark = $data['remark'];
if ($order->save()) {
return $this->success('备注成功');
} else
return $this->fail('备注失败');
}
/**
* 获取订单状态列表并分页
* @param $id
* @return mixed
*/
public function status(StoreIntegralOrderStatusServices $services, $id)
{
if (!$id) return $this->fail('缺少参数');
return $this->success($services->getStatusList(['oid' => $id])['list']);
}
/**
* 易联云打印机打印
* @param $id
* @return mixed
*/
public function order_print($id)
{
if (!$id) return $this->fail('缺少参数');
$res = $this->services->orderPrint((int)$id);
if ($res) {
return $this->success('打印成功');
} else {
return $this->fail('打印失败');
}
}
/**
* 电子面单模板
* @param $com
* @return mixed
*/
public function expr_temp(ServeServices $services, $com)
{
if (!$com) {
return $this->fail('快递公司编号缺失');
}
$list = $services->express()->temp($com);
return $this->success($list);
}
/**
* 获取模板
*/
public function express_temp(ServeServices $services)
{
$data = $this->request->getMore([['com', '']]);
$tpd = $services->express()->temp($data['com']);
return $this->success($tpd['data']);
}
/**
* 订单发货后打印电子面单
* @param $orderId
* @param StoreOrderDeliveryServices $storeOrderDeliveryServices
* @return mixed
*/
public function order_dump($order_id, StoreOrderDeliveryServices $storeOrderDeliveryServices)
{
return $this->success($storeOrderDeliveryServices->orderDump($order_id));
}
/**
* 获取配置信息
* @return mixed
*/
public function getDeliveryInfo()
{
$data = SystemConfigService::more(['config_export_temp_id', 'config_export_id', 'config_export_to_name', 'config_export_to_tel', 'config_export_to_address', 'config_export_open']);
return $this->success([
'express_temp_id' => $data['config_export_temp_id'] ?? '',
'id' => $data['config_export_id'] ?? '',
'to_name' => $data['config_export_to_name'] ?? '',
'to_tel' => $data['config_export_to_tel'] ?? '',
'to_add' => $data['config_export_to_address'] ?? '',
'export_open' => (bool)($data['config_export_open'] ?? 0)
]);
}
}

View File

@@ -0,0 +1,165 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\integral;
use app\controller\admin\AuthController;
use app\services\activity\integral\UserPointServices;
use app\services\user\UserBillServices;
use think\annotation\Inject;
use think\Response;
/**
* 积分控制器
* Class StoreCategory
* @package app\admin\controller\system
*/
class UserPoint extends AuthController
{
/**
* @var UserBillServices
*/
#[Inject]
protected UserBillServices $services;
/**
* @return Response
*/
public function index(): Response
{
$where = $this->request->getMore([
['start_time', ''],
['end_time', ''],
['nickname', ''],
['page', 1],
['limit', 10],
['id', '']
]);
return $this->success($this->services->getPointList($where));
}
/**
* 获取积分日志头部信息
* @return mixed
*/
public function integral_statistics()
{
$where = $this->request->getMore([
['start_time', ''],
['end_time', ''],
['nickname', ''],
]);
return $this->success(['res' => $this->services->getUserPointBadgelist($where)]);
}
/**
* 积分记录
* @return mixed
*/
public function pointRecord(UserPointServices $pointServices)
{
$where = $this->request->getMore([
['time', ''],
['trading_type', 0]
]);
$date = $pointServices->pointRecord($where);
return app('json')->success($date);
}
/**
* 积分记录备注
* @return mixed
*/
public function pointRecordRemark(UserPointServices $pointServices, $id = 0)
{
[$mark] = $this->request->postMore([
['mark', '']
], true);
$pointServices->recordRemark($id, $mark);
return app('json')->success('备注成功');
}
/**
* 积分统计基础信息
* @return mixed
*/
public function getBasic(UserPointServices $pointServices)
{
$where = $this->request->getMore([
['time', '']
]);
$where['time'] = $this->getDay($where['time']);
return app('json')->success($pointServices->getBasic($where));
}
/**
* 积分统计趋势图
* @return mixed
*/
public function getTrend(UserPointServices $pointServices)
{
$where = $this->request->getMore([
['time', '']
]);
$where['time'] = $this->getDay($where['time']);
return app('json')->success($pointServices->getTrend($where));
}
/**
* 积分来源
* @return mixed
*/
public function getChannel(UserPointServices $pointServices)
{
$where = $this->request->getMore([
['time', '']
]);
$where['time'] = $this->getDay($where['time']);
return app('json')->success($pointServices->getChannel($where));
}
/**
* 积分消耗
* @return mixed
*/
public function getType(UserPointServices $pointServices)
{
$where = $this->request->getMore([
['time', '']
]);
$where['time'] = $this->getDay($where['time']);
return app('json')->success($pointServices->getType($where));
}
/**
* 格式化时间
* @param $time
* @return string
*/
public function getDay($time)
{
if (strstr($time, '-') !== false) {
[$startTime, $endTime] = explode('-', $time);
if (!$startTime && !$endTime) {
return date("Y/m/d", strtotime("-30 days", time())) . '-' . date("Y/m/d 23:59:59", time());
} else {
if (strtotime($endTime) == strtotime(date('Y-m-d', strtotime($endTime)))) {
$endTime = $endTime . ' 23:59:59';
}
return $startTime . '-' . $endTime;
}
} else {
return date("Y/m/d", strtotime("-30 days", time())) . '-' . date("Y/m/d 23:59:59", time());
}
}
}

View File

@@ -0,0 +1,117 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\live;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\activity\live\LiveAnchorServices;
/**
* 直播间主播
* Class LiveAnchor
* @package app\controller\admin\store
*/
class LiveAnchor extends AuthController
{
/**
* @var LiveAnchorServices
*/
#[Inject]
protected LiveAnchorServices $services;
/**
* 列表
* @return mixed
*/
public function list()
{
$where = $this->request->postMore([
['kerword', ''],
]);
return $this->success($this->services->getList($where));
}
/**
* 添加修改表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function add()
{
[$id] = $this->request->getMore([
['id', 0],
], true);
return $this->success($this->services->add((int)$id));
}
/**
* 保存标签表单数据
* @param int $id
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
['id', 0],
['name', ''],
['wechat', ''],
['phone', ''],
['cover_img', '']
]);
if (!$data['name'] = trim($data['name'])) return $this->fail('名称不能为空!');
if (!$data['wechat'] = trim($data['wechat'])) return $this->fail('微信号不能为空!');
if (!$data['phone'] = trim($data['phone'])) return $this->fail('手机号不能为空!');
if (!check_phone($data['phone'])) return app('json')->fail('请输入正确手机号');
if (!$data['cover_img'] = trim($data['cover_img'])) return $this->fail('请选择主播图像');
$res = $this->services->save((int)$data['id'], $data);
if ($res === true) {
return $this->success('保存成功', ['auth' => false]);
}
return $this->success('请先去小程序认证主播', $res);
}
/**
* 删除
* @param $id
* @throws \Exception
*/
public function delete()
{
[$id] = $this->request->getMore([
['id', 0],
], true);
if (!$id) return $this->fail('数据不存在');
$this->services->delAnchor((int)$id);
return $this->success('刪除成功!');
}
/**
* 设置会员等级显示|隐藏
*
* @return json
*/
public function setShow($id = '', $is_show = '')
{
if ($is_show == '' || $id == '') return $this->fail('缺少参数');
return $this->success($this->services->setShow((int)$id, (int)$is_show));
}
/**
* 同步主播
* @return mixed
*/
public function syncAnchor()
{
$this->services->syncAnchor();
return app('json')->success('同步成功');
}
}

View File

@@ -0,0 +1,120 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\live;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\activity\live\LiveGoodsServices;
/**
* 直播间商品
* Class LiveGoods
* @package app\controller\admin\store
*/
class LiveGoods extends AuthController
{
/**
* @var LiveGoodsServices
*/
#[Inject]
protected LiveGoodsServices $services;
/**
* @return \think\Response
* @author 等风来
* @email 136327134@qq.com
* @date 2023/9/19
*/
public function list()
{
$where = $this->request->postMore([
['kerword', ''],
['status', ''],
['is_show', ''],
['live_id', 0]
]);
return app('json')->success($this->services->getList($where));
}
public function create()
{
[$product_ids] = $this->request->postMore([
['product_id', []]
], true);
if (!$product_ids) return app('json')->fail('请选择商品');
return app('json')->success($this->services->create($product_ids));
}
public function add()
{
[$goods_info] = $this->request->postMore([
['goods_info', []]
], true);
if (!$goods_info) return app('json')->fail('请选择商品');
foreach ($goods_info as $goods) {
if (!$goods['id']) return app('json')->fail('请选择商品');
if (!$goods['store_name']) return app('json')->fail('请输入名称');
if (!$goods['image']) return app('json')->fail('请选择背景图');
if (!$goods['price']) return app('json')->fail('请输入直播价格');
if ($goods['price'] <= 0) return app('json')->fail('直播价格必须大于0');
}
$this->services->add($goods_info);
return app('json')->success('添加成功');
}
public function detail($id)
{
if (!$id)
return app('json')->fail('数据不存在');
$goods = $this->services->get($id, ['*'], ['product']);
return app('json')->success('ok', $goods ? $goods->toArray() : []);
}
public function syncGoods()
{
$this->services->syncGoodStatus();
return app('json')->success('同步成功');
}
public function audit($id)
{
if (!$id)
return app('json')->fail('数据不存在');
$this->services->audit((int)$id);
return app('json')->success('提交审核成功');
}
public function resetAudit($id)
{
if (!$id)
return app('json')->fail('数据不存在');
$this->services->resetAudit((int)$id);
return app('json')->success('撤销成功');
}
public function setShow(int $id, $is_show)
{
if (!$id)
return app('json')->fail('数据不存在');
return app('json')->success($this->services->isShow($id, $is_show));
}
public function delete($id)
{
if (!$id)
return app('json')->fail('数据不存在');
$this->services->delete($id);
return app('json')->success('删除成功');
}
}

View File

@@ -0,0 +1,131 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\live;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\activity\live\LiveRoomServices;
/**
* 直播间
* Class LiveRoom
* @package app\controller\admin\v1\marketing\live
*/
class LiveRoom extends AuthController
{
/**
* @var LiveRoomServices
*/
#[Inject]
protected LiveRoomServices $services;
/**
* @return \think\Response
* @author 等风来
* @email 136327134@qq.com
* @date 2023/9/19
*/
public function list()
{
$where = $this->request->postMore([
['kerword', ''],
['status', '']
]);
return app('json')->success($this->services->getList($where));
}
public function detail($id)
{
if (!$id)
return app('json')->fail('数据不存在');
return app('json')->success('ok', $this->services->get((int)$id)->toArray());
}
public function add()
{
$data = $this->request->postMore([
['name', ''],
['cover_img', ''],
['share_img', ''],
['anchor_name', ''],
['anchor_wechat', ''],
['phone', ''],
['start_time', ['', '']],
['type', 1],
['screen_type', 1],
['close_like', 0],
['close_goods', 0],
['close_comment', 0],
['replay_status', 1],
['sort', 0]
]);
if (!$data['name']) return app('json')->fail('请输入名称');
if (!$data['cover_img']) return app('json')->fail('请选择背景图');
if (!$data['share_img']) return app('json')->fail('请选择分享图');
if (!$data['anchor_wechat']) return app('json')->fail('请选择主播');
if (!$data['start_time'] || count($data['start_time']) != 2) return app('json')->fail('请选择直播开始、结束时间');
if (!$data['phone'] || !check_phone($data['phone'])) return app('json')->fail('请输入正确手机号');
[$data['start_time'], $data['end_time']] = $data['start_time'];
$this->services->add($data);
return app('json')->success('添加成功');
}
public function addGoods()
{
[$room_id, $goods_ids] = $this->request->postMore([
['room_id', 0],
['goods_ids', []]
], true);
if (!$room_id) return app('json')->fail('请选择直播间');
if (!$goods_ids) return app('json')->fail('请选择商品');
$this->services->exportGoods((int)$room_id, $goods_ids);
return app('json')->success('添加商品成功');
}
public function apply($id)
{
[$status, $msg] = $this->request->postMore([
['status', ''],
['msg', '']
], true);
if (!$id)
return app('json')->fail('数据不存在');
$status = $status == 1 ? 1 : -1;
if ($status == -1 && !$msg)
return app('json')->fail('请输入理由');
$this->services->apply((int)$id, $status, $msg);
return app('json')->success('操作成功');
}
public function setShow($id, $is_show)
{
if (!$id)
return app('json')->fail('数据不存在');
return app('json')->success($this->services->isShow((int)$id, $is_show));
}
public function delete($id)
{
if (!$id)
return app('json')->fail('数据不存在');
$this->services->delete($id);
return app('json')->success('删除成功');
}
public function syncRoom()
{
$this->services->syncRoomStatus();
return app('json')->success('同步成功');
}
}

View File

@@ -0,0 +1,266 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\controller\admin\v1\marketing\lottery;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\activity\lottery\LuckLotteryServices;
/**
* 抽奖活动
* Class LuckLottery
* @package app\controller\admin\v1\marketing\lottery
*/
class LuckLottery extends AuthController
{
/**
* @var LuckLotteryServices
*/
#[Inject]
protected LuckLotteryServices $services;
/**
* 列表
* @return mixed
*/
public function index()
{
$where = $this->request->postMore([
['start', ''],
['status', ''],
['factor', ''],
['keyword', ''],
['time', '', '', 'time_ranges'],
]);
return $this->success($this->services->getList($where));
}
/**
* id查询详情
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function detail($id)
{
if (!$id) {
return $this->fail('缺少参数id');
}
return $this->success($this->services->getlotteryInfo((int)$id));
}
/**
* 活动类型查询详情
* @param $factor
* @return mixed
*/
public function factorInfo($factor)
{
if (!$factor) {
return app('json')->fail('缺少参数');
}
return app('json')->success($this->services->getlotteryFactorInfo((int)$factor));
}
/**
* 添加
* @return mixed
*/
public function add()
{
$data = $this->request->postMore([
['name', ''],
['desc', ''],
['image', ''],
['factor', 1],
['type', 1],
['factor_num', 1],
['attends_user', 1],
['user_level', []],
['user_label', []],
['is_svip', 0],
['period', [0, 0]],
['lottery_num_term', 1],
['lottery_num', 1],
['total_lottery_num', 1],
['spread_num', 1],
['is_all_record', 1],
['is_personal_record', 1],
['is_content', 1],
['status', 1],
['prize', []]
]);
$data['content'] = $this->request->param('content', '');
if (!$data['name']) {
return $this->fail('请添加抽奖活动名称');
}
if ($data['is_content'] && !$data['content']) {
return $this->fail('请添加抽奖描述等文案');
}
[$start, $end] = $data['period'];
unset($data['period']);
$data['start_time'] = $start ? strtotime($start) : 0;
$data['end_time'] = $end ? strtotime($end) : 0;
if ($data['start_time'] && $data['end_time'] && $data['end_time'] <= $data['start_time']) {
return $this->fail('活动结束时间必须大于开始时间');
}
if (!$data['prize']) {
return $this->fail('请添加奖品');
}
if (in_array($data['factor'], [1, 2]) && !$data['factor_num']) {
return $this->fail('请填写消耗' . ($data['factor'] == '1' ? '积分' : '余额') . '数量');
}
if ($data['factor'] == 1 && $data['lottery_num'] > $data['total_lottery_num']) {
return $this->fail('积分抽奖时每天抽奖次数不能大于总次数');
}
$this->services->add($data);
return $this->success('保存成功');
}
/**
* 修改
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit($id)
{
$data = $this->request->postMore([
['name', ''],
['desc', ''],
['image', ''],
['factor', 1],
['type', 1],
['factor_num', 1],
['attends_user', 1],
['user_level', []],
['user_label', []],
['is_svip', 0],
['period', [0, 0]],
['lottery_num_term', 1],
['lottery_num', 1],
['spread_num', 1],
['total_lottery_num', 1],
['is_all_record', 1],
['is_personal_record', 1],
['is_content', 1],
['status', 1],
['prize', []]
]);
$data['content'] = $this->request->param('content', '');
if (!$id) {
return $this->fail('缺少参数id');
}
if (!$data['name']) {
return $this->fail('请添加抽奖活动名称');
}
[$start, $end] = $data['period'];
unset($data['period']);
$data['start_time'] = $start ? strtotime($start) : 0;
$data['end_time'] = $end ? strtotime($end) : 0;
if ($data['start_time'] && $data['end_time'] && $data['end_time'] <= $data['start_time']) {
return $this->fail('活动结束时间必须大于开始时间');
}
if ($data['end_time'] < time()) {
return $this->fail('活动结束时间必须大于当前时间');
}
if ($data['is_content'] && !$data['content']) {
return $this->fail('请添加抽奖描述等文案');
}
if (!$data['prize']) {
return $this->fail('请添加奖品');
}
if (in_array($data['factor'], [1, 2]) && !$data['factor_num']) {
return $this->fail('请填写消耗' . ($data['factor'] == '1' ? '积分' : '余额') . '数量');
}
if ($data['factor'] == 1 && $data['lottery_num'] > $data['total_lottery_num']) {
return $this->fail('积分抽奖时每天抽奖次数不能大于总次数');
}
$this->services->edit((int)$id, $data);
return $this->success('保存成功');
}
/**
* 删除
* @param $id
* @throws \Exception
*/
public function delete()
{
[$id] = $this->request->getMore([
['id', 0],
], true);
if (!$id) return $this->fail('数据不存在');
$this->services->delLottery((int)$id);
return $this->success('刪除成功!');
}
/**
* 设置活动状态
*/
public function setStatus($id = '', $status = '')
{
$info = $this->services->get((int)$id);
if ($info['end_time'] < time() && $status == 1) {
return $this->fail('活动已结束,不能修改状态');
}
if ($status == '' || $id == '') {
return $this->fail('缺少参数');
}
$res = $this->services->setStatus((int)$id, (int)$status);
if (!$res) {
return $this->fail('设置失败');
}
return $this->success($status == 1 ? '开启成功' : '关闭成功');
}
/**
* 获取抽奖列表以及正在使用的抽奖活动
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2025/3/18
*/
public function factorList()
{
return $this->success($this->services->factorList());
}
/**
* 活动类型使用
* @return \think\Response
* @author wuhaotian
* @email 442384644@qq.com
* @date 2025/3/18
*/
public function factorUse()
{
$data = $this->request->postMore([
[['point', 'd'], 0],
[['pay', 'd'], 0],
[['evaluate', 'd'], 0],
[['follow', 'd'], 0],
]);
$this->services->factorUse($data);
return app('json')->success('保存成功');
}
}

View File

@@ -0,0 +1,81 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\controller\admin\v1\marketing\lottery;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\activity\lottery\LuckLotteryRecordServices;
/**
* 抽奖中奖记录
* Class LuckLotteryRecord
* @package app\controller\admin\v1\marketing\lottery
*/
class LuckLotteryRecord extends AuthController
{
/**
* @var LuckLotteryRecordServices
*/
#[Inject]
protected LuckLotteryRecordServices $services;
/**
* 用抽奖id查询中奖记录
* @param $id
* @return mixed
*/
public function index($id)
{
$where = $this->request->postMore([
['lottery_id', 0],
['is_receive', ''],
['is_deliver', ''],
['type', ''],
['keyword', ''],
['data', '', '', 'time'],
]);
if (!$id) {
return $this->fail('缺少活动ID');
}
$where['lottery_id'] = $id;
return $this->success($this->services->getList($where));
}
public function list()
{
$where = $this->request->postMore([
['lottery_id', 0],
['is_receive', ''],
['is_deliver', ''],
['type', ''],
['keyword', ''],
['data', '', '', 'time'],
['factor', ''],
]);
return $this->success($this->services->getList($where));
}
public function deliver($id)
{
$data = $this->request->postMore([
['deliver_name', ''],
['deliver_number', ''],
['mark', ''],
]);
if (!$id) {
return $this->fail('缺少ID');
}
return $this->success($this->services->setDeliver((int)$id, $data) ? '处理成功' : '处理失败');
}
}

View File

@@ -0,0 +1,67 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\controller\admin\v1\marketing\lottery;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\activity\lottery\LuckPrizeServices;
/**
* 抽奖奖品
* Class LuckPrize
* @package app\controller\admin\v1\marketing\lottery
*/
class LuckPrize extends AuthController
{
/**
* @var LuckPrizeServices
*/
#[Inject]
protected LuckPrizeServices $services;
/**
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 等风来
* @email 136327134@qq.com
* @date 2023/9/19
*/
public function edit($id)
{
$data = $this->request->postMore([
['type', 1],
['lottery_id', 0],
['name', ''],
['prompt', ''],
['image', ''],
['chance', 1],
['total', 1],
['couon_id', 0],
['product_id', 0],
['unique', ''],
['num', 1]
]);
if (!$id) {
return $this->fail('缺少参数id');
}
if (!$data['lottery_id']) {
return $this->fail('缺少抽奖活动id');
}
return $this->success($this->services->edit((int)$id, $data) ? '编辑成功' : '编辑失败');
}
}

View File

@@ -0,0 +1,204 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\promotions;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\activity\promotions\StorePromotionsServices;
/**
* 促销活动
* Class StorePromotions
* @package app\controller\admin\v1\marketing\promotions
*/
class StorePromotions extends AuthController
{
/**
* @var StorePromotionsServices
*/
#[Inject]
protected StorePromotionsServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index($type)
{
$where = $this->request->getMore([
[['status', 's'], ''],
['threshold_type', ''],
['n_piece_n_discount', ''],
[['name', 's'], '']
]);
$where['promotions_type'] = $type;
$where['type'] = 1;
$where['store_id'] = 0;
$where['pid'] = 0;
$where['is_del'] = 0;
return $this->success($this->services->systemPage($where));
}
/**
* 详情
* @param $id
* @return mixed
*/
public function getInfo($id)
{
$info = $this->services->getInfo($id);
return $this->success(compact('info'));
}
/**
* 保存折扣促销活动
* @param $type
* @param $id
* @return mixed
*/
public function saveDiscount($type, $id)
{
$data = $this->request->postMore([
[['promotions_cate', 'd'], 1],//优惠类型
[['name', 's'], ''],//名称
[['threshold_type', 'd'], 1],//门槛类型1:满N元2:满N件
['threshold', 0],//优惠门槛
[['discount_type', 'd'], 1],//优惠类型1:满减2:满折
[['n_piece_n_discount', 'd'], 3],//n件n折类型:1:第二件半件2:买1送1 3:自定义
['discount', 0],//优惠
[['give_integral', 'd'], 0],//赠送积分
['give_coupon_id', []],//赠送优惠券ID
['give_product_id', []],//赠送商品ID
['give_product_unique', []],//赠送商品规格唯一值
[['is_label', 'd'], 0],
['label_id', []],//关联标签
[['product_partake_type', 'd'], 1],//商品参与类型
['product_id', []],//关联商品
['brand_id', []],//关联品牌ID
['store_label_id', []],//关联商品标签ID
[['is_limit', 'd'], 0],//是否限量
[['limit_num', 'd'], 0],//限量个数
[['is_overlay', 'd'], 0],
['overlay', []],//叠加方式方式
['section_time', []],//时间
[['sort', 'd'], 0],//排序
]);
$data['promotions_type'] = $type;
if ($data['promotions_type'] == 2) {
$data['threshold_type'] = 2;
}
if (!$data['is_label']) {
$data['label_id'] = [];
}
if (!$data['is_overlay']) {
$data['overlay'] = [];
}
unset($data['is_label'], $data['is_overlay']);
$data['promotions'][] = [
'threshold_type' => $data['threshold_type'],
'threshold' => $data['threshold'],
'discount_type' => $data['discount_type'],
'n_piece_n_discount' => $data['n_piece_n_discount'],
'discount' => $data['discount'],
'give_integral' => $data['give_integral'],
'give_coupon_id' => [],
'give_product_id' => [],
'give_product_unique' => [],
];
if ($data['product_partake_type'] == 2 && !$data['product_id']) {
return $this->fail('请选择要参与活动的商品');
}
if ($data['product_partake_type'] == 4 && !$data['brand_id']) {
return $this->fail('请选择要参与活动的商品品牌');
}
if ($data['product_partake_type'] == 5 && !$data['store_label_id']) {
return $this->fail('请选择要参与活动的商品标签');
}
$this->services->saveData((int)$id, $data);
return $this->success('保存成功');
}
/**
* 保存促销活动
* @param $type
* @param $id
* @return mixed
*/
public function save($type, $id)
{
$data = $this->request->postMore([
[['promotions_cate', 'd'], 1],//优惠类型
[['threshold_type', 'd'], 1],//门槛类型1:满N元2:满N件
[['name', 's'], ''],//名称
[['is_label', 'd'], 0],
['label_id', []],//关联标签
[['product_partake_type', 'd'], 1],//商品参与类型
['product_id', []],//关联商品ID
['brand_id', []],//关联品牌ID
['store_label_id', []],//关联商品标签ID
[['is_limit', 'd'], 0],//是否限量
[['limit_num', 'd'], 0],//限量个数
[['is_overlay', 'd'], 0],
['overlay', []],//叠加方式方式
['section_time', []],//时间
[['sort', 'd'], 0],//排序
['promotions', []]//阶梯优惠数组
]);
$data['promotions_type'] = $type;
if (!$data['is_label']) {
$data['label_id'] = [];
}
if (!$data['is_overlay']) {
$data['overlay'] = [];
}
if ($data['product_partake_type'] == 2 && !$data['product_id']) {
return $this->fail('请选择要参与活动的商品');
}
if ($data['product_partake_type'] == 4 && !$data['brand_id']) {
return $this->fail('请选择要参与活动的商品品牌');
}
if ($data['product_partake_type'] == 5 && !$data['store_label_id']) {
return $this->fail('请选择要参与活动的商品标签');
}
unset($data['is_label'], $data['is_overlay']);
$this->services->saveData((int)$id, $data);
return $this->success('保存成功');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id) return $this->fail('缺少参数');
$this->services->update(['id|pid' => $id], ['is_del' => 1]);
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function setStatus($id, $status)
{
$this->services->update($id, ['status' => $status, 'update_time' => time()]);
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
}

View File

@@ -0,0 +1,170 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\seckill;
use app\controller\admin\AuthController;
use app\services\activity\seckill\StoreSeckillServices;
use app\services\activity\StoreActivityServices;
use app\services\product\sku\StoreProductAttrValueServices;
use crmeb\services\CacheService;
use think\annotation\Inject;
use think\facade\App;
/**
* 秒杀活动
* Class StoreActivitySeckill
* @package app\controller\admin\v1\marketing\seckill
*/
class StoreActivitySeckill extends AuthController
{
/**
* @var StoreActivityServices
*/
#[Inject]
protected StoreActivityServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['time', ''],
[['status', 's'], ''],
[['store_name', 's'], ''],
[['start_status', 's'], '']
]);
$where['is_del'] = 0;
$where['type'] = 1;
return $this->success($this->services->systemPage($where));
}
/**
* 详情
* @param $id
* @return mixed
*/
public function read($id)
{
$info = $this->services->getSeckillInfo((int)$id);
if (empty($info)) {
return $this->fail('秒杀活动不存在');
}
return $this->success(compact('info'));
}
/**
* 保存秒杀商品
* @param int $id
*/
public function save($id = '')
{
$data = $this->request->postMore([
['name', 's', ''],
['seckill_ids', []],
['image', ''],
['section_data', []],
[['status', 'd'], 0],
[['num', 'd'], 0],
[['once_num', 'd'], 0],
['time_id', []],
['applicable_type', 1],//适用门店类型
['applicable_store_id', []],//适用门店IDS
['is_commission', 0],//是否参与返佣
]);
$this->validate($data, \app\validate\admin\marketing\StoreActivitySeckillValidate::class, 'save');
if ($data['section_data']) {
[$start_time, $end_time] = $data['section_data'];
if (strtotime($end_time) + 86400 < time()) {
return $this->fail('活动结束时间不能小于当前时间');
}
}
if ($data['num'] < $data['once_num']) {
return $this->fail('限制单次购买数量不能大于总购买数量');
}
if ($data['applicable_type'] == 1) {
$data['applicable_store_id'] = [];
} elseif ($data['applicable_type'] == 2) {
if (!$data['applicable_store_id']) {
return $this->fail('请选择要适用门店');
}
}
$expend = $data['seckill_ids'];
$this->services->saveData((int)$id, $data, $expend);
return $this->success('保存成功');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id) return $this->fail('缺少参数');
$this->services->update($id, ['is_del' => 1]);
/** @var StoreSeckillServices $storeSeckillServices */
$storeSeckillServices = app()->make(StoreSeckillServices::class);
//秒杀商品
$seckillIds = $storeSeckillServices->getActivitySeckillIds(['activity_id' => $id]);
if ($seckillIds) {
/** @var StoreProductAttrValueServices $storeProductAttrValueServices */
$storeProductAttrValueServices = app()->make(StoreProductAttrValueServices::class);
foreach ($seckillIds as $seckillId) {
$storeSeckillServices->update($seckillId, ['is_del' => 1]);
$unique = $storeProductAttrValueServices->value(['product_id' => $seckillId, 'type' => 1], 'unique');
if ($unique) {
$name = 'seckill_' . $unique . '_1';
/** @var CacheService $cache */
$cache = app()->make(CacheService::class);
$cache->del($name);
}
$this->services->cacheDelById($seckillId);
}
CacheService::redisHandler('product_attr')->clear();
}
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_status($id, $status)
{
$info = $this->services->get((int)$id);
if (bcadd((string)$info['end_day'], '86400') < time() && $status == 1) {
return $this->fail('活动已结束,不能修改状态');
}
$this->services->update($id, ['status' => $status]);
/** @var StoreSeckillServices $storeSeckillServices */
$storeSeckillServices = app()->make(StoreSeckillServices::class);
//秒杀商品
$seckillIds = $storeSeckillServices->getActivitySeckillIds(['activity_id' => $id]);
if (!empty($seckillIds)) {
foreach ($seckillIds as $seckillId) {
$storeSeckillServices->update($seckillId, ['status' => $status]);
//修改状态同步缓存
$this->services->cacheSaveValue($seckillId, 'status', $status);
}
}
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
}

View File

@@ -0,0 +1,217 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\seckill;
use app\controller\admin\AuthController;
use app\services\activity\seckill\StoreSeckillServices;
use app\services\product\sku\StoreProductAttrValueServices;
use crmeb\services\CacheService;
use think\annotation\Inject;
/**
* 限时秒杀 控制器
* Class StoreSeckill
* @package app\admin\controller\store
*/
class StoreSeckill extends AuthController
{
/**
* @var StoreSeckillServices
*/
#[Inject]
protected StoreSeckillServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['start_status', ''],
[['status', 's'], ''],
[['store_name', 's'], '']
]);
$where['is_del'] = 0;
return $this->success($this->services->systemPage($where));
}
/**
* 详情
* @param $id
* @return mixed
*/
public function read($id)
{
$info = $this->services->getInfo($id);
return $this->success(compact('info'));
}
/**
* 保存秒杀商品
* @param int $id
*/
public function save($id)
{
$data = $this->request->postMore([
[['product_id', 'd'], 0],
[['title', 's'], ''],
[['info', 's'], ''],
[['unit_name', 's'], ''],
['images', []],
[['give_integral', 'd'], 0],
['section_time', []],
[['is_hot', 'd'], 0],
[['status', 'd'], 0],
[['num', 'd'], 0],
[['once_num', 'd'], 0],
[['time_id', 'd'], 0],
[['temp_id', 'd'], 0],
[['sort', 'd'], 0],
[['description', 's'], ''],
['attrs', []],
['items', []],
['copy', 0],
['is_support_refund', 1],//是否支持退款
['delivery_type', []],//物流方式
['freight', 1],//运费设置
['postage', 0],//邮费
['custom_form', ''],//自定义表单
['system_form_id', 0],//系统表单ID
['product_type', 0],//商品类型
]);
$this->validate($data, \app\validate\admin\marketing\StoreSeckillValidate::class, 'save');
if ($data['section_time']) {
[$start_time, $end_time] = $data['section_time'];
if (strtotime($end_time) + 86400 < time()) {
return $this->fail('活动结束时间不能小于当前时间');
}
}
$seckill = [];
if ($id) {
$seckill = $this->services->get((int)$id);
if (!$seckill) {
return $this->fail('数据不存在');
}
}
//限制编辑
if ($data['copy'] == 0 && $seckill) {
if (($seckill['stop_time'] + 86400) < time()) {
return $this->fail('活动已结束,请重新添加或复制');
}
}
if ($data['num'] < $data['once_num']) {
return $this->fail('限制单次购买数量不能大于总购买数量');
}
if ($data['copy'] == 1) {
$id = 0;
unset($data['copy']);
}
$this->services->saveData($id, $data);
return $this->success('保存成功');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id) return $this->fail('缺少参数');
$this->services->update($id, ['is_del' => 1]);
/** @var StoreProductAttrValueServices $storeProductAttrValueServices */
$storeProductAttrValueServices = app()->make(StoreProductAttrValueServices::class);
$unique = $storeProductAttrValueServices->value(['product_id' => $id, 'type' => 1], 'unique');
if ($unique) {
$name = 'seckill_' . $unique . '_1';
/** @var CacheService $cache */
$cache = app()->make(CacheService::class);
$cache->del($name);
}
$this->services->cacheDelById($id);
CacheService::redisHandler('product_attr')->clear();
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_status($id, $status)
{
$this->services->update($id, ['status' => $status]);
//修改状态同步缓存
$this->services->cacheSaveValue($id, 'status', $status);
CacheService::redisHandler('product_attr')->clear();
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
/**
* 秒杀时间段列表
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
*/
public function time_list()
{
$list['data'] = sys_data('routine_seckill_time');
return $this->success(compact('list'));
}
/**
* 秒杀统计
* @return mixed
*/
public function seckillStatistics($id)
{
$data = $this->services->seckillStatistics($id);
return app('json')->success($data);
}
/**
* 秒杀参与人统计
* @param $id
* @return mixed
*/
public function seckillPeople($id)
{
[$real_name] = $this->request->getMore([
['real_name', '']
], true);
return app('json')->success($this->services->seckillPeople($id, $real_name));
}
/**
* 秒杀订单统计
* @param $id
* @return mixed
*/
public function seckillOrder($id)
{
$where = $this->request->getMore([
['real_name', ''],
['status', '']
]);
return app('json')->success($this->services->seckillOrder((int)$id, $where));
}
}

View File

@@ -0,0 +1,152 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\seckill;
use app\controller\admin\AuthController;
use app\services\activity\seckill\StoreSeckillTimeServices;
use app\services\activity\StoreActivityServices;
use think\annotation\Inject;use think\facade\App;
/**
* 限时秒杀时间 控制器
* Class StoreSeckillTime
* @package app\controller\admin\v1\marketing\seckill
*/
class StoreSeckillTime extends AuthController
{
/**
* @var StoreSeckillTimeServices
*/
#[Inject]
protected StoreSeckillTimeServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['title', ''],
[['status', 's'], '']
]);
return $this->success($this->services->systemPage($where));
}
/**
* 可用秒杀时间段
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function time_list()
{
return $this->success($this->services->time_list());
}
/**
* @param $id
* @return mixed
*/
public function create($id = '')
{
return $this->success($this->services->createForm((int)$id));
}
/**
* 详情
* @param $id
* @return mixed
*/
public function read($id)
{
$info = $this->services->getInfo((int)$id);
return $this->success(compact('info'));
}
/**
* 保存秒杀商品
* @param int $id
*/
public function save($id)
{
$data = $this->request->postMore([
[['title', 's'], ''],
[['describe', 's'], ''],
['time', []],
['pic', ''],
[['status', 'd'], 0],
]);
$this->validate($data, \app\validate\admin\marketing\StoreSeckillTimeValidate::class, 'save');
$data['start_time'] = str_replace(':', '', $data['time'][0]);
$data['end_time'] = str_replace(':', '', $data['time'][1]);
unset($data['time']);
$id = (int)$id;
if ($data['end_time'] <= $data['start_time']) {
return app('json')->fail('时间段结束时间要大于开始时间');
}
if (!$this->services->checkTime($data, $id))
return app('json')->fail('时间段不可重叠');
if ($id) {
$seckill = $this->services->get($id);
if (!$seckill) {
return $this->fail('数据不存在');
}
}
if ($id) {
$this->services->update($id, $data);
} else {
$this->services->save($data);
}
return $this->success('保存成功');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_status($id, $status)
{
$this->services->update($id, ['status' => $status]);
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete(StoreActivityServices $activityServices, $id)
{
if (!$id) return $this->fail('缺少参数');
$info = $this->services->get((int)$id);
if (!$info) {
return $this->fail('数据不存在');
}
if ($activityServices->existenceActivity(['start_time' => $info->start_time, 'end_time' => $info->end_time]))
return app('json')->fail('已有开启活动,不可删除');
$this->services->delete($id);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,175 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\video;
use app\controller\admin\AuthController;
use app\services\activity\video\VideoServices;
use think\annotation\Inject;
/**
* 短视频控制器
* Class StoreCategory
* @package app\admin\controller\v1\marketing\video
*/
class Video extends AuthController
{
/**
* @var VideoServices
*/
#[Inject]
protected VideoServices $services;
/**
* 分类列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['data', '', '', 'time'],
['keyword', ''],
['is_verify', '']
]);
$where['is_del'] = 0;
return $this->success($this->services->sysPage($where));
}
/**
* 获取视频信息
* @param $id
* @return mixed
*/
public function info($id)
{
if (!$id) return $this->fail('缺少参数');
return $this->success($this->services->getInfo((int)$id));
}
/**
* 保存新增分类
* @return mixed
*/
public function save($id)
{
$data = $this->request->postMore([
['image', ''],
['desc', ''],
['video_url', ''],
['product_id', []],
['is_show', 1],
['is_recommend', 0],
['sort', 0]
]);
$data['type'] = 0;
$data['relation_id'] = 0;
$data['is_verify'] = 1;
if ($id) {
$info = $this->services->get($id);
if (!$info) {
$this->fail('视频不存在');
}
$this->services->update($id, $data);
} else {
$data['add_time'] = time();
$this->services->save($data);
}
return $this->success('添加视频成功!');
}
/**
* 修改状态
* @param string $is_show
* @param string $id
*/
public function set_show($id = '', $status = '')
{
if ($status == '' || $id == '') return $this->fail('缺少参数');
$this->services->update($id, ['is_show' => $status]);
return $this->success($status == 1 ? '显示成功' : '隐藏成功');
}
/**
* 审核
* @param $id
* @param $verify
* @return mixed
*/
public function verify($id, $verify)
{
if ($verify == '' || $id == '') return $this->fail('缺少参数');
$info = $this->services->get($id);
if (!$info) {
$this->fail('视频不存在');
}
if ($verify == 1) {
$verify = 1;
} else {//拒绝通过
$verify = -1;
}
$this->services->update($id, ['is_verify' => $verify]);
return $this->success('审核成功');
}
/**
* 推荐
* @param $id
* @param $recommend
* @return mixed
*/
public function recommend($id, $recommend)
{
if ($recommend == '' || $id == '') return $this->fail('缺少参数');
$info = $this->services->get($id);
if (!$info) {
$this->fail('视频不存在');
}
$this->services->update($id, ['is_recommend' => $recommend]);
return $this->success($recommend == 1 ? '推荐成功' : '取消推荐');
}
/**
* 强制下架
* @param $id
* @param $recommend
* @return mixed
*/
public function takeDown($id)
{
if ($id == '') return $this->fail('缺少参数');
$info = $this->services->get($id);
if (!$info) {
$this->fail('视频不存在');
}
$this->services->update($id, ['is_verify' => -2, 'is_show' => 0, 'is_recommend' => 0]);
return $this->success('下架成功');
}
/**
* 删除视频
* @param $id
* @return mixed
*/
public function delete($id)
{
if ($id == '') return $this->fail('缺少参数');
$info = $this->services->get($id);
if ($info) {
$this->services->update($id, ['is_del' => 1]);
}
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,173 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\marketing\video;
use think\annotation\Inject;
use think\db\exception\DbException;
use app\controller\admin\AuthController;
use app\services\activity\video\VideoCommentServices;
use app\services\activity\video\VideoServices;
/**
* 视频评论控制器
* Class VideoComment
* @package app\admin\controller\v1\marketing\video
*/
class VideoComment extends AuthController
{
/**
* @var VideoCommentServices
*/
#[Inject]
protected VideoCommentServices $services;
/**
* 显示资源列表
*
* @return \think\Response
* @throws DbException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['is_reply', ''],
['keyword', ''],
['data', '', '', 'time'],
['video_id', 0]
]);
$list = $this->services->sysPage($where);
return $this->success($list);
}
/**
* 获取评论回复列表
* @param $id
* @return mixed
* @throws DbException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getCommentReply($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
$time = $this->request->get('data', '');
return $this->success($this->services->getCommentReplyList((int)$id, ['time' => $time]));
}
/**
* 管理员回复评论
* @param $id
* @return mixed
*/
public function setReply($id)
{
[$content] = $this->request->postMore([
['content', '']
], true);
$this->services->setReply($id, $content);
return $this->success('回复成功!');
}
/**
* 获取管理员评论
* @param $id
* @return mixed
*/
public function getReply($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
$where = ['pid' => $id, 'uid' => 0];
$commentInfo = $this->dao->get($where);
if ($commentInfo) {
return $this->success($commentInfo->toArray());
} else {
return $this->success(['content' => '']);
}
}
/**
* 创建虚拟评论表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function fictitiousComment()
{
[$video_id] = $this->request->postMore([
['video_id', 0],
], true);
return $this->success($this->services->createForm((int)$video_id));
}
/**
* 保存虚拟评论
* @return mixed
*/
public function saveFictitiousComment()
{
$data = $this->request->postMore([
['video', ''],
['nickname', ''],
['avatar', ''],
['content', ''],
['video_id', 0],
['add_time', 0]
]);
if (!$data['video_id']) {
$data['video_id'] = $data['video']['video_id'] ?? '';
}
if (!isset($data['video_id']) || !$data['video_id']) {
return $this->fail('请选择要评论的视频');
}
$video_id = (int)$data['video_id'];
unset($data['video_id'], $data['video']);
$data['ip'] = $this->request->ip();
$this->services->saveComment(-1, $video_id, 0, $data);
return $this->success('添加成功!');
}
/**
* 删除评论
* @param $id
* @return mixed
*/
public function delete($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
$id = (int)$id;
$count_par = $this->services->getCount(['id' => $id, 'is_del' => 0]);
if ($count_par) {
$count_sub = $this->services->getCount(['pid' => $id, 'is_del' => 0]);
$res_par = $this->services->update($id, ['is_del' => 1]);
$res_sub = $this->services->update(['pid' => $id], ['is_del' => 1]);
if ($res_par && $res_sub) {
$count = $count_par + $count_sub;
//产找视频id
if ($video_id = $this->services->value(['id' => $id], 'video_id')) {
/** @var VideoServices $videoServices */
$videoServices = app()->make(VideoServices::class);
$videoServices->bcDec($video_id, 'comment_num', $count);
}
}
}
return $this->success('删除成功');
}
}

View File

@@ -0,0 +1,166 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\merchant;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\store\SystemStoreServices;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Response;
/**
* 门店管理控制器
* Class SystemAttachment
* @package app\admin\controller\system
*
*/
class SystemStore extends AuthController
{
/**
* @var SystemStoreServices
*/
#[Inject]
protected SystemStoreServices $services;
/**
* 获取门店列表1
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
[['keywords', 's'], ''],
[['type', 'd'], 0]
]);
return $this->success($this->services->getStoreList($where));
}
/**
* 获取门店头部
* @return mixed
*/
public function get_header()
{
$count = $this->services->getStoreData();
return $this->success(compact('count'));
}
/**
* 门店设置
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function get_info()
{
[$id] = $this->request->getMore([
[['id', 'd'], 0],
], true);
$info = $this->services->getStoreDispose($id);
return $this->success(compact('info'));
}
/**
* 位置选择
* @return mixed
*/
public function select_address()
{
$key = sys_config('tengxun_map_key');
if (!$key) return $this->fail('提示:前往设置->系统设置->第三方接口 配置腾讯地图KEY');
return $this->success(compact('key'));
}
/**
* 设置单个门店是否显示
* @param string $is_show
* @param string $id
* @return Response
*/
public function set_show($is_show = '', $id = '')
{
($is_show == '' || $id == '') && $this->fail('缺少参数');
$res = $this->services->update((int)$id, ['is_show' => (int)$is_show]);
if ($res) {
return $this->success($is_show == 1 ? '设置显示成功' : '设置隐藏成功');
} else {
return $this->fail($is_show == 1 ? '设置显示失败' : '设置隐藏失败');
}
}
/**
* 保存修改门店信息
* param int $id
* */
public function save($id = 0)
{
$data = $this->request->postMore([
['name', ''],
['introduction', ''],
['image', ''],
['phone', ''],
['address', ''],
['detailed_address', ''],
['latlng', ''],
['day_time', []],
]);
$this->validate($data, \app\validate\admin\merchant\SystemStoreValidate::class, 'save');
$data['address'] = implode(',', $data['address']);
$data['latlng'] = explode(',', $data['latlng']);
if (!isset($data['latlng'][0]) || !isset($data['latlng'][1])) {
return $this->fail('请选择门店位置');
}
$data['latitude'] = $data['latlng'][0];
$data['longitude'] = $data['latlng'][1];
$data['day_time'] = implode(' - ', $data['day_time']);
unset($data['latlng']);
if ($data['image'] && strstr($data['image'], 'http') === false) {
$site_url = sys_config('site_url');
$data['image'] = $site_url . $data['image'];
}
$this->services->saveStore((int)$id, $data);
return $this->success('操作成功!');
}
/**
* 删除恢复门店
* @param $id
*/
public function delete($id)
{
if (!$id) return $this->fail('数据不存在');
$storeInfo = $this->services->get($id);
if (!$storeInfo) {
return $this->fail('数据不存在');
}
if ($storeInfo->is_del == 1) {
$storeInfo->is_del = 0;
if (!$storeInfo->save())
return $this->fail('恢复失败,请稍候再试!');
else
return $this->success('恢复自提点成功!');
} else {
$storeInfo->is_del = 1;
if (!$storeInfo->save())
return $this->fail('删除失败,请稍候再试!');
else
return $this->success('删除自提点成功!');
}
}
}

View File

@@ -0,0 +1,175 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\merchant;
use app\services\store\SystemStoreServices;
use app\services\store\SystemStoreStaffServices;
use FormBuilder\Exception\FormBuilderException;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
/**
* 店员
* Class SystemStoreStaff
* @package app\controller\admin\v1\merchant
*/
class SystemStoreStaff extends AuthController
{
/**
* @var SystemStoreStaffServices
*/
#[Inject]
protected SystemStoreStaffServices $services;
/**
* 获取店员列表
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
[['store_id', 'd'], 0],
]);
return $this->success($this->services->getStoreStaffList($where, ['store', 'user']));
}
/**
* 门店列表
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function store_list(SystemStoreServices $services)
{
return $this->success($services->getStore());
}
/**
* 店员新增表单
* @return mixed
* @throws FormBuilderException
*/
public function create()
{
return $this->success($this->services->createForm());
}
/**
* 店员修改表单
* @return mixed
* @throws FormBuilderException
*/
public function edit()
{
[$id] = $this->request->getMore([
[['id', 'd'], 0],
], true);
return $this->success($this->services->updateForm($id));
}
/**
* 保存店员信息
*/
public function save($id = 0)
{
$data = $this->request->postMore([
['image', ''],
['uid', 0],
['avatar', ''],
['store_id', ''],
['staff_name', ''],
['phone', ''],
['verify_status', 1],
['status', 1],
]);
if ($data['store_id'] == '') {
return $this->fail('请选择所属提货点');
}
if ($data['staff_name'] == '') {
return $this->fail('请填写核销员名称');
}
if ($data['phone'] == '') {
return $this->fail('请填写核销员电话');
}
if ($data['uid'] == 0) {
return $this->fail('请选择用户');
}
if (!$id) {
if ($data['image'] == '') {
return $this->fail('请选择用户');
}
if ($this->services->count(['uid' => $data['uid'], 'store_id' => $data['store_id'], 'is_del' => 0])) {
return $this->fail('添加的核销员用户已存在!');
}
$data['uid'] = $data['image']['uid'];
$data['avatar'] = $data['image']['image'];
} else {
$data['avatar'] = $data['image'];
}
unset($data['image']);
if ($id) {
$res = $this->services->update($id, $data);
if ($res) {
return $this->success('编辑成功');
} else {
return $this->fail('编辑失败');
}
} else {
$data['add_time'] = time();
$res = $this->services->save($data);
if ($res) {
return $this->success('核销员添加成功');
} else {
return $this->fail('核销员添加失败,请稍后再试');
}
}
}
/**
* 设置单个店员是否开启
* @param string $is_show
* @param string $id
* @return mixed
*/
public function set_show($is_show = '', $id = '')
{
if ($is_show == '' || $id == '') {
$this->fail('缺少参数');
}
$res = $this->services->update($id, ['status' => (int)$is_show]);
if ($res) {
return $this->success($is_show == 1 ? '开启成功' : '关闭成功');
} else {
return $this->fail($is_show == 1 ? '开启失败' : '关闭失败');
}
}
/**
* 删除店员
* @param $id
*/
public function delete($id)
{
if (!$id) return $this->fail('数据不存在');
if (!$this->services->delete($id))
return $this->fail('删除失败,请稍候再试!');
else
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,86 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\merchant;
use app\controller\admin\AuthController;
use app\services\order\StoreOrderServices;
use app\services\user\UserServices;
use think\annotation\Inject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
/**
* 核销订单
* Class SystemVerifyOrder
* @package app\controller\admin\v1\merchant
*/
class SystemVerifyOrder extends AuthController
{
/**
* @var StoreOrderServices
*/
#[Inject]
protected StoreOrderServices $services;
/**
* 获取核销订单列表
* return json
*/
public function list()
{
$where = $this->request->getMore([
['data', '', '', 'time'],
['real_name', ''],
['store_id', ''],
['type', ''],
['field_key', ''],
]);
$data = $this->services->getOrderList($where + ['status' => 6], ['*'], ['store', 'staff']);
return $this->success(['count' => $data['count'], 'data' => $data['data'], 'badge' => $data['stat']]);
}
/**
* 未使用,获取核销订单头部
* @return mixed
*/
public function getVerifyBadge()
{
return $this->success([]);
}
/**
* 订单列表推荐人详细
* @param $uid
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function order_spread_user($uid)
{
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userInfo = $userServices->getUserInfo((int)$uid);
$spread = [];
if ($userInfo['spread_uid']) {
$spread = $userServices->getUserInfo((int)$userInfo['spread_uid']);
if ($spread) {
$spread = $spread->toArray();
$spread['brokerage_pric'] = $spread['brokerage_price'];
$spread['birthday'] = $spread['birthday'] ?: '';
$spread['last_time'] = $spread['last_time'] ? date('Y-m-d H:i:s', $spread['last_time']) : '';
}
}
return $this->success(['spread' => $spread]);
}
}

View File

@@ -0,0 +1,107 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\message;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\message\SystemNotificationServices;
/**
* Class SystemRole
* @package app\adminapi\controller\v1\setting
*/
class SystemNotification extends AuthController
{
/**
* @var SystemNotificationServices
*/
#[Inject]
protected SystemNotificationServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['type', ''],
]);
return app('json')->success($this->services->getNotList($where));
}
/**
* 显示编辑
*
* @return \think\Response
*/
public function info()
{
$where = $this->request->getMore([
['type', ''],
['id', 0]
]);
if (!$where['id']) return app('json')->fail('参数错误');
return app('json')->success($this->services->getNotInfo($where));
}
/**
* 保存新建的资源
*
* @return \think\Response
*/
public function save()
{
$data = $this->request->postMore([
['id', 0],
['type', ''],
['name', ''],
['title', ''],
['is_system', 0],
['is_app', 0],
['is_wechat', 0],
['is_routine', 0],
['is_sms', 0],
['sms_id', 0],
['is_ent_wechat', 0],
['system_title', ''],
['system_text', ''],
['tempid', ''],
['ent_wechat_text', ''],
['url', ''],
['wechat_id', ''],
['routine_id', '']
]);
if (!$data['id']) return app('json')->fail('参数错误');
if ($this->services->saveData($data)) {
$this->services->clearTemplateCache();
return app('json')->success('修改成功!');
} else {
return app('json')->fail('修改失败,请稍候再试!');
}
}
/**
* 修改消息状态
*
* @return array
*/
public function set_status($type, $status, $id)
{
if ($type == '' || $status == '' || $id == 0) return $this->fail('参数错误');
$this->services->update($id, [$type => $status]);
$this->services->clearTemplateCache();
return $this->success($status == 1 ? '开启成功' : '关闭成功');
}
}

View File

@@ -0,0 +1,321 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\message\service;
use app\controller\admin\AuthController;
use app\services\kefu\LoginServices;
use app\services\message\service\StoreServiceLogServices;
use app\services\message\service\StoreServiceServices;
use app\services\user\UserServices;
use app\services\user\UserWechatuserServices;
use crmeb\exceptions\AdminException;
use crmeb\services\CacheService;
use think\annotation\Inject;
/**
* 客服管理
* Class StoreService
* @package app\admin\controller\store
*/
class StoreService extends AuthController
{
/**
* @var StoreServiceServices
*/
#[Inject]
protected StoreServiceServices $services;
/**
* 显示资源列表
*
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
return $this->success($this->services->getServiceList([]));
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create(UserWechatuserServices $services)
{
$where = $this->request->getMore([
['nickname', ''],
['data', '', '', 'time'],
['type', '', '', 'user_type'],
['is_channel','']
]);
$where['is_filter_del'] = 1;
[$list, $count] = $services->getWhereUserList($where, 'u.nickname,u.uid,u.avatar as headimgurl,u.user_type,u.add_time,w.subscribe,w.province,w.country,w.city,w.sex');
foreach ($list as &$item) {
$item['subscribe'] = is_null($item['subscribe']) ? 0 : $item['subscribe'];
$item['country'] = is_null($item['country']) ? '' : $item['country'];
$item['province'] = is_null($item['province']) ? '' : $item['province'];
$item['city'] = is_null($item['city']) ? '' : $item['city'];
$item['sex'] = is_null($item['sex']) ? 0 : $item['sex'];
$item['add_time'] = date('Y-m-d H:i', $item['add_time']);
}
return $this->success(compact('list', 'count'));
}
/**
* 添加客服表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function add()
{
return $this->success($this->services->create());
}
/*
* 保存新建的资源
*/
public function save()
{
$data = $this->request->postMore([
['image', ''],
['uid', 0],
['avatar', ''],
['customer', ''],
['notify', ''],
['phone', ''],
['account', ''],
['password', ''],
['true_password', ''],
['phone', ''],
['nickname', ''],
['status', 1],
['account_status', 1],
]);
if ($data['image'] == '') return $this->fail('请选择用户');
$data['uid'] = $data['image']['uid'];
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$userInfo = $userService->get($data['uid']);
if ($data['phone'] == '') {
if (!$userInfo['phone']) {
return $this->fail('该用户没有绑定手机号,请手动填写');
} else {
$data['phone'] = $userInfo['phone'];
}
} else {
if (!check_phone($data['phone'])) {
return $this->fail('请输入正确的手机号');
}
}
if ($data['nickname'] == '') $data['nickname'] = $userInfo['nickname'];
$data['avatar'] = $data['image']['image'];
if ($this->services->count(['uid' => $data['uid']])) {
return $this->fail('客服已存在!');
}
unset($data['image']);
$data['add_time'] = time();
if (!$data['account']) {
return $this->fail('请输入账号');
}
if (!preg_match('/^[a-zA-Z0-9]{4,30}$/', $data['account'])) {
return $this->fail('账号必须为数字或者字母的组合4-30位');
}
if (!$data['password']) {
return $this->fail('请输入密码');
}
if (!preg_match('/^[0-9a-z_$]{6,20}$/i', $data['password'])) {
return $this->fail('密码必须为数字或者字母的组合6-20位');
}
if ($this->services->count(['phone' => $data['phone']])) {
return $this->fail('该手机号的客服已存在!');
}
if ($this->services->count(['account' => $data['account']])) {
return $this->fail('该客服账号已存在!');
}
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
$res = $this->services->save($data);
if ($res) {
return $this->success('客服添加成功');
} else {
return $this->fail('客服添加失败,请稍后再试');
}
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
return $this->success($this->services->edit((int)$id));
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return \think\Response
*/
public function update($id)
{
$data = $this->request->postMore([
['avatar', ''],
['nickname', ''],
['account', ''],
['phone', ''],
['status', 1],
['account_status', 1],
['notify', 1],
['customer', 1],
['password', ''],
['true_password', ''],
]);
$customer = $this->services->get((int)$id);
if (!$customer) {
return $this->fail('数据不存在');
}
if ($data["nickname"] == '') {
return $this->fail("客服名称不能为空!");
}
if (!check_phone($data['phone'])) {
return $this->fail('请输入正确的手机号');
}
if ($customer['phone'] != $data['phone'] && $this->services->count(['phone' => $data['phone']])) {
return $this->fail('该手机号的客服已存在!');
}
if ($data['password']) {
if (!preg_match('/^[0-9a-z_$]{6,16}$/i', $data['password'])) {
return $this->fail('密码必须为数字或者字母的组合');
}
if (!$data['true_password']) {
return $this->fail('请输入确认密码');
}
if ($data['password'] != $data['true_password']) {
return $this->fail('两次输入的密码不正确');
}
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
} else {
unset($data['password']);
}
$this->services->update($id, $data);
return $this->success('修改成功!');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$this->services->delete($id))
return $this->fail('删除失败,请稍候再试!');
else
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_status(UserServices $services, $id, $status)
{
if ($status == '' || $id == 0) return $this->fail('参数错误');
$info = $this->services->get($id, ['account_status', 'uid']);
if (!$services->count(['uid' => $info['uid']])) {
$info->account_status = 1;
$info->save();
return $this->fail('用户不存在,客服将强制禁止登录');
}
$info->account_status = $status;
$info->save();
return $this->success($status == 0 ? '隐藏成功' : '显示成功');
}
/**
* 聊天记录
*
* @return \think\Response
*/
public function chat_user($id)
{
$uid = $this->services->value(['id' => $id], 'uid');
if (!$uid) {
return $this->fail('数据不存在!');
}
return $this->success($this->services->getChatUser((int)$uid));
}
/**
* 聊天记录
* @param StoreServiceLogServices $services
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function chat_list(StoreServiceLogServices $services)
{
$data = $this->request->getMore([
['uid', 0],
['to_uid', 0],
['id', 0]
]);
if ($data['uid']) {
CacheService::set('admin_chat_list' . $this->adminId, $data);
}
$data = CacheService::get('admin_chat_list' . $this->adminId);
if ($data['uid']) {
$where = [
'chat' => [$data['uid'], $data['to_uid']],
];
} else {
$where = [];
}
$list = $services->getChatLogList($where);
return $this->success($list);
}
/**
* 客服登录
* @param LoginServices $services
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function keufLogin(LoginServices $services, $id)
{
$serviceInfo = $services->get($id);
if (!$serviceInfo) {
return $this->fail('登录的客服不存在');
}
if (!$serviceInfo->account || !$serviceInfo->password) {
return $this->fail('请先填写客服账号和密码再尝试进入客服平台');
}
if (!$serviceInfo->account_status || !$serviceInfo->status) {
return $this->fail('客服帐号已被禁用');
}
return $this->success($services->authLogin($serviceInfo->account));
}
}

View File

@@ -0,0 +1,109 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\message\service;
use app\controller\admin\AuthController;
use app\services\message\service\StoreServiceFeedbackServices;
use think\annotation\Inject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
/**
* 客服用户留言反馈
* Class StoreServiceFeedback
* @package app\controller\admin\v1\application\wechat
*/
class StoreServiceFeedback extends AuthController
{
/**
* @var StoreServiceFeedbackServices
*/
#[Inject]
protected StoreServiceFeedbackServices $services;
/**
* 获取留言列表
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['title', ''],
['time', '']
]);
return $this->success($this->services->getFeedbackList($where));
}
/**
* 获取修改表单
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function edit($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
return $this->success($this->services->editForm((int)$id));
}
/**
* 修改
* @param $id
* @return mixed
*/
public function update($id)
{
$data = $this->request->postMore([
['make', ''],
['status', 0],
]);
if (!$id || !($feedInfo = $this->services->get($id))) {
return $this->fail('反馈内容不存在');
}
$feedInfo->make = $data['make'];
if ($data['status']) {
$feedInfo->status = $data['status'];
}
$feedInfo->save();
return $this->success('修改成功');
}
/**
* 删除反馈
* @param $id
* @return mixed
* @throws \Exception
*/
public function delete($id)
{
if (!$id) {
return $this->fail('缺少参数');
}
if ($this->services->delete($id)) {
return $this->success('删除成功');
} else {
return $this->fail('删除失败');
}
}
}

View File

@@ -0,0 +1,167 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\message\service;
use app\Request;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\message\service\StoreServiceSpeechcraftServices;
use app\validate\admin\service\StoreServiceSpeechcraftValidate;
/**
* 话术空控制器
* Class StoreServiceSpeechcraft
* @package app\controller\admin\v1\application\wechat
*/
class StoreServiceSpeechcraft extends AuthController
{
/**
* @var StoreServiceSpeechcraftServices
*/
#[Inject]
protected StoreServiceSpeechcraftServices $services;
/**
* 显示资源列表
*
* @param Request $request
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index(Request $request)
{
$where = $request->getMore([
['title', ''],
['message', ''],
[['cate_id', 'd'], ''],
]);
$where['kefu_id'] = 0;
return $this->success($this->services->getSpeechcraftList($where));
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
[$cate_id] = $this->request->getMore([
['cate_id', 0]
], true);
return $this->success($this->services->createForm((int)$cate_id));
}
/**
* 保存新建的资源
*
* @param \app\Request $request
* @return \think\Response
*/
public function save(Request $request)
{
$data = $request->postMore([
['title', ''],
['message', ''],
[['cate_id', 'd'], 0],
['sort', 0],
]);
$this->validate($data, StoreServiceSpeechcraftValidate::class);
$data['add_time'] = time();
$data['kefu_id'] = 0;
if ($this->services->count(['message' => $data['message']])) {
return $this->fail('话术不能重复添加');
}
if ($this->services->save($data)) {
return $this->success('创建话术成功');
} else {
return $this->fail('创建话术失败');
}
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
$info = $this->services->get($id);
if (!$info) {
return $this->fail('获取失败');
}
return $this->success($info);
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
return $this->success($this->services->updateForm((int)$id));
}
/**
* 保存更新的资源
*
* @param \app\Request $request
* @param int $id
* @return \think\Response
*/
public function update(Request $request, $id)
{
$data = $request->postMore([
['title', ''],
['message', ''],
['sort', 0],
[['cate_id', 'd'], 0],
]);
$this->validate($data, StoreServiceSpeechcraftValidate::class);
$message = $this->services->get(['message' => $data['message']]);
if ($message && $message['id'] != $id) {
return $this->fail('话术不能重复添加');
}
if ($this->services->update($id, $data)) {
return $this->success('修改成功');
} else {
return $this->fail('修改失败');
}
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id || !($info = $this->services->get($id))) {
return $this->fail('删除的话术不存在!');
}
if ($info->delete()) {
return $this->success('删除成功');
} else {
return $this->fail('删除失败');
}
}
}

View File

@@ -0,0 +1,145 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\message\service;
use app\Request;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\message\service\StoreServiceSpeechcraftCateServices;
/**
* Class StoreServiceSpeechcraftCate
* @package app\controller\admin\v1\application\wechat
*/
class StoreServiceSpeechcraftCate extends AuthController
{
/**
* @var StoreServiceSpeechcraftCateServices
*/
#[Inject]
protected StoreServiceSpeechcraftCateServices $services;
/**
* 获取列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['name', '']
]);
$where['owner_id'] = 0;
$where['type'] = 0;
$where['group'] = 1;
return $this->success($this->services->getCateList($where));
}
/**
* 获取创建表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function create()
{
return $this->success($this->services->createForm());
}
/**
* 保存数据
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
['name', ''],
['sort', 0],
]);
if (!$data['name']) {
return $this->fail('请输入分类名称');
}
if ($this->services->count(['name' => $data['name'], 'group' => 1])) {
return $this->fail('分类已存在');
}
$data['add_time'] = time();
$data['group'] = 1;
$this->services->save($data);
return $this->success('添加成功');
}
/**
* 获取修改表单
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit($id)
{
return $this->success($this->services->editForm((int)$id));
}
/**
* 修改保存
* @param Request $request
* @param $id
* @return mixed
*/
public function update(Request $request, $id)
{
$data = $request->postMore([
['name', ''],
[['sort', 'd'], 0],
]);
if (!$data['name']) {
return $this->fail('请输入分类名称');
}
$cateInfo = $this->services->get($id);
if (!$cateInfo) {
return $this->fail('修改的分类不存在');
}
$old = $this->services->getOne(['name' => $data['name'], 'group' => 1]);
if ($old && $old['id'] != $id) {
return $this->fail('分类已存在');
}
$cateInfo->name = $data['name'];
$cateInfo->sort = $data['sort'];
$cateInfo->save();
return $this->success('修改成功');
}
/**
* 删除
* @param $id
* @return mixed
*/
public function delete($id)
{
$cateInfo = $this->services->get($id);
if (!$cateInfo) {
return $this->fail('删除的分类不存在');
}
$cateInfo->delete();
return $this->success('删除成功');
}
}

View File

@@ -0,0 +1,75 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\notification\sms;
use app\controller\admin\AuthController;
use app\services\message\sms\SmsAdminServices;
use think\facade\App;
/**
* 短信账号
* Class SmsAdmin
* @package app\controller\admin\v1\sms
*/
class SmsAdmin extends AuthController
{
/**
* 构造方法
* SmsAdmin constructor.
* @param App $app
* @param SmsAdminServices $services
*/
public function __construct(App $app, SmsAdminServices $services)
{
parent::__construct($app);
$this->services = $services;
}
/**
* 发送验证码
* @return mixed
*/
public function captcha()
{
if (!request()->isPost()) {
return $this->fail('发送失败');
}
$phone = request()->param('phone');
if (!trim($phone)) {
return $this->fail('请填写手机号');
}
return $this->success($this->services->captcha($phone));
}
/**
* 修改/注册短信平台账号
*/
public function save()
{
[$account, $password, $phone, $code, $url, $sign] = $this->request->postMore([
['account', ''],
['password', ''],
['phone', ''],
['code', ''],
['url', ''],
['sign', ''],
], true);
$signLen = mb_strlen(trim($sign));
if (!strlen(trim($account))) return $this->fail('请填写账号');
if (!strlen(trim($password))) return $this->fail('请填写密码');
if (!$signLen) return $this->fail('请填写短信签名');
if ($signLen > 8) return $this->fail('短信签名最长为8位');
if (!strlen(trim($code))) return $this->fail('请填写验证码');
if (!strlen(trim($url))) return $this->fail('请填写域名');
$status = $this->services->register($account, $password, $url, $phone, $code, $sign);
return $this->success('短信平台:' . $status['msg']);
}
}

View File

@@ -0,0 +1,57 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\notification\sms;
use think\annotation\Inject;
use app\services\message\sms\SmsAdminServices;
use app\services\serve\ServeServices;
use crmeb\services\CacheService;
use app\controller\admin\AuthController;
use crmeb\services\SystemConfigService;
/**
* 短信配置
* Class SmsConfig
* @package app\admin\controller\sms
*/
class SmsConfig extends AuthController
{
/**
* @var SmsAdminServices
*/
#[Inject]
protected SmsAdminServices $services;
/**
* 保存短信配置
* @return mixed
*/
public function save_basics()
{
[$account, $token] = $this->request->postMore([
['sms_account', ''],
['sms_token', '']
], true);
$this->validate(['sms_account' => $account, 'sms_token' => $token], \app\validate\admin\notification\SmsConfigValidate::class);
if(sys_config('sms_account') && sys_config('sms_token')){
return $this->success('保存成功');
}
if ($this->services->updateSmsConfig($account, $token)) {
return $this->success('保存成功');
} else {
return $this->fail('保存失败');
}
}
}

View File

@@ -0,0 +1,80 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\notification\sms;
use crmeb\exceptions\AdminException;
use app\controller\admin\AuthController;
use crmeb\services\{sms\Sms, SystemConfigService};
/**
* 短信购买
* Class SmsPay
* @package app\controller\admin\v1\notification\sms
*/
class SmsPay extends AuthController
{
/**
* @var Sms
*/
protected $smsHandle;
public function initialize()
{
parent::initialize();
$data = SystemConfigService::more(['sms_account', 'sms_token', 'site_url']);
$this->smsHandle = new Sms('yunxin', $data);
if (!$this->smsHandle->isLogin()) {
return $this->fail('请先填写短息配置');
}
}
/**
* 获取账号信息
*/
public function number()
{
$countInfo = $this->smsHandle->count();
if ($countInfo['status'] == 400) return $this->fail($countInfo['msg']);
$info['account'] = sys_config('sms_account');
$info['number'] = $countInfo['data']['number'];
$info['send_total'] = $countInfo['data']['send_total'];
return $this->success($info);
}
/**
* 获取支付套餐
*/
public function price()
{
[$page, $limit] = $this->request->getMore([
['page', 1],
['limit', 20],
], true);
$mealInfo = $this->smsHandle->meal($page, $limit);
if ($mealInfo['status'] == 400) return $this->fail($mealInfo['msg']);
return $this->success($mealInfo['data']);
}
/**
* 获取支付码
*/
public function pay()
{
[$payType, $mealId, $price] = $this->request->postMore([
['payType', 'weixin'],
['mealId', 0],
['price', 0],
], true);
$payInfo = $this->smsHandle->pay($payType, $mealId, $price, $this->adminId);
if ($payInfo['status'] == 400) return $this->fail($payInfo['msg']);
return $this->success($payInfo['data']);
}
}

View File

@@ -0,0 +1,77 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\notification\sms;
use app\controller\admin\AuthController;
use crmeb\exceptions\AdminException;
use crmeb\services\sms\Sms;
use crmeb\services\SystemConfigService;
/**
* 公共短信模板
* Class SmsPublicTemp
* @package app\controller\admin\v1\notification\sms
*/
class SmsPublicTemp extends AuthController
{
/**
* @var Sms
*/
protected $smsHandle;
/**
* 初始化短信配置
* @return void
*/
public function initialize()
{
parent::initialize();
$data = SystemConfigService::more(['sms_account', 'sms_token', 'site_url']);
$this->smsHandle = new Sms('yunxin', $data);
if (!$this->smsHandle->isLogin()) {
return $this->fail('请先填写短息配置');
}
}
/**
* 异步获取公共模板列表
*/
public function index()
{
$where = $this->request->getMore([
['is_have', ''],
['page', 1],
['limit', 20],
]);
$templateList = $this->smsHandle->publictemp($where);
if ($templateList['status'] == 400) return $this->fail($templateList['msg']);
$arr = $templateList['data']['data'];
foreach ($arr as $key => $value) {
switch ($value['type']) {
case 1:
$arr[$key]['type'] = '验证码';
break;
case 2:
$arr[$key]['type'] = '通知';
break;
case 3:
$arr[$key]['type'] = '推广';
break;
default:
$arr[$key]['type'] = '';
break;
}
}
$templateList['data']['data'] = $arr;
return $this->success($templateList['data']);
}
}

View File

@@ -0,0 +1,93 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\notification\sms;
use app\controller\admin\AuthController;
use app\services\serve\ServeServices;
use think\facade\App;
/**
* 短信模板申请
* Class SmsTemplateApply
* @package app\controller\admin\v1\notification\sms
*/
class SmsTemplateApply extends AuthController
{
public function __construct(App $app, ServeServices $services)
{
parent::__construct($app);
$this->services = $services;
}
/**
* 异步获取模板列表
*/
public function index()
{
$where = $this->request->getMore([
[['type', 'd'], 0],
['status', ''],
['title', ''],
[['page', 'd'], 1],
[['limit', 'd'], 20],
]);
$where['temp_type'] = $where['type'];
$templateList = $this->services->sms()->temps($where['page'], $where['limit'], $where['type']);
$templateList['data'] = $templateList['data'] ?? [];
foreach ($templateList['data'] as $key => &$item) {
$item['templateid'] = $item['temp_id'];
switch ((int)$item['temp_type']) {
case 1:
$item['type'] = '验证码';
break;
case 2:
$item['type'] = '通知';
break;
case 30:
$item['type'] = '营销短信';
break;
}
}
return $this->success($templateList);
}
/**
* 显示创建资源表单页.
*
* @return string
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function create()
{
return $this->success($this->services->getSmsTemplateForm());
}
/**
* 保存新建的资源
*/
public function save()
{
$data = $this->request->postMore([
['title', ''],
['content', ''],
['type', 0]
]);
if (!strlen(trim($data['title']))) {
return $this->fail('请输入模板名称');
}
if (!strlen(trim($data['content']))) {
return $this->fail('请输入模板内容');
}
$this->services->sms()->apply($data['title'], $data['content'], $data['type']);
return $this->success('申请成功');
}
}

View File

@@ -0,0 +1,199 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\order;
use app\controller\admin\AuthController;
use app\services\store\DeliveryServiceServices;
use app\services\user\UserServices;
use app\services\user\UserWechatuserServices;
use crmeb\exceptions\AdminException;
use think\annotation\Inject;
/**
* 配送员
* Class StoreService
* @package app\admin\controller\store
*/
class DeliveryService extends AuthController
{
/**
* @var DeliveryServiceServices
*/
#[Inject]
protected DeliveryServiceServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
return $this->success($this->services->getServiceList(['type' => 0, 'is_del' => 0]));
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create(UserWechatuserServices $services)
{
$where = $this->request->getMore([
['nickname', ''],
['data', '', '', 'time'],
['type', '', '', 'user_type'],
]);
[$list, $count] = $services->getWhereUserList($where, 'u.nickname,u.uid,u.avatar as headimgurl,w.subscribe,w.province,w.country,w.city,w.sex');
return $this->success(compact('list', 'count'));
}
/**
* 添加客服表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function add()
{
return $this->success($this->services->create());
}
/*
* 保存新建的资源
*/
public function save()
{
$data = $this->request->postMore([
['image', ''],
['uid', 0],
['avatar', ''],
['phone', ''],
['nickname', ''],
['status', 1],
]);
if ($data['image'] == '') return $this->fail('请选择用户');
$data['uid'] = $data['image']['uid'];
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$userInfo = $userService->get($data['uid']);
if ($data['phone'] == '') {
if (!$userInfo['phone']) {
return $this->fail('该用户没有绑定手机号,请手动填写');
} else {
$data['phone'] = $userInfo['phone'];
}
} else {
if (!check_phone($data['phone'])) {
return $this->fail('请输入正确的手机号!');
}
}
if ($data['nickname'] == '') $data['nickname'] = $userInfo['nickname'];
$data['avatar'] = $data['image']['image'];
if ($this->services->count(['uid' => $data['uid'], 'type' => 0, 'is_del' => 0])) {
return $this->fail('配送员已存在!');
}
if ($this->services->count(['phone' => $data['phone'], 'type' => 0, 'is_del' => 0])) {
return $this->fail('同一个手机号的配送员只能添加一个!');
}
unset($data['image']);
$data['type'] = 0;
$data['add_time'] = time();
$res = $this->services->save($data);
if ($res) {
return $this->success('配送员添加成功');
} else {
return $this->fail('配送员添加失败,请稍后再试');
}
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
return $this->success($this->services->edit((int)$id));
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return \think\Response
*/
public function update($id)
{
$data = $this->request->postMore([
['avatar', ''],
['nickname', ''],
['phone', ''],
['status', 1],
]);
$delivery = $this->services->get((int)$id);
if (!$delivery) {
return $this->fail('数据不存在');
}
if ($data["nickname"] == '') {
return $this->fail("配送员名称不能为空!");
}
if (!$data['phone']) {
return $this->fail("手机号不能为空!");
}
if (!check_phone($data['phone'])) {
return $this->fail('请输入正确的手机号!');
}
if ($delivery['phone'] != $data['phone'] && $this->services->count(['phone' => $data['phone'], 'type' => 0, 'is_del' => 0])) {
return $this->fail('同一个手机号的配送员只能添加一个!');
}
$this->services->update($id, $data);
return $this->success('修改成功!');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$this->services->delete($id))
return $this->fail('删除失败,请稍候再试!');
else
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_status($id, $status)
{
if ($status == '' || $id == 0) return $this->fail('参数错误');
$this->services->update($id, ['status' => $status]);
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
/**
*获取所有配送员列表
*/
public function get_delivery_list()
{
$data = $this->services->getDeliveryList();
return $this->success($data);
}
}

View File

@@ -0,0 +1,102 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\order;
use app\controller\admin\AuthController;
use app\services\order\OtherOrderServices;
use app\services\other\QrcodeServices;
use crmeb\utils\Canvas;
use think\annotation\Inject;
/**
* Class OtherOrder
* @package app\controller\admin\v1\order
*/
class OtherOrder extends AuthController
{
/**
* @var OtherOrderServices
*/
#[Inject]
protected OtherOrderServices $services;
/**
* 线下收银
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function scan_list()
{
$where = $this->request->getMore([
['order_id', ''],
['add_time', ''],
['name', ''],
['page', 1],
['limit', 20],
]);
$data = $this->services->getScanOrderList($where);
return $this->success($data);
}
/**
* 获取线下二维码
* @return mixed
* @throws \Exception
*/
public function offline_scan()
{
[$type] = $this->request->getMore([
['type', 1]
], true);
//生成h5地址
$weixinPage = "/pages/annex/offline_pay/index";
$weixinFileName = "wechat_offline_scan.png";
/** @var QrcodeServices $QrcodeService */
$QrcodeService = app()->make(QrcodeServices::class);
$wechatQrcode = $QrcodeService->getWechatQrcodePath($weixinFileName, $weixinPage, false, false);
//生成小程序地址
$routineQrcode = $QrcodeService->getRoutineQrcodePath(4, 6, 103, $weixinFileName, false);
$qrcod = ['wechat' => $wechatQrcode, 'routine' => $routineQrcode];
if ($type) {
//生成画布
$canvas = Canvas::instance();
$path = 'uploads/offline/';
$imageType = 'jpg';
$siteUrl = sys_config('site_url');
$canvas->setImageUrl(public_path() . 'statics/qrcode/offlines.jpg')->setImageHeight(730)->setImageWidth(500)->pushImageValue();
foreach ($qrcod as $k => $v) {
if ($v) {
$name = 'offline_' . $k;
//再本地接去掉http使用本地绝对路径获取
if (strstr($v, $this->request->host(true)) !== false) {
$v = str_replace([
'https://' . $this->request->host(true) . '/',
'http://' . $this->request->host(true) . '/'
], public_path(), $v);
}
$canvas->setImageUrl($v)->setImageHeight(344)->setImageWidth(344)->setImageLeft(76)->setImageTop(120)->pushImageValue();
$image = $canvas->setFileName($name)->setImageType($imageType)->setPath($path)->setBackgroundWidth(500)->setBackgroundHeight(720)->starDrawChart();
$data[$k] = $image ? $siteUrl . '/' . $image : '';
} else {
$data[$k] = "";
}
}
} else {
$data = ['wechat' => $wechatQrcode, 'routine' => $routineQrcode];
}
return $this->success($data);
}
}

View File

@@ -0,0 +1,222 @@
<?php
namespace app\controller\admin\v1\order;
use app\controller\admin\AuthController;
use app\Request;
use app\services\order\StoreOrderRefundServices;
use app\services\order\StoreOrderServices;
use app\services\user\UserServices;
use think\annotation\Inject;
class RefundOrder extends AuthController
{
/**
* @var StoreOrderRefundServices
*/
#[Inject]
protected StoreOrderRefundServices $services;
/**
* 退款订单列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getRefundList()
{
$where = $this->request->getMore([
['order_id', ''],
['time', ''],
['apply_type', ''],
['refund_type', ''],
['refund_express', ''],
['refund_reason', '']
]);
if ($this->supplierId != 0) {
$where['supplier_id'] = $this->supplierId;
}
return $this->success($this->services->refundList($where));
}
/**
* 退款表单生成
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function refund($id)
{
if (!$id) {
return app('json')->fail('Data does not exist!');
}
return app('json')->success($this->services->refundOrderForm((int)$id));
}
/**
* 订单退款
* @param Request $request
* @param StoreOrderServices $services
* @param $id
* @return mixed
*/
public function update_refund(Request $request, StoreOrderServices $services, $id)
{
$data = $request->postMore([
['refund_price', 0],
['type', 1],
['refuse_reason', '']
]);
if (!$id) {
return app('json')->fail('Data does not exist!');
}
$data['refund_price'] = sprintf("%.2f", $data['refund_price']);
$orderRefund = $this->services->get($id);
if (!$orderRefund) {
return app('json')->fail('Data does not exist!');
}
if ($orderRefund['is_cancel'] == 1) {
return app('json')->fail('用户已取消申请');
}
$order = $services->get((int)$orderRefund['store_order_id']);
if (!$order) {
return app('json')->fail('Data does not exist!');
}
if (!in_array($orderRefund['refund_type'], [0, 1, 2, 5]) && !($orderRefund['refund_type'] == 4 && $orderRefund['apply_type'] == 3)) {
return app('json')->fail('售后订单状态不支持该操作');
}
if ($data['type'] == 1) {
$data['refund_type'] = 6;
} else if ($data['type'] == 2) {
$data['refund_type'] = 3;
}
$data['refunded_time'] = time();
$type = $data['type'];
//拒绝退款
if ($type == 2) {
$this->services->refuseRefund((int)$id, $data, $orderRefund);
return app('json')->successful('修改退款状态成功!');
} else {
//0元退款
if ($orderRefund['refund_price'] == 0) {
$refund_price = 0;
} else {
if (!$data['refund_price']) {
return app('json')->fail('请输入退款金额');
}
if ($orderRefund['refund_price'] == $orderRefund['refunded_price']) {
return app('json')->fail('已退完支付金额!不能再退款了');
}
$refund_price = $data['refund_price'];
$data['refunded_price'] = bcadd($data['refund_price'], $orderRefund['refunded_price'], 2);
$bj = bccomp((string)$orderRefund['refund_price'], (string)$data['refunded_price'], 2);
if ($bj < 0) {
return app('json')->fail('退款金额大于支付金额,请修改退款金额');
}
}
unset($data['type']);
$refund_data['pay_price'] = $order['pay_price'];
$refund_data['refund_price'] = $refund_price;
if ($order['refund_price'] > 0) {
mt_srand();
$refund_data['refund_id'] = $order['order_id'] . rand(100, 999);
}
//修改订单退款状态
unset($data['refund_price']);
$adminAccount = $this->adminInfo['account'] ?? '';
if ($this->services->agreeRefund($id, $refund_data, $adminAccount)) {
$this->services->update($id, $data);
return app('json')->success('退款成功');
}
// else {
// $this->services->storeProductOrderRefundYFasle((int)$id, $refund_price);
// return app('json')->fail('退款失败');
// }
}
}
/**
* 商家同意退货退款
* @return mixed
*/
public function agreeRefund()
{
[$order_id] = $this->request->getMore([
['order_id', '']
], true);
$this->services->agreeRefundProdcut((int)$order_id);
return app('json')->success('操作成功');
}
/**
* 修改备注
* @param $id
* @return mixed
*/
public function remark($id)
{
$data = $this->request->postMore([['remark', '']]);
if (!$data['remark'])
return app('json')->fail('请输入要备注的内容');
if (!$id)
return app('json')->fail('缺少参数');
if (!$order = $this->services->get($id)) {
return app('json')->fail('修改的订单不存在!');
}
$order->remark = $data['remark'];
if ($order->save()) {
return app('json')->success('备注成功');
} else
return app('json')->fail('备注失败');
}
/**
* 售后详情
* @param $id
* @return mixed
*/
public function refundDetail($id)
{
if (!$id) return app('json')->fail('缺少参数');
$orderInfo = $this->services->refundDetail($id);
$userInfo = ['spread_uid' => '', 'spread_name' => '无'];
if ($orderInfo['uid']) {
/** @var UserServices $services */
$services = app()->make(UserServices::class);
$userInfo = $services->getUserWithTrashedInfo($orderInfo['uid']);
if (!$userInfo) return app('json')->fail('用户信息不存在');
$userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
$userInfo = $userInfo->toArray();
$userInfo['spread_name'] = '无';
if ($orderInfo['spread_uid']) {
$spreadName = $services->value(['uid' => $orderInfo['spread_uid']], 'nickname');
if ($spreadName) {
$userInfo['spread_name'] = $orderInfo['uid'] == $orderInfo['spread_uid'] ? $spreadName . '(自购)' : $spreadName;
$userInfo['spread_uid'] = $orderInfo['spread_uid'];
} else {
$userInfo['spread_uid'] = '';
}
} else {
$userInfo['spread_uid'] = '';
}
}
return $this->success(compact('orderInfo', 'userInfo'));
}
/**
* 售后原因
* @return \think\Response
* User: liusl
* DateTime: 2024/9/7 14:18
*/
public function refund_reason()
{
$reason = sys_config('stor_reason') ?: [];//退款理由
$reason = str_replace("\r\n", "\n", $reason);//防止不兼容
$reason = explode("\n", $reason);
return app('json')->successful($reason);
}
}

View File

@@ -0,0 +1,120 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\order;
use app\controller\admin\AuthController;
use app\services\order\StoreDeliveryOrderServices;
use think\annotation\Inject;
/**
* 配送订单
* Class StoreDeliveryOrder
* @package app\admin\controller\store
*/
class StoreDeliveryOrder extends AuthController
{
/**
* @var StoreDeliveryOrderServices
*/
#[Inject]
protected StoreDeliveryOrderServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['keyword', ''],
['store_id',],
['status', ''],
['data', '', '', 'time'],
['station_type']
]);
if ($where['store_id']) {
$where['type'] = 1;
$where['relation_id'] = $where['store_id'];
unset($where['store_id']);
}
return $this->success($this->services->systemPage($where));
}
/**
* 详情
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function detail($id)
{
if (!$id) {
return app('json')->fail('缺少参数ID');
}
$data = $this->services->detail($id);
return app('json')->success($data);
}
/**
* 获取取消发单表单
* @param int $id 发单ID
* @return mixed
*/
public function cancelForm($id)
{
if (!$id) {
return app('json')->fail('缺少参数ID');
}
return app('json')->success($this->services->cancelForm($id));
}
/**
* 取消发单
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function cancel($id)
{
$reason = $this->request->getMore([
['reason', ''],
['cancel_reason', '']
]);
if (!$id) {
return app('json')->fail('缺少参数ID');
}
if (empty($reason['reason']))
return app('json')->fail('取消理由不能为空');
$this->services->cancel($id, $reason);
return app('json')->success('取消成功');
}
/**
* @param $id
* @return mixed
*/
public function delete($id)
{
if (!$id) {
return app('json')->fail('缺少参数ID');
}
$this->services->delete((int)$id);
return app('json')->success('删除成功');
}
}

View File

@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\order;
use app\common\controller\Order;
use app\controller\admin\AuthController;
use app\services\order\{
StoreOrderServices
};
use think\annotation\Inject;
/**
* 订单管理
* Class StoreOrder
* @package app\controller\admin\v1\order
*/
class StoreOrder extends AuthController
{
use Order;
/**
* @var StoreOrderServices
*/
#[Inject]
protected StoreOrderServices $services;
/**
* 易联云打印机打印
* @param $id
* @return mixed
*/
public function order_print($id)
{
if (!$id) return app('json')->fail('缺少参数');
$order = $this->services->get($id);
if (!$order) {
return app('json')->fail('订单没有查到,无法打印!');
}
$res = $this->services->orderPrint((int)$id, 0, 0);
if ($res) {
return app('json')->success('打印成功');
} else {
return app('json')->fail('打印失败');
}
}
}

View File

@@ -0,0 +1,149 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\order;
use app\controller\admin\AuthController;
use app\services\order\StoreOrderInvoiceServices;
use app\services\order\StoreOrderServices;
use app\services\product\category\StoreProductCategoryServices;
use app\services\product\product\StoreProductServices;
use app\services\store\SystemStoreServices;
use app\services\user\UserServices;
use think\annotation\Inject;
/**
* 发票管理
* Class StoreOrderInvoice
* @package app\controller\admin\v1\order
*/
class StoreOrderInvoice extends AuthController
{
/**
* @var StoreOrderInvoiceServices
*/
#[Inject]
protected StoreOrderInvoiceServices $services;
/**
* 获取订单类型数量
* @return mixed
*/
public function chart()
{
$where = $this->request->getMore([
['data', '', '', 'time'],
[['type', 'd'], 0],
]);
$data = $this->services->chart($where);
return $this->success($data);
}
/**
* 查询发票列表
* @return mixed
*/
public function list()
{
$where = $this->request->getMore([
['status', 0],
['real_name', ''],
['header_type', ''],
['type', ''],
['data', '', '', 'time'],
['field_key', ''],
]);
return $this->success($this->services->getList($where));
}
/**
* 设置发票状态
* @param string $id
* @return mixed
*/
public function set_invoice($id = '')
{
if ($id == '') return $this->fail('缺少参数');
$data = $this->request->postMore([
['is_invoice', 0],
['invoice_number', 0],
['invoice_amount', 0],
['remark', '']
]);
if ($data['is_invoice'] == 1 && !$data['invoice_number']) {
return $this->fail('请填写开票号');
}
if ($data['invoice_number'] && !preg_match('/^\d{8,20}$/', $data['invoice_number'])) {
return $this->fail('请填写正确的开票号');
}
$this->services->setInvoice((int)$id, $data);
return $this->success('设置成功');
}
/**
* 订单详情
* @param $id 订单id
* @return mixed
*/
public function orderInfo(StoreProductServices $productServices, StoreOrderServices $orderServices, $id)
{
if (!$id || !($orderInfo = $orderServices->get($id))) {
return $this->fail('订单不存在');
}
/** @var UserServices $services */
$services = app()->make(UserServices::class);
$userInfo = $services->get($orderInfo['uid']);
if (!$userInfo) {
return app('json')->fail('用户信息不存在');
}
$userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
$userInfo['spread_name'] = '';
if ($userInfo['spread_uid'])
$userInfo['spread_name'] = $services->value(['uid' => $userInfo['spread_uid']], 'nickname');
$orderInfo = $orderServices->tidyOrder($orderInfo->toArray(), true, true);
//核算优惠金额
$vipTruePrice = 0;
foreach ($orderInfo['cartInfo'] ?? [] as $cart) {
$vipTruePrice = bcadd((string)$vipTruePrice, (string)$cart['vip_sum_truePrice'], 2);
}
$orderInfo['vip_true_price'] = $vipTruePrice;
$orderInfo['add_time'] = $orderInfo['_add_time'] ?? '';
$cateIds = [];
foreach ($orderInfo['cartInfo'] as &$item) {
$cateIds = array_merge($cateIds, explode(',', $item['productInfo']['cate_id'] ?? ''));
}
$cateIds = implode(',', array_unique($cateIds));
/** @var StoreProductCategoryServices $categoryService */
$categoryService = app()->make(StoreProductCategoryServices::class);
$cateList = $categoryService->getCateParentAndChildName($cateIds);
foreach ($orderInfo['cartInfo'] as &$item) {
$item['class_name'] = '';
if (isset($item['productInfo']['cate_id']) && $item['productInfo']['cate_id']) {
$cate_name = $categoryService->getCateName(explode(',', $item['productInfo']['cate_id']), $cateList);
if ($cate_name) {
$item['class_name'] = is_array($cate_name) ? implode(',', $cate_name) : '';
}
}
}
if ($orderInfo['store_id'] && $orderInfo['shipping_type'] == 2) {
/** @var $storeServices */
$storeServices = app()->make(SystemStoreServices::class);
$orderInfo['_store_name'] = $storeServices->value(['id' => $orderInfo['store_id']], 'name');
} else {
$orderInfo['_store_name'] = '';
}
$userInfo = $userInfo->toArray();
$invoice = $this->services->getOne(['order_id' => $id]);
return app('json')->success(compact('orderInfo', 'userInfo', 'invoice'));
}
}

View File

@@ -0,0 +1,138 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\other;
use app\controller\admin\AuthController;
use app\services\other\CityAreaServices;
use think\annotation\Inject;
use crmeb\services\CacheService;
/**
* 城市数据
* Class CityArea
* @package app\controller\admin\v1\setting
*/
class CityArea extends AuthController
{
/**
* @var CityAreaServices
*/
#[Inject]
protected CityAreaServices $services;
/**
* 城市列表
* @return string
* @throws \Exception
*/
public function index()
{
[$parent_id] = $this->request->getMore([
[['parent_id', 'd'], 0]
], true);
return $this->success($this->services->getCityTreeList((int)$parent_id));
}
/**
* 添加城市
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function add()
{
[$parentId] = $this->request->getMore([
[['parent_id', 'd'], 0]
], true);
return $this->success($this->services->createCityForm((int)$parentId));
}
/**
* 保存
*/
public function save()
{
$data = $this->request->postMore([
[['id', 'd'], 0],
[['name', 's'], ''],
[['level', 'd'], 0],
[['parent_id', 'd'], 0],
]);
if ($data['id'] == 0) {
if ($data['parent_id']) {
$parent = $this->services->get($data['parent_id']);
if ($parent) {
$data['path'] = $parent['path'] . $parent['id'] .'/';
}
} else {
$data['path'] = '/';
}
unset($data['id']);
$data['level'] = $data['level'] + 1;
$data['type'] = $this->services->type[$data['level']] ?? '';
$data['create_time'] = date('Y-m-d H:i:s');
$this->services->save($data);
$this->services->bcInc($data['parent_id'], 'snum', 1);
return $this->success('添加城市成功!');
} else {
unset($data['level']);
unset($data['parent_id']);
$this->services->update($data['id'], $data);
return $this->success('修改城市成功!');
}
}
/**
* 修改城市
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit()
{
[$id] = $this->request->getMore([
[['id', 'd'], 0]
], true);
return $this->success($this->services->updateCityForm((int)$id));
}
/**
* 删除城市
* @throws \Exception
*/
public function delete()
{
[$id] = $this->request->getMore([
[['city_id', 'd'], 0]
], true);
$city = $this->services->get((int)$id);
if ($city) {
$this->services->deleteCity($id);
if ($city['parent_id']) $this->services->bcDec($city['parent_id'], 'snum', 1);
}
return $this->success('删除成功!');
}
/**
* 清除城市缓存
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function clean_cache()
{
CacheService::delete('CITY_LIST');
return $this->success('清除成功!');
}
}

View File

@@ -0,0 +1,164 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\other;
use app\controller\admin\AuthController;
use app\services\other\ExpressServices;
use think\annotation\Inject;
/**
* 物流
* Class Express
* @package app\controller\admin\v1\freight
*/
class Express extends AuthController
{
/**
* @var ExpressServices
*/
#[Inject]
protected ExpressServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['keyword', '']
]);
return $this->success($this->services->getExpressList($where));
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
return $this->success($this->services->createForm());
}
/**
* 保存新建的资源
*
* @return \think\Response
*/
public function save()
{
$data = $this->request->postMore([
'name',
'code',
['sort', 0],
['is_show', 0]]);
if (!$data['name']) return $this->fail('请输入公司名称');
$this->services->save($data);
return $this->success('添加公司成功!');
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
//
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
return $this->success($this->services->updateForm((int)$id));
}
/**
* 保存更新的资源
*
* @param int $id
* @return \think\Response
*/
public function update($id)
{
$data = $this->request->postMore([
['account', ''],
['key', ''],
['net_name', ''],
['sort', 0],
['is_show', 0]]);
if (!$expressInfo = $this->services->get($id)) return $this->fail('编辑的记录不存在!');
if ($expressInfo['partner_id'] == 1 && !$data['account']) {
return $this->fail('请输入月结账号');
}
if ($expressInfo['partner_key'] == 1 && !$data['key']) {
return $this->fail('请输入月结密码');
}
if ($expressInfo['net'] == 1 && !$data['net_name']) {
return $this->fail('请输入取件网点');
}
$expressInfo->account = $data['account'];
$expressInfo->key = $data['key'];
$expressInfo->net_name = $data['net_name'];
$expressInfo->sort = $data['sort'];
$expressInfo->is_show = $data['is_show'];
$expressInfo->status = 1;
$expressInfo->save();
return $this->success('修改成功!');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id) return $this->fail('参数错误,请重新打开');
$res = $this->services->delete($id);
if (!$res)
return $this->fail('删除失败,请稍候再试!');
else
return $this->success('删除成功!');
}
/**
* 修改状态
* @param int $id
* @param string $status
* @return mixed
*/
public function set_status($id = 0, $status = '')
{
if ($status == '' || $id == 0) return $this->fail('参数错误');
$this->services->update($id, ['is_show' => $status]);
return $this->success($status == 0 ? '隐藏成功' : '显示成功');
}
/**
* 同步平台快递公司
* @return mixed
*/
public function syncExpress()
{
$this->services->syncExpress();
return $this->success('同步成功');
}
}

View File

@@ -0,0 +1,135 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\other;
use app\controller\admin\AuthController;
use app\services\other\SystemCityServices;
use think\annotation\Inject;
use crmeb\services\CacheService;
/**
* 城市数据
* Class SystemCity
* @package app\controller\admin\v1\setting
*/
class SystemCity extends AuthController
{
/**
* @var SystemCityServices
*/
#[Inject]
protected SystemCityServices $services;
/**
* 城市列表
* @return string
* @throws \Exception
*/
public function index()
{
$where = $this->request->getMore([
[['parent_id', 'd'], 0]
]);
return $this->success($this->services->getCityList($where));
}
/**
* 添加城市
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function add()
{
[$parentId] = $this->request->getMore([
[['parent_id', 'd'], 0]
], true);
return $this->success($this->services->createCityForm($parentId));
}
/**
* 保存
*/
public function save()
{
$data = $this->request->postMore([
[['id', 'd'], 0],
[['name', 's'], ''],
[['merger_name', 's'], ''],
[['area_code', 's'], ''],
[['lng', 's'], ''],
[['lat', 's'], ''],
[['level', 'd'], 0],
[['parent_id', 'd'], 0],
]);
$this->validate($data, \app\validate\admin\setting\SystemCityValidate::class, 'save');
if ($data['parent_id'] == 0) {
$data['merger_name'] = $data['name'];
} else {
$data['merger_name'] = $this->services->value(['id' => $data['parent_id']], 'name') . ',' . $data['name'];
}
CacheService::delete($this->services->tree_city_key);
if ($data['id'] == 0) {
unset($data['id']);
$data['level'] = $data['level'] + 1;
$data['city_id'] = intval($this->services->getCityIdMax() + 1);
$this->services->save($data);
return $this->success('添加城市成功!');
} else {
unset($data['level']);
unset($data['parent_id']);
$this->services->update($data['id'], $data);
return $this->success('修改城市成功!');
}
}
/**
* 修改城市
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit()
{
[$id] = $this->request->getMore([
[['id', 'd'], 0]
], true);
return $this->success($this->services->updateCityForm($id));
}
/**
* 删除城市
* @throws \Exception
*/
public function delete()
{
[$id] = $this->request->getMore([
[['city_id', 'd'], 0]
], true);
$this->services->deleteCity($id);
CacheService::delete($this->services->tree_city_key);
return $this->success('删除成功!');
}
/**
* 清除城市缓存
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function clean_cache()
{
CacheService::delete($this->services->tree_city_key);
CacheService::delete('CITY_LIST');
return $this->success('清除成功!');
}
}

View File

@@ -0,0 +1,745 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\other\export;
use app\controller\admin\AuthController;
use app\services\activity\card\CardCodeServices;
use app\services\activity\integral\StoreIntegralOrderServices;
use app\services\activity\bargain\StoreBargainServices;
use app\services\activity\combination\StoreCombinationServices;
use app\services\activity\combination\StorePinkServices;
use app\services\activity\seckill\StoreSeckillServices;
use app\services\agent\AgentManageServices;
use app\services\agent\DivisionServices;
use app\services\order\StoreOrderInvoiceServices;
use app\services\other\export\ExportServices;
use app\services\order\StoreOrderServices;
use app\services\other\Import\ImportRecordErrorServices;
use app\services\other\queue\QueueAuxiliaryServices;
use app\services\other\queue\QueueServices;
use app\services\product\product\StoreProductServices;
use app\services\other\ExpressServices;
use app\services\product\stock\StockInventoryServices;
use app\services\product\stock\StockRecordServices;
use app\services\store\SystemStoreServices;
use app\services\supplier\finance\SupplierFlowingWaterServices;
use app\services\system\form\SystemFormDataServices;
use app\services\user\member\MemberCardServices;
use app\services\user\UserBillServices;
use app\services\user\UserBrokerageServices;
use app\services\user\UserMoneyServices;
use app\services\user\UserRechargeServices;
use app\services\user\UserServices;
use app\services\wechat\WechatUserServices;
use think\annotation\Inject;
use think\facade\App;
/**
* 导出excel类
* Class ExportExcel
* @package app\controller\admin\v1\export
*/
class ExportExcel extends AuthController
{
/**
* @var ExportServices
*/
#[Inject]
protected ExportServices $service;
/**
* 用户列表导出
* @param UserServices $services
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author wuhaotian
* @email 442384644@qq.com
* @date 2025/3/11
*/
public function user(UserServices $services)
{
$where = $this->request->getMore([
['page', 1],
['limit', 1000],
['nickname', ''],
['status', ''],
['pay_count', ''],
['is_promoter', ''],
['order', ''],
['data', ''],
['user_type', ''],
['country', ''],
['province', ''],
['city', ''],
['user_time_type', ''],
['user_time', ''],
['sex', ''],
[['level', 0], 0],
[['group_id', 'd'], 0],
[['label_id', 'd'], 0],
['now_money', 'normal'],
['field_key', ''],
['isMember', ''],
['label_ids', ''],
['ids', '', '', 'uid'],
]);
if ($where['label_ids']) {
$where['label_id'] = stringToIntArray($where['label_ids']);
unset($where['label_ids']);
}
$where['user_time_type'] = $where['user_time_type'] == 'all' ? '' : $where['user_time_type'];
if ($where['uid'] !== '') {
$where['uid'] = stringToIntArray($where['uid']);
} else {
unset($where['uid']);
}
$data = $services->index($where);
return $this->success($this->service->user($data['list'] ?? []));
}
/**
* 保存用户资金监控的excel表格
* @param UserMoneyServices $services
* @return mixed
*/
public function userFinance(UserMoneyServices $services)
{
$where = $this->request->getMore([
['start_time', ''],
['end_time', ''],
['nickname', ''],
['type', ''],
]);
$data = $services->getMoneyList($where, '*', $this->service->limit);
return $this->success($this->service->userFinance($data['data'] ?? []));
}
/**
* 用户佣金
* @param UserBrokerageServices $services
* @return mixed
*/
public function userCommission(UserBrokerageServices $services)
{
$where = $this->request->getMore([
['page', 1],
['limit', 20],
['nickname', ''],
['price_max', ''],
['price_min', ''],
['excel', '1'],
['date', '', '', 'time']
]);
$data = $services->getCommissionList($where, $this->service->limit);
return $this->success($this->service->userCommission($data['list'] ?? []));
}
/**
* 用户积分
* @param UserBillServices $services
* @return mixed
*/
public function userPoint(UserBillServices $services)
{
$where = $this->request->getMore([
['start_time', ''],
['end_time', ''],
['nickname', ''],
['excel', '1'],
]);
$data = $services->getPointList($where, '*', $this->service->limit);
return $this->success($this->service->userPoint($data['list'] ?? []));
}
/**
* 用户充值
* @param UserRechargeServices $services
* @return mixed
*/
public function userRecharge(UserRechargeServices $services)
{
$where = $this->request->getMore([
['data', ''],
['paid', ''],
['page', 1],
['limit', 20],
['nickname', ''],
['excel', '1'],
]);
$data = $services->getRechargeList($where, '*', $this->service->limit);
return $this->success($this->service->userRecharge($data['list'] ?? []));
}
/**
* 分销管理 用户推广
* @param AgentManageServices $services
* @return mixed
*/
public function userAgent(AgentManageServices $services)
{
$where = $this->request->getMore([
['nickname', ''],
['data', ''],
['excel', '1'],
]);
$data = $services->agentSystemPage($where, $this->service->limit);
return $this->success($this->service->userAgent($data['list']));
}
/**
* 微信用户导出
* @param WechatUserServices $services
* @return mixed
*/
public function wechatUser(WechatUserServices $services)
{
$where = $this->request->getMore([
['page', 1],
['limit', 20],
['nickname', ''],
['data', ''],
['tagid_list', ''],
['groupid', '-1'],
['sex', ''],
['export', '1'],
['subscribe', '']
]);
$tagidList = explode(',', $where['tagid_list']);
foreach ($tagidList as $k => $v) {
if (!$v) {
unset($tagidList[$k]);
}
}
$tagidList = array_unique($tagidList);
$where['tagid_list'] = implode(',', $tagidList);
$data = $services->exportData($where);
return $this->success($this->service->wechatUser($data));
}
/**
* 商铺砍价活动导出
* @param StoreBargainServices $services
* @return mixed
*/
public function storeBargain(StoreBargainServices $services)
{
$where = $this->request->getMore([
['start_status', ''],
['status', ''],
['store_name', ''],
['page', 0]
]);
$where['is_del'] = 0;
$page = $where['page'];
unset($where['page']);
$data = $services->getList($where, $page, $this->service->limit);
return $this->success($this->service->storeBargain($data));
}
/**
* 商铺拼团导出
* @param StoreCombinationServices $services
* @return mixed
*/
public function storeCombination(StoreCombinationServices $services)
{
$where = $this->request->getMore([
['start_status', ''],
['is_show', ''],
['store_name', ''],
['page', 0]
]);
$where['is_del'] = 0;
$page = $where['page'];
unset($where['page']);
$data = $services->getList($where, $page, $this->service->limit);
/** @var StorePinkServices $storePinkServices */
$storePinkServices = app()->make(StorePinkServices::class);
$countAll = $storePinkServices->getPinkCount([]);
$countTeam = $storePinkServices->getPinkCount(['k_id' => 0, 'status' => 2]);
$countPeople = $storePinkServices->getPinkCount(['k_id' => 0]);
foreach ($data as &$item) {
$item['count_people'] = $countPeople[$item['id']] ?? 0;//拼团数量
$item['count_people_all'] = $countAll[$item['id']] ?? 0;//参与人数
$item['count_people_pink'] = $countTeam[$item['id']] ?? 0;//成团数量
}
return $this->success($this->service->storeCombination($data));
}
/**
* 商铺秒杀导出
* @param StoreSeckillServices $services
* @return mixed
*/
public function storeSeckill(StoreSeckillServices $services)
{
$where = $this->request->getMore([
['start_status', ''],
['status', ''],
['store_name', ''],
['page', 0]
]);
$where['is_del'] = 0;
$page = $where['page'];
unset($where['page']);
$data = $services->getList($where, $page, $this->service->limit);
return $this->success($this->service->storeSeckill($data));
}
/**
* 导出商品卡号、卡密模版
* @return mixed
*/
public function storeProductCardTemplate()
{
return $this->success($this->service->storeProductCardTemplate());
}
/**
* 商铺产品导出
* @param StoreProductServices $services
* @return mixed
*/
public function storeProduct(StoreProductServices $services)
{
$where = $this->request->getMore([
['store_name', ''],
['cate_id', ''],
['type', '', '', 'status'],
['store_id', ''],
['supplier_id', ''],
['sales', 'normal'],
['store_label_id', ''],
['brand_id', ''],
['ids', ''],
['all', 0]
]);
if (!$where['ids'] && $where['all'] == 0) return $this->fail('请选择批处理商品');
if ($where['supplier_id']) {
$where['relation_id'] = $where['supplier_id'];
$where['type'] = 2;
} else {
$where['pid'] = 0;
}
$where['ids'] = stringToIntArray($where['ids']);
unset($where['supplier_id'], $where['store_id'], $where['all']);
$data = $services->searchList($where, true, $this->service->limit);
return $this->success($this->service->storeProduct($data['list'] ?? []));
}
/**
* 订单列表导出
* @param StoreOrderServices $services
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function storeOrder(StoreOrderServices $services)
{
$where_tmp = $this->request->getMore([
['status', ''],
['real_name', ''],
['is_del', ''],
['data', '', '', 'time'],
['type', ''],
['export_type', ''],
['pay_type', ''],
['plat_type', -1],
['order', ''],
['field_key', ''],
['store_id', ''],
['supplier_id', ''],
['ids', '']
]);
$type = $where_tmp['export_type'];
unset($where_tmp['export_type']);
$with = [];
if ($where_tmp['ids']) {
$where['id'] = stringToIntArray($where_tmp['ids']);
} else {
$where['pid'] = 0;
}
if ($type) {
$where['status'] = 1;
$where['paid'] = 1;
$where['is_del'] = 0;
$where['shipping_type'] = 1;
$where['is_system_del'] = 0;
$with = ['pink', 'refund' => function ($query) {
$query->whereIn('refund_type', [0, 1, 2, 4, 5])->where('is_cancel', 0)->where('is_del', 0)->field('id,store_order_id');
}];
}
if (!$where_tmp['ids'] && !$type) {
unset($where_tmp['ids']);
$where = $where_tmp;
}
$where['is_system_del'] = 0;
$where['plat_type'] = $where_tmp['plat_type'];
$where['store_id'] = $where_tmp['store_id'];
if ($this->supplierId) {
$where['supplier_id'] = $this->supplierId;
} else {
$where['supplier_id'] = $where_tmp['supplier_id'];
}
$data = $services->getExportList($where, $with, $this->service->limit);
return $this->success($this->service->storeOrder($data, $type));
}
/**
* 获取提货点
* @return mixed
*/
public function storeMerchant(SystemStoreServices $services)
{
$where = $this->request->getMore([
[['keywords', 's'], ''],
[['type', 'd'], 0],
]);
$data = $services->getExportData($where);
return $this->success($this->service->storeMerchant($data));
}
/**
* 会员卡导出
* @param int $id
* @param MemberCardServices $services
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function memberCard(int $id, MemberCardServices $services)
{
$data = $services->getExportData(['batch_card_id' => $id], $this->service->limit);
return $this->success($this->service->memberCard($data));
}
/**
* 导出批量任务发货的记录
* @param int $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function batchOrderDelivery($id, $queueType, $cacheType)
{
/** @var QueueAuxiliaryServices $auxiliaryService */
$auxiliaryService = app()->make(QueueAuxiliaryServices::class);
/** @var QueueServices $queueService */
$queueService = app()->make(QueueServices::class);
$queueInfo = $queueService->getQueueOne(['id' => $id]);
if (!$queueInfo) $this->fail("数据不存在");
$queueValue = json_decode($queueInfo['queue_in_value'], true);
if (!$queueValue || !isset($queueValue['cacheType'])) $this->fail("数据参数缺失");
$data = $auxiliaryService->getExportData(['binding_id' => $id, 'type' => $cacheType], $this->service->limit);
return $this->success($this->service->batchOrderDelivery($data, $queueType));
}
/**
* 物流公司表导出
* @return mixed
*/
public function expressList()
{
/** @var ExpressServices $expressService */
$expressService = app()->make(ExpressServices::class);
$data = $expressService->apiExpressList();
return $this->success($this->service->expressList($data));
}
/**
* 导出积分兑换订单
* @param StoreIntegralOrderServices $services
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function storeIntegralOrder(StoreIntegralOrderServices $services)
{
$where = $this->request->getMore([
['status', ''],
['real_name', ''],
['data', '', '', 'time'],
['order', ''],
['field_key', ''],
['product_id', '']
]);
$where['is_system_del'] = 0;
$data = $services->getExportList($where, $this->service->limit);
return $this->success($this->service->storeIntegralOrder($data));
}
/**
* 供应商资金流水导出
* @param SupplierFlowingWaterServices $services
* @return mixed
*/
public function waterExport(SupplierFlowingWaterServices $services)
{
$where = $this->request->getMore([
['supplier_id', 0],
['keyword', ''],
['data', '', '', 'time'],
]);
$where['is_del'] = 0;
$data = $services->getList($where);
return $this->success($this->service->SupplierFinanceRecord($data['list'] ?? [], '供应商资金流水导出'));
}
/**
* 供应商账单下载
* @param SupplierFlowingWaterServices $services
* @return mixed
*/
public function waterRecord(SupplierFlowingWaterServices $services)
{
[$ids] = $this->request->getMore([
['ids', ''],
['supplier_id', 0]
], true);
$where['id'] = stringToIntArray($ids);
$where['is_del'] = 0;
$data = $services->getList($where);
return $this->success($this->service->SupplierFinanceRecord($data['list'] ?? []));
}
/**
* 发票导出
* @param StoreOrderInvoiceServices $services
* @return mixed
*/
public function invoiceExport(StoreOrderInvoiceServices $services)
{
$where = $this->request->getMore([
['status', 0],
['real_name', ''],
['header_type', ''],
['type', ''],
['data', '', '', 'time'],
['field_key', ''],
]);
$data = $services->getList($where);
return $this->success($this->service->invoiceRecord($data['list'] ?? []));
}
/**
* 系统表单收集数据导出
* @param SystemFormDataServices $systemFormDataServices
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException'
*/
public function systemFormDataExport(SystemFormDataServices $systemFormDataServices, $id)
{
$where = $this->request->postMore([
['data', '', '', 'time']
]);
$data = $systemFormDataServices->getFormDataList((int)$id, $where);
return $this->success($this->service->systemFormData($data['list'] ?? []));
}
public function divisionOrderExport()
{
$where = $this->request->getMore([
['time', '',],
['field_key', ''],
['real_name', ''],
['division_id', ''],
['division_agent_id', ''],
]);
$adminInfo = $this->request->adminInfo();
$data = app()->make(DivisionServices::class)->divisionOrder($adminInfo, $where)['data'];
$divisionIds = array_unique(array_column($data, 'division_id'));
$agentIds = array_unique(array_column($data, 'division_agent_id'));
$staffIds = array_unique(array_column($data, 'division_staff_id'));
$userServices = app()->make(UserServices::class);
$divisionInfos = array_column($userServices->getUserInfoList(['uids' => $divisionIds], 'uid,division_name'), 'division_name', 'uid');
$agentInfos = array_column($userServices->getUserInfoList(['uids' => $agentIds], 'uid,division_name'), 'division_name', 'uid');
$staffInfos = array_column($userServices->getUserInfoList(['uids' => $staffIds], 'uid,nickname'), 'nickname', 'uid');
foreach ($data as &$item) {
$item['division_name'] = $divisionInfos[$item['division_id']] ?? '';
$item['division_agent_name'] = $agentInfos[$item['division_agent_id']] ?? '';
$item['division_staff_name'] = $staffInfos[$item['division_staff_id']] ?? '';
}
return $this->success($this->service->divisionOrder($data, 1));
}
/**
* 导入用户错误记录导出
* @return \think\Response
* @throws \ReflectionException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* User: liusl
* DateTime: 2024/12/19 下午5:34
*/
public function importUserExport()
{
$where = $this->request->getMore([
['record_id', '',],
]);
if (!$where['record_id']) {
return $this->fail('参数错误');
}
$data = app()->make(ImportRecordErrorServices::class)->getErrorList($where);
return $this->success($this->service->importUser($data['list'] ?? []));
}
/**
* 商品迁移数据导出
* @param StoreProductServices $services
* @return \think\Response
* User: liusl
* DateTime: 2025/1/6 下午5:10
*/
public function storeProductImport(StoreProductServices $services)
{
$where = $this->request->getMore([
['store_name', ''],
['cate_id', ''],
['type', '', '', 'status'],
['store_id', ''],
['supplier_id', ''],
['sales', 'normal'],
['store_label_id', ''],
['brand_id', ''],
['ids', ''],
['all', 0]
]);
if (!$where['ids'] && $where['all'] == 0) return $this->fail('请选择批处理商品');
if ($where['supplier_id']) {
$where['relation_id'] = $where['supplier_id'];
$where['type'] = 2;
} else {
$where['pid'] = 0;
}
$where['ids'] = stringToIntArray($where['ids']);
unset($where['supplier_id'], $where['store_id'], $where['all']);
$data = $services->searchList($where, true, $this->service->limit);
return $this->success($this->service->storeProductImport($data['list'] ?? []));
}
/**
* 礼品卡导出
* @param CardCodeServices $services
* @return \think\Response
* User: liusl
* DateTime: 2025/5/28 16:21
*/
public function cardCodeExport(CardCodeServices $services)
{
$where = $this->request->getMore([
['field_key', ''],//卡号card_number,用户名nickname,uid
['keyword', ''],//关键字
['card_id', ''],//礼品卡 id
['batch_id', ''],//批次id
['status', ''],//状态: 0-未使用 1-已使用 2-已过期
['active_time', ''],//active_time
]);
$data = $services->getList($where);
return $this->success($this->service->cardCodeExport($data['list'] ?? []));
}
/**
* 出入库导出
* @param StockRecordServices $services
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* User: liusl
* DateTime: 2025/10/10 18:33
*/
public function stockExport(StockRecordServices $services)
{
$where = $this->request->getMore([
['record_no', ''],//单据编号
['type', ''],//类型: 1-入库 2-出库
['stock_type', ''],//类型
['record_date', ''],//出库时间
['create_time', ''],//创建时间
['ids', ''],
['all', 0]
]);
if (!$where['ids'] && $where['all'] == 0) return $this->fail('请选择批处理');
$where['id'] = stringToIntArray($where['ids']);
$data = $services->getStockRecordList($where, ['items'], $this->service->limit);
return $this->success($this->service->stockExport($data['list'] ?? [], 1, $where['type']));
}
/**
* 出入库明细导出
* @param StockRecordServices $services
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* User: liusl
* DateTime: 2025/10/10 18:36
*/
public function stockDetailsExport(StockRecordServices $services)
{
$where = $this->request->getMore([
['record_no', ''],//单据编号
['stock_type', ''],//类型
['create_time', ''],//创建时间
['unique', ''],
['type', ''],//类型: 1-入库 2-出库
['record_date', ''],//创建时间
]);
$data = $services->getStockDetailsList($where,$this->service->limit);
return $this->success($this->service->stockDetailsExport($data));
}
/**
* 盘点导出
* @param StockInventoryServices $services
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* User: liusl
* DateTime: 2025/10/10 18:34
*/
public function inventoryExport(StockInventoryServices $services)
{
$where = $this->request->getMore([
['record_no', ''],
['create_time', ''],
['status', ''],
['ids', ''],
['all', 0]
]);
if (!$where['ids'] && $where['all'] == 0) return $this->fail('请选择批处理');
$where['id'] = stringToIntArray($where['ids']);
$data = $services->getStockRecordList($where, ['items'], $this->service->limit);
return $this->success($this->service->inventoryExport($data['list'] ?? []));
}
}

View File

@@ -0,0 +1,115 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\other\queue;
use app\controller\admin\AuthController;
use app\services\other\queue\QueueAuxiliaryServices;
use app\services\other\queue\QueueServices;
use think\annotation\Inject;
/**
* Class Queue
* @package app\controller\admin\v1\queue
*/
class Queue extends AuthController
{
/**
* @var QueueServices
*/
#[Inject]
protected QueueServices $services;
/**
* 队列任务列表
* @return mixed
*/
public function index()
{
$where = $this->request->getMore([
['data', '', '', 'time'],
['type', [6, 7, 8, 9, 10]],
['status', [0, 1, 2, 3]],
['page', 1],
['limit', 20],
]);
$data = $this->services->getList($where);
return $this->success($data);
}
/**
* 批量发货记录
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function delivery_log($id, $type)
{
/** @var QueueAuxiliaryServices $auxiliaryService */
$auxiliaryService = app()->make(QueueAuxiliaryServices::class);
$data = $auxiliaryService->deliveryLogList(['binding_id' => $id, 'type' => $type]);
return $this->success($data);
}
/**
* 再次执行批量任务
* @param $id
* @param $type
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function again_do_queue($id, $type)
{
if (!$id || !$type) return $this->fail("参数缺失");
$this->services->againDoQueue($id, $type);
return $this->success("后台程序已再次执行此批量任务");
}
/**
* 清除异常任务
* @param $id
* @param $type
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function del_wrong_queue($id, $type)
{
if (!$id || !$type) return $this->fail("参数缺失");
$res = $this->services->delWrongQueue($id, $type);
return $this->success($res ? "异常任务清除成功" : "数据无异常");
}
/**
* 任务停止
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function stop_wrong_queue($id)
{
if (!$id) return $this->fail("参数缺失");
$queueInfo = $this->services->getQueueOne(['id' => $id]);
if (!$queueInfo) $this->fail('任务不存在');
$this->services->delWrongQueue($id, $queueInfo['type'], false);
return $this->success("任务停止成功");
}
}

View File

@@ -0,0 +1,266 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\out;
use app\controller\admin\AuthController;
use app\services\out\OutAccountServices;
use app\services\out\OutInterfaceServices;
use think\annotation\Inject;
/**
* 对外接口账户
* Class SystemCity
* @package app\controller\admin\v1\setting
*/
class SystemOut extends AuthController
{
/**
* @var OutAccountServices
*/
#[Inject]
protected OutAccountServices $services;
/**
* 账号信息
* @return string
* @throws \Exception
*/
public function index()
{
$where = $this->request->getMore([
['name', '', ''],
['status', ''],
]);
return $this->success($this->services->getList($where));
}
/**
* 修改状态
* @param string $status
* @param string $id
* @return mixed
*/
public function set_status($id = '', $status = '')
{
if ($status == '' || $id == '') return $this->fail('缺少参数');
$this->services->update($id, ['status' => $status]);
return $this->success($status == 1 ? '开启成功' : '禁用成功');
}
/**
* 删除
* @param $id
* @return mixed
*/
public function delete($id)
{
if ($id == '') return $this->fail('缺少参数');
$this->services->update($id, ['is_del' => 1]);
return $this->success('删除成功!');
}
/**
* 获取对外接口账号详情
* @param int $id 账号ID
* @return mixed
*/
public function info($id)
{
return $this->success($this->services->getOne(['id' => $id]));
}
/**
* 添加保存
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
[['appid', 's'], ''],
[['appsecret', 's'], ''],
[['title', 's'], ''],
['rules', []],
]);
if (!$data['appid']) {
return $this->fail('参数错误');
}
if ($this->services->getOne(['appid' => $data['appid'], 'is_del' => 0])) return $this->fail('账号重复');
if (!$data['appsecret']) {
unset($data['appsecret']);
} else {
$data['apppwd'] = $data['appsecret'];
$data['appsecret'] = password_hash($data['appsecret'], PASSWORD_DEFAULT);
}
$data['rules'] = json_encode($data['rules']);
$data['add_time'] = time();
if (!$this->services->save($data)) {
return $this->fail('添加失败');
} else {
return $this->success('添加成功');
}
}
/**
* 修改保存
* @param string $id
* @return mixed
*/
public function update($id = '')
{
$data = $this->request->postMore([
[['appid', 's'], ''],
[['appsecret', 's'], ''],
[['title', 's'], ''],
['rules', []],
]);
if (!$data['appid']) {
return $this->fail('参数错误');
}
if (!$data['appsecret']) {
unset($data['appsecret']);
} else {
$data['apppwd'] = $data['appsecret'];
$data['appsecret'] = password_hash($data['appsecret'], PASSWORD_DEFAULT);
}
if (!$this->services->getOne(['id' => $id])) return $this->fail('没有此账号');
$data['rules'] = json_encode($data['rules']);
$res = $this->services->update($id, $data);
if (!$res) {
return $this->fail('修改失败');
} else {
return $this->success('修改成功!');
}
}
/**
* 对外接口权限
* @param OutInterfaceServices $service
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function outInterfaceList(OutInterfaceServices $service)
{
return $this->success($service->outInterfaceList());
}
/**
* 设置推送接口
* @param $id
* @return mixed
*/
public function outSetUpSave($id)
{
$data = $this->request->postMore([
['push_open', 0],
['push_account', ''],
['push_password', ''],
['push_token_url', ''],
['user_update_push', ''],
['order_create_push', ''],
['order_pay_push', ''],
['refund_create_push', ''],
['refund_cancel_push', ''],
]);
$this->services->outSetUpSave($id, $data);
return $this->success('设置成功');
}
/**
* 测试获取token接口
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function textOutUrl()
{
$data = $this->request->postMore([
['push_account', 0],
['push_password', 0],
['push_token_url', '']
]);
return $this->success('测试成功',$this->services->textOutUrl($data));
}
/**
* 对外接口文档
* @param $id
* @param OutInterfaceServices $service
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function interfaceInfo($id, OutInterfaceServices $service)
{
return app('json')->success($service->interfaceInfo($id));
}
/**
* 保存接口文档
* @param $id
* @param OutInterfaceServices $service
* @return mixed
*/
public function saveInterface($id, OutInterfaceServices $service)
{
$data = $this->request->postMore([
['pid', 0], //上级id
['type', 0], //类型 0菜单 1接口
['name', ''], //名称
['describe', ''], //说明
['method', ''], //方法
['url', ''], //链接地址
['request_params', []], //请求参数
['return_params', []], //返回参数
['request_example', ''], //请求示例
['return_example', ''], //返回示例
['error_code', []] //错误码
]);
$service->saveInterface((int)$id, $data);
return app('json')->success('保存成功');
}
/**
* 修改接口名称
* @param OutInterfaceServices $service
* @return mixed
*/
public function editInterfaceName(OutInterfaceServices $service)
{
$data = $this->request->postMore([
['id', 0], //上级id
['name', ''], //名称
]);
if (!$data['id'] || !$data['name']) {
return app('json')->success('参数错误');
}
$service->editInterfaceName($data);
return app('json')->success('修改成功');
}
/**
* 删除接口
* @param $id
* @param OutInterfaceServices $service
* @return mixed
*/
public function delInterface($id, OutInterfaceServices $service)
{
if (!$id) return app('json')->success('参数错误');
$service->delInterface($id);
return app('json')->success('删除成功');
}
}

View File

@@ -0,0 +1,110 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product;
use app\controller\admin\AuthController;
use app\services\product\product\CopyTaobaoServices;
use app\services\serve\ServeServices;
use think\annotation\Inject;
/**
* Class CopyTaobao
* @package app\controller\admin\v1\product
*/
class CopyTaobao extends AuthController
{
/**
* @var CopyTaobaoServices
*/
#[Inject]
protected CopyTaobaoServices $services;
/**
* 获取复制商品配置信息
* @return mixed
*/
public function getConfig()
{
$data = [];
$copy = sys_config('system_product_copy_type', 1);
$data['copy_type'] = $copy;
$data['copy_num'] = 0;
if ($copy == 1) {//一号通
/** @var ServeServices $serverServices */
$serverServices = app()->make(ServeServices::class);
try {
$info = $serverServices->user()->getUser();
} catch (\Throwable $e) {
$info = [];
}
if ($info) {
$data['copy_num'] = $info['copy']['num'] ?? 0;
}
}
return $this->success($data);
}
/**
* 复制商品
* @return mixed
*/
public function copyProduct()
{
[$type, $id, $shopid, $url] = $this->request->postMore([
['type', ''],
['id', ''],
['shopid', ''],
['url', '']
], true);
$res = $this->services->copyProduct($type, $id, $shopid, $url);
return $this->success($res);
}
/**
* 保存图片保存商品信息
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function save_product()
{
$data = $this->request->postMore([
['cate_id', ''],
['store_name', ''],
['store_info', ''],
['keyword', ''],
['unit_name', ''],
['image', ''],
['slider_image', []],
['price', 0],
['ot_price', 0],
['give_integral', ''],
['postage', ''],
['sales', 0],
['ficti', ''],
['stock', 0],
['cost', 0],
['description_images', []],
['description', ''],
['is_show', 0],
['soure_link', ''],
['temp_id', 0],
['spec_type', 0],
['items', []],
['attrs', []],
]);
$this->services->save($data);
return $this->success('生成商品成功');
}
}

View File

@@ -0,0 +1,123 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product;
use app\controller\admin\AuthController;
use app\services\product\shipping\ShippingTemplatesServices;
use app\services\other\SystemCityServices;
use think\annotation\Inject;
/**
* 运费模板
* Class ShippingTemplates
* @package app\controller\admin\v1\setting
*/
class ShippingTemplates extends AuthController
{
/**
* @var ShippingTemplatesServices
*/
#[Inject]
protected ShippingTemplatesServices $services;
/**
* 运费模板列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function temp_list()
{
$where = $this->request->getMore([
[['name', 's'], '']
]);
$where['type'] = 0;
$where['relation_id'] = 0;
if($this->supplierId > 0){
$where['type'] = 2;
$where['relation_id'] = $this->supplierId;
}
return $this->success($this->services->getShippingList($where));
}
/**
* 修改
* @return string
* @throws \Exception
*/
public function edit($id)
{
return $this->success($this->services->getShipping((int)$id));
}
/**
* 保存或者修改
* @param int $id
*/
public function save($id = 0)
{
$data = $this->request->postMore([
[['region_info', 'a'], []],
[['appoint_info', 'a'], []],
[['no_delivery_info', 'a'], []],
[['sort', 'd'], 0],
[['type', 'd'], 0, '', 'group'],
[['name', 's'], ''],
[['appoint', 'd'], 0],
[['no_delivery', 'd'], 0]
]);
$this->validate($data, \app\validate\admin\setting\ShippingTemplatesValidate::class, 'save');
$temp['name'] = $data['name'];
$temp['group'] = $data['group'];
$temp['appoint'] = $data['appoint'] && $data['appoint_info'] ? 1 : 0;
$temp['no_delivery'] = $data['no_delivery'] && $data['no_delivery_info'] ? 1 : 0;
$temp['sort'] = $data['sort'];
$temp['add_time'] = time();
if($this->supplierId > 0){
$temp['type'] = 2;
$temp['relation_id'] = $this->supplierId;
}
$this->services->save((int)$id, $temp, $data);
event('product.shipping.update');
return $this->success((int)$id ? '修改成功!' : '添加成功!');
}
/**
* 删除运费模板
*/
public function delete()
{
[$id] = $this->request->getMore([
[['id', 'd'], 0],
], true);
if ($id == 1) {
return $this->fail('默认模板不能删除');
} else {
$this->services->detete($id);
event('product.shipping.update');
return $this->success('删除成功');
}
}
/**
* 城市数据
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function city_list(SystemCityServices $services)
{
return $this->success($services->getShippingCity());
}
}

View File

@@ -0,0 +1,127 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product;
use app\controller\admin\AuthController;
use app\services\product\brand\StoreBrandServices;
use think\annotation\Inject;
/**
* 商品品牌控制器
* Class StoreCategory
* @package app\admin\controller\system
*/
class StoreBrand extends AuthController
{
/**
* @var StoreBrandServices
*/
#[Inject]
protected StoreBrandServices $service;
/**
* 品牌列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['brand_name', ''],
['pid', 0]
]);
$where['is_del'] = 0;
$data = $this->service->getList($where);
return $this->success($data);
}
/**
* 获取品牌cascader格式数据
* @param $type
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function cascader_list($type = 1)
{
return $this->success($this->service->cascaderList($type));
}
/**
* 修改状态
* @param string $is_show
* @param string $id
*/
public function set_show($is_show = '', $id = '')
{
if ($is_show == '' || $id == '') return $this->fail('缺少参数');
$this->service->setShow($id, $is_show);
return $this->success($is_show == 1 ? '显示成功' : '隐藏成功');
}
/**
* 保存新增品牌
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
['fid', []],
['brand_name', ''],
['sort', 0],
['is_show', 0]
]);
if (!$data['brand_name']) {
return $this->fail('请输入品牌名称');
}
if (iconv_strlen($data['brand_name'], 'UTF-8') > 10) {
return $this->fail('品牌名称过长');
}
$this->service->createData($data);
return $this->success('添加品牌成功!');
}
/**
* 更新品牌
* @param $id
* @return mixed
*/
public function update($id)
{
$data = $this->request->postMore([
['fid', []],
['brand_name', ''],
['sort', 0],
['is_show', 0]
]);
if (!$data['brand_name']) {
return $this->fail('请输入品牌名称');
}
if (iconv_strlen($data['brand_name'], 'UTF-8') > 10) {
return $this->fail('品牌名称过长');
}
$this->service->editData($id, $data);
return $this->success('修改成功!');
}
/**
* 删除品牌
* @param $id
* @return mixed
*/
public function delete($id)
{
$this->service->del((int)$id);
return $this->success('删除成功!');
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,165 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product;
use app\controller\admin\AuthController;
use app\services\product\category\StoreProductCategoryServices;
use think\annotation\Inject;
/**
* 商品分类控制器
* Class StoreProductCategory
* @package app\admin\controller\system
*/
class StoreProductCategory extends AuthController
{
/**
* @var StoreProductCategoryServices
*/
#[Inject]
protected StoreProductCategoryServices $service;
/**
* 分类列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['is_show', ''],
['pid', 0],
['cate_name', ''],
['id', ''],
]);
$where['type'] = 0;
$where['pid'] = (int)$where['pid'];
if ($where['cate_name'] !== '') unset($where['pid']);
$data = $this->service->getList($where, '*', ['AdminChildren']);
return $this->success($data);
}
/**
* 商品分类搜索
* @return mixed
*/
public function tree_list($type)
{
$list = $this->service->getTierList(1, $type);
return $this->success($list);
}
/**
* 获取分类cascader格式数据
* @param $type
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function cascader_list($type = 1)
{
return $this->success($this->service->cascaderList());
}
/**
* 修改状态
* @param string $is_show
* @param string $id
*/
public function set_show($is_show = '', $id = '')
{
if ($is_show == '' || $id == '') return $this->fail('缺少参数');
$this->service->setShow($id, $is_show);
return $this->success($is_show == 1 ? '显示成功' : '隐藏成功');
}
/**
* 生成新增表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function create()
{
return $this->success($this->service->createForm());
}
/**
* 保存新增分类
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
['pid', []],
['cate_name', ''],
['pic', ''],
['big_pic', ''],
['sort', 0],
['is_show', 0]
]);
if (!$data['cate_name']) {
return $this->fail('请输入分类名称');
}
$data['pid'] = end($data['pid']);
$data['type'] = 0;
$data['relation_id'] = 0;
$this->service->createData($data);
return $this->success('添加分类成功!');
}
/**
* 生成更新表单
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function edit($id)
{
return $this->success($this->service->editForm((int)$id));
}
/**
* 更新分类
* @param $id
* @return mixed
*/
public function update($id)
{
$data = $this->request->postMore([
['pid', []],
['cate_name', ''],
['pic', ''],
['big_pic', ''],
['sort', 0],
['is_show', 0]
]);
if (!$data['cate_name']) {
return $this->fail('请输入分类名称');
}
$data['pid'] = end($data['pid']);
$this->service->editData($id, $data);
return $this->success('修改成功!');
}
/**
* 删除分类
* @param $id
* @return mixed
*/
public function delete($id)
{
$this->service->del((int)$id);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,225 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product;
use app\controller\admin\AuthController;
use app\services\product\product\StoreProductReplyCommentServices;
use app\services\product\product\StoreProductReplyServices;
use think\annotation\Inject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
/**
* 评论管理 控制器
* Class StoreProductReply
* @package app\controller\admin\v1\product
*/
class StoreProductReply extends AuthController
{
/**
* @var StoreProductReplyServices
*/
#[Inject]
protected StoreProductReplyServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['is_reply', ''],
['store_name', ''],
['account', ''],
['data', ''],
['product_id', 0]
]);
$where['type'] = 0;
$where['relation_id'] = 0;
if ($this->supplierId != 0) {
$where['type'] = 2;
$where['relation_id'] = $this->supplierId;
}
$list = $this->services->sysPage($where);
return $this->success($list);
}
/**
* 删除评论
* @param $id
* @return mixed
*/
public function delete($id)
{
$this->services->del($id);
return $this->success('删除成功!');
}
/**
* 管理员回复评论
* @param $id
* @return mixed
*/
public function set_reply($id)
{
[$content] = $this->request->postMore([
['content', '']
], true);
$this->services->setReply($id, $content);
return $this->success('回复成功!');
}
/**
* 获取管理员评论
* @param StoreProductReplyCommentServices $services
* @param $id
* @return mixed
*/
public function getReply(StoreProductReplyCommentServices $services, $id)
{
if (!$id) {
return $this->fail('缺少参数');
}
$where = ['reply_id' => $id, 'uid' => 0, 'relation_id' => 0];
$commentInfo = $services->get($where);
if ($commentInfo) {
return $this->success($commentInfo->toArray());
} else {
return $this->success(['content' => '']);
}
}
/**
* 创建自评表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function fictitious_reply()
{
[$product_id] = $this->request->postMore([
['product_id', 0],
], true);
return $this->success($this->services->createForm($product_id));
}
/**
* 保存虚拟评论
* @return mixed
*/
public function save_fictitious_reply()
{
$data = $this->request->postMore([
['image', ''],
['nickname', ''],
['avatar', ''],
['comment', ''],
['pics', []],
['reply_score', 3],
['product_score', 5],
['service_score', 5],
['delivery_score', 5],
['product_id', 0],
['unique', '', '', 'sku_unique'],
['add_time', 0]
]);
if (!$data['product_id']) {
$data['product_id'] = $data['image']['product_id'] ?? '';
}
$this->validate(['product_id' => $data['product_id'], 'nickname' => $data['nickname'], 'avatar' => $data['avatar'], 'comment' => $data['comment'], 'reply_score' => $data['reply_score'], 'product_score' => $data['product_score'], 'service_score' => $data['service_score'], 'delivery_score' => $data['delivery_score']], \app\validate\admin\product\StoreProductReplyValidate::class, 'save');
$this->services->saveReply($data);
return $this->success('添加成功!');
}
/**
* 获取评论回复列表
* @param StoreProductReplyCommentServices $services
* @param $id
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getComment(StoreProductReplyCommentServices $services, $id)
{
if (!$id) {
return $this->fail('缺少参数');
}
$time = $this->request->get('time', '');
return $this->success($services->getReplCommenList((int)$id, $time));
}
/**
* 管理员二级回复
* @param StoreProductReplyCommentServices $services
* @param $replyId
* @param $id
* @return mixed
*/
public function saveComment(StoreProductReplyCommentServices $services, $replyId, $id)
{
if (!$id) {
return $this->fail('缺少参数');
}
$data = $this->request->postMore([
['content', ''],
]);
if (!$data['content']) {
return app('json')->fail('缺少回复内容');
}
$data['reply_id'] = $replyId;
$data['create_time'] = time();
$data['uid'] = 0;
$data['pid'] = $id;
$where = ['uid' => 0, 'pid' => $id, 'reply_id' => $replyId];
if ($services->count($where)) {
$services->update($where, ['content' => $data['content'], 'update_time' => time()]);
} else {
$services->save($data);
}
return $this->success('保存成功');
}
/**
* 删除用户回复
* @param StoreProductReplyCommentServices $services
* @param $id
* @return mixed
*/
public function deleteComment(StoreProductReplyCommentServices $services, $id)
{
if (!$id) {
return $this->fail('缺少参数');
}
$services->transaction(function () use ($id, $services) {
$services->delete($id);
$services->delete(['pid' => $id]);
});
return $this->success('删除成功');
}
/**
* 批量保存AI生成的评价回复
* @return mixed
*/
public function saveAllAiReply()
{
[$data] = $this->request->postMore([
['data', []]
], true);
$this->services->saveAllAiReply($data);
return $this->success('保存成功');
}
}

View File

@@ -0,0 +1,109 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product;
use app\controller\admin\AuthController;
use app\jobs\BatchHandleJob;
use app\services\other\queue\QueueServices;
use app\services\product\sku\StoreProductRuleServices;
use think\annotation\Inject;
/**
* 规则管理
* Class StoreProductRule
* @package app\controller\admin\v1\product
*/
class StoreProductRule extends AuthController
{
/**
* @var StoreProductRuleServices
*/
#[Inject]
protected StoreProductRuleServices $services;
/**
* 规格列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['rule_name', '']
]);
if ($this->supplierId > 0) {
$where['type'] = 2;
$where['relation_id'] = $this->supplierId;
} else {
$where['type'] = 0;
$where['relation_id'] = 0;
}
$list = $this->services->getList($where);
return $this->success($list);
}
/**
* 保存规格
* @param $id
* @return mixed
*/
public function save($id)
{
$data = $this->request->postMore([
['rule_name', ''],
['spec', []]
]);
if (!$data['rule_name']) {
return $this->fail('请输入分类名称');
}
$type = $relation_id = 0;
if ($this->supplierId > 0) {
$type = 2;
$relation_id = $this->supplierId;
}
$this->services->save($id, $data, $type, $relation_id);
return $this->success('保存成功!');
}
/**
* 获取规格信息
* @param $id
* @return mixed
*/
public function read($id)
{
$info = $this->services->getInfo((int)$id);
return $this->success($info);
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id) {
return $this->fail('缺少ID');
}
$info = $this->services->getInfo((int)$id);
if (!$info) {
return $this->fail('删除的数据不存在');
}
$this->services->delete($id);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,176 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product;
use app\Request;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\product\product\StoreProductServices;
use app\services\product\product\StoreProductUnitServices;
/**
* 商品单位
* Class StoreProductUnit
* @package app\controller\admin\v1\product
*/
class StoreProductUnit extends AuthController
{
/**
* @var StoreProductUnitServices
*/
#[Inject]
protected StoreProductUnitServices $services;
/**
* 获取所有商品单位
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getAllUnit()
{
return $this->success($this->services->getAllUnitList());
}
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index(Request $request)
{
$where = $request->postMore([
['name', '']
]);
$where['type'] = 0;
$where['relation_id'] = 0;
$where['status'] = 1;
$where['is_del'] = 0;
return $this->success($this->services->getUnitList($where));
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
return $this->success($this->services->createForm());
}
/**
* 保存新建的资源
*
* @param \app\Request $request
* @return \think\Response
*/
public function save(Request $request)
{
$data = $request->postMore([
['name', ''],
['sort', 0]
]);
validate(\app\validate\admin\product\StoreProductUnitValidate::class)->scene('get')->check(['name' => $data['name']]);
if ($this->services->getCount(['name' => $data['name'], 'is_del' => 0, 'type' => 0])) {
return $this->fail('单位已经存在,请勿重复添加');
}
$data['add_time'] = time();
if ($this->services->save($data)) {
return $this->success('保存成功');
} else {
return $this->fail('保存失败');
}
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
if (!$id) {
return $this->fail('缺少ID');
}
$info = $this->services->get($id);
if (!$info) {
return $this->fail('获取商品单位失败');
}
return $this->success($info->toArray());
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
return $this->success($this->services->updateForm((int)$id));
}
/**
* 保存更新的资源
*
* @param \app\Request $request
* @param int $id
* @return \think\Response
*/
public function update(Request $request, $id)
{
$data = $request->postMore([
['name', ''],
['sort', 0]
]);
validate(\app\validate\admin\product\StoreProductUnitValidate::class)->scene('get')->check(['name' => $data['name']]);
$unit = $this->services->getOne(['name' => $data['name'], 'is_del' => 0, 'type' => 0]);
if ($unit && $unit['id'] != $id) {
return $this->fail('单位名称已经存在');
}
if ($this->services->update($id, $data)) {
return $this->success('修改成功');
} else {
return $this->fail('修改失败');
}
}
/**
* 删除指定资源
* @param StoreProductServices $productServices
* @param $id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function delete(StoreProductServices $productServices, $id)
{
if (!$id || !($info = $this->services->get($id))) {
return $this->fail('删除的数据不存在');
}
if ($productServices->getCount(['unit_name' => $info['name'], 'is_del' => 0])) {
return $this->fail('该单位正在使用,不能删除');
}
if ($info && $info['is_del'] == 0) {
$this->services->update($id, ['is_del' => 1]);
}
return $this->success('删除成功');
}
}

View File

@@ -0,0 +1,126 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product;
use app\Request;
use app\services\product\product\StoreProductWordsServices;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\product\product\StoreProductServices;
/**
* 热词
* Class StoreProductWords
* @package app\controller\admin\v1\product
*/
class StoreProductWords extends AuthController
{
/**
* @var StoreProductWordsServices
*/
#[Inject]
protected StoreProductWordsServices $services;
/**
* 获取所有热词
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getAllWords()
{
return $this->success($this->services->getAllWordsList());
}
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index(Request $request)
{
$where = $request->postMore([
['name', '']
]);
$where['type'] = 0;
$where['relation_id'] = 0;
$where['is_del'] = 0;
return $this->success($this->services->getWordsList($where));
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function info($id)
{
if (!$id) {
return $this->fail('缺少ID');
}
$info = $this->services->get($id);
if (!$info) {
return $this->fail('获取热词失败');
}
return $this->success($info->toArray());
}
/**
* 保存新建的资源
*
* @param \app\Request $request
* @return \think\Response
*/
public function save(Request $request, $id)
{
$data = $request->postMore([
['name', ''],//名称
['color', ''],//颜色
['bg_color', ''],//背景色
['border_color', ''],//边框色
['icon', ''],//图标
['sort', 0],//排序
['is_search', 1],
['is_show', 1]//状态
]);
validate(\app\validate\admin\product\StoreProductWordsValidate::class)->scene('get')->check(['name' => $data['name']]);
$res = $this->services->saveData((int)$id, $data);
return $this->success( $res ? '保存成功' : '保存失败');
}
/**
* 修改状态
* @param string $is_show
* @param string $id
*/
public function set_show($is_show = '', $id = '')
{
if ($is_show == '' || $id == '') return $this->fail('缺少参数');
$this->services->setShow($id, $is_show);
return $this->success($is_show == 1 ? '显示成功' : '隐藏成功');
}
/**
* 删除
* @param $id
* @return mixed
*/
public function delete($id)
{
$this->services->del((int)$id);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,174 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product\ensure;
use app\controller\admin\AuthController;
use app\Request;
use app\services\product\ensure\StoreProductEnsureServices;
use think\annotation\Inject;
/**
* 商品保障服务
* Class StoreProductEnsure
* @package app\controller\admin\v1\product\ensure
*/
class StoreProductEnsure extends AuthController
{
/**
* @var StoreProductEnsureServices
*/
#[Inject]
protected StoreProductEnsureServices $services;
/**
* 获取保障服务列表
* @param Request $request
* @return mixed
*/
public function index(Request $request)
{
$where = $request->postMore([
['name', '']
]);
$where['relation_id'] = 0;
$where['type'] = 0;
return $this->success($this->services->getEnsureList($where));
}
/**
* 获取保障服务列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function allEnsure()
{
return $this->success($this->services->getAllEnsure());
}
/**
* 生成新增表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function create()
{
return $this->success($this->services->createForm());
}
/**
* 保存新增保障服务
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
['name', ''],
['image', ''],
['desc', ''],
['sort', 0],
]);
if (!$data['name']) {
return $this->fail('请输入保障服务条款');
}
if (!$data['image']) return $this->fail('请上传图标');
if ($this->services->getOne(['name' => $data['name']])) {
return $this->fail('保障服务条款已存在');
}
$data['type'] = 0;
$data['relation_id'] = 0;
$data['add_time'] = time();
$res = $this->services->save($data);
$data['id'] = $res->id;
$this->services->cacheUpdate($data);
return $this->success('添加保障服务成功!');
}
/**
* 生成更新表单
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function edit($id)
{
return $this->success($this->services->editForm((int)$id));
}
/**
* 更新保障服务
* @param $id
* @return mixed
*/
public function update($id)
{
$data = $this->request->postMore([
['name', ''],
['image', ''],
['desc', ''],
['sort', 0],
]);
if (!$data['name']) {
return $this->fail('请输入保障服务条款');
}
if (!$data['image']) return $this->fail('请上传图标');
$cate = $this->services->getOne(['name' => $data['name']]);
if ($cate && $cate['id'] != $id) {
return $this->fail('保障服务条款已存在');
}
$this->services->update($id, $data);
$data['id'] = $id;
$this->services->cacheUpdate($data);
return $this->success('修改成功!');
}
/**
* 设置保障服务是否显示
* @param $id
* @param $is_show
* @return mixed
*/
public function set_show($id, $is_show)
{
($is_show == '' || $id == '') && $this->fail('缺少参数');
$res = $this->services->update((int)$id, ['status' => (int)$is_show]);
if ($res) {
//更新缓存
if ($is_show) {
$this->services->cacheSaveValue((int)$id, 'status', $is_show);
} else {
$this->services->cacheDelById($id);
}
return $this->success('设置成功');
} else {
return $this->fail('设置失败');
}
}
/**
* 删除保障服务
* @param $id
* @return mixed
*/
public function delete($id)
{
if (!$id || !$this->services->count(['id' => $id])) {
return $this->fail('删除的数据不存在');
}
$this->services->delete((int)$id);
$this->services->cacheDelById($id);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,220 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product\label;
use app\Request;
use crmeb\services\CacheService;
use think\annotation\Inject;
use app\controller\admin\AuthController;
use app\services\product\label\StoreProductLabelCateServices;
use app\services\product\label\StoreProductLabelServices;
/**
* 商品标签
* Class StoreProductLabel
* @package app\controller\admin\v1\product\label
*/
class StoreProductLabel extends AuthController
{
/**
* @var StoreProductLabelServices
*/
#[Inject]
protected StoreProductLabelServices $services;
/**
* 标签列表
* @return mixed
*/
public function index($label_cate = 0)
{
return $this->success($this->services->getList(['label_cate' => $label_cate, 'type' => 0, 'relation_id' => 0]));
}
/**
* 带标签的标签组树形结构
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function tree_list()
{
return $this->success($this->services->getProductLabelTreeList());
}
/**
* 获取商品标签列表
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function allLabel()
{
return $this->success($this->services->getAllLabel());
}
/**
* 添加、编辑商品标签
* @param Request $request
* @param $id
* @return mixed
*/
public function save(Request $request, $id)
{
$data = $request->postMore([
['label_cate', 0],//分组ID
['label_name', ''],//标签名称
['style_type', 1],//样式类型1:自定义2:图片
['color', ''],//颜色
['bg_color', ''],//背景色
['border_color', ''],//边框色
['icon', ''],//图标
['is_show', 1],//移动端是否展示
['status', 1],//状态是否开启
['sort', 0],//排序
]);
if (!$data['label_cate']) {
return $this->fail('请选择标签组');
}
if (!trim($data['label_name'])) {
return $this->fail('请输入标签名称');
}
$label = $this->services->getOne(['label_cate' => $data['label_cate'], 'label_name' => $data['label_name']]);
if ($id) {
if ($label && $id != $label['id']) {
return $this->fail('标签已经存在');
}
if ($this->services->update($id, $data)) {
$data['id'] = $id;
$this->services->cacheUpdate($data);
return $this->success('编辑成功');
} else {
return $this->fail('编辑失败');
}
} else {
if ($label) {
return $this->fail('标签已经存在');
}
$data['type'] = 0;
$data['relation_id'] = 0;
$data['add_time'] = time();
if ($this->services->save($data)) {
$data['id'] = $id;
$this->services->cacheUpdate($data);
return $this->success('保存成功');
} else {
return $this->fail('保存失败');
}
}
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_status($id, $status)
{
$this->services->update($id, ['status' => $status]);
//修改状态同步缓存
$this->services->cacheSaveValue($id, 'status', $status);
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
/**
* 修改移动端是否展示
* @param $id
* @param $status
* @return mixed
*/
public function set_show($id, $show)
{
$this->services->update($id, ['is_show' => $show]);
//修改状态同步缓存
$this->services->cacheSaveValue($id, 'is_show', $show);
return $this->success($show == 0 ? '关闭成功' : '开启成功');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id || !$this->services->count(['id' => $id])) {
return $this->fail('删除的数据不存在');
}
$info = $this->services->get((int)$id);
if (in_array($id, [1, 2, 3, 4, 5]) && $info['label_cate'] == 1) {//系统默认
return $this->fail('默认标签不允许删除');
}
$this->services->delete($id);
$this->services->cacheDelById($id);
return $this->success('删除成功');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function del(Request $request)
{
[$ids, $all, $where] = $request->postMore([
['ids', ''],
['all', 0],
['where', []],
], true);
if ($all == 0) {//单页不走队列
if (!$ids) {
return $this->fail('请选择需要删除的标签');
}
} else {
$ids = $this->services->getColumn($where + ['type' => 0, 'relation_id' => 0], 'id');
}
$ids = is_string($ids) ? stringToIntArray($ids) : $ids;
//默认标签不允许删除
$ids = array_diff($ids, [1, 2, 3, 4, 5]);
if ($ids) {
$this->services->del($ids);
foreach ($ids as $id) {
$this->services->cacheDelById($id);
}
} else {
return $this->fail('默认标签不允许删除');
}
return $this->success('删除成功');
}
/**
* 获取表单
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getLabelForm()
{
return $this->success($this->services->getLabelForm());
}
}

View File

@@ -0,0 +1,139 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product\label;
use app\controller\admin\AuthController;
use app\Request;
use app\services\product\category\StoreProductCategoryServices;
use app\services\product\label\StoreProductLabelCateServices;
use app\services\product\label\StoreProductLabelServices;
use think\annotation\Inject;
use think\facade\App;
/**
* 商品标签组
* Class StoreProductLabelCate
* @package app\controller\admin\v1\product\label
*/
class StoreProductLabelCate extends AuthController
{
/**
* @var StoreProductLabelCateServices
*/
#[Inject]
protected StoreProductLabelCateServices $services;
/**
* 获取标签组列表
* @param Request $request
* @return mixed
*/
public function index(Request $request)
{
$where = $request->postMore([
['name', '']
]);
$where['type'] = 0;
$where['relation_id'] = 0;
$where['group'] = 2;
$where['product_label'] = 1;
return $this->success($this->services->getProductLabelCateList($where));
}
/**
* 生成新增表单
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function create()
{
return $this->success($this->services->createForm());
}
/**
* 保存新增标签组
* @return mixed
*/
public function save()
{
$data = $this->request->postMore([
['name', ''],
['sort', 0],
]);
if (!trim($data['name'])) {
return $this->fail('请输入标签组名称');
}
if ($this->services->getOne(['name' => $data['name'], 'group' => 2, 'type' => 0])) {
return $this->fail('标签组已存在');
}
$data['type'] = 0;
$data['relation_id'] = 0;
$data['group'] = 2;
$data['add_time'] = time();
$this->services->save($data);
return $this->success('添加标签组成功!');
}
/**
* 生成更新表单
* @param $id
* @return mixed
* @throws \FormBuilder\Exception\FormBuilderException
*/
public function edit($id)
{
return $this->success($this->services->editForm((int)$id));
}
/**
* 更新标签组
* @param $id
* @return mixed
*/
public function update($id)
{
$data = $this->request->postMore([
['name', ''],
['sort', 0],
]);
if (!$data['name']) {
return $this->fail('请输入标签组名称');
}
$cate = $this->services->getOne(['name' => $data['name'], 'group' => 2, 'type' => 0]);
if ($cate && $cate['id'] != $id) {
return $this->fail('标签组已存在');
}
$this->services->update($id, $data);
return $this->success('修改成功!');
}
/**
* 删除标签组
* @param StoreProductLabelServices $labelServices
* @param $id
* @return mixed
*/
public function delete(StoreProductLabelServices $labelServices, $id)
{
if (!$id || !$this->services->count(['id' => $id])) {
return $this->fail('删除的数据不存在');
}
if ($id == 1) {//系统默认分组 不允许删除
return $this->fail('系统默认标签组不能删除');
}
if ($labelServices->count(['label_cate' => $id])) {
return $this->fail('标签组下有标签不能删除');
}
$this->services->delete((int)$id);
return $this->success('删除成功!');
}
}

View File

@@ -0,0 +1,145 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product\specs;
use app\controller\admin\AuthController;
use app\services\product\specs\StoreProductSpecsServices;
use app\services\product\specs\StoreProductSpecsTemplateServices;
use think\annotation\Inject;
use app\Request;
/**
* 商品参数
* Class StoreProductSpecs
* @package app\controller\admin\v1\product\specs
*/
class StoreProductSpecs extends AuthController
{
/**
* 参数模版services
* @var StoreProductSpecsTemplateServices
*/
#[Inject]
protected StoreProductSpecsTemplateServices $templateServices;
/**
* @var StoreProductSpecsServices
*/
#[Inject]
protected StoreProductSpecsServices $services;
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index(Request $request)
{
$where = $request->postMore([
['name', '']
]);
return $this->success($this->templateServices->getProductSpecsTemplateList($where));
}
/**
* 显示资源列表
*
* @return \think\Response
*/
public function allSpecs(Request $request)
{
return $this->success($this->templateServices->getAllSpecs());
}
/**
* 获取参数模版信息
* @param $id
* @return mixed
*/
public function getInfo($id)
{
if (!$id) return $this->fail('缺少参数ID');
$temp = $this->templateServices->get(['id' => $id, 'group' => 3], ['*'], ['specs']);
if (!$temp) {
return $this->fail('参数模版不存在');
}
return $this->success($temp->toArray());
}
/**
* 添加、编辑商品参数模版
* @param Request $request
* @param $id
* @return mixed
*/
public function save(Request $request, $id)
{
$data = $request->postMore([
['name', ''],
['specs', []],
['sort', ''],
]);
if (!$data['name']) {
return $this->fail('请输入参数模版名称');
}
$specs = $data['specs'];
unset($data['specs']);
$temp = $this->templateServices->getOne(['name' => $data['name'], 'group' => 3, 'type' => 0, 'relation_id' => 0]);
if ($id) {
if ($temp && $id != $temp['id']) {
return $this->fail('参数模版已经存在');
}
$this->templateServices->transaction(function () use ($id, $data, $specs) {
if (!$this->templateServices->update($id, $data)) {
return $this->success('编辑失败');
}
if (!$this->services->updateData($id, $specs)) {
return $this->success('编辑失败');
}
});
return $this->success('编辑成功');
} else {
if ($temp) {
return $this->fail('参数模版已经存在');
}
$data['type'] = 0;
$data['relation_id'] = 0;
$data['group'] = 3;
$data['add_time'] = time();
$this->templateServices->transaction(function () use ($id, $data, $specs) {
if (!$res = $this->templateServices->save($data)) {
return $this->success('保存失败');
}
if (!$this->services->saveData((int)$res->id, $specs)) {
return $this->success('保存失败');
}
});
return $this->success('保存成功');
}
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id || !($this->templateServices->count(['id' => $id]))) {
return $this->fail('删除的数据不存在');
}
$this->templateServices->delete($id);
$this->services->delete(['temp_id' => $id]);
return $this->success('删除成功');
}
}

View File

@@ -0,0 +1,148 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\product\stock;
use app\controller\admin\AuthController;
use app\services\product\sku\StoreProductAttrValueServices;
use app\services\product\stock\StockInventoryServices;
use think\annotation\Inject;
/**
* 库存管理控制器
* Class StockRecordController
* @package app\controller\admin\stock
*/
class StockInventoryController extends AuthController
{
/**
* @var StockInventoryServices
*/
#[Inject]
protected StockInventoryServices $services;
/**
* 获取出入库记录列表
* @return \think\Response
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$where = $this->request->getMore([
['record_no', ''],
['create_time', ''],
['unique', ''],
['status', ''],
]);
return $this->success($this->services->getStockRecordList($where));
}
/**
* 创建出入库记录
* @return \think\Response
*/
public function save()
{
$data = $this->request->postMore([
['status', 0],
['remark', ''],
['product', []],
]);
if (empty($data['product'])) {
return $this->fail('请添加商品信息');
}
try {
$this->services->createStockRecord($data, $this->adminId);
return $this->success('创建成功');
} catch (\Exception $e) {
return $this->fail($e->getMessage());
}
}
public function update($id)
{
$data = $this->request->postMore([
['status', 0],
['remark', ''],
['product', []],
]);
if (empty($data['product'])) {
return $this->fail('请添加商品信息');
}
try {
$this->services->createStockRecord($data, $this->adminId, $id);
return $this->success('创建成功');
} catch (\Exception $e) {
return $this->fail($e->getMessage());
}
}
/**
* 获取出入库记录详情
* @param int $id
* @return \think\Response
*/
public function read($id)
{
if (!$id) {
return $this->fail('记录不存在');
}
return $this->success($this->services->read($id));
}
/**
* 备注表单
* @param $id
* @return \think\Response
* User: liusl
* DateTime: 2025/9/18 14:36
*/
public function remark($id)
{
if (!$id) {
return $this->fail('记录不存在');
}
return $this->success($this->services->remarkFrom($id));
}
/**
* 备注
* @param $id
* @return \think\Response
* User: liusl
* DateTime: 2025/9/18 14:43
*/
public function remarkSave($id)
{
$data = $this->request->postMore([
['remark', ''],
]);
if (!$id) {
return $this->fail('记录不存在');
}
if (!$data['remark']) {
return $this->fail('请填写备注');
}
try {
$this->services->update($id, ['remark' => $data['remark']]);
return $this->success('保存成功');
} catch (\Exception $e) {
return $this->fail($e->getMessage());
}
}
}

Some files were not shown because too many files have changed in this diff Show More