Merge branch 'dev'
This commit is contained in:
commit
0c8bc4a6e9
|
|
@ -22,16 +22,17 @@ abstract class MyController extends BaseController
|
|||
if ($platform == "APP_ANDROID" || $platform == "APP_IOS") {
|
||||
|
||||
// 密钥和加密算法
|
||||
$secretKey = 'g6R@9!zB2fL#1cVm'; // 必须是 16/24/32 位
|
||||
$cipher = 'AES-128-CBC';
|
||||
$iv = substr(md5($secretKey), 0, 16); // IV 长度必须是 16 字节
|
||||
// $secretKey = 'g6R@9!zB2fL#1cVm'; // 必须是 16/24/32 位
|
||||
// $cipher = 'AES-128-CBC';
|
||||
// $iv = substr(md5($secretKey), 0, 16); // IV 长度必须是 16 字节
|
||||
|
||||
// 对 $data 进行加密处理
|
||||
$dataString = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
$encrypted = openssl_encrypt($dataString, $cipher, $secretKey, 0, $iv);
|
||||
// $dataString = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
// $encrypted = openssl_encrypt($dataString, $cipher, $secretKey, 0, $iv);
|
||||
return [
|
||||
'ret' => $status,
|
||||
'payload' => $encrypted,
|
||||
// 'payload' => $data,//$encrypted,
|
||||
'data' => $data,
|
||||
'note' => $msg,
|
||||
'ts' => time(), // 当前时间戳
|
||||
];
|
||||
|
|
@ -39,6 +40,17 @@ abstract class MyController extends BaseController
|
|||
$request = request();
|
||||
return compact('status', 'msg', 'data');
|
||||
}
|
||||
protected function encryption($data)
|
||||
{
|
||||
$secretKey = 'g6R@9!zB2fL#1cVm'; // 必须是 16/24/32 位
|
||||
$cipher = 'AES-128-CBC';
|
||||
$iv = substr(md5($secretKey), 0, 16); // IV 长度必须是 16 字节
|
||||
|
||||
// 对 $data 进行加密处理
|
||||
$dataString = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
$encrypted = openssl_encrypt($dataString, $cipher, $secretKey, 0, $iv);
|
||||
return $encrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回操作成功json
|
||||
|
|
|
|||
179
app/admin/controller/FFCategoriesController.php
Normal file
179
app/admin/controller/FFCategoriesController.php
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\facade\View;
|
||||
use think\facade\Db;
|
||||
use app\common\model\FFCategories;
|
||||
|
||||
class FFCategoriesController extends Base
|
||||
{
|
||||
/**
|
||||
* 商品分类列表
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$limit = input('param.limit', 15);
|
||||
$page = input('param.page', 1);
|
||||
$offset = ($page - 1) * $limit;
|
||||
$category_name = input('param.category_name', '');
|
||||
$status = input('param.status', '');
|
||||
|
||||
$where = [];
|
||||
if ($category_name) {
|
||||
$where[] = ['category_name', 'like', "%{$category_name}%"];
|
||||
}
|
||||
if ($status !== '') {
|
||||
$where[] = ['status', '=', $status];
|
||||
}
|
||||
|
||||
$res = FFCategories::where($where)
|
||||
->order(['sort_order' => 'asc', 'id' => 'desc'])
|
||||
->limit($offset, $limit)
|
||||
->select();
|
||||
|
||||
$total = FFCategories::where($where)->count();
|
||||
|
||||
return $this->renderTable('获取成功', $total, $res, 0);
|
||||
}
|
||||
|
||||
return View::fetch('FFCategories/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品分类
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$param = input('post.');
|
||||
$validate = $this->validate($param, [
|
||||
'category_name' => 'require',
|
||||
]);
|
||||
|
||||
if (true !== $validate) {
|
||||
return $this->renderError($validate);
|
||||
}
|
||||
|
||||
// 默认值设置
|
||||
if (!isset($param['parent_id'])) {
|
||||
$param['parent_id'] = 0;
|
||||
$param['category_level'] = 1;
|
||||
} else if ($param['parent_id'] > 0) {
|
||||
// 查询父级分类的等级,并设置当前分类的等级为父级+1
|
||||
$parent = FFCategories::where('id', $param['parent_id'])->find();
|
||||
if (!$parent) {
|
||||
return $this->renderError('父级分类不存在');
|
||||
}
|
||||
$param['category_level'] = $parent['category_level'] + 1;
|
||||
// 分类最多支持3级
|
||||
if ($param['category_level'] > 3) {
|
||||
return $this->renderError('分类最多支持3级');
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($param['sort_order'])) {
|
||||
$param['sort_order'] = 0;
|
||||
}
|
||||
if (!isset($param['status'])) {
|
||||
$param['status'] = 1;
|
||||
}
|
||||
|
||||
$res = FFCategories::create($param);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('添加成功', ['url' => (string) url('ff_products')]);
|
||||
} else {
|
||||
return $this->renderError('添加失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取父级分类列表
|
||||
$parentList = FFCategories::where([
|
||||
['category_level', '<', 3], // 只查询1级和2级分类作为父级
|
||||
['status', '=', 1]
|
||||
])
|
||||
->order('sort_order', 'asc')
|
||||
->select();
|
||||
View::assign('parentList', $parentList);
|
||||
|
||||
return View::fetch('FFCategories/add');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品分类
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$info = FFCategories::where('id', $id)->find();
|
||||
if (empty($info)) {
|
||||
return $this->renderError('数据不存在');
|
||||
}
|
||||
|
||||
if (request()->isPost()) {
|
||||
$param = input('post.');
|
||||
$validate = $this->validate($param, [
|
||||
'category_name' => 'require',
|
||||
]);
|
||||
|
||||
if (true !== $validate) {
|
||||
return $this->renderError($validate);
|
||||
}
|
||||
|
||||
// 不允许修改分类级别和父级分类,因为会影响分类结构
|
||||
unset($param['parent_id']);
|
||||
unset($param['category_level']);
|
||||
|
||||
$res = FFCategories::update($param, ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('编辑成功', ['url' => (string) url('ff_products')]);
|
||||
} else {
|
||||
return $this->renderError('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
View::assign('info', $info);
|
||||
return View::fetch('FFCategories/edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改分类状态
|
||||
*/
|
||||
public function status()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$status = input('param.status', 0);
|
||||
|
||||
$res = FFCategories::update(['status' => $status], ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('操作成功');
|
||||
} else {
|
||||
return $this->renderError('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分类
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
|
||||
// 检查是否有子分类
|
||||
$hasChildren = FFCategories::where('parent_id', $id)->count();
|
||||
if ($hasChildren > 0) {
|
||||
return $this->renderError('该分类下有子分类,无法删除');
|
||||
}
|
||||
|
||||
$res = FFCategories::destroy($id);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('删除成功');
|
||||
} else {
|
||||
return $this->renderError('删除失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
250
app/admin/controller/FFProductsController.php
Normal file
250
app/admin/controller/FFProductsController.php
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\facade\View;
|
||||
use think\facade\Db;
|
||||
use app\common\model\FFCategories;
|
||||
use app\common\model\FFProducts;
|
||||
|
||||
class FFProductsController extends Base
|
||||
{
|
||||
/**
|
||||
* 商品列表
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$limit = input('param.limit', 15);
|
||||
$page = input('param.page', 1);
|
||||
$offset = ($page - 1) * $limit;
|
||||
$product_name = input('param.product_name', '');
|
||||
$status = input('param.status', '');
|
||||
$is_hot = input('param.is_hot', '');
|
||||
$is_new = input('param.is_new', '');
|
||||
$is_recommend = input('param.is_recommend', '');
|
||||
$category_name = input('param.category_name', '');
|
||||
|
||||
$where = [];
|
||||
if ($product_name) {
|
||||
$where[] = ['product_name', 'like', "%{$product_name}%"];
|
||||
}
|
||||
if ($status !== '') {
|
||||
$where[] = ['status', '=', $status];
|
||||
}
|
||||
if ($is_hot !== '') {
|
||||
$where[] = ['is_hot', '=', $is_hot];
|
||||
}
|
||||
if ($is_new !== '') {
|
||||
$where[] = ['is_new', '=', $is_new];
|
||||
}
|
||||
if ($is_recommend !== '') {
|
||||
$where[] = ['is_recommend', '=', $is_recommend];
|
||||
}
|
||||
if ($category_name) {
|
||||
$where[] = ['category_name', 'like', "%{$category_name}%"];
|
||||
}
|
||||
|
||||
$res = FFProducts::where($where)
|
||||
->order('id', 'desc')
|
||||
->limit($offset, $limit)
|
||||
->select();
|
||||
|
||||
$total = FFProducts::where($where)->count();
|
||||
|
||||
return $this->renderTable('获取成功', $total, $res, 0);
|
||||
}
|
||||
|
||||
return View::fetch('FFProducts/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$param = input('post.');
|
||||
$validate = $this->validate($param, [
|
||||
'product_name' => 'require',
|
||||
'price' => 'require|float',
|
||||
'stock' => 'require|number',
|
||||
]);
|
||||
|
||||
if (true !== $validate) {
|
||||
return $this->renderError($validate);
|
||||
}
|
||||
|
||||
// 处理多选的分类,转换为逗号分隔的字符串
|
||||
if (isset($param['categories']) && is_array($param['categories'])) {
|
||||
$param['category_name'] = implode(',', $param['categories']);
|
||||
unset($param['categories']);
|
||||
}
|
||||
|
||||
// 设置默认值
|
||||
if (!isset($param['status'])) {
|
||||
$param['status'] = 1;
|
||||
}
|
||||
if (!isset($param['sales'])) {
|
||||
$param['sales'] = 0;
|
||||
}
|
||||
if (!isset($param['is_hot'])) {
|
||||
$param['is_hot'] = 0;
|
||||
}
|
||||
if (!isset($param['is_new'])) {
|
||||
$param['is_new'] = 0;
|
||||
}
|
||||
if (!isset($param['is_recommend'])) {
|
||||
$param['is_recommend'] = 0;
|
||||
}
|
||||
|
||||
$res = FFProducts::create($param);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('添加成功', ['url' => (string) url('ff_products')]);
|
||||
} else {
|
||||
return $this->renderError('添加失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取分类列表
|
||||
$categories = FFCategories::where('status', 1)
|
||||
->order('sort_order', 'asc')
|
||||
->select();
|
||||
View::assign('categories', $categories);
|
||||
|
||||
return View::fetch('FFProducts/add');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$info = FFProducts::where('id', $id)->find();
|
||||
if (empty($info)) {
|
||||
return $this->renderError('数据不存在');
|
||||
}
|
||||
|
||||
if (request()->isPost()) {
|
||||
$param = input('post.');
|
||||
$validate = $this->validate($param, [
|
||||
'product_name' => 'require',
|
||||
'price' => 'require|float',
|
||||
'stock' => 'require|number',
|
||||
]);
|
||||
|
||||
if (true !== $validate) {
|
||||
return $this->renderError($validate);
|
||||
}
|
||||
|
||||
// 处理多选的分类,转换为逗号分隔的字符串
|
||||
if (isset($param['categories']) && is_array($param['categories'])) {
|
||||
$param['category_name'] = implode(',', $param['categories']);
|
||||
unset($param['categories']);
|
||||
}
|
||||
|
||||
$res = FFProducts::update($param, ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('编辑成功', ['url' => (string) url('ff_products')]);
|
||||
} else {
|
||||
return $this->renderError('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取分类列表
|
||||
$categories = FFCategories::where('status', 1)
|
||||
->order('sort_order', 'asc')
|
||||
->select()->toArray();
|
||||
|
||||
// 将已有的分类名称转为数组
|
||||
$selectedCategories = [];
|
||||
if ($info['category_name']) {
|
||||
$selectedCategories = explode(',', $info['category_name']);
|
||||
}
|
||||
|
||||
View::assign('categories', $categories);
|
||||
View::assign('selectedCategories', $selectedCategories);
|
||||
View::assign('info', $info);
|
||||
|
||||
return View::fetch('FFProducts/edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品状态(上架/下架)
|
||||
*/
|
||||
public function status()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$status = input('param.status', 0);
|
||||
|
||||
$res = FFProducts::update(['status' => $status], ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('操作成功');
|
||||
} else {
|
||||
return $this->renderError('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改热销状态
|
||||
*/
|
||||
public function hot()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$is_hot = input('param.is_hot', 0);
|
||||
|
||||
$res = FFProducts::update(['is_hot' => $is_hot], ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('操作成功');
|
||||
} else {
|
||||
return $this->renderError('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改新品状态
|
||||
*/
|
||||
public function new()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$is_new = input('param.is_new', 0);
|
||||
|
||||
$res = FFProducts::update(['is_new' => $is_new], ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('操作成功');
|
||||
} else {
|
||||
return $this->renderError('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改推荐状态
|
||||
*/
|
||||
public function recommend()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$is_recommend = input('param.is_recommend', 0);
|
||||
|
||||
$res = FFProducts::update(['is_recommend' => $is_recommend], ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('操作成功');
|
||||
} else {
|
||||
return $this->renderError('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$res = FFProducts::destroy($id);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('删除成功');
|
||||
} else {
|
||||
return $this->renderError('删除失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
185
app/admin/controller/NewsController.php
Normal file
185
app/admin/controller/NewsController.php
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use think\facade\View;
|
||||
use think\facade\Db;
|
||||
use app\common\model\News;
|
||||
|
||||
class NewsController extends Base
|
||||
{
|
||||
/**
|
||||
* 资讯列表
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$limit = input('param.limit', 15);
|
||||
$page = input('param.page', 1);
|
||||
$offset = ($page - 1) * $limit;
|
||||
$title = input('param.title', '');
|
||||
$status = input('param.status', '');
|
||||
|
||||
$where = [];
|
||||
if ($title) {
|
||||
$where[] = ['title', 'like', "%{$title}%"];
|
||||
}
|
||||
if ($status !== '') {
|
||||
$where[] = ['status', '=', $status];
|
||||
}
|
||||
|
||||
$res = News::where($where)
|
||||
->order('id', 'desc')
|
||||
->limit($offset, $limit)
|
||||
->select();
|
||||
|
||||
$total = News::where($where)->count();
|
||||
|
||||
return $this->renderTable('获取成功', $total, $res, 0);
|
||||
}
|
||||
|
||||
return View::fetch('News/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加资讯
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$param = input('post.');
|
||||
$validate = $this->validate($param, [
|
||||
'title' => 'require',
|
||||
// 'author_id' => 'require|number',
|
||||
]);
|
||||
|
||||
if (true !== $validate) {
|
||||
return $this->renderError($validate);
|
||||
}
|
||||
$param['author_id'] = 1;
|
||||
// 如果状态为发布,确保有发布时间
|
||||
if (isset($param['status']) && $param['status'] == 1 && empty($param['publish_time'])) {
|
||||
$param['publish_time'] = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
$res = News::create($param);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('添加成功', ['url' => (string) url('news')]);
|
||||
} else {
|
||||
return $this->renderError('添加失败');
|
||||
}
|
||||
}
|
||||
|
||||
return View::fetch('News/add');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑资讯
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$info = News::where('id', $id)->find();
|
||||
if (empty($info)) {
|
||||
return $this->renderError('数据不存在');
|
||||
}
|
||||
|
||||
if (request()->isPost()) {
|
||||
$param = input('post.');
|
||||
$validate = $this->validate($param, [
|
||||
'title' => 'require',
|
||||
// 'author_id' => 'require|number',
|
||||
]);
|
||||
|
||||
if (true !== $validate) {
|
||||
return $this->renderError($validate);
|
||||
}
|
||||
$param['author_id'] = 1;
|
||||
// 如果状态为发布,确保有发布时间
|
||||
if (isset($param['status']) && $param['status'] == 1 && empty($param['publish_time'])) {
|
||||
$param['publish_time'] = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
$res = News::update($param, ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('编辑成功', ['url' => (string) url('news')]);
|
||||
} else {
|
||||
return $this->renderError('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
View::assign('info', $info);
|
||||
return View::fetch('News/edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改资讯状态(发布/草稿)
|
||||
*/
|
||||
public function status()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$status = input('param.status', 0);
|
||||
|
||||
// 如果状态为发布,确保有发布时间
|
||||
$update = ['status' => $status];
|
||||
if ($status == 1) {
|
||||
$info = News::where('id', $id)->find();
|
||||
if (!$info->publish_time) {
|
||||
$update['publish_time'] = date('Y-m-d H:i:s');
|
||||
}
|
||||
}
|
||||
|
||||
$res = News::update($update, ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('操作成功');
|
||||
} else {
|
||||
return $this->renderError('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改热榜状态
|
||||
*/
|
||||
public function hot()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$is_hot = input('param.is_hot', 0);
|
||||
|
||||
$res = News::update(['is_hot' => $is_hot], ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('操作成功');
|
||||
} else {
|
||||
return $this->renderError('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改精选状态
|
||||
*/
|
||||
public function featured()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$is_featured = input('param.is_featured', 0);
|
||||
|
||||
$res = News::update(['is_featured' => $is_featured], ['id' => $id]);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('操作成功');
|
||||
} else {
|
||||
return $this->renderError('操作失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除资讯
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
$id = input('param.id', 0);
|
||||
$res = News::destroy($id);
|
||||
if ($res) {
|
||||
return $this->renderSuccess('删除成功');
|
||||
} else {
|
||||
return $this->renderError('删除失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ class Upload extends Base
|
|||
}
|
||||
|
||||
// 文件格式校验
|
||||
$ext = ['jpg', 'png', 'jpeg', 'JPG', 'PNG', 'JPEG', 'gif', 'apk', 'mp3'];
|
||||
$ext = ['jpg', 'png', 'jpeg', 'JPG', 'PNG', 'JPEG', 'gif', 'apk', 'mp3','webp','avif'];
|
||||
$type = substr($_FILES['file']['name'], strrpos($_FILES['file']['name'], '.') + 1);
|
||||
if (!in_array($type, $ext)) {
|
||||
return $this->renderError("文件格式错误");
|
||||
|
|
|
|||
|
|
@ -400,6 +400,17 @@ Route::rule('float_ball_edit', 'FloatBall/edit', 'GET|POST');
|
|||
Route::rule('float_ball_del', 'FloatBall/del', 'POST');
|
||||
Route::rule('float_ball_status', 'FloatBall/status', 'POST');
|
||||
|
||||
#============================
|
||||
#NewsController.php资讯管理
|
||||
#============================
|
||||
Route::rule('news', 'NewsController/index', 'GET|POST');
|
||||
Route::rule('news_add', 'NewsController/add', 'GET|POST');
|
||||
Route::rule('news_edit', 'NewsController/edit', 'GET|POST');
|
||||
Route::rule('news_del', 'NewsController/del', 'POST');
|
||||
Route::rule('news_status', 'NewsController/status', 'POST');
|
||||
Route::rule('news_hot', 'NewsController/hot', 'POST');
|
||||
Route::rule('news_featured', 'NewsController/featured', 'POST');
|
||||
|
||||
#============================
|
||||
#Reward.php奖励管理
|
||||
#============================
|
||||
|
|
@ -457,7 +468,7 @@ Route::rule('Statistics/getCurrencyInfoData', 'Statistics/getCurrencyInfoData',
|
|||
// 盒子下架日志相关路由
|
||||
Route::post('goods_offshelf_read', 'GoodsOffshelfController/read');
|
||||
Route::get('goods_offshelf_unread_count', 'GoodsOffshelfController/getUnreadCount');
|
||||
|
||||
|
||||
|
||||
#============================
|
||||
# dynamicJs
|
||||
|
|
@ -484,4 +495,25 @@ Route::rule('diamond_get_max_sort', 'Diamond/get_max_sort', 'GET');
|
|||
#VerificationCode.php 验证码管理
|
||||
#============================
|
||||
Route::rule('verification_code', 'VerificationCode/index', 'GET|POST');
|
||||
|
||||
|
||||
#============================
|
||||
#News.php 新闻管理
|
||||
#============================
|
||||
Route::rule('news', 'News/index', 'GET|POST');
|
||||
|
||||
#============================
|
||||
#FFProductsController.php商品分类管理
|
||||
#============================
|
||||
Route::rule('ff_categories', 'FFCategoriesController/index', 'GET|POST');
|
||||
Route::rule('ff_categories_add', 'FFCategoriesController/add', 'GET|POST');
|
||||
Route::rule('ff_categories_edit', 'FFCategoriesController/edit', 'GET|POST');
|
||||
Route::rule('ff_categories_del', 'FFCategoriesController/del', 'POST');
|
||||
Route::rule('ff_categories_status', 'FFCategoriesController/status', 'POST');
|
||||
Route::rule('ff_products', 'FFProductsController/index', 'GET|POST');
|
||||
Route::rule('ff_products_add', 'FFProductsController/add', 'GET|POST');
|
||||
Route::rule('ff_products_edit', 'FFProductsController/edit', 'GET|POST');
|
||||
Route::rule('ff_products_del', 'FFProductsController/del', 'POST');
|
||||
Route::rule('ff_products_status', 'FFProductsController/status', 'POST');
|
||||
Route::rule('ff_products_hot', 'FFProductsController/hot', 'POST');
|
||||
Route::rule('ff_products_new', 'FFProductsController/new', 'POST');
|
||||
Route::rule('ff_products_recommend', 'FFProductsController/recommend', 'POST');
|
||||
|
|
|
|||
78
app/admin/view/FFCategories/add.html
Normal file
78
app/admin/view/FFCategories/add.html
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
{include file="Public/header3" /}
|
||||
<div class="layui-form" style="width: 90%; margin: 0 auto; padding-top: 20px;">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类名称</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="category_name" id="category_name" autocomplete="off" placeholder="请输入分类名称" class="layui-input"
|
||||
lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">父级分类</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="parent_id" lay-filter="parent_id">
|
||||
<option value="0">顶级分类</option>
|
||||
{foreach $parentList as $parent}
|
||||
<option value="{$parent.id}">{$parent.category_name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort_order" id="sort_order" value="0" autocomplete="off" placeholder="请输入排序数值" class="layui-input">
|
||||
<div class="layui-form-mid layui-word-aux">数值越小越靠前</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="status" value="1" title="启用" checked>
|
||||
<input type="radio" name="status" value="0" title="禁用">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="saveBtn">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="Public/footer" /}
|
||||
<script>
|
||||
layui.use(['form', 'layer', 'jquery'], function () {
|
||||
var form = layui.form,
|
||||
layer = layui.layer,
|
||||
$ = layui.jquery;
|
||||
|
||||
// 表单提交
|
||||
form.on('submit(saveBtn)', function (data) {
|
||||
if (!data.field.category_name) {
|
||||
layer.msg('分类名称不能为空', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '{:url("/admin/ff_categories_add")}',
|
||||
type: 'POST',
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1, time: 1000 }, function () {
|
||||
parent.layui.table.reload('tableList');
|
||||
var iframeIndex = parent.layer.getFrameIndex(window.name);
|
||||
parent.layer.close(iframeIndex);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
85
app/admin/view/FFCategories/edit.html
Normal file
85
app/admin/view/FFCategories/edit.html
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
{include file="Public/header3" /}
|
||||
<div class="layui-form" style="width: 90%; margin: 0 auto; padding-top: 20px;">
|
||||
<input type="hidden" name="id" value="{$info.id}">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类名称</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="category_name" id="category_name" autocomplete="off" placeholder="请输入分类名称" class="layui-input"
|
||||
lay-verify="required" value="{$info.category_name}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">父级分类</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-form-mid">{if $info.parent_id == 0}顶级分类{else}父级ID:{$info.parent_id}{/if}</div>
|
||||
<div class="layui-form-mid layui-word-aux">为维护分类结构,不允许修改父级分类</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类层级</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-form-mid">
|
||||
{if $info.category_level == 1}一级分类{elseif $info.category_level == 2}二级分类{else}三级分类{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort_order" id="sort_order" value="{$info.sort_order}" autocomplete="off" placeholder="请输入排序数值" class="layui-input">
|
||||
<div class="layui-form-mid layui-word-aux">数值越小越靠前</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="status" value="1" title="启用" {if $info.status eq 1}checked{/if}>
|
||||
<input type="radio" name="status" value="0" title="禁用" {if $info.status eq 0}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="saveBtn">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="Public/footer" /}
|
||||
<script>
|
||||
layui.use(['form', 'layer', 'jquery'], function () {
|
||||
var form = layui.form,
|
||||
layer = layui.layer,
|
||||
$ = layui.jquery;
|
||||
|
||||
// 表单提交
|
||||
form.on('submit(saveBtn)', function (data) {
|
||||
if (!data.field.category_name) {
|
||||
layer.msg('分类名称不能为空', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '{:url("/admin/ff_categories_edit")}',
|
||||
type: 'POST',
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1, time: 1000 }, function () {
|
||||
parent.layui.table.reload('tableList');
|
||||
var iframeIndex = parent.layer.getFrameIndex(window.name);
|
||||
parent.layer.close(iframeIndex);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
179
app/admin/view/FFCategories/index.html
Normal file
179
app/admin/view/FFCategories/index.html
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
{include file="Public:header3"/}
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">商品分类管理</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form toolbar">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="searchCategoryName" placeholder="请输入分类名称" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<select id="searchStatus">
|
||||
<option value="">全部状态</option>
|
||||
<option value="0">禁用</option>
|
||||
<option value="1">启用</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn layui-btn-sm" id="btnSearch"><i
|
||||
class="layui-icon"></i>搜索</button>
|
||||
<button class="layui-btn layui-btn-sm" id="btnAdd"><i class="layui-icon"></i>添加</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table id="tableList" lay-filter="tableList"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格操作列 -->
|
||||
<script type="text/html" id="tableBar">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
|
||||
{{# if(d.status == 0){ }}
|
||||
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="enable">启用</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="disable">禁用</a>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<!-- 状态模板 -->
|
||||
<script type="text/html" id="statusTpl">
|
||||
{{# if(d.status == 1){ }}
|
||||
<span class="layui-badge layui-bg-green">启用</span>
|
||||
{{# }else{ }}
|
||||
<span class="layui-badge">禁用</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<!-- 分类层级模板 -->
|
||||
<script type="text/html" id="levelTpl">
|
||||
{{# if(d.category_level == 1){ }}
|
||||
<span>一级分类</span>
|
||||
{{# }else if(d.category_level == 2){ }}
|
||||
<span>二级分类</span>
|
||||
{{# }else if(d.category_level == 3){ }}
|
||||
<span>三级分类</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
{include file="Public/footer3" /}
|
||||
<script>
|
||||
layui.use(['table', 'form', 'jquery', 'layer', 'laydate'], function () {
|
||||
var $ = layui.jquery;
|
||||
var table = layui.table;
|
||||
var form = layui.form;
|
||||
var layer = layui.layer;
|
||||
var laydate = layui.laydate;
|
||||
|
||||
// 渲染表格
|
||||
var tableIns = table.render({
|
||||
elem: '#tableList',
|
||||
url: '{:url("/admin/ff_categories")}',
|
||||
page: true,
|
||||
cols: [[
|
||||
{ type: 'numbers', title: '序号', width: 60 },
|
||||
{ field: 'category_name', title: '分类名称', width: 200 },
|
||||
{ field: 'category_level', title: '分类层级', width: 100, templet: '#levelTpl' },
|
||||
{ field: 'parent_id', title: '父级ID', width: 100 },
|
||||
{ field: 'sort_order', title: '排序', width: 80 },
|
||||
{ field: 'status', title: '状态', width: 80, templet: '#statusTpl' },
|
||||
{
|
||||
field: 'create_time', title: '创建时间', width: 160, templet: function (d) {
|
||||
return layui.util.toDateString(new Date(d.create_time).getTime(), 'yyyy-MM-dd HH:mm:ss');
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'update_time', title: '更新时间', width: 160, templet: function (d) {
|
||||
return layui.util.toDateString(new Date(d.update_time).getTime(), 'yyyy-MM-dd HH:mm:ss');
|
||||
}
|
||||
},
|
||||
{ title: '操作', toolbar: '#tableBar', width: 200 }
|
||||
]],
|
||||
limits: [10, 15, 20, 25, 50, 100],
|
||||
limit: 15,
|
||||
text: {
|
||||
none: '暂无相关数据'
|
||||
}
|
||||
});
|
||||
|
||||
// 搜索按钮点击事件
|
||||
$('#btnSearch').click(function () {
|
||||
tableIns.reload({
|
||||
where: {
|
||||
category_name: $('#searchCategoryName').val(),
|
||||
status: $('#searchStatus').val()
|
||||
},
|
||||
page: {
|
||||
curr: 1
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 添加按钮点击事件
|
||||
$('#btnAdd').click(function () {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '添加商品分类',
|
||||
area: ['90%', '90%'],
|
||||
shade: 0.4,
|
||||
shadeClose: true,
|
||||
content: '{:url("/admin/ff_categories_add")}'
|
||||
});
|
||||
});
|
||||
|
||||
// 表格工具条点击事件
|
||||
table.on('tool(tableList)', function (obj) {
|
||||
var data = obj.data;
|
||||
var layEvent = obj.event;
|
||||
|
||||
if (layEvent === 'edit') {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '编辑商品分类',
|
||||
area: ['90%', '90%'],
|
||||
shade: 0.4,
|
||||
shadeClose: true,
|
||||
content: '{:url("/admin/ff_categories_edit")}?id=' + data.id
|
||||
});
|
||||
} else if (layEvent === 'del') {
|
||||
layer.confirm('确定要删除该分类吗?', function (i) {
|
||||
layer.close(i);
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_categories_del")}', { id: data.id }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
});
|
||||
} else if (layEvent === 'enable') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_categories_status")}', { id: data.id, status: 1 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'disable') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_categories_status")}', { id: data.id, status: 0 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
438
app/admin/view/FFProducts/add.html
Normal file
438
app/admin/view/FFProducts/add.html
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
{include file="Public/header3" /}
|
||||
<link href="https://unpkg.com/@wangeditor/editor@latest/dist/css/style.css" rel="stylesheet" />
|
||||
<style>
|
||||
#editor—wrapper {
|
||||
border: 1px solid #ccc;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#toolbar-container {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#editor-container {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.category-checkbox {
|
||||
display: inline-block;
|
||||
margin-right: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.custom-checkbox {
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.category-label {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid #e6e6e6;
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 5px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.category-label:hover {
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
|
||||
.category-label.checked {
|
||||
background-color: #009688;
|
||||
color: #fff;
|
||||
border-color: #009688;
|
||||
}
|
||||
</style>
|
||||
<div class="layui-form" style="width: 90%; margin: 0 auto; padding-top: 20px;">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品名称</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="product_name" id="product_name" autocomplete="off" placeholder="请输入商品名称"
|
||||
class="layui-input" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">所属分类</label>
|
||||
<div class="layui-input-block" id="categoriesContainer">
|
||||
{foreach $categories as $category}
|
||||
<label class="category-label">
|
||||
<input type="checkbox" lay-ignore class="custom-checkbox" name="categories[]"
|
||||
value="{$category.category_name}" style="display:none;">
|
||||
{$category.category_name}
|
||||
</label>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">商品价格</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="price" id="price" autocomplete="off" placeholder="请输入价格" class="layui-input"
|
||||
lay-verify="required|number">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">商品库存</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="stock" id="stock" autocomplete="off" placeholder="请输入库存" class="layui-input"
|
||||
lay-verify="required|number" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">剩余库存</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="sales" id="sales" autocomplete="off" placeholder="请输入初始销量" class="layui-input"
|
||||
value="0">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">封面图</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadCover">上传封面图</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="coverPreview" style="max-width: 200px; max-height: 150px;">
|
||||
</div>
|
||||
<input type="hidden" name="cover_image" id="cover_image" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情图片1</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadDetail1">上传详情图1</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="detail1Preview" style="max-width: 200px; max-height: 150px;">
|
||||
</div>
|
||||
<input type="hidden" name="detail_image1" id="detail_image1" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情图片2</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadDetail2">上传详情图2</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="detail2Preview" style="max-width: 200px; max-height: 150px;">
|
||||
</div>
|
||||
<input type="hidden" name="detail_image2" id="detail_image2" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情图片3</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadDetail3">上传详情图3</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="detail3Preview" style="max-width: 200px; max-height: 150px;">
|
||||
</div>
|
||||
<input type="hidden" name="detail_image3" id="detail_image3" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情图片4</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadDetail4">上传详情图4</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="detail4Preview" style="max-width: 200px; max-height: 150px;">
|
||||
</div>
|
||||
<input type="hidden" name="detail_image4" id="detail_image4" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品描述</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="product_desc" id="product_desc" placeholder="请输入商品描述" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情内容</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="editor—wrapper">
|
||||
<div id="toolbar-container"><!-- 工具栏 --></div>
|
||||
<div id="editor-container"><!-- 编辑器 --></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">商品状态</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="status" value="0" title="下架">
|
||||
<input type="radio" name="status" value="1" title="上架" checked>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">热销商品</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_hot" value="0" title="否" checked>
|
||||
<input type="radio" name="is_hot" value="1" title="是">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">新品</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_new" value="0" title="否">
|
||||
<input type="radio" name="is_new" value="1" title="是" checked>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">推荐</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_recommend" value="0" title="否">
|
||||
<input type="radio" name="is_recommend" value="1" title="是" checked>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="saveBtn">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="Public/footer" /}
|
||||
<script src="https://unpkg.com/@wangeditor/editor@latest/dist/index.js"></script>
|
||||
<script>
|
||||
const { createEditor, createToolbar } = window.wangEditor
|
||||
|
||||
const editorConfig = {
|
||||
placeholder: 'Type here...',
|
||||
onChange(editor) {
|
||||
const html = editor.getHtml()
|
||||
console.log('editor content', html)
|
||||
},
|
||||
MENU_CONF: {}
|
||||
}
|
||||
editorConfig.MENU_CONF['uploadImage'] = {
|
||||
customUpload: async (file, insertFn) => {
|
||||
console.log(file);
|
||||
|
||||
// 上传图片
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const res = await fetch('/admin/picture?dir=products', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
console.log("res", res);
|
||||
|
||||
const result = await res.json();
|
||||
|
||||
// 成功后插入图片
|
||||
insertFn(result.data.imgurl, '图片描述', result.data.imgurl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const editor = createEditor({
|
||||
selector: '#editor-container',
|
||||
html: '<p><br></p>',
|
||||
config: editorConfig,
|
||||
mode: 'default',
|
||||
})
|
||||
|
||||
const toolbarConfig = {}
|
||||
|
||||
const toolbar = createToolbar({
|
||||
editor,
|
||||
selector: '#toolbar-container',
|
||||
config: toolbarConfig,
|
||||
mode: 'default',
|
||||
})
|
||||
|
||||
layui.use(['form', 'upload', 'layer', 'laydate'], function () {
|
||||
var form = layui.form,
|
||||
layer = layui.layer,
|
||||
upload = layui.upload,
|
||||
$ = layui.jquery;
|
||||
|
||||
// 自定义复选框的点击事件
|
||||
$('.category-label').click(function () {
|
||||
// 获取隐藏的checkbox
|
||||
var checkbox = $(this).find('.custom-checkbox');
|
||||
|
||||
// 切换选中状态
|
||||
if (checkbox.prop('checked')) {
|
||||
checkbox.prop('checked', false);
|
||||
$(this).removeClass('checked');
|
||||
} else {
|
||||
checkbox.prop('checked', true);
|
||||
$(this).addClass('checked');
|
||||
}
|
||||
});
|
||||
|
||||
// 封面图上传
|
||||
upload.render({
|
||||
elem: '#uploadCover',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#coverPreview").attr("src", res.data.path);
|
||||
$("#cover_image").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 详情图1上传
|
||||
upload.render({
|
||||
elem: '#uploadDetail1',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#detail1Preview").attr("src", res.data.path);
|
||||
$("#detail_image1").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 详情图2上传
|
||||
upload.render({
|
||||
elem: '#uploadDetail2',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#detail2Preview").attr("src", res.data.path);
|
||||
$("#detail_image2").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 详情图3上传
|
||||
upload.render({
|
||||
elem: '#uploadDetail3',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#detail3Preview").attr("src", res.data.path);
|
||||
$("#detail_image3").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 详情图4上传
|
||||
upload.render({
|
||||
elem: '#uploadDetail4',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#detail4Preview").attr("src", res.data.path);
|
||||
$("#detail_image4").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 表单提交
|
||||
form.on('submit(saveBtn)', function (data) {
|
||||
// 获取富文本编辑器内容
|
||||
data.field.detail_html = editor.getHtml();
|
||||
|
||||
if (!data.field.product_name) {
|
||||
layer.msg('商品名称不能为空', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data.field.price) {
|
||||
layer.msg('商品价格不能为空', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否选择了分类
|
||||
var selectedCategories = [];
|
||||
$('.custom-checkbox:checked').each(function () {
|
||||
selectedCategories.push($(this).val());
|
||||
});
|
||||
|
||||
if (selectedCategories.length === 0) {
|
||||
layer.msg('请至少选择一个分类', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '{:url("/admin/ff_products_add")}',
|
||||
type: 'POST',
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1, time: 1000 }, function () {
|
||||
parent.layui.table.reload('tableList');
|
||||
var iframeIndex = parent.layer.getFrameIndex(window.name);
|
||||
parent.layer.close(iframeIndex);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
448
app/admin/view/FFProducts/edit.html
Normal file
448
app/admin/view/FFProducts/edit.html
Normal file
|
|
@ -0,0 +1,448 @@
|
|||
{include file="Public/header3" /}
|
||||
<link href="https://unpkg.com/@wangeditor/editor@latest/dist/css/style.css" rel="stylesheet" />
|
||||
<style>
|
||||
#editor—wrapper {
|
||||
border: 1px solid #ccc;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#toolbar-container {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#editor-container {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.category-checkbox {
|
||||
display: inline-block;
|
||||
margin-right: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.custom-checkbox {
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.category-label {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid #e6e6e6;
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 5px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.category-label:hover {
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
|
||||
.category-label.checked {
|
||||
background-color: #009688;
|
||||
color: #fff;
|
||||
border-color: #009688;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
|
||||
<div class="layui-form" style="width: 90%; margin: 0 auto; padding-top: 20px;">
|
||||
<input type="hidden" name="id" value="{$info.id}">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品名称</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="product_name" id="product_name" autocomplete="off" placeholder="请输入商品名称"
|
||||
class="layui-input" lay-verify="required" value="{$info.product_name}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">所属分类</label>
|
||||
<div class="layui-input-block" id="categoriesContainer">
|
||||
{foreach $categories as $category}
|
||||
<label class="category-label {if in_array($category.category_name, $selectedCategories)}checked{/if}">
|
||||
<input type="checkbox" lay-ignore class="custom-checkbox" name="categories[]" value="{$category.category_name}" style="display:none;" {if in_array($category.category_name, $selectedCategories)}checked{/if}>
|
||||
{$category.category_name}
|
||||
</label>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">商品价格</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="price" id="price" autocomplete="off" placeholder="请输入价格" class="layui-input"
|
||||
lay-verify="required|number" value="{$info.price}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">商品库存</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="stock" id="stock" autocomplete="off" placeholder="请输入库存" class="layui-input"
|
||||
lay-verify="required|number" value="{$info.stock}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">剩余库存</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="sales" id="sales" autocomplete="off" placeholder="请输入销量" class="layui-input"
|
||||
value="{$info.sales}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">封面图</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadCover">上传封面图</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="coverPreview" style="max-width: 200px; max-height: 150px;"
|
||||
src="{$info.cover_image}">
|
||||
</div>
|
||||
<input type="hidden" name="cover_image" id="cover_image" value="{$info.cover_image}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情图片1</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadDetail1">上传详情图1</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="detail1Preview" style="max-width: 200px; max-height: 150px;"
|
||||
src="{$info.detail_image1}">
|
||||
</div>
|
||||
<input type="hidden" name="detail_image1" id="detail_image1" value="{$info.detail_image1}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情图片2</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadDetail2">上传详情图2</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="detail2Preview" style="max-width: 200px; max-height: 150px;"
|
||||
src="{$info.detail_image2}">
|
||||
</div>
|
||||
<input type="hidden" name="detail_image2" id="detail_image2" value="{$info.detail_image2}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情图片3</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadDetail3">上传详情图3</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="detail3Preview" style="max-width: 200px; max-height: 150px;"
|
||||
src="{$info.detail_image3}">
|
||||
</div>
|
||||
<input type="hidden" name="detail_image3" id="detail_image3" value="{$info.detail_image3}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情图片4</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadDetail4">上传详情图4</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="detail4Preview" style="max-width: 200px; max-height: 150px;"
|
||||
src="{$info.detail_image4}">
|
||||
</div>
|
||||
<input type="hidden" name="detail_image4" id="detail_image4" value="{$info.detail_image4}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">商品描述</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="product_desc" id="product_desc" placeholder="请输入商品描述"
|
||||
class="layui-textarea">{$info.product_desc}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">详情内容</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="editor—wrapper">
|
||||
<div id="toolbar-container"><!-- 工具栏 --></div>
|
||||
<div id="editor-container"><!-- 编辑器 --></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">商品状态</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="status" value="0" title="下架" {if $info.status eq 0}checked{/if}>
|
||||
<input type="radio" name="status" value="1" title="上架" {if $info.status eq 1}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">热销商品</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_hot" value="0" title="否" {if $info.is_hot eq 0}checked{/if}>
|
||||
<input type="radio" name="is_hot" value="1" title="是" {if $info.is_hot eq 1}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">新品</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_new" value="0" title="否" {if $info.is_new eq 0}checked{/if}>
|
||||
<input type="radio" name="is_new" value="1" title="是" {if $info.is_new eq 1}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">推荐</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_recommend" value="0" title="否" {if $info.is_recommend eq 0}checked{/if}>
|
||||
<input type="radio" name="is_recommend" value="1" title="是" {if $info.is_recommend eq 1}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="saveBtn">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
{include file="Public/footer" /}
|
||||
<script src="https://unpkg.com/@wangeditor/editor@latest/dist/index.js"></script>
|
||||
<script>
|
||||
const { createEditor, createToolbar } = window.wangEditor
|
||||
|
||||
const editorConfig = {
|
||||
placeholder: 'Type here...',
|
||||
onChange(editor) {
|
||||
const html = editor.getHtml()
|
||||
console.log('editor content', html)
|
||||
},
|
||||
MENU_CONF: {}
|
||||
}
|
||||
editorConfig.MENU_CONF['uploadImage'] = {
|
||||
customUpload: async (file, insertFn) => {
|
||||
console.log(file);
|
||||
|
||||
// 上传图片
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const res = await fetch('/admin/picture?dir=products', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
console.log("res", res);
|
||||
|
||||
const result = await res.json();
|
||||
|
||||
// 成功后插入图片
|
||||
insertFn(result.data.imgurl, '图片描述', result.data.imgurl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const editor = createEditor({
|
||||
selector: '#editor-container',
|
||||
html: '{$info.detail_html|raw}',
|
||||
config: editorConfig,
|
||||
mode: 'default',
|
||||
})
|
||||
|
||||
const toolbarConfig = {}
|
||||
|
||||
const toolbar = createToolbar({
|
||||
editor,
|
||||
selector: '#toolbar-container',
|
||||
config: toolbarConfig,
|
||||
mode: 'default',
|
||||
})
|
||||
|
||||
layui.use(['form', 'upload', 'layer', 'laydate'], function () {
|
||||
var form = layui.form,
|
||||
layer = layui.layer,
|
||||
upload = layui.upload,
|
||||
$ = layui.jquery;
|
||||
|
||||
// 自定义复选框的点击事件
|
||||
$('.category-label').click(function() {
|
||||
// 获取隐藏的checkbox
|
||||
var checkbox = $(this).find('.custom-checkbox');
|
||||
|
||||
// 切换选中状态
|
||||
if(checkbox.prop('checked')) {
|
||||
checkbox.prop('checked', false);
|
||||
$(this).removeClass('checked');
|
||||
} else {
|
||||
checkbox.prop('checked', true);
|
||||
$(this).addClass('checked');
|
||||
}
|
||||
});
|
||||
|
||||
// 封面图上传
|
||||
upload.render({
|
||||
elem: '#uploadCover',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#coverPreview").attr("src", res.data.path);
|
||||
$("#cover_image").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 详情图1上传
|
||||
upload.render({
|
||||
elem: '#uploadDetail1',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#detail1Preview").attr("src", res.data.path);
|
||||
$("#detail_image1").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 详情图2上传
|
||||
upload.render({
|
||||
elem: '#uploadDetail2',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#detail2Preview").attr("src", res.data.path);
|
||||
$("#detail_image2").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 详情图3上传
|
||||
upload.render({
|
||||
elem: '#uploadDetail3',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#detail3Preview").attr("src", res.data.path);
|
||||
$("#detail_image3").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 详情图4上传
|
||||
upload.render({
|
||||
elem: '#uploadDetail4',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
data: {
|
||||
dir: 'products'
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#detail4Preview").attr("src", res.data.path);
|
||||
$("#detail_image4").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 表单提交
|
||||
form.on('submit(saveBtn)', function (data) {
|
||||
// 获取富文本编辑器内容
|
||||
data.field.detail_html = editor.getHtml();
|
||||
|
||||
if (!data.field.product_name) {
|
||||
layer.msg('商品名称不能为空', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data.field.price) {
|
||||
layer.msg('商品价格不能为空', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否选择了分类
|
||||
var selectedCategories = [];
|
||||
$('.custom-checkbox:checked').each(function() {
|
||||
selectedCategories.push($(this).val());
|
||||
});
|
||||
|
||||
if (selectedCategories.length === 0) {
|
||||
layer.msg('请至少选择一个分类', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '{:url("/admin/ff_products_edit")}',
|
||||
type: 'POST',
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1, time: 1000 }, function () {
|
||||
parent.layui.table.reload('tableList');
|
||||
var iframeIndex = parent.layer.getFrameIndex(window.name);
|
||||
parent.layer.close(iframeIndex);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
308
app/admin/view/FFProducts/index.html
Normal file
308
app/admin/view/FFProducts/index.html
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
{include file="Public:header3"/}
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">商品管理</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form toolbar">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="searchProductName" placeholder="请输入商品名称关键词" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="searchCategoryName" placeholder="请输入分类名称关键词" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<select id="searchStatus">
|
||||
<option value="">全部状态</option>
|
||||
<option value="0">下架</option>
|
||||
<option value="1">上架</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<select id="searchIsHot">
|
||||
<option value="">全部热销</option>
|
||||
<option value="0">非热销</option>
|
||||
<option value="1">热销</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<select id="searchIsNew">
|
||||
<option value="">全部新品</option>
|
||||
<option value="0">非新品</option>
|
||||
<option value="1">新品</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<select id="searchIsRecommend">
|
||||
<option value="">全部推荐</option>
|
||||
<option value="0">非推荐</option>
|
||||
<option value="1">推荐</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn layui-btn-sm" id="btnSearch"><i
|
||||
class="layui-icon"></i>搜索</button>
|
||||
<button class="layui-btn layui-btn-sm" id="btnAdd"><i class="layui-icon"></i>添加</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table id="tableList" lay-filter="tableList"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格操作列 -->
|
||||
<script type="text/html" id="tableBar">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
|
||||
{{# if(d.status == 0){ }}
|
||||
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="publish">上架</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="draft">下架</a>
|
||||
{{# } }}
|
||||
{{# if(d.is_hot == 0){ }}
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="setHot">设为热销</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="cancelHot">取消热销</a>
|
||||
{{# } }}
|
||||
{{# if(d.is_new == 0){ }}
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="setNew">设为新品</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="cancelNew">取消新品</a>
|
||||
{{# } }}
|
||||
{{# if(d.is_recommend == 0){ }}
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="setRecommend">设为推荐</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="cancelRecommend">取消推荐</a>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<!-- 状态模板 -->
|
||||
<script type="text/html" id="statusTpl">
|
||||
{{# if(d.status == 1){ }}
|
||||
<span class="layui-badge layui-bg-green">上架</span>
|
||||
{{# }else{ }}
|
||||
<span class="layui-badge">下架</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<!-- 热销模板 -->
|
||||
<script type="text/html" id="hotTpl">
|
||||
{{# if(d.is_hot == 1){ }}
|
||||
<span class="layui-badge layui-bg-orange">是</span>
|
||||
{{# }else{ }}
|
||||
<span>否</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<!-- 新品模板 -->
|
||||
<script type="text/html" id="newTpl">
|
||||
{{# if(d.is_new == 1){ }}
|
||||
<span class="layui-badge layui-bg-blue">是</span>
|
||||
{{# }else{ }}
|
||||
<span>否</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<!-- 推荐模板 -->
|
||||
<script type="text/html" id="recommendTpl">
|
||||
{{# if(d.is_recommend == 1){ }}
|
||||
<span class="layui-badge layui-bg-cyan">是</span>
|
||||
{{# }else{ }}
|
||||
<span>否</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
{include file="Public/footer3" /}
|
||||
<script>
|
||||
layui.use(['table', 'form', 'jquery', 'layer', 'laydate'], function () {
|
||||
var $ = layui.jquery;
|
||||
var table = layui.table;
|
||||
var form = layui.form;
|
||||
var layer = layui.layer;
|
||||
var laydate = layui.laydate;
|
||||
|
||||
// 渲染表格
|
||||
var tableIns = table.render({
|
||||
elem: '#tableList',
|
||||
url: '{:url("/admin/ff_products")}',
|
||||
page: true,
|
||||
cols: [[
|
||||
{ type: 'numbers', title: '序号', width: 60 },
|
||||
{ field: 'product_name', title: '商品名称', width: 180 },
|
||||
{ field: 'category_name', title: '分类', width: 150 },
|
||||
{
|
||||
field: 'cover_image', title: '封面图', width: 100, templet: function (d) {
|
||||
return d.cover_image ? '<img src="' + d.cover_image + '" style="max-height: 50px;">' : '';
|
||||
}
|
||||
},
|
||||
{ field: 'price', title: '价格', width: 100 },
|
||||
{ field: 'stock', title: '库存', width: 80 },
|
||||
{ field: 'sales', title: '销量', width: 80 },
|
||||
{ field: 'is_hot', title: '热销', width: 80, templet: '#hotTpl' },
|
||||
{ field: 'is_new', title: '新品', width: 80, templet: '#newTpl' },
|
||||
{ field: 'is_recommend', title: '推荐', width: 80, templet: '#recommendTpl' },
|
||||
{ field: 'status', title: '状态', width: 80, templet: '#statusTpl' },
|
||||
{
|
||||
field: 'create_time', title: '创建时间', width: 160, templet: function (d) {
|
||||
return layui.util.toDateString(new Date(d.create_time).getTime(), 'yyyy-MM-dd HH:mm:ss');
|
||||
}
|
||||
},
|
||||
{ title: '操作', toolbar: '#tableBar', width: 380 }
|
||||
]],
|
||||
limits: [10, 15, 20, 25, 50, 100],
|
||||
limit: 15,
|
||||
text: {
|
||||
none: '暂无相关数据'
|
||||
}
|
||||
});
|
||||
|
||||
// 搜索按钮点击事件
|
||||
$('#btnSearch').click(function () {
|
||||
tableIns.reload({
|
||||
where: {
|
||||
product_name: $('#searchProductName').val(),
|
||||
category_name: $('#searchCategoryName').val(),
|
||||
status: $('#searchStatus').val(),
|
||||
is_hot: $('#searchIsHot').val(),
|
||||
is_new: $('#searchIsNew').val(),
|
||||
is_recommend: $('#searchIsRecommend').val()
|
||||
},
|
||||
page: {
|
||||
curr: 1
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 添加按钮点击事件
|
||||
$('#btnAdd').click(function () {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '添加商品',
|
||||
area: ['90%', '90%'],
|
||||
shade: 0.4,
|
||||
shadeClose: false,
|
||||
content: '{:url("/admin/ff_products_add")}'
|
||||
});
|
||||
});
|
||||
|
||||
// 表格工具条点击事件
|
||||
table.on('tool(tableList)', function (obj) {
|
||||
var data = obj.data;
|
||||
var layEvent = obj.event;
|
||||
|
||||
if (layEvent === 'edit') {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '编辑商品',
|
||||
area: ['90%', '90%'],
|
||||
shade: 0.4,
|
||||
shadeClose: false,
|
||||
content: '{:url("/admin/ff_products_edit")}?id=' + data.id
|
||||
});
|
||||
} else if (layEvent === 'del') {
|
||||
layer.confirm('确定要删除该商品吗?', function (i) {
|
||||
layer.close(i);
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_products_del")}', { id: data.id }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
});
|
||||
} else if (layEvent === 'publish') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_products_status")}', { id: data.id, status: 1 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'draft') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_products_status")}', { id: data.id, status: 0 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'setHot') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_products_hot")}', { id: data.id, is_hot: 1 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'cancelHot') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_products_hot")}', { id: data.id, is_hot: 0 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'setNew') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_products_new")}', { id: data.id, is_new: 1 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'cancelNew') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_products_new")}', { id: data.id, is_new: 0 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'setRecommend') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_products_recommend")}', { id: data.id, is_recommend: 1 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'cancelRecommend') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/ff_products_recommend")}', { id: data.id, is_recommend: 0 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
218
app/admin/view/News/add.html
Normal file
218
app/admin/view/News/add.html
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
{include file="Public/header3" /}
|
||||
<link href="https://unpkg.com/@wangeditor/editor@latest/dist/css/style.css" rel="stylesheet" />
|
||||
<style>
|
||||
#editor—wrapper {
|
||||
border: 1px solid #ccc;
|
||||
z-index: 100;
|
||||
/* 按需定义 */
|
||||
}
|
||||
|
||||
#toolbar-container {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#editor-container {
|
||||
height: 500px;
|
||||
}
|
||||
</style>
|
||||
<div class="layui-form" style="width: 90%; margin: 0 auto; padding-top: 20px;">
|
||||
<div class="layui-form-item">
|
||||
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" id="title" autocomplete="off" placeholder="请输入资讯标题" class="layui-input"
|
||||
lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">封面图</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadCover">上传封面图</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="coverPreview" style="max-width: 200px; max-height: 150px;">
|
||||
</div>
|
||||
<input type="hidden" name="cover_image" id="cover_image" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">热榜</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_hot" value="0" title="否" checked>
|
||||
<input type="radio" name="is_hot" value="1" title="是">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">精选</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_featured" value="0" title="否">
|
||||
<input type="radio" name="is_featured" value="1" title="是" checked>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">内容详情</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="editor—wrapper">
|
||||
<div id="toolbar-container"><!-- 工具栏 --></div>
|
||||
<div id="editor-container"><!-- 编辑器 --></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">作者姓名</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="author_name" id="author_name" placeholder="请输入作者姓名" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="status" value="0" title="草稿">
|
||||
<input type="radio" name="status" value="1" title="发布" checked>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发布时间</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="publish_time" id="publish_time" autocomplete="off" placeholder="请选择发布时间"
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="saveBtn">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="Public/footer" /}
|
||||
<script src="https://unpkg.com/@wangeditor/editor@latest/dist/index.js"></script>
|
||||
<script>
|
||||
|
||||
const { createEditor, createToolbar } = window.wangEditor
|
||||
|
||||
const editorConfig = {
|
||||
placeholder: 'Type here...',
|
||||
onChange(editor) {
|
||||
const html = editor.getHtml()
|
||||
console.log('editor content', html)
|
||||
// 也可以同步到 <textarea>
|
||||
},
|
||||
MENU_CONF: {}
|
||||
}
|
||||
editorConfig.MENU_CONF['uploadImage'] = {
|
||||
customUpload: async (file, insertFn) => {
|
||||
console.log(file);
|
||||
|
||||
// 模拟上传到 COS 的过程
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const res = await fetch('/admin/picture?dir=news', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
console.log("resresresresres", res);
|
||||
|
||||
const result = await res.json();
|
||||
|
||||
// // 成功后插入图片
|
||||
insertFn(result.data.imgurl, '图片描述', result.data.imgurl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const editor = createEditor({
|
||||
selector: '#editor-container',
|
||||
html: '<p><br></p>',
|
||||
config: editorConfig,
|
||||
mode: 'default', // or 'simple'
|
||||
})
|
||||
|
||||
const toolbarConfig = {}
|
||||
|
||||
const toolbar = createToolbar({
|
||||
editor,
|
||||
selector: '#toolbar-container',
|
||||
config: toolbarConfig,
|
||||
mode: 'default', // or 'simple'
|
||||
})
|
||||
|
||||
layui.use(['form', 'upload', 'layer', 'laydate'], function () {
|
||||
var form = layui.form,
|
||||
layer = layui.layer,
|
||||
upload = layui.upload,
|
||||
laydate = layui.laydate,
|
||||
// layedit = layui.layedit,
|
||||
$ = layui.jquery;
|
||||
|
||||
// 初始化日期选择器
|
||||
laydate.render({
|
||||
elem: '#publish_time',
|
||||
type: 'datetime',
|
||||
value: new Date()
|
||||
});
|
||||
|
||||
|
||||
// 上传封面图
|
||||
upload.render({
|
||||
elem: '#uploadCover',
|
||||
url: '/admin/picture',
|
||||
accept: "file",
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#coverPreview").attr("src", res.data.path);
|
||||
$("#cover_image").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 表单提交
|
||||
form.on('submit(saveBtn)', function (data) {
|
||||
// 同步富文本编辑器内容
|
||||
data.field.content = editor.getHtml();
|
||||
|
||||
if (!data.field.title) {
|
||||
layer.msg('标题不能为空', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 如果发布状态为"发布"且未设置发布时间,则设置为当前时间
|
||||
if (data.field.status == 1 && !data.field.publish_time) {
|
||||
data.field.publish_time = layui.util.toDateString(new Date(), 'yyyy-MM-dd HH:mm:ss');
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '{:url("/admin/news_add")}',
|
||||
type: 'POST',
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1, time: 1000 }, function () {
|
||||
parent.layui.table.reload('tableList');
|
||||
var iframeIndex = parent.layer.getFrameIndex(window.name);
|
||||
parent.layer.close(iframeIndex);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
225
app/admin/view/News/edit.html
Normal file
225
app/admin/view/News/edit.html
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
{include file="Public/header3" /}
|
||||
<link href="https://unpkg.com/@wangeditor/editor@latest/dist/css/style.css" rel="stylesheet" />
|
||||
<style>
|
||||
#editor—wrapper {
|
||||
border: 1px solid #ccc;
|
||||
z-index: 100;
|
||||
/* 按需定义 */
|
||||
}
|
||||
|
||||
#toolbar-container {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#editor-container {
|
||||
height: 500px;
|
||||
}
|
||||
</style>
|
||||
<div class="layui-form" style="width: 90%; margin: 0 auto; padding-top: 20px;">
|
||||
<input type="hidden" name="id" value="{$info.id}">
|
||||
|
||||
<div class="layui-form-item">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" id="title" autocomplete="off" placeholder="请输入资讯标题" class="layui-input"
|
||||
lay-verify="required" value="{$info.title}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">封面图</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="uploadCover">上传封面图</button>
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="coverPreview" style="max-width: 200px; max-height: 150px;"
|
||||
src="{$info.cover_image}">
|
||||
</div>
|
||||
<input type="hidden" name="cover_image" id="cover_image" value="{$info.cover_image}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">热榜</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_hot" value="0" title="否" {if $info.is_hot eq 0}checked{/if}>
|
||||
<input type="radio" name="is_hot" value="1" title="是" {if $info.is_hot eq 1}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">精选</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="is_featured" value="0" title="否" {if $info.is_featured eq 0}checked{/if}>
|
||||
<input type="radio" name="is_featured" value="1" title="是" {if $info.is_featured eq 1}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">内容详情</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="editor—wrapper">
|
||||
<div id="toolbar-container"><!-- 工具栏 --></div>
|
||||
<div id="editor-container"><!-- 编辑器 --></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">作者姓名</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="author_name" id="author_name" placeholder="请输入作者姓名" class="layui-input"
|
||||
value="{$info.author_name}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="status" value="0" title="草稿" {if $info.status eq 0}checked{/if}>
|
||||
<input type="radio" name="status" value="1" title="发布" {if $info.status eq 1}checked{/if}>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发布时间</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="publish_time" id="publish_time" autocomplete="off" placeholder="请选择发布时间"
|
||||
class="layui-input" value="{$info.publish_time}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="saveBtn">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="Public/footer" /}
|
||||
<script src="https://unpkg.com/@wangeditor/editor@latest/dist/index.js"></script>
|
||||
<script>
|
||||
|
||||
const { createEditor, createToolbar } = window.wangEditor
|
||||
|
||||
const editorConfig = {
|
||||
placeholder: 'Type here...',
|
||||
onChange(editor) {
|
||||
const html = editor.getHtml()
|
||||
console.log('editor content', html)
|
||||
// 也可以同步到 <textarea>
|
||||
},
|
||||
MENU_CONF: {}
|
||||
}
|
||||
editorConfig.MENU_CONF['uploadImage'] = {
|
||||
customUpload: async (file, insertFn) => {
|
||||
console.log(file);
|
||||
|
||||
// 模拟上传到 COS 的过程
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const res = await fetch('/admin/picture?dir=news', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
console.log("resresresresres", res);
|
||||
|
||||
const result = await res.json();
|
||||
|
||||
// // 成功后插入图片
|
||||
insertFn(result.data.imgurl, '图片描述', result.data.imgurl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const editor = createEditor({
|
||||
selector: '#editor-container',
|
||||
html: '{$info.content|raw}',
|
||||
config: editorConfig,
|
||||
mode: 'default', // or 'simple'
|
||||
})
|
||||
|
||||
const toolbarConfig = {}
|
||||
|
||||
const toolbar = createToolbar({
|
||||
editor,
|
||||
selector: '#toolbar-container',
|
||||
config: toolbarConfig,
|
||||
mode: 'default', // or 'simple'
|
||||
})
|
||||
|
||||
layui.use(['form', 'upload', 'layer', 'laydate'], function () {
|
||||
var form = layui.form,
|
||||
layer = layui.layer,
|
||||
upload = layui.upload,
|
||||
laydate = layui.laydate,
|
||||
$ = layui.jquery;
|
||||
|
||||
// 初始化日期选择器
|
||||
laydate.render({
|
||||
elem: '#publish_time',
|
||||
type: 'datetime',
|
||||
value: new Date()
|
||||
});
|
||||
|
||||
// 上传封面图
|
||||
upload.render({
|
||||
elem: '#uploadCover',
|
||||
accept: "file",
|
||||
url: '/admin/picture',
|
||||
done: function (res) {
|
||||
if (res.status == 1) {
|
||||
layer.msg("上传成功", { icon: 1, time: 1000 }, function () {
|
||||
$("#coverPreview").attr("src", res.data.path);
|
||||
$("#cover_image").val(res.data.imgurl);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
layer.msg('服务繁忙,请稍后再试', { icon: 2, anim: 6, time: 1500 });
|
||||
}
|
||||
});
|
||||
|
||||
// 表单提交
|
||||
form.on('submit(saveBtn)', function (data) {
|
||||
// 同步富文本编辑器内容
|
||||
data.field.content = editor.getHtml();
|
||||
|
||||
if (!data.field.title) {
|
||||
layer.msg('标题不能为空', { icon: 2 });
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 如果发布状态为"发布"且未设置发布时间,则设置为当前时间
|
||||
if (data.field.status == 1 && !data.field.publish_time) {
|
||||
data.field.publish_time = layui.util.toDateString(new Date(), 'yyyy-MM-dd HH:mm:ss');
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '{:url("/admin/news_edit")}',
|
||||
type: 'POST',
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1, time: 1000 }, function () {
|
||||
parent.layui.table.reload('tableList');
|
||||
var iframeIndex = parent.layer.getFrameIndex(window.name);
|
||||
parent.layer.close(iframeIndex);
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
245
app/admin/view/News/index.html
Normal file
245
app/admin/view/News/index.html
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
{include file="Public:header3"/}
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">资讯管理</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-form toolbar">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="searchTitle" placeholder="请输入标题关键词" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<select id="searchStatus">
|
||||
<option value="">全部状态</option>
|
||||
<option value="0">草稿</option>
|
||||
<option value="1">已发布</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn layui-btn-sm" id="btnSearch"><i
|
||||
class="layui-icon"></i>搜索</button>
|
||||
<button class="layui-btn layui-btn-sm" id="btnAdd"><i class="layui-icon"></i>添加</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table id="tableList" lay-filter="tableList"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格操作列 -->
|
||||
<script type="text/html" id="tableBar">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
|
||||
{{# if(d.status == 0){ }}
|
||||
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="publish">发布</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="draft">下架</a>
|
||||
{{# } }}
|
||||
{{# if(d.is_hot == 0){ }}
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="setHot">设为热榜</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="cancelHot">取消热榜</a>
|
||||
{{# } }}
|
||||
{{# if(d.is_featured == 0){ }}
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="setFeatured">设为精选</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="cancelFeatured">取消精选</a>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<!-- 状态模板 -->
|
||||
<script type="text/html" id="statusTpl">
|
||||
{{# if(d.status == 1){ }}
|
||||
<span class="layui-badge layui-bg-green">已发布</span>
|
||||
{{# }else{ }}
|
||||
<span class="layui-badge">草稿</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<!-- 热榜模板 -->
|
||||
<script type="text/html" id="hotTpl">
|
||||
{{# if(d.is_hot == 1){ }}
|
||||
<span class="layui-badge layui-bg-orange">是</span>
|
||||
{{# }else{ }}
|
||||
<span>否</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<!-- 精选模板 -->
|
||||
<script type="text/html" id="featuredTpl">
|
||||
{{# if(d.is_featured == 1){ }}
|
||||
<span class="layui-badge layui-bg-blue">是</span>
|
||||
{{# }else{ }}
|
||||
<span>否</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
{include file="Public/footer3" /}
|
||||
<script>
|
||||
layui.use(['table', 'form', 'jquery', 'layer', 'laydate'], function () {
|
||||
var $ = layui.jquery;
|
||||
var table = layui.table;
|
||||
var form = layui.form;
|
||||
var layer = layui.layer;
|
||||
var laydate = layui.laydate;
|
||||
|
||||
// 渲染表格
|
||||
var tableIns = table.render({
|
||||
elem: '#tableList',
|
||||
url: '{:url("/admin/news")}',
|
||||
page: true,
|
||||
cols: [[
|
||||
{ type: 'numbers', title: '序号', width: 60 },
|
||||
{ field: 'title', title: '标题', width: 200 },
|
||||
{
|
||||
field: 'cover_image', title: '封面图', width: 100, templet: function (d) {
|
||||
return d.cover_image ? '<img src="' + d.cover_image + '" style="max-height: 50px;">' : '';
|
||||
}
|
||||
},
|
||||
{ field: 'author_name', title: '作者', width: 100 },
|
||||
{
|
||||
field: 'publish_time', title: '发布时间', width: 160, templet: function (d) {
|
||||
return d.publish_time ? layui.util.toDateString(new Date(d.publish_time).getTime(), 'yyyy-MM-dd HH:mm:ss') : '';
|
||||
}
|
||||
},
|
||||
{ field: 'is_hot', title: '热榜', width: 80, templet: '#hotTpl' },
|
||||
{ field: 'is_featured', title: '精选', width: 80, templet: '#featuredTpl' },
|
||||
{ field: 'status', title: '状态', width: 80, templet: '#statusTpl' },
|
||||
{
|
||||
field: 'create_time', title: '创建时间', width: 160, templet: function (d) {
|
||||
return layui.util.toDateString(new Date(d.create_time).getTime(), 'yyyy-MM-dd HH:mm:ss');
|
||||
}
|
||||
},
|
||||
{ title: '操作', toolbar: '#tableBar', width: 380 }
|
||||
]],
|
||||
limits: [10, 15, 20, 25, 50, 100],
|
||||
limit: 15,
|
||||
text: {
|
||||
none: '暂无相关数据'
|
||||
}
|
||||
});
|
||||
|
||||
// 搜索按钮点击事件
|
||||
$('#btnSearch').click(function () {
|
||||
tableIns.reload({
|
||||
where: {
|
||||
title: $('#searchTitle').val(),
|
||||
status: $('#searchStatus').val()
|
||||
},
|
||||
page: {
|
||||
curr: 1
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 添加按钮点击事件
|
||||
$('#btnAdd').click(function () {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '添加资讯',
|
||||
area: ['90%', '90%'],
|
||||
shade: 0.4,
|
||||
shadeClose: true,
|
||||
content: '{:url("/admin/news_add")}'
|
||||
});
|
||||
});
|
||||
|
||||
// 表格工具条点击事件
|
||||
table.on('tool(tableList)', function (obj) {
|
||||
var data = obj.data;
|
||||
var layEvent = obj.event;
|
||||
|
||||
if (layEvent === 'edit') {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '编辑资讯',
|
||||
area: ['90%', '90%'],
|
||||
shade: 0.4,
|
||||
shadeClose: true,
|
||||
content: '{:url("/admin/news_edit")}?id=' + data.id
|
||||
});
|
||||
} else if (layEvent === 'del') {
|
||||
layer.confirm('确定要删除该资讯吗?', function (i) {
|
||||
layer.close(i);
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/news_del")}', { id: data.id }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
});
|
||||
} else if (layEvent === 'publish') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/news_status")}', { id: data.id, status: 1 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'draft') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/news_status")}', { id: data.id, status: 0 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'setHot') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/news_hot")}', { id: data.id, is_hot: 1 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'cancelHot') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/news_hot")}', { id: data.id, is_hot: 0 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'setFeatured') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/news_featured")}', { id: data.id, is_featured: 1 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
} else if (layEvent === 'cancelFeatured') {
|
||||
layer.load(2);
|
||||
$.post('{:url("/admin/news_featured")}', { id: data.id, is_featured: 0 }, function (res) {
|
||||
layer.closeAll('loading');
|
||||
if (res.status) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
tableIns.reload();
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}, 'json');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
declare (strict_types = 1);
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\api\controller;
|
||||
use app\api\controller\Base;
|
||||
|
|
@ -18,7 +18,7 @@ use \think\Request;
|
|||
|
||||
class Coupon extends Base
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* 首页优惠券列表
|
||||
* @param Request $request [description]
|
||||
* @param [type] 类型 1 推荐 2 预售 3 现货 4 一番赏 5 双随机 6售罄
|
||||
|
|
@ -26,72 +26,74 @@ class Coupon extends Base
|
|||
public function index(Request $request)
|
||||
{
|
||||
$is_use_coupon = $this->getUserid1();
|
||||
|
||||
if(!$is_use_coupon){
|
||||
#领过,之后不再弹出
|
||||
$data['status'] = 2;
|
||||
return $this->renderSuccess("",$data);
|
||||
|
||||
if (!$is_use_coupon) {
|
||||
#领过,之后不再弹出
|
||||
$data['status'] = 2;
|
||||
return $this->renderSuccess("", $data);
|
||||
}
|
||||
$whe = [];
|
||||
$whe[]=['status','=',0];
|
||||
$whe[]=['type','=',1];
|
||||
$whe[] = ['status', '=', 0];
|
||||
$whe[] = ['type', '=', 1];
|
||||
$field = "id,title,price,man_price,effective_day";
|
||||
$order = "id desc";
|
||||
$goods = Couponmodel::getList($whe,$field,$order,1000);
|
||||
return $this->renderSuccess('请求成功',compact('goods'));
|
||||
$goods = Couponmodel::getList($whe, $field, $order, 1000);
|
||||
return $this->renderSuccess('请求成功', compact('goods'));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
一键领取
|
||||
*/
|
||||
public function receive(Request $request){
|
||||
$user = $this->getUser();
|
||||
$coupon_id = $request->param('coupon_id');
|
||||
if(empty($coupon_id)){
|
||||
public function receive(Request $request)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$coupon_id = $request->param('coupon_id');
|
||||
if (empty($coupon_id)) {
|
||||
return $this->renderError("缺少必要参数");
|
||||
}
|
||||
$is_find = CouponReceivemodel::where(['user_id'=>$user->id])->whereIn('coupon_id',$coupon_id)->find();
|
||||
if(!empty($is_find)){
|
||||
return $this->renderError("已经领取过了,无法在领取");
|
||||
}
|
||||
$coupon_id = explode(',',$coupon_id);
|
||||
$coupon_id = array_filter($coupon_id);
|
||||
|
||||
$num = count($coupon_id);
|
||||
for($i=0;$i<$num;$i++){
|
||||
$coupon_info = Couponmodel::find($coupon_id[$i]);
|
||||
if(!empty($coupon_info)){
|
||||
|
||||
}
|
||||
$is_find = CouponReceivemodel::where(['user_id' => $user->id])->whereIn('coupon_id', $coupon_id)->find();
|
||||
if (!empty($is_find)) {
|
||||
return $this->renderError("已经领取过了,无法在领取");
|
||||
}
|
||||
$coupon_id = explode(',', $coupon_id);
|
||||
$coupon_id = array_filter($coupon_id);
|
||||
|
||||
$num = count($coupon_id);
|
||||
for ($i = 0; $i < $num; $i++) {
|
||||
$coupon_info = Couponmodel::find($coupon_id[$i]);
|
||||
if (!empty($coupon_info)) {
|
||||
|
||||
$res[] = CouponReceivemodel::insert(
|
||||
[
|
||||
|
||||
'user_id'=>$user->id,
|
||||
'title'=>$coupon_info['title'],
|
||||
'price'=>$coupon_info['price'],
|
||||
'man_price'=>$coupon_info['man_price'],
|
||||
'end_time'=>$coupon_info['effective_day']*86400 + time(),
|
||||
'addtime'=>time(),
|
||||
'coupon_id'=>$coupon_info['id'],
|
||||
'state'=> $coupon_info['ttype']
|
||||
|
||||
]
|
||||
|
||||
[
|
||||
|
||||
'user_id' => $user->id,
|
||||
'title' => $coupon_info['title'],
|
||||
'price' => $coupon_info['price'],
|
||||
'man_price' => $coupon_info['man_price'],
|
||||
'end_time' => $coupon_info['effective_day'] * 86400 + time(),
|
||||
'addtime' => time(),
|
||||
'coupon_id' => $coupon_info['id'],
|
||||
'state' => $coupon_info['ttype']
|
||||
|
||||
]
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
#user表里is_use_coupon 值为1说明是领过优惠券
|
||||
$res[] = User::where(['id'=>$user['id'],'is_use_coupon'=>0])->update(['is_use_coupon'=>1]);
|
||||
if(resCheck($res)){
|
||||
return $this->renderSuccess("领取成功");
|
||||
}else{
|
||||
return $this->renderError("购买失败,请刷新重试");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#user表里is_use_coupon 值为1说明是领过优惠券
|
||||
$res[] = User::where(['id' => $user['id'], 'is_use_coupon' => 0])->update(['is_use_coupon' => 1]);
|
||||
if (resCheck($res)) {
|
||||
return $this->renderSuccess("领取成功");
|
||||
} else {
|
||||
return $this->renderError("购买失败,请刷新重试");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//可使用的优惠券
|
||||
public function used(Request $request){
|
||||
public function used(Request $request)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$total_price = $request->param('total_price');
|
||||
$type = $request->param('type');
|
||||
|
|
@ -99,69 +101,134 @@ class Coupon extends Base
|
|||
$status = $request->param('status');
|
||||
$state = $request->param('state');
|
||||
$page = $request->param('page');
|
||||
CouponReceivemodel::where(['user_id'=>$user->id,'status'=>0])->where('end_time','<=',time())->update(['status'=>2]);
|
||||
CouponReceivemodel::where(['user_id' => $user->id, 'status' => 0])->where('end_time', '<=', time())->update(['status' => 2]);
|
||||
#根据有效期时间改变一下状态
|
||||
if($type == 1){
|
||||
if ($type == 1) {
|
||||
#从个人中心进
|
||||
if($type1 == 1){
|
||||
#可用
|
||||
$whe[] = ['status', '=', $status];
|
||||
}else{
|
||||
#不可用
|
||||
$whe[] = ['status', '>', 0];
|
||||
if ($type1 == 1) {
|
||||
#可用
|
||||
$whe[] = ['status', '=', $status];
|
||||
} else {
|
||||
#不可用
|
||||
$whe[] = ['status', '>', 0];
|
||||
}
|
||||
$coupon_receive = CouponReceivemodel::where(['user_id'=>$user->id])->where($whe)->paginate(10)->each(function ($itme) {
|
||||
$itme['end_time'] = date('Y-m-d',$itme['end_time']);
|
||||
if($itme['status']== 1){
|
||||
$itme['mark']= "已使用";
|
||||
}elseif($itme['status']== 2){
|
||||
$itme['mark']= "已过期";
|
||||
}elseif($itme['status']== 0){
|
||||
$itme['mark']= "去使用";
|
||||
|
||||
$coupon_receive = CouponReceivemodel::where(['user_id' => $user->id])->where($whe)->paginate(10)->each(function ($itme) {
|
||||
$itme['end_time'] = date('Y-m-d', $itme['end_time']);
|
||||
if ($itme['status'] == 1) {
|
||||
$itme['mark'] = "已使用";
|
||||
} elseif ($itme['status'] == 2) {
|
||||
$itme['mark'] = "已过期";
|
||||
} elseif ($itme['status'] == 0) {
|
||||
$itme['mark'] = "去使用";
|
||||
|
||||
}
|
||||
return $itme;
|
||||
return $itme;
|
||||
});
|
||||
}else{
|
||||
} else {
|
||||
#从计算金额里面进
|
||||
if(empty($total_price)){
|
||||
if (empty($total_price)) {
|
||||
return $this->renderError("缺少必要参数");
|
||||
}
|
||||
if($type1 == 1){
|
||||
$whe = 'user_id='.$user->id.' and status=0 and man_price<='.$total_price;
|
||||
if ($type1 == 1) {
|
||||
$whe = 'user_id=' . $user->id . ' and status=0 and man_price<=' . $total_price;
|
||||
$whe1 = '';
|
||||
}else{
|
||||
$whe = 'user_id='.$user->id.' and status>0';
|
||||
$whe1 = 'user_id='.$user->id.' and status=0 and man_price>'.$total_price;
|
||||
} else {
|
||||
$whe = 'user_id=' . $user->id . ' and status>0';
|
||||
$whe1 = 'user_id=' . $user->id . ' and status=0 and man_price>' . $total_price;
|
||||
}
|
||||
|
||||
|
||||
#不可用(包括 已使用,未使用(金额不足,已过期))
|
||||
$coupon_receive = CouponReceivemodel::where($whe)->whereOr($whe1)
|
||||
->paginate(10)->each(function ($val) use ($total_price){
|
||||
$val['end_time'] = date('Y-m-d',$val['end_time']);
|
||||
if($val['status']== 1){
|
||||
$val['mark']= "已使用";
|
||||
}elseif($val['status']== 2){
|
||||
$val['mark']= "已过期";
|
||||
}elseif($val['status']== 0){
|
||||
if($val['man_price'] > $total_price){
|
||||
$val['mark']= "未满足";
|
||||
}else{
|
||||
$val['mark']= "去使用";
|
||||
->paginate(10)->each(function ($val) use ($total_price) {
|
||||
$val['end_time'] = date('Y-m-d', $val['end_time']);
|
||||
if ($val['status'] == 1) {
|
||||
$val['mark'] = "已使用";
|
||||
} elseif ($val['status'] == 2) {
|
||||
$val['mark'] = "已过期";
|
||||
} elseif ($val['status'] == 0) {
|
||||
if ($val['man_price'] > $total_price) {
|
||||
$val['mark'] = "未满足";
|
||||
} else {
|
||||
$val['mark'] = "去使用";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $val;
|
||||
});
|
||||
return $val;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
$new_data = [
|
||||
'data' => $coupon_receive->items(),
|
||||
'last_page' => $coupon_receive->lastPage(),
|
||||
];
|
||||
|
||||
return $this->renderSuccess('请求成功',$new_data);
|
||||
|
||||
return $this->renderSuccess('请求成功', $new_data);
|
||||
}
|
||||
|
||||
|
||||
public function get_coupon_list(Request $request)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$total_price = $request->param('total_price');
|
||||
$type = $request->param('type');
|
||||
$status = $request->param('status');
|
||||
$page = $request->param('page');
|
||||
$limit = $this->request->param('limit', 10);
|
||||
CouponReceivemodel::where(['user_id' => $user->id, 'status' => 0])->where('end_time', '<=', time())->update(['status' => 2]);
|
||||
#根据有效期时间改变一下状态
|
||||
if ($type == 1) {
|
||||
#从个人中心进
|
||||
$whe[] = ['status', '=', $status];
|
||||
$coupon_receive = CouponReceivemodel::where(['user_id' => $user->id])->where($whe)
|
||||
->field('id,title,price,man_price,status,end_time,coupon_id')
|
||||
->paginate(['list_rows' => $limit, 'query' => request()->param()])->
|
||||
each(function ($itme) {
|
||||
$itme['end_time'] = date('Y-m-d', $itme['end_time']);
|
||||
if ($itme['status'] == 1) {
|
||||
$itme['mark'] = "已使用";
|
||||
} elseif ($itme['status'] == 2) {
|
||||
$itme['mark'] = "已过期";
|
||||
} elseif ($itme['status'] == 0) {
|
||||
$itme['mark'] = "去使用";
|
||||
}
|
||||
return $itme;
|
||||
});
|
||||
} else {
|
||||
#从计算金额里面进
|
||||
if (empty($total_price)) {
|
||||
return $this->renderError("缺少必要参数");
|
||||
}
|
||||
$whe = 'user_id=' . $user->id . ' and status=0 and man_price<=' . $total_price;
|
||||
$whe1 = '';
|
||||
|
||||
#不可用(包括 已使用,未使用(金额不足,已过期))
|
||||
$coupon_receive = CouponReceivemodel::where($whe)->whereOr($whe1)
|
||||
->paginate(10)->each(function ($val) use ($total_price) {
|
||||
$val['end_time'] = date('Y-m-d', $val['end_time']);
|
||||
if ($val['status'] == 1) {
|
||||
$val['mark'] = "已使用";
|
||||
} elseif ($val['status'] == 2) {
|
||||
$val['mark'] = "已过期";
|
||||
} elseif ($val['status'] == 0) {
|
||||
if ($val['man_price'] > $total_price) {
|
||||
$val['mark'] = "未满足";
|
||||
} else {
|
||||
$val['mark'] = "去使用";
|
||||
}
|
||||
}
|
||||
return $val;
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
$new_data = [
|
||||
'list' => $coupon_receive->items(),
|
||||
'last_page' => $coupon_receive->lastPage(),
|
||||
];
|
||||
|
||||
return $this->renderSuccess('请求成功', $new_data);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
707
app/api/controller/FFOrdersController.php
Normal file
707
app/api/controller/FFOrdersController.php
Normal file
|
|
@ -0,0 +1,707 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\api\controller\Base;
|
||||
use app\common\model\FFProducts;
|
||||
use app\common\model\UserAddress;
|
||||
use app\common\model\CouponReceive;
|
||||
use app\common\server\platform\PlatformFactory;
|
||||
|
||||
class FFOrdersController extends Base
|
||||
{
|
||||
public function createOrder()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
$product_id = $this->request->param('product_id', 0);
|
||||
$address_id = $this->request->param('address_id', 0);
|
||||
$coupon_id = $this->request->param('coupon_id', 0);
|
||||
// $total_price = $this->request->param('total_price', 0);
|
||||
if (empty($product_id) || empty($address_id)) {
|
||||
return $this->renderError('缺少必要参数');
|
||||
}
|
||||
$product = FFProducts::where('id', $product_id)->find();
|
||||
if (!$product) {
|
||||
return $this->renderError('商品不存在');
|
||||
}
|
||||
$address = UserAddress::where('id', $address_id)->find();
|
||||
if (!$address) {
|
||||
return $this->renderError('地址不存在');
|
||||
}
|
||||
$coupon = null;
|
||||
if ($coupon_id > 0) {
|
||||
$coupon = CouponReceive::where('id', $coupon_id)->find();
|
||||
if (!$coupon) {
|
||||
return $this->renderError('优惠券不存在');
|
||||
}
|
||||
}
|
||||
//$user, $price, $title, $attach, $pre = "MH_", $pay_type = 1, $client = null
|
||||
$total_price = $product['price'];
|
||||
if ($coupon) {
|
||||
$total_price = $total_price - $coupon['price'];
|
||||
}
|
||||
$user = $this->getUser();
|
||||
$payRes = PlatformFactory::createPay($user, $total_price, $product['product_name'], 'order_product', 'YS_', 1);
|
||||
if ($payRes['status'] !== 1) {
|
||||
return $this->renderError("购买失败,请稍后再试");
|
||||
}
|
||||
//使用优惠卷
|
||||
if ($coupon) {
|
||||
$coupon['status'] = 1;
|
||||
$coupon->save();
|
||||
}
|
||||
# 订单号
|
||||
$order_num = $payRes['data']['order_no'];
|
||||
$receiver_name = $address['receiver_name'];
|
||||
$receiver_phone = $address['receiver_phone'];
|
||||
$receiver_address = $address['detailed_address'];
|
||||
|
||||
# 保存到ff_orders 表
|
||||
$orderData = [
|
||||
'order_no' => $order_num,
|
||||
'user_id' => $user_id,
|
||||
'product_id' => $product_id,
|
||||
'total_amount' => $product['price'],
|
||||
'payment_amount' => $total_price,
|
||||
'discount_amount' => $coupon ? $coupon['price'] : 0,
|
||||
'payment_type' => 1, // 假设这里是微信支付
|
||||
'order_status' => 0, // 待支付
|
||||
'pay_status' => 0, // 未支付
|
||||
'shipping_status' => 0, // 未发货
|
||||
'receiver_name' => $receiver_name,
|
||||
'receiver_phone' => $receiver_phone,
|
||||
'receiver_address' => $receiver_address,
|
||||
'source' => 2, // APP来源
|
||||
'create_time' => date('Y-m-d H:i:s')
|
||||
];
|
||||
|
||||
// 将该用户的所有未支付订单状态变成已取消
|
||||
\app\common\model\FFOrders::where([
|
||||
'user_id' => $user_id,
|
||||
'order_status' => 0, // 待支付
|
||||
'pay_status' => 0 // 未支付
|
||||
])->update([
|
||||
'order_status' => 5, // 已取消
|
||||
'cancel_time' => date('Y-m-d H:i:s') // 取消时间
|
||||
]);
|
||||
|
||||
// 创建订单
|
||||
$order = new \app\common\model\FFOrders();
|
||||
$result = $order->save($orderData);
|
||||
|
||||
if (!$result) {
|
||||
return $this->renderError('订单创建失败');
|
||||
}
|
||||
|
||||
return $this->renderSuccess('订单创建成功', [
|
||||
'order_no' => $order_num,
|
||||
'user_info' => ['is_test' => $user['istest']],
|
||||
'payment_data' => $payRes['data']['res']
|
||||
]);
|
||||
}
|
||||
|
||||
public function orderPaySuccess()
|
||||
{
|
||||
$order_no = $this->request->param('order_no', '');
|
||||
if (empty($order_no)) {
|
||||
return $this->renderError('订单号不能为空');
|
||||
}
|
||||
|
||||
// 根据订单号查询订单
|
||||
$order = \app\common\model\FFOrders::where('order_no', $order_no)->find();
|
||||
if (!$order) {
|
||||
return $this->renderError('订单不存在');
|
||||
}
|
||||
|
||||
// 判断订单状态,避免重复处理
|
||||
if ($order['pay_status'] == 2) {
|
||||
return $this->renderSuccess('订单已支付', ['order_no' => $order_no]);
|
||||
}
|
||||
|
||||
// 查询订单对应的商品信息
|
||||
$product_id = $order['product_id'];
|
||||
$product = FFProducts::where('id', $product_id)->find();
|
||||
if (!$product) {
|
||||
return $this->renderError('商品不存在');
|
||||
}
|
||||
|
||||
// 开启事务
|
||||
\think\facade\Db::startTrans();
|
||||
try {
|
||||
// 扣减库存
|
||||
if ($product['stock'] > 0) {
|
||||
$product->sales = $product['sales'] - 1; // 增加销量
|
||||
$product->save();
|
||||
} else {
|
||||
throw new \Exception('商品库存不足');
|
||||
}
|
||||
|
||||
// 更新订单状态
|
||||
$order->order_status = 2; // 已支付待发货
|
||||
$order->pay_status = 2; // 已支付
|
||||
$order->shipping_status = 1; // 未发货
|
||||
$order->shipping_company = '京东快递'; // 快递公司
|
||||
$order->shipping_no = "TEST_" . time();//TEST_开头
|
||||
$order->shipping_time = date('Y-m-d H:i:s'); // 发货时间
|
||||
$order->payment_time = date('Y-m-d H:i:s'); // 支付时间
|
||||
$order->payment_no = $this->request->param('payment_no', ''); // 支付流水号
|
||||
|
||||
// 保存订单
|
||||
if (!$order->save()) {
|
||||
throw new \Exception('订单状态更新失败');
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
\think\facade\Db::commit();
|
||||
|
||||
return $this->renderSuccess('购买成功', [
|
||||
'order_no' => $order_no,
|
||||
'order_status' => $order->order_status,
|
||||
'pay_status' => $order->pay_status
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// 回滚事务
|
||||
\think\facade\Db::rollback();
|
||||
return $this->renderError('支付处理失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getOrderList()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 接收参数
|
||||
$status = $this->request->param('status', 0); // 订单状态,0表示全部
|
||||
$keyword = $this->request->param('keyword', ''); // 商品标题搜索关键词
|
||||
$page = (int) $this->request->param('page', 1);
|
||||
$limit = (int) $this->request->param('limit', 10);
|
||||
|
||||
// 构建查询条件
|
||||
$where = [
|
||||
'user_id' => $user_id,
|
||||
'delete_status' => 0
|
||||
];
|
||||
|
||||
// 初始化查询对象
|
||||
$query = \app\common\model\FFOrders::alias('o');
|
||||
|
||||
// 根据状态筛选
|
||||
if ($status > 0) {
|
||||
if ($status == 4) {
|
||||
// 当status为4时,查询状态为6和7的订单(申请售后和退款售后成功)
|
||||
$query = $query->where($where)
|
||||
->where('o.order_status', 'in', [6, 7]);
|
||||
} else {
|
||||
// 其他状态正常查询
|
||||
$query = $query->where($where)
|
||||
->where('o.order_status', $status);
|
||||
}
|
||||
} else {
|
||||
// status为0时查询所有订单
|
||||
$query = $query->where($where);
|
||||
}
|
||||
|
||||
// 如果有搜索关键词,则需要联表查询
|
||||
if (!empty($keyword)) {
|
||||
// 通过product_id关联FFProducts表
|
||||
$query = $query->join('ff_products p', 'o.product_id = p.id')
|
||||
->where('p.product_name', 'like', "%{$keyword}%");
|
||||
}
|
||||
|
||||
// 排序方式 - 最新订单在前
|
||||
$query = $query->order('o.create_time desc');
|
||||
|
||||
// 分页查询
|
||||
$count = $query->count();
|
||||
$list = $query->page($page, $limit)->select();
|
||||
|
||||
// 处理结果
|
||||
$result = [];
|
||||
foreach ($list as $order) {
|
||||
// 获取商品信息
|
||||
$product = \app\common\model\FFProducts::where('id', $order['product_id'])->find();
|
||||
|
||||
$item = [
|
||||
'order_id' => $order['order_id'],
|
||||
'order_no' => $order['order_no'],
|
||||
'product_id' => $product ? $product['id'] : '', //
|
||||
'product_cover' => $product ? $product['cover_image'] : '', // 商品封面图
|
||||
'product_title' => $product ? $product['product_name'] : '', // 商品标题
|
||||
'payment_amount' => $order['payment_amount'], // 支付金额
|
||||
'payment_time' => $order['payment_time'] ?: '', // 支付时间
|
||||
'order_status' => $order['order_status'], // 订单状态
|
||||
'order_status_text' => $this->getOrderStatusText($order['order_status']), // 订单状态文本
|
||||
'create_time' => $order['create_time'], // 创建时间
|
||||
'receive_time' => $order['receive_time'] ?: '', // 收货时间
|
||||
'is_invoice' => $order['invoice_title'] == '' ? 0 : 1, // 是否开票
|
||||
];
|
||||
|
||||
$result[] = $item;
|
||||
}
|
||||
|
||||
return $this->renderSuccess('获取成功', [
|
||||
'total' => $count,
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
'list' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单状态文本
|
||||
* @param int $status 订单状态
|
||||
* @return string 状态文本
|
||||
*/
|
||||
private function getOrderStatusText($status)
|
||||
{
|
||||
$statusArr = [
|
||||
0 => '待支付',
|
||||
1 => '已支付待发货',
|
||||
2 => '已发货',
|
||||
3 => '已完成',
|
||||
4 => '已关闭',
|
||||
5 => '已取消',
|
||||
6 => '申请售后',
|
||||
7 => '售后结束'
|
||||
];
|
||||
|
||||
return isset($statusArr[$status]) ? $statusArr[$status] : '未知状态';
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单收货接口
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function orderReceive()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 接收订单编号参数
|
||||
$order_no = $this->request->param('order_no', '');
|
||||
if (empty($order_no)) {
|
||||
return $this->renderError('订单编号不能为空');
|
||||
}
|
||||
|
||||
// 查询订单
|
||||
$order = \app\common\model\FFOrders::where([
|
||||
'order_no' => $order_no,
|
||||
'user_id' => $user_id
|
||||
])->find();
|
||||
|
||||
if (!$order) {
|
||||
return $this->renderError('订单不存在或不属于当前用户');
|
||||
}
|
||||
|
||||
// 判断订单状态是否为已发货
|
||||
if ($order['order_status'] != 2) {
|
||||
return $this->renderError('只有已发货的订单才能确认收货');
|
||||
}
|
||||
|
||||
// 更新订单状态和收货时间
|
||||
$order->order_status = 3; // 已完成
|
||||
$order->receive_time = date('Y-m-d H:i:s'); // 收货时间
|
||||
|
||||
// 保存订单
|
||||
if ($order->save()) {
|
||||
return $this->renderSuccess('确认收货成功', [
|
||||
'order_no' => $order_no,
|
||||
'order_status' => $order->order_status,
|
||||
'order_status_text' => $this->getOrderStatusText($order->order_status),
|
||||
'receive_time' => $order->receive_time
|
||||
]);
|
||||
} else {
|
||||
return $this->renderError('确认收货失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请售后接口
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function applyRefund()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 接收参数
|
||||
$order_no = $this->request->param('order_no', '');
|
||||
$extend_info = $this->request->param('extend_info', '');
|
||||
|
||||
if (empty($order_no)) {
|
||||
return $this->renderError('订单编号不能为空');
|
||||
}
|
||||
|
||||
// 查询订单
|
||||
$order = \app\common\model\FFOrders::where([
|
||||
'order_no' => $order_no,
|
||||
'user_id' => $user_id
|
||||
])->find();
|
||||
|
||||
if (!$order) {
|
||||
return $this->renderError('订单不存在或不属于当前用户');
|
||||
}
|
||||
|
||||
// 判断订单状态是否可申请售后
|
||||
if ($order['order_status'] == 0 || $order['order_status'] == 4 || $order['order_status'] == 5 || $order['order_status'] == 6 || $order['order_status'] == 7) {
|
||||
return $this->renderError('当前订单状态不可申请售后');
|
||||
}
|
||||
|
||||
try {
|
||||
// 将当前订单状态保存到扩展信息中
|
||||
$extendData = json_decode($extend_info, true) ?: [];
|
||||
$extendData['original_status'] = $order['order_status'];
|
||||
|
||||
// 更新订单状态和扩展信息
|
||||
$order->order_status = 6; // 申请退款
|
||||
$order->extend_info = json_encode($extendData);
|
||||
|
||||
// 保存订单
|
||||
if ($order->save()) {
|
||||
return $this->renderSuccess('申请售后成功', [
|
||||
'order_no' => $order_no,
|
||||
'order_status' => $order->order_status,
|
||||
'order_status_text' => $this->getOrderStatusText($order->order_status)
|
||||
]);
|
||||
} else {
|
||||
return $this->renderError('申请售后失败');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->renderError('申请售后失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消售后接口
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function cancelRefund()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 接收参数
|
||||
$order_no = $this->request->param('order_no', '');
|
||||
|
||||
if (empty($order_no)) {
|
||||
return $this->renderError('订单编号不能为空');
|
||||
}
|
||||
|
||||
// 查询订单
|
||||
$order = \app\common\model\FFOrders::where([
|
||||
'order_no' => $order_no,
|
||||
'user_id' => $user_id
|
||||
])->find();
|
||||
|
||||
if (!$order) {
|
||||
return $this->renderError('订单不存在或不属于当前用户');
|
||||
}
|
||||
|
||||
// 判断订单状态是否为申请退款
|
||||
if ($order['order_status'] != 6) {
|
||||
return $this->renderError('只有申请退款状态的订单才能取消售后');
|
||||
}
|
||||
|
||||
try {
|
||||
// 从扩展信息中读取原始状态
|
||||
$extendInfo = $order['extend_info'] ? json_decode($order['extend_info'], true) : [];
|
||||
$originalStatus = isset($extendInfo['original_status']) ? $extendInfo['original_status'] : 3; // 默认为已完成
|
||||
|
||||
// 移除原始状态信息
|
||||
if (isset($extendInfo['original_status'])) {
|
||||
unset($extendInfo['original_status']);
|
||||
}
|
||||
|
||||
// 更新订单状态和扩展信息
|
||||
$order->order_status = $originalStatus;
|
||||
$order->extend_info = !empty($extendInfo) ? json_encode($extendInfo) : '';
|
||||
|
||||
// 保存订单
|
||||
if ($order->save()) {
|
||||
return $this->renderSuccess('取消售后成功', [
|
||||
'order_no' => $order_no,
|
||||
'order_status' => $order->order_status,
|
||||
'order_status_text' => $this->getOrderStatusText($order->order_status)
|
||||
]);
|
||||
} else {
|
||||
return $this->renderError('取消售后失败');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->renderError('取消售后失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除订单接口
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function deleteOrder()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 接收订单编号参数
|
||||
$order_no = $this->request->param('order_no', '');
|
||||
|
||||
if (empty($order_no)) {
|
||||
return $this->renderError('订单编号不能为空');
|
||||
}
|
||||
|
||||
// 查询订单
|
||||
$order = \app\common\model\FFOrders::where([
|
||||
'order_no' => $order_no,
|
||||
'user_id' => $user_id,
|
||||
'delete_status' => 0 // 未删除的订单
|
||||
])->find();
|
||||
|
||||
if (!$order) {
|
||||
return $this->renderError('订单不存在或不属于当前用户');
|
||||
}
|
||||
|
||||
// 判断订单状态是否可删除
|
||||
// 通常只有已完成(3)、已关闭(4)、已取消(5)、退款成功(7)的订单可以删除
|
||||
$allowDeleteStatus = [3, 4, 5, 7];
|
||||
if (!in_array($order['order_status'], $allowDeleteStatus)) {
|
||||
return $this->renderError('当前订单状态不允许删除');
|
||||
}
|
||||
|
||||
try {
|
||||
// 更新订单删除状态
|
||||
$order->delete_status = 1; // 标记为已删除
|
||||
|
||||
// 保存订单
|
||||
if ($order->save()) {
|
||||
return $this->renderSuccess('订单删除成功');
|
||||
} else {
|
||||
return $this->renderError('订单删除失败');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->renderError('订单删除失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单详情接口
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getOrderDetail()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 接收订单编号参数
|
||||
$order_no = $this->request->param('order_no', '');
|
||||
|
||||
if (empty($order_no)) {
|
||||
return $this->renderError('订单编号不能为空');
|
||||
}
|
||||
|
||||
// 查询订单
|
||||
$order = \app\common\model\FFOrders::where([
|
||||
'order_no' => $order_no,
|
||||
'user_id' => $user_id,
|
||||
'delete_status' => 0 // 未删除的订单
|
||||
])->find();
|
||||
|
||||
if (!$order) {
|
||||
return $this->renderError('订单不存在或不属于当前用户');
|
||||
}
|
||||
|
||||
// 查询关联商品
|
||||
$product = \app\common\model\FFProducts::where('id', $order['product_id'])->find();
|
||||
|
||||
// 组装订单详情数据
|
||||
$orderDetail = [
|
||||
// 商品信息
|
||||
'product_id' => $product ? $product['id'] : '',
|
||||
'product_cover' => $product ? $product['cover_image'] : '',
|
||||
'product_title' => $product ? $product['product_name'] : '',
|
||||
'product_price' => $product ? $product['price'] : 0.00,
|
||||
|
||||
// 订单信息
|
||||
'order_id' => $order['order_id'],
|
||||
'order_no' => $order['order_no'],
|
||||
'total_amount' => $order['total_amount'], // 订单总金额
|
||||
'payment_amount' => $order['payment_amount'], // 实际支付金额
|
||||
'discount_amount' => $order['discount_amount'], // 优惠金额
|
||||
'shipping_fee' => $order['shipping_fee'], // 运费
|
||||
'order_status' => $order['order_status'],
|
||||
'order_status_text' => $this->getOrderStatusText($order['order_status']),
|
||||
'pay_status' => $order['pay_status'],
|
||||
'payment_type' => $order['payment_type'], // 支付方式
|
||||
|
||||
// 物流信息
|
||||
'shipping_company' => $order['shipping_company'] ?: '',
|
||||
'shipping_no' => $order['shipping_no'] ?: '',
|
||||
'create_time' => $order['create_time'], // 下单时间
|
||||
'shipping_time' => $order['shipping_time'] ?: '', // 发货时间
|
||||
'receive_time' => $order['receive_time'] ?: '', // 收货时间
|
||||
'payment_time' => $order['payment_time'] ?: '', // 支付时间
|
||||
|
||||
// 收货人信息
|
||||
'receiver_name' => $order['receiver_name'],
|
||||
'receiver_phone' => $order['receiver_phone'],
|
||||
'receiver_address' => $order['receiver_address'],
|
||||
|
||||
// 发票信息
|
||||
'invoice_title' => $order['invoice_title'] ?: '',
|
||||
'invoice_content' => $order['invoice_content'] ?: '',
|
||||
'invoice_type' => $order['invoice_type'],
|
||||
'invoice_type_text' => $order['invoice_type'] == 1 ? '个人' : ($order['invoice_type'] == 2 ? '企业' : ''),
|
||||
|
||||
// 扩展信息
|
||||
'extend_info' => $order['extend_info'] ? json_decode($order['extend_info'], true) : []
|
||||
];
|
||||
|
||||
return $this->renderSuccess('获取成功', $orderDetail);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请发票接口
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function applyInvoice()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 接收参数
|
||||
$order_no = $this->request->param('order_no', '');
|
||||
$invoice_title = $this->request->param('invoice_title', '');
|
||||
$invoice_content = $this->request->param('invoice_content', '');
|
||||
$invoice_type = (int) $this->request->param('invoice_type', 1); // 默认个人
|
||||
$user_email = $this->request->param('user_email', ''); // 用户邮箱,不存储
|
||||
|
||||
// 参数验证
|
||||
if (empty($order_no)) {
|
||||
return $this->renderError('订单编号不能为空');
|
||||
}
|
||||
|
||||
if (empty($invoice_title)) {
|
||||
return $this->renderError('发票抬头不能为空');
|
||||
}
|
||||
|
||||
if (empty($invoice_content)) {
|
||||
return $this->renderError('发票内容不能为空');
|
||||
}
|
||||
|
||||
if (!in_array($invoice_type, [1, 2])) {
|
||||
return $this->renderError('发票类型不正确');
|
||||
}
|
||||
|
||||
if (empty($user_email)) {
|
||||
return $this->renderError('用户邮箱不能为空');
|
||||
}
|
||||
|
||||
// 邮箱格式验证
|
||||
if (!filter_var($user_email, FILTER_VALIDATE_EMAIL)) {
|
||||
return $this->renderError('邮箱格式不正确');
|
||||
}
|
||||
|
||||
// 查询订单
|
||||
$order = \app\common\model\FFOrders::where([
|
||||
'order_no' => $order_no,
|
||||
'user_id' => $user_id,
|
||||
'delete_status' => 0 // 未删除的订单
|
||||
])->find();
|
||||
|
||||
if (!$order) {
|
||||
return $this->renderError('订单不存在或不属于当前用户');
|
||||
}
|
||||
|
||||
// 验证订单状态,通常只有已支付的订单才能申请发票
|
||||
if ($order['pay_status'] != 2) { // 2表示已支付
|
||||
return $this->renderError('只有已支付的订单才能申请发票');
|
||||
}
|
||||
|
||||
try {
|
||||
// 更新订单发票信息
|
||||
$order->invoice_title = $invoice_title;
|
||||
$order->invoice_content = $invoice_content;
|
||||
$order->invoice_type = $invoice_type;
|
||||
|
||||
// 保存订单
|
||||
if ($order->save()) {
|
||||
return $this->renderSuccess('发票申请成功', true);
|
||||
} else {
|
||||
return $this->renderError('发票申请失败');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->renderError('发票申请失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户订单统计数据
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getOrderStatistics()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
try {
|
||||
// 查询条件 - 用户ID和未删除
|
||||
$where = [
|
||||
'user_id' => $user_id,
|
||||
'delete_status' => 0
|
||||
];
|
||||
|
||||
// 查询待发货订单数量 - 订单状态为1(已支付待发货)
|
||||
$waitingShipCount = \app\common\model\FFOrders::where($where)
|
||||
->where('order_status', 1)
|
||||
->count();
|
||||
|
||||
// 查询待收货订单数量 - 订单状态为2(已发货)
|
||||
$waitingReceiveCount = \app\common\model\FFOrders::where($where)
|
||||
->where('order_status', 2)
|
||||
->count();
|
||||
|
||||
// 查询已收货订单数量 - 订单状态为3(已完成)
|
||||
$receivedCount = \app\common\model\FFOrders::where($where)
|
||||
->where('order_status', 3)
|
||||
->count();
|
||||
|
||||
// 查询申请售后订单数量 - 订单状态为6(申请售后)和7(售后结束)
|
||||
$afterSalesCount = \app\common\model\FFOrders::where($where)
|
||||
->where('order_status', 'in', [6])
|
||||
->count();
|
||||
|
||||
// 返回统计结果
|
||||
return $this->renderSuccess('获取成功', [
|
||||
'waiting_ship_count' => $waitingShipCount, // 待发货数量
|
||||
'waiting_receive_count' => $waitingReceiveCount, // 待收货数量
|
||||
'received_count' => $receivedCount, // 已收货数量
|
||||
'after_sales_count' => $afterSalesCount // 申请售后数量
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->renderError('获取订单统计数据失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
260
app/api/controller/FFProductsController.php
Normal file
260
app/api/controller/FFProductsController.php
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\api\controller\Base;
|
||||
use app\common\model\FFProducts;
|
||||
use app\common\model\UserAddress;
|
||||
use app\common\model\CouponReceive;
|
||||
use app\common\model\FFFavorites;
|
||||
class FFProductsController extends Base
|
||||
{
|
||||
/**
|
||||
* 获取精选新闻列表
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getBannerList()
|
||||
{
|
||||
$bannerList = FFProducts::where('is_hot', '=', 1)->
|
||||
field('id,product_name as title,cover_image as image,price,stock,sales')
|
||||
->select()->toArray();
|
||||
return $this->renderSuccess('', $bannerList);
|
||||
}
|
||||
|
||||
public function getProductList()
|
||||
{
|
||||
$page = intval($this->request->param('page', 1));
|
||||
$limit = intval($this->request->param('limit', 10));
|
||||
$title = $this->request->param('title', '');
|
||||
$productData = FFProducts::where('is_hot', '=', 0);
|
||||
if ($title) {
|
||||
$productData->where('product_name', 'like', '%' . $title . '%');
|
||||
}
|
||||
$list = $productData->
|
||||
field('id,product_name as title,cover_image as image,price,stock,sales')
|
||||
->order(['is_new' => 'desc', 'id' => 'desc'])
|
||||
->page($page, $limit)
|
||||
->select()->toArray();
|
||||
|
||||
return $this->renderSuccess('', $list);
|
||||
}
|
||||
|
||||
public function getProductDetail()
|
||||
{
|
||||
$id = $this->request->param('id', 0);
|
||||
$productDetail = FFProducts::where('id', '=', $id)
|
||||
->field('id,product_name as title,cover_image as image,price,stock,sales,product_desc,detail_image1,detail_image2,detail_image3,detail_image4,detail_html,is_hot,is_new,is_recommend')->find();
|
||||
if (!$productDetail) {
|
||||
return $this->renderError('商品不存在');
|
||||
}
|
||||
$productDetail['detail_image'] = [
|
||||
$productDetail['detail_image1'],
|
||||
$productDetail['detail_image2'],
|
||||
$productDetail['detail_image3'],
|
||||
$productDetail['detail_image4']
|
||||
];
|
||||
$productDetail['detail_image'] = array_filter($productDetail['detail_image'], function ($value) {
|
||||
return !empty($value);
|
||||
});
|
||||
unset(
|
||||
$productDetail['detail_image1'],
|
||||
$productDetail['detail_image2'],
|
||||
$productDetail['detail_image3'],
|
||||
$productDetail['detail_image4']
|
||||
);
|
||||
if ($this->getUserId() > 0) {
|
||||
$productDetail['is_favorite'] = FFFavorites::isFavorite($this->getUserId(), $id);
|
||||
}
|
||||
|
||||
return $this->renderSuccess('', $productDetail);
|
||||
}
|
||||
|
||||
public function PayByOrder()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
$productId = $this->request->param('product_id', 0);
|
||||
$productDetail = FFProducts::where('id', '=', $productId)->find();
|
||||
if (!$productDetail) {
|
||||
return $this->renderError('商品不存在');
|
||||
}
|
||||
if ($productDetail['sales'] <= 0) {
|
||||
return $this->renderError('库存不足');
|
||||
}
|
||||
|
||||
// 查询默认地址
|
||||
$address = UserAddress::where('user_id', $user_id)
|
||||
->where('is_default', 1)
|
||||
->where('is_deleted', 0)
|
||||
->field('id,receiver_name,receiver_phone,detailed_address,is_default')
|
||||
->find();
|
||||
|
||||
if (!$address) {
|
||||
// 如果没有默认地址,返回最新添加的一条
|
||||
$address = UserAddress::where('user_id', $user_id)
|
||||
->where('is_deleted', 0)
|
||||
->field('id,receiver_name,receiver_phone,detailed_address,is_default')
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
}
|
||||
$whe = 'user_id=' . $user_id . ' and status=0 and man_price<=' . $productDetail['price'];
|
||||
$coupon = CouponReceive::where($whe)
|
||||
->field('id,title,man_price,price,end_time,status')
|
||||
->select()->toArray();
|
||||
$order = [
|
||||
'product_id' => $productId,
|
||||
'title' => $productDetail['product_name'],
|
||||
'image' => $productDetail['cover_image'],
|
||||
'price' => $productDetail['price'],
|
||||
'coupon' => $coupon,
|
||||
'default_address' => $address,
|
||||
];
|
||||
return $this->renderSuccess('', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户收藏商品列表
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getFavoriteList()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
$page = intval($this->request->param('page', 1));
|
||||
$limit = intval($this->request->param('limit', 10));
|
||||
|
||||
// 使用模型静态方法获取收藏列表
|
||||
$favoriteList = FFFavorites::getUserFavoriteList($user_id, $page, $limit);
|
||||
|
||||
// 格式化数据
|
||||
$result = [];
|
||||
foreach ($favoriteList as $item) {
|
||||
if (isset($item['product']) && $item['product']) {
|
||||
$result[] = [
|
||||
'id' => $item['product']['id'],
|
||||
'title' => $item['product']['product_name'],
|
||||
'image' => $item['product']['cover_image'],
|
||||
'price' => $item['product']['price'],
|
||||
'stock' => $item['product']['stock'],
|
||||
'sales' => $item['product']['sales'],
|
||||
'favorite_time' => $item['create_time']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->renderSuccess('', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品收藏
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function addFavorite()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
$product_id = intval($this->request->param('product_id', 0));
|
||||
if (!$product_id) {
|
||||
return $this->renderError('商品ID不能为空');
|
||||
}
|
||||
|
||||
// 检查商品是否存在
|
||||
$product = FFProducts::where('id', $product_id)->find();
|
||||
if (!$product) {
|
||||
return $this->renderError('商品不存在');
|
||||
}
|
||||
|
||||
// 使用模型静态方法添加收藏
|
||||
$result = FFFavorites::addFavorite($user_id, $product_id);
|
||||
|
||||
return $this->renderSuccess('收藏成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消商品收藏
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function cancelFavorite()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
$product_id = intval($this->request->param('product_id', 0));
|
||||
if (!$product_id) {
|
||||
return $this->renderError('商品ID不能为空');
|
||||
}
|
||||
|
||||
// 使用模型静态方法取消收藏
|
||||
$result = FFFavorites::cancelFavorite($user_id, $product_id);
|
||||
|
||||
if ($result) {
|
||||
return $this->renderSuccess('取消收藏成功');
|
||||
} else {
|
||||
return $this->renderError('取消收藏失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量取消收藏
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function batchCancelFavorite()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
$product_ids = $this->request->param('product_ids');
|
||||
if (empty($product_ids)) {
|
||||
return $this->renderError('商品ID不能为空');
|
||||
}
|
||||
|
||||
// 转换为数组
|
||||
if (!is_array($product_ids)) {
|
||||
$product_ids = explode(',', $product_ids);
|
||||
}
|
||||
|
||||
// 批量取消收藏
|
||||
$result = FFFavorites::batchCancelFavorite($user_id, $product_ids);
|
||||
|
||||
if ($result) {
|
||||
return $this->renderSuccess('批量取消收藏成功');
|
||||
} else {
|
||||
return $this->renderError('批量取消收藏失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查商品是否已收藏
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function checkIsFavorite()
|
||||
{
|
||||
$user_id = $this->getUserId();
|
||||
if (!$user_id) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
$product_id = intval($this->request->param('product_id', 0));
|
||||
if (!$product_id) {
|
||||
return $this->renderError('商品ID不能为空');
|
||||
}
|
||||
|
||||
// 检查是否已收藏
|
||||
$isFavorite = FFFavorites::isFavorite($user_id, $product_id);
|
||||
|
||||
return $this->renderSuccess('', ['is_favorite' => $isFavorite ? true : false]);
|
||||
}
|
||||
}
|
||||
259
app/api/controller/News.php
Normal file
259
app/api/controller/News.php
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\api\controller\Base;
|
||||
use app\common\model\News as NewsModel;
|
||||
use app\common\model\UserNewsFavorite;
|
||||
|
||||
class News extends Base
|
||||
{
|
||||
/**
|
||||
* 获取精选新闻列表
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getFeaturedNewsList()
|
||||
{
|
||||
$where = [];
|
||||
$where['status'] = 1;
|
||||
$where['is_featured'] = 1;
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$title = $this->request->param('title', '');
|
||||
if ($title) {
|
||||
$where[] = ['title', 'like', '%' . $title . '%'];
|
||||
}
|
||||
$newsList = NewsModel::getList($where, 'id,title,cover_image,publish_time', 'publish_time desc', $limit);
|
||||
return $this->renderSuccess('', $newsList);
|
||||
}
|
||||
/**
|
||||
* 获取热榜新闻列表
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getHotNewsList()
|
||||
{
|
||||
$where = [];
|
||||
$where['status'] = 1;
|
||||
$where['is_hot'] = 1;
|
||||
$title = $this->request->param('title', '');
|
||||
if ($title) {
|
||||
$where[] = ['title', 'like', '%' . $title . '%'];
|
||||
}
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$newsList = NewsModel::getList($where, 'id,title,cover_image,publish_time,is_hot', 'publish_time desc', $limit);
|
||||
return $this->renderSuccess('', $newsList);
|
||||
}
|
||||
/**
|
||||
* 获取用户关注的新闻列表
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getFollowNewsList()
|
||||
{
|
||||
$title = $this->request->param('title', '');
|
||||
$limit = intval($this->request->param('limit', 10));
|
||||
$page = intval($this->request->param('page', 1));
|
||||
|
||||
$userId = $this->getUserId();
|
||||
if ($userId == 0) {
|
||||
return $this->renderSuccess('', ['list' => [], 'count' => 0]);
|
||||
}
|
||||
|
||||
// 构建查询
|
||||
$model = NewsModel::alias('n')
|
||||
->join('user_news_favorite u', 'n.id=u.news_id')
|
||||
->where('u.user_id', '=', $userId)
|
||||
->where('u.is_canceled', '=', 0)
|
||||
->where('n.status', '=', 1);
|
||||
|
||||
// 如果有标题搜索条件
|
||||
if ($title) {
|
||||
$model = $model->where('n.title', 'like', '%' . $title . '%');
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
$count = $model->count();
|
||||
|
||||
// 查询数据并分页
|
||||
$list = $model->field('n.id, n.title, n.cover_image, n.publish_time, n.author_name')
|
||||
->order('u.create_time', 'desc')
|
||||
->page($page, $limit)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return $this->renderSuccess('', [
|
||||
'list' => $list,
|
||||
'count' => $count,
|
||||
'limit' => $limit,
|
||||
'page' => $page
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取新闻详情
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getNewsDetail()
|
||||
{
|
||||
$id = $this->request->param('id', 0);
|
||||
//来源 0: 热榜,1精选,2关注
|
||||
$current = $this->request->param('current', 0);
|
||||
$newsInfo = NewsModel::getInfo(['id' => $id], 'id,title,cover_image,publish_time,content,author_name');
|
||||
if (!$newsInfo) {
|
||||
return $this->renderError('新闻不存在');
|
||||
}
|
||||
$newsInfo['content'] = htmlspecialchars_decode($newsInfo['content']);
|
||||
|
||||
// 获取上下篇数据
|
||||
$condition = $this->getCondition($current);
|
||||
if ($condition) {
|
||||
// 获取上一篇(发布时间小于当前文章)
|
||||
$newsInfo['next_data'] = $this->getAdjacentNews($id, $newsInfo['publish_time'], $condition, '<', 'desc');
|
||||
// 获取下一篇(发布时间大于当前文章)
|
||||
$newsInfo['prev_data'] = $this->getAdjacentNews($id, $newsInfo['publish_time'], $condition, '>', 'asc');
|
||||
} else {
|
||||
$newsInfo['next_data'] = null;
|
||||
$newsInfo['prev_data'] = null;
|
||||
}
|
||||
$newsInfo['user_follow'] = false;
|
||||
$userId = $this->getUserId();
|
||||
if ($userId > 0) {
|
||||
$newsInfo['user_follow'] = UserNewsFavorite::isFavorite($userId, $id);
|
||||
}
|
||||
|
||||
// 随机查询5条新闻数据
|
||||
$re = NewsModel::where('status', 1)
|
||||
->where($condition, '=', 1)
|
||||
->where('cover_image', '!=', '')
|
||||
->field('id,title,cover_image,publish_time,author_name,is_hot,is_featured')
|
||||
->orderRaw('rand()')
|
||||
->limit(5)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$newsInfo['recommend_news'] = $re;
|
||||
// $newsInfo['publish_time'] = date('Y-m-d H:i:s', $newsInfo['publish_time']);
|
||||
return $this->renderSuccess('', $newsInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据来源类型获取条件
|
||||
* @param int $current 来源类型 0: 热榜,1精选,2关注
|
||||
* @return string|null 对应的条件字段
|
||||
*/
|
||||
private function getCondition($current)
|
||||
{
|
||||
switch ($current) {
|
||||
case 0:
|
||||
return 'is_hot';
|
||||
case 1:
|
||||
return 'is_featured';
|
||||
case 2:
|
||||
// 可以根据需求扩展
|
||||
// return 'is_follow';
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取相邻的新闻
|
||||
* @param int $id 当前新闻ID
|
||||
* @param int $publishTime 当前发布时间
|
||||
* @param string $condition 条件字段
|
||||
* @param string $comparison 比较符号
|
||||
* @param string $orderType 排序方式
|
||||
* @return mixed 查询结果
|
||||
*/
|
||||
private function getAdjacentNews($id, $publishTime, $condition, $comparison, $orderType)
|
||||
{
|
||||
return NewsModel::where('id', '!=', $id)
|
||||
->where($condition, '=', 1)
|
||||
->where('status', '=', 1)
|
||||
->where('publish_time', $comparison, $publishTime)
|
||||
->field('id,title,cover_image,publish_time,is_hot,is_featured')
|
||||
->order('publish_time ' . $orderType)
|
||||
->find();
|
||||
}
|
||||
|
||||
/**
|
||||
* 收藏新闻
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function addFavorite()
|
||||
{
|
||||
$newsId = $this->request->param('news_id', 0);
|
||||
if (empty($newsId)) {
|
||||
return $this->renderError('参数错误');
|
||||
}
|
||||
|
||||
// 检查新闻是否存在
|
||||
$newsInfo = NewsModel::getInfo(['id' => $newsId], 'id');
|
||||
if (!$newsInfo) {
|
||||
return $this->renderError('新闻不存在');
|
||||
}
|
||||
|
||||
// 获取当前用户ID
|
||||
$userId = $this->getUserId();
|
||||
if (!$userId) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 添加收藏
|
||||
$result = UserNewsFavorite::addFavorite($userId, $newsId);
|
||||
if ($result) {
|
||||
return $this->renderSuccess('收藏成功');
|
||||
}
|
||||
|
||||
return $this->renderError('收藏失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏新闻
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function cancelFavorite()
|
||||
{
|
||||
$newsId = $this->request->param('news_id', 0);
|
||||
if (empty($newsId)) {
|
||||
return $this->renderError('参数错误');
|
||||
}
|
||||
|
||||
// 获取当前用户ID
|
||||
$userId = $this->getUserId();
|
||||
if (!$userId) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 取消收藏
|
||||
$result = UserNewsFavorite::cancelFavorite($userId, $newsId);
|
||||
if ($result) {
|
||||
return $this->renderSuccess('取消收藏成功');
|
||||
}
|
||||
|
||||
return $this->renderError('取消收藏失败或未收藏该新闻');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查新闻是否已收藏
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function checkFavorite()
|
||||
{
|
||||
$newsId = $this->request->param('news_id', 0);
|
||||
if (empty($newsId)) {
|
||||
return $this->renderError('参数错误');
|
||||
}
|
||||
|
||||
// 获取当前用户ID
|
||||
$userId = $this->getUserId();
|
||||
if (!$userId) {
|
||||
return $this->renderError('请先登录');
|
||||
}
|
||||
|
||||
// 检查是否已收藏
|
||||
$favorite = UserNewsFavorite::isFavorite($userId, $newsId);
|
||||
|
||||
return $this->renderSuccess('', ['is_favorite' => $favorite ? true : false]);
|
||||
}
|
||||
}
|
||||
|
|
@ -959,7 +959,7 @@ class User extends Base
|
|||
|
||||
/*
|
||||
海报生成器
|
||||
|
||||
|
||||
*/
|
||||
public function product_img()
|
||||
{
|
||||
|
|
@ -1274,10 +1274,43 @@ class User extends Base
|
|||
return $this->renderError("用户不存在");
|
||||
}
|
||||
$userinfo['id'] = $user['id'];
|
||||
$userinfo['ID'] = $user['id'];
|
||||
$userinfo['mobile_is'] = $user['mobile'] ? 1 : 0;
|
||||
$userinfo['username'] = $user['nickname'];
|
||||
$userinfo['userIcon'] = imageUrl($user['headimg']);
|
||||
$userinfo['mobile'] = $user['mobile'] ? substr_replace($user['mobile'], '****', 3, 4) : '';
|
||||
|
||||
$other = [
|
||||
'uid' => $user['uid'] ? $user['uid'] : $user['id'],
|
||||
'pid' => $user['pid'],
|
||||
'a' => $user['money'],//钻石
|
||||
'b' => $user['money2'],//达达券
|
||||
'c' => $user['integral'],//UU币
|
||||
];
|
||||
$userinfo['other'] = $this->encryption($other);
|
||||
|
||||
$day = floor(abs(time() - $user['addtime']) / 86400);
|
||||
$userinfo['days'] = $day;
|
||||
|
||||
return $this->renderSuccess("请求成功", $userinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的
|
||||
*/
|
||||
public function userInfo2(Request $request)
|
||||
{
|
||||
$user_id = $this->getuserid();
|
||||
if ($user_id == 0) {
|
||||
return $this->renderError("未登录");
|
||||
}
|
||||
$user = Usermodel::where('id', '=', $user_id)->find();
|
||||
if (!$user) {
|
||||
return $this->renderError("用户不存在");
|
||||
}
|
||||
$userinfo['id'] = $user['id'];
|
||||
$userinfo['mobile_is'] = $user['mobile'] ? 1 : 0;
|
||||
$userinfo['nickname'] = $user['nickname'];
|
||||
$userinfo['headimg'] = imageUrl($user['headimg']);
|
||||
$userinfo['userIcon'] = imageUrl($user['headimg']);
|
||||
$userinfo['mobile'] = $user['mobile'] ? substr_replace($user['mobile'], '****', 3, 4) : '';
|
||||
$userinfo['money'] = $user['money'];//钻石
|
||||
$userinfo['money2'] = $user['money2'];//达达券
|
||||
|
|
@ -1289,6 +1322,7 @@ class User extends Base
|
|||
return $this->renderSuccess("请求成功", $userinfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 绑定邀请码
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -30,12 +30,13 @@ Route::any('user_yaoqing', 'Index/get_user_yaoqing');
|
|||
// Route::any('yushourili', 'Index/yushourili');
|
||||
Route::any('danye', 'Index/danye');
|
||||
Route::any('getDanye', 'Index/getDanye');
|
||||
|
||||
Route::any('getAgreement', 'Index/getDanye');
|
||||
#============================
|
||||
#User.php个人中心
|
||||
#============================
|
||||
Route::any('user', 'User/user');
|
||||
Route::any('userInfo', 'User/userInfo');
|
||||
Route::any('userInfo', 'User/userInfo2');
|
||||
Route::any('get_userInfo', 'User/userInfo');
|
||||
Route::any('update_userinfo', 'User/update_userinfo');
|
||||
Route::any('vip_list', 'User/vip_list');
|
||||
Route::any('profitIntegral', 'User/profitIntegral');
|
||||
|
|
@ -55,6 +56,7 @@ Route::any('recharge', 'User/recharge');
|
|||
Route::any('item_card_list', 'User/item_card_list');
|
||||
Route::any('bind_invite_code', 'User/bind_invite_code');
|
||||
Route::any('user_log_off', 'User/user_log_off');
|
||||
Route::any('deleteAccount', 'User/user_log_off');
|
||||
#Rank.php排行榜
|
||||
#============================
|
||||
Route::any('rank_week', 'Rank/rank_week');
|
||||
|
|
@ -90,7 +92,7 @@ Route::any('getGoodExtend', 'Goods/getGoodExtend');
|
|||
Route::any('coupon', 'Coupon/index');
|
||||
Route::any('receive', 'Coupon/receive');
|
||||
Route::any('used', 'Coupon/used');
|
||||
|
||||
Route::any('get_coupon_list', 'Coupon/get_coupon_list');
|
||||
#============================
|
||||
#Infinite.php 无限赏管理
|
||||
#============================
|
||||
|
|
@ -230,6 +232,39 @@ Route::any('get_diamond_list', 'Mall/get_diamond_list');
|
|||
Route::any('createOrderProducts', 'Mall/createOrderProducts');
|
||||
Route::any('get_diamond_order_log', 'Mall/get_diamond_order_log');
|
||||
|
||||
#============================
|
||||
# 新闻管理
|
||||
#============================
|
||||
Route::any('get_featured_news_list', 'News/getFeaturedNewsList');
|
||||
Route::any('get_hot_news_list', 'News/getHotNewsList');
|
||||
Route::any('get_news_detail', 'News/getNewsDetail');
|
||||
Route::any('get_follow_news_list', 'News/getFollowNewsList');
|
||||
Route::any('user_favorite_news', 'News/addFavorite');
|
||||
Route::any('user_cancel_favorite_news', 'News/cancelFavorite');
|
||||
|
||||
#============================
|
||||
# 商品管理
|
||||
#============================
|
||||
Route::any('get_banner_list', 'FFProductsController/getBannerList');
|
||||
Route::any('get_product_list', 'FFProductsController/getProductList');
|
||||
Route::any('get_product_detail', 'FFProductsController/getProductDetail');
|
||||
Route::any('pay_by_order', 'FFProductsController/PayByOrder');
|
||||
Route::any('get_favorite_list', 'FFProductsController/getFavoriteList');
|
||||
Route::any('add_favorite', 'FFProductsController/addFavorite');
|
||||
Route::any('cancel_favorite', 'FFProductsController/cancelFavorite');
|
||||
Route::any('batch_cancel_favorite', 'FFProductsController/batchCancelFavorite');
|
||||
Route::any('check_is_favorite', 'FFProductsController/checkIsFavorite');
|
||||
Route::any('pay_by_create_order', 'FFOrdersController/createOrder');
|
||||
Route::any('order_pay_success', 'FFOrdersController/orderPaySuccess');
|
||||
Route::any('get_order_list', 'FFOrdersController/getOrderList');
|
||||
Route::any('order_receive', 'FFOrdersController/orderReceive');
|
||||
Route::any('apply_refund', 'FFOrdersController/applyRefund');
|
||||
Route::any('cancel_refund', 'FFOrdersController/cancelRefund');
|
||||
Route::any('delete_order', 'FFOrdersController/deleteOrder');
|
||||
Route::any('get_order_detail', 'FFOrdersController/getOrderDetail');
|
||||
Route::any('apply_invoice', 'FFOrdersController/applyInvoice');
|
||||
Route::any('get_order_statistics', 'FFOrdersController/getOrderStatistics');
|
||||
|
||||
|
||||
#============================APP使用的路由 ============================#
|
||||
Route::any('V5Vx6qHOM5Ks9HqH', 'Login/login');
|
||||
|
|
|
|||
104
app/common/model/FFCategories.php
Normal file
104
app/common/model/FFCategories.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
namespace app\common\model;
|
||||
|
||||
use app\common\model\Base;
|
||||
use think\Model;
|
||||
|
||||
class FFCategories extends Base{
|
||||
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $table = 'ff_categories';
|
||||
|
||||
// 设置主键
|
||||
protected $pk = 'id';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 获取分页列表
|
||||
* @param array $where 查询条件
|
||||
* @param string $field 查询字段
|
||||
* @param string $order 排序规则
|
||||
* @param string $pageSize 每页数量
|
||||
* @return array
|
||||
*/
|
||||
public static function getList($where = [], $field = '*', $order = 'sort_order asc', $pageSize = "15")
|
||||
{
|
||||
$list = self::where($where)
|
||||
->field($field)
|
||||
->order($order)
|
||||
->paginate(['list_rows' => $pageSize, 'query' => request()->param()]);
|
||||
$page = $list->render();
|
||||
$data['list'] = $list->toArray()['data'];
|
||||
$data['count'] = $list->total();
|
||||
$data['page'] = $page;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有列表(不分页)
|
||||
* @param array $where 查询条件
|
||||
* @param string $field 查询字段
|
||||
* @param string $order 排序规则
|
||||
* @param string $limit 限制条数
|
||||
* @return \think\Collection
|
||||
*/
|
||||
public static function getAllList($where = [], $field = '*', $order = 'sort_order asc', $limit = '0')
|
||||
{
|
||||
$data = self::where($where)
|
||||
->field($field)
|
||||
->order($order)
|
||||
->limit($limit)
|
||||
->select();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单条数据
|
||||
* @param array $where 查询条件
|
||||
* @param string $field 查询字段
|
||||
* @return array|Model|null
|
||||
*/
|
||||
public static function getInfo($where = [], $field = '*')
|
||||
{
|
||||
$data = self::where($where)
|
||||
->field($field)
|
||||
->find();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取树形结构分类数据
|
||||
* @param int $parentId 父级ID
|
||||
* @param array $where 额外查询条件
|
||||
* @return array
|
||||
*/
|
||||
public static function getTreeList($parentId = 0, $where = [])
|
||||
{
|
||||
$where[] = ['status', '=', 1];
|
||||
$allCategories = self::getAllList($where)->toArray();
|
||||
return self::buildTree($allCategories, $parentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建树形结构
|
||||
* @param array $elements 所有元素
|
||||
* @param int $parentId 父级ID
|
||||
* @return array
|
||||
*/
|
||||
protected static function buildTree(array $elements, $parentId = 0)
|
||||
{
|
||||
$branch = [];
|
||||
foreach ($elements as $element) {
|
||||
if ($element['parent_id'] == $parentId) {
|
||||
$children = self::buildTree($elements, $element['id']);
|
||||
if ($children) {
|
||||
$element['children'] = $children;
|
||||
}
|
||||
$branch[] = $element;
|
||||
}
|
||||
}
|
||||
return $branch;
|
||||
}
|
||||
}
|
||||
145
app/common/model/FFFavorites.php
Normal file
145
app/common/model/FFFavorites.php
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 用户商品收藏模型
|
||||
* Class FFFavorites
|
||||
* @package app\common\model
|
||||
*/
|
||||
class FFFavorites extends Model
|
||||
{
|
||||
// 设置表名
|
||||
protected $name = 'ff_favorites';
|
||||
|
||||
// 设置主键
|
||||
protected $pk = 'favorite_id';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
// 关联商品
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo('FFProducts', 'product_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户是否收藏了指定商品
|
||||
* @param int $userId 用户ID
|
||||
* @param int $productId 商品ID
|
||||
* @return bool|array false表示未收藏,array表示收藏信息
|
||||
*/
|
||||
public static function isFavorite($userId, $productId)
|
||||
{
|
||||
$where = [
|
||||
'user_id' => $userId,
|
||||
'product_id' => $productId,
|
||||
];
|
||||
|
||||
$favorite = self::where($where)->find();
|
||||
|
||||
return $favorite ? $favorite->toArray() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加收藏
|
||||
* @param int $userId 用户ID
|
||||
* @param int $productId 商品ID
|
||||
* @return bool|array 收藏结果
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public static function addFavorite($userId, $productId)
|
||||
{
|
||||
// 检查是否已收藏
|
||||
$favorite = self::where([
|
||||
'user_id' => $userId,
|
||||
'product_id' => $productId,
|
||||
])->find();
|
||||
|
||||
if ($favorite) {
|
||||
// 已收藏,返回已存在
|
||||
return $favorite->toArray();
|
||||
}
|
||||
|
||||
// 新增收藏
|
||||
$model = new self();
|
||||
$model->user_id = $userId;
|
||||
$model->product_id = $productId;
|
||||
$model->save();
|
||||
|
||||
return $model->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏
|
||||
* @param int $userId 用户ID
|
||||
* @param int $productId 商品ID
|
||||
* @return bool 取消结果
|
||||
*/
|
||||
public static function cancelFavorite($userId, $productId)
|
||||
{
|
||||
return self::where([
|
||||
'user_id' => $userId,
|
||||
'product_id' => $productId,
|
||||
])->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户收藏列表
|
||||
* @param int $userId 用户ID
|
||||
* @param int $page 页码
|
||||
* @param int $limit 每页条数
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public static function getUserFavoriteList($userId, $page = 1, $limit = 10)
|
||||
{
|
||||
$list = self::where('user_id', $userId)
|
||||
->with(['product'])
|
||||
->page($page, $limit)
|
||||
->order('create_time', 'desc')
|
||||
->select();
|
||||
|
||||
return $list ? $list->toArray() : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品收藏数量
|
||||
* @param int $productId 商品ID
|
||||
* @return int 收藏数量
|
||||
*/
|
||||
public static function getProductFavoriteCount($productId)
|
||||
{
|
||||
return self::where('product_id', $productId)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量取消收藏
|
||||
* @param int $userId 用户ID
|
||||
* @param array $productIds 商品ID数组
|
||||
* @return int 影响行数
|
||||
*/
|
||||
public static function batchCancelFavorite($userId, $productIds)
|
||||
{
|
||||
return self::where('user_id', $userId)
|
||||
->whereIn('product_id', $productIds)
|
||||
->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联用户表
|
||||
* @return \think\model\relation\HasOne
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->hasOne(User::class, 'id', 'user_id');
|
||||
}
|
||||
}
|
||||
150
app/common/model/FFOrders.php
Normal file
150
app/common/model/FFOrders.php
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use app\common\model\Base;
|
||||
use app\common\model\User;
|
||||
use think\Model;
|
||||
|
||||
class FFOrders extends Base
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $table = 'ff_orders';
|
||||
|
||||
// 设置主键
|
||||
protected $pk = 'order_id';
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*/
|
||||
public static function getList($where = [], $field = '*', $order = 'order_id desc', $pageSize = "15")
|
||||
{
|
||||
$list = self::where($where)
|
||||
->field($field)
|
||||
->order($order)
|
||||
->paginate(['list_rows' => $pageSize, 'query' => request()->param()]);
|
||||
$page = $list->render();
|
||||
$data['list'] = $list->toArray()['data'];
|
||||
$data['count'] = $list->total();
|
||||
$data['last_page'] = $list->toArray()['last_page'];
|
||||
$data['page'] = $page;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表 不分页
|
||||
*/
|
||||
public static function getAllList($where = [], $field = '*', $order = 'order_id desc', $limit = '0')
|
||||
{
|
||||
$data = self::where($where)
|
||||
->field($field)
|
||||
->order($order)
|
||||
->limit($limit)
|
||||
->select();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单条数据
|
||||
*/
|
||||
public static function getInfo($where = [], $field = '*')
|
||||
{
|
||||
$data = self::where($where)
|
||||
->field($field)
|
||||
->find();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取关联用户信息
|
||||
*/
|
||||
public function getUserInfoAttr($value, $data)
|
||||
{
|
||||
$user_info = User::field('nickname,headimg,mobile')->where(['id' => $data['user_id']])->find();
|
||||
return $user_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单状态获取器
|
||||
*/
|
||||
public function getOrderStatusTextAttr($value, $data)
|
||||
{
|
||||
$status = [
|
||||
0 => '待支付',
|
||||
1 => '已支付待发货',
|
||||
2 => '已发货',
|
||||
3 => '已完成',
|
||||
4 => '已关闭',
|
||||
5 => '已取消'
|
||||
];
|
||||
return isset($status[$data['order_status']]) ? $status[$data['order_status']] : '未知状态';
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付状态获取器
|
||||
*/
|
||||
public function getPayStatusTextAttr($value, $data)
|
||||
{
|
||||
$status = [
|
||||
0 => '未支付',
|
||||
1 => '支付中',
|
||||
2 => '已支付'
|
||||
];
|
||||
return isset($status[$data['pay_status']]) ? $status[$data['pay_status']] : '未知状态';
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送状态获取器
|
||||
*/
|
||||
public function getShippingStatusTextAttr($value, $data)
|
||||
{
|
||||
$status = [
|
||||
0 => '未发货',
|
||||
1 => '已发货',
|
||||
2 => '已收货'
|
||||
];
|
||||
return isset($status[$data['shipping_status']]) ? $status[$data['shipping_status']] : '未知状态';
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付方式获取器
|
||||
*/
|
||||
public function getPaymentTypeTextAttr($value, $data)
|
||||
{
|
||||
$types = [
|
||||
1 => '支付宝',
|
||||
2 => '微信',
|
||||
3 => '银联'
|
||||
];
|
||||
return isset($types[$data['payment_type']]) ? $types[$data['payment_type']] : '未知方式';
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单来源获取器
|
||||
*/
|
||||
public function getSourceTextAttr($value, $data)
|
||||
{
|
||||
$sources = [
|
||||
1 => 'PC',
|
||||
2 => 'APP',
|
||||
3 => '小程序',
|
||||
4 => 'H5'
|
||||
];
|
||||
return isset($sources[$data['source']]) ? $sources[$data['source']] : '未知来源';
|
||||
}
|
||||
|
||||
/**
|
||||
* 发票类型获取器
|
||||
*/
|
||||
public function getInvoiceTypeTextAttr($value, $data)
|
||||
{
|
||||
if (empty($data['invoice_type'])) {
|
||||
return '';
|
||||
}
|
||||
$types = [
|
||||
1 => '个人',
|
||||
2 => '企业'
|
||||
];
|
||||
return isset($types[$data['invoice_type']]) ? $types[$data['invoice_type']] : '未知类型';
|
||||
}
|
||||
}
|
||||
170
app/common/model/FFProducts.php
Normal file
170
app/common/model/FFProducts.php
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
namespace app\common\model;
|
||||
|
||||
use app\common\model\Base;
|
||||
use think\Model;
|
||||
|
||||
class FFProducts extends Base{
|
||||
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $table = 'ff_products';
|
||||
|
||||
// 设置主键
|
||||
protected $pk = 'id';
|
||||
|
||||
// 自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 获取分页列表
|
||||
* @param array $where 查询条件
|
||||
* @param string $field 查询字段
|
||||
* @param string $order 排序规则
|
||||
* @param string $pageSize 每页数量
|
||||
* @return array
|
||||
*/
|
||||
public static function getList($where = [], $field = '*', $order = 'create_time desc', $pageSize = "15")
|
||||
{
|
||||
$list = self::where($where)
|
||||
->field($field)
|
||||
->order($order)
|
||||
->paginate(['list_rows' => $pageSize, 'query' => request()->param()]);
|
||||
$page = $list->render();
|
||||
$data['list'] = $list->toArray()['data'];
|
||||
$data['count'] = $list->total();
|
||||
$data['page'] = $page;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有列表(不分页)
|
||||
* @param array $where 查询条件
|
||||
* @param string $field 查询字段
|
||||
* @param string $order 排序规则
|
||||
* @param string $limit 限制条数
|
||||
* @return \think\Collection
|
||||
*/
|
||||
public static function getAllList($where = [], $field = '*', $order = 'create_time desc', $limit = '0')
|
||||
{
|
||||
$data = self::where($where)
|
||||
->field($field)
|
||||
->order($order)
|
||||
->limit($limit)
|
||||
->select();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单条数据
|
||||
* @param array $where 查询条件
|
||||
* @param string $field 查询字段
|
||||
* @return array|Model|null
|
||||
*/
|
||||
public static function getInfo($where = [], $field = '*')
|
||||
{
|
||||
$data = self::where($where)
|
||||
->field($field)
|
||||
->find();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取热销商品
|
||||
*/
|
||||
public static function getHotProducts($limit = 10, $field = '*')
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where('is_hot', 1)
|
||||
->field($field)
|
||||
->order('sales desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取新品商品
|
||||
*/
|
||||
public static function getNewProducts($limit = 10, $field = '*')
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where('is_new', 1)
|
||||
->field($field)
|
||||
->order('create_time desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取推荐商品
|
||||
*/
|
||||
public static function getRecommendProducts($limit = 10, $field = '*')
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where('is_recommend', 1)
|
||||
->field($field)
|
||||
->order('create_time desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类名称获取商品
|
||||
* @param string $categoryName 分类名称
|
||||
* @param int $limit 限制条数
|
||||
* @param string $field 查询字段
|
||||
* @return \think\Collection
|
||||
*/
|
||||
public static function getProductsByCategory($categoryName, $limit = 10, $field = '*')
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where('category_name', 'like', "%{$categoryName}%")
|
||||
->field($field)
|
||||
->order('create_time desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索商品
|
||||
*/
|
||||
public static function searchProducts($keyword, $field = '*', $pageSize = 15)
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where(function ($query) use ($keyword) {
|
||||
$query->where('product_name', 'like', "%{$keyword}%")
|
||||
->whereOr('product_desc', 'like', "%{$keyword}%")
|
||||
->whereOr('category_name', 'like', "%{$keyword}%");
|
||||
})
|
||||
->field($field)
|
||||
->order('create_time desc')
|
||||
->paginate(['list_rows' => $pageSize, 'query' => request()->param()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新库存
|
||||
* @param int $id 商品ID
|
||||
* @param int $num 减少的数量
|
||||
* @return bool
|
||||
*/
|
||||
public static function updateStock($id, $num)
|
||||
{
|
||||
return self::where('id', $id)
|
||||
->where('stock', '>=', $num)
|
||||
->dec('stock', $num)
|
||||
->inc('sales', $num)
|
||||
->update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件获取商品列表并按价格排序
|
||||
* @param array $where 查询条件
|
||||
* @param string $order 排序规则 asc-升序 desc-降序
|
||||
* @param int $pageSize 每页数量
|
||||
* @return array
|
||||
*/
|
||||
public static function getListByPrice($where = [], $order = 'asc', $pageSize = 15)
|
||||
{
|
||||
$orderRule = $order == 'asc' ? 'price asc' : 'price desc';
|
||||
return self::getList($where, '*', $orderRule, $pageSize);
|
||||
}
|
||||
}
|
||||
110
app/common/model/News.php
Normal file
110
app/common/model/News.php
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class News extends Base
|
||||
{
|
||||
// 设置当前模型对应的完整数据表名称
|
||||
protected $table = 'news';
|
||||
|
||||
// 设置字段自动写入时间戳
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'create_time';
|
||||
protected $updateTime = 'update_time';
|
||||
|
||||
/**
|
||||
* 获取列表(分页)
|
||||
*/
|
||||
public static function getList($where, $field = '*', $order = 'publish_time desc', $pageSize = "15")
|
||||
{
|
||||
$list = self::where($where)
|
||||
->field($field)
|
||||
->order($order)
|
||||
->paginate(['list_rows' => $pageSize, 'query' => request()->param()]);
|
||||
$page = $list->render();
|
||||
$data['list'] = $list->toArray()['data'];
|
||||
$data['count'] = $list->total();
|
||||
$data['last_page'] = $list->toArray()['last_page'];
|
||||
// $data['page'] = $page;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部列表(不分页)
|
||||
*/
|
||||
public static function getAllList($where = [], $field = '*', $order = 'publish_time desc', $limit = '0')
|
||||
{
|
||||
$data = self::where($where)
|
||||
->field($field)
|
||||
->order($order)
|
||||
->limit($limit)
|
||||
->select();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单条数据
|
||||
*/
|
||||
public static function getInfo($where = [], $field = '*')
|
||||
{
|
||||
$data = self::where($where)
|
||||
->field($field)
|
||||
->find();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取热榜资讯
|
||||
*/
|
||||
public static function getHotNews($limit = 10, $field = '*')
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where('is_hot', 1)
|
||||
->field($field)
|
||||
->order('publish_time desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取精选资讯
|
||||
*/
|
||||
public static function getFeaturedNews($limit = 10, $field = '*')
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where('is_featured', 1)
|
||||
->field($field)
|
||||
->order('publish_time desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据作者ID获取资讯
|
||||
*/
|
||||
public static function getNewsByAuthor($authorId, $limit = 10, $field = '*')
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where('author_id', $authorId)
|
||||
->field($field)
|
||||
->order('publish_time desc')
|
||||
->limit($limit)
|
||||
->select();
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索资讯
|
||||
*/
|
||||
public static function searchNews($keyword, $field = '*', $pageSize = 15)
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->where('title', 'like', '%' . $keyword . '%')
|
||||
->field($field)
|
||||
->order('publish_time desc')
|
||||
->paginate(['list_rows' => $pageSize, 'query' => request()->param()]);
|
||||
}
|
||||
}
|
||||
141
app/common/model/UserNewsFavorite.php
Normal file
141
app/common/model/UserNewsFavorite.php
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 用户收藏资讯模型
|
||||
* Class UserNewsFavorite
|
||||
* @package app\common\model
|
||||
*/
|
||||
class UserNewsFavorite extends Model
|
||||
{
|
||||
// 设置表名
|
||||
protected $name = 'user_news_favorite';
|
||||
|
||||
// 设置主键
|
||||
protected $pk = 'id';
|
||||
|
||||
// 自动写入时间戳字段
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
// 定义时间戳字段名
|
||||
protected $createTime = 'create_time';
|
||||
protected $updateTime = false; // 不使用更新时间
|
||||
|
||||
/**
|
||||
* 查询用户是否收藏了指定新闻
|
||||
* @param int $userId 用户ID
|
||||
* @param int $newsId 新闻ID
|
||||
* @return bool|array false表示未收藏,array表示收藏信息
|
||||
*/
|
||||
public static function isFavorite($userId, $newsId)
|
||||
{
|
||||
$where = [
|
||||
'user_id' => $userId,
|
||||
'news_id' => $newsId,
|
||||
'is_canceled' => 0, // 未取消收藏
|
||||
];
|
||||
|
||||
$favorite = self::where($where)->find();
|
||||
|
||||
return $favorite ? $favorite->toArray() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加收藏
|
||||
* @param int $userId 用户ID
|
||||
* @param int $newsId 新闻ID
|
||||
* @return bool|array 收藏结果
|
||||
*/
|
||||
public static function addFavorite($userId, $newsId)
|
||||
{
|
||||
// 检查是否已收藏
|
||||
$favorite = self::where([
|
||||
'user_id' => $userId,
|
||||
'news_id' => $newsId,
|
||||
])->find();
|
||||
|
||||
if ($favorite) {
|
||||
// 已收藏但被取消,则恢复收藏
|
||||
if ($favorite['is_canceled'] == 1) {
|
||||
$favorite->is_canceled = 0;
|
||||
$favorite->cancel_time = null;
|
||||
$favorite->create_time = date('Y-m-d H:i:s');
|
||||
$favorite->save();
|
||||
return $favorite->toArray();
|
||||
}
|
||||
// 已收藏未取消,返回已存在
|
||||
return $favorite->toArray();
|
||||
}
|
||||
|
||||
// 新增收藏
|
||||
$model = new self();
|
||||
$model->user_id = $userId;
|
||||
$model->news_id = $newsId;
|
||||
$model->is_canceled = 0;
|
||||
$model->save();
|
||||
|
||||
return $model->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏
|
||||
* @param int $userId 用户ID
|
||||
* @param int $newsId 新闻ID
|
||||
* @return bool 取消结果
|
||||
*/
|
||||
public static function cancelFavorite($userId, $newsId)
|
||||
{
|
||||
$favorite = self::where([
|
||||
'user_id' => $userId,
|
||||
'news_id' => $newsId,
|
||||
'is_canceled' => 0,
|
||||
])->find();
|
||||
|
||||
if (!$favorite) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$favorite->is_canceled = 1;
|
||||
$favorite->cancel_time = date('Y-m-d H:i:s');
|
||||
return $favorite->save() !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户收藏列表
|
||||
* @param int $userId 用户ID
|
||||
* @param int $page 页码
|
||||
* @param int $limit 每页条数
|
||||
* @return array 收藏列表
|
||||
*/
|
||||
public static function getUserFavoriteList($userId, $page = 1, $limit = 10)
|
||||
{
|
||||
$where = [
|
||||
'user_id' => $userId,
|
||||
'is_canceled' => 0,
|
||||
];
|
||||
|
||||
$list = self::where($where)
|
||||
->with(['news' => function ($query) {
|
||||
$query->field('id,title,cover_image,publish_time,author_name');
|
||||
}])
|
||||
->page($page, $limit)
|
||||
->order('create_time', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联新闻表
|
||||
* @return \think\model\relation\HasOne
|
||||
*/
|
||||
public function news()
|
||||
{
|
||||
return $this->hasOne(News::class, 'id', 'news_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -35,12 +35,19 @@ class AppPlatform extends BasePlatform
|
|||
$versionNumber = (int) preg_replace('/[^0-9]/', '', $version);
|
||||
$config = [
|
||||
'isWebPay' => false,
|
||||
'isCheck' => false,
|
||||
'buildVersion' => '106',
|
||||
'version' => '1.0.0',
|
||||
'userAgreement' => "https://zfunbox.cn?_p=cb20xad0e35094521ae46a1d1fb0ddd1&time=" . time()
|
||||
];
|
||||
$is_env_test = EnvHelper::getIsTest();
|
||||
if ($is_env_test) {
|
||||
$config['userAgreement'] = "https://testweb.zfunbox.cn?_p=cb20xad0e35094521ae46a1d1fb0ddd1&time=" . time();
|
||||
}
|
||||
$configVersion = (int) preg_replace('/[^0-9]/', '', $config['version']);
|
||||
if ($versionNumber >= $configVersion) {
|
||||
$config['isCheck'] = true;
|
||||
$config['buildVersion'] = '105';
|
||||
// $config['isCheck'] = true;
|
||||
$config['userAgreement'] = "https://zfunbox.cn/pages/guize/guize?type=4";
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class PlatformFactory
|
|||
if ($client == "WEB_APP") {
|
||||
return new H5Platform();
|
||||
}
|
||||
if ($client == "APP_ANDROID") {
|
||||
if ($client == "APP_ANDROID" || $client == "WEB_APP_ANDROID") {
|
||||
return new AppPlatform();
|
||||
}
|
||||
if ($client == "APP_IOS") {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ return [
|
|||
'url' => '/admin/sign_config',
|
||||
'name' => '用户签到设置',
|
||||
],
|
||||
|
||||
|
||||
// [
|
||||
// 'url' => '/admin/user_loginStat',
|
||||
// 'name' => '用户登录统计',
|
||||
|
|
@ -96,7 +96,7 @@ return [
|
|||
'url' => '/admin/diamond',
|
||||
'name' => '钻石商品配置',
|
||||
],
|
||||
|
||||
|
||||
],
|
||||
],
|
||||
[
|
||||
|
|
@ -217,6 +217,23 @@ return [
|
|||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => '审核页面管理',
|
||||
'son' => [
|
||||
[
|
||||
'url' => '/admin/news',
|
||||
'name' => '新闻列表',
|
||||
],
|
||||
[
|
||||
'url' => '/admin/ff_categories',
|
||||
'name' => '商品分类管理',
|
||||
],
|
||||
[
|
||||
'url' => '/admin/ff_products',
|
||||
'name' => '商品列表',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => '管理员管理',
|
||||
'son' => [
|
||||
|
|
@ -277,7 +294,7 @@ return [
|
|||
// 'url' => '/admin/wechatofficialaccount',
|
||||
// 'name' => '公众号设置',
|
||||
// ],
|
||||
|
||||
|
||||
],
|
||||
],
|
||||
|
||||
|
|
|
|||
3
public/js/quill/quill.js
Normal file
3
public/js/quill/quill.js
Normal file
File diff suppressed because one or more lines are too long
10
public/js/quill/quill.snow.css
Normal file
10
public/js/quill/quill.snow.css
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user