Excel.php 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: leo
  5. * Date: 2018/5/17
  6. * Time: 上午11:34
  7. */
  8. namespace common\helpers;
  9. use common\helpers\http\RemoteUploadApi;
  10. use common\models\ExcelAddUser;
  11. use common\models\ExcelChangeBalance;
  12. use common\models\ExcelImport;
  13. use common\models\ExcelRegInfo;
  14. use common\models\ExcelWithdrawPaidFalse;
  15. use common\models\Export;
  16. use common\models\ExportFile;
  17. use common\models\forms\AdminAddUserForm;
  18. use common\models\forms\ChangeBalanceForm;
  19. use common\models\forms\ExcelOrderDecForm;
  20. use common\models\forms\ExcelOrderShopForm;
  21. use common\models\forms\ExcelOrderStandardForm;
  22. use common\models\forms\RegInfoAuditForm;
  23. use common\models\forms\WithdrawForm;
  24. use common\models\Uploads;
  25. use common\models\UserNetwork;
  26. use common\models\User;
  27. use yii\base\BaseObject;
  28. use yii\base\Exception;
  29. use yii\base\StaticInstanceTrait;
  30. class Excel extends BaseObject {
  31. use StaticInstanceTrait;
  32. const CHILD_PATH = 'excel_export';
  33. public $isRemote = true;
  34. public $uploadInfo;
  35. public $exportInfo;
  36. private $_errors = [];
  37. const EXCEL_STRUCTURE = [
  38. 'addUser' => [
  39. 'formClass' => AdminAddUserForm::class,
  40. 'formScenario' => 'add',
  41. 'formAction' => 'edit',
  42. 'errorTipField' => 'USER_NAME',
  43. 'excelTableClass' => ExcelAddUser::class,
  44. 'excelTableField' => [
  45. '序号' => 'SORT',
  46. '会员编号' => 'USER_NAME',
  47. '会员姓名' => 'REAL_NAME',
  48. '会员级别' => 'DEC_LV',
  49. '身份证' => 'ID_CARD',
  50. '手机' => 'MOBILE',
  51. '备用手机号' => 'TEL',
  52. '省/市' => 'AREA_PROVINCE',
  53. '市/区' => 'AREA_CITY',
  54. '区/县' => 'AREA_COUNTY',
  55. '身份证地址' => 'ADDRESS',
  56. '开户银行' => 'OPEN_BANK',
  57. '开户行地址' => 'BANK_ADDRESS',
  58. '银行账号' => 'BANK_NO',
  59. '银行 省/市' => 'BANK_PROVINCE',
  60. '银行 市/区' => 'BANK_CITY',
  61. '银行 区/县' => 'BANK_COUNTY',
  62. '是否报单中心' => 'IS_DEC',
  63. '报单中心级别' => 'DEC_ROLE',
  64. '所属报单中心编号' => 'DEC_USER_NAME',
  65. '生日' => 'BIRTHDAY',
  66. '接点人' => 'CON_USER_NAME',
  67. '开拓人' => 'REC_USER_NAME',
  68. '区位' => 'LOCATION',
  69. ],
  70. 'formField' => [
  71. 'USER_NAME' => [
  72. 'name' => 'userName',
  73. 'type' => 'common',
  74. ],
  75. 'REAL_NAME' => [
  76. 'name' => 'realName',
  77. 'type' => 'common',
  78. ],
  79. 'DEC_LV' => [
  80. 'name' => 'decLv',
  81. 'type' => 'table',
  82. 'table' => 'DECLARATION_LEVEL',
  83. 'field' => 'LEVEL_NAME',
  84. 'select' => 'ID',
  85. ],
  86. 'ID_CARD' => [
  87. 'name' => 'idCard',
  88. 'type' => 'common',
  89. ],
  90. 'MOBILE' => [
  91. 'name' => 'mobile',
  92. 'type' => 'common',
  93. ],
  94. 'TEL' => [
  95. 'name' => 'tel',
  96. 'type' => 'common',
  97. ],
  98. 'AREA_PROVINCE' => [
  99. 'name' => 'areaSelected',
  100. 'isArray' => true,
  101. 'type' => 'table',
  102. 'table' => 'REGION',
  103. 'field' => 'REGION_NAME',
  104. 'where' => 'DEEP=2',
  105. 'select' => 'REGION_CODE',
  106. ],
  107. 'AREA_CITY' => [
  108. 'name' => 'areaSelected',
  109. 'isArray' => true,
  110. 'type' => 'table',
  111. 'table' => 'REGION',
  112. 'field' => 'REGION_NAME',
  113. 'where' => 'DEEP=3',
  114. 'select' => 'REGION_CODE',
  115. ],
  116. 'AREA_COUNTY' => [
  117. 'name' => 'areaSelected',
  118. 'isArray' => true,
  119. 'type' => 'table',
  120. 'table' => 'REGION',
  121. 'field' => 'REGION_NAME',
  122. 'where' => 'DEEP=4',
  123. 'select' => 'REGION_CODE',
  124. ],
  125. 'ADDRESS' => [
  126. 'name' => 'address',
  127. 'type' => 'common',
  128. ],
  129. 'OPEN_BANK' => [
  130. 'name' => 'openBank',
  131. 'type' => 'table',
  132. 'table' => 'OPEN_BANK',
  133. 'field' => 'BANK_NAME',
  134. 'select' => 'BANK_CODE',
  135. ],
  136. 'BANK_ADDRESS' => [
  137. 'name' => 'bankAddress',
  138. 'type' => 'common',
  139. ],
  140. 'BANK_NO' => [
  141. 'name' => 'bankNo',
  142. 'type' => 'common',
  143. ],
  144. 'BANK_PROVINCE' => [
  145. 'name' => 'bankAreaSelected',
  146. 'isArray' => true,
  147. 'type' => 'table',
  148. 'table' => 'REGION',
  149. 'field' => 'REGION_NAME',
  150. 'where' => 'DEEP=2',
  151. 'select' => 'REGION_CODE',
  152. ],
  153. 'BANK_CITY' => [
  154. 'name' => 'bankAreaSelected',
  155. 'isArray' => true,
  156. 'type' => 'table',
  157. 'table' => 'REGION',
  158. 'field' => 'REGION_NAME',
  159. 'where' => 'DEEP=3',
  160. 'select' => 'REGION_CODE',
  161. ],
  162. 'BANK_COUNTY' => [
  163. 'name' => 'bankAreaSelected',
  164. 'isArray' => true,
  165. 'type' => 'table',
  166. 'table' => 'REGION',
  167. 'field' => 'REGION_NAME',
  168. 'where' => 'DEEP=4',
  169. 'select' => 'REGION_CODE',
  170. ],
  171. 'IS_DEC' => [
  172. 'name' => 'isDec',
  173. 'type' => 'bool',
  174. ],
  175. 'DEC_ROLE' => [
  176. 'name' => 'decRoleId',
  177. 'type' => 'table',
  178. 'table' => 'DEC_ROLE',
  179. 'field' => 'ROLE_NAME',
  180. 'select' => 'ID',
  181. 'isAllowNull' => true,
  182. ],
  183. 'DEC_USER_NAME' => [
  184. 'name' => 'decUserName',
  185. 'type' => 'common',
  186. ],
  187. 'BIRTHDAY' => [
  188. 'name' => 'birthday',
  189. 'type' => 'common',
  190. ],
  191. 'CON_USER_NAME' => [
  192. 'name' => 'conUserName',
  193. 'type' => 'common',
  194. ],
  195. 'REC_USER_NAME' => [
  196. 'name' => 'recUserName',
  197. 'type' => 'common',
  198. ],
  199. 'LOCATION' => [
  200. 'name' => 'location',
  201. 'type' => 'int',
  202. ],
  203. ]
  204. ],
  205. 'withdrawPaidFalse' => [
  206. 'formClass' => WithdrawForm::class,
  207. 'formScenario' => 'excelPaidFalse',
  208. 'formAction' => 'excelPaidFalse',
  209. 'errorTipField' => 'SN',
  210. 'excelTableClass' => ExcelWithdrawPaidFalse::class,
  211. 'excelTableField' => [
  212. '序号' => 'SORT',
  213. '提现流水号' => 'SN',
  214. '提现期数' => 'WITHDRAW_PERIOD_NUM',
  215. '付款日期' => 'PAID_AT',
  216. '付款失败原因' => 'PAID_FAIL_REMARK',
  217. '会员编号' => 'USER_NAME',
  218. '会员姓名' => 'REAL_NAME',
  219. '实付金额' => 'AMOUNT',
  220. '实时开户名' => 'BANK_REAL_NAME',
  221. '实时银行账户' => 'BANK_NO',
  222. ],
  223. 'formField' => [
  224. 'SN' => [
  225. 'name' => 'sn',
  226. 'type' => 'common',
  227. ],
  228. 'WITHDRAW_PERIOD_NUM' => [
  229. 'name' => 'withdrawPeriodNum',
  230. 'type' => 'common',
  231. ],
  232. 'PAID_AT' => [
  233. 'name' => 'paidAt',
  234. 'type' => 'common',
  235. ],
  236. 'PAID_FAIL_REMARK' => [
  237. 'name' => 'paidFailRemark',
  238. 'type' => 'common',
  239. ],
  240. 'USER_NAME' => [
  241. 'name' => 'userName',
  242. 'type' => 'common',
  243. ],
  244. 'REAL_NAME' => [
  245. 'name' => 'realName',
  246. 'type' => 'common',
  247. ],
  248. 'AMOUNT' => [
  249. 'name' => 'amount',
  250. 'type' => 'common',
  251. ],
  252. 'BANK_REAL_NAME' => [
  253. 'name' => 'bankRealName',
  254. 'type' => 'common',
  255. ],
  256. 'BANK_NO' => [
  257. 'name' => 'bankNo',
  258. 'type' => 'common',
  259. ],
  260. ]
  261. ],
  262. 'changeBalance' => [
  263. 'formClass' => ChangeBalanceForm::class,
  264. 'formScenario' => 'excelChangeBalance',
  265. 'formAction' => 'excelChangeBalance',
  266. 'errorTipField' => 'USER_NAME',
  267. 'excelTableClass' => ExcelChangeBalance::class,
  268. 'excelTableField' => [
  269. '序号' => 'SORT',
  270. '会员编号' => 'USER_NAME',
  271. '会员姓名' => 'REAL_NAME',
  272. '账户类型' => 'TYPE',
  273. '交易类型' => 'DEAL_TYPE',
  274. '调整金额' => 'AMOUNT',
  275. '备注' => 'REMARK',
  276. '备注是否前台显示' => 'REMARK_IS_SHOW',
  277. ],
  278. 'formField' => [
  279. 'USER_NAME' => [
  280. 'name' => 'userName',
  281. 'type' => 'common',
  282. ],
  283. 'REAL_NAME' => [
  284. 'name' => 'realName',
  285. 'type' => 'common',
  286. ],
  287. 'TYPE' => [
  288. 'name' => 'type',
  289. 'type' => 'param',
  290. 'index' => 'bonusWalletType',
  291. ],
  292. 'DEAL_TYPE' => [
  293. 'name' => 'dealType',
  294. 'type' => 'table',
  295. 'db' => 'db',
  296. 'table' => 'DEAL_TYPE',
  297. 'field' => 'TYPE_NAME',
  298. 'select' => 'ID',
  299. ],
  300. 'AMOUNT' => [
  301. 'name' => 'amount',
  302. 'type' => 'common',
  303. ],
  304. 'REMARK' => [
  305. 'name' => 'remark',
  306. 'type' => 'common',
  307. ],
  308. 'REMARK_IS_SHOW' => [
  309. 'name' => 'isShow',
  310. 'type' => 'bool',
  311. ],
  312. ]
  313. ],
  314. 'regInfo' => [
  315. 'formClass' => RegInfoAuditForm::class,
  316. 'formScenario' => 'excelAdd',
  317. 'formAction' => 'excelAdd',
  318. 'errorTipField' => 'USER_NAME',
  319. 'excelTableClass' => ExcelRegInfo::class,
  320. 'excelTableField' => [
  321. '序号' => 'SORT',
  322. '会员编号' => 'USER_NAME',
  323. '会员姓名' => 'REAL_NAME',
  324. '身份证' => 'ID_CARD',
  325. '注册类型' => 'REG_TYPE',
  326. '注册名称' => 'REG_NAME',
  327. '统一社会信用代码' => 'CREDIT_CODE',
  328. '经营场所' => 'PREMISES',
  329. '注册有效期' => 'REG_EXPIRES',
  330. '法人' => 'LEGAL_PERSON',
  331. '企业开户名称' => 'OPEN_NAME',
  332. '企业开户银行' => 'OPEN_BANK',
  333. '企业开户行地址' => 'BANK_ADDRESS',
  334. '企业银行账号' => 'BANK_NO',
  335. '企业银行 省/市' => 'BANK_PROVINCE',
  336. '企业银行 市/区' => 'BANK_CITY',
  337. '企业银行 区/县' => 'BANK_COUNTY',
  338. '备注' => 'REMARK',
  339. ],
  340. 'formField' => [
  341. 'USER_NAME' => [
  342. 'name' => 'userName',
  343. 'type' => 'common',
  344. ],
  345. 'REAL_NAME' => [
  346. 'name' => 'realName',
  347. 'type' => 'common',
  348. ],
  349. 'ID_CARD' => [
  350. 'name' => 'idCard',
  351. 'type' => 'common',
  352. ],
  353. 'REG_TYPE' => [
  354. 'name' => 'type',
  355. 'type' => 'table',
  356. 'db' => 'db',
  357. 'table' => 'REG_TYPE',
  358. 'field' => 'TYPE_NAME',
  359. 'select' => 'ID',
  360. ],
  361. 'REG_NAME' => [
  362. 'name' => 'regName',
  363. 'type' => 'common',
  364. ],
  365. 'CREDIT_CODE' => [
  366. 'name' => 'creditCode',
  367. 'type' => 'common',
  368. ],
  369. 'PREMISES' => [
  370. 'name' => 'premises',
  371. 'type' => 'common',
  372. ],
  373. 'REG_EXPIRES' => [
  374. 'name' => 'regExpires',
  375. 'type' => 'common',
  376. ],
  377. 'LEGAL_PERSON' => [
  378. 'name' => 'legalPerson',
  379. 'type' => 'common',
  380. ],
  381. 'OPEN_NAME' => [
  382. 'name' => 'openName',
  383. 'type' => 'common',
  384. ],
  385. 'OPEN_BANK' => [
  386. 'name' => 'openBank',
  387. 'type' => 'table',
  388. 'table' => 'OPEN_BANK',
  389. 'field' => 'BANK_NAME',
  390. 'select' => 'BANK_CODE',
  391. 'isAllowNull' => true,
  392. ],
  393. 'BANK_ADDRESS' => [
  394. 'name' => 'bankAddress',
  395. 'type' => 'common',
  396. 'isAllowNull' => true,
  397. ],
  398. 'BANK_NO' => [
  399. 'name' => 'bankNo',
  400. 'type' => 'common',
  401. 'isAllowNull' => true,
  402. ],
  403. 'BANK_PROVINCE' => [
  404. 'name' => 'bankAreaSelected',
  405. 'isArray' => true,
  406. 'type' => 'table',
  407. 'table' => 'REGION',
  408. 'field' => 'REGION_NAME',
  409. 'where' => 'DEEP=2',
  410. 'select' => 'REGION_CODE',
  411. 'isAllowNull' => true,
  412. ],
  413. 'BANK_CITY' => [
  414. 'name' => 'bankAreaSelected',
  415. 'isArray' => true,
  416. 'type' => 'table',
  417. 'table' => 'REGION',
  418. 'field' => 'REGION_NAME',
  419. 'where' => 'DEEP=3',
  420. 'select' => 'REGION_CODE',
  421. 'isAllowNull' => true,
  422. ],
  423. 'BANK_COUNTY' => [
  424. 'name' => 'bankAreaSelected',
  425. 'isArray' => true,
  426. 'type' => 'table',
  427. 'table' => 'REGION',
  428. 'field' => 'REGION_NAME',
  429. 'where' => 'DEEP=4',
  430. 'select' => 'REGION_CODE',
  431. 'isAllowNull' => true,
  432. ],
  433. 'REMARK' => [
  434. 'name' => 'createRemark',
  435. 'type' => 'common',
  436. ],
  437. ]
  438. ],
  439. 'orderShop' => [
  440. 'excelTableClass' => ExcelOrderShopForm::class,
  441. 'excelTableAction' => 'run',
  442. ],
  443. 'orderDec' => [
  444. 'excelTableClass' => ExcelOrderDecForm::class,
  445. 'excelTableAction' => 'run',
  446. ],
  447. 'orderShopStandard' => [
  448. 'excelTableClass' => ExcelOrderStandardForm::class,
  449. 'excelTableAction' => 'run',
  450. ],
  451. ];
  452. public function init() {
  453. parent::init();
  454. $this->isRemote = \Yii::$app->params['isRemoteUpload'];
  455. }
  456. /**
  457. * 加入错误错误
  458. * @param $attr
  459. * @param $error
  460. */
  461. public function addError($attr, $error) {
  462. $this->_errors[$attr][] = $error;
  463. }
  464. /**
  465. * 获取错误信息
  466. * @return array
  467. */
  468. public function getErrors() {
  469. return $this->_errors;
  470. }
  471. /**
  472. * 导出到文件
  473. * @param $exportId
  474. * @param array $dataArr
  475. * @param array $columns
  476. * @param $fileName
  477. * @param callable|null $callBack
  478. * @return bool
  479. */
  480. public function exportToFile($exportId, array $dataArr, array $columns, $fileName, callable $callBack = null) {
  481. $result = true;
  482. $headers = $columns;
  483. $columns = array_keys($columns);
  484. $fileName = $fileName . '_export_' . date('YmdHis') . uniqid() . '.xlsx';
  485. $path = \Yii::getAlias('@common/runtime/' . self::CHILD_PATH . '/');
  486. if (!is_dir($path)) {
  487. mkdir($path, 0755);
  488. }
  489. try {
  490. \sunmoon\phpspreadsheet\Excel::export([
  491. 'models' => $dataArr,
  492. 'columns' => $columns,
  493. 'headers' => $headers,
  494. 'savePath' => $path,
  495. 'asAttachment' => false,
  496. 'format' => 'Xlsx',
  497. 'fileName' => $fileName,
  498. 'exit' => false,
  499. 'exportIterationCallback' => $callBack,
  500. ]);
  501. // 把导出的文件上传至静态文件服务器
  502. if ($this->isRemote) {
  503. $remoteUploadApi = RemoteUploadApi::instance();
  504. if ($uploadResult = $remoteUploadApi->upload($path . $fileName)) {
  505. $this->exportInfo = [
  506. 'fileName' => $uploadResult['name'],
  507. 'url' => $uploadResult['url'],
  508. 'fileSize' => $uploadResult['size'] ?? null,
  509. 'md5' => $uploadResult['md5'] ?? null,
  510. ];
  511. } else {
  512. throw new Exception('文件远程上传失败');
  513. }
  514. // 删除本地临时文件
  515. unlink($path . $fileName);
  516. } else {
  517. $this->exportInfo = [
  518. 'fileName' => $fileName,
  519. 'url' => $path . $fileName,
  520. 'fileSize' => null,
  521. 'md5' => null,
  522. ];
  523. }
  524. // 把文件对应的相关资料存入数据库中
  525. $uploads = new ExportFile();
  526. $uploads->FILE_NAME = $this->exportInfo['fileName'];
  527. $uploads->EXPORT_ID = $exportId;
  528. $uploads->URL = $this->exportInfo['url'];
  529. $uploads->FILE_SIZE = $this->exportInfo['fileSize'] ?? null;
  530. $uploads->MD5 = $this->exportInfo['md5'] ?? null;
  531. $uploads->CREATED_AT = Date::nowTime();
  532. if (!$uploads->save()) {
  533. throw new Exception(Form::formatErrorsForApi($uploads->getErrors()));
  534. }
  535. } catch (\Exception $e) {
  536. $this->addError('export', $e->getMessage());
  537. $result = false;
  538. }
  539. return $result;
  540. }
  541. /**
  542. * 过滤读取到的数据把空的未填写的行都删掉
  543. * @param $data
  544. * @return mixed
  545. */
  546. public static function filterData(&$data) {
  547. foreach ($data as $key => $value) {
  548. $isAllNull = true;
  549. foreach ($value as $k => $v) {
  550. if ($v !== null) {
  551. $isAllNull = false;
  552. }
  553. }
  554. if ($isAllNull) {
  555. unset($data[$key]);
  556. }
  557. }
  558. return $data;
  559. }
  560. /**
  561. * 分页导入数据
  562. * @param $excelStructureKey
  563. * @param $excelImportId
  564. * @param int $rowCount
  565. * @param int $startRow
  566. * @param int $limit
  567. * @return int
  568. * @throws Exception
  569. */
  570. public function pageImportDataFromExcel($excelStructureKey, $excelImportId, $rowCount = 1000, $startRow = 1, $limit = 1000) {
  571. if ($startRow > 1) {
  572. $startRow = $startRow + 1;
  573. $limit = $limit - 1;
  574. }
  575. $fileNameArray = ExcelImport::find()->select('U.FILE_NAME')->from(ExcelImport::tableName() . ' AS ET')->join('LEFT JOIN', Uploads::tableName() . ' AS U', 'ET.UPLOAD_ID=U.ID')->where('ET.ID=:ID', [':ID' => $excelImportId])->asArray()->one();
  576. $filePath = \Yii::getAlias('@common/runtime/uploads/' . $fileNameArray['FILE_NAME']);
  577. if ($startRow > $rowCount) {
  578. return 0;
  579. }
  580. try {
  581. // 临时文件不存在则创建
  582. $tempFileName = \Yii::getAlias('@common/runtime/uploads/' . 'importTemp.txt');
  583. if (!file_exists($tempFileName)) {
  584. $fp = fopen($tempFileName, 'w+');
  585. fclose($fp);
  586. } else {
  587. if ($startRow == 1) {
  588. file_put_contents($tempFileName, '');
  589. }
  590. }
  591. $data = \sunmoon\phpspreadsheet\Excel::import($filePath, [
  592. 'setFirstRecordAsKeys' => true,
  593. 'readStartRow' => $startRow,
  594. 'readEndRow' => $startRow + $limit,
  595. 'storeFile' => $tempFileName,
  596. 'dropKeysRow' => $startRow == 1 ? false : true,
  597. ]);
  598. } catch (\Exception $e) {
  599. throw new Exception($e->getMessage());
  600. }
  601. self::filterData($data);
  602. if ($data) {
  603. // if($startRow != 1){
  604. // unset($data[0]);
  605. // }
  606. // if(!$data) return 0;
  607. // self::filterData($data);
  608. $this->importDataToExcelTable($excelStructureKey, $excelImportId, $data);
  609. return 1;
  610. } else {
  611. return 0;
  612. }
  613. }
  614. /**
  615. * Excel数据导入到待导入的表中
  616. * @param $excelStructureKey
  617. * @param $excelImportId
  618. * @param $excelData
  619. */
  620. public function importDataToExcelTable($excelStructureKey, $excelImportId, $excelData) {
  621. $tableClass = self::EXCEL_STRUCTURE[$excelStructureKey]['excelTableClass'];
  622. $tableIndex = self::EXCEL_STRUCTURE[$excelStructureKey]['excelTableField'];
  623. $insertData = [];
  624. foreach ($excelData as $data) {
  625. $oneInsertData = [
  626. 'EXCEL_IMPORT_ID' => $excelImportId,
  627. 'CREATED_AT' => Date::nowTime(),
  628. ];
  629. foreach ($data as $key => $value) {
  630. $oneInsertData[$tableIndex[$key]] = $value;
  631. }
  632. $insertData[] = $oneInsertData;
  633. }
  634. $tableClass::batchInsert($insertData);
  635. }
  636. /**
  637. * 分页从待导入表中导入数据到真实数据中
  638. * @param $excelStructureKey
  639. * @param $excelImportId
  640. * @param int $offset
  641. * @param int $limit
  642. * @return int
  643. * @throws Exception
  644. */
  645. public function pageImportDataFromExcelTable($excelStructureKey, $excelImportId, $offset = 0, $limit = 1000) {
  646. $tableClass = self::EXCEL_STRUCTURE[$excelStructureKey]['excelTableClass'];
  647. // 获取1000条数据
  648. $allData = $tableClass::find()->where('EXCEL_IMPORT_ID=:EXCEL_IMPORT_ID', [':EXCEL_IMPORT_ID' => $excelImportId])->orderBy('SORT ASC')->offset($offset)->limit($limit)->asArray()->all();
  649. if ($allData) {
  650. $this->importToDbWithForm($excelStructureKey, $allData);
  651. return 1;
  652. }
  653. return 0;
  654. }
  655. /**
  656. * 通过表单类导入
  657. * @param $excelStructureKey
  658. * @param $excelDatas
  659. * @throws Exception
  660. */
  661. public function importToDbWithForm($excelStructureKey, $excelDatas) {
  662. foreach ($excelDatas as $value) {
  663. $formClassName = self::EXCEL_STRUCTURE[$excelStructureKey]['formClass'];
  664. $formScenario = self::EXCEL_STRUCTURE[$excelStructureKey]['formScenario'];
  665. $formAction = self::EXCEL_STRUCTURE[$excelStructureKey]['formAction'];
  666. $formData = $this->excelDataToFormData($excelStructureKey, $value);
  667. if ($formData) {
  668. $form = new $formClassName();
  669. $form->scenario = $formScenario;
  670. foreach ($formData as $formKey => $formValue) {
  671. $form->$formKey = $formValue;
  672. }
  673. $errorTipField = self::EXCEL_STRUCTURE[$excelStructureKey]['errorTipField'];
  674. $tableClass = self::EXCEL_STRUCTURE[$excelStructureKey]['excelTableClass'];
  675. if (!$form->$formAction()) {
  676. // 失败信息写入到待导入数据库excel表中
  677. $tableClass::updateAll(['STATUS' => 2, 'ERROR_REMARK' => Form::formatErrorsForApi($form->getErrors())], 'ID=:ID', [':ID' => $value['ID']]);
  678. throw new Exception('错误序号【'.$value['SORT'].'】会员编号【'.$value['USER_NAME'].'】。导入' . $value[$errorTipField] . '发生错误,原因:' . Form::formatErrorsForApi($form->getErrors()));
  679. } else {
  680. $tableClass::updateAll(['STATUS' => 1], 'ID=:ID', [':ID' => $value['ID']]);
  681. }
  682. }
  683. }
  684. }
  685. /**
  686. * excel数据转为表单可提交的数据
  687. * @param $excelStructureKey
  688. * @param $excelData
  689. * @return array
  690. * @throws Exception
  691. */
  692. public function excelDataToFormData($excelStructureKey, $excelData) {
  693. $formFieldArr = self::EXCEL_STRUCTURE[$excelStructureKey]['formField'];
  694. $excelTableField = self::EXCEL_STRUCTURE[$excelStructureKey]['excelTableField'];
  695. $sort = $excelData['SORT'];
  696. $result = [];
  697. foreach ($excelData as $key => $value) {
  698. if (in_array($key, ['ID', 'EXCEL_IMPORT_ID', 'STATUS', 'ERROR_REMARK', 'CREATED_AT', 'SORT', 'ROWNUMID'])) continue;
  699. if (!array_key_exists($key, $formFieldArr)) {
  700. throw new Exception('excel表格字段不符合要求,字段为:' . $key);
  701. }
  702. $resultKey = $formFieldArr[$key]['name'];
  703. // 这里要判断是否允许为空值,如果允许则可以直接付空值
  704. if (isset($formFieldArr[$key]['isAllowNull']) && $formFieldArr[$key]['isAllowNull'] && $value === null) {
  705. $result[$resultKey] = $value;
  706. } elseif ($formFieldArr[$key]['type'] === 'common') {
  707. $result[$resultKey] = $value;
  708. } elseif ($formFieldArr[$key]['type'] === 'bool') {
  709. $result[$resultKey] = intval($value == '是');
  710. } elseif ($formFieldArr[$key]['type'] === 'int') {
  711. $result[$resultKey] = intval($value);
  712. } elseif ($formFieldArr[$key]['type'] === 'param') {
  713. // 从param的数据中获取
  714. $tempArray = \Yii::$app->params[$formFieldArr[$key]['index']];
  715. if ($formFieldArr[$key]['name'] === 'nation') {
  716. array_unshift($tempArray, [
  717. 'id' => '0',
  718. 'name' => '',
  719. ]);
  720. $nationsArray = array_column($tempArray, 'name');
  721. $tempResultIndex = array_search($value, $nationsArray);
  722. if ($tempResultIndex === false){
  723. if($errTableField = array_search($key, $excelTableField)){
  724. throw new Exception('序号' . $sort . '的表格【' . $errTableField . '】值填写有误,系统中未找到填写的"' . $value . '"');
  725. }else{
  726. throw new Exception('序号' . $sort . '的表格' . $key . '值填写有误,系统中未找到"' . $value . '"');
  727. }
  728. }
  729. $result[$resultKey] = $tempArray[$tempResultIndex]['id'];
  730. } elseif ($formFieldArr[$key]['index'] === 'bonusWalletType') {
  731. $nationsArray = array_column($tempArray, 'name');
  732. $tempResultIndex = array_search($value, $nationsArray);
  733. if ($tempResultIndex === false){
  734. if($errTableField = array_search($key, $excelTableField)){
  735. throw new Exception('序号' . $sort . '的表格【' . $errTableField . '】值填写有误,系统中未找到填写的"' . $value . '"');
  736. }else{
  737. throw new Exception('序号' . $sort . '的表格' . $key . '值填写有误,系统中未找到"' . $value . '"');
  738. }
  739. }
  740. $result[$resultKey] = $nationsArray[$tempResultIndex];
  741. }
  742. } elseif ($formFieldArr[$key]['type'] === 'table') {
  743. // 从数据库中获取对应的参数值
  744. $db = $formFieldArr[$key]['db'] ?? 'db';
  745. $field = $formFieldArr[$key]['field'];
  746. $select = $formFieldArr[$key]['select'];
  747. $table = $formFieldArr[$key]['table'];
  748. $where = $field . '=:' . $field;
  749. $where .= (isset($formFieldArr[$key]['where']) && $formFieldArr[$key]['where']) ? ' AND ' . $formFieldArr[$key]['where'] : '';
  750. $bindValues = [$field => $value];
  751. $tempResult = \Yii::$app->$db->createCommand("SELECT $select FROM {{%$table}} WHERE $where")->bindValues($bindValues)->queryOne();
  752. if (!$tempResult){
  753. if($errTableField = array_search($key, $excelTableField)){
  754. throw new Exception('序号' . $sort . '的表格【' . $errTableField . '】值填写有误,系统中未找到填写的"' . $value . '"');
  755. }else{
  756. throw new Exception('序号' . $sort . '的表格' . $key . '值填写有误,系统中未找到"' . $value . '"');
  757. }
  758. }
  759. if (isset($formFieldArr[$key]['isArray']) && $formFieldArr[$key]['isArray']) {
  760. $result[$resultKey][] = $tempResult[$select];
  761. } else {
  762. $result[$resultKey] = $tempResult[$select];
  763. }
  764. }
  765. }
  766. return $result;
  767. }
  768. /**
  769. * 分页导入数据
  770. * @param $excelStructureKey
  771. * @param $excelImportId
  772. * @param int $rowCount
  773. * @param int $startRow
  774. * @param int $limit
  775. * @param int $orderDay
  776. * @param int $orderType
  777. * @return int
  778. * @throws Exception
  779. */
  780. public function pageImportCustomDataFromExcel($excelStructureKey, $excelImportId, $rowCount, $startRow, $limit, $orderDay, $orderType = 'cash') {
  781. if ($startRow > 1) {
  782. $startRow = $startRow + 1;
  783. $limit = $limit - 1;
  784. }
  785. $fileNameArray = ExcelImport::find()->select('U.FILE_NAME')->from(ExcelImport::tableName() . ' AS ET')->join('LEFT JOIN', Uploads::tableName() . ' AS U', 'ET.UPLOAD_ID=U.ID')->where('ET.ID=:ID', [':ID' => $excelImportId])->asArray()->one();
  786. // $filePath = \Yii::getAlias('@common/runtime/uploads/' . $fileNameArray['FILE_NAME']);
  787. $filePath = '/Volumes/HDD/workshop/old/ar.upload.ming/files/' . $fileNameArray['FILE_NAME'];
  788. if ($startRow > $rowCount) {
  789. return 0;
  790. }
  791. try {
  792. // 临时文件不存在则创建
  793. $tempFileName = \Yii::getAlias('@common/runtime/uploads/' . 'import'.$excelStructureKey.'Temp.txt');
  794. if (!file_exists($tempFileName)) {
  795. $fp = fopen($tempFileName, 'w+');
  796. fclose($fp);
  797. } else {
  798. if ($startRow == 1) {
  799. file_put_contents($tempFileName, '');
  800. }
  801. }
  802. $data = \sunmoon\phpspreadsheet\Excel::import($filePath, [
  803. 'setFirstRecordAsKeys' => true,
  804. 'readStartRow' => $startRow,
  805. 'readEndRow' => $startRow + $limit,
  806. 'storeFile' => $tempFileName,
  807. 'dropKeysRow' => $startRow == 1 ? false : true,
  808. ]);
  809. $errUserArray = [];
  810. foreach ($data as $u){ // 记录了导入中不存在的会员
  811. $u['USER_NAME'] = trim($u['会员编号']);
  812. if(!$u['USER_NAME']){
  813. continue;
  814. }
  815. $userInfo = User::checkUser($u['USER_NAME']);
  816. if(!$userInfo){
  817. $errUserArray[] = $u['USER_NAME'];
  818. }
  819. }
  820. if(count($errUserArray)>0){
  821. $errUserStr = implode(', ', $errUserArray);
  822. throw new Exception(count($errUserArray).'个用户不存在:'.substr($errUserStr,0, 600).'...');
  823. }
  824. } catch (\Exception $e) {
  825. throw new Exception($e->getMessage());
  826. }
  827. self::filterData($data);
  828. if ($data) {
  829. $tableClass = self::EXCEL_STRUCTURE[$excelStructureKey]['excelTableClass'];
  830. $tableAction = self::EXCEL_STRUCTURE[$excelStructureKey]['excelTableAction'];
  831. $form = new $tableClass();
  832. if (!$form->$tableAction($data,$orderDay,$orderType)) {
  833. return 0;
  834. }
  835. return 1;
  836. } else {
  837. return 0;
  838. }
  839. }
  840. /**
  841. * 分页导入数据
  842. * @param string $fileName
  843. * @param int $rowCount
  844. * @param int $startRow
  845. * @param int $limit
  846. * @return array
  847. * @throws Exception
  848. */
  849. public function pageImportDataByExcelFile($fileName, $rowCount = 1000, $startRow = 1, $limit = 1000) {
  850. if ($startRow > 1) {
  851. $startRow = $startRow + 1;
  852. $limit = $limit - 1;
  853. }
  854. $filePath = \Yii::getAlias('@common/runtime/uploads/' . $fileName);
  855. if ($startRow > $rowCount) {
  856. return [];
  857. }
  858. try {
  859. // 临时文件不存在则创建
  860. $tempFileName = \Yii::getAlias('@common/runtime/uploads/' . 'importTemp.txt');
  861. if (!file_exists($tempFileName)) {
  862. $fp = fopen($tempFileName, 'w+');
  863. fclose($fp);
  864. } else {
  865. if ($startRow == 1) {
  866. file_put_contents($tempFileName, '');
  867. }
  868. }
  869. $data = \sunmoon\phpspreadsheet\Excel::import($filePath, [
  870. 'setFirstRecordAsKeys' => true,
  871. 'readStartRow' => $startRow,
  872. 'readEndRow' => $startRow + $limit,
  873. 'storeFile' => $tempFileName,
  874. 'dropKeysRow' => $startRow == 1 ? false : true,
  875. ]);
  876. } catch (\Exception $e) {
  877. throw new Exception($e->getMessage());
  878. }
  879. self::filterData($data);
  880. if ($data) {
  881. return $data;
  882. } else {
  883. return [];
  884. }
  885. }
  886. }