Add 添加客户端API接口和商品分类管理

This commit is contained in:
Bob
2021-07-24 22:08:14 +08:00
committed by 兔姬桑
parent 6f37cb6b0f
commit d226d62cbf
13 changed files with 646 additions and 39 deletions

View File

@@ -48,4 +48,6 @@ MAILGUN_DOMAIN=
MAILGUN_SECRET=
REDIRECT_HTTPS=true
BAIDU_APP_AK =
BAIDU_APP_AK =
JWT_SECRET=

View File

@@ -0,0 +1,72 @@
<?php
namespace App\Http\Controllers\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\GoodsCategory;
use App\Models\Level;
use Exception;
use Illuminate\Http\Request;
use Log;
use Response;
use Validator;
class CategoryController extends Controller
{
// 添加等级
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required',
]);
if ($validator->fails()) {
return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]);
}
if (GoodsCategory::create($validator->validated())) {
return Response::json(['status' => 'success', 'message' => '提交成功']);
}
return Response::json(['status' => 'fail', 'message' => '操作失败']);
}
// 编辑等级
public function update(Request $request, GoodsCategory $category)
{
$validator = Validator::make($request->all(), [
'name' => 'required',
'sort' => 'required|numeric',
]);
if ($validator->fails()) {
return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]);
}
if ($category->update($validator->validated())) {
return Response::json(['status' => 'success', 'message' => '操作成功']);
}
return Response::json(['status' => 'fail', 'message' => '操作失败']);
}
// 删除等级
public function destroy(GoodsCategory $category)
{
// 校验该等级下是否存在关联账号
if ($category->goods()->exists()) {
return Response::json(['status' => 'fail', 'message' => '该分类下存在关联账号,请先取消关联']);
}
try {
if ($category->delete()) {
return Response::json(['status' => 'success', 'message' => '删除成功']);
}
} catch (Exception $e) {
Log::error('删除时报错:'.$e->getMessage());
return Response::json(['status' => 'fail', 'message' => '删除失败:'.$e->getMessage()]);
}
return Response::json(['status' => 'fail', 'message' => '删除失败']);
}
}

View File

