Commit 18bb1b13 authored by 刘小敏's avatar 刘小敏

管理后台功能:代理商审批和代理商管理 初始化

parent 7c9a426b
<?php
namespace app\admin\controller\shopro\agent;
use app\common\controller\Backend;
/**
* 代理商
*
* @icon fa fa-circle-o
*/
class Agent extends Backend
{
/**
* Agent模型对象
* @var \app\admin\model\shopro\agent\Agent
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\shopro\agent\Agent;
$this->view->assign("statusList", $this->model->statusList());
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
/**
* 编辑
*/
public function edit($ids = null)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
// 佣金类型列表
$commissionModel = new \app\admin\model\shopro\agent\AgentCommission;
$this->view->assign('typeList', $commissionModel->typeList());
// 佣金流水分页查询(支持 Ajax 分页请求)
if ($this->request->isAjax() && $this->request->request('commission_page')) {
$where = [
'agent_id' => $row->id,
];
$offset = $this->request->request('offset', 0);
$limit = 10;
$list = $commissionModel
->where($where)
->order('id', 'desc')
->limit($offset, $limit)
->select();
$total = $commissionModel->where($where)->count();
return json([
'code' => 1,
'total' => $total,
'rows' => $list,
]);
}
if ($this->request->isPost()) {
$params = $this->request->post('row/a');
if (empty($params)) {
$this->error(__('Parameter %s can not be empty', ''));
}
$result = false;
\think\Db::startTrans();
try {
$result = $row->allowField(true)->save($params);
\think\Db::commit();
} catch (\Exception $e) {
\think\Db::rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success();
} else {
$this->error(__('No rows updated'));
}
}
$this->view->assign('row', $row);
return $this->view->fetch();
}
/**
* 查看
*/
public function index()
{
//当前是否为关联查询
$this->relationSearch = false;
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage,则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->where($where)
->order($sort, $order)
->paginate($limit);
foreach ($list as $row) {
$row->visible(['id','user_id','province_name','real_name','id_card','id_card_images','commission_rate','total_commission','status','apply_id','createtime','updatetime']);
}
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
}
<?php
namespace app\admin\controller\shopro\agent;
use app\common\controller\Backend;
use think\Db;
use think\exception\PDOException;
use Exception;
/**
* 代理申请记录
*
* @icon fa fa-circle-o
*/
class Apply extends Backend
{
/**
* Apply模型对象
* @var \app\admin\model\shopro\agent\Apply
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\shopro\agent\Apply;
$this->view->assign("statusList", $this->model->statusList());
}
/**
* 查看
*/
public function index()
{
//当前是否为关联查询
$this->relationSearch = false;
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage,则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->where($where)
->order($sort, $order)
->paginate($limit);
foreach ($list as $row) {
$row->visible(['id','user_id','province_name','real_name','id_card','id_card_images','status','reject_reason','audit_user_id','audit_time','createtime','updatetime']);
}
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
/**
* 查看详情
*/
public function detail($ids)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* 批量审批(通过/驳回)
*/
public function multi($ids = null)
{
if (false === $this->request->isPost()) {
$this->error(__('Invalid parameters'));
}
$ids = $ids ?: $this->request->post('ids');
if (empty($ids)) {
$this->error(__('Parameter %s can not be empty', 'ids'));
}
// 解析 params 获取 status
parse_str($this->request->post('params', ''), $values);
$targetStatus = $values['status'] ?? '';
if (!in_array($targetStatus, [\app\admin\model\shopro\agent\Apply::STATUS_APPROVED, \app\admin\model\shopro\agent\Apply::STATUS_REJECTED])) {
$this->error(__('Invalid parameters'));
}
$rejectReason = $this->request->post('reject_reason', '');
$auditData = [
'status' => $targetStatus,
'audit_user_id' => $this->auth->id,
'audit_time' => time(),
];
if ($targetStatus == \app\admin\model\shopro\agent\Apply::STATUS_REJECTED) {
$auditData['reject_reason'] = $rejectReason;
}
// 只审批 status=pending 的记录
$count = 0;
$agentModel = new \app\admin\model\shopro\agent\Agent;
Db::startTrans();
try {
$list = $this->model->where('id', 'in', $ids)->where('status', \app\admin\model\shopro\agent\Apply::STATUS_PENDING)->select();
foreach ($list as $item) {
$count += $item->allowField(true)->isUpdate(true)->save($auditData);
// 审核通过后,新增代理商记录
if ($targetStatus == \app\admin\model\shopro\agent\Apply::STATUS_APPROVED) {
$agentData = [
'user_id' => $item->user_id,
'province_id' => $item->province_id ?? 0,
'province_name' => $item->province_name,
'real_name' => $item->real_name,
'id_card' => $item->id_card,
'id_card_images' => $item->id_card_images,
'commission_rate' => 5.00,
'total_commission' => 0.00,
'status' => \app\admin\model\shopro\agent\Agent::STATUS_NORMAL,
'apply_id' => $item->id,
];
$agentModel->isUpdate(false)->allowField(true)->data($agentData, true)->save();
}
}
Db::commit();
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($count) {
$this->success(__('Operate completed'), null, ['count' => $count]);
}
$this->error(__('No rows were updated'));
}
}
<?php
return [
'User_id' => '用户ID',
'Province_id' => '代理省份ID',
'Province_name' => '省份名称',
'Real_name' => '真实姓名(快照)',
'Id_card' => '身份证号(脱敏)',
'Id_card_images' => '身份证照片(JSON)',
'Commission_rate' => '佣金比例(%)',
'Total_commission' => '累计佣金',
'Status' => '状态',
'Status normal' => '正常',
'Set status to normal'=> '设为正常',
'Status frozen' => '已冻结',
'Set status to frozen'=> '设为已冻结',
'Apply_id' => '关联申请记录ID',
'Createtime' => '创建时间',
'Updatetime' => '更新时间',
'Commission_logs' => '佣金流水记录',
'Order_id' => '订单ID',
'Amount' => '佣金金额',
'Type' => '流水类型',
'Remark' => '备注',
];
<?php
return [
'User_id' => '申请人用户ID',
'Province_id' => '代理省份ID',
'Province_name' => '省份名称',
'Real_name' => '真实姓名',
'Id_card' => '身份证号',
'Id_card_images' => '身份证照片(JSON数组)',
'Status' => '审核状态',
'Status pending' => '审核中',
'Set status to pending'=> '设为审核中',
'Status approved' => '已通过',
'Set status to approved'=> '设为已通过',
'Status rejected' => '已驳回',
'Set status to rejected'=> '设为已驳回',
'Reject_reason' => '驳回原因',
'Audit_user_id' => '审核人ID',
'Audit_time' => '审核时间',
'Createtime' => '申请时间',
'Updatetime' => '更新时间',
'Batch approve' => '批量通过',
'Batch reject' => '批量驳回',
'Approve' => '通过',
'Reject' => '驳回',
'Please input reject reason' => '请输入驳回原因',
'Are you sure you want to approve the %s selected item?' => '确认要通过选中的 %s 条申请吗?',
'Are you sure you want to approve' => '确认要通过该申请吗?',
'Operate completed'=> '操作成功',
'No rows were updated' => '没有记录被更新(可能已审核过)',
];
<?php
namespace app\admin\model\shopro;
use think\Model;
class Agent extends Model
{
// 表名
protected $name = 'shopro_agent';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'integer';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = false;
// 追加属性
protected $append = [
'status_text'
];
public function getStatusList()
{
return ['normal' => __('Status normal'), 'frozen' => __('Status frozen')];
}
public function getStatusTextAttr($value, $data)
{
$value = $value ?: ($data['status'] ?? '');
$list = $this->getStatusList();
return $list[$value] ?? '';
}
}
<?php
namespace app\admin\model\shopro\agent;
use app\admin\model\shopro\Common;
class AgentCommission extends Common
{
protected $name = 'shopro_agent_commission';
// 佣金类型
const TYPE_ORDER_COMMISSION = 'order_commission'; // 订单佣金
const TYPE_REFUND = 'refund'; // 退款
const TYPE_MANUAL = 'manual'; // 手动调整
public function typeList()
{
return [
self::TYPE_ORDER_COMMISSION => '订单佣金',
self::TYPE_REFUND => '退款',
self::TYPE_MANUAL => '手动调整',
];
}
}
...@@ -6,7 +6,6 @@ use app\admin\model\shopro\Common; ...@@ -6,7 +6,6 @@ use app\admin\model\shopro\Common;
class Apply extends Common class Apply extends Common
{ {
protected $name = 'shopro_agent_apply';
protected $type = [ protected $type = [
'id_card_images' => 'json', 'id_card_images' => 'json',
...@@ -25,4 +24,25 @@ class Apply extends Common ...@@ -25,4 +24,25 @@ class Apply extends Common
self::STATUS_REJECTED => '已驳回', self::STATUS_REJECTED => '已驳回',
]; ];
} }
protected $append = [
'status_text',
];
// 表名
protected $name = 'shopro_agent_apply';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'integer';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = false;
protected function setAuditTimeAttr($value)
{
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
}
} }
<?php
namespace app\admin\validate\shopro;
use think\Validate;
class Agent extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}
<?php
namespace app\admin\validate\shopro\agent;
use think\Validate;
class Apply extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<td> <td>
<table class="table table-striped"> <table class="table table-striped">
{foreach name="row.params" id="item"} {foreach name="row.params" id="item"}
<tr><td>{$key|htmlentities}</td><td>{$item|htmlentities}</td></tr> <tr><td>{$key|htmlentities}</td><td>{if is_array($item)}{$item|json_encode|htmlentities}{else/}{$item|htmlentities}{/if}</td></tr>
{/foreach} {/foreach}
</table> </table>
</td> </td>
......
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-user_id" data-rule="required" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Province_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-province_id" data-rule="required" data-source="province/index" class="form-control selectpage" name="row[province_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Province_name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-province_name" class="form-control" name="row[province_name]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Real_name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-real_name" class="form-control" name="row[real_name]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Id_card')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-id_card" class="form-control" name="row[id_card]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Id_card_images')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-id_card_images" class="form-control" size="50" name="row[id_card_images]" type="textarea">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-id_card_images" class="btn btn-danger faupload" data-input-id="c-id_card_images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-id_card_images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-id_card_images" class="btn btn-primary fachoose" data-input-id="c-id_card_images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-id_card_images"></span>
</div>
<ul class="row list-inline faupload-preview" id="p-id_card_images"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Commission_rate')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-commission_rate" data-rule="required" class="form-control" step="0.01" name="row[commission_rate]" type="number" value="5.00">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Total_commission')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-total_commission" data-rule="required" class="form-control" step="0.01" name="row[total_commission]" type="number" value="0.00">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="radio">
{foreach name="statusList" item="vo"}
<label for="row[status]-{$key}"><input id="row[status]-{$key}" name="row[status]" type="radio" value="{$key}" {in name="key" value="normal"}checked{/in} /> {$vo}</label>
{/foreach}
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Apply_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-apply_id" data-rule="required" data-source="apply/index" class="form-control selectpage" name="row[apply_id]" type="text" value="">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
</form>
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-user_id" data-rule="required" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="{$row.user_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Province_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-province_id" data-rule="required" data-source="province/index" class="form-control selectpage" name="row[province_id]" type="text" value="{$row.province_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Province_name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-province_name" class="form-control" name="row[province_name]" type="text" value="{$row.province_name|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Real_name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-real_name" class="form-control" name="row[real_name]" type="text" value="{$row.real_name|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Id_card')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-id_card" class="form-control" name="row[id_card]" type="text" value="{$row.id_card|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Id_card_images')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-id_card_images" class="form-control" size="50" name="row[id_card_images]" type="textarea" value="{:implode(',', (array)($row['id_card_images'] ?? []))}">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-id_card_images" class="btn btn-danger faupload" data-input-id="c-id_card_images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-id_card_images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-id_card_images" class="btn btn-primary fachoose" data-input-id="c-id_card_images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-id_card_images"></span>
</div>
<ul class="row list-inline faupload-preview" id="p-id_card_images"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Commission_rate')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-commission_rate" data-rule="required" class="form-control" step="0.01" name="row[commission_rate]" type="number" value="{$row.commission_rate|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Total_commission')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-total_commission" data-rule="required" class="form-control" step="0.01" name="row[total_commission]" type="number" value="{$row.total_commission|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="radio">
{foreach name="statusList" item="vo"}
<label for="row[status]-{$key}"><input id="row[status]-{$key}" name="row[status]" type="radio" value="{$key}" {in name="key" value="$row.status"}checked{/in} /> {$vo}</label>
{/foreach}
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Apply_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-apply_id" data-rule="required" data-source="apply/index" class="form-control selectpage" name="row[apply_id]" type="text" value="{$row.apply_id|htmlentities}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
</form>
<div class="panel panel-default" style="margin-top:15px;">
<div class="panel-heading">{:__('Commission_logs')}</div>
<div class="panel-body">
<table id="commission-table" class="table table-striped table-bordered table-hover"
width="100%">
</table>
</div>
</div>
<script type="text/javascript">
require(['jquery', 'bootstrap', 'table'], function ($, undefined, Table) {
var commissionTable = $("#commission-table");
var commissionAjax = function (params) {
var agentId = $('input[name="row[id]"]').length > 0
? $('input[name="row[id]"]').val()
: location.pathname.match(/edit\/(\d+)/)?.[1];
if (!agentId) {
// 从 Form.api 取值或 URL 截取
agentId = "{$row.id ?? ''}";
}
if (!agentId) {
params.success({ total: 0, rows: [] });
return;
}
$.ajax({
url: "{:url('shopro/agent/agent/edit', ['ids' => $row['id'] ?? 0])}",
data: $.extend({}, params.data, {
commission_page: 1,
offset: params.data.offset,
limit: params.data.limit
}),
type: 'get',
dataType: 'json',
success: function (res) {
params.success({ total: res.total, rows: res.rows });
},
error: function () {
params.success({ total: 0, rows: [] });
}
});
};
commissionTable.bootstrapTable({
url: '',
sidePagination: 'server',
pagination: true,
pageSize: 10,
pageList: [10, 20, 50],
showRefresh: false,
showToggle: false,
showColumns: false,
queryParams: function () {
return {};
},
ajax: commissionAjax,
columns: [
[
{ field: 'id', title: 'ID', width: 60, align: 'center', sortable: true },
{ field: 'order_id', title: '{:__("Order_id")}', width: 80, align: 'center' },
{ field: 'amount', title: '{:__("Amount")}', width: 100, align: 'center',
formatter: function (value) {
return '¥' + parseFloat(value).toFixed(2);
}
},
{ field: 'type', title: '{:__("Type")}', width: 100, align: 'center',
formatter: function (value) {
var typeMap = {:json_encode($typeList ?? [])};
return typeMap[value] || value;
}
},
{ field: 'remark', title: '{:__("Remark")}', align: 'left' },
{ field: 'createtime', title: '{:__("Createtime")}', width: 160, align: 'center',
formatter: function (value) {
if (!value) return '-';
var d = new Date(parseInt(value) * 1000);
return d.getFullYear() + '-' +
('0' + (d.getMonth() + 1)).slice(-2) + '-' +
('0' + d.getDate()).slice(-2) + ' ' +
('0' + d.getHours()).slice(-2) + ':' +
('0' + d.getMinutes()).slice(-2) + ':' +
('0' + d.getSeconds()).slice(-2);
}
}
]
]
});
});
</script>
<div class="panel panel-default panel-intro">
<div class="panel-heading">
{:build_heading(null,FALSE)}
<ul class="nav nav-tabs" data-field="status">
<li class="{:$Think.get.status === null ? 'active' : ''}"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
{foreach name="statusList" item="vo"}
<li class="{:$Think.get.status === (string)$key ? 'active' : ''}"><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
{/foreach}
</ul>
</div>
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('shopro/agent/agent/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('shopro/agent/agent/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('shopro/agent/agent/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
<div class="dropdown btn-group {:$auth->check('shopro/agent/agent/multi')?'':'hide'}">
<a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
<ul class="dropdown-menu text-left" role="menu">
{foreach name="statusList" item="vo"}
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:" data-params="status={$key}">{:__('Set status to ' . $key)}</a></li>
{/foreach}
</ul>
</div>
</div>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
data-operate-edit="{:$auth->check('shopro/agent/agent/edit')}"
data-operate-del="{:$auth->check('shopro/agent/agent/del')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-user_id" data-rule="required" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Province_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-province_id" data-rule="required" data-source="province/index" class="form-control selectpage" name="row[province_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Province_name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-province_name" class="form-control" name="row[province_name]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Real_name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-real_name" class="form-control" name="row[real_name]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Id_card')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-id_card" class="form-control" name="row[id_card]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Id_card_images')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-id_card_images" class="form-control" size="50" name="row[id_card_images]" type="textarea">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-id_card_images" class="btn btn-danger faupload" data-input-id="c-id_card_images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-id_card_images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-id_card_images" class="btn btn-primary fachoose" data-input-id="c-id_card_images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-id_card_images"></span>
</div>
<ul class="row list-inline faupload-preview" id="p-id_card_images"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="radio">
{foreach name="statusList" item="vo"}
<label for="row[status]-{$key}"><input id="row[status]-{$key}" name="row[status]" type="radio" value="{$key}" {in name="key" value="pending"}checked{/in} /> {$vo}</label>
{/foreach}
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Reject_reason')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-reject_reason" class="form-control" name="row[reject_reason]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Audit_user_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-audit_user_id" data-rule="required" data-source="audit/user/index" class="form-control selectpage" name="row[audit_user_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Audit_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-audit_time" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[audit_time]" type="text" value="{:date('Y-m-d H:i:s')}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
</form>
<table class="table table-striped">
<thead>
<tr>
<th>{:__('Title')}</th>
<th>{:__('Content')}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{:__('Id')}</td>
<td>{$row.id}</td>
</tr>
<tr>
<td>{:__('User_id')}</td>
<td>{$row.user_id}</td>
</tr>
<tr>
<td>{:__('Province_name')}</td>
<td>{$row.province_name}</td>
</tr>
<tr>
<td>{:__('Real_name')}</td>
<td>{$row.real_name}</td>
</tr>
<tr>
<td>{:__('Id_card')}</td>
<td>{$row.id_card}</td>
</tr>
<tr>
<td>{:__('Id_card_images')}</td>
<td>
{if !empty($row.id_card_images)}
{foreach name="row.id_card_images" item="img"}
<a href="{:cdnurl($img)}" target="_blank"><img src="{:cdnurl($img)}" style="max-width:200px;max-height:150px;margin:5px;" /></a>
{/foreach}
{else /}
-
{/if}
</td>
</tr>
<tr>
<td>{:__('Status')}</td>
<td>{$row.status_text|default='-'}</td>
</tr>
<tr>
<td>{:__('Reject_reason')}</td>
<td>{$row.reject_reason|default='-'}</td>
</tr>
<tr>
<td>{:__('Audit_user_id')}</td>
<td>{$row.audit_user_id|default='-'}</td>
</tr>
<tr>
<td>{:__('Audit_time')}</td>
<td>{:empty($row['audit_time']) ? '-' : date('Y-m-d H:i:s', $row['audit_time'])}</td>
</tr>
<tr>
<td>{:__('Createtime')}</td>
<td>{$row.createtime|datetime}</td>
</tr>
<tr>
<td>{:__('Updatetime')}</td>
<td>{$row.updatetime|datetime}</td>
</tr>
</tbody>
</table>
<div class="hide layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="reset" class="btn btn-primary btn-embossed btn-close" onclick="Layer.closeAll();">{:__('Close')}</button>
</div>
</div>
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-user_id" data-rule="required" data-source="user/user/index" data-field="nickname" class="form-control selectpage" name="row[user_id]" type="text" value="{$row.user_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Province_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-province_id" data-rule="required" data-source="province/index" class="form-control selectpage" name="row[province_id]" type="text" value="{$row.province_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Province_name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-province_name" class="form-control" name="row[province_name]" type="text" value="{$row.province_name|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Real_name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-real_name" class="form-control" name="row[real_name]" type="text" value="{$row.real_name|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Id_card')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-id_card" class="form-control" name="row[id_card]" type="text" value="{$row.id_card|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Id_card_images')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-id_card_images" class="form-control" size="50" name="row[id_card_images]" type="textarea" value="{$row.id_card_images|htmlentities}">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-id_card_images" class="btn btn-danger faupload" data-input-id="c-id_card_images" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-id_card_images"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-id_card_images" class="btn btn-primary fachoose" data-input-id="c-id_card_images" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-id_card_images"></span>
</div>
<ul class="row list-inline faupload-preview" id="p-id_card_images"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="radio">
{foreach name="statusList" item="vo"}
<label for="row[status]-{$key}"><input id="row[status]-{$key}" name="row[status]" type="radio" value="{$key}" {in name="key" value="$row.status"}checked{/in} /> {$vo}</label>
{/foreach}
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Reject_reason')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-reject_reason" class="form-control" name="row[reject_reason]" type="text" value="{$row.reject_reason|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Audit_user_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-audit_user_id" data-rule="required" data-source="audit/user/index" class="form-control selectpage" name="row[audit_user_id]" type="text" value="{$row.audit_user_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Audit_time')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-audit_time" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[audit_time]" type="text" value="{:$row.audit_time?datetime($row.audit_time):''}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button>
</div>
</div>
</form>
<div class="panel panel-default panel-intro">
<div class="panel-heading">
{:build_heading(null,FALSE)}
<ul class="nav nav-tabs" data-field="status">
<li class="{:$Think.get.status === null ? 'active' : ''}"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
{foreach name="statusList" item="vo"}
<li class="{:$Think.get.status === (string)$key ? 'active' : ''}"><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li>
{/foreach}
</ul>
</div>
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<a href="javascript:;" class="btn btn-success btn-approve btn-disabled disabled {:$auth->check('shopro/agent/apply/multi')?'':'hide'}" title="{:__('Batch approve')}" ><i class="fa fa-check"></i> {:__('Batch approve')}</a>
<a href="javascript:;" class="btn btn-danger btn-reject btn-disabled disabled {:$auth->check('shopro/agent/apply/multi')?'':'hide'}" title="{:__('Batch reject')}" ><i class="fa fa-times"></i> {:__('Batch reject')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
data-operate-detail="{:$auth->check('shopro/agent/apply/detail')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'shopro/agent/agent/index' + location.search,
// add_url: 'shopro/agent/agent/add',
edit_url: 'shopro/agent/agent/edit',
// del_url: 'shopro/agent/agent/del',
multi_url: 'shopro/agent/agent/multi',
import_url: 'shopro/agent/agent/import',
table: 'shopro_agent',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
fixedColumns: true,
fixedRightNumber: 1,
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'user_id', title: __('User_id')},
{field: 'province_name', title: __('Province_name'), operate: 'LIKE'},
{field: 'real_name', title: __('Real_name'), operate: 'LIKE'},
{field: 'id_card', title: __('Id_card'), operate: 'LIKE'},
{field: 'commission_rate', title: __('Commission_rate'), operate:'BETWEEN'},
{field: 'total_commission', title: __('Total_commission'), operate:'BETWEEN'},
{field: 'status', title: __('Status'), searchList: {"normal":__('Status normal'),"frozen":__('Status frozen')}, formatter: Table.api.formatter.status},
{field: 'apply_id', title: __('Apply_id')},
{field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
{field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
add: function () {
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'shopro/agent/apply/index' + location.search,
table: 'shopro_agent_apply',
}
});
var table = $("#table");
// 审批请求
var doAudit = function (ids, status, rejectReason, callback) {
var url = 'shopro/agent/apply/multi';
var data = {ids: ids, params: 'status=' + status};
if (rejectReason) {
data.reject_reason = rejectReason;
}
Fast.api.ajax({url: url, data: data}, function (data, ret) {
table.bootstrapTable('refresh');
if (typeof callback === 'function') {
callback();
}
});
};
// 获取单行ID
var getSingleRowId = function (btn) {
var tr = $(btn).closest('tr');
var data = table.bootstrapTable('getData');
var index = parseInt(tr.data('index'));
return data[index] ? data[index].id : null;
};
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
fixedColumns: true,
fixedRightNumber: 1,
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'user_id', title: __('User_id')},
{field: 'province_name', title: __('Province_name'), operate: 'LIKE'},
{field: 'real_name', title: __('Real_name'), operate: 'LIKE'},
{field: 'id_card', title: __('Id_card'), operate: 'LIKE'},
{field: 'status', title: __('Status'), searchList: {"pending":__('Status pending'),"approved":__('Status approved'),"rejected":__('Status rejected')}, formatter: Table.api.formatter.status},
{field: 'reject_reason', title: __('Reject_reason'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content},
{field: 'audit_user_id', title: __('Audit_user_id')},
{field: 'audit_time', title: __('Audit_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
{field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
{field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
{
field: 'operate',
title: __('Operate'),
buttons: [
{
name: 'detail',
title: __('Detail'),
text: __('Detail'),
url: 'shopro/agent/apply/detail',
icon: 'fa fa-list',
classname: 'btn btn-info btn-xs btn-detail btn-dialog'
},
{
name: 'approve',
title: __('Approve'),
text: __('Approve'),
icon: 'fa fa-check',
classname: 'btn btn-success btn-xs btn-approve-one'
},
{
name: 'reject',
title: __('Reject'),
text: __('Reject'),
icon: 'fa fa-times',
classname: 'btn btn-danger btn-xs btn-reject-one'
}
],
table: table,
events: Table.api.events.operate,
formatter: Table.api.formatter.operate
}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
// 单行通过
$(document).on('click', '.btn-approve-one', function (e) {
e.stopPropagation();
var id = getSingleRowId(this);
if (!id) return false;
var that = this;
Layer.confirm(
__('Are you sure you want to approve'),
{icon: 3, title: __('Warning'), offset: 0, shadeClose: true, btn: [__('OK'), __('Cancel')]},
function (index) {
Layer.close(index);
doAudit(String(id), 'approved');
}
);
return false;
});
// 单行驳回
$(document).on('click', '.btn-reject-one', function (e) {
e.stopPropagation();
var id = getSingleRowId(this);
if (!id) return false;
var that = this;
Layer.prompt({title: __('Please input reject reason'), area: ['400px', '150px']}, function (value, index) {
Layer.close(index);
doAudit(String(id), 'rejected', value);
});
return false;
});
// 工具栏:批量通过
$(document).on('click', '.toolbar .btn-approve', function () {
var ids = Table.api.selectedids(table);
if (ids.length === 0) {
Layer.msg(__('Please choose data to operate'));
return false;
}
Layer.confirm(
__('Are you sure you want to approve the %s selected item?', ids.length),
{icon: 3, title: __('Warning'), offset: 0, shadeClose: true, btn: [__('OK'), __('Cancel')]},
function (index) {
Layer.close(index);
doAudit(ids.join(','), 'approved');
}
);
return false;
});
// 工具栏:批量驳回
$(document).on('click', '.toolbar .btn-reject', function () {
var ids = Table.api.selectedids(table);
if (ids.length === 0) {
Layer.msg(__('Please choose data to operate'));
return false;
}
Layer.prompt({title: __('Please input reject reason'), area: ['400px', '150px']}, function (value, index) {
Layer.close(index);
doAudit(ids.join(','), 'rejected', value);
});
return false;
});
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment