|
|
@@ -0,0 +1,283 @@
|
|
|
+<!-- 编辑弹窗 -->
|
|
|
+<template>
|
|
|
+ <ele-modal
|
|
|
+ form
|
|
|
+ :width="1080"
|
|
|
+ :bodyStyle="{ 'min-height': '400px' }"
|
|
|
+ v-model="visible"
|
|
|
+ :title="title"
|
|
|
+ @open="handleOpen"
|
|
|
+ >
|
|
|
+ <div class="flex flex-col" v-loading="loading">
|
|
|
+ <div class="flex" v-for="dq in areaList" :key="dq.code">
|
|
|
+ <el-checkbox
|
|
|
+ :label="dq.name"
|
|
|
+ :indeterminate="isIndeterminateShow(dq)"
|
|
|
+ style="min-width: 100px"
|
|
|
+ @change="(value) => handleDqChange(value, dq)"
|
|
|
+ ></el-checkbox>
|
|
|
+
|
|
|
+ <div v-for="item in dq.children" class="mr-6 flex items-center">
|
|
|
+ <el-checkbox
|
|
|
+ @change="(value) => handleParentChange(value, item)"
|
|
|
+ :data-id="item.id"
|
|
|
+ v-model="item.otherSelected"
|
|
|
+ style="margin-right: 5px"
|
|
|
+ :true-value="1"
|
|
|
+ :false-value="0"
|
|
|
+ :indeterminate="isIndeterCityShow(item, 'otherSelected')"
|
|
|
+ v-if="item.otherSelected == 1"
|
|
|
+ disabled
|
|
|
+ ></el-checkbox>
|
|
|
+ <el-checkbox
|
|
|
+ @change="(value) => handleParentChange(value, item)"
|
|
|
+ :data-id="item.id"
|
|
|
+ v-model="item.mySelected"
|
|
|
+ style="margin-right: 5px"
|
|
|
+ :true-value="1"
|
|
|
+ :false-value="0"
|
|
|
+ :indeterminate="isIndeterCityShow(item, 'mySelected')"
|
|
|
+ v-else
|
|
|
+ ></el-checkbox>
|
|
|
+ <ele-popover
|
|
|
+ :width="400"
|
|
|
+ trigger="click"
|
|
|
+ :title="item.district"
|
|
|
+ :showArrow="false"
|
|
|
+ :disabled="isPopoverDisabled(item)"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <div
|
|
|
+ class="flex items-center cursor-pointer"
|
|
|
+ :class="{ 'disabled-popover': isPopoverDisabled(item) }"
|
|
|
+ >
|
|
|
+ <el-text :type="item.mySelected == 1 ? 'primary' : ''">{{
|
|
|
+ item.district
|
|
|
+ }}</el-text>
|
|
|
+ <el-text type="warning" v-if="isShowAll(item)">(全)</el-text>
|
|
|
+ <el-icon><CaretBottom /></el-icon>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-for="child in item.childInfo">
|
|
|
+ <el-checkbox
|
|
|
+ @change="(value) => handleChildChange(value, item, child)"
|
|
|
+ :data-id="child.id"
|
|
|
+ :label="child.district"
|
|
|
+ v-model="child.otherSelected"
|
|
|
+ :true-value="1"
|
|
|
+ :false-value="0"
|
|
|
+ v-if="child.otherSelected == 1"
|
|
|
+ disabled
|
|
|
+ ></el-checkbox>
|
|
|
+ <el-checkbox
|
|
|
+ v-else
|
|
|
+ @change="(value) => handleChildChange(value, item, child)"
|
|
|
+ :data-id="child.id"
|
|
|
+ v-model="child.mySelected"
|
|
|
+ :label="child.district"
|
|
|
+ :true-value="1"
|
|
|
+ :false-value="0"
|
|
|
+ ></el-checkbox>
|
|
|
+ </template>
|
|
|
+ </ele-popover>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="handleCancel">关闭</el-button>
|
|
|
+ <el-button type="primary" @click="handleSubmit">确定</el-button>
|
|
|
+ </template>
|
|
|
+ </ele-modal>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+ import { ref, reactive, nextTick } from 'vue';
|
|
|
+ import request from '@/utils/request';
|
|
|
+ import { ElMessage } from 'element-plus';
|
|
|
+ import { CaretBottom, CaretTop } from '@element-plus/icons-vue';
|
|
|
+
|
|
|
+ /** 弹窗是否打开 */
|
|
|
+ const visible = defineModel({ type: Boolean });
|
|
|
+
|
|
|
+ /** 关闭弹窗 */
|
|
|
+ const handleCancel = () => {
|
|
|
+ visible.value = false;
|
|
|
+ };
|
|
|
+
|
|
|
+ //计算是否禁用
|
|
|
+ const isPopoverDisabled = computed(() => (item) => {
|
|
|
+ let checked = item.childInfo.every((i) => i.otherSelected == 1);
|
|
|
+ return checked;
|
|
|
+ });
|
|
|
+
|
|
|
+ //计算是否显示全
|
|
|
+ const isShowAll = computed(() => (item) => {
|
|
|
+ let checked = item.childInfo.every((i) => i.mySelected == 1);
|
|
|
+ return checked;
|
|
|
+ });
|
|
|
+ //计算大区是否全选
|
|
|
+ const isIndeterminateShow = computed(() => (dq) => {
|
|
|
+ let len = dq.children.length;
|
|
|
+ let length = dq.children.filter((i) => i.mySelected == 1).length;
|
|
|
+
|
|
|
+ return length > 0 && length < len;
|
|
|
+ });
|
|
|
+
|
|
|
+ //计算省市是否全选
|
|
|
+ const isIndeterCityShow = computed(() => (item, type) => {
|
|
|
+ let len = item.childInfo.length;
|
|
|
+ let length = item.childInfo.filter((i) => i[type] == 1).length;
|
|
|
+
|
|
|
+ return length > 0 && length < len;
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 弹窗打开事件 */
|
|
|
+ const title = ref('活动区域设置');
|
|
|
+ const handleOpen = (row) => {
|
|
|
+ visible.value = true;
|
|
|
+ nextTick(() => {
|
|
|
+ if (row && row.id) {
|
|
|
+ title.value = row.activityName
|
|
|
+ ? `${row.activityName}区域设置`
|
|
|
+ : `活动区域设置`;
|
|
|
+
|
|
|
+ row && getAreaInfo(row.id);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ let formdata = reactive({
|
|
|
+ activityId: '',
|
|
|
+ selectendList: [{ provinceId: '', cityId: '' }]
|
|
|
+ });
|
|
|
+
|
|
|
+ //获取区域基础数据信息
|
|
|
+ let dqList = ref([
|
|
|
+ { name: '华东', code: 'hd' },
|
|
|
+ { name: '华北', code: 'hb' },
|
|
|
+ { name: '华中', code: 'hz' },
|
|
|
+ { name: '华南', code: 'hn' },
|
|
|
+ { name: '东北', code: 'db' },
|
|
|
+ { name: '西北', code: 'xb' },
|
|
|
+ { name: '西南', code: 'xn' },
|
|
|
+ { name: '港澳台', code: 'gat' },
|
|
|
+ { name: '海外', code: 'hw' }
|
|
|
+ ]);
|
|
|
+ const areaList = ref([]);
|
|
|
+ const loading = ref(false);
|
|
|
+ const getAreaInfo = (activityId) => {
|
|
|
+ formdata.activityId = activityId;
|
|
|
+ loading.value = true;
|
|
|
+ request
|
|
|
+ .get(`/activity/activityUpsellInfo/areaList/${activityId}`)
|
|
|
+ .then((res) => {
|
|
|
+ if (res.data.code == 200) {
|
|
|
+ areaList.value.length = 0;
|
|
|
+ dqList.value.forEach((item) => {
|
|
|
+ item.checked = false;
|
|
|
+ item.children = res.data.data[item.code];
|
|
|
+ areaList.value.push(item);
|
|
|
+ });
|
|
|
+
|
|
|
+ console.log(areaList.value, 'areaList.value');
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .finally(() => (loading.value = false));
|
|
|
+ };
|
|
|
+
|
|
|
+ //区域checkbox改变事件
|
|
|
+ const handleDqChange = (value, dq) => {
|
|
|
+ if (value == 1) {
|
|
|
+ dq.children.forEach((item) => {
|
|
|
+ if (item.otherSelected != 1) {
|
|
|
+ item.mySelected = 1;
|
|
|
+ item.childInfo.forEach((i) => {
|
|
|
+ if (i.otherSelected != 1) {
|
|
|
+ i.mySelected = 1;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else if (value == 0) {
|
|
|
+ dq.children.forEach((item) => {
|
|
|
+ if (item.otherSelected != 1) {
|
|
|
+ item.mySelected = 0;
|
|
|
+ item.childInfo.forEach((i) => {
|
|
|
+ if (i.otherSelected != 1) {
|
|
|
+ i.mySelected = 1;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ //父级checkbox改变事件
|
|
|
+ const handleParentChange = (value, item) => {
|
|
|
+ if (value == 1) {
|
|
|
+ item.childInfo.forEach((i) => {
|
|
|
+ i.mySelected = 1;
|
|
|
+ });
|
|
|
+ } else if (value == 0) {
|
|
|
+ item.childInfo.forEach((i) => {
|
|
|
+ i.mySelected = 0;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
+ //子级checkbox改变事件
|
|
|
+ const handleChildChange = (value, item, child) => {
|
|
|
+ let checked = item.childInfo.some((i) => i.mySelected == 1);
|
|
|
+ item.mySelected = checked ? 1 : 0;
|
|
|
+ };
|
|
|
+
|
|
|
+ //格式化选中数据
|
|
|
+ const formatterSelected = () => {
|
|
|
+ let arr = [];
|
|
|
+ areaList.value.forEach((item) => {
|
|
|
+ item.children.forEach((i) => {
|
|
|
+ i.childInfo.forEach((j) => {
|
|
|
+ if (j.mySelected == 1 && j.otherSelected != 1) {
|
|
|
+ arr.push({
|
|
|
+ provinceId: i.id,
|
|
|
+ cityId: j.id
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return arr;
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 提交 */
|
|
|
+ const emit = defineEmits(['success']);
|
|
|
+ const handleSubmit = () => {
|
|
|
+ formdata.selectendList = formatterSelected();
|
|
|
+ console.log(formdata);
|
|
|
+ let data = JSON.parse(JSON.stringify(formdata));
|
|
|
+ request.post(`/activity/activityUpsellInfo/setAreaList`, data).then((res) => {
|
|
|
+ if (res.data.code == 200) {
|
|
|
+ visible.value = false;
|
|
|
+ ElMessage.success('设置成功');
|
|
|
+ emit('success');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ defineExpose({
|
|
|
+ handleOpen
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+ .disabled-popover {
|
|
|
+ cursor: not-allowed;
|
|
|
+ .el-text {
|
|
|
+ color: #909399;
|
|
|
+ }
|
|
|
+ .el-icon {
|
|
|
+ color: #909399;
|
|
|
+ fill: #909399;
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|