| | |
| | | @click="handleDeleteRegion">删除</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="left-search"> |
| | | <el-input v-model="regionKeyword" |
| | | placeholder="查询地区" |
| | | clearable |
| | | :prefix-icon="Search" /> |
| | | </div> |
| | | |
| | | <div class="left-list"> |
| | | <el-skeleton v-if="regionsLoading" |
| | | :rows="8" |
| | |
| | | </template> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="right-panel"> |
| | | <div class="toolbar-card"> |
| | | <div class="search_form right-search-form"> |
| | | <div class="search-fields"> |
| | | <span class="search_title">客户名称:</span> |
| | | <el-input v-model="searchForm.customerName" |
| | | style="width: 240px;margin-right: 10px" |
| | | placeholder="请输入" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" /> |
| | | <span class="search_title">客户分类:</span> |
| | | <el-select v-model="searchForm.customerType" |
| | | placeholder="请选择" |
| | | style="width: 240px" |
| | | clearable |
| | | @change="handleQuery"> |
| | | <el-option label="零售客户" |
| | | value="零售客户" /> |
| | | <el-option label="进销商客户" |
| | | value="进销商客户" /> |
| | | </el-select> |
| | | <el-button type="primary" |
| | | @click="handleQuery" |
| | | style="margin-left: 10px">搜索</el-button> |
| | | </div> |
| | | <div class="toolbar-divider"></div> |
| | | <div class="action-buttons"> |
| | | <el-button type="primary" |
| | | @click="openForm('add')">新增客户</el-button> |
| | | <el-button @click="handleOut">导出</el-button> |
| | | <el-button type="info" |
| | | plain |
| | | icon="Upload" |
| | | @click="handleImport">导入</el-button> |
| | | <el-button type="danger" |
| | | plain |
| | | @click="handleDelete">删除</el-button> |
| | | </div> |
| | | <div class="search-fields"> |
| | | <span class="search_title">客户名称:</span> |
| | | <el-input v-model="searchForm.customerName" |
| | | style="width: 240px;margin-right: 10px" |
| | | placeholder="请输入" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" /> |
| | | <span class="search_title">客户分类:</span> |
| | | <el-select v-model="searchForm.customerType" |
| | | placeholder="请选择" |
| | | style="width: 240px" |
| | | clearable |
| | | @change="handleQuery"> |
| | | <el-option label="零售客户" |
| | | value="零售客户" /> |
| | | <el-option label="进销商客户" |
| | | value="进销商客户" /> |
| | | </el-select> |
| | | <el-button type="primary" |
| | | @click="handleQuery" |
| | | style="margin-left: 10px">搜索</el-button> |
| | | </div> |
| | | <div class="toolbar-divider"></div> |
| | | <div class="action-buttons"> |
| | | <el-button type="primary" |
| | | @click="openForm('add')">新增客户</el-button> |
| | | <el-button @click="handleOut">导出</el-button> |
| | | <el-button type="info" |
| | | plain |
| | | icon="Upload" |
| | | @click="handleImport">导入</el-button> |
| | | <el-button type="danger" |
| | | plain |
| | | @click="handleDelete">删除</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="table_list table-card"> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <el-dialog v-model="addRegionDialogVisible" |
| | | title="新增地区" |
| | | width="420px" |
| | |
| | | filterable |
| | | placeholder="不选则为顶级地区" /> |
| | | </el-form-item> |
| | | <el-form-item label="地区名称"> |
| | | <el-form-item label="地区名称" |
| | | required> |
| | | <el-input v-model="addRegionForm.regionsName" |
| | | placeholder="请输入" |
| | | clearable /> |
| | |
| | | <!-- 用户导入对话框 --> |
| | | <el-dialog :title="upload.title" |
| | | v-model="upload.open" |
| | | @close="onClose" |
| | | width="400px" |
| | | append-to-body> |
| | | <el-upload ref="uploadRef" |
| | |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <div class="info-item"> |
| | | <span class="info-label">维护时间:</span> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, ref, reactive, getCurrentInstance, toRefs, computed, watch } from "vue"; |
| | | import { |
| | | onMounted, |
| | | ref, |
| | | reactive, |
| | | getCurrentInstance, |
| | | toRefs, |
| | | computed, |
| | | watch, |
| | | } from "vue"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { |
| | | addCustomer, |
| | |
| | | }, |
| | | { |
| | | label: "客户地区", |
| | | prop: "regions", |
| | | prop: "regionsName", |
| | | width: 120, |
| | | }, |
| | | { |
| | |
| | | // openReminderDialog(row); |
| | | // }, |
| | | // }, |
| | | { |
| | | name: "详情", |
| | | type: "text", |
| | | clickFun: row => { |
| | | openDetailDialog(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "详情", |
| | | type: "text", |
| | | clickFun: row => { |
| | | openDetailDialog(row); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | |
| | | taxpayerIdentificationNumber: "", |
| | | companyAddress: "", |
| | | regions: "", |
| | | regionsId: "", |
| | | regionsld: "", |
| | | companyPhone: "", |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | |
| | | }, |
| | | rules: { |
| | | customerName: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | taxpayerIdentificationNumber: [ |
| | | { required: true, message: "请输入", trigger: "blur" }, |
| | | ], |
| | | companyAddress: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | regions: [{ required: true, message: "请选择客户地区", trigger: "change" }], |
| | | companyPhone: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | // contactPerson: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | // contactPhone: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | maintainer: [{ required: false, message: "请选择", trigger: "change" }], |
| | | maintenanceTime: [ |
| | | { required: false, message: "请选择", trigger: "change" }, |
| | | ], |
| | | basicBankAccount: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | bankAccount: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | bankCode: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | customerType: [{ required: true, message: "请选择", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const upload = reactive({ |
| | |
| | | const addRegionDialogVisible = ref(false); |
| | | const editRegionDialogVisible = ref(false); |
| | | const addRegionForm = reactive({ parentPath: [], regionsName: "" }); |
| | | const editRegionForm = reactive({ id: undefined, parentId: 0, regionsName: "" }); |
| | | const editRegionForm = reactive({ |
| | | id: undefined, |
| | | parentId: 0, |
| | | regionsName: "", |
| | | }); |
| | | const regionTreeProps = { label: "label", children: "children" }; |
| | | const regionCascaderProps = { |
| | | value: "id", |
| | |
| | | regionsName: item.regionsName || item.label || "", |
| | | children: normalizeRegionTree(item.children || []), |
| | | })); |
| | | }; |
| | | const onClose = () => { |
| | | upload.open = false; |
| | | proxy.$refs["uploadRef"].clearFiles(); |
| | | }; |
| | | |
| | | const fetchRegions = async () => { |
| | |
| | | editRegionForm.id = selectedRegionNode.value.id; |
| | | editRegionForm.parentId = selectedRegionNode.value.parentId || 0; |
| | | editRegionForm.regionsName = |
| | | selectedRegionNode.value.regionsName || selectedRegionNode.value.label || ""; |
| | | selectedRegionNode.value.regionsName || |
| | | selectedRegionNode.value.label || |
| | | ""; |
| | | editRegionDialogVisible.value = true; |
| | | }; |
| | | const closeEditRegionDialog = () => { |
| | |
| | | const ids = value || []; |
| | | if (!ids.length) { |
| | | form.value.regions = ""; |
| | | form.value.regionsId = ""; |
| | | form.value.regionsld = ""; |
| | | return; |
| | | } |
| | | const lastId = ids[ids.length - 1]; |
| | | form.value.regions = regionNodeMap.value.get(lastId)?.regionsName || ""; |
| | | form.value.regionsId = lastId; |
| | | form.value.regionsld = lastId; |
| | | }; |
| | | const findRegionPathByName = (tree, targetName, parentPath = []) => { |
| | | for (const item of tree || []) { |
| | |
| | | if ((item.regionsName || item.label) === targetName) { |
| | | return currentPath; |
| | | } |
| | | const childResult = findRegionPathByName(item.children || [], targetName, currentPath); |
| | | const childResult = findRegionPathByName( |
| | | item.children || [], |
| | | targetName, |
| | | currentPath |
| | | ); |
| | | if (childResult.length) return childResult; |
| | | } |
| | | return []; |
| | | }; |
| | | const findRegionPathById = (tree, targetId, parentPath = []) => { |
| | | if (targetId === undefined || targetId === null || targetId === "") return []; |
| | | for (const item of tree || []) { |
| | | const currentPath = [...parentPath, item.id]; |
| | | if (String(item.id) === String(targetId)) { |
| | | return currentPath; |
| | | } |
| | | const childResult = findRegionPathById( |
| | | item.children || [], |
| | | targetId, |
| | | currentPath |
| | | ); |
| | | if (childResult.length) return childResult; |
| | | } |
| | | return []; |
| | |
| | | operationType.value = type; |
| | | form.value = {}; |
| | | formRegionPath.value = []; |
| | | form.value.regionsId = ""; |
| | | form.value.regionsld = ""; |
| | | form.value.maintainer = userStore.nickName; |
| | | formYYs.value.contactList = [ |
| | | { |
| | |
| | | if (type === "edit") { |
| | | getCustomer(row.id).then(res => { |
| | | form.value = { ...res.data }; |
| | | formRegionPath.value = findRegionPathByName( |
| | | const regionIdForEdit = form.value.regionsId || form.value.regionsld; |
| | | formRegionPath.value = findRegionPathById( |
| | | regionTreeData.value, |
| | | form.value.regions || "" |
| | | regionIdForEdit |
| | | ); |
| | | if (!formRegionPath.value.length) { |
| | | formRegionPath.value = findRegionPathByName( |
| | | regionTreeData.value, |
| | | form.value.regionsName || form.value.regions || "" |
| | | ); |
| | | } |
| | | const selectedRegionId = |
| | | formRegionPath.value.length > 0 |
| | | ? formRegionPath.value[formRegionPath.value.length - 1] |
| | | : ""; |
| | | if (selectedRegionId && !form.value.regions) { |
| | | form.value.regions = |
| | | regionNodeMap.value.get(selectedRegionId)?.regionsName || ""; |
| | | } |
| | | form.value.regionsId = form.value.regionsId || selectedRegionId; |
| | | form.value.regionsld = |
| | | form.value.regionsld || form.value.regionsId || selectedRegionId; |
| | | formYYs.value.contactList = res.data.contactPerson |
| | | .split(",") |
| | | .map((item, index) => { |
| | |
| | | form.value.contactPhone = formYYs.value.contactList |
| | | .map(item => item.contactPhone) |
| | | .join(","); |
| | | if (!form.value.regionsId && formRegionPath.value.length) { |
| | | form.value.regionsId = |
| | | formRegionPath.value[formRegionPath.value.length - 1]; |
| | | } |
| | | form.value.regionsld = form.value.regionsId || ""; |
| | | addCustomer(form.value).then(res => { |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | closeDia(); |
| | |
| | | form.value.contactPhone = formYYs.value.contactList |
| | | .map(item => item.contactPhone) |
| | | .join(","); |
| | | if (!form.value.regionsId && formRegionPath.value.length) { |
| | | form.value.regionsId = |
| | | formRegionPath.value[formRegionPath.value.length - 1]; |
| | | } |
| | | form.value.regionsld = form.value.regionsId || ""; |
| | | updateCustomer(form.value).then(res => { |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | closeDia(); |
| | |
| | | .toolbar-divider { |
| | | width: 1px; |
| | | align-self: stretch; |
| | | background: linear-gradient(to bottom, transparent, #e4e7ed 15%, #e4e7ed 85%, transparent); |
| | | background: linear-gradient( |
| | | to bottom, |
| | | transparent, |
| | | #e4e7ed 15%, |
| | | #e4e7ed 85%, |
| | | transparent |
| | | ); |
| | | } |
| | | |
| | | .action-buttons { |