first commit

This commit is contained in:
2020-08-06 16:42:18 +08:00
commit eb792c34aa
12972 changed files with 1511424 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Admin\Actions\Coupon;
use App\Models\Coupon;
use App\Models\User;
use Encore\Admin\Actions\Action;
use Illuminate\Http\Request;
class Batch extends Action
{
public $name = '批量打款';
protected $selector = '.import-post';
public function handle(Request $request)
{
$user_id = $request->user_id;
$date = $request->date;
$list = Coupon::where('user_id', $user_id)->whereDate('created_at', $date)->where('status', 2)->get();
if ($list->isEmpty()) {
return $this->response()->error('打款失败!没有可处理的数据')->refresh();
}
$success = $error = 0;
foreach ($list as $key => $coupon) {
$res = $coupon->sendMoney();
if ($res === true) {
$success++;
} else {
$error++;
}
}
return $this->response()->success("处理完成,成功:{$success}条,失败:{$error}")->refresh();
}
public function form()
{
$users = User::query()
->whereHas('identity', function ($query) {
$query->where('identity_id', 1);
})
->where('type', 'pingan')
->get()
->pluck('nickname', 'id');
$this->select('user_id', '渠道')->options($users)->required();
// 时间日期选择
$this->date('date', '核销日期')->required();
}
public function html()
{
return <<<HTML
<a class="btn btn-sm btn-default import-post"><i class="fa fa-Yuan"></i>批量打款</a>
HTML;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Admin\Actions\Coupon;
use Encore\Admin\Actions\RowAction;
use Illuminate\Database\Eloquent\Model;
class BatchProfit extends RowAction
{
public $name = '打款';
public function handle(Model $model)
{
if ($model->canProfit()) {
$res = $model->sendMoney();
if ($res === true) {
return $this->response()->success('操作成功')->refresh();
} else {
return $this->response()->success($res)->refresh();
}
} else {
return $this->response()->success('操作失败')->refresh();
}
}
public function dialog()
{
$this->confirm('确定分润?');
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Admin\Actions\Coupon;
use Encore\Admin\Actions\BatchAction;
use Illuminate\Database\Eloquent\Collection;
class BatchProfits extends BatchAction
{
public $name = '批量打款';
public function handle(Collection $collection)
{
$success = $error = 0;
foreach ($collection as $model) {
$res = $model->sendMoney();
if ($res === true) {
$success++;
} else {
$error++;
}
}
return $this->response()->success('成功' . $success . '条,失败' . $error . '条')->refresh();
}
public function dialog()
{
$this->confirm('确定打款?');
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Admin\Actions\User;
use Encore\Admin\Actions\RowAction;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
class Profit extends RowAction
{
public $name = '设置分润';
public function handle(Model $model, Request $request)
{
$datas = $request->code;
$codes = $model->code;
foreach ($codes as $key => $code) {
$code->profit = round($datas[$code->id], 2);
$code->save();
}
return $this->response()->success('操作成功')->refresh();
}
public function form(Model $model)
{
$codes = $model->code;
foreach ($codes as $key => $code) {
$this->text("code[{$code->id}]", $code->name)->value($code->profit)->required();
}
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Admin\Actions\User;
use Encore\Admin\Actions\RowAction;
use Illuminate\Database\Eloquent\Model;
use RuLong\Identity\Models\Identity;
class ReCode extends RowAction
{
public $name = '重置规则';
public function handle(Model $model)
{
if ($model->identity_id != 1) {
return $this->response()->error('只有渠道才能刷新');
}
$all_codes = Identity::find(1)->codes;
$user_codes = $model->code;
if ($all_codes->count() == $user_codes->count()) {
return $this->response()->success('操作成功')->refresh();
}
foreach ($all_codes as $key => $code) {
$model->code()->updateOrCreate([
'code' => $code->code,
], [
'name' => $code->name,
'code' => $code->code,
'profit' => $code->profit,
]);
}
return $this->response()->success('操作成功')->refresh();
}
public function dialog()
{
$this->confirm('确定要重置卡券规则吗?刷新后将重置此渠道卡券规则');
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Admin\Actions\User;
use Encore\Admin\Actions\RowAction;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class RefD3Key extends RowAction
{
public $name = '刷新D3key';
public function handle(Model $model)
{
$model->des3key = Str::random(24);
$model->save();
return $this->response()->success('操作成功')->refresh();
}
public function dialog()
{
$this->confirm('确定要刷新D3key吗');
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Admin\Actions\User;
use App\Admin\Imports\User;
use Encore\Admin\Actions\Action;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
class UserImport extends Action
{
public $name = '导入网点编号';
protected $selector = '.import-post';
public $modelName = '';
public function handle(Request $request)
{
$res = Excel::import(new User, $request->file('file'), 'excel');
if ($res === true) {
return $this->response()->success('导入完成!')->refresh();
} else {
return $this->response()->error('失败' . $res)->refresh();
}
}
public function form()
{
$this->file('file', '请选择文件');
}
public function html()
{
return <<<HTML
<a class="btn btn-sm btn-default import-post"><i class="fa fa-upload"></i>导入数据</a>
HTML;
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Admin\Actions\User;
use Encore\Admin\Actions\RowAction;
use Encore\Admin\Form;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use RuLong\Identity\Models\Identity;
class UserUpgrade extends RowAction
{
public $name = '账号升级';
public function handle(Model $model, Request $request)
{
$identity_id = $request->identity_id;
$model->identityUpdate($identity_id, 'EmptyUp');
return $this->response()->success('升级成功')->refresh();
}
public function form(Model $model)
{
$identitys = Identity::where('id', '!=', $model->identity_id)->orderBy('id', 'asc')->pluck('title', 'id')->toArray();
$this->text('用户名称')->disable()->value($model->info->nickname);
$this->text('当前等级')->disable()->value($model->identity_text);
$this->select('identity_id', '目标等级')->options($identitys);
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace App\Admin\Actions\Wo;
use Encore\Admin\Actions\RowAction;
use Illuminate\Database\Eloquent\Model;
use Wo;
class Unsubscribe extends RowAction
{
public $name = '退订';
public function handle(Model $model)
{
$postData = [
'logNo' => $model->logNo,
];
//查询状态
$res = Wo::ticketQuery($postData, $model->user_id);
if (is_string($res)) {
return $this->response()->error($res)->refresh();
}
$ConfigTicketState = config('wo.ticketState');
$ConfigTicketStateText = config('wo.ticketStateText');
$ticketState = $res['ticketState'];
if (!in_array($ticketState, ['A', 'U'])) {
$msg = (array_key_exists($ticketState, $ConfigTicketStateText)) ? $ConfigTicketStateText[$ticketState] : '未知状态';
return $this->response()->error($msg)->refresh();
}
//判断数组中是否存在下标
if (!array_key_exists($ticketState, $ConfigTicketState)) {
return $this->response()->error('未知状态')->refresh();
}
$postData['service'] = $ConfigTicketState[$ticketState];
$postData['ologNo'] = $postData['logNo'];
//退业务
$res = Wo::ticketBack($postData, $model->user);
if (is_string($res)) {
return $this->response()->error($res)->refresh();
}
return $this->response()->success($res)->refresh();
}
public function dialog()
{
$this->confirm('确定要退订吗?');
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Admin\Controllers\Account;
use App\Models\Account;
use App\Models\User;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
class IndexController extends AdminController
{
protected $title = '账户管理';
protected function grid()
{
$grid = new Grid(new Account);
$grid->model()->whereHasMorph(
'accountable',
User::class,
function ($query) {
$query->where('type', 'pingan')->whereHas('identity', function ($q) {
$q->where('identity_id', 1);
});
}
);
$grid->disableActions();
$grid->disableCreateButton();
// $grid->column('所属项目')->display(function () {
// return $this->accountable->type_text;
// });
$grid->column('渠道名称')->display(function () {
return $this->accountable->name ?? $this->accountable->nickname;
});
$grid->column('balance', '总分润');
$grid->column('score', '已打款');
// $grid->column('updated_at', '更新时间');
$grid->column('日志')->display(function () {
return '<a href="' . admin_url('accounts/logs?id=' . $this->id) . '">账户日志</a>';
});
return $grid;
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace App\Admin\Controllers\Account;
use App\Models\AccountLog;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
class LogController extends AdminController
{
protected $title = '账户日志';
function grid()
{
$grid = new Grid(new AccountLog);
$userId = request()->user_id;
$grid->model()->when($userId, function ($query, $userId) {
$query->where('user_id', $userId);
});
$grid->disableActions();
$grid->disableCreateButton();
$grid->filter(function ($filter) {
$filter->column(1 / 3, function ($filter) {
$filter->like('rule.title', '触发规则');
$filter->equal('type', '账户类型')->select(config('account.account_type'));
});
// $filter->column(1 / 3, function ($filter) {
// $filter->where(function ($query) {
// $query->whereHas('user', function ($query) {
// $query->whereHas('info', function ($query) {
// $query->where('nickname', 'like', "%{$this->input}%");
// });
// });
// }, '会员姓名');
// $filter->between('variable', '变量');
// });
$filter->column(1 / 3, function ($filter) {
$filter->equal('frozen', '冻结')->select([
0 => '否',
1 => '是',
]);
$filter->between('created_at', '创建时间')->datetime();
});
});
// $grid->column('user.username', '会员账号');
// $grid->column('user.nickname', '会员姓名');
$grid->column('rule.title', '触发规则');
$grid->column('type', '类型')->using(config('account.account_type'));
$grid->column('variable', '变量');
$grid->column('balance', '余额');
$grid->column('frozen', '冻结')
->using([0 => '否', 1 => '是'])
->label([
0 => 'success',
1 => 'warning',
]);
$grid->column('created_at', '获取时间');
return $grid;
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace App\Admin\Controllers\Account;
use App\Models\AccountRule;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Illuminate\Validation\Rule;
class RuleController extends AdminController
{
/**
* Title for current resource.
*
* @var string
*/
protected $title = '账户规则';
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
$grid = new Grid(new AccountRule);
$grid->tools(function (Grid\Tools $tools) {
$tools->batch(function ($batch) {
$batch->disableDelete();
});
});
$grid->quickSearch('title')->placeholder('规则名称');
$grid->filter(function ($filter) {
$filter->column(1 / 3, function ($filter) {
$filter->like('title', '规则名称');
});
$filter->column(1 / 3, function ($filter) {
$filter->like('name', '调用标记');
});
$filter->column(1 / 3, function ($filter) {
$filter->equal('type', '账户类型')->select([
'cash' => '现金账户',
'score' => '积分账户',
]);
});
});
$grid->column('id', '编号');
$grid->column('title', '规则名称');
$grid->column('name', '调用标记');
$grid->column('type', '账户类型')->using(config('account.account_type'));
$grid->column('variable', '增减变量');
$grid->column('trigger', '频率')->display(function () {
return $this->trigger_text;
});
$grid->column('deductions', '立即处理')->bool();
$grid->column('remark', '备注');
$grid->column('created_at', '创建时间');
$grid->column('updated_at', '更新时间');
return $grid;
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
$form = new Form(new AccountRule);
$form->text('title', '规则名称')
->rules('required|between:2,50');
$form->text('name', '调用标记')
->creationRules('required|alpha_dash|between:2,50|unique:account_rules')
->updateRules('required|alpha_dash|between:2,50|unique:account_rules,name,{{id}}');
$form->select('type', '账户类型')
->options(config('account.account_type'))
->rules(['required', Rule::in(array_keys(config('account.account_type')))]);
$form->number('variable', '增减变量')
->value(0)
->rules('required|numeric');
$form->number('trigger', '次数限制')->value(0)
->help('执行次数限制小于0则终身一次等于0不限制大于0每日N次')
->rules('required|integer');
$states = [
'on' => ['value' => 1, 'text' => '打开'],
'off' => ['value' => 0, 'text' => '关闭'],
];
$form->switch('deductions', '立即处理')->value(1)->states($states);
$form->textarea('remark', '备注信息')->rules('nullable|max:255');
return $form;
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace App\Admin\Controllers\Activity;
use App\Models\ActivityCoupon;
use App\Models\ActivityRule;
use App\Models\User;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
class CouponController extends AdminController
{
protected $title = '卡券列表管理';
protected function grid()
{
$grid = new Grid(new ActivityCoupon);
$grid->model()->latest();
$grid->disableActions();
$grid->disableCreateButton();
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->equal('status', '状态')->select(ActivityCoupon::STATUS);
$filter->between('used_at', '核销时间')->datetime();
$users = User::whereHas('identity', function ($query) {
$query->where('identity_id', 1);
})->get()->pluck('nickname', 'id');
$filter->equal('activity.user_id', '渠道')->select(array_merge(['0' => '系统'], $users->toArray()));
});
$filter->column(1 / 2, function ($filter) {
$filter->like('redemptionCode', '平安券编号');
$filter->where(function ($query) {
$query->whereHas('activity', function ($query) {
$query->whereHas('rule', function ($query) {
$query->where('code', $this->input);
});
});
}, '优惠政策', 'rule_code')->select(ActivityRule::where('status', 1)->pluck('title', 'code'));
});
});
$grid->column('id', '#ID#');
$grid->column('activity.title', '卡券名称');
$grid->column('mobile', '手机号');
$grid->column('优惠政策')->display(function () {
return $this->activity->rule->title;
});
$grid->column('agent', '所属渠道')->display(function () {
return $this->activity->user_nickname;
});
$grid->column('code', '卡券编号');
$grid->column('status', '状态')
->using(ActivityCoupon::STATUS)
->label([
1 => 'default',
2 => 'warning',
3 => 'info',
]);
$grid->column('used_at', '核销时间');
$grid->column('created_at', '创建时间');
return $grid;
}
}

View File

@@ -0,0 +1,127 @@
<?php
namespace App\Admin\Controllers\Activity;
use App\Models\Activity;
use App\Models\ActivityRule;
use App\Models\User;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Illuminate\Support\MessageBag;
class IndexController extends AdminController
{
protected $title = '活动管理';
protected function grid()
{
$grid = new Grid(new Activity);
$grid->actions(function ($actions) {
$actions->disableView();
});
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->equal('status', '状态')->select(Activity::STATUS);
$filter->equal('type', '类型')->select(Activity::TYPES);
$users = User::whereHas('identity', function ($query) {
$query->where('identity_id', 1);
})->get()->pluck('nickname', 'id');
$filter->equal('user_id', '渠道')->select($users);
});
$filter->column(1 / 2, function ($filter) {
$filter->between('start_at', '开始时间')->datetime();
$filter->between('end_at', '结束时间')->datetime();
});
});
$grid->column('id', '#ID#');
$grid->column('title', '活动名称');
$grid->column('code', '活动编号');
$grid->column('rule.code', '卡券规则');
$grid->column('所属')->display(function () {
return $this->user_id ? $this->user->nickname : '系统券';
});
$grid->column('类型')->display(function () {
return $this->type_text;
});
$grid->column('days', '延期(天)');
$grid->column('rule.full', '满足金额');
$grid->column('rule.take', '扣除金额');
$grid->column('开始时间')->display(function () {
return $this->type == Activity::TYPE_SCOPE ? $this->start_at->format('Y-m-d') : '---';
});
$grid->column('结束时间')->display(function () {
return $this->type == Activity::TYPE_SCOPE ? $this->end_at->format('Y-m-d') : '---';
});
$grid->status('状态')->switch([
'on' => ['value' => 1, 'text' => '正常', 'color' => 'primary'],
'off' => ['value' => 0, 'text' => '关闭', 'color' => 'danger'],
]);
$grid->column('created_at', '创建时间');
return $grid;
}
/**
* Make a form builder.
* @return Form
*/
protected function form()
{
$form = new Form(new Activity);
$form->text('title', '活动名称')->required();
$form->textarea('description', '活动说明')->required();
$form->select('user_id', '隶属渠道')
->options(function ($option, $info) {
return User::with('info')->whereHas('identity', function ($q) {
$q->where('identity_id', 1);
})->orderBy('id', 'desc')->get()->pluck('nickname', 'id');
});
$form->select('activity_rule_id', '所属规则')
->options(function ($option, $info) {
return ActivityRule::where('status', 1)->pluck('title', 'id');
})
->required();
$form->radio('type', '类型')
->options(Activity::TYPES)
->when(Activity::TYPE_EXTEND, function (Form $form) {
$form->number('days', '延期天数')->default(60)->help('到期日期=发券日期+延期天数');
})
->when(Activity::TYPE_SCOPE, function (Form $form) {
$form->dateRange('start_at', 'end_at', '有效时间');
})
->required();
$form->switch('status', '状态')->default(1);
$form->saving(function (Form $form) {
$request = request();
if ($request->type == Activity::TYPE_EXTEND && empty($request->days)) {
$error = new MessageBag([
'title' => '错误',
'message' => '必须添加延期天数',
]);
return back()->withInput()->with(compact('error'));
}
});
return $form;
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace App\Admin\Controllers\Activity;
use App\Models\ActivityRule;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
class RuleController extends AdminController
{
protected $title = '规则管理';
protected function grid()
{
$grid = new Grid(new ActivityRule);
$grid->actions(function ($actions) {
$actions->disableView();
});
$grid->column('id', '#ID#');
$grid->column('title', '规则名称');
$grid->column('code', '规则编号');
$grid->column('full', '满足金额');
$grid->column('take', '扣除金额');
$grid->status('状态')->switch([
'on' => ['value' => 1, 'text' => '正常', 'color' => 'primary'],
'off' => ['value' => 0, 'text' => '关闭', 'color' => 'danger'],
]);
$grid->column('created_at', '创建时间');
return $grid;
}
/**
* Make a form builder.
* @return Form
*/
protected function form()
{
$form = new Form(new ActivityRule);
$form->text('title', '规则名称')->required();
$form->text('code', '规则编号')->required()->help('列YSD-full100-15');
$form->decimal('full', '满足金额')->required()->default(0);
$form->decimal('take', '抵扣金额')->required()->default(0);
$form->switch('status', '状态')->default(1);
return $form;
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Admin\Controllers\Ajax;
use App\Models\Area;
use DB;
use Illuminate\Http\Request;
class AreaController
{
public function children(Request $request)
{
$code = $request->get('q');
return Area::whereHas('parent', function ($q) use ($code) {
$q->where('code', $code);
})->get(['code as id', DB::raw('name as text')]);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace App\Admin\Controllers;
use Encore\Admin\Controllers\AuthController as BaseAuthController;
class AuthController extends BaseAuthController
{
}

View File

@@ -0,0 +1,194 @@
<?php
namespace App\Admin\Controllers\Coupon;
use App\Admin\Exporters\CouponExport;
use App\Models\Coupon;
use App\Models\User;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
class IndexController extends AdminController
{
protected $title = '卡券列表';
/**
* Notes:
* @Author: <C.Jason>
* @Date : 2019/9/18 14:50
* @return Grid
*/
protected function grid()
{
$grid = new Grid(new Coupon);
$grid->disableCreateButton();
$grid->disableBatchActions();
$grid->disableActions();
$grid->model()->whereIn('status', [2, 3])->orderBy('id', 'desc');
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->equal('status', '状态')->select([
'2' => '核销成功',
'3' => '核销失败',
]);
$filter->between('created_at', '核销时间')->datetime();
$users = User::query()
->whereHas('identity', function ($query) {
$query->where('identity_id', 1);
})
->where('type', 'pingan')
->get()
->pluck('nickname', 'id');
$filter->equal('user_id', '渠道')->select($users);
$filter->equal('thirdPartyGoodsId', '优惠政策')->select([
'YSD-full100-10' => '100减10元',
'YSD-full100-25' => '100减25元',
'YSD-full100-50' => '100减50元',
'YSD-full200-100' => '200减100元',
]);
});
$filter->column(1 / 2, function ($filter) {
$filter->like('redemptionCode', '平安券编号');
$filter->where(function ($query) {
$query->whereHas('outlet', function ($query) {
$query->whereHas('info', function ($query) {
$query->where('nickname', 'like', "%{$this->input}%");
});
});
}, '网点名称');
});
});
$grid->column('id', '#ID#');
$grid->column('渠道')->display(function () {
return $this->user->nickname;
});
$grid->column('网点名称/编号')->display(function () {
return $this->outlet ? $this->outlet->nickname : $this->outletId;
});
$grid->column('redemptionCode', '平安券编号');
$grid->column('couponName', '优惠政策');
$grid->column('price', '核销金额');
$grid->column('资金通道结算')->display(function () {
$profit = $this->status == 2 ? $this->profit : '0.00';
return '<span style="color:red">' . $profit . '</span>';
});
$grid->column('状态')->display(function () {
switch ($this->status) {
case 2:
return '<span style="color:green">' . $this->status_text . '</span>';
break;
case 3:
return '<span style="color:red">' . $this->status_text . '</span>';
break;
default:
return $this->status_text;
break;
}
});
$grid->column('remark', '处理结果');
$grid->column('startTime', '起始时间');
$grid->column('endTime', '到期时间');
$grid->column('created_at', '核销时间');
$grid->column('省')->display(function () {
return ($this->outlet && $this->outlet->province) ? $this->outlet->province->name : '';
});
$grid->column('市')->display(function () {
return ($this->outlet && $this->outlet->province) ? $this->outlet->city->name : '';
});
$grid->column('区')->display(function () {
return ($this->outlet && $this->outlet->province) ? $this->outlet->district->name : '';
});
$grid->footer(function ($query) {
$all = $query->get();
$pass = $all->where('status', 2)->all();
$pass = collect($pass);
return '<label class="label label-success">全部:' . $all->count() . '张</label>&nbsp;&nbsp;'
. '<label class="label label-success">成功:' . $pass->count() . '张</label>&nbsp;&nbsp;'
. '<label class="label label-success">失败:' . $all->where('status', 3)
->count() . '张</label>&nbsp;&nbsp;'
. '<label class="label label-success">核销金额:' . $pass->sum('price') . '元</label>&nbsp;&nbsp;'
. '<label class="label label-success">资金通道结算:' . $pass->sum('profit') . '元</label>&nbsp;&nbsp;'
. '<label class="label label-success">打款金额:' . $pass->where('is_profit', 1)
->sum('profit') . '元</label>&nbsp;&nbsp;';
});
$grid->disableExport(false);
$grid->export(function ($export) {
$export->column('状态', function ($value, $original) {
return strip_tags($value);
});
$export->column('redemptionCode', function ($value, $original) {
return $value . "\t";
});
$export->column('price', function ($value, $original) {
return $value . "\t";
});
$export->column('资金通道结算', function ($value, $original) {
return strip_tags($value) . "\t";
});
$export->filename('卡券列表' . date("YmdHis"));
});
return $grid;
}
/**
* Make a form builder.
* @return Form
*/
protected function form()
{
$form = new Form(new Gift);
$form->text('title', '商品名称')->required();
$form->decimal('price', '价格')->required()->default('1');
$form->decimal('pv', 'PV')->required()->default(0);
$form->decimal('bonus', '主播佣金')->required()->default(0);
$form->decimal('recommend', '推荐人佣金')->required()->default(0);
$form->number('hots', '热度/亲密度')->required()->default('1');
$form->text('times', '显示时间')
->default('200')
->required()
->help('礼物显示时间,毫秒');
$form->textarea('description', '礼物说明');
$form->image('cover', '封面')
->rules(function ($form) {
if ($form->model()->cover != '') {
return 'nullable|image';
} else {
return 'required';
}
})
->move('images/' . date('Y/m/d'))
->removable()
->uniqueName();
$form->switch('status', '状态')->default(1);
$form->decimal('sort', '排序')->default(0)->help('序号越大越靠前');
$form->saving(function ($form) {
$sum = (int)$form->pv + (int)$form->bonus + (int)$form->recommend;
if ((int)$sum > $form->price) {
admin_warning('配置错误', 'PV+佣金+推荐人佣金不能超过礼物价值');
throw new \Exception('配置错误,PV+佣金+推荐人佣金不能超过礼物价值');
}
});
return $form;
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace App\Admin\Controllers\Finance;
use App\Models\User;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
class CensusController extends AdminController
{
protected $today = false;
/**
* Index interface.
*
* @param Content $content
* @return Content
*/
public function index(Content $content)
{
return $content
->header('核销总数据')
->description('description')
->body($this->grid());
}
/**
* 今日核销数据
* @param Content $content [description]
* @return [type] [description]
*/
public function today(Content $content)
{
$this->today = true;
return $content
->header('核销今日数据')
->description('description')
->body($this->grid());
}
protected function grid()
{
$grid = new Grid(new User);
$grid->model()->whereHas('identity', function ($q) {
$q->where('identity_id', 1);
})->where('type', 'pingan');
$grid->disableCreateButton();
$grid->disableBatchActions();
$grid->disableActions();
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->where(function ($query) {
$query->whereHas('info', function ($query) {
$query->where('nickname', 'like', "%{$this->input}%");
});
}, '渠道名称');
});
});
$grid->column('渠道')->display(function () {
return $this->info->nickname;
});
$today = $this->today;
$grid->column('100元减10元优惠券')->display(function () use ($today) {
return $this->getCouponCount('YSD-full100-10', $today);
});
$grid->column('100元减25元优惠券')->display(function () use ($today) {
return $this->getCouponCount('YSD-full100-25', $today);
});
$grid->column('100元减50元优惠券')->display(function () use ($today) {
return $this->getCouponCount('YSD-full100-50', $today);
});
$grid->column(' 200元减100元优惠券')->display(function () use ($today) {
return $this->getCouponCount('YSD-full200-100', $today);
});
return $grid;
}
}

View File

@@ -0,0 +1,159 @@
<?php
namespace App\Admin\Controllers\Finance;
use App\Admin\Actions\Coupon\Batch;
use App\Admin\Actions\Coupon\BatchProfit;
use App\Admin\Actions\Coupon\BatchProfits;
use App\Admin\Exporters\CouponPassExport;
use App\Models\Coupon;
use App\Models\User;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
class IndexController extends AdminController
{
protected $title = '平安渠道打款处理';
/**
* Notes:
* @Author: <C.Jason>
* @Date : 2019/9/18 14:50
* @return Grid
*/
protected function grid()
{
$grid = new Grid(new Coupon);
$grid->disableCreateButton();
$grid->disableBatchActions(false);
$grid->tools(function (Grid\Tools $tools) {
$tools->append(new Batch);
$tools->batch(function ($batch) {
$batch->disableDelete();
$batch->add(new BatchProfits);
});
});
$grid->actions(function (Grid\Displayers\Actions $actions) {
$actions->disableView();
$actions->disableEdit();
$actions->disableDelete();
if ($actions->row->canProfit()) {
$actions->add(new BatchProfit);
}
});
$grid->model()->where('status', 2)->orderBy('id', 'desc');
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->equal('is_profit', '打款')->select([
'0' => '未打款',
'1' => '已打款',
]);
$filter->between('created_at', '核销时间')->datetime();
$filter->between('paid_at', '打款时间')->datetime();
$users = User::query()
->whereHas('identity', function ($query) {
$query->where('identity_id', 1);
})
->where('type', 'pingan')
->get()
->pluck('nickname', 'id');
$filter->equal('user_id', '渠道')->select($users);
});
$filter->column(1 / 2, function ($filter) {
$filter->like('redemptionCode', '平安券编号');
$filter->where(function ($query) {
$query->whereHas('outlet', function ($query) {
$query->whereHas('info', function ($query) {
$query->where('nickname', 'like', "%{$this->input}%");
});
});
}, '渠道名称');
});
});
$grid->column('id', '#ID#');
$grid->column('渠道')->display(function () {
return $this->user->nickname;
});
$grid->column('网点名称/编号')->display(function () {
return $this->outlet ? $this->outlet->nickname : $this->outletId;
});
$grid->column('redemptionCode', '平安券编号');
$grid->column('couponName', '优惠政策');
$grid->column('price', '核销金额');
$grid->column('profit', '资金通道结算');
$grid->column('状态')->display(function () {
switch ($this->status) {
case 2:
return '<span style="color:green">' . $this->status_text . '</span>';
break;
case 3:
return '<span style="color:red">' . $this->status_text . '</span>';
break;
default:
return $this->status_text;
break;
}
});
$grid->column('打款')->display(function () {
switch ($this->is_profit) {
case 0:
return '<span style="color:green">未打款</span>';
break;
case 1:
return '<span style="color:red">已打款</span>';
break;
default:
return '未知';
break;
}
});
$grid->column('paid_at', '打款时间');
$grid->column('created_at', '核销时间');
$grid->footer(function ($query) {
$all = $query->get();
$pass = $query->where('status', 2)->get();
$reject = $query->where('status', 3)->get();
return '<label class="label label-success">全部:' . $all->count() . '张</label>&nbsp;&nbsp;'
. '<label class="label label-success">核销金额:' . $pass->sum('price') . '元</label>&nbsp;&nbsp;'
. '<label class="label label-success">资金通道结算:' . $pass->sum('profit') . '元</label>&nbsp;&nbsp;'
. '<label class="label label-success">打款金额:' . $pass->where('is_profit', 1)
->sum('profit') . '元</label>&nbsp;&nbsp;';
});
$grid->disableExport(false);
$grid->export(function ($export) {
$export->column('状态', function ($value, $original) {
return strip_tags($value);
});
$export->column('打款', function ($value, $original) {
return strip_tags($value);
});
$export->column('redemptionCode', function ($value, $original) {
return $value . "\t";
});
$export->column('price', function ($value, $original) {
return $value . "\t";
});
$export->column('profit', function ($value, $original) {
return strip_tags($value) . "\t";
});
$export->filename('平安渠道打款处理' . date("YmdHis"));
});
return $grid;
}
}

View File

@@ -0,0 +1,111 @@
<?php
namespace App\Admin\Controllers\Finance;
use App\Admin\Exporters\CouponProfitExport;
use App\Models\Coupon;
use App\Models\User;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
class LogController extends AdminController
{
protected $title = '已打款记录';
/**
* Notes:
* @Author: <C.Jason>
* @Date : 2019/9/18 14:50
* @return Grid
*/
protected function grid()
{
$grid = new Grid(new Coupon);
$grid->model()->where('profit', '>', 0);
$grid->disableCreateButton();
$grid->disableBatchActions();
$grid->disableActions();
$grid->model()->where('is_profit', 1)->orderBy('id', 'desc');
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->between('paid_at', '打款时间')->datetime();
$users = User::query()
->whereHas('identity', function ($query) {
$query->where('identity_id', 1);
})
->where('type', 'pingan')
->get()
->pluck('nickname', 'id');
$filter->equal('user_id', '渠道')->select($users);
});
$filter->column(1 / 2, function ($filter) {
$filter->like('redemptionCode', '平安券编号');
$filter->where(function ($query) {
$query->whereHas('outlet', function ($query) {
$query->whereHas('info', function ($query) {
$query->where('nickname', 'like', "%{$this->input}%");
});
});
}, '网点名称');
});
});
$grid->column('id', '#ID#');
$grid->column('渠道')->display(function () {
return $this->user->nickname;
});
$grid->column('网点名称/编号')->display(function () {
return $this->outlet ? $this->outlet->nickname : $this->outletId;
});
$grid->column('redemptionCode', '平安券编号');
$grid->column('couponName', '优惠政策');
$grid->column('price', '核销金额');
$grid->column('profit', '资金通道结算');
$grid->column('paid_at', '打款时间');
$grid->footer(function ($query) {
$all = $query->get();
$pass = $query->where('status', 2)->get();
$reject = $query->where('status', 3)->get();
return '<label class="label label-success">全部:' . $all->count() . '张</label>&nbsp;&nbsp;'
. '<label class="label label-success">核销金额:' . $pass->sum('price') . '元</label>&nbsp;&nbsp;'
. '<label class="label label-success">资金通道结算:' . $pass->sum('profit') . '元</label>&nbsp;&nbsp;'
. '<label class="label label-success">打款金额:' . $pass->where('is_profit', 1)
->sum('profit') . '元</label>&nbsp;&nbsp;';
});
$grid->disableExport(false);
$grid->export(function ($export) {
$export->column('状态', function ($value, $original) {
return strip_tags($value);
});
$export->column('打款', function ($value, $original) {
return strip_tags($value);
});
$export->column('redemptionCode', function ($value, $original) {
return $value . "\t";
});
$export->column('网点名称/编号', function ($value, $original) {
return $value . "\t";
});
$export->column('price', function ($value, $original) {
return $value . "\t";
});
$export->column('profit', function ($value, $original) {
return strip_tags($value) . "\t";
});
$export->filename('已打款记录' . date("YmdHis"));
});
return $grid;
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace App\Admin\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Coupon;
use App\Models\User;
use Encore\Admin\Layout\Column;
use Encore\Admin\Layout\Content;
use Encore\Admin\Layout\Row;
use Encore\Admin\Widgets\InfoBox;
class HomeController extends Controller
{
public function index(Content $content)
{
return $content
->title('数据看版')
->row(function (Row $row) {
$row->column(2, function (Column $column) {
$column->append(new InfoBox('渠道商', 'users', 'yellow', '/admin/users?identity[identity_id]=1', User::whereHas('identity', function ($q) {$q->where('identity_id', 1);})->count()));
});
})
->row(function (Row $row) {
$row->column(2, function (Column $column) {
$column->append(new InfoBox('核销卡券总数', '', 'blue', '/admin/coupons', Coupon::whereIn('status', [2, 3])->count()));
});
$row->column(2, function (Column $column) {
$column->append(new InfoBox('核销成功', '', 'blue', '/admin/coupons', Coupon::where('status', 2)->count()));
});
$row->column(2, function (Column $column) {
$column->append(new InfoBox('核销失败', '', 'black', '/admin/coupons', Coupon::where('status', 3)->count()));
});
$row->column(2, function (Column $column) {
$column->append(new InfoBox('资金通道结算', '', 'red', '/admin/coupons', Coupon::where('status', 2)->sum('price')));
});
$row->column(2, function (Column $column) {
$column->append(new InfoBox('应打款金额', '', 'green', '/admin/coupons', Coupon::where('status', 2)->sum('profit')));
});
$row->column(2, function (Column $column) {
$column->append(new InfoBox('已打款金额', '', 'green', '/admin/coupons', Coupon::where('status', 2)->where('is_profit', 1)->sum('profit')));
});
})
->row(function (Row $row) {
$coupons = Coupon::where('status', 2)
->whereDate('created_at', now()->format('Y-m-d'))
->get();
$lists = [
'ysd10' => $coupons->where('thirdPartyGoodsId', 'YSD-full100-10')->count(),
'ysd25' => $coupons->where('thirdPartyGoodsId', 'YSD-full100-25')->count(),
'ysd50' => $coupons->where('thirdPartyGoodsId', 'YSD-full100-50')->count(),
'ysd100' => $coupons->where('thirdPartyGoodsId', 'YSD-full200-100')->count(),
];
$row->column(2, function (Column $column) use ($lists) {
$column->append(new InfoBox('100元减10元成功今日总数', '', 'blue', '/admin/coupons', $lists['ysd10']));
});
$row->column(2, function (Column $column) use ($lists) {
$column->append(new InfoBox('100元减25元成功今日总数', '', 'blue', '/admin/coupons', $lists['ysd25']));
});
$row->column(2, function (Column $column) use ($lists) {
$column->append(new InfoBox('100元减50元成功今日总数', '', 'blue', '/admin/coupons', $lists['ysd50']));
});
$row->column(2, function (Column $column) use ($lists) {
$column->append(new InfoBox('200元减100元成功今日总数', '', 'blue', '/admin/coupons', $lists['ysd100']));
});
})
->row(function (Row $row) {
$coupons = Coupon::where('status', 2)->get();
$lists = [
'ysd10' => $coupons->where('thirdPartyGoodsId', 'YSD-full100-10')->count(),
'ysd25' => $coupons->where('thirdPartyGoodsId', 'YSD-full100-25')->count(),
'ysd50' => $coupons->where('thirdPartyGoodsId', 'YSD-full100-50')->count(),
'ysd100' => $coupons->where('thirdPartyGoodsId', 'YSD-full200-100')->count(),
];
$row->column(2, function (Column $column) use ($lists) {
$column->append(new InfoBox('100元减10元成功总数', '', 'blue', '/admin/coupons', $lists['ysd10']));
});
$row->column(2, function (Column $column) use ($lists) {
$column->append(new InfoBox('100元减25元成功总数', '', 'blue', '/admin/coupons', $lists['ysd25']));
});
$row->column(2, function (Column $column) use ($lists) {
$column->append(new InfoBox('100元减50元成功总数', '', 'blue', '/admin/coupons', $lists['ysd50']));
});
$row->column(2, function (Column $column) use ($lists) {
$column->append(new InfoBox('200元减100元成功总数', '', 'blue', '/admin/coupons', $lists['ysd100']));
});
});
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace App\Admin\Controllers;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Widgets\Table;
use RuLong\Identity\Models\Identity;
class IdentityController extends AdminController
{
protected $title = '用户身份配置';
protected function grid()
{
$grid = new Grid(new Identity);
$grid->disableCreateButton();
$grid->disableFilter();
$grid->disableExport();
$grid->disableRowSelector();
$grid->tools(function ($tools) {
$tools->batch(function ($batch) {
$batch->disableDelete();
});
});
$grid->actions(function ($actions) {
$actions->disableDelete();
$actions->disableView();
});
$grid->fixColumns(0, 0);
$grid->model()->orderBy('id', 'asc');
$grid->column('id', '身份编号')->sortable();
$grid->column('title', '身份');
$grid->column('name', '等级');
$grid->column('分润规则')->display(function ($title, $column) {
return '点击查看';
})->modal(function ($model) {
$codes = $model->codes->map(function ($code) {
return $code->only(['name', 'code', 'profit']);
});
return new Table(['名称', '规则项', '分润金额(元)'], $codes->toArray());
});
$grid->column('remark', '说明');
$grid->column('updated_at', '修改时间');
return $grid;
}
protected function form()
{
$form = new Form(new Identity);
$form->display('id', 'ID');
$form->text('title', '级别')->rules('required');
$form->text('name', '等级')->rules('required');
$form->hasMany('codes', '分润项目', function (Form\NestedForm $form) {
$form->text('name', '标题');
$form->text('code', '分润的项目');
$form->text('profit', '分润金额');
});
$form->textarea('remark', '说明')->rules('required');
$form->tools(function (Form\Tools $tools) {
$tools->disableDelete();
$tools->disableView();
});
$form->footer(function ($footer) {
$footer->disableReset();
$footer->disableViewCheck();
$footer->disableCreatingCheck();
});
return $form;
}
}

View File

@@ -0,0 +1,83 @@
<?php
namespace App\Admin\Controllers\Log;
use App\Models\Log;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
use Encore\Admin\Widgets\Table;
class IndexController extends AdminController
{
protected $title = 'api 日志';
/**
* Notes:
* @Author: <C.Jason>
* @Date: 2019/9/18 14:50
* @return Grid
*/
protected function grid()
{
$grid = new Grid(new Log);
$grid->model()->orderBy('id', 'desc');
$grid->disableActions();
$grid->filter(function ($filter) {
$filter->equal('type', '接口类型')->select([
'pingan' => '平安',
'self' => '自己',
]);
$filter->where(function ($query) {
$query->where("in_source->query->redemptionCode", $this->input);
}, '券码');
$filter->between('created_at', '提交时间')->datetime();
});
$grid->column('id', '#ID#');
// $grid->column('path', '请求地址');
$grid->column('请求地址')->display(function ($title, $column) {
return '展开';
})->expand(function ($model) {
$header = ['请求地址'];
$array = [[$model->path]];
return new Table($header, $array);
});
$grid->column('method', '模式');
// $grid->column('in_source', '请求参数');
$grid->column('请求参数')->display(function () {
$in_source = $this->in_source;
unset($in_source['merchantSign']);
unset($in_source['merchantCert']);
unset($in_source['sign']);
unset($in_source['data']);
unset($in_source['json']);
unset($in_source['query']['merchantSign']);
unset($in_source['query']['merchantCert']);
return $in_source;
});
// $grid->column('out_source', '返回信息');
$grid->column('返回信息')->display(function () {
$out_source = $this->out_source;
if (!is_array($out_source)) {
return $out_source;
}
unset($out_source['merchantSign']);
unset($out_source['merchantCert']);
unset($out_source['serverCert']);
unset($out_source['serverSign']);
unset($out_source['data']);
return $out_source;
});
$grid->column('created_at', '提交时间');
return $grid;
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Admin\Controllers;
use Encore\Admin\Controllers\AdminController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class UploadController extends AdminController
{
public function editor(Request $request)
{
$files = $request->file("image");
if (empty($files)) {
return response()->json(['errno' => 5, 'msg' => '请选择文件']);
}
foreach ($files as $file) {
$path = $file->store(
'editor/' . date('Y/m/d'),
config('admin.upload.disk')
);
$data[] = Storage::disk(config('admin.upload.disk'))->url($path);
}
return ['errno' => 0, 'data' => $data];
}
}

View File

@@ -0,0 +1,278 @@
<?php
namespace App\Admin\Controllers\User;
use App\Admin\Actions\User\Profit;
use App\Admin\Actions\User\ReCode;
use App\Admin\Actions\User\RefD3Key;
use App\Admin\Exporters\UsersExport;
use App\Models\Area;
use App\Models\User;
use Auth;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Widgets\Table;
use Illuminate\Http\Request;
use RuLong\Identity\Models\Identity;
class IndexController extends AdminController
{
protected $title = '用户管理';
/**
* Notes:
* @Author: <C.Jason>
* @Date : 2019/9/18 14:50
* @return Grid
*/
protected function grid()
{
$user = Auth::guard('admin')->user();
$grid = new Grid(new User);
$grid->actions(function ($actions) use ($user) {
$actions->disableDelete();
$actions->disableView();
if ($actions->row->identity_id == 1) {
$actions->add(new RefD3Key);
}
if ($actions->row->identity_id == 1) {
$actions->add(new ReCode);
}
if ($actions->row->type == 'pingan' && $actions->row->identity_id == 1 && $user->id == 1) {
$actions->add(new Profit);
}
});
$grid->tools(function (Grid\Tools $tools) {
// $tools->append(new UserImport);
});
$grid->model()->orderBy('id', 'desc');
$grid->quickSearch('username')->placeholder('登录账户');
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->like('username', '登录账户');
$filter->like('server_id', '渠道编号');
$filter->like('outlet_id', '网点编号');
$filter->like('PaOutletId', '平安网点id');
$filter->between('created_at', '注册时间')->datetime();
});
$filter->column(1 / 2, function ($filter) {
$filter->like('info.nickname', '渠道/网点');
$filter->like('server_key', '服务秘钥');
$filter->equal('identity.identity_id', '用户身份')->select([
' ' => '全部',
'1' => '渠道商',
'2' => '网点',
]);
$filter->equal('type', '所属项目')->select([
' ' => '全部',
'pingan' => '平安券',
'wo' => '沃支付',
]);
});
});
$grid->column('id', '#ID#');
$grid->column('username', '登录账户');
$grid->column('渠道编号')->display(function () {
return $this->server_id;
});
$grid->column('网点编号')->display(function () {
return $this->outlet_id ?? '---';
});
$grid->column('平安网点id')->display(function () {
return $this->PaOutletId ?? '---';
});
$grid->column('所属项目')->display(function () {
return $this->type_text;
});
$grid->column('密钥')->display(function ($title, $column) {
return '点击查看';
})->modal(function ($model) {
$data = [
[
'服务秘钥', $model->server_key ?? '---',
],
[
'DES3秘钥', $model->des3key ?? '---',
],
];
return new Table(['名称', '参数'], $data);
});
$grid->column('nickname', '渠道/网点');
$grid->column('用户身份')->display(function () {
if ($this->identity_id == 1) {
return "<p style='color:green'>" . $this->identity_text . "</p>";
} else {
return $this->identity_text;
}
});
$grid->column('隶属渠道')->display(function () {
return $this->parent ? $this->parent->nickname : '---';
});
if ($user->id == 1) {
$grid->column('分润规则')->display(function ($title, $column) {
return '点击展开';
})->modal(function ($model) {
if ($model->code) {
$codes = $model->code->map(function ($code) {
return $code->only(['name', 'code', 'profit']);
});
return new Table(['名称', '规则项', '分润金额(元)'], $codes->toArray());
}
});
}
$grid->column('created_at', '注册时间');
$grid->disableExport(false);
$grid->export(function ($export) {
$export->except(['密钥', '分润规则']);
$export->column('用户身份', function ($value, $original) {
return strip_tags($value);
});
$export->column('渠道编号', function ($value, $original) {
return $value . "\t";
});
$export->column('网点编号', function ($value, $original) {
return $value . "\t";
});
$export->filename('用户管理' . date("YmdHis"));
});
return $grid;
}
/**
* Notes:
* @Author: <C.Jason>
* @Date : 2019/9/18 14:50
* @return Form
*/
protected function form()
{
$province = Area::where('parent_id', 1)->pluck('name', 'code');
$form = new Form(new User);
$identity = Identity::find(1);
$form->text('username', '登录账户')
->creationRules(['required', "unique:users", 'max:11'], ['max' => '小于11个字符'])
->updateRules(['required', "unique:users,username,{{id}}"])->required();
$form->password('password', '登录密码')->creationRules('required|min:6', [
'required' => '必填',
'min' => '密码不能少于6个字符',
]);
$form->text('PaOutletId', '平安网点id');
$form->select('type', '项目')
->options(['pingan' => '平安券', 'wo' => '沃支付'])
->load('parent_id', '/admin/user/parent')
->required();
$form->select('parent_id', '隶属渠道')
->options(function ($option, $info) {
$user = $this;
if (!$option || ($user && $user->identity_id == 2)) {
return User::with('info')->whereHas('identity', function ($q) {
$q->where('identity_id', 1);
})->when(isset($user->id), function ($q) use ($user) {
$q->where('type', $user->type);
})->orderBy('id', 'desc')->get()->pluck('nickname', 'id');
} else {
return [0 => '没有隶属渠道'];
}
})
->default(function ($info) {
if ($info->model() && $info->model()->parent) {
return $info->model()->parent_id;
} else {
return 0;
}
});
$form->select('province_id', '行政省份')
->options($province)
->load('city_id', '/admin/ajax/areas/children')
->required();
$form->select('city_id', '行政城市')->options(function ($option, $info) {
if ($option) {
return Area::whereHas('parent', function ($q) use ($info) {
$q->where('code', $this->province_id);
})->pluck('name', 'code');
}
})->load('district_id', '/admin/ajax/areas/children')->required();
$form->select('district_id', '行政区域')->options(function ($option, $info) {
if ($option) {
return Area::whereHas('parent', function ($q) use ($info) {
$q->where('code', $this->city_id);
})->pluck('name', 'code');
}
})->required();
$form->divider('用户资料');
$form->text('info.nickname', '渠道/网点')->placeholder('请输入渠道/网点名称')->required();
$form->saved(function (Form $form) {
$user_id = $form->model()->id;
$user = User::find($user_id);
if ($user->identity_id == 1 && $user->code()->count() === 0) {
$userCodes = Identity::find(1)->codes->map(function ($code) {
return $code->only(['name', 'code', 'profit']);
});
$user->code()->createMany($userCodes);
}
});
return $form;
}
/**
* 获取隶属
* @author 玄尘 2020-03-12
* @param Request $request [description]
* @return [type] [description]
*/
public function getParent(Request $request)
{
$type = $request->get('q');
$users = User::whereHas('identity', function ($query) {
$query->where('identity_id', 1);
})->where('type', $type)->get();
$userRet = $users->map(function ($code) {
return [
'id' => $code->id,
'text' => $code->info->nickname,
];
});
$userRet->prepend(['id' => '', 'text' => '']);
return $userRet;
}
}

View File

@@ -0,0 +1,150 @@
<?php
namespace App\Admin\Controllers\Wo;
use App\Admin\Actions\Wo\Unsubscribe;
use App\Admin\Exporters\WoCouponExport;
use App\Models\User;
use App\Models\WoCoupon;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
use Encore\Admin\Widgets\Table;
class IndexController extends AdminController
{
protected $title = '沃钱包业务';
/**
* Notes:
* @Author: <C.Jason>
* @Date : 2019/9/18 14:50
* @return Grid
*/
protected function grid()
{
$grid = new Grid(new WoCoupon);
$grid->disableCreateButton();
$grid->disableBatchActions();
// $grid->disableActions();
$grid->model()->whereIn('status', [1, 2, 3])->orderBy('id', 'desc');
$grid->actions(function ($actions) {
$actions->disableDelete();
$actions->disableView();
$actions->disableEdit();
if ($actions->row->status == 1 && $actions->row->service == 'ticketGrant') {
$actions->add(new Unsubscribe);
}
});
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->equal('status', '状态')->select([
'1' => '成功',
'2' => '失败',
'3' => '退订',
]);
$filter->equal('service', '业务')->select([
'ticketGrant' => '发券请求',
'ticketBuyback' => '返销请求',
'ticketInvalid' => '作废请求',
]);
$filter->like('mobile', '手机号');
$filter->like('logNo', '发券流水号');
});
$filter->column(1 / 2, function ($filter) {
$filter->like('number', '工号');
$users = User::query()
->whereHas('identity', function ($query) {
$query->where('identity_id', 1);
})
->where('type', 'wo')
->get()
->pluck('nickname', 'id');
$filter->equal('user_id', '渠道')->select($users);
$filter->equal('activityId', '活动')->select([
'97LJ202025' => '25元兑换券',
'97LJ202010' => '100元兑换券',
'97LJ202018' => '180元话费券',
]);
$filter->between('created_at', '处理时间')->datetime();
});
});
$grid->column('id', '#ID#');
$grid->column('渠道')->display(function () {
return $this->user->nickname;
});
$grid->column('number', '工号');
$grid->column('业务')->display(function () {
return $this->service_text;
});
$grid->column('活动')->display(function () {
return $this->activity_text;
});
$grid->column('mobile', '手机号')->display(function ($title, $column) {
return $this->mobile;
})->modal(function ($model) {
$datas = $model->logs->map(function ($data) {
return [
'mobile' => $data->mobile,
'service_text' => $data->coupon->service_text ?? '---',
'activity_text' => $data->coupon->activity_text ?? '---',
'status_text' => $data->coupon->status_text ?? '---',
'created_at' => $data->created_at,
];
});
return new Table(['手机号', '业务', '活动', '结果', '时间'], $datas->toArray());
});
$grid->column('ticketAmt', '电子券面值');
$grid->column('status', '状态')->display(function () {
switch ($this->status) {
case 1:
return "<span class='label label-success' >" . $this->status_text . "</span>";
break;
case 2:
return "<span class='label label-warning' >" . $this->status_text . "</span>";
break;
case 3:
return "<span class='label label-primary' >" . $this->status_text . "</span>";
break;
default:
return $this->status_text;
break;
}
});
$grid->column('remark', '处理结果');
$grid->column('原发放流水')->display(function () {
return $this->ologNo ?? '---';
});
$grid->column('logNo', '发券流水号');
$grid->column('created_at', '处理时间');
$grid->disableExport(false);
$grid->export(function ($export) {
$export->column('status', function ($value, $original) {
return strip_tags($value);
});
$export->column('mobile', function ($value, $original) {
return $original . "\t";
});
$export->column('ticketAmt', function ($value, $original) {
return $value . "\t";
});
$export->filename('沃钱包业务' . date("YmdHis"));
});
return $grid;
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace App\Admin\Exporters;
use Encore\Admin\Grid\Exporters\ExcelExporter;
use Maatwebsite\Excel\Concerns\WithMapping;
class CouponExport extends ExcelExporter implements WithMapping
{
protected $headings = ['渠道', '网点名称/编号', '订单号', '平安券编号', '优惠政策', '核销金额', '资金通道结算', '状态', '处理结果', '起始时间', '到期时间', '核销时间', '省', '市', '区'];
public function __construct()
{
$this->fileName = '卡券记录' . date('YmdHis') . '.xlsx';
}
public function map($info): array
{
$data = [
$info->user->nickname,
$info->outlet ? $info->outlet->nickname : $info->outletId,
' ' . $info->redemptionCode,
$info->couponName,
$info->price,
$info->profit,
$info->status_text,
$info->remark,
$info->startTime,
$info->endTime,
$info->created_at,
($info->outlet && $info->outlet->province) ? $info->outlet->province->name : '',
($info->outlet && $info->outlet->province) ? $info->outlet->city->name : '',
($info->outlet && $info->outlet->province) ? $info->outlet->district->name : '',
];
return $data;
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace App\Admin\Exporters;
use Encore\Admin\Grid\Exporters\ExcelExporter;
use Maatwebsite\Excel\Concerns\WithMapping;
class CouponPassExport extends ExcelExporter implements WithMapping
{
protected $headings = ['渠道', '网点名称/编号', '订单号', '平安券编号', '优惠政策', '核销金额', '资金通道结算', '状态', '打款', '打款时间', '核销时间', '省', '市', '区'];
public function __construct()
{
$this->fileName = '平安渠道打款处理' . date('YmdHis') . '.xlsx';
}
public function map($info): array
{
$data = [
$info->user->nickname,
$info->outlet ? $info->outlet->nickname : $info->outletId,
' ' . $info->redemptionCode,
$info->couponName,
$info->price,
$info->profit,
$info->status_text,
$info->profit_text,
$info->paid_at,
$info->created_at,
($info->outlet && $info->outlet->province) ? $info->outlet->province->name : '',
($info->outlet && $info->outlet->province) ? $info->outlet->city->name : '',
($info->outlet && $info->outlet->province) ? $info->outlet->district->name : '',
];
return $data;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Admin\Exporters;
use Encore\Admin\Grid\Exporters\ExcelExporter;
use Maatwebsite\Excel\Concerns\WithMapping;
class CouponProfitExport extends ExcelExporter implements WithMapping
{
protected $headings = ['渠道', '网点名称/编号', '订单号', '平安券编号', '优惠政策', '核销金额', '分润金额', '打款时间'];
public function __construct()
{
$this->fileName = '已打款记录 ' . date('YmdHis') . '.xlsx';
}
public function map($info): array
{
$data = [
$info->user->nickname,
$info->outlet ? $info->outlet->nickname : $info->outletId,
' ' . $info->redemptionCode,
$info->couponName,
$info->price,
$info->profit,
$info->paid_at,
];
return $data;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace App\Admin\Exporters;
use Encore\Admin\Grid\Exporters\ExcelExporter;
use Maatwebsite\Excel\Concerns\WithMapping;
class UsersExport extends ExcelExporter implements WithMapping
{
protected $headings = ['登录账户', '渠道编号', '网点编号', '平安网点id', '所属项目', '服务秘钥', 'DES3秘钥', '渠道/网点', '用户身份', '隶属渠道', '注册时间'];
public function __construct()
{
$this->fileName = '用户列表' . date('YmdHis') . '.xlsx';
}
public function map($info): array
{
$data = [
$info->username,
' ' . $info->server_id ?? $info->parent->server_id,
' ' . $info->outlet_id ?? '---',
' ' . $info->PaOutletId ?? '---',
$info->type_text,
$info->server_key ?? '---',
$info->des3key ?? '---',
$info->nickname,
$info->identity_text,
$info->parent ? $info->parent->nickname : '---',
$info->created_at,
];
return $data;
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Admin\Exporters;
use Encore\Admin\Grid\Exporters\ExcelExporter;
use Maatwebsite\Excel\Concerns\WithMapping;
class WoCouponExport extends ExcelExporter implements WithMapping
{
protected $headings = ['渠道', '网点', '工号', '业务', '活动编号', '手机号', '电子券面值', '状态', '处理结果', '原发放流水', '发券流水号', '处理时间'];
public function __construct()
{
$this->fileName = '沃支付业务记录' . date('YmdHis') . '.xlsx';
}
public function map($info): array
{
$data = [
$info->user->nickname,
$info->outlet ? $info->outlet->nickname : $info->outletId,
' ' . $info->number,
' ' . $info->service_text,
$info->activityId,
' ' . $info->mobile,
$info->ticketAmt,
$info->status_text,
$info->remark,
' ' . $info->ologNo,
' ' . $info->logNo,
$info->created_at,
];
return $data;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Admin\Extensions;
use Encore\Admin\Form\Field;
class WangEditor extends Field
{
protected $view = 'admin.wang-editor';
protected static $css = [
'/vendor/wangEditor-3.1.1/release/wangEditor.min.css',
];
protected static $js = [
'/vendor/wangEditor-3.1.1/release/wangEditor.min.js',
];
public function render()
{
$_token = csrf_token();
$name = $this->formatName($this->column);
$this->script = <<<EOT
var E = window.wangEditor
var editor = new E('#{$this->id}');
editor.customConfig.zIndex = 0
editor.customConfig.uploadImgServer = '/admin/uploads/editor'
editor.customConfig.uploadImgMaxSize = 2 * 1024 * 1024
editor.customConfig.uploadFileName = 'image[]'
editor.customConfig.uploadImgParams = {
_token: '{$_token}'
}
editor.customConfig.onchange = function (html) {
$('input[name=\'$name\']').val(html);
}
editor.create()
EOT;
return parent::render();
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace App\Admin\Extensions;
/**
* 校验手机号
*/
class mobile
{
public function phoneOperator()
{
$isPhone = "/^1[3-9]\d{9}$/"; //先判断正确手机号格式
if (preg_match($isPhone, $phone)) {
$isChinaMobile = "/^134[0-9]\d{7}$|^1703\d{7}$|^170[5-6]\d{7}$|^(?:13[5-9]|147|148|15[0-27-9]|178|18[2-478]|198)\d{8}$/"; //
$isChinaUnion = "/^1704\d{7}$|^170[7-9]\d{7}$|^171[0-9]\d{7}$|^(?:13[0-2]|145|15[56]|166|140|175|176|18[56])\d{8}$/"; //
$isChinaTelcom = "/^(?:133|153|169|177|173|174|170|179|18[019]|199)\d{8}$|^170[0-2]\d{7}$/"; //
if (preg_match($isChinaMobile, $phone)) {
return 'mobile'; //中国移动
} else if (preg_match($isChinaUnion, $phone)) {
return 'unicom'; //中国联通
} else if (preg_match($isChinaTelcom, $phone)) {
return 'telecom'; //中国电信
} else {
return 0;
}
} else {
return 0;
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Admin\Imports;
use App\Models\User as UserModel;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
class User implements ToCollection
{
public function collection(Collection $rows)
{
$error = [];
foreach ($rows as $row) {
$user = UserModel::whereHas('info', function ($q) use ($row) {
$q->where('nickname', $row[1]);
})->where('type', 'pingan')->whereNull('PaOutletId')->first();
if ($user) {
$user->PaOutletId = $row[2];
$user->save();
} else {
$error[] = $row['1'];
}
}
if (count($error) > 0) {
dd($error);
return implode(' ,', $error);
}
return true;
}
}

32
app/Admin/bootstrap.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
use App\Admin\Extensions\WangEditor;
use Encore\Admin\Form;
use Encore\Admin\Grid;
//Form::forget(['map', 'editor']);
Form::extend('editor', WangEditor::class);
Form::init(function (Form $form) {
$form->disableEditingCheck();
$form->disableCreatingCheck();
$form->disableViewCheck();
$form->tools(function (Form\Tools $tools) {
$tools->disableDelete();
$tools->disableView();
// $tools->disableList();
});
});
Grid::init(function (Grid $grid) {
$grid->disableExport();
$grid->actions(function (Grid\Displayers\Actions $actions) {
$actions->disableView();
});
$grid->disableBatchActions();
$grid->filter(function ($filter) {
$filter->disableIdFilter();
});
// $grid->expandFilter();
});

64
app/Admin/routes.php Normal file
View File

@@ -0,0 +1,64 @@
<?php
use Illuminate\Routing\Router;
Admin::routes();
Route::group([
'prefix' => config('admin.route.prefix'),
'namespace' => config('admin.route.namespace'),
'middleware' => config('admin.route.middleware'),
], function (Router $router) {
$router->get('/', 'HomeController@index')->name('admin.home');
$router->post('uploads/editor', 'UploadController@editor')->name('uploads.editor');
/**
* 账户管理
*/
$router->get('accounts', 'Account\IndexController@index');
$router->get('accounts/logs', 'Account\LogController@index');
$router->resource('accounts/rules', 'Account\RuleController');
/**
* 用户管理
*/
$router->get('user/parent', 'User\IndexController@getParent');
$router->resource('users', 'User\IndexController');
//商品管理
$router->resource('goods', 'GoodsController');
//身份管理
$router->resource('identity', 'IdentityController');
$router->get('orders', 'Order\IndexController@index');
$router->get('payments', 'Payment\IndexController@index');
//用户提现管理
$router->get('cashout/logs', 'CashOutController@logs')->name('admin.cashout.logs');
$router->resource('cashout', 'CashOutController');
/**
* api 日志
*/
$router->resource('logs', 'Log\IndexController');
$router->resource('coupons', 'Coupon\IndexController'); //平安卡券
$router->resource('wos', 'Wo\IndexController'); //沃钱包业务
/**
* 财务管理
*/
$router->resource('finances', 'Finance\IndexController');
$router->resource('financelogs', 'Finance\LogController');
$router->get('census/today', 'Finance\CensusController@today');
$router->resource('census', 'Finance\CensusController');
//省份地址
$router->get('ajax/areas/children', 'Ajax\AreaController@children')->name('areas.children');
//活动列表
$router->resource('activities', 'Activity\IndexController');
$router->resource('rules', 'Activity\RuleController');
$router->resource('activitycoupons', 'Activity\CouponController');
});

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Api;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
class ApiServiceProvider extends ServiceProvider
{
public function boot()
{
}
public function register()
{
$this->loadAdminRoutes();
}
protected function loadAdminRoutes()
{
Route::prefix('api')
->namespace('App\Api\Controllers')
->group(__DIR__ . '/routes.php');
}
}

View File

@@ -0,0 +1,174 @@
<?php
namespace App\Api\Controllers;
use App\Facades\PingAn\Log as LogFacade;
use App\Models\User;
use Illuminate\Http\Request;
use Response;
use Symfony\Component\HttpFoundation\Response as FoundationResponse;
use XuanChen\Coupon\Traits\Log as LogTraits;
trait ApiResponse
{
use LogTraits;
/**
* [$statusCode description]
* @var [type]
*/
protected $statusCode = FoundationResponse::HTTP_OK;
protected $user;
/**
* 加密
* @param <type> $value
* @return <type>
*/
public function keyasc($value)
{
$iv = substr($this->user->des3key, 0, 8);
$ret = openssl_encrypt($value, 'DES-EDE3-CBC', $this->user->des3key, 0, $iv);
if (false === $ret) {
return openssl_error_string();
}
return $ret;
}
/**
* 解密
* @param <type> $value
* @return <type>
*/
public function keydesc($value)
{
$iv = substr($this->user->des3key, 0, 8);
$ret = openssl_decrypt($value, 'DES-EDE3-CBC', $this->user->des3key, 0, $iv);
if (false === $ret) {
return openssl_error_string();
}
return $ret;
}
public function checkSign(Request $request)
{
$server_id = $request->server_id ?? false;
$key = $request->key ?? false;
$data = $request->data ?? false;
$addcode = $request->addcode ?? false;
$sign = $request->sign ?? false;
if (!$server_id) {
return '参数server_id不能为空';
}
if (!$key) {
return '参数key不能为空';
}
$this->user = User::where('server_id', $server_id)
->where('server_key', $key)->first();
if (!$this->user) {
return '参数server_id与key不匹配';
}
if ($this->user->status != 1) {
return '渠道商状态不正确';
}
if (!$sign) {
return '参数sign不能为空';
}
if (!$data) {
return '参数data不能为空';
}
if (!$addcode) {
return '参数addcode不能为空';
}
$data = str_replace('\\', '', $data);
$data = str_replace(' ', '+', $data);
$checksign = $this->keysign($data, $addcode);
if ($checksign != $sign) {
return '参数sign不正确';
}
$keydesc = $this->keydesc($data);
$keydescArr = json_decode($this->keydesc($data), true);
if (empty($keydescArr) && !empty($keydesc)) {
return '传递的json数据不对';
}
return $keydescArr;
}
public function keysign($jsonData = '', $addcode = '')
{
$signStr = 'data=' . $jsonData . '&addcode=' . $addcode . '&key=' . $this->user->server_key;
$sign = hash_hmac('sha256', $signStr, $this->user->server_key);
return $sign;
}
/**
* 成功的返回
* @Author :<C.Jason>
* @Date :2018-05-22
* @param [type] $data [description]
* @param string $status [description]
* @return [type] [description]
*/
public function success($data, $log = '')
{
$jsonData = json_encode($data); //数据JSON化
$ascdata = $this->keyasc($jsonData); //加密
$addcode = sprintf("%08d", mt_rand(0, 99999999)); //随机code 验证签名用
$sign = $this->keysign($ascdata, $addcode);
$data = [
'code' => 1,
'message' => 'SUCCESS',
'data' => $ascdata,
'addcode' => $addcode,
'sign' => $sign,
];
if ($log) {
if (!is_array($data)) {
$data = [$data];
}
$this->updateLog($log, $data); //更新日志
}
return $this->respond(200, $data);
}
public function error($message = '', $log = '')
{
$data = [
'code' => 0,
'message' => $message,
];
if ($log) {
$this->updateLog($log, [$message]); //更新日志
}
return $this->respond(200, $data);
}
public function respond($code, $data, $header = [])
{
$rt = microtime(true) - LARAVEL_START;
$header = array_merge($header, ['rt' => round($rt * 1000, 2) . 'ms', 'qps' => round(1 / $rt, 1)]);
return Response::json($data, $code, $header);
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Api\Controllers;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use ValidatesRequests, ApiResponse;
}

View File

@@ -0,0 +1,191 @@
<?php
namespace App\Api\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use XuanChen\Coupon\Coupon;
class UserController extends Controller
{
public function index()
{
$this->user = User::find(1);
$data = [
'user_id' => $this->user->id,
'nickname' => $this->user->info->nickname,
];
return $this->success($data);
}
public function check(Request $request)
{
$res = $this->checkSign($request);
if (!is_array($res)) {
return $this->error($res);
}
$user_id = $res['user_id'];
$user = User::find($user_id);
return $this->success($user);
}
/**
* Notes: 发券
* @Author: 玄尘
* @Date : 2020/6/29 13:57
*/
public function grant(Request $request)
{
$inputdata = $request->all();
$res = $this->checkSign($request);
$inputdata['jiemi'] = $res;
$log = $this->createLog($request->url(), 'POST', $inputdata, 'grant'); //添加日志
if (is_string($res)) {
return $this->error($res, $log);
}
$validator = \Validator::make($res, [
'activityId' => 'required',
'outletId' => 'required',
'mobile' => 'required',
], [
'activityId.required' => '缺少活动编码',
'outletId.required' => '缺少网点id',
'mobile.required' => '缺少手机号',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
$res = Coupon::Grant($res['activityId'], $res['outletId'], $res['mobile']);
if (is_string($res)) {
return $this->error($res, $log);
}
return $this->success($res, $log);
}
/**
* Notes: 查询
* @Author: 玄尘
* @Date : 2020/7/22 11:23
* @param \Illuminate\Http\Request $request
*/
public function query(Request $request)
{
$inputdata = $request->all();
$res = $this->checkSign($request);
$inputdata['jiemi'] = $res;
$log = $this->createLog($request->url(), 'POST', $inputdata, 'grant'); //添加日志
if (is_string($res)) {
return $this->error($res, $log);
}
$validator = \Validator::make($res, [
'redemptionCode' => 'required',
'outletId' => 'required',
], [
'redemptionCode.required' => '缺少卡券兑换码',
'outletId.required' => '缺少网点id',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
$redemptionCode = $res['redemptionCode'];
$outletId = $res['outletId'];
$res = Coupon::Query($redemptionCode, $outletId);
if (is_string($res)) {
return $this->error($res, $log);
}
return $this->success($res, $log);
}
//作废
public function destroy(Request $request)
{
$inputdata = $request->all();
$res = $this->checkSign($request);
$inputdata['jiemi'] = $res;
$log = $this->createLog($request->url(), 'POST', $inputdata, 'grant'); //添加日志
if (is_string($res)) {
return $this->error($res, $log);
}
$validator = \Validator::make($res, [
'redemptionCode' => 'required',
], [
'redemptionCode.required' => '缺少卡券兑换码',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
$redemptionCode = $res['redemptionCode'];
$res = Coupon::Destroy($redemptionCode);
if ($res !== true) {
return $this->error($res, $log);
}
return $this->success('作废成功', $log);
}
//核销
public function freezecoupon(Request $request)
{
$inputdata = $request->all();
$res = $this->checkSign($request);
$inputdata['jiemi'] = $res;
//插入日志表
$log = $this->createLog($request->url(), 'POST', $inputdata, 'self'); //添加日志
if (!is_array($res)) {
return $this->error($res, $log);
}
$validator = \Validator::make($res, [
'redemptionCode' => 'required',
'total' => 'required',
'outletId' => 'required',
], [
'redemptionCode.required' => '缺少卡券兑换码',
'total.required' => '缺少订单总额',
'outletId.required' => '缺少网点id',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
$redemptionCode = $res['redemptionCode'] ?? ''; //'915400693355';
$total = $res['total'] ?? ''; //订单总额;
$outletId = $res['outletId'] ?? ''; //网点id;
$redemptionCode = trim($redemptionCode);
$outletId = trim($outletId);
$coupon = Coupon::Redemption($this->user, $redemptionCode, $total, $outletId);
if (is_string($coupon)) {
return $this->error($coupon, $log);
}
return $this->success($coupon, $log);
}
}

View File

@@ -0,0 +1,263 @@
<?php
namespace App\Api\Controllers;
use App\Facades\Wo\Log as LogFacade;
use Illuminate\Http\Request;
use Wo;
class WoController extends Controller
{
/**
* 180元的话费券 一次发放 活动编号 97LJ202018
* @author 玄尘 2020-03-09
* @param Request $request [description]
* @return [type] [description]
*/
public function grant180(Request $request)
{
$type = 'phoneTicket';
$log = LogFacade::insert($request->url(), 'POST', $request->all(), $type); //添加日志
$res = $this->checkSign($request);
if (!is_array($res)) {
return $this->error($res, $log);
}
$validator = \Validator::make($res, [
'mobile' => 'required',
], [
'mobile.required' => '缺少手机号',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
$res['user'] = $this->user;
$res['activity'] = '97LJ202018';
$res['ticketAmt'] = '180';
$res['type'] = $type;
$res = Wo::ticketGrant($res);
if (is_string($res)) {
return $this->error($res, $log);
}
return $this->success($res, $log);
}
/**
* 电子提货券 一共600 每期发放25元 活动编号 97LJ202025
* @author 玄尘 2020-03-09
* @param Request $request [description]
* @return [type] [description]
*/
public function grant25(Request $request)
{
$type = 'pickTicket25';
$log = LogFacade::insert($request->url(), 'POST', $request->all(), $type); //添加日志
$res = $this->checkSign($request);
if (!is_array($res)) {
return $this->error($res, $log);
}
$validator = \Validator::make($res, [
'mobile' => 'required',
], [
'mobile.required' => '缺少手机号',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
$res['user'] = $this->user;
$res['activity'] = '97LJ202025';
$res['ticketAmt'] = '25';
$res['type'] = $type;
$res = Wo::ticketGrant($res);
if (is_string($res)) {
return $this->error($res, $log);
}
return $this->success($res, $log);
}
/**
* 电子提货券 每次100元 活动编号 97LJ202010
* @author 玄尘 2020-03-09
* @param Request $request [description]
* @return [type] [description]
*/
public function grant100(Request $request)
{
$type = 'pickTicket100';
$log = LogFacade::insert($request->url(), 'POST', $request->all(), $type); //添加日志
$res = $this->checkSign($request);
if (!is_array($res)) {
return $this->error($res, $log);
}
$validator = \Validator::make($res, [
'mobile' => 'required',
], [
'mobile.required' => '缺少手机号',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
$res['user'] = $this->user;
$res['activity'] = '97LJ202010';
$res['ticketAmt'] = '100';
$res['type'] = $type;
$res = Wo::ticketGrant($res);
if (is_string($res)) {
return $this->error($res, $log);
}
return $this->success($res, $log);
}
/**
* 10元购物券
* @author 玄尘 2020-06-11
* @param Request $request [description]
* @return [type] [description]
*/
public function grant10(Request $request)
{
$type = 'pickTicket10';
$log = LogFacade::insert($request->url(), 'POST', $request->all(), $type); //添加日志
$res = $this->checkSign($request);
if (!is_array($res)) {
return $this->error($res, $log);
}
$validator = \Validator::make($res, [
'mobile' => 'required',
], [
'mobile.required' => '缺少手机号',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
$res['user'] = $this->user;
$res['activity'] = '97LJ202001';
$res['ticketAmt'] = '10';
$res['type'] = $type;
$res = Wo::ticketGrant($res);
if (is_string($res)) {
return $this->error($res, $log);
}
return $this->success($res, $log);
}
//退业务
public function cancel(Request $request)
{
$log = LogFacade::insert($request->url(), 'POST', $request->all(), 'refund'); //添加日志
$postData = $this->checkSign($request);
if (!is_array($postData)) {
return $this->error($postData, $log);
}
$validator = \Validator::make($postData, [
'logNo' => 'required',
], [
'logNo.required' => '缺少发券流水号',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
//查询状态
$res = Wo::ticketQuery($postData, $this->user->id);
if (is_string($res)) {
return $this->error($res, $log);
}
$ConfigTicketState = config('wo.ticketState');
$ConfigTicketStateText = config('wo.ticketStateText');
$ticketState = $res['ticketState'];
if (!in_array($ticketState, ['A', 'U'])) {
$msg = (array_key_exists($ticketState, $ConfigTicketStateText)) ? $ConfigTicketStateText[$ticketState] : '未知状态';
return $this->error($msg, $log);
}
//判断数组中是否存在下标
if (!array_key_exists($ticketState, $ConfigTicketState)) {
return $this->error('未知状态', $log);
}
$postData['service'] = $ConfigTicketState[$ticketState];
$postData['ologNo'] = $postData['logNo'];
$postData['user'] = $this->user;
//退业务
$res = Wo::ticketBack($postData, $this->user);
if (is_string($res)) {
return $this->error($res, $log);
}
return $this->success($res, $log);
}
/**
* 查询状态
* @author 玄尘 2020-03-13
* @param Request $request [description]
* @return [type] [description]
*/
public function query(Request $request)
{
$log = LogFacade::insert($request->url(), 'POST', $request->all(), 'refund'); //添加日志
$postData = $this->checkSign($request);
if (!is_array($postData)) {
return $this->error($postData, $log);
}
$validator = \Validator::make($postData, [
'logNo' => 'required',
], [
'logNo.required' => '缺少发券流水号',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first(), $log);
}
//查询状态
$res = Wo::ticketQuery($postData, $this->user->id);
if (is_string($res)) {
return $this->error($res, $log);
}
return $this->success($res, $log);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Api\Middleware;
use Auth;
use Closure;
use Response;
class Authenticate
{
// Authorization
public function handle($request, Closure $next)
{
if (Auth::guard('api')->guest()) {
return Response::json([
'status' => 'Unauthenticated',
'status_code' => 401,
'message' => '没有权限访问',
]);
}
return $next($request);
}
}

21
app/Api/routes.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
Route::group(['prefix' => 'V1'], function () {
Route::post('user/get', 'UserController@index');
Route::post('user/check', 'UserController@check');
//平安接口
Route::post('user/grant', 'UserController@grant'); //发券
Route::post('user/query', 'UserController@query'); //查询
Route::post('user/destroy', 'UserController@destroy'); //作废
Route::any('user/freezecoupon', 'UserController@freezecoupon'); //核销
//沃支付接口
Route::post('ticket/grant10', 'WoController@grant10'); //发券
Route::post('ticket/grant25', 'WoController@grant25'); //发券
Route::post('ticket/grant100', 'WoController@grant100'); //发券
Route::post('ticket/grant180', 'WoController@grant180'); //发券
Route::post('ticket/cancel', 'WoController@cancel'); //退业务
Route::post('ticket/query', 'WoController@query'); //退业务
});

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Channels;
use Illuminate\Notifications\Notification;
class VoiceChannel
{
/**
* 发送指定的通知.
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return void
*/
public function send($notifiable, Notification $notification)
{
$message = $notification->toWeChat($notifiable);
}
}

42
app/Console/Kernel.php Normal file
View File

@@ -0,0 +1,42 @@
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
}

290
app/Facades/Wo/Action.php Normal file
View File

@@ -0,0 +1,290 @@
<?php
namespace App\Facades\Wo;
use App\Jobs\TicketBack;
use App\Models\WoCoupon;
class Action extends Wo
{
/**
* [ticketGrant 沃支付发券接口]
* @author 玄尘 2020-02-13
* @param [type] $data [post 过来的数据 array]
* @return [type] [description]
*/
public function ticketGrant($data)
{
$mobile = $data['mobile'];
$activity = $data['activity'];
$type = $data['type'];
$user = $data['user'];
// $activity .= '--';
//如果是话费券
if ($type == 'phoneTicket') {
$info = WoCoupon::where('mobile', $mobile)->where('status', 1)->where('activityId', $activity)->first();
if ($info) {
return '已经领取过了';
}
}
$logNo = 'YSD' . $this->getMsecTime();
$params = [
'charset' => $this->charset,
'version' => $this->version,
'merchantSign' => '',
'merchantCert' => '',
'signType' => $this->signType,
'service' => 'ticketGrant',
'requestId' => $logNo,
'merchantId' => $this->merchant_id,
'activityId' => $activity,
'mobilepNo' => $mobile,
'ticketAmt' => $data['ticketAmt'],
'logNo' => $logNo,
'channelType' => $this->channelType,
'transactionDate' => now()->format('Ymd'),
'effectDate' => now()->format('Ymd'),
];
$merchantCert = $this->merchantCert();
if (!$merchantCert) {
return '证书文件有错误';
}
$couponData = [
'user_id' => $user->id,
'number' => $data['number'] ?? '',
'service' => 'ticketGrant',
'ticketAmt' => $data['ticketAmt'] ?? '0.00',
'mobile' => $mobile,
'logNo' => $params['logNo'],
'activityId' => $activity,
];
//记录
$coupon = WoCoupon::create($couponData);
//签名
$merchantSign = $this->rsaSign($params);
if (is_array($merchantSign)) {
return $merchantSign['msg'];
}
//验签
// $checkdata = $params;
// $res = $this->rsaCheck($checkdata, $merchantSign);
// dd($res);
$params['merchantSign'] = $merchantSign;
$params['merchantCert'] = $merchantCert;
$res = $this->getWoData($params);
//判断是否是数组,不是数组返回错误信息
if (!is_array($res)) {
$coupon->remark = $res;
$coupon->status = 2;
$coupon->save();
return $res;
}
//判断是否成功
$status = ($res['rspCode'] == 'MKM00000') ? 1 : 2;
$coupon->remark = $res['rspMessage'];
$coupon->status = $status;
$coupon->ticketId = $res['ticketId'] ?? '';
$coupon->serialNo = $res['serialNo'] ?? '';
$coupon->save();
if ($status == 1) {
$ret = [
'logNo' => $coupon->logNo,
'rspMessage' => $res['rspMessage'],
];
return $ret;
} else {
// PhoneTicket::dispatch($data);
return $res['rspMessage'];
}
}
/**
* 查询券
* @param [type] $data [description]
* @param [type] $user_id [description]
* @return [type] [description]
*/
public function ticketQuery($data, $user_id)
{
$logNo = $data['logNo'];
if (!$logNo) {
return '缺少发券流水号';
}
$info = WoCoupon::where('logNo', $logNo)->first();
if (!$info) {
return '没有查询到信息';
}
if ($info->user_id != $user_id) {
return '这不是您的券。';
}
$params = [
'charset' => $this->charset,
'version' => $this->version,
'merchantCert' => '',
'merchantSign' => '',
'signType' => $this->signType,
'service' => 'ticketQuery',
'requestId' => $this->getMsecTime(),
'merchantId' => $this->merchant_id,
'logNo' => $info->logNo,
'channelType' => $this->channelType,
];
$merchantCert = $this->merchantCert();
if (!$merchantCert) {
return '证书文件有错误';
}
$merchantSign = $this->rsaSign($params);
if (is_array($merchantSign)) {
return $merchantSign['msg'];
}
$params['merchantSign'] = $merchantSign;
$params['merchantCert'] = $merchantCert;
$res = $this->getWoData($params);
if (is_array($res)) {
if ($res['rspCode'] == 'MKM00000') {
$ret = [
'ticketState' => $res['ticketState'],
'ticketBalance' => $res['ticketBalance'],
'ticketAmt' => $res['ticketAmt'],
'expireDate' => $res['expireDate'],
'ticketId' => $res['ticketId'],
'ticketName' => $res['ticketName'],
'activityId' => $res['activityId'],
'logNo' => $params['logNo'],
'mobile' => $info->mobile,
];
return $ret;
} else {
return $res['rspMessage'];
}
} else {
return $res;
}
}
/**
* 退业务
* @author 玄尘 2020-02-13
* @param [type] $data [description]
* @param [type] $user [description]
* @return [type] [description]
*/
public function ticketBack($data, $user)
{
$ologNo = $data['ologNo'];
$info = WoCoupon::where('logNo', $ologNo)->where('status', 1)->first();
if (!$info) {
return '没有查询到信息';
}
$logNo = 'YSD' . $this->getMsecTime();
$params = [
'charset' => $this->charset,
'version' => $this->version,
'merchantSign' => '',
'merchantCert' => '',
'signType' => $this->signType,
'service' => $data['service'],
'requestId' => $logNo,
'merchantId' => $this->merchant_id,
'activityId' => $info->activityId,
'mobilepNo' => $info->mobile,
'ologNo' => $data['ologNo'] ?? '',
'logNo' => $logNo,
'channelType' => $this->channelType,
'transactionDate' => now()->format('Ymd'),
];
if (!empty($data['ticketAmt'])) {
// $params['ticketAmt'] = $data['ticketAmt'];
}
$merchantCert = $this->merchantCert();
if (!$merchantCert) {
return '证书文件有错误';
}
$couponData = [
'user_id' => $user->id,
'number' => $data['number'] ?? '',
'service' => $params['service'],
'ticketAmt' => $info->ticketAmt ?? '0.00',
'mobile' => $params['mobilepNo'],
'ologNo' => $params['ologNo'],
'logNo' => $params['logNo'],
'activityId' => $params['activityId'],
];
//记录
$coupon = WoCoupon::create($couponData);
//签名
$merchantSign = $this->rsaSign($params);
if (is_array($merchantSign)) {
return $merchantSign['msg'];
}
$params['merchantSign'] = $merchantSign;
$params['merchantCert'] = $merchantCert;
$res = $this->getWoData($params);
//判断是否是数组,不是数组返回错误信息
if (!is_array($res)) {
$coupon->remark = $res;
$coupon->status = 2;
$coupon->save();
return $res;
}
//判断是否成功
$status = ($res['rspCode'] == 'MKM00000') ? 1 : 2;
$coupon->remark = $res['rspMessage'];
$coupon->status = $status;
$coupon->ticketId = $res['ticketId'] ?? '';
$coupon->serialNo = $res['serialNo'] ?? '';
$coupon->save();
if ($status == 1) {
//退订成功
// $info->ticketAmt = $info->ticketAmt . '/' . $res['ticketAmt'];
$info->status = 3;
$info->remark = $info->remark . '/已经退订';
$info->save();
$ret = [
'alreadyconAmt' => $res['alreadyconAmt'],
'ticketAmt' => $res['ticketAmt'],
'rspMessage' => $res['rspMessage'],
];
return $ret;
} else {
// TicketBack::dispatch($data);
return $res['rspMessage'];
}
}
}

13
app/Facades/Wo/Facade.php Normal file
View File

@@ -0,0 +1,13 @@
<?php
namespace App\Facades\Wo;
use Illuminate\Support\Facades\Facade as BaseFacade;
class Facade extends BaseFacade
{
protected static function getFacadeAccessor()
{
return Action::class;
}
}

40
app/Facades/Wo/Log.php Normal file
View File

@@ -0,0 +1,40 @@
<?php
namespace App\Facades\Wo;
use App\Models\Log as LogModel;
class Log
{
/**
* 插入日志
* @param [type] $url [description]
* @param [type] $method [description]
* @param [type] $params [description]
* @param string $type [description]
* @return [type] [description]
*/
public static function insert($url, $method, $params, $type = 'pingan')
{
$params['form_params']['merchantCert'] = '';
$params['form_params']['merchantSign'] = '';
$data = [
'path' => $url,
'method' => $method,
'type' => $type,
'in_source' => $params,
];
$info = LogModel::create($data);
return $info;
}
//更新日志
public static function update($log, $params)
{
$log->out_source = $params;
$log->save();
}
}

158
app/Facades/Wo/Wo.php Normal file
View File

@@ -0,0 +1,158 @@
<?php
namespace App\Facades\Wo;
use App\Facades\Wo\Log as LogFacade;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
/**
* 花呗分期业务
*/
class Wo
{
protected $baseUri;
public function __construct()
{
$config = config('wo');
$this->merchantCert = $config['merchantCert'];
$this->merchant_id = $config['merchant_id'];
$this->charset = $config['charset'];
$this->version = $config['version'];
$this->signType = $config['signType'];
$this->channelType = $config['channelType'];
$this->baseUri = $config['baseUri'];
}
//获取私钥
public function getPrivate()
{
$config = config('wo');
return file_get_contents($config['private']);
}
//获取公钥
public function getPublic()
{
$config = config('wo');
return file_get_contents($config['public']);
}
/**
* 获取毫秒级别的时间戳
*/
public function getMsecTime()
{
list($msec, $sec) = explode(' ', microtime());
$msectime = (float) sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
$msectime = explode('.', $msectime);
return $msectime[0];
}
//签名
public function rsaSign($params)
{
$signStr = $this->getSignString($params);
$private_key = $this->getPrivate();
$privKeyId = openssl_pkey_get_private($private_key);
if (!$privKeyId) {
return ['msg' => '私钥格式有误'];
}
$signature = '';
openssl_sign($signStr, $signature, $privKeyId, OPENSSL_ALGO_SHA1);
openssl_free_key($privKeyId);
return bin2hex($signature);
}
/**
* RSA验签
* @param $params 待签名数据
* @param $public_key 公钥字符串
* @param $sign 要校对的的签名结果
* return 验证结果
*/
public function rsaCheck($params, $sign)
{
$public_key = $this->getPublic();
$res = openssl_get_publickey($public_key);
$signStr = $this->getSignString($params);
if ($res) {
$result = (bool) openssl_verify($signStr, $sign, $res);
openssl_free_key($res);
} else {
return '公钥格式有误!';
}
return $result;
}
/**
* 获取待签名字符串
* @param array $params 参数数组
* @return string
*/
public function getSignString($params)
{
$params = array_filter($params);
ksort($params);
$signStr = http_build_query($params);
return $signStr;
}
//获取证书
public function merchantCert()
{
if (!file_exists($this->merchantCert)) {
return false;
}
$cert = file_get_contents($this->merchantCert);
$cer_key = bin2hex($cert);
return $cer_key;
}
/**
* 通用获取数据接口
* @param [type] $url 请求地址
* @param array $query 传递参数
* @param array $json 需要传的json数据
* @param string $method 方式
* @return [type] [description]
*/
public function getWoData($params = [], $method = 'POST')
{
$url = $this->baseUri;
$postData = [
'form_params' => $params,
];
$log = LogFacade::insert($url, $method, $postData, 'wo'); //日志
try {
$client = new Client();
$response = $client->request($method, $url, $postData);
$body = $response->getBody();
$content = $body->getContents();
$result = json_decode($content, true);
if (is_array($result)) {
return '发券失败';
LogFacade::update($log, $result); //更新日志
}
parse_str($content, $res);
LogFacade::update($log, $res); //更新日志
return $res;
} catch (RequestException $e) {
LogFacade::update($log, [$e->getMessage()]); //更新日志
return ['ret' => '99999', $e->getMessage()];
}
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers;
trait AjaxResponse
{
public function success($message = '', $redirect = null)
{
return [
'status' => 'SUCCESS',
'statusCode' => 200,
'message' => $message,
'redirect' => $redirect,
];
}
public function error($message = '', $redirect = null)
{
return [
'status' => 'ERROR',
'statusCode' => 400,
'message' => $message,
'redirect' => $redirect,
];
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Http\Controllers;
use Auth;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests, AjaxResponse;
public function checkUserAuth($identity_id = 0)
{
$url = 'wxlogin';
if ($identity_id > 0) {
$url = 'login';
}
if (!Auth::user() || ($identity_id && Auth::user()->identity_id != $identity_id)) {
return route($url) . '?callback=' . url()->current();
}
return true;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers;
class CouponController extends Controller
{
public function index()
{
$tick = 'YSD' . date('ymdHi') . mt_rand(100, 999);
$tick = strtotime(date('YmdHi', time())) . substr(microtime(), 2, 6) . sprintf('%03d', rand(0, 999));
$data = [
'code' => 200,
'couponCode' => $tick,
];
return $data;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Http\Controllers;
use Auth;
use Illuminate\Http\Request;
use Image;
use QrCode;
class IndexController extends Controller
{
public function index(Request $request)
{
return view('index.index');
}
public function makeCode(Request $request)
{
$user = Auth::user();
$shareimg = Image::make(QrCode::size(3000)->format('png')->margin(0)->generate(route('checkcode', $user)))
->resize(240, 240)
->encode('data-url');
return view('index.makeCode', compact('shareimg', 'user'));
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Http\Controllers;
use App\Api\Controllers\ApiResponse;
class SkyxuController
{
use ApiResponse;
public function index()
{
$postData = [
'server_id' => '20200103490104',
'key' => 'rRhHO7Jbao2SSxAH8VygV4DgS4L2WESa',
'addcode' => '69198663',
'sign' => '6cd2232e9aa853219a0dff80430567796d0ae33d6c0289dfa835813def08ed8c',
'data' => 'DBEgnb5HidvKQDyxL0BAcCwuMkVdbTZRVu4mxwwzAM5TWj\/HAQfcrH9VzcgdG42lINsHYvI2Tv+MJfyP9eXVEQ==',
];
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "http://pa.cnskl.com/api/V1/user/freezecoupon",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $postData,
CURLOPT_HTTPHEADER => array(
"Content-Type: multipart/form-data;",
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers;
use File;
use Illuminate\Http\Request;
use Storage;
class StorageController extends Controller
{
public function index(Request $request)
{
$File = $request->file('image');
$oldName = $File->getClientOriginalName();
$hash = File::hash($File->path());
$size = File::size($File->path());
if ($size > (10 * 1024 * 1024)) {
return [
'code' => 0,
'message' => '文件不能超过10M',
];
}
$pathUrl = 'images' . date('/Y-m/d');
$fileName = $hash . '.' . $File->getClientOriginalExtension();
$path = Storage::disk('public')->putFileAs(
$pathUrl, $File, $fileName
);
if (!$path) {
return [
'code' => 0,
'message' => '文件上传失败',
];
}
return [
'code' => 1,
'message' => '文件上传成功',
'path' => '/' . $pathUrl . '/' . $fileName,
];
}
}

View File

@@ -0,0 +1,219 @@
<?php
namespace App\Http\Controllers;
use App\Api\Controllers\ApiResponse;
use SelfCoupon;
use App\Models\User;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use XuanChen\Coupon\Coupon;
// use Wo;
class TestController
{
use ApiResponse;
public function index(Request $request)
{
$this->user = User::find(3);
$data = 'Q7dhxBxcPnSGbnhDtHGgTNPYJfcRf0IcpOBSr+jjRF5SfLe0RLoiAMXYynZ9bb/dnon8MMw/o/AgO/yIIfhxo45Ya9yXOAEAogwR6Ti9nnM=';
$iv = substr($this->user->des3key, 0, 8);
$ret = openssl_decrypt($data, 'DES-EDE3-CBC', $this->user->des3key, 0, $iv);
if (false === $ret) {
return openssl_error_string();
}
dd($ret);
dd();
$this->user = User::find(215);
$ret = [
'redemptionCode' => '951951858070',
'total' => 5,
'outletId' => '2006151433887',
];
return $this->success($ret);
dd(phpinfo());
dd();
$num = 100;
for ($i = 1; $i <= $num; $i++) {
$data = [
'outletId' => '2004020935777',
'activityId' => 'ysd20200740',
'mobile' => '15663876870',
];
$this->user = User::find(3);
$data = $this->jiami($data);
$url = 'http://pac.ysd-bs.com/api/V1/user/grant';
$res = $this->http($data, $url);
// if (isset($res['data'])) {
// $jiemi = $this->jiemi($res['data']);
// dump($jiemi);
// }
}
dump($this->getElapsedTime());
dump($this->getMemoryUsage());
}
/**
* Notes: 发券
* @Author: 玄尘
* @Date : 2020/6/29 13:57
*/
public function grant(Request $request)
{
$this->user = User::find(3);
$data = $this->jiami($request->all());
$url = 'http://pac.ysd-bs.com/api/V1/user/grant';
$res = $this->http($data, $url);
return $res;
// dump($this->getElapsedTime());
// dump($this->getMemoryUsage());
//
// dd($res);
}
//查询
public function query(Request $request)
{
$this->user = User::find(3);
$redemptionCode = $request->redemptionCode;
$outletId = $request->outletId;
$data = $this->jiami($request->all());
$url = 'http://pac.ysd-bs.com/api/V1/user/query';
$res = $this->http($data, $url);
return $res;
if (isset($res['data'])) {
$jiemi = $this->jiemi($res['data']);
dump($jiemi);
}
dump($this->getElapsedTime());
dump($this->getMemoryUsage());
dump($res);
}
//卡券作废
public function destroy(Request $request)
{
$this->user = User::find(3);
$redemptionCode = $request->redemptionCode;
$data = $this->jiami($request->all());
$url = 'http://pac.ysd-bs.com/api/V1/user/destroy';
$res = $this->http($data, $url);
dump($this->getElapsedTime());
dump($this->getMemoryUsage());
if (isset($res['data'])) {
$jiemi = $this->jiemi($res['data']);
dump($jiemi);
}
dump($res);
}
/**
* Notes: 核销
* @Author: 玄尘
* @Date : 2020/6/29 14:01
*/
public function checkcoupon(Request $request)
{
$redemptionCode = $request->redemptionCode;
$total = $request->total;
$outletId = $request->outletId;
$user_id = $request->user_id;
$this->user = User::find($user_id);
$res = Coupon::Redemption($this->user, $redemptionCode, $total, $outletId);
dump($this->getElapsedTime());
dump($this->getMemoryUsage());
dd($res);
}
public function http($data, $url)
{
$client = new Client();
$response = $client->request('POST', $url, ['form_params' => $data, 'http_errors' => false]);
$body = $response->getBody();
$content = $body->getContents();
$result = json_decode($content, true);
return $result;
}
public function jiami($ret)
{
$jsonData = json_encode($ret); //数据JSON化
$ascdata = $this->keyasc($jsonData); //加密
$addcode = sprintf("%08d", mt_rand(0, 99999999)); //随机code 验证签名用
$sign = $this->keysign($ascdata, $addcode);
$data = [
'server_id' => $this->user->server_id,
'key' => $this->user->server_key,
'addcode' => $addcode,
'sign' => $sign,
'data' => $ascdata,
];
return $data;
}
/**
* 解密
* @param <type> $value
* @return <type>
*/
public function jiemi($value)
{
$iv = substr($this->user->des3key, 0, 8);
$ret = openssl_decrypt($value, 'DES-EDE3-CBC', $this->user->des3key, 0, $iv);
if (false === $ret) {
return openssl_error_string();
}
return $ret;
}
function getMemoryUsage($precision = 2)
{
$size = memory_get_usage(true);
$unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb'];
return round($size / pow(1024, ($i = floor(log($size, 1024)))), $precision) . ' ' . $unit[$i];
}
function getElapsedTime(int $decimals = 2)
{
return number_format(microtime(true) - request()->server('REQUEST_TIME_FLOAT'), $decimals) . ' s';
}
}

82
app/Http/Kernel.php Normal file
View File

@@ -0,0 +1,82 @@
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
class CheckForMaintenanceMode extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array
*/
protected $except = [
//
];
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
//
];
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array
*/
protected $except = [
'password',
'password_confirmation',
];
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Http\Middleware;
use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array|string
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* Indicates whether the XSRF-TOKEN cookie should be set on the response.
*
* @var bool
*/
protected $addHttpCookie = true;
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
'payment/notify', 'wechat',
];
}

View File

@@ -0,0 +1,109 @@
<?php
namespace App\Http\WechatHandlers;
use App\Models\User;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
use EasyWeChat\Kernel\Messages\Text;
class EventMessageHandler implements EventHandlerInterface
{
private $payload;
public function handle($payload = null)
{
if (method_exists($this, $payload['Event'])) {
$this->payload = $payload;
return call_user_func_array([$this, $payload['Event']], []);
} else {
return '暂不支持的消息类型';
}
}
/**
* 扫码事件
* @Author:<C.Jason>
* @Date:2018-11-12T16:28:19+0800
*/
private function SCAN()
{
}
/**
* 主菜单点击
* @Author:<C.Jason>
* @Date:2018-11-12T16:28:06+0800
*/
private function CLICK()
{
return false;
}
/**
* 关注事件
* @Author:<C.Jason>
* @Date:2018-11-12T16:27:51+0800
*/
private function subscribe()
{
$app = app('wechat.official_account');
$user = $app->user->get($this->payload['FromUserName']);
// 先查找用户是否存在,不存在再注册
$existUser = User::where('openid', $this->payload['FromUserName'])->first();
if ($existUser) {
$existUser->update([
'info' => [
'headimgurl' => $user['headimgurl'],
'sex' => $user['sex'],
'country' => $user['country'],
'province' => $user['province'],
'city' => $user['city'],
'subscribe_at' => $user['subscribe_time'],
'subscribe_scene' => $user['subscribe_scene'],
// 'qr_scene' => $user['qr_scene'],
// 'qr_scene_str' => $user['qr_scene_str'],
],
]);
return $this->firstSubscribeMessage($existUser);
}
}
public function VIEW()
{
#Todo..
}
public function LOCATION()
{
#Todo..
}
/**
* 取消关注事件
* @Author:<Leady>
* @Date:2018-12-12T13:44:54+0800
* @return [type] [description]
*/
private function unsubscribe()
{
$existUser = User::where('openid', $this->payload['FromUserName'])->first();
if ($existUser) {
$existUser->update([
'info' => [
'subscribe_at' => null,
// 'subscribe_scene' => null,
],
]);
}
}
private function firstSubscribeMessage($user)
{
$text = new Text('您好,欢迎关注连卡蝠');
return $text;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Http\WechatHandlers;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
class FileMessageHandler implements EventHandlerInterface
{
public function handle($payload = null)
{
$payload->ToUserName;
$payload->FromUserName;
$payload->CreateTime;
$payload->MsgId;
$payload->Title;
$payload->Description;
$payload->FileKey;
$payload->FileMd5;
$payload->FileTotalLen;
return '文件消息';
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Http\WechatHandlers;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
class ImageMessageHandler implements EventHandlerInterface
{
public function handle($payload = null)
{
$payload->ToUserName;
$payload->FromUserName;
$payload->CreateTime;
$payload->MsgId;
$payload->MediaId;
$payload->PicUrl;
return '图片消息';
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Http\WechatHandlers;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
class LinkMessageHandler implements EventHandlerInterface
{
public function handle($payload = null)
{
$payload->ToUserName;
$payload->FromUserName;
$payload->CreateTime;
$payload->MsgId;
$payload->Title;
$payload->Description;
$payload->Url;
return '链接消息';
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Http\WechatHandlers;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
class LocationMessageHandler implements EventHandlerInterface
{
public function handle($payload = null)
{
$payload->ToUserName;
$payload->FromUserName;
$payload->CreateTime;
$payload->MsgId;
$payload->Latitude;
$payload->Longitude;
$payload->Precision;
return '上报位置消息';
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Http\WechatHandlers;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
class ShortVideoMessageHandler implements EventHandlerInterface
{
public function handle($payload = null)
{
$payload->ToUserName;
$payload->FromUserName;
$payload->CreateTime;
$payload->MsgId;
$payload->MediaId;
$payload->ThumbMediaId;
return '短视频消息';
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace App\Http\WechatHandlers;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
class TextMessageHandler implements EventHandlerInterface
{
public function handle($payload = null)
{
return '您的留言已经收到';
return $payload->Content;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace App\Http\WechatHandlers;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
class TransferMessageHandler implements EventHandlerInterface
{
public function handle($payload = null)
{
return '客服消息' . json_encode($payload);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Http\WechatHandlers;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
class VideoMessageHandler implements EventHandlerInterface
{
public function handle($payload = null)
{
$payload->ToUserName;
$payload->FromUserName;
$payload->CreateTime;
$payload->MsgId;
$payload->MediaId;
$payload->ThumbMediaId;
return '视频消息';
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Http\WechatHandlers;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
class VoiceMessageHandler implements EventHandlerInterface
{
public function handle($payload = null)
{
$payload->ToUserName;
$payload->FromUserName;
$payload->CreateTime;
$payload->MsgId;
$payload->MediaId;
$payload->Format;
$payload->Recognition;
return '语音消息';
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace App\Merchant\Controllers;
use Auth;
use Illuminate\Http\Request;
use Validator;
class AuthController extends Controller
{
public function login(Request $request)
{
if ($request->isMethod('post')) {
$validator = Validator::make($request->all(), [
'username' => 'required|min:4',
'password' => 'required|min:6',
], [
'username.requird' => '用户名不能为空',
'username.min' => '用户名不能小于:min字符',
'password.requird' => '密码不能为空',
'password.min' => '密码不能小于:min字符',
]);
if ($validator->fails()) {
return [
'code' => 0,
'msg' => $validator->errors()->first(),
];
}
$remember = $request->remember ?: false;
if (Auth::guard('merchant')->attempt(['username' => $request->username, 'password' => $request->password], $remember)) {
$user = Auth::guard('merchant')->user();
if (in_array($user->identity->identity_id, ['1'])) {
return [
'code' => 1,
'msg' => '登录成功',
'url' => route('merchant.index'),
];
} else {
Auth::guard('merchant')->logout();
session()->flush();
return [
'code' => 0,
'msg' => '没有登录权限',
];
}
} else {
return [
'code' => 0,
'msg' => '用户名或密码错误',
];
}
} else {
return view('Merchant::auth.login');
}
}
public function logout(Request $request)
{
Auth::guard('merchant')->logout();
session()->flush();
return $this->success('注销成功', 'merchant.login');
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace App\Merchant\Controllers\Census;
use App\Merchant\Controllers\Controller;
use App\Merchant\Exporters\CensusExport;
use App\Models\Coupon;
use Auth;
use Illuminate\Http\Request;
class IndexController extends Controller
{
public function index(Request $request)
{
$user = Auth::guard('merchant')->user();
$month = $request->month ?? now()->format('Y-m');
$action = $request->action ?? 'search';
$month = explode('-', $month);
$coupons = Coupon::where('user_id', $user->id)
->whereYear('created_at', $month[0])
->whereMonth('created_at', $month[1])
->where('status', 2)
->get(['id', 'thirdPartyGoodsId', 'created_at']);
$coupons = $coupons->groupBy('create_day')->map(function ($items, $key) {
$data = [
'day' => $key,
'ysd10' => $items->where('thirdPartyGoodsId', 'YSD-full100-10')->count(),
'ysd25' => $items->where('thirdPartyGoodsId', 'YSD-full100-25')->count(),
'ysd50' => $items->where('thirdPartyGoodsId', 'YSD-full100-50')->count(),
'ysd100' => $items->where('thirdPartyGoodsId', 'YSD-full200-100')->count(),
];
return collect($data);
});
$all = [
'ysd10' => $coupons->sum('ysd10'),
'ysd25' => $coupons->sum('ysd25'),
'ysd50' => $coupons->sum('ysd50'),
'ysd100' => $coupons->sum('ysd100'),
];
$coupons = $coupons->sortByDesc('day');
if ($action == 'search') {
return view('Merchant::census.index', compact('coupons', 'all'));
} else {
return (new CensusExport($month, $user))->download();
}
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace App\Merchant\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests, Traits\AjaxResponse;
}

View File

@@ -0,0 +1,163 @@
<?php
namespace App\Merchant\Controllers\Coupon;
use App\Merchant\Controllers\Controller;
use App\Merchant\Exporters\CouponExport;
use App\Models\Coupon;
use Auth;
use Illuminate\Http\Request;
class IndexController extends Controller
{
public function index(Request $request)
{
$user = Auth::guard('merchant')->user();
$outlet = $request->outlet;
$status = $request->status;
$redemptionCode = $request->redemptionCode;
$start = $request->start;
$end = $request->end;
$thirdPartyGoodsId = $request->thirdPartyGoodsId;
$action = $request->action ?? 'search';
if ($start) {
$start = $start . ' 00:00:00';
}
if ($end) {
$end = $end . ' 23:59:59';
}
$coupons = Coupon::where('user_id', $user->id)
->when($outlet, function ($q) use ($outlet) {
$q->whereHas('outlet', function ($q) use ($outlet) {
$q->whereHas('info', function ($q) use ($outlet) {
$q->where('nickname', 'like', "%{$outlet}%");
});
});
})
->when($redemptionCode, function ($q) use ($redemptionCode) {
$q->where('redemptionCode', $redemptionCode);
})
->when($thirdPartyGoodsId, function ($q) use ($thirdPartyGoodsId) {
$q->where('thirdPartyGoodsId', $thirdPartyGoodsId);
})
->when(is_numeric($status), function ($query) use ($status) {
if ($status == 4) {
$query->where('is_profit', 1);
} else {
$query->where('status', $status);
}
})
->when($start && $end, function ($query) use ($start, $end) {
$query->whereBetween('created_at', [$start, $end]);
})
->when($start && !$end, function ($query) use ($start) {
$query->where('created_at', '>', $start);
})
->when(!$start && $end, function ($query) use ($end) {
$query->where('created_at', '<', $end);
})
->whereIn('status', [2, 3])
->orderBy('created_at', 'desc')->orderBy('id', 'desc')->paginate();
$all = Coupon::query()
->where('user_id', $user->id)
->when($outlet, function ($q) use ($outlet) {
$q->whereHas('outlet', function ($q) use ($outlet) {
$q->whereHas('info', function ($q) use ($outlet) {
$q->where('nickname', 'like', "%{$outlet}%");
});
});
})
->when($redemptionCode, function ($q) use ($redemptionCode) {
$q->where('redemptionCode', $redemptionCode);
})
->when(is_numeric($status), function ($query) use ($status) {
$query->where('status', $status);
}, function ($query) {
$query->whereIn('status', [2, 3]);
})
->when($start && $end, function ($query) use ($start, $end) {
$query->whereBetween('created_at', [$start, $end]);
})
->when($start, function ($query) use ($start) {
$query->where('created_at', '>', $start);
})
->when($end, function ($query) use ($end) {
$query->where('created_at', '<', $end);
})
->orderBy('created_at', 'desc')->orderBy('id', 'desc')->get();
$pass = $all->whereIn('status', [2, 4])->all();
$reject = $all->where('status', 3)->all();
$pass = collect($pass);
$reject = collect($reject);
$data = [
'all' => $all->count(),
'pass' => $pass->count(),
'reject' => $reject->count(),
'price' => $pass->sum('price'),
'profit' => $pass->sum('profit'),
'hasPrice' => $pass->where('is_profit', 1)->sum('profit'),
];
if ($action == 'search') {
return view('Merchant::coupon.index', compact('coupons', 'data'));
} else {
return (new CouponExport($request->all(), $user))->download();
}
}
/**
* 按照日期分润
* @param Request $request [description]
* @return array|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @author 玄尘 2020-03-11
*/
public function profits(Request $request)
{
$user = Auth::guard('merchant')->user();
if ($request->isMethod('POST')) {
$date = $request->date;
$list = Coupon::where('user_id', $user->id)->whereDate('created_at', $date)->where('status', 2)->get();
if ($list->isEmpty()) {
return $this->error('分润失败!没有可处理的数据');
}
if (Coupon::where('user_id', $user->id)->whereDate('created_at', $date)->where('status', 2)->update(['status' => 4])) {
return $this->success('分润成功!');
} else {
return $this->error('分润失败!');
}
} else {
return view('Merchant::coupon.profits');
}
}
/**
* 分润
* @author 玄尘 2020-03-11
* @param Coupon $coupon [description]
* @return [type] [description]
*/
public function profit(Coupon $coupon)
{
if ($coupon->status == 2) {
$coupon->status = 4;
$coupon->save();
return $this->success('分润成功');
} else {
return $this->error('分润失败');
}
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Merchant\Controllers;
use Auth;
class IndexController extends Controller
{
public function index()
{
return view('Merchant::index.index');
}
public function dashboard()
{
$user = Auth::guard('merchant')->user();
return view('Merchant::index.dashboard', compact('user'));
}
}

View File

@@ -0,0 +1,55 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace App\Merchant\Controllers\Setting;
use App\Merchant\Controllers\Controller;
use Auth;
use Illuminate\Http\Request;
use Validator;
class IndexController extends Controller
{
/**
* 修改密码
* @param Request $request 数据集
* @return [type] [description]
*/
public function password(Request $request)
{
$user = Auth::guard('merchant')->user();
if ($request->isMethod('post')) {
$validator = Validator::make($request->all(), [
'password' => 'required|confirmed',
'password_confirmation' => 'required',
], [
'password.required' => '新密码必须填写',
'password_confirmation.required' => '确认密码必须填写',
'password.confirmed' => '两次密码不一致',
]);
if ($validator->fails()) {
return $this->error($validator->errors()->first());
}
$user->password = $request->password;
$res = $user->save();
if ($res === true) {
return $this->success('修改成功');
} else {
return $this->error('修改失败');
}
} else {
return view('Merchant::setting.password');
}
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Merchant\Controllers\Traits;
trait AjaxResponse
{
protected function success($message = '', $url = null, $data = null)
{
return [
'code' => 1,
'msg' => $message ?: '操作成功',
'url' => is_null($url) ? '' : route($url),
'data' => $data,
];
}
protected function error($message = '', $url = null, $data = null)
{
return [
'code' => 0,
'msg' => $message ?: '操作失败',
'url' => is_null($url) ? '' : route($url),
'data' => $data,
];
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace App\Merchant\Exporters;
use App\Models\Coupon;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class CensusExport implements FromCollection, WithMapping, WithHeadings
{
use Exportable;
public $year = '';
public $month = '';
public $user = '';
public function __construct($date, $user)
{
$this->year = $date[0];
$this->month = $date[1];
$this->user = $user;
$this->fileName = '核销统计' . $this->year . '-' . $this->month . '.xlsx';
}
public function headings(): array
{
return ['日期', '100元减10元优惠券', '100元减25元优惠券', '100元减50元优惠券', '200元减100元优惠券'];
}
public function collection()
{
$coupons = Coupon::where('user_id', $this->user->id)
->whereYear('created_at', $this->year)
->whereMonth('created_at', $this->month)
->where('status', 2)
->get(['id', 'thirdPartyGoodsId', 'created_at']);
$coupons = $coupons->groupBy('create_day')->map(function ($items, $key) {
$data = [
'day' => $key,
'ysd10' => $items->where('thirdPartyGoodsId', 'YSD-full100-10')->count() ?? 0,
'ysd25' => $items->where('thirdPartyGoodsId', 'YSD-full100-25')->count() ?? 0,
'ysd50' => $items->where('thirdPartyGoodsId', 'YSD-full100-50')->count() ?? 0,
'ysd100' => $items->where('thirdPartyGoodsId', 'YSD-full200-100')->count() ?? 0,
];
return collect($data);
});
$coupons = $coupons->sortByDesc('day');
return $coupons;
}
public function map($info): array
{
$data = [
$info['day'],
' ' . $info['ysd10'],
' ' . $info['ysd25'],
' ' . $info['ysd50'],
' ' . $info['ysd100'],
];
return $data;
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace App\Merchant\Exporters;
use App\Models\Coupon;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class CouponExport implements FromQuery, WithMapping, WithHeadings
{
use Exportable;
public $outlet = '';
public $status = '';
public $redemptionCode = '';
public $start = '';
public $end = '';
public $user = '';
public $thirdPartyGoodsId = '';
public function __construct($serchDatas, $user)
{
$this->fileName = '卡券记录' . date('YmdHis') . '.xlsx';
$this->user = $user;
if (!empty($serchDatas)) {
foreach ($serchDatas as $key => $data) {
if ($data) {
$this->$key = $data;
}
}
}
}
public function headings(): array
{
return ['ID', '网点名称', '平安券编号', '优惠政策', '核销金额', '状态', '处理结果', '核销时间'];
}
/**
* @inheritDoc
*/
public function query()
{
return Coupon::where('user_id', $this->user->id)
->when($this->outlet, function ($q) {
$q->whereHas('outlet', function ($q) {
$q->whereHas('info', function ($q) {
$q->where('nickname', 'like', "%{$this->outlet}%");
});
});
})
->when($this->redemptionCode, function ($q) {
$q->where('redemptionCode', $this->redemptionCode);
})
->when($this->thirdPartyGoodsId, function ($q) {
$q->where('thirdPartyGoodsId', $this->thirdPartyGoodsId);
})
->when(is_numeric($this->status), function ($query) {
if ($this->status == 4) {
$query->where('is_profit', 1);
} else {
$query->where('status', $this->status);
}
})
->when($this->start && $this->end, function ($query) {
$query->whereBetween('created_at', [$this->start, $this->end]);
})
->when($this->start, function ($query) {
$query->where('created_at', '>', $this->start);
})
->when($this->end, function ($query) {
$query->where('created_at', '<', $this->end);
})
->whereIn('status', [2, 3])
->orderBy('created_at', 'desc');
}
public function map($info): array
{
$data = [
$info->id,
$info->outlet ? $info->outlet->nickname : 'Id:' . $info->outletId,
' ' . $info->redemptionCode,
' ' . $info->couponName,
$info->price,
$info->status_text,
$info->remark,
$info->created_at,
];
return $data;
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace App\Merchant;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
class MerchantServiceProvider extends ServiceProvider
{
protected $routeMiddleware = [
'merchant.auth' => Middleware\Authenticate::class,
'merchant.guest' => Middleware\Guest::class,
];
protected $middlewareGroups = [
'merchant' => [
'merchant.auth',
],
];
public function boot()
{
$this->publishes([__DIR__ . '/Resources/assets' => public_path('assets/merchant')]);
$this->loadViewsFrom(__DIR__ . '/Resources/views', 'Merchant');
}
public function register()
{
$this->registerRouteMiddleware();
$this->loadAdminRoutes();
}
protected function registerRouteMiddleware()
{
foreach ($this->routeMiddleware as $key => $middleware) {
Route::aliasMiddleware($key, $middleware);
}
}
protected function loadAdminRoutes()
{
Route::middleware('web')
->prefix('merchant')
->name('merchant.')
->namespace('App\Merchant\Controllers')
->group(__DIR__ . '/routes.php');
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace App\Merchant\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class Authenticate
{
public function handle($request, Closure $next)
{
if (Auth::guard('merchant')->guest()) {
return redirect()->route('merchant.login');
}
return $next($request);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace App\Merchant\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class Guest
{
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard('merchant')->check()) {
return redirect()->route('merchant.index');
}
return $next($request);
}
}

View File

@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>{{ config('app.name', '') }} --渠道管理系统登录</title>
<link rel="stylesheet" href="{{ asset('assets/merchant/js/plugins/layui/css/layui.css') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/login.css') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/animate.min.css') }}" />
<style type="text/css">
body {
background-image: url({{ asset('assets/merchant/img/bg'.rand(1,3).'.jpg') }});
}
</style>
<script>
if (window.top !== window.self) {
window.top.location = window.location;
}
</script>
</head>
<body>
<div class="mask"></div>
<div class="main">
<h1><span style="font-size: 84px;">{{ config('app.name', '') }} 渠道管理</span><span style="font-size:20px;">{{ env('APP_VERSION') }}</span></h1>
<div class="enter">
<h2 class="animated">Click&nbsp;&nbsp;Here&nbsp;&nbsp;To&nbsp;&nbsp;Login</h2>
<form action="{{ route('merchant.login') }}" class="layui-form animated bounceInLeft" method="post">
<div class="layui-form-item">
<label class="login-icon"> <i class="layui-icon">&#xe612;</i> </label>
<input type="text" name="username" lay-verify="username" autocomplete="off" placeholder="请输入登录名" class="layui-input" value="" />
</div>
<div class="layui-form-item">
<label class="login-icon"> <i class="layui-icon">&#xe642;</i> </label>
<input type="password" name="password" lay-verify="password" autocomplete="off" placeholder="请输入密码" class="layui-input" />
</div>
<div class="layui-form-item">
<div class="pull-left login-remember">
<label>记住帐号?</label>
<input type="checkbox" name="remember" value="true" checked lay-skin="switch" title="保持登录">
</div>
<div class="pull-right">
@csrf
<button class="layui-btn layui-btn-primary" lay-submit lay-filter="login"> <i class="layui-icon">&#xe650;</i> 登录 </button>
</div>
<div class="clear"></div>
</div>
</form>
</div>
</div>
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/layui/layui.js') }}"></script>
<script>
layui.use(['form'], function() {
var $ = layui.jquery, form = layui.form();
$("h2").on('click', function(){
$(this).hide();
$('.layui-form').show();
});
layer.config({
time: 1000
});
form.verify({
username: function (value) {
if (value.length < 4 || value.length > 20) {
return "账号应在4-20位之间"
}
var reg = /^[a-zA-Z0-9]*$/;
if (!reg.test(value)) {
return "账号只能为英文或数字";
}
},
password: [/^[\S]{4,20}$/, '密码应在4-20位之间'],
verify: [/^[\S]{4}$/, '验证码长度有误']
});
form.on('submit(login)', function(data) {
layer.load(2);
$('form').removeClass('bounceInLeft');
$.post(data.form.action, data.field, function(res) {
layer.closeAll('loading');
if (res.code == 1) {
layer.msg(res.msg, {icon: 1, time: 1000}, function() {
location.href = res.url;
});
} else {
$('form').addClass('shake');
layer.msg(res.msg, {icon: 5}, function() {
$('form').removeClass('shake');
});
$('.code').click();
}
});
return false;
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,97 @@
@extends('Merchant::layouts.app')
@section('title', '核销统计')
@section('css')
<link rel="stylesheet" href="{{ asset('assets/merchant/css/plugins/datapicker/datepicker3.css') }}" />
@endsection
@push('script')
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/datapicker/bootstrap-datepicker.js') }}"></script>
<script type="text/javascript">
$("#time-interval .input-daterange").datepicker({
autoclose: true, //自动关闭
beforeShowDay: $.noop, //在显示日期之前调用的函数
clearBtn: true, //显示清除按钮
forceParse: true, //是否强制转换不符合格式的字符串
format: 'yyyy-mm', //日期格式
language: 'cn', //语言
minViewMode: 1, // 最小精度选择
startView: 1, //开始显示
WeekHighlighted:true, // 本周高亮
endDate:new Date()
});
$("button").click(function(){
var $this = $(this);
var $form = $this.parents('form');
$("input[name='action']").val($this.data('action'));
$form.submit();
});
</script>
@endpush
@section('content')
<div class="ibox">
<div class="row">
<div class="col-sm-12 m-b">
<form action="{{ route('merchant.census')}}" class="form-inline pull-right" method="get" accept-charset="utf-8">
<div class="form-group" id="time-interval">
<div class="input-daterange input-group">
<input type="text" class="input-sm form-control" placeholder="核销月份" readonly name="month" value="{{ Request::input('month')??now()->format('Y-m') }}" />
</div>
</div>
<div class="input-group">
<span class="input-group-btn">
<input type="hidden" name="action" value="search">
<button type="button" class="btn btn-sm btn-primary" data-action="search" ><i class="fa fa-check"></i>&nbsp;刷新</button>
<button type="button" class="btn btn-sm btn-warning confirm" tip='确认要导出当前条件内容?' data-action="excel"><i class="fa fa-paste"></i>&nbsp;导出</button>
</span>
</div>
</form>
</div>
</div>
<div class="ibox-content">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>日期</th>
<th>100元减10元优惠券</th>
<th>100元减25元优惠券</th>
<th>100元减50元优惠券</th>
<th>200元减100元优惠券</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach ($coupons as $coupon)
<tr>
<td> {{ $coupon['day'] }} </td>
<td> {{ $coupon['ysd10'] ??''}} </td>
<td> {{ $coupon['ysd25'] ??''}} </td>
<td> {{ $coupon['ysd50'] ??''}} </td>
<td> {{ $coupon['ysd100']??'' }} </td>
<td>
<a href="{{ route('merchant.coupons',['start'=>$coupon['day'],'end'=>$coupon['day']]) }}">查看</a>
</td>
</tr>
@endforeach
<tr style="color: #f8ac59">
<td> 全部</td>
<td> {{ $all['ysd10'] ??''}} </td>
<td> {{ $all['ysd25'] ??''}} </td>
<td> {{ $all['ysd50'] ??''}} </td>
<td> {{ $all['ysd100']??'' }} </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,57 @@
<!--左侧导航开始-->
<nav class="navbar-default navbar-static-side" role="navigation">
<div class="nav-close">
<i class="fa fa-times-circle"></i>
</div>
<div class="sidebar-collapse">
<ul class="nav" id="side-menu">
<li class="nav-header">
<div class="dropdown profile-element">
<span><img alt="image" class="img-circle" src="{{ asset('assets/merchant/img/avatar.jpg') }}" width="70" height ="70" /></span>
<a data-toggle="dropdown" class="dropdown-toggle" href="javascript:void(0);">
<span class="clear">
<span class="block m-t-xs">
<strong class="font-bold">{{ Auth::guard('merchant')->user()->info->nickname }}({{ Auth::guard('merchant')->user()->username }})</strong>
</span>
<span class="text-muted text-xs block">修改密码 <b class="caret"></b></span>
</span>
</a>
<ul class="dropdown-menu m-t-xs">
<li><a data-toggle="layer" data-height="360" data-width="700" href="{{ route('merchant.setting.password') }}" class ="password">修改密码</a></li>
</ul>
</div>
<div class="logo-element">FX</div>
</li>
{{-- <li>--}}
{{-- <a href="#">--}}
{{-- <i class="fa fa-user"></i>--}}
{{-- <span class="nav-label">个人信息</span>--}}
{{-- <span class="fa arrow"></span>--}}
{{-- </a>--}}
{{-- <ul class="nav nav-second-level">--}}
{{-- <li>--}}
{{-- <a class="J_menuItem" href="{{ route('merchant.setting.password') }}"><i class="fa fa-list"></i>修改登陆密码</a>--}}
{{-- </li>--}}
{{-- </ul>--}}
{{-- </li>--}}
<li>
<a href="#">
<i class="fa fa-users"></i>
<span class="nav-label">平安券管理</span>
<span class="fa arrow"></span>
</a>
<ul class="nav nav-second-level">
<li>
<a class="J_menuItem" href="{{ route('merchant.coupons') }}"><i class="fa fa-list"></i>核销记录</a>
<a class="J_menuItem" href="{{ route('merchant.census') }}"><i class="fa fa-list"></i>核销统计</a>
</li>
</ul>
</li>
</ul>
</div>
</nav>
<!--左侧导航结束-->

View File

@@ -0,0 +1,9 @@
<ul class="nav navbar-top-links navbar-right">
<li><h3>渠道后台管理系统</h3></li>
{{-- <li>
<a href="/" target="_blank" title="网站主页"><i class="fa fa-home"></i></a>
</li> --}}
<li>
<a href="javascript:void(0);" id="refreshActive" title="刷新当前页面"><i class="fa fa-refresh"></i></a>
</li>
</ul>

View File

@@ -0,0 +1,53 @@
@if ($paginator->hasPages())
<form action="{{ url()->current() }}" method="get" accept-charset="utf-8">
<ul class="pagination" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span class="page-link" aria-hidden="true">&lsaquo;</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span class="page-link" aria-hidden="true">&rsaquo;</span>
</li>
@endif
<li class="page-item disabled" aria-disabled="true">
<span class="page-link" aria-hidden="true">{{ $paginator->total() }}</span>
</li>
<li>
<input type="text" style="width:50px;height:28px;border:1px solid #DDD;border-left:none;vertical-align:top;text-align:center" name="page" value="{{ $paginator->currentPage() }}"><button type="submit" class="btn btn-sm" style="border-radius: 0 3px 3px 0;padding: 4px;">跳转</button>
</li>
</ul>
</form>
@endif

View File

@@ -0,0 +1,145 @@
@extends('Merchant::layouts.app')
@section('title', '核销列表')
@section('css')
<link rel="stylesheet" href="{{ asset('assets/merchant/css/plugins/datapicker/datepicker3.css') }}" />
@endsection
@push('script')
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/datapicker/bootstrap-datepicker.js') }}"></script>
<script type="text/javascript">
$("#time-interval .input-daterange").datepicker({
keyboardNavigation: !1,
forceParse: !1,
autoclose: !0,
clearBtn: true,
});
$("button").click(function(){
var $this = $(this);
var $form = $this.parents('form');
$("input[name='action']").val($this.data('action'));
$form.submit();
});
</script>
@endpush
@section('content')
<div class="ibox">
<div class="ibox-content">
<div class="row">
<div class="col-sm-12 m-b">
<form action="{{ route('merchant.coupons')}}" class="form-inline pull-right" method="get" accept-charset="utf-8">
<div class="input-group">
<div class="form-group">
<input type="text" placeholder="网点名称" name="outlet" class="input-sm form-control" value="{{ Request::input('outlet') }}">
</div>
<div class="form-group">
<input type="text" placeholder="平安券编号" name="redemptionCode" class="input-sm form-control" value="{{ Request::input('redemptionCode') }}">
</div>
<div class="form-group">
<select class="form-control m-b" name="status">
<option value="">状态</option>
<option value="2" @if(request()->status==2) selected="" @endif >核销成功</option>
<option value="3" @if(request()->status==3) selected="" @endif >核销失败</option>
{{-- <option value="4" @if(request()->status==4) selected="" @endif >已分润</option> --}}
</select>
</div>
<div class="form-group">
<select class="form-control m-b" name="thirdPartyGoodsId">
<option value="">政策</option>
<option value="YSD-full100-10" @if(request()->thirdPartyGoodsId=='YSD-full100-10') selected="" @endif >100减10元</option>
<option value="YSD-full100-25" @if(request()->thirdPartyGoodsId=='YSD-full100-25') selected="" @endif >100减25元</option>
<option value="YSD-full100-50" @if(request()->thirdPartyGoodsId=='YSD-full100-50') selected="" @endif >100减50元</option>
<option value="YSD-full200-100" @if(request()->thirdPartyGoodsId=='YSD-full200-100') selected="" @endif >200减100元</option>
</select>
</div>
<div class="form-group" id="time-interval">
<div class="input-daterange input-group">
<input type="text" class="input-sm form-control" placeholder="核销时间" readonly name="start" value="{{ Request::input('start') }}" />
<span class="input-group-addon">~</span>
<input type="text" class="input-sm form-control" placeholder="核销时间" readonly name="end" value="{{ Request::input('end') }}" />
</div>
</div>
<span class="input-group-btn">
<input type="hidden" name="action" value="search">
<button type="button" class="btn btn-sm btn-primary" data-action="search" ><i class="fa fa-check"></i>&nbsp;搜索</button>
<button type="button" class="btn btn-sm btn-warning confirm" tip='确认要导出当前条件内容?' data-action="excel"><i class="fa fa-paste"></i>&nbsp;导出</button>
</span>
<span class="input-group-btn">
{{-- <button type="submit" class="btn btn-sm btn-primary " ><i class="fa fa-check"></i>&nbsp;搜索</button>--}}
{{-- <button class="btn btn-sm btn-primary" type="button" data-toggle="layer" data-height="360" data-width="700" href="{{ route('merchant.coupons.profits') }}">
<i class="fa fa-plus"></i>
批量分润
</button> --}}
</span>
</div>
</form>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th width="100">ID</th>
<th>网点名称</th>
{{-- <th>订单号</th> --}}
<th>平安券编号</th>
<th>优惠政策</th>
<th>核销金额</th>
<th>状态</th>
<th>处理结果</th>
<th>核销时间</th>
{{-- <th>操作</th> --}}
</tr>
</thead>
<tbody>
@foreach ($coupons as $coupon)
<tr>
<td> {{ $coupon->id }} </td>
<td>{{ $coupon->outlet ? $coupon->outlet->nickname : 'Id:' . $coupon->outletId }}</td>
{{-- <td>{{ $coupon->partnerOrderId }}</td> --}}
<td>{{ $coupon->redemptionCode }}</td>
<td>{{ $coupon->couponName }}</td>
<td>{{ $coupon->price }}</td>
<td>{{ $coupon->status_text }}</td>
<td>{{ $coupon->remark }}</td>
<td>{{ $coupon->created_at }}</td>
{{-- <td>
<a class="btn btn-sm btn-primary ajax-get confirm" tip="您确定要分润吗" href="{{ route('merchant.coupons.profit',$coupon)}}">分润</a>
</td> --}}
</tr>
@endforeach
</tbody>
</table>
</div>
<div>
<span class="badge badge-primary">全部:{{ $data['all'] }} </span>
<span class="badge badge-success">成功:{{ $data['pass'] }} </span>
<span class="badge badge-error">失败:{{ $data['reject'] }} </span>
{{-- <span class="badge badge-primary">核销金额:{{ $data['price'] }} </span> --}}
{{-- <span class="badge badge-primary">分润金额:{{ $data['profit'] }} </span> --}}
{{-- <span class="badge badge-primary">打款金额:{{ $data['hasPrice'] }} </span> --}}
</div>
<div class="text-right">
{{
$coupons->appends([
'outlet'=>Request::input('outlet'),
'status'=>Request::input('status'),
'redemptionCode'=>Request::input('redemptionCode'),
'start'=>Request::input('start'),
'end'=>Request::input('end'),
])->links('Merchant::common.pagination')
}}
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,39 @@
@extends('Merchant::layouts.app')
@section('title', '订单列表')
@section('css')
<link rel="stylesheet" href="{{ asset('assets/merchant/css/plugins/datapicker/datepicker3.css') }}" />
@endsection
@push('script')
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/datapicker/bootstrap-datepicker.js') }}"></script>
<script type="text/javascript">
$("#time-interval .input-daterange").datepicker({
keyboardNavigation: !1,
forceParse: !1,
autoclose: !0,
clearBtn: true,
});
</script>
@endpush
@section('content')
<form method="post" class="form-horizontal">
<div class="form-group" id="time-interval">
<label class="col-xs-3 control-label">日期</label>
<div class="col-xs-8 input-daterange">
<input type="text" class="input-sm form-control" placeholder="核销时间" readonly name="date" value="" />
</div>
</div>
<div class="form-group">
<div class="col-xs-8 col-xs-offset-3">
@csrf
<button class="btn btn-primary ajax-post" type="submit">确认分润</button>
</div>
</div>
</form>
@endsection

View File

@@ -0,0 +1,21 @@
@extends('Merchant::layouts.app')
@section('title', 'dashboard - index')
@section('content')
<div class="row">
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>商户信息</h5>
</div>
<div class="ibox-content">
<p><i class="fa "></i> 登录账户:{{ $user->username}}</p>
<p><i class="fa "></i> 用户昵称:{{ $user->nickname}}</p>
<p><i class="fa "></i> 用户身份:{{ $user->identity_text}}</p>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="renderer" content="webkit" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<title>{{ config('app.name', '') }} 渠道后台管理系统</title>
<link rel="stylesheet" href="{{ asset('assets/merchant/css/bootstrap.min.css?v=3.3.6') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/font-awesome.min.css?v=4.4.0') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/animate.min.css') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/style.min.css?v=4.1.0') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/plugins/sweetalert/sweetalert.css') }}" />
<script type="text/javascript" src="{{ asset('assets/merchant/js/jquery.min.js?v=2.1.4') }}"></script>
</head>
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow:hidden">
<div id="wrapper">
@include('Merchant::common.menu')
<!--右侧部分开始-->
<div id="page-wrapper" class="gray-bg dashbard-1">
<div class="row border-bottom">
<nav class="navbar navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<a class="navbar-minimalize minimalize-styl-2 btn btn-primary" href="#"><i class="fa fa-bars"></i></a>
</div>
@include('Merchant::common.msg')
</nav>
</div>
<div class="row content-tabs">
<button class="roll-nav roll-left J_tabLeft"><i class="fa fa-backward"></i></button>
<nav class="page-tabs J_menuTabs">
<div class="page-tabs-content">
<a href="javascript:;" class="active J_menuTab" data-id="{{ route('merchant.dashboard') }}">首页</a>
</div>
</nav>
<button class="roll-nav roll-right J_tabRight"><i class="fa fa-forward"></i></button>
<div class="btn-group roll-nav roll-right">
<button class="dropdown J_tabClose" data-toggle="dropdown">关闭操作&nbsp;<span class="caret"></span></button>
<ul role="menu" class="dropdown-menu dropdown-menu-right">
<li class="J_tabShowActive"><a>定位当前选项卡</a></li>
<li class="J_tabReloadActive"><a>重载当前选项卡</a></li>
<li class="divider"></li>
<li class="J_tabCloseAll"><a>关闭全部选项卡</a></li>
<li class="J_tabCloseOther"><a>关闭其他选项卡</a></li>
</ul>
</div>
<a href="javascript:void(0);" data-href="{{ route('merchant.logout') }}" class="roll-nav roll-right J_tabExit"><i class="fa fa fa-sign-out"></i>&nbsp;退出</a>
</div>
<div class="row J_mainContent" id="content-main">
<iframe class="J_iframe" name="iframe0" width="100%" height="100%" src="{{ route('merchant.dashboard') }}" frameborder="0" data-id="{{ route('merchant.dashboard') }}" seamless></iframe>
</div>
<div class="footer">
<div class="pull-right">
&copy; 2018-{{ date('Y') }} V 1.0
</div>
</div>
</div>
<!--右侧部分结束-->
</div>
<script type="text/javascript" src="{{ asset('assets/merchant/js/bootstrap.min.js?v=3.3.6') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/metisMenu/jquery.metisMenu.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/slimscroll/jquery.slimscroll.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/layer/layer.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/hplus.min.js?v=4.1.0') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/sweetalert/sweetalert.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/layer/layer.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/contabs.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/common.js') }}"></script>
</body>
</html>

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@yield('title','商户管理')</title>
<link rel="stylesheet" href="{{ asset('assets/merchant/css/bootstrap.min.css?v=3.3.6') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/font-awesome.min.css?v=4.4.0') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/animate.min.css') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/style.min.css?v=4.1.0') }}" />
<link rel="stylesheet" href="{{ asset('assets/merchant/css/plugins/sweetalert/sweetalert.css') }}" />
@yield('css')
@yield('js')
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeInDown">
@yield('content')
</div>
<script type="text/javascript" src="{{ asset('assets/merchant/js/jquery.min.js?v=2.1.4') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/bootstrap.min.js?v=3.3.6') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/content.min.js?v=1.0.0') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/pace/pace.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/sweetalert/sweetalert.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/plugins/layer/layer.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/merchant/js/common.js') }}"></script>
@stack('script')
</body>
</html>

View File

@@ -0,0 +1,58 @@
@extends('Merchant::layouts.app')
@section('title', '修改密码')
@section('content')
<form class="form-horizontal" method="post" action="{{ route('merchant.setting.password') }}">
<div class="form-group">
<label class="col-xs-3 control-label">新密码</label>
<div class="col-xs-8">
<input type="password" class="form-control" value="" name="password">
</div>
</div>
<div class="form-group">
<label class="col-xs-3 control-label">确认密码</label>
<div class="col-xs-8">
<input type="password" class="form-control" value="" name="password_confirmation">
</div>
</div>
<div class="form-group">
<div class="col-xs-offset-3 col-xs-8">
@csrf
<button class="btn btn-primary btn-block ajax" type="button">
<i class="icon icon-check"></i> 保存
</button>
</div>
</div>
</form>
@endsection
@push('script')
<script type="text/javascript">
$('body').on('click', '.ajax', function(event) {
if ($(this).hasClass('disabled') || $(this).attr('disabled')) {
return false;
};
event.preventDefault();
var $this = $(this);
var $form = $this.parents('form');
var $action = $form.attr("action");
$this.attr('disabled', 'disabled');
var query = $form.serialize();
$.post($action, query, function(res) {
$this.removeAttr('disabled');
if (res.code) {
parent.updateAlert(res.msg, res.code, function() {
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
});
} else {
parent.updateAlert(res.msg, res.code);
}
});
});
</script>
@endpush

19
app/Merchant/routes.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
// 登录
Route::match(['get', 'post'], 'login', 'AuthController@login')->name('login');
Route::middleware(['merchant.auth'])->group(function ($route) {
$route->get('dashboard', 'IndexController@dashboard')->name('dashboard');
$route->get('/', 'IndexController@index')->name('index');
$route->get('logout', 'AuthController@logout')->name('logout');
$route->get('coupons', 'Coupon\IndexController@index')->name('coupons');
$route->get('coupons/{coupon}/profit', 'Coupon\IndexController@profit')->name('coupons.profit');
$route->any('coupons/profits', 'Coupon\IndexController@profits')->name('coupons.profits');
$route->any('setting/password', 'Setting\IndexController@password')->name('setting.password');
$route->get('census', 'Census\IndexController@index')->name('census');
});

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