city.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <template>
  2. <div>
  3. <Modal v-model="addressModal" title="选择可配送区域" width="50%" class="modal" :mask="true">
  4. <Row :gutter="24" type="flex">
  5. <Col :xl="24" :lg="24" :md="24" :sm="24" :xs="24" class="item">
  6. <div class="acea-row row-right row-middle">
  7. <Checkbox v-model="iSselect" @on-change="allCheckbox">全选</Checkbox>
  8. <div class="empty" @click="empty">清空</div>
  9. </div>
  10. </Col>
  11. </Row>
  12. <Row :gutter="24" type="flex" :loading="loading">
  13. <Col
  14. :xl="6"
  15. :lg="6"
  16. :md="6"
  17. :sm="8"
  18. :xs="6"
  19. class="item"
  20. v-for="(item, index) in cityList"
  21. :key="index"
  22. v-if="item.isShow"
  23. >
  24. <div @mouseenter="enter(index)" @mouseleave="leave()">
  25. <Checkbox v-model="item.checked" :label="item.name" @on-change="checkedClick(index)">{{
  26. item.name
  27. }}</Checkbox
  28. ><span class="red">({{ (item.count || 0) + '/' + item.childNum }})</span>
  29. <div class="city" v-show="activeCity === index">
  30. <div class="checkBox">
  31. <div class="arrow"></div>
  32. <div>
  33. <Checkbox
  34. v-model="city.checked"
  35. :label="city.name"
  36. @on-change="primary(index, indexn)"
  37. class="itemn"
  38. v-for="(city, indexn) in item.children"
  39. :key="indexn"
  40. v-show="city.isShow"
  41. >{{ city.name }}</Checkbox
  42. >
  43. </div>
  44. </div>
  45. </div>
  46. </div>
  47. </Col>
  48. </Row>
  49. <div slot="footer">
  50. <Button @click="close">取消</Button>
  51. <Button type="primary" @click="confirm">确定</Button>
  52. </div>
  53. <Spin size="large" fix v-if="loading"></Spin>
  54. </Modal>
  55. </div>
  56. </template>
  57. <script>
  58. import { mapState } from 'vuex';
  59. import { templatesCityListApi } from '@/api/setting';
  60. export default {
  61. name: 'city',
  62. props: {
  63. type: {
  64. type: Number,
  65. default: 0,
  66. },
  67. selectArr: {
  68. type: Array,
  69. default: [],
  70. },
  71. },
  72. data() {
  73. return {
  74. iSselect: false,
  75. addressModal: false,
  76. cityList: [],
  77. activeCity: -1,
  78. loading: false,
  79. };
  80. },
  81. computed: {},
  82. methods: {
  83. enter(index) {
  84. this.activeCity = index;
  85. },
  86. leave() {
  87. this.activeCity = null;
  88. },
  89. getCityList() {
  90. this.loading = true;
  91. templatesCityListApi().then((res) => {
  92. this.loading = false;
  93. this.selectArr = [];
  94. res.data.forEach((el, index, arr) => {
  95. el.isShow = true;
  96. el.children.forEach((child, j) => {
  97. child.isShow = true;
  98. if (this.selectArr.length > 0) {
  99. this.selectArr.forEach((sel, sindex) => {
  100. sel.children.forEach((sitem, sj) => {
  101. if (child.city_id == sitem.city_id) {
  102. child.isShow = false;
  103. }
  104. });
  105. });
  106. }
  107. });
  108. });
  109. res.data.forEach((el, index, arr) => {
  110. let num = 0;
  111. let oldNum = 0;
  112. el.children.forEach((child, j) => {
  113. if (!child.isShow) {
  114. num++;
  115. } else {
  116. oldNum++;
  117. }
  118. });
  119. if (num == el.children.length) {
  120. el.isShow = false;
  121. }
  122. el.childNum = oldNum;
  123. });
  124. this.cityList = res.data;
  125. });
  126. },
  127. /**
  128. * 全选或者反选
  129. * @param checked
  130. */
  131. allCheckbox: function () {
  132. let that = this,
  133. checked = this.iSselect;
  134. that.cityList.forEach(function (item, key) {
  135. that.$set(that.cityList[key], 'checked', checked);
  136. if (checked) {
  137. that.$set(that.cityList[key], 'count', that.cityList[key].children.length);
  138. } else {
  139. that.$set(that.cityList[key], 'count', 0);
  140. }
  141. that.cityList[key].children.forEach(function (val, k) {
  142. that.$set(that.cityList[key].children[k], 'checked', checked);
  143. });
  144. });
  145. // this.render();
  146. },
  147. // 清空;
  148. empty() {
  149. let that = this;
  150. that.cityList.forEach(function (item, key) {
  151. that.$set(that.cityList[key], 'checked', false);
  152. that.cityList[key].children.forEach(function (val, k) {
  153. that.$set(that.cityList[key].children[k], 'checked', false);
  154. });
  155. that.$set(that.cityList[key], 'count', 0);
  156. });
  157. this.iSselect = false;
  158. },
  159. /**
  160. * 点击省
  161. * @param index
  162. */
  163. checkedClick: function (index) {
  164. let that = this;
  165. if (that.cityList[index].checked) {
  166. that.$set(that.cityList[index], 'count', that.cityList[index].childNum);
  167. that.cityList[index].children.forEach(function (item, key) {
  168. that.$set(that.cityList[index].children[key], 'checked', true);
  169. });
  170. } else {
  171. that.$set(that.cityList[index], 'count', 0);
  172. that.$set(that.cityList[index], 'checked', false);
  173. that.cityList[index].children.forEach(function (item, key) {
  174. that.$set(that.cityList[index].children[key], 'checked', false);
  175. });
  176. that.iSselect = false;
  177. }
  178. // this.render();
  179. },
  180. /**
  181. * 点击市区
  182. * @param index
  183. * @param ind
  184. */
  185. primary: function (index, ind) {
  186. let checked = false,
  187. count = 0;
  188. this.cityList[index].children.forEach(function (item, key) {
  189. if (item.checked) {
  190. checked = true;
  191. count++;
  192. }
  193. });
  194. this.$set(this.cityList[index], 'count', count);
  195. this.$set(this.cityList[index], 'checked', checked);
  196. // this.render();
  197. },
  198. // 确定;
  199. confirm() {
  200. let that = this;
  201. // 被选中的省市;
  202. let selectList = [];
  203. that.cityList.forEach(function (item, key) {
  204. let data = {};
  205. if (item.checked) {
  206. data = {
  207. name: item.name,
  208. city_id: item.city_id,
  209. children: [],
  210. };
  211. }
  212. that.cityList[key].children.forEach(function (i, k) {
  213. if (i.checked) {
  214. data.children.push({
  215. city_id: i.city_id,
  216. });
  217. }
  218. });
  219. if (data.city_id !== undefined) {
  220. selectList.push(data);
  221. }
  222. });
  223. if (selectList.length === 0) {
  224. return that.$Message.error('至少选择一个省份或者城市');
  225. } else {
  226. this.$emit('selectCity', selectList, this.type);
  227. that.addressModal = false;
  228. this.cityList = [];
  229. }
  230. // parent.selectCity(selectList,type);
  231. // var index = parent.layer.getFrameIndex(window.name);
  232. // parent.layer.close(index);
  233. },
  234. close() {
  235. this.addressModal = false;
  236. this.cityList = [];
  237. },
  238. },
  239. mounted() {
  240. // this.getCityList();
  241. },
  242. };
  243. </script>
  244. <style scoped lang="stylus">
  245. .modal .item {
  246. margin-bottom: 20px;
  247. }
  248. .modal .item .city {
  249. position: absolute;
  250. z-index: 9;
  251. top: 17px;
  252. width: 100%;
  253. padding-top: 18px;
  254. }
  255. .modal .item .city .checkBox {
  256. width: 97%;
  257. padding: 10px;
  258. border: 1px solid #eee;
  259. background-color: #fff;
  260. max-height: 100px;
  261. overflow-x: hidden;
  262. overflow-y: auto;
  263. }
  264. .modal .item .city .checkBox .arrow {
  265. position: absolute;
  266. top: 3px;
  267. width: 0;
  268. height: 0;
  269. border: 8px solid transparent;
  270. border-bottom-color: #ddd;
  271. }
  272. .modal .item .city .checkBox .arrow:before {
  273. position: absolute;
  274. bottom: -8px;
  275. right: -7px;
  276. content: '';
  277. width: 0;
  278. height: 0;
  279. border: 7px solid transparent;
  280. border-bottom-color: #fff;
  281. }
  282. .modal .item .city .checkBox .itemn {
  283. margin-bottom: 10px;
  284. }
  285. .radio {
  286. padding: 5px 0;
  287. font-size: 14px !important;
  288. }
  289. .red {
  290. color: #ff0000;
  291. }
  292. .empty {
  293. cursor: pointer;
  294. }
  295. </style>