ExcelQualityInspection.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. <template>
  2. <el-container>
  3. <el-row class="header">
  4. <el-button type="primary" @click="addRules"
  5. >增加数据完整性检查项</el-button
  6. >
  7. </el-row>
  8. <div class="ruleContent" ref="ruleContent">
  9. <el-table
  10. ref="multipleTable"
  11. :data="checkDetail"
  12. border
  13. :max-height="tableMaxHeight"
  14. style="width: 100%"
  15. >
  16. <el-table-column type="index" label="序号" width="50" align="center">
  17. </el-table-column>
  18. <el-table-column
  19. prop="name"
  20. label="是否检查"
  21. width="160"
  22. align="center"
  23. >
  24. <template slot-scope="scope">
  25. <el-radio v-model="scope.row.isCheck" :label="1">是</el-radio>
  26. <el-radio v-model="scope.row.isCheck" :label="0">否</el-radio>
  27. </template>
  28. </el-table-column>
  29. <el-table-column
  30. prop="checkContent"
  31. label="检查项"
  32. width="180"
  33. align="center"
  34. >
  35. <template slot-scope="scope">
  36. <!-- <div class="morerow" v-if="scope.row.children != undefined">
  37. <el-row v-for="(item, index) in scope.row.children" :key="index">
  38. <span> {{ item.checkContent }} </span>
  39. </el-row>
  40. </div>
  41. <span v-else> {{ scope.row.checkContent }} </span> -->
  42. <span> {{ scope.row.checkContent }} </span>
  43. </template>
  44. </el-table-column>
  45. <el-table-column prop="checkDescribe" label="描述" align="center">
  46. <template slot-scope="scope">
  47. <div class="morerow" v-if="scope.row.children != undefined">
  48. <el-row v-for="(item, index) in scope.row.children" :key="index">
  49. <span> {{ item.checkDescribe }} </span>
  50. </el-row>
  51. </div>
  52. <span v-else> {{ scope.row.checkDescribe }} </span>
  53. </template>
  54. </el-table-column>
  55. <el-table-column
  56. prop="fieldName"
  57. label="字段名称"
  58. width="200"
  59. align="center"
  60. >
  61. <template slot-scope="scope">
  62. <div class="morerow" v-if="scope.row.children != undefined">
  63. <el-row v-for="(item, index) in scope.row.children" :key="index">
  64. <el-input v-model="item.fieldName"></el-input>
  65. </el-row>
  66. </div>
  67. <el-input v-else v-model="scope.row.fieldName"></el-input>
  68. </template>
  69. </el-table-column>
  70. <el-table-column label="操作" width="50" align="center">
  71. <template slot-scope="scope">
  72. <el-popover
  73. v-if="scope.row.type == 'dataIntegrality'"
  74. placement="top-end"
  75. width="160"
  76. trigger="hover"
  77. :ref="`popover-${scope.$index}`"
  78. >
  79. <p style="padding: 10px 0">确定要删除此检查项吗?</p>
  80. <div style="text-align: right; margin: 0">
  81. <el-button
  82. size="mini"
  83. type="text"
  84. @click="
  85. scope._self.$refs[`popover-${scope.$index}`].doClose()
  86. "
  87. >
  88. 取消
  89. </el-button>
  90. <el-button
  91. type="primary"
  92. size="mini"
  93. @click="deleteRules(scope.$index, scope.row, scope)"
  94. >
  95. 确定
  96. </el-button>
  97. </div>
  98. <el-button
  99. slot="reference"
  100. icon="el-icon-delete iconfont"
  101. :style="{ color: '#999999' }"
  102. size="mini"
  103. :title="'删除'"
  104. circle
  105. ></el-button>
  106. </el-popover>
  107. </template>
  108. </el-table-column>
  109. </el-table>
  110. </div>
  111. <el-row>
  112. <el-upload
  113. class="uploadbtn"
  114. ref="upload"
  115. accept="csv, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  116. :action="''"
  117. :auto-upload="true"
  118. :show-file-list="false"
  119. :limit="1"
  120. :before-upload="uploadFile"
  121. >
  122. <el-button type="primary" class="add-item" @click="beforeUploadFile">
  123. 上传文件
  124. </el-button>
  125. </el-upload>
  126. </el-row>
  127. </el-container>
  128. </template>
  129. <script>
  130. import qualityApi from "@/api/qualityinspection";
  131. export default {
  132. data() {
  133. return {
  134. tableMaxHeight: 450,
  135. defaultField: {
  136. isCheck: 1,
  137. checkContent: "数据完整性",
  138. checkDescribe:
  139. "检查所填字段数据是否完整(可填写多个字段,会动态扩展行数)",
  140. fieldName: "",
  141. delBtn: true,
  142. type: "dataIntegrality",
  143. },
  144. checkDefaultDetail: [
  145. {
  146. isCheck: 1,
  147. checkContent: "数据完整性",
  148. checkDescribe:
  149. "检查所填字段数据是否完整(可填写多个字段,会动态扩展行数)",
  150. fieldName: "",
  151. delBtn: true,
  152. type: "dataIntegrality",
  153. },
  154. {
  155. isCheck: 1,
  156. checkContent: "省级行政区划编码检查",
  157. checkDescribe: '验证是否是以"13"开头的纯数字的行政区划编码',
  158. fieldName: "",
  159. delBtn: false,
  160. type: "provinceCode",
  161. },
  162. {
  163. isCheck: 1,
  164. checkContent: "市级行政区划编码检查",
  165. checkDescribe: '验证是否是以"13"开头的纯数字且至少4位的行政区划编码',
  166. fieldName: "",
  167. type: "cityCode",
  168. delBtn: false,
  169. },
  170. {
  171. isCheck: 1,
  172. checkContent: "县级行政区划编码检查",
  173. checkDescribe: '验证是否是以"13"开头的纯数字且至少6位的行政区划编码',
  174. fieldName: "",
  175. type: "countyCode",
  176. delBtn: false,
  177. },
  178. {
  179. isCheck: 1,
  180. checkContent: "经纬度验证",
  181. checkDescribe: "经纬度是否在河北省境内",
  182. fieldName: "",
  183. type: "latlon",
  184. delBtn: false,
  185. children: [
  186. {
  187. checkDescribe: "验证所需经度字段名",
  188. fieldName: "",
  189. type: "lon",
  190. delBtn: false,
  191. },
  192. {
  193. checkDescribe: "验证所需纬度字段名",
  194. fieldName: "",
  195. type: "lat",
  196. delBtn: false,
  197. },
  198. ],
  199. },
  200. {
  201. isCheck: 1,
  202. checkContent: "行政区划+经纬度验证",
  203. checkDescribe:
  204. "检查经纬度点位是否在行政区划范围内部,例:经纬度为116.4,39.9的位置是否在石家庄范围内",
  205. fieldName: "",
  206. type: "areaLatlon",
  207. delBtn: false,
  208. children: [
  209. {
  210. checkDescribe: "验证所需行政区划编码字段名",
  211. fieldName: "",
  212. type: "areaCode",
  213. delBtn: false,
  214. },
  215. {
  216. checkDescribe: "验证所需经度字段名",
  217. fieldName: "",
  218. type: "lon",
  219. delBtn: false,
  220. },
  221. {
  222. checkDescribe: "验证所需纬度字段名",
  223. fieldName: "",
  224. type: "lat",
  225. delBtn: false,
  226. },
  227. ],
  228. },
  229. ],
  230. checkDetail: [],
  231. };
  232. },
  233. components: {},
  234. mounted() {
  235. let that = this;
  236. this.checkDetail = JSON.parse(JSON.stringify(this.checkDefaultDetail));
  237. setTimeout(() => {
  238. that.resizeWindowEvent();
  239. }, 100);
  240. },
  241. methods: {
  242. // 重置表格高度
  243. resizeWindowEvent() {
  244. let that = this;
  245. this.tableInterval = setInterval(() => {
  246. if (that.$refs["ruleContent"]) {
  247. that.tableMaxHeight = that.$refs["ruleContent"].clientHeight;
  248. clearInterval(that.tableInterval);
  249. }
  250. }, 100);
  251. window.onresize = () => {
  252. return (() => {
  253. if (that.$refs["ruleContent"])
  254. that.tableMaxHeight = that.$refs["ruleContent"].clientHeight;
  255. })();
  256. };
  257. },
  258. addRules() {
  259. let obj = JSON.parse(JSON.stringify(this.defaultField));
  260. this.checkDetail.unshift(obj);
  261. this.checkDetail = JSON.parse(JSON.stringify(this.checkDetail));
  262. },
  263. deleteRules(index, data, scope) {
  264. scope._self.$refs["popover-" + scope.$index].doClose();
  265. this.checkDetail.splice(index, 1);
  266. },
  267. beforeUploadFile(e) {
  268. let that = this;
  269. if (!jy()) e.stopPropagation();
  270. function jy() {
  271. for (let i = 0; i < that.checkDetail.length; i++) {
  272. let param = that.checkDetail[i];
  273. if (param.isCheck) {
  274. if (!param.children) {
  275. switch (param.type) {
  276. case "dataIntegrality":
  277. if (
  278. that.webMessage(param.fieldName.trim(), param.checkContent)
  279. )
  280. return false;
  281. break;
  282. case "provinceCode":
  283. case "cityCode":
  284. case "countyCode":
  285. if (
  286. that.webMessage(param.fieldName.trim(), param.checkContent)
  287. )
  288. return false;
  289. break;
  290. default:
  291. break;
  292. }
  293. } else {
  294. switch (param.type) {
  295. case "latlon":
  296. let judge1 = that.webMessage(
  297. param.children[0].fieldName.trim(),
  298. param.checkContent
  299. );
  300. if (judge1) return false;
  301. let judge2 = that.webMessage(
  302. param.children[1].fieldName.trim(),
  303. param.checkContent
  304. );
  305. if (judge2) return false;
  306. break;
  307. case "areaLatlon":
  308. let judge3 = that.webMessage(
  309. param.children[0].fieldName.trim(),
  310. param.checkContent
  311. );
  312. if (judge3) return false;
  313. let judge4 = that.webMessage(
  314. param.children[1].fieldName.trim(),
  315. param.checkContent
  316. );
  317. if (judge4) return false;
  318. let judge5 = that.webMessage(
  319. param.children[2].fieldName.trim(),
  320. param.checkContent
  321. );
  322. if (judge5) return false;
  323. break;
  324. default:
  325. break;
  326. }
  327. }
  328. }
  329. }
  330. return true;
  331. }
  332. },
  333. uploadFile(file) {
  334. let that = this;
  335. let obj = new FormData();
  336. let completeArr = [];
  337. for (let i = 0; i < this.checkDetail.length; i++) {
  338. let param = this.checkDetail[i];
  339. if (param.isCheck) {
  340. if (!param.children) {
  341. switch (param.type) {
  342. case "dataIntegrality":
  343. completeArr.push(param.fieldName.trim());
  344. break;
  345. case "provinceCode":
  346. case "cityCode":
  347. case "countyCode":
  348. obj.append(param.type, param.fieldName.trim());
  349. break;
  350. default:
  351. break;
  352. }
  353. } else {
  354. switch (param.type) {
  355. case "latlon":
  356. obj.append(
  357. param.type,
  358. // {
  359. // check: true,
  360. // lonlat: [
  361. // param.children[0].fieldName,
  362. // param.children[1].fieldName,
  363. // ],
  364. // }
  365. [
  366. param.children[0].fieldName.trim(),
  367. param.children[1].fieldName.trim(),
  368. ]
  369. );
  370. break;
  371. case "areaLatlon":
  372. obj.append(param.type, [
  373. param.children[0].fieldName.trim(),
  374. param.children[1].fieldName.trim(),
  375. param.children[2].fieldName.trim(),
  376. ]);
  377. break;
  378. default:
  379. break;
  380. }
  381. }
  382. }
  383. }
  384. if (completeArr.length > 0) {
  385. obj.append("dataIntegrality", completeArr);
  386. }
  387. obj.append("file", file);
  388. const loading = this.$createLoading("数据质检中,请稍后!");
  389. qualityApi
  390. .uploadInspectionFile(obj)
  391. .then((result) => {
  392. loading.close();
  393. if (result.code == 200) {
  394. that
  395. .$confirm(result.content, "质检结果", {
  396. showConfirmButton: false,
  397. cancelButtonText: "关闭",
  398. type: "success",
  399. })
  400. .then(() => {})
  401. .catch(() => {});
  402. } else {
  403. that
  404. .$confirm(result.content, "质检结果", {
  405. showConfirmButton: false,
  406. cancelButtonText: "关闭",
  407. type: "error",
  408. })
  409. .then(() => {})
  410. .catch(() => {});
  411. }
  412. })
  413. .catch((err) => {
  414. loading.close();
  415. that.$message({
  416. type: "error",
  417. message: err,
  418. });
  419. });
  420. return false;
  421. },
  422. webMessage(fieldName, str) {
  423. if (fieldName == "") {
  424. this.$message({
  425. message: "请完善" + str,
  426. type: "warning",
  427. });
  428. return true;
  429. }
  430. return false;
  431. },
  432. },
  433. };
  434. </script>
  435. <style lang="less" scoped>
  436. .el-container {
  437. display: block;
  438. width: 100%;
  439. padding: 10px 20px;
  440. box-sizing: border-box;
  441. background: #ffffff;
  442. overflow: hidden;
  443. overflow-y: auto;
  444. .el-row {
  445. line-height: 40px;
  446. &::before {
  447. display: unset;
  448. }
  449. }
  450. .header {
  451. margin-bottom: 10px;
  452. }
  453. .ruleContent {
  454. height: calc(100% - 110px);
  455. }
  456. .el-table {
  457. /deep/ .el-table--border .el-table__cell:first-child .cell {
  458. padding-left: unset;
  459. }
  460. /deep/ .cell {
  461. padding-left: unset;
  462. padding-right: unset;
  463. }
  464. .el-input {
  465. margin: 0 10px;
  466. width: calc(100% - 20px);
  467. }
  468. .morerow {
  469. .el-row {
  470. padding-bottom: 10px;
  471. border-bottom: 1px solid #eeeeee;
  472. &:last-child {
  473. padding-top: 10px;
  474. padding-bottom: 0px;
  475. border-bottom: 0px;
  476. }
  477. }
  478. }
  479. }
  480. .uploadbtn {
  481. float: right;
  482. margin-top: 10px;
  483. margin-right: 20px;
  484. }
  485. }
  486. </style>