GoodsExport.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace app\model\goods;
  11. use app\model\BaseModel;
  12. use think\facade\Db;
  13. /**
  14. * 商品导出
  15. * @author Administrator
  16. */
  17. class GoodsExport extends BaseModel
  18. {
  19. public $field = [
  20. 'sku_no' => '商品编码',
  21. 'sku_name' => '商品名称',
  22. 'goods_class_name' => '商品类型',
  23. 'goods_state' => '商品状态',
  24. 'price' => '销售价',
  25. 'market_price' => '划线价',
  26. 'cost_price' => '成本价',
  27. 'stock' => '库存',
  28. 'stock_alarm' => '库存预警',
  29. 'real_stock' => '实物库存',
  30. 'weight' => '重量(单位g)',
  31. 'volume' => '体积(单位立方米)',
  32. 'unit' => '单位',
  33. 'sale_num' => '销量',
  34. 'click_num' => '点击量',
  35. 'collect_num' => '收藏量',
  36. 'keywords' => '关键词',
  37. 'introduction' => '促销语',
  38. 'brand_name' => '品牌名称',
  39. ];
  40. /**
  41. * 查询商品项数据并导出
  42. * @param $condition
  43. * @param $condition_desc
  44. * @param $site_id
  45. * @return array
  46. */
  47. public function export($condition, $condition_desc, $site_id)
  48. {
  49. try {
  50. // 预先创建导出的记录
  51. $data = array (
  52. 'condition' => json_encode($condition_desc),
  53. 'create_time' => time(),
  54. 'type' => 1,//订单
  55. 'status' => 0,
  56. 'site_id' => $site_id
  57. );
  58. $records_result = $this->addExport($data);
  59. $export_id = $records_result[ 'data' ] ?? 0;
  60. if ($export_id <= 0) {
  61. return $this->error();
  62. }
  63. $alias = 'gs';
  64. $field = $this->field;
  65. // 通过分批次执行数据导出(防止内存超出配置设置的)
  66. set_time_limit(0);
  67. $file_name = date('YmdHis');// csv文件名
  68. $file_path = 'upload/goods_csv/';
  69. if (dir_mkdir($file_path)) {
  70. $file_path = $file_path . $file_name . '.csv';
  71. //创建一个临时csv文件
  72. $fp = fopen($file_path, 'w'); // 生成临时文件
  73. fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF)); // 添加 BOM
  74. $field_value = [];
  75. $field_key = [];
  76. $field_key_array = [];
  77. // 为了防止部分代码被筛选中替换, 给变量前后两边增加字符串
  78. foreach ($field as $k => $v) {
  79. $field_value[] = $v;
  80. $field_key[] = "{\$$k}";
  81. $field_key_array[] = $k;
  82. }
  83. $order_table = Db::name('goods_sku')->where($condition)->alias($alias);
  84. $join[] = [
  85. 'goods g',
  86. "g.goods_id = gs.goods_id",
  87. 'left'
  88. ];
  89. $order_table = $this->parseJoin($order_table, $join);
  90. $first_line = implode(',', $field_value);
  91. // 写入第一行表头
  92. fwrite($fp, $first_line . "\n");
  93. $temp_line = implode(',', $field_key) . "\n";
  94. $table_field = 'gs.sku_id, gs.sku_no, gs.sku_name, gs.goods_state, gs.goods_class_name, gs.price, gs.market_price, gs.cost_price, gs.stock, gs.stock_alarm, gs.real_stock, gs.weight, gs.volume, gs.unit, gs.sale_num, gs.click_num, gs.collect_num, gs.keywords, gs.introduction, gs.brand_name';
  95. $order_table->field($table_field)->chunk(5000, function($item_list) use ($fp, $temp_line, $field_key_array) {
  96. // 写入导出信息
  97. $this->itemExport($item_list, $field_key_array, $temp_line, $fp);
  98. unset($item_list);
  99. }, 'gs.sku_id');
  100. $order_table->removeOption();
  101. fclose($fp); // 每生成一个文件关闭
  102. unset($order_table);
  103. // 将同步导出记录状态
  104. $records_data = array (
  105. 'path' => $file_path,
  106. 'status' => 1
  107. );
  108. $records_condition = array (
  109. [ 'export_id', '=', $export_id ]
  110. );
  111. $this->editExport($records_data, $records_condition);
  112. return $this->success();
  113. } else {
  114. return $this->error();
  115. }
  116. } catch (\Exception $e) {
  117. return $this->error([], $e->getMessage() . $e->getFile() . $e->getLine());
  118. }
  119. }
  120. /**
  121. * @param $db_obj
  122. * @param $join
  123. * @return mixed
  124. */
  125. public function parseJoin($db_obj, $join)
  126. {
  127. foreach ($join as $item) {
  128. list($table, $on, $type) = $item;
  129. $type = strtolower($type);
  130. switch ( $type ) {
  131. case "left":
  132. $db_obj = $db_obj->leftJoin($table, $on);
  133. break;
  134. case "inner":
  135. $db_obj = $db_obj->join($table, $on);
  136. break;
  137. case "right":
  138. $db_obj = $db_obj->rightjoin($table, $on);
  139. break;
  140. case "full":
  141. $db_obj = $db_obj->fulljoin($table, $on);
  142. break;
  143. default:
  144. break;
  145. }
  146. }
  147. return $db_obj;
  148. }
  149. /**
  150. * 给csv写入新的数据
  151. * @param $item_list
  152. * @param $field_key
  153. * @param $temp_line
  154. * @param $fp
  155. */
  156. public function itemExport($item_list, $field_key, $temp_line, $fp)
  157. {
  158. $item_list = $item_list->toArray();
  159. foreach ($item_list as $k => $item_v) {
  160. $new_line_value = $temp_line;
  161. if (isset($item_v[ 'goods_num' ])) {
  162. $item_v[ 'goods_num' ] = numberFormat($item_v[ 'goods_num' ]);
  163. }
  164. if (isset($item_v[ 'num' ])) {
  165. $item_v[ 'num' ] = numberFormat($item_v[ 'num' ]);
  166. }
  167. if (isset($item_v[ 'stock' ])) {
  168. $item_v[ 'stock' ] = numberFormat($item_v[ 'stock' ]);
  169. }
  170. if (isset($item_v[ 'stock_alarm' ])) {
  171. $item_v[ 'stock_alarm' ] = numberFormat($item_v[ 'stock_alarm' ]);
  172. }
  173. if (isset($item_v[ 'sale_num' ])) {
  174. $item_v[ 'sale_num' ] = numberFormat($item_v[ 'sale_num' ]);
  175. }
  176. if (isset($item_v[ 'virtual_sale' ])) {
  177. $item_v[ 'virtual_sale' ] = numberFormat($item_v[ 'virtual_sale' ]);
  178. }
  179. if (isset($item_v[ 'real_stock' ])) {
  180. $item_v[ 'real_stock' ] = numberFormat($item_v[ 'real_stock' ]);
  181. }
  182. $item_v[ 'goods_state' ] = $item_v[ 'goods_state' ] == 1 ? '销售中' : '仓库中';
  183. foreach ($item_v as $key => $value) {
  184. $value = trim($value);
  185. //CSV比较简单,记得转义 逗号就好
  186. $values = str_replace(',', '\\', $value . "\t");
  187. $values = str_replace("\n", '', $values);
  188. $values = str_replace("\r", '', $values);
  189. $new_line_value = str_replace("{\$$key}", $values, $new_line_value);
  190. }
  191. // 写入第一行表头
  192. fwrite($fp, $new_line_value);
  193. // 销毁变量, 防止内存溢出
  194. unset($new_line_value);
  195. }
  196. }
  197. /**
  198. * 添加导出记录
  199. * @param $data
  200. * @return array
  201. */
  202. public function addExport($data)
  203. {
  204. $res = model("goods_export")->add($data);
  205. return $this->success($res);
  206. }
  207. /**
  208. * 更新导出记录
  209. * @param $data
  210. * @param $condition
  211. * @return array
  212. */
  213. public function editExport($data, $condition)
  214. {
  215. $res = model("goods_export")->update($data, $condition);
  216. return $this->success($res);
  217. }
  218. /**
  219. * 删除导出记录
  220. * @param $condition
  221. * @return array
  222. */
  223. public function deleteExport($condition)
  224. {
  225. // 先查询数据
  226. $list = model("goods_export")->getList($condition, '*');
  227. if (!empty($list)) {
  228. foreach ($list as $k => $v) {
  229. if (file_exists($v[ 'path' ])) {
  230. // 删除物理文件路径
  231. if (!unlink($v[ 'path' ])) {
  232. // 失败
  233. } else {
  234. // 成功
  235. }
  236. }
  237. }
  238. $res = model("goods_export")->delete($condition);
  239. }
  240. return $this->success($res);
  241. }
  242. /**
  243. * 获取导出记录
  244. * @param $condition
  245. * @param string $field
  246. * @param string $order
  247. * @return array
  248. */
  249. public function getExport($condition, $field = "*", $order = '')
  250. {
  251. $list = model("goods_export")->getList($condition, $field, $order);
  252. return $this->success($list);
  253. }
  254. /**
  255. * 导出记录
  256. * @param array $condition
  257. * @param int $page
  258. * @param int $page_size
  259. * @param string $order
  260. * @param string $field
  261. * @return array
  262. */
  263. public function getExportPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
  264. {
  265. $list = model('goods_export')->pageList($condition, $field, $order, $page, $page_size);
  266. return $this->success($list);
  267. }
  268. }