region.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. <template>
  2. <el-row>
  3. <el-col :span="9">
  4. <div class="box">
  5. <el-scrollbar>
  6. <basic-container>
  7. <avue-tree :option="treeOption" :data="treeData" @node-click="nodeClick"/>
  8. </basic-container>
  9. </el-scrollbar>
  10. </div>
  11. </el-col>
  12. <el-col :span="15">
  13. <basic-container>
  14. <el-button-group>
  15. <el-button v-if="permission.region_add" type="primary" size="small" icon="el-icon-circle-plus-outline" @click="addChildren">新增下级</el-button>
  16. <el-button v-if="permission.region_delete" type="primary" size="small" icon="el-icon-delete" @click="handleDelete">删除</el-button>
  17. <el-button v-if="permission.region_import" type="primary" size="small" icon="el-icon-upload2" @click="handleImport">导入</el-button>
  18. <el-button v-if="permission.region_export" type="primary" size="small" icon="el-icon-download" @click="handleExport">导出</el-button>
  19. <el-button v-if="permission.region_debug" type="primary" size="small" icon="el-icon-video-play" @click="handleDebug">调试</el-button>
  20. </el-button-group>
  21. </basic-container>
  22. <basic-container>
  23. <avue-form ref="form" :option="regionOption" v-model="regionForm" @submit="handleSubmit">
  24. <template slot="code" slot-scope="{}">
  25. <el-input placeholder="请输入 区划子编号" v-model="regionForm.subCode">
  26. <template slot="prepend">{{regionForm.parentCode}}</template>
  27. </el-input>
  28. </template>
  29. </avue-form>
  30. <el-dialog title="行政区划数据导入"
  31. append-to-body
  32. :visible.sync="excelBox"
  33. :close-on-click-modal="false"
  34. width="555px">
  35. <avue-form :option="excelOption" v-model="excelForm" :upload-after="uploadAfter">
  36. <template slot="excelTemplate">
  37. <el-button type="primary" @click="handleTemplate">
  38. 点击下载<i class="el-icon-download el-icon--right"></i>
  39. </el-button>
  40. </template>
  41. </avue-form>
  42. </el-dialog>
  43. <el-dialog title="行政区划数据调试"
  44. append-to-body
  45. :visible.sync="debugBox"
  46. :close-on-click-modal="false"
  47. width="350px">
  48. <avue-form :option="debugOption" v-model="debugForm"/>
  49. </el-dialog>
  50. </basic-container>
  51. </el-col>
  52. </el-row>
  53. </template>
  54. <script>
  55. import {getLazyTree, getDetail, submit, remove} from "@/api/base/region";
  56. import {mapGetters} from "vuex";
  57. import {validatenull} from "@/util/validate";
  58. import {getToken} from "@/util/auth";
  59. export default {
  60. data() {
  61. return {
  62. topCode: '00',
  63. treeCode: '',
  64. treeParentCode: '',
  65. treeData: [],
  66. treeOption: {
  67. nodeKey: 'id',
  68. lazy: true,
  69. treeLoad: function (node, resolve) {
  70. const parentCode = (node.level === 0) ? "00" : node.data.id;
  71. getLazyTree(parentCode).then(res => {
  72. resolve(res.data.data.map(item => {
  73. return {
  74. ...item,
  75. leaf: !item.hasChildren
  76. }
  77. }))
  78. });
  79. },
  80. addBtn: false,
  81. menu: false,
  82. size: 'small',
  83. props: {
  84. labelText: '标题',
  85. label: 'title',
  86. value: 'value',
  87. children: 'children'
  88. }
  89. },
  90. regionForm: {},
  91. regionOption: {
  92. labelWidth: 100,
  93. column: [
  94. {
  95. label: "父区划编号",
  96. prop: "parentCode",
  97. span: 24,
  98. disabled: true,
  99. rules: [{
  100. required: true,
  101. message: "请输入父区划编号",
  102. trigger: "blur"
  103. }]
  104. },
  105. {
  106. label: "父区划名称",
  107. prop: "parentName",
  108. span: 24,
  109. disabled: true,
  110. },
  111. {
  112. label: "区划编号",
  113. prop: "code",
  114. formslot: true,
  115. span: 24,
  116. rules: [{
  117. required: true,
  118. message: "请输入区划编号",
  119. trigger: "blur"
  120. }]
  121. },
  122. {
  123. label: "区划子编号",
  124. prop: "subCode",
  125. display: false,
  126. },
  127. {
  128. label: "区划名称",
  129. prop: "name",
  130. span: 24,
  131. rules: [{
  132. required: true,
  133. message: "请输入区划名称",
  134. trigger: "blur"
  135. }]
  136. },
  137. {
  138. label: "区划等级",
  139. prop: "regionLevel",
  140. type: "radio",
  141. dicUrl: "/api/blade-system/dict/dictionary?code=region",
  142. props: {
  143. label: "dictValue",
  144. value: "dictKey"
  145. },
  146. dataType: "number",
  147. span: 24,
  148. rules: [{
  149. required: true,
  150. message: "请选择区划等级",
  151. trigger: "blur"
  152. }]
  153. },
  154. {
  155. label: "区划排序",
  156. prop: "sort",
  157. type: "number",
  158. span: 24,
  159. rules: [{
  160. required: true,
  161. message: "请输入区划排序",
  162. trigger: "blur"
  163. }]
  164. },
  165. {
  166. label: "区划备注",
  167. prop: "remark",
  168. type: "textarea",
  169. minRows: 6,
  170. span: 24,
  171. },
  172. ]
  173. },
  174. excelBox: false,
  175. excelForm: {},
  176. excelOption: {
  177. submitBtn: false,
  178. emptyBtn: false,
  179. column: [
  180. {
  181. label: '模板上传',
  182. prop: 'excelFile',
  183. type: 'upload',
  184. drag: true,
  185. loadText: '模板上传中,请稍等',
  186. span: 24,
  187. propsHttp: {
  188. res: 'data'
  189. },
  190. tip: '请上传 .xls,.xlsx 标准格式文件',
  191. action: "/api/blade-system/region/import-region"
  192. },
  193. {
  194. label: "数据覆盖",
  195. prop: "isCovered",
  196. type: "switch",
  197. align: "center",
  198. width: 80,
  199. dicData: [
  200. {
  201. label: "否",
  202. value: 0
  203. },
  204. {
  205. label: "是",
  206. value: 1
  207. }
  208. ],
  209. value: 0,
  210. slot: true,
  211. rules: [
  212. {
  213. required: true,
  214. message: "请选择是否覆盖",
  215. trigger: "blur"
  216. }
  217. ]
  218. },
  219. {
  220. label: '模板下载',
  221. prop: 'excelTemplate',
  222. formslot: true,
  223. span: 24,
  224. }
  225. ]
  226. },
  227. debugBox: false,
  228. debugForm: {},
  229. debugOption: {
  230. labelWidth: 50,
  231. submitBtn: false,
  232. emptyBtn: false,
  233. column: [
  234. {
  235. label: '省份',
  236. prop: 'province',
  237. type: 'select',
  238. props: {
  239. label: 'name',
  240. value: 'code'
  241. },
  242. cascaderItem: ['city', 'district'],
  243. dicUrl: '/api/blade-system/region/select',
  244. span: 24,
  245. },
  246. {
  247. label: '地市',
  248. prop: 'city',
  249. type: 'select',
  250. props: {
  251. label: 'name',
  252. value: 'code'
  253. },
  254. dicFlag: false,
  255. dicUrl: '/api/blade-system/region/select?code={{key}}',
  256. span: 24,
  257. },
  258. {
  259. label: '区县',
  260. prop: 'district',
  261. type: 'select',
  262. props: {
  263. label: 'name',
  264. value: 'code'
  265. },
  266. dicFlag: false,
  267. dicUrl: '/api/blade-system/region/select?code={{key}}',
  268. span: 24,
  269. }
  270. ]
  271. }
  272. };
  273. },
  274. watch: {
  275. 'regionForm.subCode'() {
  276. this.regionForm.code = this.regionForm.parentCode + this.regionForm.subCode;
  277. },
  278. 'excelForm.isCovered'() {
  279. if (this.excelForm.isCovered !== '') {
  280. const column = this.findObject(this.excelOption.column, "excelFile");
  281. column.action = `/api/blade-system/region/import-region?isCovered=${this.excelForm.isCovered}`;
  282. }
  283. }
  284. },
  285. computed: {
  286. ...mapGetters(["permission"]),
  287. permissionList() {
  288. return {
  289. addBtn: this.vaildData(this.permission.region_add, false),
  290. viewBtn: this.vaildData(this.permission.region_view, false),
  291. delBtn: this.vaildData(this.permission.region_delete, false),
  292. editBtn: this.vaildData(this.permission.region_edit, false)
  293. };
  294. },
  295. ids() {
  296. let ids = [];
  297. this.selectionList.forEach(ele => {
  298. ids.push(ele.id);
  299. });
  300. return ids.join(",");
  301. }
  302. },
  303. methods: {
  304. initTree() {
  305. this.treeData = [];
  306. getLazyTree(this.topCode).then(res => {
  307. this.treeData = res.data.data.map(item => {
  308. return {
  309. ...item,
  310. leaf: !item.hasChildren
  311. }
  312. })
  313. });
  314. },
  315. nodeClick(data) {
  316. const column = this.findObject(this.regionOption.column, "parentCode");
  317. column.disabled = true;
  318. this.treeCode = data.id;
  319. this.treeParentCode = data.parentId;
  320. getDetail(this.treeCode).then(res => {
  321. this.regionForm = res.data.data;
  322. this.regionForm.subCode = this.regionForm.code.replace(this.regionForm.parentCode, '');
  323. })
  324. },
  325. addChildren() {
  326. if (validatenull(this.regionForm.code) || validatenull(this.regionForm.name)) {
  327. this.$message.warning("请先选择一项区划");
  328. return;
  329. }
  330. this.regionForm.parentCode = this.regionForm.code;
  331. this.regionForm.parentName = this.regionForm.name;
  332. this.regionForm.code = '';
  333. this.regionForm.subCode = '';
  334. this.regionForm.name = '';
  335. this.regionForm.regionLevel = (this.regionForm.regionLevel === 5) ? 5 : this.regionForm.regionLevel + 1;
  336. },
  337. handleSubmit(form, done, loading) {
  338. const parentCode = form.parentCode === this.topCode ? '' : form.parentCode;
  339. form.code = parentCode + form.subCode;
  340. submit(form).then(() => {
  341. this.$message({
  342. type: "success",
  343. message: "操作成功!"
  344. });
  345. this.initTree();
  346. this.regionForm.subCode = '';
  347. this.$refs.form.resetForm();
  348. done();
  349. }, error => {
  350. loading();
  351. window.console.log(error);
  352. });
  353. },
  354. handleDelete() {
  355. if (validatenull(this.regionForm.code)) {
  356. this.$message.warning("请先选择一项区划");
  357. return;
  358. }
  359. this.$confirm(`确定将 [${this.regionForm.name}] 数据删除?`, {
  360. confirmButtonText: "确定",
  361. cancelButtonText: "取消",
  362. type: "warning"
  363. })
  364. .then(() => {
  365. return remove(this.treeCode);
  366. })
  367. .then(() => {
  368. this.$message({
  369. type: "success",
  370. message: "操作成功!"
  371. });
  372. this.initTree();
  373. this.regionForm.subCode = '';
  374. this.$refs.form.resetForm();
  375. });
  376. },
  377. uploadAfter(res, done, loading, column) {
  378. window.console.log(column);
  379. this.excelBox = false;
  380. this.initTree();
  381. done();
  382. },
  383. handleDebug() {
  384. this.debugBox = true;
  385. },
  386. handleImport() {
  387. this.excelBox = true;
  388. },
  389. handleExport() {
  390. this.$confirm("是否导出行政区划数据?", "提示", {
  391. confirmButtonText: "确定",
  392. cancelButtonText: "取消",
  393. type: "warning"
  394. }).then(() => {
  395. window.open(`/api/blade-system/region/export-region?${this.website.tokenHeader}=${getToken()}`);
  396. });
  397. },
  398. handleTemplate() {
  399. window.open(`/api/blade-system/region/export-template?${this.website.tokenHeader}=${getToken()}`);
  400. },
  401. }
  402. };
  403. </script>
  404. <style>
  405. .box {
  406. height: 800px;
  407. }
  408. .el-scrollbar {
  409. height: 100%;
  410. }
  411. .box .el-scrollbar__wrap {
  412. overflow: scroll;
  413. }
  414. </style>