正在显示
14 个修改的文件
包含
662 行增加
和
31 行删除
1 | +<?php | ||
2 | + | ||
3 | +namespace app\admin\controller\user; | ||
4 | + | ||
5 | +use app\common\controller\Backend; | ||
6 | +use EasyWeChat\Foundation\Application; | ||
7 | +use think\Db; | ||
8 | +use think\exception\PDOException; | ||
9 | +use think\exception\ValidateException; | ||
10 | + | ||
11 | +/** | ||
12 | + * 提现记录管理 | ||
13 | + * | ||
14 | + * @icon fa fa-circle-o | ||
15 | + */ | ||
16 | +class UserWithdraw extends Backend | ||
17 | +{ | ||
18 | + | ||
19 | + /** | ||
20 | + * UserWithdraw模型对象 | ||
21 | + * @var \app\admin\model\user\UserWithdraw | ||
22 | + */ | ||
23 | + protected $model = null; | ||
24 | + | ||
25 | + public function _initialize() | ||
26 | + { | ||
27 | + parent::_initialize(); | ||
28 | + $this->model = new \app\admin\model\user\UserWithdraw; | ||
29 | + $this->view->assign("statusList", $this->model->getStatusList()); | ||
30 | + } | ||
31 | + | ||
32 | + /** | ||
33 | + * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法 | ||
34 | + * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑 | ||
35 | + * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改 | ||
36 | + */ | ||
37 | + | ||
38 | + | ||
39 | + /** | ||
40 | + * 查看 | ||
41 | + */ | ||
42 | + public function index() | ||
43 | + { | ||
44 | + //当前是否为关联查询 | ||
45 | + $this->relationSearch = true; | ||
46 | + //设置过滤方法 | ||
47 | + $this->request->filter(['strip_tags', 'trim']); | ||
48 | + if ($this->request->isAjax()) | ||
49 | + { | ||
50 | + //如果发送的来源是Selectpage,则转发到Selectpage | ||
51 | + if ($this->request->request('keyField')) | ||
52 | + { | ||
53 | + return $this->selectpage(); | ||
54 | + } | ||
55 | + list($where, $sort, $order, $offset, $limit) = $this->buildparams(); | ||
56 | + $total = $this->model | ||
57 | + ->with(['user']) | ||
58 | + ->where($where) | ||
59 | + ->order($sort, $order) | ||
60 | + ->count(); | ||
61 | + | ||
62 | + $list = $this->model | ||
63 | + ->with(['user']) | ||
64 | + ->where($where) | ||
65 | + ->order($sort, $order) | ||
66 | + ->limit($offset, $limit) | ||
67 | + ->select(); | ||
68 | + | ||
69 | + foreach ($list as $row) { | ||
70 | + | ||
71 | + $row->getRelation('user')->visible(['nickname']); | ||
72 | + } | ||
73 | + $list = collection($list)->toArray(); | ||
74 | + $result = array("total" => $total, "rows" => $list); | ||
75 | + | ||
76 | + return json($result); | ||
77 | + } | ||
78 | + return $this->view->fetch(); | ||
79 | + } | ||
80 | + | ||
81 | + | ||
82 | + /** | ||
83 | + * 审核 | ||
84 | + */ | ||
85 | + public function examine($ids = null) | ||
86 | + { | ||
87 | + if($ids) { | ||
88 | + $row = $this->model->get($ids); | ||
89 | + if (!$row) { | ||
90 | + $this->error(__('No Results were found')); | ||
91 | + } | ||
92 | + $adminIds = $this->getDataLimitAdminIds(); | ||
93 | + if (is_array($adminIds)) { | ||
94 | + if (!in_array($row[$this->dataLimitField], $adminIds)) { | ||
95 | + $this->error(__('You have no permission')); | ||
96 | + } | ||
97 | + } | ||
98 | + $params = $this->request->param(); | ||
99 | + if ($params['status'] == 2) { | ||
100 | + if ($row->status == 2) { | ||
101 | + $this->error('该提现申请已通过审核'); | ||
102 | + } | ||
103 | + } | ||
104 | + if ($params['status'] == 3) { | ||
105 | + if ($row->status == 3) { | ||
106 | + $this->error('该提现申请已驳回审核'); | ||
107 | + } | ||
108 | + } | ||
109 | + $row->status = $params['status']; | ||
110 | + Db::startTrans(); | ||
111 | + try { | ||
112 | + $user_model = new \app\admin\model\User(); | ||
113 | + $user = $user_model->where('id', $row->user_id)->find(); | ||
114 | + if ($params['status'] == 2) { | ||
115 | + // 微信提现 | ||
116 | + $options = get_addon_config('epay'); | ||
117 | + $wechat_option = [ | ||
118 | + 'app_id' => $options['wechat']['appid'], | ||
119 | + 'app_secret' => $options['wechat']['app_secret'], | ||
120 | + 'payment' => [ | ||
121 | + 'merchant_id' => $options['wechat']['mch_id'], | ||
122 | + 'key' => $options['wechat']['key'], | ||
123 | + 'cert_path' => ROOT_PATH . 'addons' . $options['wechat']['cert_client'], | ||
124 | + 'key_path' => ROOT_PATH . 'addons' . $options['wechat']['cert_key'], | ||
125 | + ] | ||
126 | + ]; | ||
127 | + $app = new Application($wechat_option); | ||
128 | + $merchantPay = $app->merchant_pay; | ||
129 | + $order_sn = $row->order_sn; | ||
130 | + $user_openid = Db::name('third')->where('user_id', $row->user_id)->where('third_party', 'wechat')->value('openid'); | ||
131 | + $merchantPayData = [ | ||
132 | + 'partner_trade_no' => $order_sn, //随机字符串作为订单号,跟红包和支付一个概念。 | ||
133 | + 'openid' => $user_openid, //收款人的openid | ||
134 | + 'check_name' => 'NO_CHECK', //文档中有三种校验实名的方法 NO_CHECK OPTION_CHECK FORCE_CHECK | ||
135 | + 'amount' => $row->money * 100, //单位为分 | ||
136 | + 'desc' => '用户提现', | ||
137 | + 'spbill_create_ip' => request()->ip(), //发起交易的IP地址 | ||
138 | + ]; | ||
139 | + $result_pay = $merchantPay->send($merchantPayData); | ||
140 | + if ($result_pay['return_code'] == 'SUCCESS' && $result_pay['result_code'] == 'SUCCESS') { | ||
141 | + // 余额变动记录 | ||
142 | + $log = [ | ||
143 | + 'user_id' => $row->user_id, | ||
144 | + 'money' => $row->money, | ||
145 | + 'before' => $user['money'], | ||
146 | + 'after' => $user['money'] - $row->money, | ||
147 | + 'createtime' => time(), | ||
148 | + 'memo' => '用户微信提现' | ||
149 | + ]; | ||
150 | + $result_log = Db::name('user_money_log')->insertGetId($log); | ||
151 | + $row->success_time = time(); | ||
152 | + $row->more = json_encode($result_pay, JSON_UNESCAPED_UNICODE); | ||
153 | + } else { | ||
154 | + Db::rollback(); | ||
155 | + $this->error($result_pay['err_code_des']); | ||
156 | + } | ||
157 | + } else { | ||
158 | + // 返还用户余额 | ||
159 | + $result_user = $user_model->where('id', $user['id'])->setInc('money', $row->money); | ||
160 | + if (!$result_user) { | ||
161 | + Db::rollback(); | ||
162 | + $this->error('提现审核失败'); | ||
163 | + } | ||
164 | + } | ||
165 | + $result = $row->save(); | ||
166 | + Db::commit(); | ||
167 | + } catch (ValidateException $e) { | ||
168 | + Db::rollback(); | ||
169 | + $this->error($e->getMessage()); | ||
170 | + } catch (PDOException $e) { | ||
171 | + Db::rollback(); | ||
172 | + $this->error($e->getMessage()); | ||
173 | + } catch (\think\Exception $e) { | ||
174 | + Db::rollback(); | ||
175 | + $this->error($e->getMessage()); | ||
176 | + } | ||
177 | + if(!$result) { | ||
178 | + $this->error('提现审核失败'); | ||
179 | + } | ||
180 | + $this->success('提现审核成功'); | ||
181 | + } | ||
182 | + } | ||
183 | +} |
1 | +<?php | ||
2 | + | ||
3 | +return [ | ||
4 | + 'User_id' => '用户id', | ||
5 | + 'Before_money' => '提现前余额', | ||
6 | + 'After_money' => '提现后余额', | ||
7 | + 'Order_sn' => '提现单号', | ||
8 | + 'Status' => '订单状态', | ||
9 | + 'Status 0' => '待提现', | ||
10 | + 'Status 1' => '提现中', | ||
11 | + 'Status 2' => '提现完成', | ||
12 | + 'Status 3' => '提现失败', | ||
13 | + 'Pay_type' => '提现方式:1=微信', | ||
14 | + 'Money' => '提现金额', | ||
15 | + 'Success_time' => '提现时间', | ||
16 | + 'Transaction_id' => '提现回调参数', | ||
17 | + 'More' => '提现回调json', | ||
18 | + 'Createtime' => '创建时间', | ||
19 | + 'Updatetime' => '更新时间', | ||
20 | + 'Percent' => '提现手续费比例', | ||
21 | + 'User.nickname' => '昵称' | ||
22 | +]; |
1 | +<?php | ||
2 | + | ||
3 | +namespace app\admin\model\user; | ||
4 | + | ||
5 | +use think\Model; | ||
6 | + | ||
7 | + | ||
8 | +class UserWithdraw extends Model | ||
9 | +{ | ||
10 | + | ||
11 | + | ||
12 | + | ||
13 | + | ||
14 | + | ||
15 | + // 表名 | ||
16 | + protected $name = 'user_withdraw'; | ||
17 | + | ||
18 | + // 自动写入时间戳字段 | ||
19 | + protected $autoWriteTimestamp = 'int'; | ||
20 | + | ||
21 | + // 定义时间戳字段名 | ||
22 | + protected $createTime = 'createtime'; | ||
23 | + protected $updateTime = 'updatetime'; | ||
24 | + protected $deleteTime = false; | ||
25 | + | ||
26 | + // 追加属性 | ||
27 | + protected $append = [ | ||
28 | + 'status_text', | ||
29 | + 'success_time_text' | ||
30 | + ]; | ||
31 | + | ||
32 | + | ||
33 | + | ||
34 | + public function getStatusList() | ||
35 | + { | ||
36 | + return ['0' => __('Status 0'), '1' => __('Status 1'), '2' => __('Status 2'), '3' => __('Status 3')]; | ||
37 | + } | ||
38 | + | ||
39 | + | ||
40 | + public function getStatusTextAttr($value, $data) | ||
41 | + { | ||
42 | + $value = $value ? $value : (isset($data['status']) ? $data['status'] : ''); | ||
43 | + $list = $this->getStatusList(); | ||
44 | + return isset($list[$value]) ? $list[$value] : ''; | ||
45 | + } | ||
46 | + | ||
47 | + | ||
48 | + public function getSuccessTimeTextAttr($value, $data) | ||
49 | + { | ||
50 | + $value = $value ? $value : (isset($data['success_time']) ? $data['success_time'] : ''); | ||
51 | + return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value; | ||
52 | + } | ||
53 | + | ||
54 | + protected function setSuccessTimeAttr($value) | ||
55 | + { | ||
56 | + return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value); | ||
57 | + } | ||
58 | + | ||
59 | + | ||
60 | + public function user() | ||
61 | + { | ||
62 | + return $this->belongsTo('app\admin\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0); | ||
63 | + } | ||
64 | +} |
1 | +<?php | ||
2 | + | ||
3 | +namespace app\admin\validate\user; | ||
4 | + | ||
5 | +use think\Validate; | ||
6 | + | ||
7 | +class UserWithdraw extends Validate | ||
8 | +{ | ||
9 | + /** | ||
10 | + * 验证规则 | ||
11 | + */ | ||
12 | + protected $rule = [ | ||
13 | + ]; | ||
14 | + /** | ||
15 | + * 提示消息 | ||
16 | + */ | ||
17 | + protected $message = [ | ||
18 | + ]; | ||
19 | + /** | ||
20 | + * 验证场景 | ||
21 | + */ | ||
22 | + protected $scene = [ | ||
23 | + 'add' => [], | ||
24 | + 'edit' => [], | ||
25 | + ]; | ||
26 | + | ||
27 | +} |
1 | +<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action=""> | ||
2 | + | ||
3 | + <div class="form-group"> | ||
4 | + <label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label> | ||
5 | + <div class="col-xs-12 col-sm-8"> | ||
6 | + <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=""> | ||
7 | + </div> | ||
8 | + </div> | ||
9 | + <div class="form-group"> | ||
10 | + <label class="control-label col-xs-12 col-sm-2">{:__('Before_money')}:</label> | ||
11 | + <div class="col-xs-12 col-sm-8"> | ||
12 | + <input id="c-before_money" data-rule="required" class="form-control" step="0.01" name="row[before_money]" type="number" value="0.00"> | ||
13 | + </div> | ||
14 | + </div> | ||
15 | + <div class="form-group"> | ||
16 | + <label class="control-label col-xs-12 col-sm-2">{:__('After_money')}:</label> | ||
17 | + <div class="col-xs-12 col-sm-8"> | ||
18 | + <input id="c-after_money" data-rule="required" class="form-control" step="0.01" name="row[after_money]" type="number" value="0.00"> | ||
19 | + </div> | ||
20 | + </div> | ||
21 | + <div class="form-group"> | ||
22 | + <label class="control-label col-xs-12 col-sm-2">{:__('Order_sn')}:</label> | ||
23 | + <div class="col-xs-12 col-sm-8"> | ||
24 | + <input id="c-order_sn" data-rule="required" class="form-control" name="row[order_sn]" type="text" value="''"> | ||
25 | + </div> | ||
26 | + </div> | ||
27 | + <div class="form-group"> | ||
28 | + <label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label> | ||
29 | + <div class="col-xs-12 col-sm-8"> | ||
30 | + | ||
31 | + <div class="radio"> | ||
32 | + {foreach name="statusList" item="vo"} | ||
33 | + <label for="row[status]-{$key}"><input id="row[status]-{$key}" name="row[status]" type="radio" value="{$key}" {in name="key" value="0"}checked{/in} /> {$vo}</label> | ||
34 | + {/foreach} | ||
35 | + </div> | ||
36 | + | ||
37 | + </div> | ||
38 | + </div> | ||
39 | + <div class="form-group"> | ||
40 | + <label class="control-label col-xs-12 col-sm-2">{:__('Pay_type')}:</label> | ||
41 | + <div class="col-xs-12 col-sm-8"> | ||
42 | + <input id="c-pay_type" data-rule="required" class="form-control" name="row[pay_type]" type="number" value="1"> | ||
43 | + </div> | ||
44 | + </div> | ||
45 | + <div class="form-group"> | ||
46 | + <label class="control-label col-xs-12 col-sm-2">{:__('Money')}:</label> | ||
47 | + <div class="col-xs-12 col-sm-8"> | ||
48 | + <input id="c-money" data-rule="required" class="form-control" step="0.01" name="row[money]" type="number" value="0.00"> | ||
49 | + </div> | ||
50 | + </div> | ||
51 | + <div class="form-group"> | ||
52 | + <label class="control-label col-xs-12 col-sm-2">{:__('Success_time')}:</label> | ||
53 | + <div class="col-xs-12 col-sm-8"> | ||
54 | + <input id="c-success_time" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[success_time]" type="text" value="{:date('Y-m-d H:i:s')}"> | ||
55 | + </div> | ||
56 | + </div> | ||
57 | + <div class="form-group"> | ||
58 | + <label class="control-label col-xs-12 col-sm-2">{:__('Transaction_id')}:</label> | ||
59 | + <div class="col-xs-12 col-sm-8"> | ||
60 | + <input id="c-transaction_id" data-rule="required" data-source="transaction/index" class="form-control selectpage" name="row[transaction_id]" type="text" value=""> | ||
61 | + </div> | ||
62 | + </div> | ||
63 | + <div class="form-group"> | ||
64 | + <label class="control-label col-xs-12 col-sm-2">{:__('More')}:</label> | ||
65 | + <div class="col-xs-12 col-sm-8"> | ||
66 | + <textarea id="c-more" class="form-control " rows="5" name="row[more]" cols="50">NULL</textarea> | ||
67 | + </div> | ||
68 | + </div> | ||
69 | + <div class="form-group"> | ||
70 | + <label class="control-label col-xs-12 col-sm-2">{:__('Percent')}:</label> | ||
71 | + <div class="col-xs-12 col-sm-8"> | ||
72 | + <input id="c-percent" class="form-control" step="0.1" name="row[percent]" type="number" value="0.0"> | ||
73 | + </div> | ||
74 | + </div> | ||
75 | + <div class="form-group layer-footer"> | ||
76 | + <label class="control-label col-xs-12 col-sm-2"></label> | ||
77 | + <div class="col-xs-12 col-sm-8"> | ||
78 | + <button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button> | ||
79 | + <button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button> | ||
80 | + </div> | ||
81 | + </div> | ||
82 | +</form> |
1 | +<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action=""> | ||
2 | + | ||
3 | + <div class="form-group"> | ||
4 | + <label class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label> | ||
5 | + <div class="col-xs-12 col-sm-8"> | ||
6 | + <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}"> | ||
7 | + </div> | ||
8 | + </div> | ||
9 | + <div class="form-group"> | ||
10 | + <label class="control-label col-xs-12 col-sm-2">{:__('Before_money')}:</label> | ||
11 | + <div class="col-xs-12 col-sm-8"> | ||
12 | + <input id="c-before_money" data-rule="required" class="form-control" step="0.01" name="row[before_money]" type="number" value="{$row.before_money|htmlentities}"> | ||
13 | + </div> | ||
14 | + </div> | ||
15 | + <div class="form-group"> | ||
16 | + <label class="control-label col-xs-12 col-sm-2">{:__('After_money')}:</label> | ||
17 | + <div class="col-xs-12 col-sm-8"> | ||
18 | + <input id="c-after_money" data-rule="required" class="form-control" step="0.01" name="row[after_money]" type="number" value="{$row.after_money|htmlentities}"> | ||
19 | + </div> | ||
20 | + </div> | ||
21 | + <div class="form-group"> | ||
22 | + <label class="control-label col-xs-12 col-sm-2">{:__('Order_sn')}:</label> | ||
23 | + <div class="col-xs-12 col-sm-8"> | ||
24 | + <input id="c-order_sn" data-rule="required" class="form-control" name="row[order_sn]" type="text" value="{$row.order_sn|htmlentities}"> | ||
25 | + </div> | ||
26 | + </div> | ||
27 | + <div class="form-group"> | ||
28 | + <label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label> | ||
29 | + <div class="col-xs-12 col-sm-8"> | ||
30 | + | ||
31 | + <div class="radio"> | ||
32 | + {foreach name="statusList" item="vo"} | ||
33 | + <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> | ||
34 | + {/foreach} | ||
35 | + </div> | ||
36 | + | ||
37 | + </div> | ||
38 | + </div> | ||
39 | + <div class="form-group"> | ||
40 | + <label class="control-label col-xs-12 col-sm-2">{:__('Pay_type')}:</label> | ||
41 | + <div class="col-xs-12 col-sm-8"> | ||
42 | + <input id="c-pay_type" data-rule="required" class="form-control" name="row[pay_type]" type="number" value="{$row.pay_type|htmlentities}"> | ||
43 | + </div> | ||
44 | + </div> | ||
45 | + <div class="form-group"> | ||
46 | + <label class="control-label col-xs-12 col-sm-2">{:__('Money')}:</label> | ||
47 | + <div class="col-xs-12 col-sm-8"> | ||
48 | + <input id="c-money" data-rule="required" class="form-control" step="0.01" name="row[money]" type="number" value="{$row.money|htmlentities}"> | ||
49 | + </div> | ||
50 | + </div> | ||
51 | + <div class="form-group"> | ||
52 | + <label class="control-label col-xs-12 col-sm-2">{:__('Success_time')}:</label> | ||
53 | + <div class="col-xs-12 col-sm-8"> | ||
54 | + <input id="c-success_time" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[success_time]" type="text" value="{:$row.success_time?datetime($row.success_time):''}"> | ||
55 | + </div> | ||
56 | + </div> | ||
57 | + <div class="form-group"> | ||
58 | + <label class="control-label col-xs-12 col-sm-2">{:__('Transaction_id')}:</label> | ||
59 | + <div class="col-xs-12 col-sm-8"> | ||
60 | + <input id="c-transaction_id" data-rule="required" data-source="transaction/index" class="form-control selectpage" name="row[transaction_id]" type="text" value="{$row.transaction_id|htmlentities}"> | ||
61 | + </div> | ||
62 | + </div> | ||
63 | + <div class="form-group"> | ||
64 | + <label class="control-label col-xs-12 col-sm-2">{:__('More')}:</label> | ||
65 | + <div class="col-xs-12 col-sm-8"> | ||
66 | + <textarea id="c-more" class="form-control " rows="5" name="row[more]" cols="50">{$row.more|htmlentities}</textarea> | ||
67 | + </div> | ||
68 | + </div> | ||
69 | + <div class="form-group"> | ||
70 | + <label class="control-label col-xs-12 col-sm-2">{:__('Percent')}:</label> | ||
71 | + <div class="col-xs-12 col-sm-8"> | ||
72 | + <input id="c-percent" class="form-control" step="0.1" name="row[percent]" type="number" value="{$row.percent|htmlentities}"> | ||
73 | + </div> | ||
74 | + </div> | ||
75 | + <div class="form-group layer-footer"> | ||
76 | + <label class="control-label col-xs-12 col-sm-2"></label> | ||
77 | + <div class="col-xs-12 col-sm-8"> | ||
78 | + <button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button> | ||
79 | + <button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button> | ||
80 | + </div> | ||
81 | + </div> | ||
82 | +</form> |
1 | +<div class="panel panel-default panel-intro"> | ||
2 | + | ||
3 | + <div class="panel-heading"> | ||
4 | + {:build_heading(null,FALSE)} | ||
5 | + <ul class="nav nav-tabs" data-field="status"> | ||
6 | + <li class="active"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li> | ||
7 | + {foreach name="statusList" item="vo"} | ||
8 | + <li><a href="#t-{$key}" data-value="{$key}" data-toggle="tab">{$vo}</a></li> | ||
9 | + {/foreach} | ||
10 | + </ul> | ||
11 | + </div> | ||
12 | + | ||
13 | + | ||
14 | + <div class="panel-body"> | ||
15 | + <div id="myTabContent" class="tab-content"> | ||
16 | + <div class="tab-pane fade active in" id="one"> | ||
17 | + <div class="widget-body no-padding"> | ||
18 | + <div id="toolbar" class="toolbar"> | ||
19 | + <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a> | ||
20 | + <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('user/user_withdraw/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a> | ||
21 | + <a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('user/user_withdraw/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a> | ||
22 | + <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('user/user_withdraw/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a> | ||
23 | + <a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('user/user_withdraw/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a> | ||
24 | + | ||
25 | + <div class="dropdown btn-group {:$auth->check('user/user_withdraw/multi')?'':'hide'}"> | ||
26 | + <a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a> | ||
27 | + <ul class="dropdown-menu text-left" role="menu"> | ||
28 | + <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=normal"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li> | ||
29 | + <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li> | ||
30 | + </ul> | ||
31 | + </div> | ||
32 | + | ||
33 | + | ||
34 | + </div> | ||
35 | + <table id="table" class="table table-striped table-bordered table-hover table-nowrap" | ||
36 | + data-operate-edit="{:$auth->check('user/user_withdraw/edit')}" | ||
37 | + data-operate-del="{:$auth->check('user/user_withdraw/del')}" | ||
38 | + width="100%"> | ||
39 | + </table> | ||
40 | + </div> | ||
41 | + </div> | ||
42 | + | ||
43 | + </div> | ||
44 | + </div> | ||
45 | +</div> |
@@ -142,7 +142,7 @@ class Goods extends Api | @@ -142,7 +142,7 @@ class Goods extends Api | ||
142 | $basic_where['goods_name'] = ['like','%'.$param['keyword'].'%']; | 142 | $basic_where['goods_name'] = ['like','%'.$param['keyword'].'%']; |
143 | } | 143 | } |
144 | $where = [ | 144 | $where = [ |
145 | - 'where' => $basic_where | 145 | + 'where' => $basic_where, |
146 | ]; | 146 | ]; |
147 | $goods = $this->goods_model->pageSelect($page,$where,$field,$order,config('option.num')); | 147 | $goods = $this->goods_model->pageSelect($page,$where,$field,$order,config('option.num')); |
148 | $list = $goods->items(); | 148 | $list = $goods->items(); |
@@ -293,6 +293,23 @@ class Goods extends Api | @@ -293,6 +293,23 @@ class Goods extends Api | ||
293 | "stock_num": 剩余库存, | 293 | "stock_num": 剩余库存, |
294 | "goods_price": "销售价", | 294 | "goods_price": "销售价", |
295 | "line_price": "划线价", | 295 | "line_price": "划线价", |
296 | + "store": { | ||
297 | + "id": 1, | ||
298 | + "order_sn": "20200826142729172194", | ||
299 | + "user_id": 1, | ||
300 | + "store_name": "店铺名称", | ||
301 | + "industry_id": "行业标签", | ||
302 | + "name": "测试11", | ||
303 | + "mobile": "13911111111", | ||
304 | + "store_icon": "http://cloud.caiyunpan.brotop.cn/assets/img/qrcode.png", | ||
305 | + "province": "地址省", | ||
306 | + "city": "地址市", | ||
307 | + "region": "地址区", | ||
308 | + "image_arr": [ | ||
309 | + "http://cloud.caiyunpan.brotop.cn/assets/img/qrcode.png", | ||
310 | + "http://cloud.caiyunpan.brotop.cn/assets/img/qrcode.png" | ||
311 | + ] | ||
312 | + }, | ||
296 | "image": "https://her-family.oss-cn-qingdao.aliyuncs.com/addons_store_uploads/20181105/ffc4440df18661948b9c2d4dd4ae419b.jpg" | 313 | "image": "https://her-family.oss-cn-qingdao.aliyuncs.com/addons_store_uploads/20181105/ffc4440df18661948b9c2d4dd4ae419b.jpg" |
297 | }, | 314 | }, |
298 | } | 315 | } |
@@ -323,6 +340,7 @@ class Goods extends Api | @@ -323,6 +340,7 @@ class Goods extends Api | ||
323 | $specData['spec_list'][$index]["form"]['imgshow'] = $specData['spec_list'][$index]["form"]['spec_image']==='' ? null:cdnurl($specData['spec_list'][$index]["form"]['spec_image'], true); | 340 | $specData['spec_list'][$index]["form"]['imgshow'] = $specData['spec_list'][$index]["form"]['spec_image']==='' ? null:cdnurl($specData['spec_list'][$index]["form"]['spec_image'], true); |
324 | } | 341 | } |
325 | } | 342 | } |
343 | + $detail['store'] = \app\api\model\Store::get($detail['store_id']); | ||
326 | // $basic_where = [ | 344 | // $basic_where = [ |
327 | // 'goods_id' => $param['goods_id'], | 345 | // 'goods_id' => $param['goods_id'], |
328 | // 'goods_status' => '10', | 346 | // 'goods_status' => '10', |
@@ -62,13 +62,37 @@ class Hot extends Api | @@ -62,13 +62,37 @@ class Hot extends Api | ||
62 | 'code':'1', | 62 | 'code':'1', |
63 | 'msg':'返回成功', | 63 | 'msg':'返回成功', |
64 | "data": { | 64 | "data": { |
65 | - "list": [ | ||
66 | - { | ||
67 | - "id": 1, | ||
68 | - "name": "行业名称", | ||
69 | - "weigh": 0, | ||
70 | - } | ||
71 | - ] | 65 | + "list": [ |
66 | + { | ||
67 | + "id": 5, | ||
68 | + "user_id": 1, | ||
69 | + "store_id": 0, | ||
70 | + "content": "内容", | ||
71 | + "images": "http://cloud.caiyunpan.brotop.cn/assets/img/qrcode.png", | ||
72 | + "house_ids": ",1,", | ||
73 | + "type": 类型1=红包2=一般信息, | ||
74 | + "score": "5800", | ||
75 | + "red_package": "5000", | ||
76 | + "number": 红包数量, | ||
77 | + "single": "单人领取金额", | ||
78 | + "get": 已领数量, | ||
79 | + "surplus": 剩余数量, | ||
80 | + "views": 浏览量, | ||
81 | + "good_count": 点赞总数, | ||
82 | + "is_good": 是否点赞0=否1=是 | ||
83 | + "image_arr"图片: [ | ||
84 | + "http://cloud.caiyunpan.brotop.cn/assets/img/qrcode.png" | ||
85 | + ], | ||
86 | + "store": { | ||
87 | + "id": 1, | ||
88 | + "store_name": "店铺名称", | ||
89 | + "store_icon": "图标", | ||
90 | + "industry_id": "行业标签", | ||
91 | + }, | ||
92 | + }, | ||
93 | + ], | ||
94 | + "this_page": 当前页数, | ||
95 | + "total_page": 总页数 | ||
72 | } | 96 | } |
73 | }) | 97 | }) |
74 | */ | 98 | */ |
@@ -88,7 +112,8 @@ class Hot extends Api | @@ -88,7 +112,8 @@ class Hot extends Api | ||
88 | } | 112 | } |
89 | }; | 113 | }; |
90 | $where = [ | 114 | $where = [ |
91 | - 'where' => $query | 115 | + 'where' => $query, |
116 | + 'with' => ['store'] | ||
92 | ]; | 117 | ]; |
93 | $order = ['number'=>'DESC','createtime'=>'DESC']; | 118 | $order = ['number'=>'DESC','createtime'=>'DESC']; |
94 | $inform = $this->store_inform_model->pageSelect($page,$where,'*',$order,config('option.num')); | 119 | $inform = $this->store_inform_model->pageSelect($page,$where,'*',$order,config('option.num')); |
@@ -787,13 +787,13 @@ class Store extends Api | @@ -787,13 +787,13 @@ class Store extends Api | ||
787 | 'code':'1', | 787 | 'code':'1', |
788 | 'msg':'返回成功', | 788 | 'msg':'返回成功', |
789 | "data": { | 789 | "data": { |
790 | - "list": [ | ||
791 | - { | ||
792 | - "id": 1, | ||
793 | - "name": "行业名称", | ||
794 | - "weigh": 0, | ||
795 | - } | ||
796 | - ] | 790 | + "list": [ |
791 | + { | ||
792 | + "id": 1, | ||
793 | + "name": "行业名称", | ||
794 | + "weigh": 0, | ||
795 | + } | ||
796 | + ] | ||
797 | } | 797 | } |
798 | }) | 798 | }) |
799 | */ | 799 | */ |
@@ -852,23 +852,16 @@ class Store extends Api | @@ -852,23 +852,16 @@ class Store extends Api | ||
852 | if (!$validate->check($param)) { | 852 | if (!$validate->check($param)) { |
853 | $this->error($validate->getError()); | 853 | $this->error($validate->getError()); |
854 | } | 854 | } |
855 | - $withdraw_percent = config('site.withdraw_percent'); | ||
856 | - $withdraw_percent = $withdraw_percent > 0 ? ($withdraw_percent / 100) : 1; | ||
857 | if ($param['money'] < 1) { | 855 | if ($param['money'] < 1) { |
858 | $this->error('提现金额不可小于1元'); | 856 | $this->error('提现金额不可小于1元'); |
859 | } | 857 | } |
860 | - if ($param['money'] > 5000) { | ||
861 | - $this->error('提现金额不可大于5000元'); | 858 | + if ($param['money'] > 1000) { |
859 | + $this->error('提现金额不可大于1000元'); | ||
862 | } | 860 | } |
863 | // 判断余额是否充足 | 861 | // 判断余额是否充足 |
864 | - if ($param['money'] / $withdraw_percent * 10 > $this->auth->money) { | 862 | + if ($param['money'] > $this->auth->money) { |
865 | $this->error('桃币余额不足,无法提现'); | 863 | $this->error('桃币余额不足,无法提现'); |
866 | } | 864 | } |
867 | - // 判断用户是否绑定微信 | ||
868 | - $user_openid = Db::name('third')->where(['user_id'=>$this->auth->id,'third_party'=>'wechat'])->value('openid'); | ||
869 | - if(!$user_openid) { | ||
870 | - $this->error('请先绑定微信之后进行提现',40004); | ||
871 | - } | ||
872 | // 提现记录 | 865 | // 提现记录 |
873 | Db::startTrans(); | 866 | Db::startTrans(); |
874 | $user_model = $this->auth->getUser(); | 867 | $user_model = $this->auth->getUser(); |
@@ -878,15 +871,24 @@ class Store extends Api | @@ -878,15 +871,24 @@ class Store extends Api | ||
878 | $withdraw = [ | 871 | $withdraw = [ |
879 | 'user_id' => $this->auth->id, | 872 | 'user_id' => $this->auth->id, |
880 | 'before_money' => $this->auth->money, | 873 | 'before_money' => $this->auth->money, |
881 | - 'after_money' => $this->auth->money - $param['money'] / $withdraw_percent * 10, | 874 | + 'after_money' => $this->auth->money - $param['money'], |
882 | 'order_sn' => $order_sn, | 875 | 'order_sn' => $order_sn, |
883 | 'money' => $param['money'], | 876 | 'money' => $param['money'], |
884 | - 'percent' => $withdraw_percent | ||
885 | ]; | 877 | ]; |
886 | $result = $withdraw_model->isUpdate(false)->save($withdraw); | 878 | $result = $withdraw_model->isUpdate(false)->save($withdraw); |
887 | // 记录用户余额 | 879 | // 记录用户余额 |
888 | - $result_user = $user_model->isUpdate(true)->save(['money' => $user['money'] - $param['money'] / $withdraw_percent * 10], ['id' => $this->auth->id]); | ||
889 | - if (!$result || !$result_user) { | 880 | + $result_user = $user_model->isUpdate(true)->save(['money' => $user['money'] - $param['money']]); |
881 | + // 记录余额变更 | ||
882 | + $insert_data = array( | ||
883 | + 'user_id' => $this->auth->id, | ||
884 | + 'money' => $param['money'], | ||
885 | + 'before' => $this->auth->money, | ||
886 | + 'after' => $this->auth->money - $param['money'], | ||
887 | + 'createtime' => time(), | ||
888 | + 'memo' => '提现', | ||
889 | + ); | ||
890 | + $res_log = Db::name('user_money_log')->insert($insert_data); | ||
891 | + if (!$result || !$result_user || !$res_log) { | ||
890 | Db::rollback(); | 892 | Db::rollback(); |
891 | $this->error('提现申请失败', [$result, $result_user]); | 893 | $this->error('提现申请失败', [$result, $result_user]); |
892 | } | 894 | } |
@@ -47,7 +47,7 @@ class Base extends Model { | @@ -47,7 +47,7 @@ class Base extends Model { | ||
47 | * 构造关联社区文章查询 | 47 | * 构造关联社区文章查询 |
48 | */ | 48 | */ |
49 | public function store(){ | 49 | public function store(){ |
50 | - return $this->hasOne("Store","sort_id","id")->field("id,store_name,store_icon,industry_id"); | 50 | + return $this->hasOne("Store","id","store_id")->field("id,store_name,store_icon,industry_id,images"); |
51 | } | 51 | } |
52 | 52 | ||
53 | /** | 53 | /** |
@@ -11,6 +11,11 @@ class Store extends Base | @@ -11,6 +11,11 @@ class Store extends Base | ||
11 | 'image_arr' | 11 | 'image_arr' |
12 | ]; | 12 | ]; |
13 | 13 | ||
14 | + public function getStoreIconAttr($value) | ||
15 | + { | ||
16 | + return cdnurl($value); | ||
17 | + } | ||
18 | + | ||
14 | public function getImageArrAttr($value,$data) | 19 | public function getImageArrAttr($value,$data) |
15 | { | 20 | { |
16 | $arr = []; | 21 | $arr = []; |
@@ -7,4 +7,18 @@ namespace app\api\model; | @@ -7,4 +7,18 @@ namespace app\api\model; | ||
7 | class StoreInform extends Base | 7 | class StoreInform extends Base |
8 | { | 8 | { |
9 | 9 | ||
10 | + protected $append = [ | ||
11 | + 'image_arr' | ||
12 | + ]; | ||
13 | + public function getImageArrAttr($value,$data) | ||
14 | + { | ||
15 | + $image_arr = []; | ||
16 | + if($data['images']) { | ||
17 | + $image_arr = explode(',',$data['images']); | ||
18 | + foreach ($image_arr as &$v) { | ||
19 | + $v = cdnurl($v); | ||
20 | + } | ||
21 | + } | ||
22 | + return $image_arr; | ||
23 | + } | ||
10 | } | 24 | } |
1 | +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { | ||
2 | + | ||
3 | + var Controller = { | ||
4 | + index: function () { | ||
5 | + // 初始化表格参数配置 | ||
6 | + Table.api.init({ | ||
7 | + extend: { | ||
8 | + index_url: 'user/user_withdraw/index' + location.search, | ||
9 | + add_url: 'user/user_withdraw/add', | ||
10 | + edit_url: 'user/user_withdraw/edit', | ||
11 | + del_url: 'user/user_withdraw/del', | ||
12 | + multi_url: 'user/user_withdraw/multi', | ||
13 | + table: 'user_withdraw', | ||
14 | + } | ||
15 | + }); | ||
16 | + | ||
17 | + var table = $("#table"); | ||
18 | + | ||
19 | + // 初始化表格 | ||
20 | + table.bootstrapTable({ | ||
21 | + url: $.fn.bootstrapTable.defaults.extend.index_url, | ||
22 | + pk: 'id', | ||
23 | + sortName: 'id', | ||
24 | + columns: [ | ||
25 | + [ | ||
26 | + {checkbox: true}, | ||
27 | + {field: 'id', title: __('Id')}, | ||
28 | + {field: 'user_id', title: __('User_id')}, | ||
29 | + {field: 'before_money', title: __('Before_money'), operate:'BETWEEN'}, | ||
30 | + {field: 'after_money', title: __('After_money'), operate:'BETWEEN'}, | ||
31 | + {field: 'order_sn', title: __('Order_sn')}, | ||
32 | + {field: 'status', title: __('Status'), searchList: {"0":__('Status 0'),"1":__('Status 1'),"2":__('Status 2'),"3":__('Status 3')}, formatter: Table.api.formatter.status}, | ||
33 | + {field: 'pay_type', title: __('Pay_type')}, | ||
34 | + {field: 'money', title: __('Money'), operate:'BETWEEN'}, | ||
35 | + {field: 'success_time', title: __('Success_time'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime}, | ||
36 | + {field: 'transaction_id', title: __('Transaction_id')}, | ||
37 | + {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime}, | ||
38 | + {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime}, | ||
39 | + {field: 'percent', title: __('Percent'), operate:'BETWEEN'}, | ||
40 | + {field: 'user.nickname', title: __('User.nickname')}, | ||
41 | + {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} | ||
42 | + ] | ||
43 | + ] | ||
44 | + }); | ||
45 | + | ||
46 | + // 为表格绑定事件 | ||
47 | + Table.api.bindevent(table); | ||
48 | + }, | ||
49 | + add: function () { | ||
50 | + Controller.api.bindevent(); | ||
51 | + }, | ||
52 | + edit: function () { | ||
53 | + Controller.api.bindevent(); | ||
54 | + }, | ||
55 | + api: { | ||
56 | + bindevent: function () { | ||
57 | + Form.api.bindevent($("form[role=form]")); | ||
58 | + } | ||
59 | + } | ||
60 | + }; | ||
61 | + return Controller; | ||
62 | +}); |
-
请 注册 或 登录 后发表评论