@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\ShopStoreRequest;
use App\Http\Requests\Admin\ShopUpdateRequest;
use App\Models\Goods;
use App\Models\GoodsCategory;
use App\Models\Level;
use Arr;
use Exception;
@@ -37,7 +38,7 @@ class ShopController extends Controller
// 添加商品页面
public function create()
{
return view('admin.shop.info', ['levels' => Level::orderBy('level')->get()]);
return view('admin.shop.info', ['levels' => Level::orderBy('level')->get(), 'categories' => GoodsCategory::all()]);
}
// 添加商品
@@ -92,6 +93,7 @@ class ShopController extends Controller
return view('admin.shop.info', [
'good' => $good,
'levels' => Level::orderBy('level')->get(),
'categories' => GoodsCategory::all(),
]);
}
@@ -109,6 +111,7 @@ class ShopController extends Controller
return $path;
}
}
try {
$data['is_hot'] = array_key_exists('is_hot', $data) ? 1 : 0;
$data['status'] = array_key_exists('status', $data) ? 1 : 0;

View File

@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Models\Country;
use App\Models\GoodsCategory;
use App\Models\Invite;
use App\Models\Label;
use App\Models\Level;
@@ -118,6 +119,7 @@ class AdminController extends Controller
return view('admin.config.config', [
'methods' => SsConfig::type(1)->get(),
'protocols' => SsConfig::type(2)->get(),
'categories' => GoodsCategory::all(),
'obfsList' => SsConfig::type(3)->get(),
'countries' => Country::all(),
'levels' => Level::all(),

View File

@@ -2,17 +2,30 @@
namespace App\Http\Controllers\Api\Client;
use App\Components\Helpers;
use App\Http\Controllers\Controller;
use App\Http\Controllers\PaymentController;
use App\Models\Coupon;
use App\Models\Goods;
use App\Models\GoodsCategory;
use App\Models\Order;
use App\Models\Payback;
use App\Models\Payment;
use App\Models\ReferralLog;
use App\Models\User;
use Hashids\Hashids;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Validator;
class V1Controller extends Controller
{
private static $method;
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login', 'register', 'shop']]);
$this->middleware('auth:api', ['except' => ['login', 'register', 'shop', 'config', 'getConfig']]);
auth()->shouldUse('api');
}
@@ -27,7 +40,7 @@ class V1Controller extends Controller
return response()->json(['ret' => 0, 'msg' => $validator->errors()->all()], 422);
}
if ($token = auth()->attempt($validator->validated())) {
if ($token = auth('api')->attempt($validator->validated())) {
return $this->createNewToken($token);
}
@@ -37,18 +50,20 @@ class V1Controller extends Controller
protected function createNewToken($token)
{
return response()->json([
'ret' => 1,
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60,
'user' => auth()->user()->profile(),
'ret' => 1,
'data' => [
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth('api')->factory()->getTTL() * 60,
'user' => auth('api')->user()->profile(),
],
]);
}
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|between:2,100',
'name' => 'required|string|between:2,100',
'username' => 'required|'.(sysConfig('username_type') ?? 'email').'|max:100|unique:user,username',
'password' => 'required|string|confirmed|min:6',
]);
@@ -67,46 +82,256 @@ class V1Controller extends Controller
public function logout()
{
auth()->logout();
auth('api')->logout();
return response()->json(['ret' => 1]);
}
public function refresh()
{
return $this->createNewToken(auth()->refresh());
return $this->createNewToken(auth('api')->refresh());
}
public function userProfile()
{
return response()->json(auth()->user()->profile());
$user = auth('api')->user();
$userInfo = $user->profile();
$userInfo['subUrl'] = $user->subUrl();
$totalTransfer = $user->transfer_enable;
$usedTransfer = $user->used_traffic;
$unusedTraffic = $totalTransfer - $usedTransfer > 0 ? $totalTransfer - $usedTransfer : 0;
$userInfo['unusedTraffic'] = flowAutoShow($unusedTraffic);
return response()->json(['ret' => 1, 'data' => $userInfo]);
}
public function nodeList(int $id = null)
{
$user = auth()->user();
$user = auth('api')->user();
$nodes = $user->nodes()->get();
if (isset($id)) {
$node = $nodes->find($id);
if (empty($node)) {
return response()->json([], 204);
}
return response()->json($node->config($user));
}
$servers = [];
foreach ($nodes as $node) {
$servers[] = $node->config($user);
}
return response()->json($servers);
return response()->json(['ret' => 1, 'data' => $nodes]);
}
public function shop()
{
$shop = Goods::whereStatus(1)->where('type', '<=', '2')->orderByDesc('type')->orderByDesc('sort')->get();
$shops = [
'keys' => [],
'data' => [],
];
$shop_plan = GoodsCategory::query()->where('status', 1)->get();
foreach ($shop_plan as $item) {
array_push($shops['keys'], $item['name']);
$shops['data'][$item['name']] = $item->goods()->get()->append('traffic_label')->toArray();
}
return response()->json($shop);
return response()->json(['ret' => 1, 'data' => $shops]);
}
public function getConfig()
{
$config = config('bobclient');
$config['website_name'] = sysConfig('website_name');
$config['website_url'] = sysConfig('website_url');
$config['payment'] = [
'alipay' => sysConfig('is_AliPay'),
'wechat' => sysConfig('is_WeChatPay'),
];
return response()->json(['ret' => 1, 'data' => $config]);
}
// 创建支付订单
public function purchase(Request $request)
{
$goods_id = $request->input('goods_id');
$coupon_sn = $request->input('coupon_sn');
self::$method = $request->input('method');
$credit = $request->input('amount');
$pay_type = $request->input('pay_type');
$amount = 0;
// 充值余额
if ($credit) {
if (! is_numeric($credit) || $credit <= 0) {
return response()->json(['ret' => 0, 'msg' => trans('user.payment.error')]);
}
$amount = $credit;
// 购买服务
} elseif ($goods_id && self::$method) {
$goods = Goods::find($goods_id);
if (! $goods || ! $goods->status) {
return response()->json(['ret' => 0, 'msg' => '订单创建失败:商品已下架']);
}
$amount = $goods->price;
// 是否有生效的套餐
$activePlan = Order::userActivePlan()->doesntExist();
// 无生效套餐,禁止购买加油包
if ($goods->type === 1 && $activePlan) {
return response()->json(['ret' => 0, 'msg' => '购买加油包前,请先购买套餐']);
}
// 单个商品限购
if ($goods->limit_num) {
$count = Order::uid()->where('status', '>=', 0)->whereGoodsId($goods_id)->count();
if ($count >= $goods->limit_num) {
return response()->json(['ret' => 0, 'msg' => '此商品限购'.$goods->limit_num.'次,您已购买'.$count.'次']);
}
}
// 使用优惠券
if ($coupon_sn) {
$coupon = Coupon::whereStatus(0)->whereIn('type', [1, 2])->whereSn($coupon_sn)->first();
if (! $coupon) {
return response()->json(['ret' => 0, 'msg' => '订单创建失败:优惠券不存在']);
}
// 计算实际应支付总价
$amount = $coupon->type === 2 ? $goods->price * $coupon->value / 100 : $goods->price - $coupon->value;
$amount = $amount > 0 ? round($amount, 2) : 0; // 四舍五入保留2位小数避免无法正常创建订单
}
//非余额付款下,检查在线支付是否开启
if (self::$method !== 'credit') {
// 判断是否开启在线支付
if (! sysConfig('is_onlinePay')) {
return response()->json(['ret' => 0, 'msg' => '订单创建失败:系统并未开启在线支付功能']);
}
// 判断是否存在同个商品的未支付订单
if (Order::uid()->whereStatus(0)->exists()) {
return response()->json(['ret' => 0, 'msg' => '订单创建失败:尚有未支付的订单,请先去支付']);
}
} elseif (Auth::getUser()->credit < $amount) { // 验证账号余额是否充足
return response()->json(['ret' => 0, 'msg' => '您的余额不足,请先充值']);
}
// 价格异常判断
if ($amount < 0) {
return response()->json(['ret' => 0, 'msg' => '订单创建失败:订单总价异常']);
}
if ($amount === 0 && self::$method !== 'credit') {
return response()->json(['ret' => 0, 'msg' => '订单创建失败订单总价为0无需使用在线支付']);
}
}
// 生成订单
try {
$newOrder = Order::create([
'sn' => date('ymdHis').random_int(100000, 999999),
'user_id' => auth()->id(),
'goods_id' => $credit ? null : $goods_id,
'coupon_id' => $coupon->id ?? null,
'origin_amount' => $credit ?: $goods->price ?? 0,
'amount' => $amount,
'pay_type' => $pay_type,
'pay_way' => self::$method,
]);
// 使用优惠券,减少可使用次数
if (! empty($coupon)) {
if ($coupon->usable_times > 0) {
$coupon->decrement('usable_times', 1);
}
Helpers::addCouponLog('订单支付使用', $coupon->id, $goods_id, $newOrder->id);
}
$request->merge(['id' => $newOrder->id, 'type' => $pay_type, 'amount' => $amount]);
PaymentController::$method = self::$method;
// 生成支付单
$data = PaymentController::getClient()->purchase($request);
$data = $data->getData(true);
$data['order_id'] = $newOrder->id;
return response()->json($data);
} catch (Exception $e) {
Log::error('订单生成错误:'.$e->getMessage());
}
return response()->json(['ret' => 0, 'msg' => '订单创建失败']);
}
/**
* @param Request $request
* @return JsonResponse
*/
public static function getStatus(Request $request): JsonResponse
{
$order_id = $request->input('order_id');
$payment = Order::query()->find($order_id)->payment;
if ($payment) {
if ($payment->status === 1) {
return response()->json(['ret' => 1, 'msg' => '支付成功']);
}
if ($payment->status === -1) {
return response()->json(['ret' => 0, 'msg' => '订单超时未支付,已自动关闭']);
}
return response()->json(['ret' => 0, 'msg' => '等待支付']);
}
return response()->json(['ret' => 0, 'msg' => '未知订单']);
}
public function gift(Request $request)
{
$user = $request->user('api');
$referral_traffic = flowAutoShow(sysConfig('referral_traffic') * MB);
$referral_percent = sysConfig('referral_percent');
// 邀请码
$code = $user->invites()->whereStatus(1)->value('code');
$data['invite_gift'] = trans('user.invite.promotion', [
'traffic' => $referral_traffic,
'referral_percent' => $referral_percent * 100,
]);
$affSalt = sysConfig('aff_salt');
if (isset($affSalt)) {
$aff_link = route('register', ['aff' => (new Hashids($affSalt, 8))->encode($user->id)]);
} else {
$aff_link = route('register', ['aff' => $user->id]);
}
$data['invite_url'] = $aff_link;
$data['invite_text'] = $aff_link.'&(复制整段文字到浏览器打开即可访问),找梯子最重要的就是稳定,这个已经上线三年了,一直稳定没有被封过,赶紧下载备用吧!安装后打开填写我的邀请码【'.$code.'】,你还能多得3天会员.';
// 累计数据
$data['back_sum'] = ReferralLog::query()->where('inviter_id', $user->id)->sum('commission') / 100;
$data['user_sum'] = $user->invitees()->count();
$data['list'] = $user->invitees()->selectRaw('username, UNIX_TIMESTAMP(created_at) as created_at')->limit(10)->get();
return response()->json(['ret' => 1, 'data' => $data]);
}
public function checkIn(Request $request): JsonResponse
{
$user = $request->user();
// 系统开启登录加积分功能才可以签到
if (! sysConfig('is_checkin')) {
return response()->json(['ret' => 0, 'title' => trans('common.failed'), 'msg' => trans('user.home.attendance.disable')]);
}
// 已签到过,验证是否有效
if (Cache::has('userCheckIn_'.$user->id)) {
return response()->json(['ret' => 0, 'title' => trans('common.success'), 'msg' => trans('user.home.attendance.done')]);
}
$traffic = random_int((int) sysConfig('min_rand_traffic'), (int) sysConfig('max_rand_traffic')) * MB;
if (! $user->incrementData($traffic)) {
return response()->json(['ret' => 0, 'title' => trans('common.failed'), 'msg' => trans('user.home.attendance.failed')]);
}
// 写入用户流量变动记录
Helpers::addUserTrafficModifyLog($user->id, null, $user->transfer_enable, $user->transfer_enable + $traffic, trans('user.home.attendance.attribute'));
// 多久后可以再签到
$ttl = sysConfig('traffic_limit_time') ? sysConfig('traffic_limit_time') * Minute : Day;
Cache::put('userCheckIn_'.$user->id, '1', $ttl);
return response()->json(['ret' => 1, 'msg' => trans('user.home.attendance.success', ['data' => flowAutoShow($traffic)])]);
}
}

