Lists.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <?php
  2. namespace app\admin\controller\product;
  3. use app\common\controller\Backend;
  4. use Exception;
  5. use think\Db;
  6. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  7. use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
  8. use PhpOffice\PhpSpreadsheet\Reader\Xls;
  9. use PhpOffice\PhpSpreadsheet\Reader\Csv;
  10. use app\common\model\ProductArea;
  11. use think\exception\DbException;
  12. use think\exception\PDOException;
  13. use app\admin\model\Importregion;
  14. use app\admin\model\Importlog;
  15. use think\exception\ValidateException;
  16. /**
  17. * 商品列管理
  18. *
  19. * @icon fa fa-circle-o
  20. */
  21. class Lists extends Backend
  22. {
  23. /**
  24. * Lists模型对象
  25. * @var \app\admin\model\product\Lists
  26. */
  27. protected $model = null;
  28. protected $productArea = null;
  29. protected $areaCode = null;
  30. public function _initialize()
  31. {
  32. parent::_initialize();
  33. $this->productArea = new ProductArea;
  34. $this->model = new \app\common\model\ProductLists;
  35. }
  36. /**
  37. * 查看
  38. *
  39. * @return string|Json
  40. * @throws \think\Exception
  41. * @throws DbException
  42. */
  43. public function index()
  44. {
  45. //设置过滤方法
  46. $this->request->filter(['strip_tags', 'trim']);
  47. if (false === $this->request->isAjax()) {
  48. return $this->view->fetch();
  49. }
  50. //如果发送的来源是 Selectpage,则转发到 Selectpage
  51. if ($this->request->request('keyField')) {
  52. return $this->selectpage();
  53. }
  54. [$where, $sort, $order, $offset, $limit] = $this->buildparams();
  55. $list = $this->model->with('products')
  56. ->where($where)
  57. ->order($sort, $order)
  58. ->paginate($limit);
  59. foreach ($list as &$item) {
  60. $item['total_num']= $this->productArea::where('product_id', $item->id)->count();
  61. $item['sell_num'] = $this->productArea::where('product_id', $item->id)->where('status', $this->productArea::STOP)->count();
  62. }
  63. $result = ['total' => $list->total(), 'rows' => $list->items()];
  64. return json($result);
  65. }
  66. /**
  67. * 添加
  68. *
  69. * @return string
  70. * @throws \think\Exception
  71. */
  72. public function add()
  73. {
  74. if (false === $this->request->isPost()) {
  75. $this->assignconfig('areaData', []);
  76. return $this->view->fetch();
  77. }
  78. $params = $this->request->post('row/a');
  79. if (empty($params)) {
  80. $this->error(__('Parameter %s can not be empty', ''));
  81. }
  82. $params = $this->preExcludeFields($params);
  83. if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
  84. $params[$this->dataLimitField] = $this->auth->id;
  85. }
  86. $result = false;
  87. Db::startTrans();
  88. try {
  89. //是否采用模型验证
  90. if ($this->modelValidate) {
  91. $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  92. $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
  93. $this->model->validateFailException()->validate($validate);
  94. }
  95. $areaArr = json_decode($params['product_area'], true);
  96. $areaArrTxt = json_decode($params['product_area_txt'], true);
  97. if(empty($areaArr) || empty($areaArrTxt)) throw new ValidateException('请添加商品关联地区');
  98. unset($params['product_area'], $params['product_area_txt']);
  99. //商品
  100. $add = $this->model->create($params);
  101. $result= self::setEqualArea($add->id, $areaArr, $areaArrTxt, 0);
  102. Db::commit();
  103. } catch (ValidateException|PDOException|Exception $e) {
  104. Db::rollback();
  105. $this->error($e->getMessage());
  106. }
  107. if ($result === false) {
  108. $this->error(__('No rows were inserted'));
  109. }
  110. $this->success();
  111. }
  112. /**
  113. * 编辑
  114. * @param $ids
  115. * @return string
  116. * @throws DbException
  117. * @throws \think\Exception
  118. */
  119. public function edit($ids = null)
  120. {
  121. $row = $this->model->get($ids);
  122. if (!$row) {
  123. $this->error(__('No Results were found'));
  124. }
  125. $adminIds = $this->getDataLimitAdminIds();
  126. if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
  127. $this->error(__('You have no permission'));
  128. }
  129. if (false === $this->request->isPost()) {
  130. $area = $this->productArea::where('product_id', $ids)->select();
  131. $areaData = array();
  132. $areaCode = array();
  133. $areaTxt = array();
  134. foreach ($area as $key =>$item) {
  135. if($item->province > 0){
  136. $areaData[$key] = $item->province;
  137. $areaCode[$key][0] = $item->province;
  138. }
  139. if($item->city > 0){
  140. $areaData[$key] = $item->city;
  141. $areaCode[$key][1] = $item->city;
  142. }
  143. if($item->area > 0) {
  144. $areaData[$key] = $item->area;
  145. $areaCode[$key][2] = $item->area;
  146. }
  147. if($item->county > 0) {
  148. $areaData[$key] = $item->county;
  149. $areaCode[$key][3] = $item->county;
  150. }
  151. $areaTxt[] = [$item->address];
  152. }
  153. $this->assignconfig('areaData', json_encode($areaData));
  154. $this->view->assign('row', $row);
  155. $this->view->assign('areaTxt', json_encode($areaTxt, JSON_UNESCAPED_UNICODE));
  156. $this->view->assign('areaCode', json_encode($areaCode));
  157. return $this->view->fetch();
  158. }
  159. $params = $this->request->post('row/a');
  160. if (empty($params)) {
  161. $this->error(__('Parameter %s can not be empty', ''));
  162. }
  163. $params = $this->preExcludeFields($params);
  164. $result = false;
  165. Db::startTrans();
  166. try {
  167. //是否采用模型验证
  168. if ($this->modelValidate) {
  169. $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  170. $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
  171. $row->validateFailException()->validate($validate);
  172. }
  173. $areaArr = json_decode($params['product_area'], true);
  174. $areaArrTxt = json_decode($params['product_area_txt'], true);
  175. if(empty($areaArr) || empty($areaArrTxt)) throw new ValidateException('请添加商品关联地区');
  176. unset($params['product_area'], $params['product_area_txt']);
  177. $row->allowField(true)->save($params);
  178. //$this->productArea::where('product_id', $ids)->where('status', 1)->delete();
  179. $result= self::setEqualArea($ids, $areaArr, $areaArrTxt, 1);
  180. Db::commit();
  181. } catch (ValidateException|PDOException|Exception $e) {
  182. Db::rollback();
  183. $this->error($e->getMessage());
  184. }
  185. if (false === $result) {
  186. $this->error(__('No rows were updated'));
  187. }
  188. $this->success();
  189. }
  190. /**
  191. * 导入产品地区
  192. * @param $ids
  193. * @return string
  194. * @throws DbException
  195. * @throws \think\Exception
  196. */
  197. public function exports(Importregion $importregion, Importlog $Importlog){
  198. if (false === $this->request->isPost()) {
  199. $this->assignconfig('areaData', []);
  200. return $this->view->fetch();
  201. }
  202. $params = $this->request->post('row/a');
  203. if (empty($params)) {
  204. $this->error(__('Parameter %s can not be empty', ''));
  205. }
  206. $params = $this->preExcludeFields($params);
  207. if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
  208. $params[$this->dataLimitField] = $this->auth->id;
  209. }
  210. $file = $params['export'];
  211. $filePath = ROOT_PATH . DS . 'public' . DS . $file;
  212. if (!is_file($filePath)) {
  213. $this->error(__('No results were found'));
  214. }
  215. //实例化reader
  216. $ext = pathinfo($filePath, PATHINFO_EXTENSION);
  217. if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
  218. $this->error(__('Unknown data format'));
  219. }
  220. $reader = ($ext === 'xls')? new Xls(): new Xlsx();
  221. $result = false;
  222. Db::startTrans();
  223. try {
  224. if (!$PHPExcel = $reader->load($filePath)) {
  225. $this->error(__('Unknown data format'));
  226. }
  227. $PHPExcel = $reader->load($filePath);
  228. $currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
  229. $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
  230. //读取第二行字段名
  231. $data = [];
  232. $fields = [];
  233. $k = 0;
  234. $i = 0;
  235. $time = time();
  236. for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
  237. $values = [];
  238. //列字段
  239. for ($currentColumn = 2; $currentColumn <= 5; $currentColumn++) {
  240. $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
  241. $values[] = is_null($val) ? '' : $val;
  242. }
  243. $field = implode('-', $values);
  244. $row = $importregion::where('name', $field)->find();
  245. if(!empty($row)){
  246. if($this->productArea::where('product_id',$params['product_id'])->where('address',$row['name'])->count() > 0) continue;
  247. $data = self::importData($data, $k, $params['product_id'], $row->com_id, $time);
  248. $data[$k]['address'] = $row['name'];
  249. $k +=1;
  250. }else{
  251. $fields = self::importData($fields, $i, $params['product_id'], $field, $time);
  252. $i += 1;
  253. }
  254. }
  255. if(!empty($data)) $result= $this->productArea::insertAll($data);
  256. //错误日志
  257. if(!empty($fields)) $Importlog::insertAll($fields);
  258. Db::commit();
  259. } catch (ValidateException|PDOException|Exception $e) {
  260. Db::rollback();
  261. $this->error($e->getMessage());
  262. }
  263. if ($result === false) {
  264. $this->error(__('No rows were inserted'));
  265. }
  266. $this->success();
  267. }
  268. /**
  269. * 导入数据
  270. * @return array
  271. */
  272. private static function importData(array $data, int $k, int $product_id, string $ids, $time): array
  273. {
  274. //$data = array();
  275. $arr = explode('-', $ids); //分割ID
  276. $data[$k]['product_id'] = $product_id;
  277. $data[$k]['province'] = $arr[0]??0;
  278. $data[$k]['city'] = $arr[1]??0 ;
  279. $data[$k]['area'] = $arr[2]??0;
  280. $data[$k]['county'] = $arr[3]??0;
  281. $data[$k]['create_time'] = $time;
  282. return $data;
  283. }
  284. //判断是否存在相同元素
  285. private function setEqualArea(int $product_id,array $areaArr, array $areaArrTxt, int $type): bool
  286. {
  287. foreach ($areaArr as $key=>$row)
  288. {
  289. $arr['product_id'] = $product_id;
  290. $arr['province'] = $row[0]??0;
  291. $arr['city'] = $row[1]??0 ;
  292. $arr['area'] = $row[2]??0;
  293. $arr['county'] = $row[3]??0;
  294. $arr['address'] = $areaArrTxt[$key][0];
  295. if(!empty($type)){
  296. if($this->productArea::where('product_id',$arr['product_id'])
  297. ->where('province',$arr['province'])
  298. ->where('city',$arr['city'])->where('area',$arr['area'])
  299. ->where('county',$arr['county'])
  300. ->count() > 0) continue;
  301. }
  302. $this->productArea::create($arr);
  303. }
  304. return true;
  305. }
  306. }