area-setting.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <!-- 编辑弹窗 -->
  2. <template>
  3. <ele-modal form :width="1080" :bodyStyle="{ 'min-height': '400px' }" v-model="visible" :title="title"
  4. @open="handleOpen">
  5. <div class="flex flex-col" v-loading="loading">
  6. <div class="flex" v-for="dq in areaList" :key="dq.code">
  7. <el-checkbox :label="dq.name" :indeterminate="isIndeterminateShow(dq)" style="min-width: 100px"
  8. @change="(value) => handleDqChange(value, dq)" />
  9. <div v-for="item in dq.children" class="mr-6 flex items-center" :key="item.code">
  10. <el-checkbox @change="(value) => handleParentChange(value, item)" :data-id="item.id"
  11. v-model="item.otherSelected" style="margin-right: 5px" :true-value="1" :false-value="0"
  12. :indeterminate="isIndeterCityShow(item, 'otherSelected')
  13. " v-if="item.otherSelected == 1" disabled />
  14. <el-checkbox @change="(value) => handleParentChange(value, item)" :data-id="item.id"
  15. v-model="item.mySelected" style="margin-right: 5px" :true-value="1" :false-value="0"
  16. :indeterminate="isIndeterCityShow(item, 'mySelected')" v-else />
  17. <ele-popover :width="400" trigger="click" :title="item.district" :showArrow="false"
  18. :disabled="isPopoverDisabled(item)">
  19. <template #reference>
  20. <div class="flex items-center cursor-pointer" :class="{
  21. 'disabled-popover': isPopoverDisabled(item)
  22. }">
  23. <el-text :type="item.mySelected == 1 ? 'primary' : ''
  24. ">{{ item.district }}</el-text>
  25. <el-text type="warning" v-if="isShowAll(item)">(全)</el-text>
  26. <el-icon>
  27. <CaretBottom />
  28. </el-icon>
  29. </div>
  30. </template>
  31. <template v-for="child in item.childInfo">
  32. <el-checkbox @change="
  33. (value) =>
  34. handleChildChange(value, item, child)
  35. " :data-id="child.id" :label="child.district" v-model="child.otherSelected" :true-value="1"
  36. :false-value="0" v-if="child.otherSelected == 1" disabled />
  37. <el-checkbox v-else @change="
  38. (value) =>
  39. handleChildChange(value, item, child)
  40. " :data-id="child.id" v-model="child.mySelected" :label="child.district" :true-value="1"
  41. :false-value="0" />
  42. </template>
  43. </ele-popover>
  44. </div>
  45. </div>
  46. </div>
  47. <el-text type="danger">灰色地区表示已经添加到其他仓库中,请先在其他仓库中去掉勾选后,再重新选择</el-text>
  48. <template #footer>
  49. <el-button @click="handleCancel">关闭</el-button>
  50. <el-button type="primary" @click="handleSubmit">确定</el-button>
  51. </template>
  52. </ele-modal>
  53. </template>
  54. <script setup>
  55. import { ref, reactive, nextTick } from 'vue';
  56. import request from '@/utils/request';
  57. import { CaretBottom, CaretTop } from '@element-plus/icons-vue';
  58. /** 弹窗是否打开 */
  59. const visible = defineModel({ type: Boolean });
  60. /** 关闭弹窗 */
  61. const handleCancel = () => {
  62. visible.value = false;
  63. };
  64. //计算是否禁用
  65. const isPopoverDisabled = computed(() => (item) => {
  66. let checked = item.childInfo.every((i) => i.otherSelected == 1);
  67. return checked;
  68. });
  69. //计算是否显示全
  70. const isShowAll = computed(() => (item) => {
  71. let checked = item.childInfo.every((i) => i.mySelected == 1);
  72. return checked;
  73. });
  74. //计算大区是否全选
  75. const isIndeterminateShow = computed(() => (dq) => {
  76. let len = dq.children.length;
  77. let length = dq.children.filter((i) => i.mySelected == 1).length;
  78. return length > 0 && length < len;
  79. });
  80. //计算省市是否全选
  81. const isIndeterCityShow = computed(() => (item, type) => {
  82. let len = item.childInfo.length;
  83. let length = item.childInfo.filter((i) => i[type] == 1).length;
  84. return length > 0 && length < len;
  85. });
  86. /** 弹窗打开事件 */
  87. const title = ref('仓库区域设置');
  88. const handleOpen = (row) => {
  89. visible.value = true;
  90. nextTick(() => {
  91. if (row && row.id) {
  92. title.value = row.godownName
  93. ? `${row.godownName}区域设置`
  94. : `仓库区域设置`;
  95. row && getAreaInfo(row.id);
  96. }
  97. });
  98. };
  99. let formdata = reactive({
  100. godownId: '',
  101. selectendList: [{ provinceId: '', cityId: '' }]
  102. });
  103. //获取区域基础数据信息
  104. let dqList = ref([
  105. { name: '华东', code: 'hd' },
  106. { name: '华北', code: 'hb' },
  107. { name: '华中', code: 'hz' },
  108. { name: '华南', code: 'hn' },
  109. { name: '东北', code: 'db' },
  110. { name: '西北', code: 'xb' },
  111. { name: '西南', code: 'xn' },
  112. { name: '港澳台', code: 'gat' },
  113. { name: '海外', code: 'hw' }
  114. ]);
  115. const areaList = ref([]);
  116. const loading = ref(false);
  117. const getAreaInfo = (godownId) => {
  118. formdata.godownId = godownId;
  119. loading.value = true;
  120. request
  121. .get(`/baseinfo/godown/getGodownAreaList/${godownId}`)
  122. .then((res) => {
  123. if (res.data.code == 200) {
  124. areaList.value.length = 0;
  125. dqList.value.forEach((item) => {
  126. item.checked = false;
  127. item.children = res.data.data[item.code];
  128. areaList.value.push(item);
  129. });
  130. console.log(areaList.value, 'areaList.value');
  131. }
  132. })
  133. .finally(() => (loading.value = false));
  134. };
  135. //区域checkbox改变事件
  136. const handleDqChange = (value, dq) => {
  137. if (value == 1) {
  138. dq.children.forEach((item) => {
  139. if (item.otherSelected != 1) {
  140. item.mySelected = 1;
  141. item.childInfo.forEach((i) => {
  142. if (i.otherSelected != 1) {
  143. i.mySelected = 1;
  144. }
  145. });
  146. }
  147. });
  148. } else if (value == 0) {
  149. dq.children.forEach((item) => {
  150. if (item.otherSelected != 1) {
  151. item.mySelected = 0;
  152. item.childInfo.forEach((i) => {
  153. if (i.otherSelected != 1) {
  154. i.mySelected = 1;
  155. }
  156. });
  157. }
  158. });
  159. }
  160. };
  161. //父级checkbox改变事件
  162. const handleParentChange = (value, item) => {
  163. if (value == 1) {
  164. item.childInfo.forEach((i) => {
  165. i.mySelected = 1;
  166. });
  167. } else if (value == 0) {
  168. item.childInfo.forEach((i) => {
  169. i.mySelected = 0;
  170. });
  171. }
  172. };
  173. //子级checkbox改变事件
  174. const handleChildChange = (value, item, child) => {
  175. let checked = item.childInfo.some((i) => i.mySelected == 1);
  176. item.mySelected = checked ? 1 : 0;
  177. };
  178. //格式化选中数据
  179. const formatterSelected = () => {
  180. let arr = [];
  181. areaList.value.forEach((item) => {
  182. item.children.forEach((i) => {
  183. i.childInfo.forEach((j) => {
  184. if (j.mySelected == 1 && j.otherSelected != 1) {
  185. arr.push({
  186. provinceId: i.id,
  187. cityId: j.id
  188. });
  189. }
  190. });
  191. });
  192. });
  193. return arr;
  194. };
  195. /** 提交 */
  196. const handleSubmit = () => {
  197. formdata.selectendList = formatterSelected();
  198. console.log(formdata);
  199. let data = JSON.parse(JSON.stringify(formdata));
  200. request.post(`/baseinfo/godown/setGodownAreaInfo`, data).then((res) => {
  201. if (res.data.code == 200) {
  202. visible.value = false;
  203. }
  204. });
  205. };
  206. defineExpose({
  207. handleOpen
  208. });
  209. </script>
  210. <style lang="scss">
  211. .disabled-popover {
  212. cursor: not-allowed;
  213. .el-text {
  214. color: #909399;
  215. }
  216. .el-icon {
  217. color: #909399;
  218. fill: #909399;
  219. }
  220. }
  221. </style>