View File

@@ -26,7 +26,7 @@ use Response;
class PaymentController extends Controller
{
private static $method;
public static $method;
public static function notify(Request $request): void
{

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class GoodsCategory extends Model
{
protected $table = 'goods_category';
protected $guarded = [];
public function goods(): HasMany
{
return $this->hasMany(Goods::class, 'category_id');
}
}

53
config/bobclient.php Normal file
View File

@@ -0,0 +1,53 @@
<?php
// ┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐ \\
// │ BobVPN │ \\
// ├───────────────────────────────────────────────────────────────────────────────────────────────────────┤ \\
// │ Copyright © 2021 (https://t.me/Bobs9) │ \\
// └───────────────────────────────────────────────────────────────────────────────────────────────────────┘ \\
return [
// 登录页面配置
'login' => [
'telegram_url' => 'https://t.me/Bobs9', // 留空的话则不展示telegram群
'qq_url' => 'https://t.me/Bobs9', // 留空的话则不展示QQ群
'background_img' => 'https://shige.group/such/pic.php/forum/pic/item/00e93901213fb80e3d28759b21d12f2eb8389484/mlike.jpg', // 背景图片地址,图片宽高不超过 860px * 544px 就行 (留空为默认的背景图)
'text' => '一键开启<br>极速上网体验',
'text_color' => 'rgba(255, 255, 255, 0.8);', // 文字和按钮颜色 默认颜色 rgba(255, 255, 255, 0.8);
'button_color' => '#8077f1', // 文字和按钮颜色 默认颜色:#8077f1(v2版本配置)
],
// PC端消息中心图片和跳转链接
'message' => [
'background_img' => 'https://malus.s3cdn.net/uploads/malus_user-guide.jpg', // 背景图片地址
'url' => 'https://www.goole.com', // 跳转链接
],
// Crisp在线客服
'crisp_enable' => false, // 是否开启
'crisp_id' => '2c3c28c2-9265-45ea-8e85-0xxxxx', // Crisp 的网站ID
// 弹窗公告
'notice' => [
'is_start' => true, // 是否开启弹窗公告
'title' => '最新公告', // 标题
'content' => '<strong>这是最新 <i>公告</i> 内容</strong>', // 公告内容可以为html格式也可以纯文本
],
// PC端菜单栏显示控制
'menu' => [
'shop' => true, // 会员
'user' => true, // 我的
'gift' => true, // 邀请
],
// 检查用户计算机时间
'check_time' => [
'is_check' => true, // 是否开启检查
'differ_time' => 90, // 相差多少秒提示
'warning_text' => '请校准系统时间为北京时间,否则会导致无法上网!', // 提示内容
],
// 个人中心头像
'user_avatar' => 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=4109802972,297162689&fm=11&gp=0.jpg',
];

View File

@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Spatie\Permission\Models\Permission;
class CreateGoodsCategoryTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('goods_category', function (Blueprint $table) {
$table->id();
$table->string('name')->default('')->comment('分类名称');
$table->tinyInteger('status')->default('1')->comment('状态 0隐藏 1显示');
$table->integer('sort')->default('0')->comment('排序');
$table->timestamps();
});
Schema::table('goods', function (Blueprint $table) {
$table->integer('category_id')->default(1)->nullable()->comment('分类ID');
});
\App\Models\GoodsCategory::query()->create(['name' => '黄金套餐']);
\App\Models\GoodsCategory::query()->create(['name' => '白金套餐']);
\App\Models\GoodsCategory::query()->create(['name' => '钻石套餐']);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('goods_category');
Schema::table('goods', function (Blueprint $table) {
$table->dropColumn(['category_id']);
});
}
}

