Produceorder.php 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. <?php
  2. namespace app\admin\controller;
  3. use app\admin\library\Auth;
  4. use app\admin\model\Admin;
  5. use app\admin\model\MobileOrderAdmin;
  6. use app\admin\model\MobileOrderRefundLog;
  7. use app\admin\model\MobileOrderSubAnchor;
  8. use app\admin\model\ShortcutContent;
  9. use app\common\controller\Backend;
  10. use app\common\model\Area;
  11. use app\common\model\LogisticsCompany;
  12. use app\common\model\MobileOrder;
  13. use app\common\model\MobileOrderOperation;
  14. use app\common\model\Produce;
  15. use app\common\service\MobileOrderExport;
  16. use app\common\service\TransferCheck;
  17. use app\common\service\ZopOrderService;
  18. use app\common\validate\RefundValidate;
  19. use app\service\byte_dance\ByteDanceSettle;
  20. use Exception;
  21. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  22. use PhpOffice\PhpSpreadsheet\Reader\Csv;
  23. use PhpOffice\PhpSpreadsheet\Reader\Xls;
  24. use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
  25. use think\Db;
  26. use think\db\Query;
  27. use think\exception\PDOException;
  28. use think\exception\ValidateException;
  29. use think\Loader;
  30. /**
  31. *
  32. *
  33. * @icon fa fa-circle-o
  34. */
  35. class Produceorder extends Backend
  36. {
  37. protected $noNeedRight=['status','pay_type'];
  38. /**
  39. * MobileOrder模型对象
  40. * @var \app\admin\model\MobileOrder
  41. */
  42. protected $model = null;
  43. protected $proxy = 0;
  44. public function _initialize()
  45. {
  46. parent::_initialize();
  47. $this->model = new \app\admin\model\MobileOrder;
  48. $this->assign('status',\app\common\model\MobileOrder::$status);
  49. $this->assign('logistics_list',json_encode(LogisticsCompany::all()));
  50. if(in_array(2, $this->auth->getGroupIds())){
  51. $this->proxy = 1;
  52. $this->assign('status',\app\common\model\MobileOrder::$GongYSStatus);
  53. }
  54. $platformSourceList = [
  55. '1' => '自动生产',
  56. '0' => '手动生产',
  57. ];
  58. $this->assign('platformSourceList', $platformSourceList);
  59. }
  60. public function import()
  61. {
  62. $file = $this->request->request('file');
  63. if (!$file) {
  64. $this->error(__('Parameter %s can not be empty', 'file'));
  65. }
  66. $file=parse_url($file,PHP_URL_PATH);
  67. $filePath = ROOT_PATH . DS . 'public' . DS . $file;
  68. if (!is_file($filePath)) {
  69. $this->error(__('No results were found'));
  70. }
  71. //实例化reader
  72. $ext = pathinfo($filePath, PATHINFO_EXTENSION);
  73. if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
  74. $this->error(__('Unknown data format'));
  75. }
  76. if ($ext === 'csv') {
  77. $file = fopen($filePath, 'r');
  78. $filePath = tempnam(sys_get_temp_dir(), 'import_csv');
  79. $fp = fopen($filePath, "w");
  80. $n = 0;
  81. while ($line = fgets($file)) {
  82. $line = rtrim($line, "\n\r\0");
  83. $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
  84. if ($encoding != 'utf-8') {
  85. $line = mb_convert_encoding($line, 'utf-8', $encoding);
  86. }
  87. if ($n == 0 || preg_match('/^".*"$/', $line)) {
  88. fwrite($fp, $line . "\n");
  89. } else {
  90. fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
  91. }
  92. $n++;
  93. }
  94. fclose($file) || fclose($fp);
  95. $reader = new Csv();
  96. } elseif ($ext === 'xls') {
  97. $reader = new Xls();
  98. } else {
  99. $reader = new Xlsx();
  100. }
  101. //导入文件首行类型,默认是注释,如果需要使用字段名称请使用name
  102. $importHeadType = isset($this->importHeadType) ? $this->importHeadType : 'comment';
  103. $table = $this->model->getQuery()->getTable();
  104. $database = \think\Config::get('database.database');
  105. $fieldArr = [];
  106. $list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);
  107. foreach ($list as $k => $v) {
  108. if ($importHeadType == 'comment') {
  109. $fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME'];
  110. } else {
  111. $fieldArr[$v['COLUMN_NAME']] = $v['COLUMN_NAME'];
  112. }
  113. }
  114. //加载文件
  115. $insert = [];
  116. try {
  117. if (!$PHPExcel = $reader->load($filePath)) {
  118. $this->error(__('Unknown data format'));
  119. }
  120. $currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
  121. $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
  122. $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
  123. $maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
  124. $fields = [];
  125. for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
  126. for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
  127. $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
  128. $fields[] = $val;
  129. }
  130. }
  131. for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
  132. $values = [];
  133. for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
  134. $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
  135. $values[] = is_null($val) ? '' : $val;
  136. }
  137. $row = [];
  138. $temp = array_combine($fields, $values);
  139. foreach ($temp as $k => $v) {
  140. if (isset($fieldArr[$k]) && $k !== '') {
  141. $row[$fieldArr[$k]] = $v;
  142. }
  143. }
  144. if ($row) {
  145. $insert[] = $row;
  146. }
  147. }
  148. } catch (Exception $exception) {
  149. $this->error($exception->getMessage());
  150. }
  151. if (!$insert) {
  152. $this->error(__('No rows were updated'));
  153. }
  154. try {
  155. //是否包含admin_id字段
  156. $has_admin_id = false;
  157. foreach ($fieldArr as $name => $key) {
  158. if ($key == 'admin_id') {
  159. $has_admin_id = true;
  160. break;
  161. }
  162. }
  163. if ($has_admin_id) {
  164. $auth = Auth::instance();
  165. foreach ($insert as &$val) {
  166. if (!isset($val['admin_id']) || empty($val['admin_id'])) {
  167. $val['admin_id'] = $auth->isLogin() ? $auth->id : 0;
  168. }
  169. $val['is_auto'] = 0;
  170. }
  171. }
  172. (new MobileOrder)->insertAll($insert);
  173. } catch (PDOException $exception) {
  174. $msg = $exception->getMessage();
  175. if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {
  176. $msg = "导入失败,包含【{$matches[1]}】的记录已存在";
  177. };
  178. $this->error($msg);
  179. } catch (Exception $e) {
  180. $this->error($e->getMessage());
  181. }
  182. $this->success();
  183. }
  184. /**
  185. * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
  186. * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
  187. * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
  188. */
  189. /**
  190. * 查看
  191. */
  192. public function index()
  193. {
  194. //当前是否为关联查询
  195. $this->relationSearch = true;
  196. //设置过滤方法
  197. $this->request->filter(['strip_tags', 'trim']);
  198. $map=[];
  199. if($this->admin('is_sub')){
  200. $map['s_id']=$this->admin('id');
  201. }
  202. //if(!$this->admin('is_manager')){
  203. // $map['s_id']=$this->admin('id');
  204. //}
  205. $export=input('export');
  206. if($export){
  207. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  208. $list = $this->model
  209. ->where($where)
  210. ->where($map)
  211. ->where('type',1)
  212. // ->where(['platform_source'=>'敢探号','api_goods_id'=>123564678989,'or'])
  213. // ->whereOr('platform_source','敢探号')
  214. // ->whereOr('api_goods_id','123564678989')
  215. ->where('is_need_push', 1)
  216. ->where(function($q) {
  217. //供应商
  218. if($this->proxy){
  219. return $q->where('mobile_order.admin_id', $this->auth->id);
  220. }
  221. })
  222. ->order($sort, $order)
  223. ->paginate($limit);
  224. return MobileOrderExport::export($list,$this->admin());
  225. }
  226. if ($this->request->isAjax()) {
  227. //如果发送的来源是Selectpage,则转发到Selectpage
  228. if ($this->request->request('keyField')) {
  229. return $this->selectpage();
  230. }
  231. // status需要组装的搜索条件
  232. $filter = json_decode($this->request->get('filter'),true);
  233. $op = json_decode($this->request->get('op'),true);
  234. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  235. if($this->admin('is_manager')){
  236. // 注销关联 ,'refund_log.refunduser'
  237. $relation=['operation','operation.admin','admin','admin.admin','refund_log',
  238. 'sub_remark','sub_remark.admin','anchor','sub_anchor','sub_anchor.mobileAnchor','proxy','payment'];
  239. }else{
  240. // 注销关联 ,'refund_log.refunduser'
  241. $relation=['admin','admin.admin','refund_log','sub_remark'=>function(Query $query){
  242. $query->where('sub_admin_id',$this->auth->id);
  243. },'sub_remark.admin','anchor','sub_anchor','sub_anchor.mobileAnchor','proxy','payment'];
  244. }
  245. $list = $this->model
  246. ->where($where)
  247. ->where($map)
  248. ->where('type',1)
  249. // ->where(['platform_source'=>'敢探号','api_goods_id'=>123564678989,'or'])
  250. ->where(function($q) {
  251. //供应商
  252. if($this->proxy){
  253. return $q->where('mobile_order.admin_id', $this->auth->id);
  254. }
  255. })
  256. // ->where(function ($q){
  257. // $q->whereOr('platform_source','敢探号')->whereOr('api_goods_id','123564678989');
  258. // })
  259. ->where('is_need_push', 1)
  260. // ->whereOr('platform_source','敢探号')
  261. ->order($sort, $order)
  262. ->paginate($limit);
  263. // print_r($list->getLastSql());
  264. $upStatus=[];
  265. if($list->items()) {
  266. $upStatus = \app\admin\model\Mobile::whereIn('id', array_column($list->items(), 'mobile_id'))->where('status', '<>',0)->column('id');
  267. }
  268. foreach ($list as $row) {
  269. $row['pay_link']=h5_link("oder-detail/{$row['id']}");
  270. $row->append(['phone_order_count']);
  271. $row['mobile_can_up']=!in_array($row['mobile_id'],$upStatus);
  272. if($row['s_id']) {
  273. $row['s_name'] = Admin::where('id', $row['s_id'])->value('nickname');
  274. }else{
  275. $row['s_name']='';
  276. }
  277. }
  278. $extend=[];
  279. $amountMap=[];
  280. $amountMap['type']=1;
  281. if(!$this->admin('is_manager')){
  282. $amountMap['s_id']=$this->admin('id');
  283. }
  284. /*$amountBase=$this->model->filterSaled()->where($where)->where($amountMap)->sum('amount_base');
  285. $amountDi=$this->model->filterSaled()->where($where)->where($amountMap)->sum('amount_di');
  286. $extend['total']=bcsub($amountBase,$amountDi);*/
  287. $extend['total']=$this->model->filterSaled()->where($where)->where($amountMap)->sum('amount_base');
  288. $extend['alipay']=$this->model->filterSaled()->where($where)->where($amountMap)->where('pay_type',2)->sum('amount');
  289. $extend['wechat']=$this->model->filterSaled()->where($where)->where($amountMap)->where('pay_type',1)->sum('amount');
  290. $extend['jd']=$this->model->filterSaled()->where($where)->where($amountMap)->where('pay_type',3)->sum('amount');
  291. $extend['dy']=$this->model->filterSaled()->where($where)->where($amountMap)->where('pay_type',4)->sum('amount');
  292. $extend['ks']=$this->model->filterSaled()->where($where)->where($amountMap)->where('pay_type',5)->sum('amount');
  293. $extend['di']=$this->model->filterSaled()->where($where)->where($amountMap)->sum('amount_di');
  294. $extend['profit']=$this->model->filterSaled()->where($where)->where($amountMap)->sum('amount_profit');
  295. $extend['refund']=$this->model->where($where)->where($amountMap)->sum('amount_refund');
  296. // select count(id) as total,status from mobile_order where type=1 GROUP BY status; 角标查询
  297. if (isset($filter['status'])){
  298. unset($filter['status']);
  299. unset($op['status']);
  300. }
  301. $this->request->get(['filter'=>json_encode($filter)]);
  302. $this->request->get(['op'=>json_encode($op)]);
  303. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  304. // if($this->admin('is_manager')){
  305. // $relation=['mobile','anchor'];
  306. // }else{
  307. // $relation=['mobile'];
  308. // }
  309. $status_list = $this->model
  310. //->with($relation)
  311. ->field('count(mobile_order.id) as total,mobile_order.status')
  312. ->where($where)
  313. ->where($map)
  314. ->where('mobile_order.type',1)
  315. ->where(function($q) {
  316. //供应商
  317. if($this->proxy){
  318. return $q->where('mobile_order.admin_id', $this->auth->id)->whereIn('status',[15,17,20,25,60]);
  319. }
  320. })
  321. ->group('mobile_order.status')
  322. ->select();
  323. $status_10_count=0;
  324. if (!$this->proxy) {
  325. // 状态10的数据统计
  326. $status_10_count = $this->model
  327. // ->with($relation)
  328. ->where($where)
  329. ->whereNotIn('status', [0, 50, 90])
  330. ->where($map)
  331. ->where('mobile_order.type', 1)
  332. ->where(function ($q) {
  333. //供应商
  334. if ($this->proxy) {
  335. return $q->where('mobile_order.admin_id', $this->auth->id);
  336. }
  337. })->count();
  338. }
  339. $result = array("total" => $list->total(), "rows" => $list->items(),'extend'=>$extend,'status_list'=>$status_list,'status_10_count'=>$status_10_count);
  340. $result['link']=$this->request->url().'&export=1';
  341. return json($result);
  342. }
  343. // print_r(123);
  344. // exit();
  345. $this->assign('admins',Admin::getAdmins());
  346. $this->assign('subs',Admin::getSubs());
  347. $this->assign('is_proxy',$this->proxy);
  348. $this->assignconfig('is_proxy',$this->proxy);
  349. return $this->view->fetch();
  350. }
  351. protected function buildparams($searchfields = null, $relationSearch = null)
  352. {
  353. $searchfields = is_null($searchfields) ? $this->searchFields : $searchfields;
  354. $relationSearch = is_null($relationSearch) ? $this->relationSearch : $relationSearch;
  355. $search = $this->request->get("search", '');
  356. $filter = $this->request->get("filter", '');
  357. $op = $this->request->get("op", '', 'trim');
  358. $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
  359. $order = $this->request->get("order", "DESC");
  360. $offset = $this->request->get("offset/d", 0);
  361. $limit = $this->request->get("limit/d", 999999);
  362. //新增自动计算页码
  363. $page = $limit ? intval($offset / $limit) + 1 : 1;
  364. if ($this->request->has("page")) {
  365. $page = $this->request->get("page/d", 1);
  366. }
  367. $this->request->get([config('paginate.var_page') => $page]);
  368. $filter = (array)json_decode($filter, true);
  369. $op = (array)json_decode($op, true);
  370. $filter = $filter ? $filter : [];
  371. $where = [];
  372. $alias = [];
  373. $bind = [];
  374. $name = '';
  375. $aliasName = '';
  376. if (!empty($this->model) && $this->relationSearch) {
  377. $name = $this->model->getTable();
  378. $alias[$name] = Loader::parseName(basename(str_replace('\\', '/', get_class($this->model))));
  379. $aliasName = $alias[$name] . '.';
  380. }
  381. $sortArr = explode(',', $sort);
  382. foreach ($sortArr as $index => & $item) {
  383. $item = stripos($item, ".") === false ? $aliasName . trim($item) : $item;
  384. }
  385. unset($item);
  386. $sort = implode(',', $sortArr);
  387. $adminIds = $this->getDataLimitAdminIds();
  388. if (is_array($adminIds)) {
  389. $where[] = [$aliasName . $this->dataLimitField, 'in', $adminIds];
  390. }
  391. if ($search) {
  392. $searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields);
  393. foreach ($searcharr as $k => &$v) {
  394. $v = stripos($v, ".") === false ? $aliasName . $v : $v;
  395. }
  396. unset($v);
  397. $where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
  398. }
  399. $index = 0;
  400. foreach ($filter as $k => $v) {
  401. if (!preg_match('/^[a-zA-Z0-9_\-\.]+$/', $k)) {
  402. continue;
  403. }
  404. $sym = isset($op[$k]) ? $op[$k] : '=';
  405. if (stripos($k, ".") === false) {
  406. $k = $aliasName . $k;
  407. }
  408. $v = !is_array($v) ? trim($v) : $v;
  409. $sym = strtoupper(isset($op[$k]) ? $op[$k] : $sym);
  410. //null和空字符串特殊处理
  411. if (!is_array($v)) {
  412. if (in_array(strtoupper($v), ['NULL', 'NOT NULL'])) {
  413. $sym = strtoupper($v);
  414. }
  415. if (in_array($v, ['""', "''"])) {
  416. $v = '';
  417. $sym = '=';
  418. }
  419. }
  420. switch ($sym) {
  421. case '=':
  422. case '<>':
  423. $where[] = [$k, $sym, (string)$v];
  424. break;
  425. case 'LIKE':
  426. case 'NOT LIKE':
  427. case 'LIKE %...%':
  428. case 'NOT LIKE %...%':
  429. $where[] = [$k, trim(str_replace('%...%', '', $sym)), "%{$v}%"];
  430. break;
  431. case '>':
  432. case '>=':
  433. case '<':
  434. case '<=':
  435. $where[] = [$k, $sym, intval($v)];
  436. break;
  437. case 'FINDIN':
  438. case 'FINDINSET':
  439. case 'FIND_IN_SET':
  440. $v = is_array($v) ? $v : explode(',', str_replace(' ', ',', $v));
  441. $findArr = array_values($v);
  442. foreach ($findArr as $idx => $item) {
  443. $bindName = "item_" . $index . "_" . $idx;
  444. $bind[$bindName] = $item;
  445. $where[] = "FIND_IN_SET(:{$bindName}, `" . str_replace('.', '`.`', $k) . "`)";
  446. }
  447. break;
  448. case 'IN':
  449. case 'IN(...)':
  450. case 'NOT IN':
  451. case 'NOT IN(...)':
  452. $where[] = [$k, str_replace('(...)', '', $sym), is_array($v) ? $v : explode(',', $v)];
  453. break;
  454. case 'BETWEEN':
  455. case 'NOT BETWEEN':
  456. $arr = array_slice(explode(',', $v), 0, 2);
  457. if (stripos($v, ',') === false || !array_filter($arr)) {
  458. continue 2;
  459. }
  460. //当出现一边为空时改变操作符
  461. if ($arr[0] === '') {
  462. $sym = $sym == 'BETWEEN' ? '<=' : '>';
  463. $arr = $arr[1];
  464. } elseif ($arr[1] === '') {
  465. $sym = $sym == 'BETWEEN' ? '>=' : '<';
  466. $arr = $arr[0];
  467. }
  468. $where[] = [$k, $sym, $arr];
  469. break;
  470. case 'RANGE':
  471. case 'NOT RANGE':
  472. $v = str_replace(' - ', ',', $v);
  473. $arr = array_slice(explode(',', $v), 0, 2);
  474. if (stripos($v, ',') === false || !array_filter($arr)) {
  475. continue 2;
  476. }
  477. //当出现一边为空时改变操作符
  478. if ($arr[0] === '') {
  479. $sym = $sym == 'RANGE' ? '<=' : '>';
  480. $arr = $arr[1];
  481. } elseif ($arr[1] === '') {
  482. $sym = $sym == 'RANGE' ? '>=' : '<';
  483. $arr = $arr[0];
  484. }
  485. $tableArr = explode('.', $k);
  486. if (count($tableArr) > 1 && $tableArr[0] != $name && !in_array($tableArr[0], $alias) && !empty($this->model)) {
  487. //修复关联模型下时间无法搜索的BUG
  488. $relation = Loader::parseName($tableArr[0], 1, false);
  489. $alias[$this->model->$relation()->getTable()] = $tableArr[0];
  490. }
  491. $where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' TIME', $arr];
  492. break;
  493. case 'NULL':
  494. case 'IS NULL':
  495. case 'NOT NULL':
  496. case 'IS NOT NULL':
  497. $where[] = [$k, strtolower(str_replace('IS ', '', $sym))];
  498. break;
  499. default:
  500. break;
  501. }
  502. $index++;
  503. }
  504. if (!empty($this->model)) {
  505. $this->model->alias($alias);
  506. }
  507. $model = $this->model;
  508. $where = function (Query $query) use ($where, $alias, $bind, &$model) {
  509. if (!empty($model)) {
  510. $model->alias($alias);
  511. $model->bind($bind);
  512. }
  513. foreach ($where as $k => $v) {
  514. if (is_array($v)) {
  515. if($v[0]=='rules.rule'){
  516. $query->whereExists("select * from mobile_order_rules where mobile_order_rules.mobile_order_id=mobile_order.id and rule='{$v[2]}'");
  517. continue;
  518. }elseif ($v[0]=='admin.admin_id'){
  519. $query->whereExists("select * from mobile_order_admin where mobile_order_admin.mobile_order_id=mobile_order.id and admin_id={$v[2]}");
  520. continue;
  521. }elseif ($v[0]=='mobile_order.sub_mobile_anchor_id'){
  522. $query->whereExists("select * from mobile_order_sub_anchor where mobile_order_sub_anchor.mobile_order_id=mobile_order.id and sub_mobile_anchor_id={$v[2]}");
  523. continue;
  524. }elseif ($v[0]=='status'){
  525. $v[0]='mobile_order.status';
  526. }elseif ($v[0]=='create_time'){
  527. $v[0]='mobile_order.create_time';
  528. }elseif ($v[0]=='update_time'){
  529. $v[0]='mobile_order.update_time';
  530. }elseif ($v[0]=='mobile_order.status' && $v[2]==10){
  531. $query->whereNotIn('status',[0,50,90]);
  532. continue;
  533. }
  534. call_user_func_array([$query, 'where'], $v);
  535. } else {
  536. $query->where($v);
  537. }
  538. }
  539. };
  540. return [$where, $sort, $order, $offset, $limit, $page, $alias, $bind];
  541. }
  542. /**
  543. * 添加
  544. */
  545. public function add()
  546. {
  547. if ($this->request->isPost()) {
  548. $params = $this->request->post("row/a");
  549. if ($params) {
  550. $params = $this->preExcludeFields($params);
  551. if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
  552. $params[$this->dataLimitField] = $this->auth->id;
  553. }
  554. $result = false;
  555. Db::startTrans();
  556. try {
  557. //是否采用模型验证
  558. if ($this->modelValidate) {
  559. $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  560. $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
  561. $this->model->validateFailException(true)->validate($validate);
  562. }
  563. // $params['city'] = implode('/', Area::getTreeId($params['city']));
  564. $params['city'] = implode(',',Area::getTreeId(explode('/',$params['city'])[2]));
  565. $params['status'] = 10;
  566. $params['pay_time'] = strtotime($params['pay_time']);
  567. $params['order_no'] = order_no();
  568. $params['is_need_push'] = 1;
  569. $params['is_push_zop'] = 0;
  570. $params['is_auto'] = 0;
  571. $result = MobileOrder::insert($params);
  572. // exit();
  573. // $result = $this->model->allowField(true)->save($params);
  574. Db::commit();
  575. } catch (ValidateException $e) {
  576. Db::rollback();
  577. $this->error($e->getMessage());
  578. } catch (PDOException $e) {
  579. Db::rollback();
  580. $this->error($e->getMessage());
  581. } catch (Exception $e) {
  582. Db::rollback();
  583. throw $e;
  584. //$this->error($e->getMessage());
  585. }
  586. if ($result !== false) {
  587. $this->success();
  588. } else {
  589. $this->error(__('No rows were inserted'));
  590. }
  591. }
  592. $this->error(__('Parameter %s can not be empty', ''));
  593. }
  594. $produces = Produce::all();
  595. $this->assign('produces', $produces);
  596. return $this->view->fetch();
  597. }
  598. /**
  599. * 详情
  600. *
  601. * @param [type] $ids
  602. * @return void
  603. */
  604. public function detail($ids = null)
  605. {
  606. $model = $this->model->with('produce')->where('id', $ids)->find();
  607. $row = $model->toArray();
  608. $row['produce_activation_name'] = $row['produce_activation'] == 1 ? '已激活' : '未激活';
  609. $row['produce_is_recharge_name'] = $row['produce_is_recharge'] == 1 ? '已首充' : '未首充';
  610. $this->assign('row', $row);
  611. $this->assign('produce', $model->produce ?? []);
  612. return $this->view->fetch();
  613. }
  614. public function edit($ids = null)
  615. {
  616. $model=$this->model->find($ids);
  617. $originStatus=$model['status'];
  618. $row=$model->toArray();
  619. if($this->request->isGet()){
  620. $row['address']=$model->originData()['address'];
  621. $row['city']=\app\common\model\Area::getNameString($row['city'],'/');
  622. $this->assign('row',$row);
  623. return view();
  624. }else{
  625. $field=[
  626. 'name',
  627. 'phone',
  628. 'id_no',
  629. 'address',
  630. 'trans_no',
  631. 'trans_id',
  632. 'status',
  633. 'city',
  634. ];
  635. $data=input('row/a');
  636. Db::startTrans();
  637. if(isset($data['city'])){
  638. $data['city']=\app\common\model\Area::whereIn('name|shortname',str_replace('/',',',$data['city']))->column('id');
  639. }
  640. $this->validate($data,[
  641. 'status'=>'in:'.implode(',',array_keys(\app\common\model\MobileOrder::$status))
  642. ]);
  643. foreach ($data as $key=>$value){
  644. if(in_array($key,$field)) {
  645. $model[$key] = $value;
  646. }
  647. }
  648. MobileOrderAdmin::add($model,$originStatus!=$model['status'],$this->auth->id);
  649. $model->save();
  650. // 只有未推送过, 并且产品信息已绑定的订单才推送
  651. if ($model->is_push_zop == 0 && $model->api_goods_id > 0) {
  652. ZopOrderService::push($ids);
  653. }
  654. Db::commit();
  655. $this->success('');
  656. }
  657. }
  658. public function refund($ids){
  659. $model=$this->model->find($ids);
  660. $this->assign('row',$model);
  661. if($this->request->isGet()){
  662. return view();
  663. }else{
  664. $data=input('row/a');
  665. $this->validate($data,RefundValidate::class);
  666. Db::startTrans();
  667. $model=$this->model->where('id',$ids)->lock(true)->findOrFail();
  668. $model->makeRefund('admin',$this->admin(),$data);
  669. Db::commit();
  670. $this->success();
  671. }
  672. }
  673. public function status(){
  674. return \app\common\model\MobileOrder::$status;
  675. }
  676. public function pay_type(){
  677. return \app\common\model\MobileOrder::$payTypes;
  678. }
  679. public function add_operation(){
  680. $id=input('ids/d');
  681. if($this->request->isGet()){
  682. $this->assign('shortcut',ShortcutContent::getList());
  683. return view();
  684. }else{
  685. $content=input('row.content');
  686. $this->validate(compact('content'),[
  687. 'content'=>'max:250',
  688. ]);
  689. MobileOrderOperation::create([
  690. 'mobile_order_id'=>$id,
  691. 'admin_id'=>$this->auth->id,
  692. 'content'=>$content,
  693. ]);
  694. $this->success();
  695. }
  696. }
  697. public function send(){
  698. $id=input('ids/d');
  699. if($this->request->isGet()){
  700. $row=$this->model->find($id);
  701. $this->assign('row',$row);
  702. return view();
  703. }else{
  704. $data=input('row/a');
  705. Db::startTrans();
  706. $row=$this->model->lock(true)->findOrFail($id);
  707. $row->dealSend($data['trans_no'],$data['trans_id']);
  708. Db::commit();
  709. $this->success();
  710. }
  711. }
  712. #展示开卡资料
  713. public function show_open_data($id){
  714. $row=$this->model->find($id);
  715. return view('',compact('row'));
  716. }
  717. public function see_logistics($ids){
  718. $order=$this->model->find($ids);
  719. $data=TransferCheck::instance()->setNo($order['trans_no'])->setName($order['name'])->setPhone($order['phone'])->setLogisticsCompany(LogisticsCompany::get($order['trans_id']))->get();
  720. $this->assign('data',$data);
  721. return view('mobile_order/see_logistics');
  722. }
  723. #备注
  724. public function sub_remark($id){
  725. $order=$this->model->find($id);
  726. if($this->admin('is_sub') && $this->auth->id!=$order['s_id']){
  727. $this->error('操作失败(a)');
  728. }
  729. if($this->request->isGet()){
  730. return view();
  731. }else{
  732. $data=input('row/a');
  733. $this->validate($data,[
  734. 'content|备注'=>['require','max:50'],
  735. ]);
  736. $order->subRemark()->save([
  737. 'sub_admin_id'=>$this->auth->id,
  738. 'content'=>$data['content'],
  739. ]);
  740. $this->success();
  741. }
  742. }
  743. public function set_anchor($ids){
  744. $order=$this->model->find($ids);
  745. if(!$order){
  746. $this->error('订单不存在');
  747. }
  748. if($this->request->isGet()){
  749. if($this->admin('is_manager')){
  750. $anchor_id=$order['mobile_anchor_id'];
  751. $this->assign('mobile_anchor_id',$anchor_id);
  752. }
  753. $sub_anchor_id=$order->subAnchor()->value('sub_mobile_anchor_id');
  754. $this->assign('sub_mobile_anchor_id',$sub_anchor_id);
  755. $this->assign('order',$order);
  756. return view('sub_anchor');
  757. }else{
  758. $data=input('row/a');
  759. if(!empty($data['mobile_anchor_id']) && !\app\admin\model\MobileAnchor::find($data['mobile_anchor_id'])){
  760. $this->error('主播不存在');
  761. }
  762. if(!empty($data['sub_mobile_anchor_id']) && !\app\admin\model\MobileAnchor::find($data['sub_mobile_anchor_id'])){
  763. $this->error('主播不存在');
  764. }
  765. if($this->admin('is_manager')){
  766. if(!empty($data['mobile_anchor_id'])){
  767. $order['mobile_anchor_id']=$data['mobile_anchor_id'];
  768. if(!$order->save()){
  769. $this->error('保存失败');
  770. }
  771. }
  772. if(!empty($data['sub_mobile_anchor_id'])){
  773. MobileOrderSubAnchor::sync($order,$data['sub_mobile_anchor_id']);
  774. }
  775. }elseif ($this->admin('is_sub') && $this->admin('id')==$order['s_id']){
  776. if(!empty($data['sub_mobile_anchor_id'])){
  777. if($order->subAnchor()->find()){
  778. $this->error('无法再次设置');
  779. }
  780. MobileOrderSubAnchor::sync($order,$data['sub_mobile_anchor_id']);
  781. }
  782. }
  783. $this->success();
  784. }
  785. }
  786. public function mobile_up($ids){
  787. $order=$this->model->find($ids);
  788. $mobile=$order->mobile()->find();
  789. if($this->request->isGet()) {
  790. $this->assign('row', $mobile);
  791. $this->assign('disabled', 1);
  792. $this->assign('otherSubDisabled', 1);
  793. return view();
  794. }else{
  795. if($mobile){
  796. $mobile->again_sell();
  797. }
  798. $this->success();
  799. }
  800. }
  801. public function refund_log(){
  802. if($this->request->isAjax()){
  803. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  804. $this->relationSearch=true;
  805. /*$limit=input('limit',10);
  806. $offset=input('offset',0);*/
  807. $filter=json_decode(input('filter'),true)?:[];
  808. $map=[];
  809. if(!empty($filter['od.mobile_id'])){
  810. $map['mobile_order.mobile_id']=['eq',$filter['od.mobile_id']];
  811. }
  812. if(!empty($filter['od.s_id'])){
  813. $map['mobile_order.s_id']=['eq',$filter['od.s_id']];
  814. }
  815. if(isset($filter['pass'])){
  816. $map['pass']=['eq',$filter['pass']];
  817. }
  818. if(!empty($filter['od.no'])){
  819. $map['mobile_order.no']=['like',"%{$filter['od.no']}%"];
  820. }
  821. if(!empty($filter['od.order_no'])){
  822. $map['mobile_order.order_no']=['like',"%{$filter['od.order_no']}%"];
  823. }
  824. if(!empty($filter['reason'])){
  825. $map['reason']=['like',"%{$filter['reason']}%"];
  826. }
  827. if(!empty($filter['admin.nickname'])){
  828. $map['admin.nickname']=['like',"%{$filter['admin.nickname']}%"];
  829. }
  830. if(!empty($filter['od.amount'])){
  831. $amountArr=explode(',',$filter['od.amount']);
  832. if(empty($amountArr[0])){
  833. $amountArr[0]=0;
  834. }
  835. if(empty($amountArr[1])){
  836. $amountArr[1]=10000000000000;
  837. }
  838. $map['mobile_order.amount']=['between',$amountArr];
  839. }
  840. if(!empty($filter['amount_backend'])){
  841. $amountArr=explode(',',$filter['amount_backend']);
  842. if(empty($amountArr[0])){
  843. $amountArr[0]=0;
  844. }
  845. if(empty($amountArr[1])){
  846. $amountArr[1]=10000000000000;
  847. }
  848. $map['amount_backend']=['between',$amountArr];
  849. }
  850. $log=(new MobileOrderRefundLog)->getTable();
  851. if(!empty($filter['create_time'])){
  852. list($s,$e)=explode(' - ',$filter['create_time']);
  853. $map["{$log}.create_time"]=['between',[strtotime($s),strtotime($e)]];
  854. }
  855. //$page=$offset/$limit+1;
  856. $data=MobileOrderRefundLog::where($map)
  857. ->where(function (Query $query){
  858. if(!$this->admin('is_manager')){
  859. $query->where('mobile_order.s_id',$this->admin('id'));
  860. }
  861. })
  862. ->with(['od','admin'])
  863. ->order('id','desc')
  864. ->paginate($limit,false);
  865. /* foreach ($data as $model){
  866. $model->setAttr('s_name',Admin::where('id',$model['od']['s_id'])->value('nickname'));
  867. }*/
  868. return json([
  869. 'total'=>$data->total(),
  870. 'rows'=>$data->items(),
  871. 'filter'=>$filter,
  872. ]);
  873. }
  874. return $this->fetch();
  875. }
  876. #dy结算
  877. public function dy_settle(){
  878. $id=input('ids');
  879. if(empty($id)){
  880. $this->error('id必须');
  881. }
  882. Db::startTrans();
  883. $order=$this->model->lock(true)->find($id);
  884. if(!$order){
  885. $this->error('订单不存在');
  886. }
  887. $order->dySettle();
  888. Db::commit();
  889. $this->success();
  890. }
  891. public function aaa(){
  892. $admin = admin::where('proxy',0)
  893. ->where('sub',1)
  894. ->field(['id','nickname'])
  895. ->select();
  896. return "$admin";
  897. }
  898. /**
  899. * 重新提交
  900. *
  901. * @return void
  902. */
  903. public function resubmit()
  904. {
  905. $id=input('ids');
  906. if(empty($id)){
  907. $this->error('id必须');
  908. }
  909. $result = ZopOrderService::push($id);
  910. if ($result['code'] != 0) {
  911. $this->error($result['message']);
  912. }
  913. $this->success();
  914. }
  915. /**
  916. * 取消订单
  917. *
  918. * @return void
  919. */
  920. public function cancel()
  921. {
  922. $id=input('ids');
  923. if(empty($id)){
  924. $this->error('id必须');
  925. }
  926. $order = MobileOrder::where('id', $id)->find();
  927. $order->is_cancel = 1;
  928. $order->canceled_by = $this->auth->id;
  929. $order->canceled_at = date('Y-m-d H:i:s');
  930. $order->save();
  931. $this->success();
  932. }
  933. }