com-district-rule.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. <!--注:本组件仅做省市区选择,返回值仅为选中的省市区数组-->
  2. <template id="com-district-rule">
  3. <div class="com-district">
  4. <el-card v-loading="districtLoading" shadow="never" body-style="padding:0" style="border:0;min-height: 100px;">
  5. <div flex="dir:left box:mean">
  6. <template v-if="list.length > 0">
  7. <el-card style="max-height: 400px;overflow-y: auto;margin-right: 20px;" shadow="never">
  8. <template v-for="(item, index) in list">
  9. <div class="el-checkbox" style="margin: 0 0 20px;display: block"
  10. @click="selectProvince(index)">
  11. <el-checkbox @change="pickerChange(item)"
  12. v-model="item.checked"
  13. :indeterminate="item.isIndeterminate"
  14. :disabled="item.unchecked">
  15. <span style="display: none" class="el-checkbox__label">{{item.name}}</span>
  16. </el-checkbox>
  17. <span class="el-checkbox__label">{{item.name}}
  18. <span class="el_checkbox_select" v-if="getCheckedSelectNum(item.children, 1) > 0"
  19. v-html="'(已选' + getCheckedSelectNum(item.children, 1) + ')'">
  20. </span>
  21. </span>
  22. </div>
  23. </template>
  24. </el-card>
  25. <el-card style="max-height: 400px;overflow-y: auto;margin-right: 20px;" shadow="never"
  26. v-if="list[p_index].children && list[p_index].children.length > 0">
  27. <template v-for="(item, index) in list[p_index].children">
  28. <div class="el-checkbox" @click="c_index = index" style="margin: 0 0 20px;display: block">
  29. <el-checkbox @change="pickerChange(item)"
  30. v-model="item.checked"
  31. :indeterminate="item.isIndeterminate"
  32. :disabled="item.unchecked">
  33. <span style="display: none" class="el-checkbox__label">{{item.name}}</span>
  34. </el-checkbox>
  35. <span class="el-checkbox__label">{{item.name}}
  36. <span class="el_checkbox_select" v-if="getCheckedSelectNum(item.children, 2) > 0"
  37. v-html="'(已选' + getCheckedSelectNum(item.children, 2) + ')'">
  38. </span>
  39. </span>
  40. </div>
  41. </template>
  42. </el-card>
  43. <el-card style="max-height: 400px;overflow-y: auto;margin-right: 20px;" shadow="never"
  44. v-if="list[p_index].children[c_index].children && list[p_index].children[c_index].children.length > 0">
  45. <template v-for="(item, index) in list[p_index].children[c_index].children">
  46. <div class="el-checkbox" @click="d_index = index" style="margin: 0 0 20px;display: block">
  47. <el-checkbox @change="pickerChange(item)"
  48. v-model="item.checked"
  49. :indeterminate="item.isIndeterminate"
  50. :disabled="item.unchecked">
  51. <span style="display: none" class="el-checkbox__label">{{item.name}}</span>
  52. </el-checkbox>
  53. <span class="el-checkbox__label">{{item.name}}</span>
  54. </div>
  55. </template>
  56. </el-card>
  57. <!-- :checked="editIds.indexOf(item.id) > -1"-->
  58. <el-card style="max-height: 400px;overflow-y: auto;margin-right: 20px;" shadow="never"
  59. v-if="level == 4 && list[p_index].children[c_index].children[d_index].children && list[p_index].children[c_index].children[d_index].children.length > 0">
  60. <template v-for="(item, index) in list[p_index].children[c_index].children[d_index].children">
  61. <div class="el-checkbox" @click="t_index = index" style="margin: 0 0 20px;display: block">
  62. <el-checkbox @change="pickerChange(item)"
  63. v-model="item.checked"
  64. :disabled="item.unchecked">
  65. <span style="display: none" class="el-checkbox__label">{{item.name}}</span>
  66. </el-checkbox>
  67. <span class="el-checkbox__label">{{item.name}}</span>
  68. </div>
  69. </template>
  70. </el-card>
  71. </template>
  72. </div>
  73. </el-card>
  74. </div>
  75. </template>
  76. <script>
  77. Vue.component('com-district-rule', {
  78. template: '#com-district-rule',
  79. data: function () {
  80. return {
  81. p_index: 0,
  82. c_index: 0,
  83. d_index: 0,
  84. t_index: 0,
  85. districtLoading: false,
  86. defaultList: [], // 所有省市区
  87. tempList: [],// 已选择待返回的省市区
  88. list: [], // 渲染页面使用省市区列表
  89. isIndeterminateIds: [], //
  90. editIdsChunk: []
  91. }
  92. },
  93. props: {
  94. detail: Array, // 传入的所有省市区数组
  95. edit: Array, // 传入的选中省市区数组
  96. level: Number, // 展示省市区的级数
  97. params: Array, // 传出值
  98. mall_id: Number,
  99. is_area_limit_town: Number,
  100. dialogVisibles:Boolean,
  101. notRule:Array //传入其它不能选择值
  102. },
  103. mounted: function () {
  104. let self = this;
  105. self.districtLoading = true;
  106. request({
  107. params: {
  108. r: 'common/region/list',
  109. level: this.level,
  110. mall_id: this.mall_id,
  111. is_area_limit_town: this.is_area_limit_town
  112. },
  113. method: 'get'
  114. }).then(function (e) {
  115. self.districtLoading = false;
  116. if (e.data.code == 0) {
  117. self.defaultList = e.data.data.list;
  118. self.newList();
  119. } else {
  120. self.$message.error(e.data.msg);
  121. }
  122. }).catch(function (e) {
  123. self.districtLoading = false;
  124. });
  125. },
  126. watch: {
  127. // 监听传入的省市区数组
  128. detail() {
  129. this.newList();
  130. },
  131. edit() {
  132. this.newList();
  133. },
  134. dialogVisibles(newVal) {
  135. if(newVal){
  136. this.resetNewList();
  137. }
  138. }
  139. },
  140. methods: {
  141. // 根据传入数据重新获取省市区列表
  142. newList() {
  143. if (this.editIdsChunk.length === 0) {
  144. this.pushEditIdsChunk(this.edit.map(val => {
  145. return val.id
  146. }))
  147. let defaultList = this.checkList(JSON.parse(JSON.stringify(this.defaultList)), this.edit);
  148. let listP = this.setListUnchecked(defaultList, 1);
  149. let list = this.setListUnchecked(listP, 0);
  150. this.list = JSON.parse(JSON.stringify(list));
  151. }
  152. },
  153. resetNewList() {
  154. this.editIdsChunk = []
  155. if (this.editIdsChunk.length === 0) {
  156. this.pushEditIdsChunk(this.edit.map(val => {
  157. return val.id
  158. }))
  159. let defaultList = this.checkList(JSON.parse(JSON.stringify(this.defaultList)), this.edit);
  160. let listP = this.setListUnchecked(defaultList, 1);
  161. let list = this.setListUnchecked(listP, 0);
  162. this.list = JSON.parse(JSON.stringify(list));
  163. this.selectProvince(0)
  164. }
  165. },
  166. // 判断哪些省市区已经选择
  167. checkList(defaultList, formDetail, edit) {
  168. if (typeof defaultList == 'undefined') {
  169. return [];
  170. }
  171. for (let i in defaultList) {
  172. defaultList[i].checked = false;
  173. defaultList[i].unchecked = false;
  174. defaultList[i].isIndeterminate = false;
  175. if (typeof defaultList[i].children != 'undefined') {
  176. defaultList[i].children = this.checkList(defaultList[i].children, formDetail, edit);
  177. }
  178. if (typeof formDetail != 'undefined') {
  179. for (let j in formDetail) {
  180. if (typeof formDetail[j].children != 'undefined') {
  181. for (let k in formDetail[j].children) {
  182. if (defaultList[i].id == formDetail[j].children[k].id) {
  183. defaultList[i].unchecked = true;
  184. break;
  185. }
  186. }
  187. } else {
  188. if (defaultList[i].id == formDetail[j].id) {
  189. defaultList[i].unchecked = true;
  190. break;
  191. }
  192. }
  193. }
  194. }
  195. if (this.editIdsChunk.length > 0) {
  196. defaultList[i].checked = this.isInEditIdsChunk(defaultList[i].id) > -1
  197. defaultList[i].unchecked = false;
  198. }
  199. }
  200. return defaultList;
  201. },
  202. // 重新赋值已经选择的省市区level == 1父级影响子级||level == 0子级影响父级
  203. setListUnchecked(list, level = 1) {
  204. if (typeof list == 'undefined') {
  205. return list;
  206. }
  207. for (let i in list) {
  208. if (typeof list[i].children != 'undefined') {
  209. if(level == 0) {
  210. list[i].children = this.setListUnchecked(list[i].children, 0);
  211. }
  212. let unchecked = false;
  213. let checkCount = 0;
  214. let isIndeterminateCount = 0;
  215. for (let j in list[i].children) {
  216. if (list[i].unchecked && level == 1) {
  217. list[i].children[j].unchecked = true;
  218. }
  219. if (list[i].children[j].unchecked) {
  220. unchecked = true;
  221. }
  222. if (list[i].checked) {
  223. list[i].children[j].checked = true;
  224. }
  225. if(list[i].children[j].checked) {
  226. checkCount++;
  227. }
  228. if(list[i].children[j].isIndeterminate) {
  229. isIndeterminateCount++;
  230. }
  231. if (this.notRule.includes(list[i].children[j].id)){
  232. list[i].children[j].unchecked =true;
  233. }
  234. }
  235. if (unchecked && level == 0) {
  236. list[i].unchecked = true;
  237. }
  238. if(list[i].children.length == checkCount) {
  239. list[i].checked = true;
  240. } else if (checkCount > 0) {
  241. list[i].checked = false;
  242. list[i].isIndeterminate = true;
  243. } else {
  244. list[i].checked = false;
  245. if(isIndeterminateCount > 0) {
  246. list[i].isIndeterminate = true;
  247. } else {
  248. list[i].isIndeterminate = false;
  249. }
  250. }
  251. if (this.notRule.includes(list[i].id)){
  252. list[i].unchecked =true;
  253. }
  254. if(level == 1) {
  255. list[i].children = this.setListUnchecked(list[i].children, 1);
  256. }
  257. }
  258. }
  259. return list;
  260. },
  261. // 将当前值的子列表的选中状态与当前值一致
  262. changeAllList(list, checked) {
  263. let ids = []
  264. if (typeof list != 'undefined') {
  265. for (let i in list) {
  266. if (typeof list[i].children != 'undefined') {
  267. list[i].children = this.changeAllList(list[i].children, checked);
  268. }
  269. list[i].checked = checked;
  270. // if (checked && this.editIds.indexOf(list[i].id) === -1) {
  271. if (checked && this.isInEditIdsChunk(list[i].id) === -1) {
  272. ids.push(list[i].id)
  273. }
  274. // if (!checked && this.editIds.indexOf(list[i].id) > -1) {
  275. if (!checked && this.isInEditIdsChunk(list[i].id) > -1) {
  276. // this.editIds.splice(this.editIds.indexOf(list[i].id), 1)
  277. this.spliceEditIdsChunk(list[i].id)
  278. }
  279. }
  280. if (ids.length > 0) {
  281. this.pushEditIdsChunk(ids)
  282. }
  283. }
  284. return list;
  285. },
  286. // 重置所有省市区的选中状态 返回已选中的省市区
  287. setTempList(list) {
  288. let newList = [];
  289. let checkCount = 0;
  290. let isIndeterminateCount = 0;
  291. for (let i in list) { // 省
  292. let iChecked = true
  293. let iIsIndeterminate = false
  294. if (typeof list[i].children != 'undefined') { // 市
  295. for (let i1 in list[i].children) {
  296. let i1Checked = true
  297. let i1IsIndeterminate = false
  298. if (typeof list[i].children[i1].children != 'undefined') { // 区
  299. for (let i2 in list[i].children[i1].children) {
  300. // 如果第三级被选中,那么就不处理第四级
  301. let i2Checked = true
  302. let i2IsIndeterminate = false
  303. // 全选,部分选,全不选
  304. if (typeof list[i].children[i1].children[i2].children != 'undefined') { // 镇
  305. for (let i3 in list[i].children[i1].children[i2].children) {
  306. if (this.isInEditIdsChunk(list[i].children[i1].children[i2].children[i3].id) > -1) {
  307. newList.push({
  308. id: list[i].children[i1].children[i2].children[i3].id,
  309. name: list[i].children[i1].children[i2].children[i3].name
  310. });
  311. i2IsIndeterminate = true
  312. i1IsIndeterminate = true
  313. iIsIndeterminate = true // 有一个为TRUE那么就肯定为TRUE
  314. } else {
  315. i2Checked = false;
  316. }
  317. }
  318. } else {
  319. i2Checked = this.isInEditIdsChunk(list[i].children[i1].children[i2].id) > -1
  320. }
  321. list[i].children[i1].children[i2].checked = i2Checked
  322. list[i].children[i1].children[i2].isIndeterminate = i2Checked ? false : i2IsIndeterminate
  323. if (i2Checked) {
  324. this.pushEditIdsChunk(list[i].children[i1].children[i2].id)
  325. i1IsIndeterminate = true
  326. iIsIndeterminate = true // 有一个为TRUE那么就肯定为TRUE
  327. newList.push({
  328. id: list[i].children[i1].children[i2].id,
  329. name: list[i].children[i1].children[i2].name
  330. });
  331. } else {
  332. i1Checked = false
  333. this.spliceEditIdsChunk(list[i].children[i1].children[i2].id)
  334. }
  335. }
  336. } else {
  337. i1Checked = this.isInEditIdsChunk(list[i].children[i1].id) > -1
  338. }
  339. list[i].children[i1].checked = i1Checked
  340. list[i].children[i1].isIndeterminate = i1Checked ? false : i1IsIndeterminate
  341. if (i1Checked) {
  342. this.pushEditIdsChunk(list[i].children[i1].id)
  343. iIsIndeterminate = true
  344. newList.push({
  345. id: list[i].children[i1].id,
  346. name: list[i].children[i1].name
  347. });
  348. } else {
  349. iChecked = false
  350. this.spliceEditIdsChunk(list[i].children[i1].id)
  351. }
  352. }
  353. } else {
  354. iChecked = this.isInEditIdsChunk(list[i].id) > -1
  355. }
  356. list[i].checked = iChecked
  357. list[i].isIndeterminate = iChecked ? false : iIsIndeterminate
  358. if (iChecked) {
  359. this.pushEditIdsChunk(list[i].id)
  360. newList.push({
  361. id: list[i].id,
  362. name: list[i].name
  363. });
  364. } else {
  365. this.spliceEditIdsChunk(list[i].id)
  366. }
  367. }
  368. /*
  369. for (let i in list) {
  370. if (typeof list[i].children != 'undefined') {
  371. let childList = this.setTempList(list[i].children);
  372. if (childList.isIndeterminateCount > 0) {
  373. // list[i].checked = false;
  374. // list[i].isIndeterminate = true;
  375. // this.setIsIndeterminateIds(list[i].id, true)
  376. // isIndeterminateCount++;
  377. // newList = newList.concat(childList.newList);
  378. } else if (childList.checkCount < list[i].children.length) {
  379. // list[i].checked = false;
  380. if (childList.checkCount > 0) {
  381. // list[i].isIndeterminate = true;
  382. // this.setIsIndeterminateIds(list[i].id, true)
  383. // isIndeterminateCount++;
  384. // newList = newList.concat(childList.newList);
  385. } else {
  386. // list[i].isIndeterminate = false;
  387. // this.setIsIndeterminateIds(list[i].id, false)
  388. }
  389. } else if(childList.checkCount == list[i].children.length){
  390. // console.log('setTempList', list[i].id, list[i].children, childList)
  391. // list[i].checked = true;
  392. // list[i].isIndeterminate = false;
  393. // this.setIsIndeterminateIds(list[i].id, false)
  394. // newList = newList.concat(childList.newList);
  395. }else {
  396. if (list[i].children > 0) {
  397. // list[i].checked = true;
  398. } else {
  399. // list[i].checked = false;
  400. }
  401. // list[i].isIndeterminate = false;
  402. // this.setIsIndeterminateIds(list[i].id, false)
  403. }
  404. }
  405. // if (list[i].checked) {
  406. if (this.editIds.indexOf(list[i].id) > -1) {
  407. // checkCount++;
  408. // newList.push(list[i]);
  409. }
  410. }*/
  411. let _ = this
  412. setTimeout(() => {
  413. _.list = list
  414. }, 5)
  415. return {
  416. newList: newList,
  417. checkCount: checkCount,
  418. isIndeterminateCount: isIndeterminateCount
  419. };
  420. },
  421. // 向父组件发送消息
  422. pickerChange(item) {
  423. if (item.checked) {
  424. this.pushEditIdsChunk(item.id)
  425. } else {
  426. this.spliceEditIdsChunk(item.id)
  427. }
  428. this.changeAllList(item.children, item.checked);
  429. let tempList = this.setTempList(this.list);
  430. this.tempList = tempList.newList;
  431. this.$forceUpdate()
  432. this.$emit('selected', this.tempList, this.params);
  433. },
  434. // 选择省份
  435. selectProvince(index) {
  436. this.p_index = index;
  437. this.c_index = 0;
  438. this.d_index = 0;
  439. this.t_index = 0;
  440. },
  441. setIsIndeterminateIds(id, value) {
  442. let index = this.isIndeterminateIds.indexOf(id)
  443. if (index === -1 && value) {
  444. this.isIndeterminateIds.push(id)
  445. }
  446. if (!value && index > -1) {
  447. this.isIndeterminateIds.splice(index, 1);
  448. }
  449. },
  450. isInEditIdsChunk(id) {
  451. let pIndex = this.getModIndex(id)
  452. let index = -1;
  453. if (this.editIdsChunk[pIndex] !== undefined) {
  454. index = this.editIdsChunk[pIndex].indexOf(id)
  455. }
  456. return index
  457. },
  458. getModIndex(id) {
  459. if (isNaN(parseInt(id))) {
  460. id = parseInt(id.substring(id.startsWith("__") ? 2 : 1))
  461. }
  462. return id % 100
  463. },
  464. pushEditIdsChunk(id) {
  465. let ids = []
  466. if (typeof id !== 'object') {
  467. ids.push(id)
  468. } else {
  469. ids = id
  470. }
  471. for (let i in ids) {
  472. let pIndex = this.getModIndex(ids[i])
  473. if (this.editIdsChunk[pIndex] === undefined) {
  474. this.editIdsChunk[pIndex] = []
  475. }
  476. // 是否已经存在 不然会重复
  477. if (this.editIdsChunk[pIndex].indexOf(ids[i]) === -1) {
  478. this.editIdsChunk[pIndex].push(ids[i])
  479. }
  480. }
  481. this.$forceUpdate()
  482. },
  483. spliceEditIdsChunk(id) {
  484. let pIndex = this.getModIndex(id)
  485. let index = this.isInEditIdsChunk(id)
  486. if ('spliceEditIdsChunk', index > -1) {
  487. this.editIdsChunk[pIndex].splice(index, 1)
  488. let _ = this
  489. _.$forceUpdate()
  490. }
  491. },
  492. getCheckedSelectNum(list, level = 1) {// 获取选中对应个数
  493. let checkedItemsCount = 0;
  494. if (!Array.isArray(list)) {
  495. throw new Error('List must be an array.');
  496. }
  497. if (level === 1) {
  498. list.forEach(item => {
  499. if (Array.isArray(item.children) && item.children.length > 0) {
  500. const hasCheckedChildren = item.children.some(child => child.checked);
  501. if (hasCheckedChildren) {
  502. checkedItemsCount++;
  503. }
  504. }
  505. });
  506. } else {
  507. list.forEach(item => {
  508. if (item.checked) {
  509. checkedItemsCount++;
  510. }
  511. });
  512. }
  513. return checkedItemsCount;
  514. }
  515. }
  516. });
  517. </script>
  518. <style>
  519. .el-checkbox__label{
  520. padding-left: 5px!important;
  521. }
  522. .el_checkbox_select{
  523. color: #02A7F0;
  524. }
  525. </style>