View File

@@ -30,6 +30,9 @@
<li class="nav-item" role="presentation">
<a class="nav-link" data-toggle="tab" href="#label" aria-controls="label" role="tab">标签</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" data-toggle="tab" href="#category" aria-controls="category" role="tab">商品分类</a>
</li>
</ul>
<div class="tab-content py-15">
<div class="tab-pane active" id="method" role="tabpanel">
@@ -168,6 +171,40 @@
</tbody>
</table>
</div>
<div class="tab-pane" id="category" role="tabpanel">
<button class="btn btn-primary float-right mb-10" data-toggle="modal" data-target="#add_category_modal">
新增<i class="icon wb-plus"></i>
</button>
<table class="text-md-center" data-toggle="table" data-height="700" data-virtual-scroll="true" data-mobile-responsive="true">
<thead class="thead-default">
<tr>
<th> 名称</th>
<th> 排序</th>
<th> {{trans('common.action')}}</th>
</tr>
</thead>
<tbody>
@foreach($categories as $category)
<tr>
<td>
<input type="text" class="form-control" name="name" id="category_name_{{$category->id}}" value="{{$category->name}}"/>
</td>
<td>
<input type="text" class="form-control" name="sort" id="category_sort_{{$category->id}}" value="{{$category->sort}}"/>
</td>
<td>
<div class="btn-group">
<button type="button" class="btn btn-primary" onclick="updateCategory('{{$category->id}}')">
<i class="icon wb-edit" aria-hidden="true"></i></button>
<button type="button" class="btn btn-danger" onclick="delCategory('{{$category->id}}','{{$category->name}}')">
<i class="icon wb-trash"></i></button>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<div class="tab-pane" id="country" role="tabpanel">
<button class="btn btn-primary float-right mb-10" data-toggle="modal" data-target="#add_country_modal">
新增<i class="icon wb-plus"></i>
@@ -310,6 +347,34 @@
</div>
</div>
<div class="modal fade" id="add_category_modal" aria-hidden="true" role="dialog" tabindex="-1">
<div class="modal-dialog modal-simple modal-center">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">新增分类</h4>
</div>
<form action="#" method="post" class="modal-body">
<div class="alert alert-danger" style="display: none;" id="category_msg"></div>
<div class="row">
<div class="col-md-6 form-group">
<input type="text" class="form-control" name="name" id="add_category_name" placeholder="分类名称">
</div>
<div class="col-md-6 form-group">
<input type="text" class="form-control" name="sort" id="add_category_sort" placeholder="分类排序">
</div>
</div>
</form>
<div class="modal-footer">
<button data-dismiss="modal" class="btn btn-danger"> </button>
<button class="btn btn-primary" onclick="addCategory()"> </button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="add_country_modal" aria-hidden="true" role="dialog" tabindex="-1">
<div class="modal-dialog modal-simple modal-center">
<div class="modal-content">
@@ -476,6 +541,111 @@
swal.fire({title: '您没有权限修改参数!', icon: 'error', timer: 1500, showConfirmButton: false});
@endcan
@can('admin.config.category.store')
// 添加分类
function addCategory() {
const name = $('#add_category_name').val();
const sort = $('#add_category_sort').val();
if (name.trim() === '') {
$('#category_msg').show().html('分类名称不能为空');
$('#category_name').focus();
return false;
}
if (sort.trim() === '') {
$('#category_msg').show().html('分类排序不能为空');
$('#category_sort').focus();
return false;
}
$.ajax({
url: '{{route('admin.config.category.store')}}',
method: 'POST',
data: {_token: '{{csrf_token()}}', name: name, sort: sort},
beforeSend: function() {
$('#category_msg').show().html('正在添加');
},
success: function(ret) {
if (ret.status === 'fail') {
$('#category_msg').show().html(ret.message);
return false;
}
$('#add_category_modal').modal('hide');
window.location.reload();
},
error: function() {
$('#category_msg').show().html('请求错误,请重试');
},
complete: function() {
swal.fire({title: '添加成功', icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload());
},
});
}
@else
swal.fire({title: '您没有权限修改参数!', icon: 'error', timer: 1500, showConfirmButton: false});
@endcan
@can('admin.config.category.update')
// 更新分类
function updateCategory(id) {
$.ajax({
method: 'PUT',
url: '{{route('admin.config.category.update', '')}}/' + id,
data: {
_token: '{{csrf_token()}}',
name: $('#category_name_' + id).val(),
sort: $('#category_sort_' + id).val(),
},
dataType: 'json',
success: function(ret) {
if (ret.status === 'success') {
swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload());
} else {
swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload());
}
},
});
}
@else
swal.fire({title: '您没有权限修改参数!', icon: 'error', timer: 1500, showConfirmButton: false});
@endcan
@can('admin.config.category.destroy')
// 删除分类
function delCategory(id, name) {
swal.fire({
title: '确定删除分类 【' + name + '】 ',
icon: 'question',
allowEnterKey: false,
showCancelButton: true,
cancelButtonText: '{{trans('common.close')}}',
confirmButtonText: '{{trans('common.confirm')}}',
}).then((result) => {
if (result.value) {
$.ajax({
method: 'DELETE',
url: '{{route('admin.config.category.destroy', '')}}/' + id,
data: {_token: '{{csrf_token()}}'},
dataType: 'json',
success: function(ret) {
if (ret.status === 'success') {
swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload());
} else {
swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload());
}
},
});
}
});
}
@else
swal.fire({title: '您没有权限修改参数!', icon: 'error', timer: 1500, showConfirmButton: false});
@endcan
@can('admin.config.country.store')
// 添加国家/地区
function addCountry() {

View File

@@ -56,6 +56,16 @@
<span class="input-group-text"></span>
</div>
</div>
<div class="form-group row">
<label for="level" class="col-md-2 col-form-label">分类</label>
<div class="col-md-4">
<select data-plugin="selectpicker" data-style="btn-outline btn-primary" class="form-control" name="category_id" id="category_id">
@foreach ($categories as $category)
<option value="{{$category->id}}">{{$category->name}}</option>
@endforeach
</select>
</div>
</div>
<div class="form-group row">
<label for="level" class="col-md-2 col-form-label">等级</label>
<div class="col-md-4">
@@ -221,6 +231,7 @@
$('#color').asColorPicker('val', '{{$good->color}}');
$('#description').val(@json($good->description));
$('#info').val(@json($good->info));
$('#category_id').selectpicker('val', '{{$good->category_id}}');
const trafficUnit = $('#traffic_unit');
const traffic = $('#traffic');
@if($good->traffic >= 1073741824)

View File

@@ -94,6 +94,7 @@ Route::prefix('admin')->name('admin.')->group(function () {
Route::resource('label', 'LabelController')->only('store', 'update', 'destroy'); // 标签配置
Route::resource('level', 'LevelController')->only('store', 'update', 'destroy'); // 等级配置
Route::resource('ss', 'SsConfigController')->only('store', 'update', 'destroy'); // ss配置
Route::resource('category', 'CategoryController')->only('store', 'update', 'destroy'); // 商品分类配置
});
Route::resource('permission', 'PermissionController')->except('show');

View File

@@ -49,14 +49,21 @@ Route::group(['namespace' => 'Api\WebApi', 'middleware' => 'webApi'], function (
});
// 客户端API
Route::group(['namespace' => 'Api\Client', 'middleware' => 'api', 'prefix' => 'client/v1'], function () {
Route::group(['namespace' => 'Api\Client', 'prefix' => 'client/v1'], function () {
Route::get('config', 'V1Controller@getConfig'); // 获取配置
Route::post('login', 'V1Controller@login'); // 登录
Route::get('logout', 'V1Controller@logout'); // 退出
Route::get('refresh', 'V1Controller@refresh'); // 刷新令牌
Route::get('profile', 'V1Controller@userProfile'); // 获取账户信息
Route::get('nodes', 'V1Controller@nodeList'); // 获取账户全部节点
Route::get('node/{id}', 'V1Controller@nodeList'); // 获取账户个别节点
Route::post('register', 'V1Controller@register'); // 注册
Route::get('shop', 'V1Controller@shop'); // 获取商品信息
Route::group(['middleware' => 'auth:api'], function () {
Route::get('logout', 'V1Controller@logout'); // 退出
Route::get('refresh', 'V1Controller@refresh'); // 刷新令牌
Route::get('profile', 'V1Controller@userProfile'); // 获取账户信息
Route::get('nodes', 'V1Controller@nodeList'); // 获取账户全部节点
Route::get('node/{id}', 'V1Controller@nodeList'); // 获取账户个别节点
Route::get('shop', 'V1Controller@shop'); // 获取商品信息
Route::get('gift', 'V1Controller@gift'); // 获取邀请信息
Route::post('checkIn', 'V1Controller@checkIn'); // 签到
Route::post('payment/purchase', 'V1Controller@purchase'); // 获取商品信息
Route::get('payment/getStatus', 'V1Controller@getStatus'); // 获取商品信息
});
});