@touchmove.prevent 阻止苹果手机透过modal层触发底层滚动

这篇博客介绍了如何通过在Modal的下一层添加一个带有`@touchmove.prevent`的`<div>`元素,来阻止页面的滚动。这个方法在移动端尤其有用,可以确保Modal窗口打开时,用户无法无意中滚动到主内容区域。

<div

class="share-loading-mask"

@touchmove.prevent

></div>

在modal层的下一层添加这一个盒子,能够阻止主层的滚动

<template> <div class="sec-container"> <van-popup v-model:show="showFeedbackModal" :style="{ width: '100%', height: '100%', overflow: 'auto' }" position="right" round closeable @close="handleFeedbackClose" > <!-- 炉批号--> <van-popup v-model:show="heatModal" :style="{ width: '100%', height: '100%', overflow: 'auto' }" position="right" round closeable :lock-scroll="true" @close="handleHeatClose" > <van-field v-model="heatData.heatNo" clearable @click="handleHeatNo" label="炉号" is-link readonly /> <van-field v-model="heatData.batchNo" clearable @click="handleBatchNo" label="批号" is-link readonly /> <div class="search-btn"> <van-button type="primary" @click="commitHeat" style="margin-left: 5px">提交 </van-button> </div> </van-popup> <!-- 异常--> <van-popup v-model:show="exceptionModal" :style="{ width: '100%', height: '100%', overflow: 'auto' }" position="right" round closeable @close="handleExceptionModalClose" > <van-field v-model="exceptionParam.exceptionType" clearable @click="handleExceptionType" label="异常类型" is-link readonly /> <van-field v-model="exceptionParam.exceptionMsg" rows="3" autosize label="异常描述" type="textarea" maxlength="500" placeholder="请输入异常描述" show-word-limit /> <div class="search-btn"> <van-button type="primary" @click="commitException">提交 </van-button> </div> </van-popup> <!-- 异常类型选择--> <van-popup v-model:show="showPicker" round position="bottom"> <van-picker :columns="exceptionTypeList" @cancel="showPicker = false" @confirm="onExceptionTypeConfirm" /> </van-popup> <!-- 炉号选择--> <van-popup v-model:show="showHeatNoPicker" round position="bottom"> <van-picker :columns="heatNoList" @cancel="showHeatNoPicker = false" @confirm="onHeatNoConfirm" /> </van-popup> <!-- 批号选择--> <van-popup v-model:show="showBatchNoPicker" round position="bottom"> <van-picker :columns="batchNoList" @cancel="showBatchNoPicker = false" @confirm="onBatchNoConfirm" /> </van-popup> <!-- root选择--> <van-popup v-model:show="showRootPicker" round position="bottom"> <van-picker :columns="rootBatchNoList" @cancel="showRootPicker = false" @confirm="onRootConfirm" /> </van-popup> <!-- fill选择--> <van-popup v-model:show="showFillPicker" round position="bottom"> <van-picker :columns="fillBatchNoList" @cancel="showFillPicker = false" @confirm="onFillConfirm" /> </van-popup> <!-- wps选择--> <van-popup v-model:show="showWpsModal" :style="{ width: '100%', height: '100%', overflow: 'auto' }" position="right" round closeable @close="handleWpsClose" > <a-table sticky style="width: 98%" :scroll="{ x: '100%' }" :columns="wpsColumns" :dataSource="addWpsData" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" > <template #bodyCell="{ column, record }"> <template v-if="column.key === 'action'"> <a-button type="link" @click="addWps(record)" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >添加</a-button > </template> </template> </a-table> </van-popup> <!-- 焊缝批号选择--> <van-popup v-model:show="showWeldHeatModal" :style="{ width: '100%', height: '100%', overflow: 'auto' }" position="right" round closeable @close="handleWeldHeatClose" > <van-field v-model="weldHeatData.rootBatchNo" clearable @click="handleRoot" label="root" is-link readonly /> <van-field v-model="weldHeatData.fillBatchNo" clearable @click="handleFill" label="fill" is-link readonly /> <div class="search-btn"> <van-button type="primary" @click="commitWeldHeat">提交 </van-button> </div> </van-popup> <!-- 新增小票明细--> <van-popup v-model:show="showCutFeedbackAddModal" :style="{ width: '100%', height: '100%', overflow: 'auto' }" position="right" round closeable @close="handleCutFeedbackAddClose" > <a-table sticky v-if="feedbackType === '下料' || feedbackType === '装配'" style="width: 98%" :scroll="{ x: '100%' }" :columns="cutColumns" :dataSource="addCutData" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" > <template #bodyCell="{ column, record }"> <template v-if="column.key === 'action'"> <a-button type="link" @click="addData(record)" :disabled="record.canFeedback==false" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >添加</a-button > </template> </template> </a-table> <a-table sticky v-if="feedbackType === '焊接'" style="width: 98%" :scroll="{ x: '100%' }" :columns="weldColumns" :dataSource="addWeldData" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" > <template #bodyCell="{ column, record }"> <template v-if="column.key === 'action'"> <a-button type="link" @click="addData(record)" :disabled="record.canFeedback==false" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >添加</a-button > </template> </template> </a-table> </van-popup> <van-cell-group :title=" feedbackType === '下料' ? '管路下料反馈' : feedbackType === '装配' ? '管路装配反馈' : '管路焊接反馈' " > <van-field v-model="feedbackParam.workDate" is-link readonly clearable label="反馈日期" placeholder="请选择反馈日期" @click="showDatePicker = true" /> <van-field v-model="feedbackParam.remark" rows="3" autosize label="备注" type="textarea" maxlength="500" placeholder="请输入备注" show-word-limit /> <van-field v-model="feedbackParam.helperName" autosize label="协助人名" readonly v-if="feedbackType === '焊接'" /> <van-field v-model="feedbackParam.helperNo" label="协助人IC号" @input="inputHelperNo" placeholder="请输入协助人IC号" v-if="feedbackType === '焊接'" /> <div class="search-btn"> <van-button type="primary" @click="addFeedbackDetail" style="margin-left:5px;margin-right: 10px">添加物量</van-button> <van-button type="primary" @click="commitFeedbackDetail">提交</van-button> <a-table sticky v-if="feedbackType === '下料'" :scroll="{ x: '100%' }" style="width: 98%" :columns="cutColumns" :dataSource="cutData" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" > <template #bodyCell="{ column, record }"> <template v-if="column.key === 'action'"> <a-button type="link" @click="delCutData(record)" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >删除</a-button > <a-button type="link" @click="saveException(record)" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >异常上报</a-button > </template> </template> </a-table> <a-table sticky v-if="feedbackType === '装配'" :scroll="{ x: '100%' }" style="width: 98%" :columns="assyColumns" :dataSource="partData" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" > <template #bodyCell="{ column, record }"> <template v-if="column.key === 'action'"> <a-button type="link" @click="delAssyData(record)" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >删除</a-button > <a-button type="link" @click="saveException(record)" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >异常上报</a-button > <a-button type="link" @click="saveHeat(record)" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >选择炉批号</a-button > </template> </template> </a-table> <a-table sticky v-if="feedbackType === '装配' || feedbackType === '焊接'" :scroll="{ x: '100%' }" style="width: 98%" :columns="weldingColumns" :dataSource="weldData" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" > <template #bodyCell="{ column, record }"> <template v-if="column.key === 'action'"> <a-button type="link" @click="delWeldData(record)" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >删除</a-button > <a-button type="link" @click="saveException(record)" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >异常上报</a-button > <a-button type="link" @click="saveWps(record)" v-if="feedbackType === '焊接'" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >选择WPSNo</a-button > <a-button type="link" @click="saveWeldHeat(record)" v-if="feedbackType === '焊接'" v-resource="[ { url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' } ]" >选择批号</a-button > </template> </template> </a-table> </div> </van-cell-group> <van-calendar v-model:show="showDatePicker" @confirm="onDateConfirm" /> </van-popup> <van-popup v-model:show="showDetailModal" :style="{ width: '100%', height: '100%', overflow: 'auto' }" position="right" round closeable @close="handleDetailClose" > <van-cell-group title="管路下料数据" v-if="detailType === '下料'"> <van-field name="projectNo" label="项目"> <template #input> {{ detailTable.dataSource.length > 0 ? detailTable.dataSource[0].printName : '' }} </template> </van-field> <van-field name="inspClass" label="派工单号"> <template #input> {{ detailTable.dataSource.length > 0 ? detailTable.dataSource[0].orderNo : '' }} ({{ detailTable.dataSource.length > 0 ? detailTable.dataSource[0].shopMatOrderNo : '' }}) </template> </van-field> </van-cell-group> <van-cell-group title="材料清单" v-if="detailType === '装配'"> <van-field name="projectNo" label="项目"> <template #input> {{ detailTable.dataSource.length > 0 ? detailTable.dataSource[0].projectNo : '' }} </template> </van-field> <van-field name="inspClass" label="派工单号"> <template #input> {{ detailData.orderNo }} </template> </van-field> <van-field name="inspClass" label="下料领料单"> <template #input> {{ detailData.cutMatListNo }} </template> </van-field> <van-field name="inspClass" label="装配领料单"> <template #input> {{ detailData.assyMatListNo }} </template> </van-field> </van-cell-group> <van-cell-group title="装配套料件材料清单" v-if="detailType === 'nesting'"> <van-field name="inspClass" label="派工单号"> <template #input> {{ detailTable.dataSource.length > 0 ? detailTable.dataSource[0].orderNo : '' }} </template> </van-field> </van-cell-group> <van-form ref="addCommentsFormRef" @submit="handleSave"> <a-table sticky :scroll="{ x: '100%' }" :columns=" detailType == 'show' ? detailTable.columns : detailType == '下料' ? detailTable.cutColumns : detailType == '装配' ? detailTable.assyColumns : detailTable.nestingColumns " style="width: 98%" :dataSource="detailTable.dataSource" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" ref="detailTableRef" > </a-table> </van-form> </van-popup> <div class="top-content"> <div class="project-content"> <div class=""></div> </div> <div class="btn-content"> <div class="btn-right" @click="openSearchDialog"> <SearchOutlined style="font-size: 20px; color: #004688" /> <p class="speNorm">搜索</p> </div> </div> </div> <div class="bot-content" @scroll="handleScroll"> <a-table sticky :scroll="{ x: '100%' }" :columns="columns" :dataSource="data" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" > <template #bodyCell="{ column, record }"> <template v-if="column.key === 'action'"> <a-button type="link" @click="showData(record, 'show')" v-resource="[{ url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' }]" >查看</a-button > <a-button type="link" @click="showData(record, '下料')" v-resource="[{ url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' }]" >下料单</a-button > <a-button type="link" @click="showData(record, '装配')" v-resource="[{ url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' }]" >材料单</a-button > <a-button type="link" @click="showData(record, 'nesting')" v-resource="[{ url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' }]" >套料件材料单</a-button > <a-button type="link" @click="feedback(record, '下料')" v-resource="[{ url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' }]" >下料反馈</a-button > <a-button type="link" @click="feedback(record, '装配')" v-resource="[{ url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' }]" >装配反馈</a-button > <a-button type="link" @click="feedback(record, '焊接')" v-resource="[{ url: '/service-piping/cp/pipe/pre/work/order/detail', method: 'GET' }]" >焊接反馈</a-button > </template> </template> </a-table> </div> <van-popup v-model:show="searchOpen" position="right" :style="{ width: popupWidth, height: '100%', overflow: 'hidden' }" round closeable @close="handleDetailClose" > <div class="search-content"> <div class="search-top"> <div class="search-project-back" v-if="projectType" @click="handleBack"> <LeftOutlined style="font-size: 15px; color: #004688; margin-top: 3px" />返回 </div> <div class="search-titles"> <span>{{ !projectType ? '搜索' : '搜索项目' }}</span> </div> </div> <div class="search-state"> <van-cell-group inset> <van-field v-model="searchState.projectNo" clearable label="项目" readonly @click="handleProject" /> <van-field v-model="searchState.orderNo" clearable label="派工单号" placeholder="请输入派工单号" /> </van-cell-group> <project-panel ref="projectpanelRef" @get="getProj"></project-panel> </div> <div class="search-btn"> <van-button type="warning" color="#9A9A9A" @click="onReset">重置</van-button> <van-button type="primary" @click="onSearch">查询 </van-button> </div> </div> </van-popup> </div> </template> <script setup> import { ref, onMounted, onUnmounted, onActivated, computed, watch, createVNode, reactive } from 'vue' import { SearchOutlined, LeftOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue' import * as serve from '@/api/cp/pipeOrderInfo' import ProjectPanel from '@/components/ProjectPanel.vue' import dayjs from 'dayjs' import { Buffer } from 'buffer' import localforage from 'localforage' import { useHomePage } from '@/stores/homePage' import { Modal } from 'ant-design-vue' import { getBuildBases } from '@/api/common/index.js' import { showConfirmDialog, showNotify } from 'vant' import { cloneDeep } from 'lodash-es' const showFillPicker = ref(false) const showRootPicker = ref(false) const submitting = ref(false) const orgNo = ref(undefined) const orderNo = ref(undefined) const projectNo = ref(undefined) const pipeNo = ref(undefined) const pipeVersion = ref(undefined) const showDatePicker = ref(false) const feedbackParam = ref({}) const exceptionParam = ref({}) const detailData = ref({}) const applyDate = ref(undefined) const weldTable = reactive({ toolbar: { // buttons: [{ code: "addCar", name: "添加物料" }] }, resToolbar: { buttons: [ { code: 'qualifiedWeld', name: '合格' }, { code: 'unqualifiedWeld', name: '不合格' }, { code: 'cancelWeld', name: '取消' } ] }, selectedRowKeys: [], selectedRows: [], columns: [ { title: '管号', dataIndex: 'pipeNo', width: 120 }, { title: '焊缝号', dataIndex: 'weldNo', width: 150 }, { title: '焊缝长度', dataIndex: 'length', width: 150 }, { title: '焊接日期', type: 'date', dataIndex: 'weldDate', width: 150 } // { // title: "操作", // key: "action", // align: "center", // width: 90, // sorter: false, // scopedSlots: { customRender: "action" }, // fixed: "right", // formInvisible: true // } ], resColumns: [ { title: '项目', dataIndex: 'projectNo', width: 90, type: 'project' }, { title: '管号', dataIndex: 'pipeNo', width: 120 }, { title: '版本号', dataIndex: 'pipeVersion', width: 120 }, { title: '焊缝号', dataIndex: 'weldNo', width: 150 }, { title: '检验结果', dataIndex: 'status', type: 'select', width: 80, customRender: function (text) { if (text.record.status) { return stateColumns.value.find((item) => item.value == text.record.status).text } else { return '新建' } } }, { title: '小票删除', dataIndex: 'pipeDelFlag', width: 80 }, { title: '小票暂停', dataIndex: 'pipePauseFlag', width: 80 }, { title: '小票最新版', dataIndex: 'pipeTopFlag', width: 80 }, { title: '焊缝删除', dataIndex: 'delFlag', width: 80 }, { title: '操作', key: 'action', align: 'center', width: 200, sorter: false, scopedSlots: { customRender: 'action' }, fixed: 'right', formInvisible: true } ], dataSource: [] }) const detailType = ref('') const feedbackType = ref('') const showType = ref('') window.Buffer = Buffer const homePage = useHomePage() const saveData = ref({}) const stateColumns = ref([ { value: 0, text: '新建' }, { value: -1, text: '不合格' }, { value: 1, text: '检验中' }, { value: 2, text: '合格' } ]) const showDetailModal = ref(false) const showFeedbackModal = ref(false) const showCutFeedbackAddModal = ref(false) const showWpsModal = ref(false) const showWeldHeatModal = ref(false) const showPicker = ref(false) const showHeatNoPicker = ref(false) const showBatchNoPicker = ref(false) const buildBaseList = ref([]) const data = ref([]) const cutData = ref([]) const partData = ref([]) const weldData = ref([]) const addCutData = ref([]) // const addPartData = ref([]) const loading = ref(false) const dataCount = ref(0) const searchState = ref({ size: 20, page: 0, projectNo: undefined, inspClass: undefined, orderNo: undefined }) const searchOpen = ref(false) const projectpanelRef = ref(null) const projectType = ref(false) const popupWidth = ref('30%') const isLast = ref(false) const detailTable = reactive({ toolbar: { buttons: [{ code: 'addPipe', name: '添加物料' }] }, resToolbar: { buttons: [ { code: 'qualifiedPipe', name: '合格' }, { code: 'unqualifiedPipe', name: '不合格' }, { code: 'cancelPipe', name: '取消' } ] }, selectedRowKeys: [], selectedRows: [], columns: [ { title: '项目', dataIndex: 'projectNo', width: 50, condition: true, type: 'project', options: { options: [], fieldNames: { label: 'projId', value: 'projId' } } }, { title: '图号', dataIndex: 'drawNo', width: 170 }, { title: '作业对象', dataIndex: 'block', width: 70 }, { title: '小票号', dataIndex: 'pipeNo', width: 150 }, { title: '版本号', dataIndex: 'pipeVersion', width: 60 }, { title: '最新版', dataIndex: 'isTopVersion', width: 60, type: 'select', options: { options: [ { label: 'Y', value: 'Y' }, { label: 'N', value: 'N' } ] } }, { title: '是否删除', dataIndex: 'isDelete', width: 80, type: 'select', options: { options: [ { label: 'Y', value: 'Y' }, { label: 'N', value: 'N' } ] } }, { title: '是否暂停', dataIndex: 'isPause', width: 80, type: 'select', options: { options: [ { label: 'Y', value: 'Y' }, { label: 'N', value: 'N' } ] } }, { title: '下料定额工时', dataIndex: 'cutQuotaWorkhour', width: 100 }, { title: '装配定额工时', dataIndex: 'assyQuotaWorkhour', width: 100 }, { title: '焊接定额工时', dataIndex: 'weldingQuotaWorkhour', width: 100 }, { title: '下料完成时间', dataIndex: 'realCutFinishDate', type: 'date', width: 100 }, { title: '装配完成时间', dataIndex: 'realAssyFinishDate', type: 'date', width: 100 }, { title: '焊接完成时间', dataIndex: 'realWeldingFinishDate', type: 'date', width: 100 } ], assyColumns: [ { title: '管号', dataIndex: 'pipeNo', width: 90 }, { title: '页号', dataIndex: 'pageNo', width: 90 }, { title: '件号', dataIndex: 'partNo', width: 90 }, { title: '零件描述', dataIndex: 'erpMatDesc', width: 90 }, { title: '物资编码', dataIndex: 'matNo', width: 90 }, { title: '物资描述', dataIndex: 'matDesp', width: 90 }, { title: '零件备注', dataIndex: 'cutRemark', width: 90 }, { title: '涂装代码', dataIndex: 'paintNo', width: 90 }, { title: '总', dataIndex: 'total', width: 90 }, { title: '需求', dataIndex: 'needNum', width: 90 }, { title: '使用余料', dataIndex: 'isUsedShopMat', width: 90 } ], nestingColumns: [ { title: '图纸号', dataIndex: 'drawNo', width: 90 }, { title: '管号', dataIndex: 'pipeNo', width: 90 }, { title: '件号', dataIndex: 'partNo', width: 90 }, { title: '零件描述', dataIndex: 'matDesp', width: 90 }, { title: '套料图号', dataIndex: 'cutBomPrintNo', width: 90 }, { title: '套料件号', dataIndex: 'partNumber', width: 90 }, { title: '材质', dataIndex: 'material', width: 90 }, { title: '板厚', dataIndex: 'partThickness', width: 90 }, { title: 'CJP', dataIndex: 'cjp', width: 90 }, { title: '筐号', dataIndex: 'basketNo', width: 90 } ], cutColumns: [ { title: '分段', dataIndex: 'block', width: 90 }, { title: '图纸号', dataIndex: 'drawNo', width: 120 }, { title: '小票号', dataIndex: 'pipeNo', width: 120 }, { title: '等级', dataIndex: 'pipeClass', width: 80 }, { title: '材料名', dataIndex: 'materialDesp', width: 80 }, { title: '页数', dataIndex: 'pageNo', width: 80 }, { title: '管段', dataIndex: 'info', width: 80 }, { title: '管长MM', dataIndex: 'length', width: 80 }, { title: '弯管', dataIndex: 'groove', width: 80 }, { title: '备注', dataIndex: 'cutRemark', width: 80 }, { title: '炉号', dataIndex: 'heatNo', width: 80 }, { title: '通舱件', dataIndex: 'isThroughCabin', width: 80 }, { title: '修改方式', dataIndex: 'modifyType', width: 80 } ], dataSource: [] }) const columns = computed(() => { return [ { title: '操作', dataIndex: 'action', width: 140, key: 'action' }, { title: '派工单号', dataIndex: 'orderNo', width: 120, condition: true }, { title: '基地', dataIndex: 'orgNo', type: 'buildCase', width: 80, condition: true }, { title: '总长度', dataIndex: 'totalLength', width: 70 }, { title: '总重量', dataIndex: 'totalWeight', width: 70 }, { title: '总寸口数', dataIndex: 'totalInch', width: 80 }, { title: '物量统计', dataIndex: 'pipeCount', width: 80 }, { title: '下料工位号', dataIndex: 'cutWorkSpaceNo', width: 80 }, { title: '下料开始日期', dataIndex: 'cutStartDate', type: 'date', width: 100 }, { title: '下料结束日期', dataIndex: 'cutEndDate', type: 'date', width: 100 }, { title: '下料状态', dataIndex: 'cutStatus', width: 80, type: 'select', options: { options: [ { value: 'Y', label: 'Y' }, { value: 'N', label: 'N' } ] } }, { title: '装配工位号', dataIndex: 'assyWorkSpaceNo', width: 80 }, { title: '装配工位类型', dataIndex: 'assyWorkSpaceType', width: 100 }, { title: '装配开始日期', dataIndex: 'assyStartDate', type: 'date', width: 100 }, { title: '装配结束日期', dataIndex: 'assyEndDate', type: 'date', width: 100 }, { title: '装配状态', dataIndex: 'assyStatus', width: 80, type: 'select', options: { options: [ { value: 'Y', label: 'Y' }, { value: 'N', label: 'N' } ] } }, { title: '焊接工位号', dataIndex: 'weldingWorkSpaceNo', width: 80 }, { title: '焊接工位类型', dataIndex: 'weldingWorkSpaceType', width: 100 }, { title: '焊接开始日期', dataIndex: 'weldingStartDate', type: 'date', width: 100 }, { title: '焊接结束日期', dataIndex: 'weldingEndDate', type: 'date', width: 100 }, { title: '焊接状态', dataIndex: 'weldingStatus', width: 80, type: 'select', options: { options: [ { value: 'Y', label: 'Y' }, { value: 'N', label: 'N' } ] } }, { title: '派工单状态', dataIndex: 'status', width: 100, type: 'select', formatter: (data) => data.cellValue == -1 ? '作废' : data.cellValue == 0 ? '新建' : data.cellValue == 1 ? '作业中' : data.cellValue == 2 ? '已完成' : '', options: { options: [ { value: -1, label: '作废' }, { value: 0, label: '新建' }, { value: 1, label: '作业中' }, { value: 2, label: '已完成' } ] } }, { title: '下料领料单号', dataIndex: 'cutMatListNo', width: 120 }, { title: '装配领料单号', dataIndex: 'assyMatListNo', width: 120 }, { title: '创建人', dataIndex: 'createUserNo', type: 'employeeDescription', options: { fieldNames: { label: 'createUserName', value: 'createUserNo' } }, width: 110 }, { title: '创建时间', dataIndex: 'createDataDate', formatter: ({ row }) => { return row.createDate ? dayjs(row.createDate).format('YYYY-MM-DD') : '-' }, width: 80, invisible: false, type: 'date' } ] }) const weldColumns = computed(() => { return [ { title: '操作', dataIndex: 'action', width: 140, key: 'action' }, { title: '项目', dataIndex: 'projectNo', width: 50, type: 'project', options: { options: [], fieldNames: { label: 'projId', value: 'projId' } } }, { title: '小票号', dataIndex: 'pipeNo', width: 150 }, { title: '版本号', dataIndex: 'pipeVersion', width: 60 }, { title: '焊缝号', dataIndex: 'weldNo', width: 170 }, { title: '描述', dataIndex: 'notFeedbackMsg', width: 80 } ] }) const cutColumns = computed(() => { return [ { title: '操作', dataIndex: 'action', width: 140, key: 'action' }, { title: '项目', dataIndex: 'projectNo', width: 50, type: 'project' }, { title: '小票号', dataIndex: 'pipeNo', condition: true, width: 150 }, { title: '版本号', condition: true, dataIndex: 'pipeVersion', width: 60 }, { title: '描述', dataIndex: 'notFeedbackMsg', width: 80 } ] }) const assyColumns = computed(() => { return [ { title: '操作', dataIndex: 'action', width: 140, key: 'action' }, { title: '项目', dataIndex: 'projectNo', width: 50 }, { title: '小票号', dataIndex: 'pipeNo', width: 150 }, { title: '版本号', dataIndex: 'pipeVersion', width: 60 }, { title: '零件号', dataIndex: 'partNo', width: 100 }, { title: '物资编码', dataIndex: 'matNo', width: 100 }, { title: '零件规格', dataIndex: 'partSize', width: 100 }, { title: '炉号', dataIndex: 'heatNo', width: 120 }, { title: '批号', dataIndex: 'batchNo', width: 120 } ] }) const weldingColumns = computed(() => { const baseColumns = [ { title: '操作', dataIndex: 'action', width: 140, key: 'action' }, { title: '项目', dataIndex: 'projectNo', width: 50 }, { title: '小票号', dataIndex: 'pipeNo', width: 150 }, { title: '版本号', dataIndex: 'pipeVersion', width: 60 }, { title: '焊缝号', dataIndex: 'weldNo', width: 170 } ]; // 只在焊接反馈时添加焊接相关列 if (feedbackType.value === '焊接') { return [ ...baseColumns, { title: 'WPS NO', dataIndex: 'wpsNo', width: 80 }, { title: '焊接方法', dataIndex: 'weldProcess', width: 100 }, { title: '焊材规格', dataIndex: 'weldingMatSpec', width: 150 }, { title: '批号', children: [ { title: '打底', dataIndex: 'rootBatchNo', width: 60 }, { title: '盖面', dataIndex: 'fillBatchNo', width: 60 } ], width: 120 }, { title: '证书', children: [ { title: '打底', dataIndex: 'rootWeldCert', width: 60 }, { title: '盖面', dataIndex: 'fillWeldCert', width: 60 } ], width: 120 } ]; } return baseColumns; }) const exceptionTypeList = ref([]) const heatNoList = ref([]) const batchNoList = ref([]) const exceptionModal = ref(false) const heatModal = ref(false) const heatData = ref({}) const partInfo = ref({}) const addWeldData = ref([]) const currentWeldData = ref({}) const addWpsData = ref([]) const wpsColumns = computed(() => { return [ { title: '操作', dataIndex: 'action', width: 140, key: 'action' }, { title: 'WPS NO', dataIndex: 'wpsNo', width: 80 }, { title: '焊接方法', dataIndex: 'process', width: 80 }, { title: '焊材规格', dataIndex: 'grade', width: 80 }, { title: '焊接类型', dataIndex: 'type', width: 80 } ] }) const rootBatchNoList = ref([]) const fillBatchNoList = ref([]) const rootBatchNoOldList = ref([]) const fillBatchNoOldList = ref([]) const weldHeatData = ref({}) const onDateConfirm = (val) => { let resDate = dayjs(val).format('YYYY-MM-DD') feedbackParam.value.workDate = resDate showDatePicker.value = false } const loadData = (type) => { loading.value = true serve.getOrderList(searchState.value).then(async (res) => { if (type == 'scroll') { data.value.push(...res.content) } else { data.value = res.content } dataCount.value = res.totalElements || 0 isLast.value = res.last loading.value = false }) } const handleScroll = (e) => { const element = e.target if (element.scrollTop + element.clientHeight >= element.scrollHeight) { if (!isLast.value) { searchState.value.page++ loadData('scroll') } } } const openSearchDialog = () => { searchOpen.value = true } const handleProject = () => { projectType.value = true projectpanelRef.value.open = true projectpanelRef.value.init() } const handleBack = () => { projectType.value = false projectpanelRef.value.open = false } const handleClose = () => { projectType.value = false projectpanelRef.value.open = false } const handleDetailClose = () => { showDetailModal.value = false } const handleFeedbackClose = () => { showFeedbackModal.value = false } const handleCutFeedbackAddClose = () => { showCutFeedbackAddModal.value = false } const handleWpsClose = () => { showWpsModal.value = false } const handleWeldHeatClose = () => { weldHeatData.value = {} showWeldHeatModal.value = false } const handleExceptionModalClose = () => { exceptionModal.value = false } const handleHeatClose = () => { heatModal.value = false } const handleResize = () => { if (window.innerWidth < 1000) { popupWidth.value = '60%' } else { popupWidth.value = '30%' } } const getProj = (val) => { searchState.value.projectNo = val.projId searchState.value.projNo = val.projNo handleClose() } const onSearch = () => { searchState.value.page = 0 loadData() searchOpen.value = false } const onReset = () => { searchState.value.page = 0 searchState.value.projectNo = undefined searchState.value.projNo = undefined searchState.value.inspClass = undefined searchState.value.orderNo = undefined } const handleBeforeUnload = () => { if (!homePage.isOnline) { Modal.confirm({ title: '浏览器当前处于离线状态,是否继续?', icon: createVNode(ExclamationCircleOutlined), content: createVNode( 'div', { style: 'color:red;' }, '一旦刷新,将无法继续使用' ), onOk() { console.log('OK') }, onCancel() { console.log('Cancel') } }) } } watch( () => homePage.isOnline, async (newVal) => { if (!newVal) { try { const listData = await localforage.getItem('downloadList') if (listData) { const list = JSON.parse(listData) list.forEach((item) => { item.isDownload = true }) data.value = list } } catch (error) { console.error('Error parsing list data:', error) } } else { onReset() loadData() } } ) onMounted(() => { getBuildBase() if (homePage.isOnline) { loadData() } serve.getDislist({ code: 'CP_EXCEPTION_TYPE' }).then((res) => { exceptionTypeList.value = res.map((item) => ({ text: item.name, value: item.name })) }) handleResize() window.addEventListener('resize', handleResize) window.addEventListener('beforeunload', handleBeforeUnload) }) onUnmounted(() => { window.removeEventListener('resize', handleResize) window.removeEventListener('beforeunload', handleBeforeUnload) }) onActivated(async () => { if (!homePage.isOnline) { try { const listData = await localforage.getItem('downloadList') if (listData) { const list = JSON.parse(listData) list.forEach((item) => { item.isDownload = true }) data.value = list } } catch (error) { console.error('Error parsing list data:', error) } } }) const getBuildBase = () => { getBuildBases().then((res) => { buildBaseList.value = res.map((item) => ({ value: item.orgNo, text: item.name })) }) } const feedback = (record, type) => { console.log('feedbackType', type) feedbackType.value = type feedbackParam.value = {} orgNo.value = record.orgNo orderNo.value = record.orderNo projectNo.value = record.projectNo if (type == '下料') { cutData.value = [] } else if (type == '装配') { partData.value = [] weldData.value = [] } else if (type == '焊接') { weldData.value = [] } console.log('record', record) console.log('orderNo.value', orderNo.value) showFeedbackModal.value = true } const showData = (record, showTypeStr) => { detailType.value = showTypeStr orderNo.value = record.orderNo console.log('detailType.value', detailType.value) if (showTypeStr == 'show') { serve .getOrderDetail({ orderNo: record.orderNo, projectNo: record.projectNo }) .then((res) => { console.log(res) detailTable.dataSource = res showDetailModal.value = true }) } else if (showTypeStr == '下料') { serve.getPreCutWorkOrderPrintList({ orderNo: record.orderNo }).then((res) => { if (!res.error) { detailData.value = res[0] detailTable.dataSource = res[0].matList console.log('res', res[0]) console.log('res.matList', res[0].matList) showDetailModal.value = true } }) } else if (showTypeStr == '装配') { serve.getPreAssyWorkOrderPrintList({ orderNo: record.orderNo }).then((res) => { if (!res.error) { detailData.value = res detailTable.dataSource = res.matList console.log('res', res) console.log('res.matList', res.matList) showDetailModal.value = true } }) } else if (showTypeStr == 'nesting') { serve.getPreNestingPartPrintList({ orderNo: record.orderNo }).then((res) => { if (!res.error) { detailTable.dataSource = res console.log('res', res) showDetailModal.value = true } }) } } const handleSave = () => { if (showType.value == 'qcOrder') { console.log('applyDate', applyDate.value) let saveApplyData = { id: saveData.value.id, applyDate: dayjs(applyDate.value) } if (!saveApplyData.applyDate) { showNotify({ type: 'success', message: '请选择日期' }) return } serve.applyOrder(saveApplyData).then(() => { showNotify({ type: 'success', message: '操作成功' }) }) } else { let param = cloneDeep(saveData.value) if (showType.value == 'result') { param.editType = 1 param.id = saveData.value.id } else { param.getEditType = 0 if ('edit' == showType.value) { param.id = saveData.value.id } } if (param.mainUserNo && param.mainUserNo.value) { param.mainUserName = param.mainUserNo.label param.mainUserNo = param.mainUserNo.value } else { param.mainUserNo = '' } param.pipeList = detailTable.dataSource param.weldList = weldTable.dataSource serve.saveOrderList(param).then(() => { showNotify({ type: 'success', message: '操作成功' }) // if(type.value != 'result'){ showDetailModal.value = false // } }) } } const addFeedbackDetail = () => { if (feedbackType.value == '下料') { serve.findCutNotFeedbackPipe({ orderNo: orderNo.value }).then((res) => { addCutData.value = res }) } else if (feedbackType.value == '装配') { serve.findAssyNotFeedbackPipe({ orderNo: orderNo.value }).then((res) => { addCutData.value = res }) } else if (feedbackType.value == '焊接') { serve.findWeldingNotFeedbackPipe({ orderNo: orderNo.value }).then((res) => { addWeldData.value = res }) } showCutFeedbackAddModal.value = true } const addData = (record) => { console.log('record', record) let dataSource = [] if (feedbackType.value == '下料') { dataSource = cutData.value } else if (feedbackType.value == '装配') { dataSource = partData.value } else if (feedbackType.value == '焊接') { dataSource = weldData.value } let isExist = true if (feedbackType.value == '焊接') { isExist = dataSource.some( (dataItem) => dataItem.projectNo === record.projectNo && dataItem.pipeNo === record.pipeNo && dataItem.pipeVersion === record.pipeVersion && dataItem.weldNo === record.weldNo ) } else { isExist = dataSource.some( (dataItem) => dataItem.projectNo === record.projectNo && dataItem.pipeNo === record.pipeNo && dataItem.pipeVersion === record.pipeVersion ) } if (isExist) { showNotify({ type: 'danger', message: '此条数据已添加到反馈清单!' }) return } else { if (feedbackType.value == '下料') { cutData.value.push(record) showNotify({ type: 'success', message: '添加成功!' }) } else if (feedbackType.value == '装配') { console.log('装配') console.log('record.partData.value', partData.value) console.log('record.preFeedbackPartList', record.preFeedbackPartList) if (record.preFeedbackPartList.length > 0) { partData.value.push(...record.preFeedbackPartList) } if (record.preFeedbackWeldList.length > 0) { weldData.value.push(...record.preFeedbackWeldList) } showNotify({ type: 'success', message: '添加成功!' }) } else if (feedbackType.value == '焊接') { weldData.value.push(record) showNotify({ type: 'success', message: '添加成功!' }) } } } const delCutData = (record) => { cutData.value = cutData.value.filter((x) => { return !( x.projectNo === record.projectNo && x.pipeNo === record.pipeNo && x.pipeVersion === record.pipeVersion ) }) } const delAssyData = (record) => { showConfirmDialog({ title: '请确认是否要进行删除', message: '该操作一旦执行无法撤回,并将删除该小票的所有零件?', confirmButtonText: '确认', cancelButtonText: '取消' }).then(() => { partData.value = partData.value.filter((x) => { return !( x.projectNo === record.projectNo && x.pipeNo === record.pipeNo && x.pipeVersion === record.pipeVersion ) }) }) } const delWeldData = (record) => { weldData.value = weldData.value.filter((x) => { return !( x.projectNo === record.projectNo && x.pipeNo === record.pipeNo && x.pipeVersion === record.pipeVersion && x.weldNo === record.weldNo ) }) } const handleExceptionType = () => { showPicker.value = true } const handleHeatNo = () => { showHeatNoPicker.value = true } const handleRoot = () => { showRootPicker.value = true } const handleFill = () => { showFillPicker.value = true } const handleBatchNo = () => { showBatchNoPicker.value = true } const onExceptionTypeConfirm = ({ selectedOptions }) => { showPicker.value = false exceptionParam.value.exceptionType = selectedOptions[0].value console.log('exceptionParam', exceptionParam.value) } const commitException = () => { console.log('exceptionParam', exceptionParam.value) const submitData = [ { projectNo: projectNo.value, bomNo: pipeNo.value, bomVersion: pipeVersion.value, orgNo: orgNo.value, exceptionType: exceptionParam.value.exceptionType, exceptionMsg: exceptionParam.value.exceptionMsg } ] serve.postExceptionManage(submitData).then(() => { showNotify({ type: 'success', message: '上报成功!' }) exceptionModal.value = false }) } const saveException = (record) => { console.log('record', record) exceptionParam.value = {} projectNo.value = record.projectNo pipeNo.value = record.pipeNo pipeVersion.value = record.pipeVersion exceptionModal.value = true } const commitFeedbackDetail = () => { if (submitting.value) return submitting.value = true const submitData = { orderNo: orderNo.value, process: feedbackType.value, workDate: feedbackParam.value.workDate, remark: feedbackParam.value.remark, helperNo: feedbackParam.value.helperNo ? feedbackParam.value.helperNo : '', pipeList: cutData.value, partList: partData.value, weldList: weldData.value } let apiPromise if (feedbackType.value == '下料') { if (cutData.value.length == 0) { showNotify({ type: 'danger', message: '请选择下料数据!' }) submitting.value = false return } apiPromise = serve.cutFeedback(submitData) } else if (feedbackType.value == '装配') { if (partData.value.length == 0) { showNotify({ type: 'danger', message: '请选择零件数据!' }) submitting.value = false return } const pipeMap = new Map() cutData.value.forEach((pipeItem) => { const key = `${pipeItem.projectNo}-${pipeItem.pipeNo}-${pipeItem.pipeVersion}` pipeMap.set(key, { ...pipeItem, weldList: [] }) }) weldData.value.forEach((weldItem) => { const key = `${weldItem.projectNo}-${weldItem.pipeNo}-${weldItem.pipeVersion}` if (pipeMap.has(key)) { pipeMap.get(key).weldList.push(weldItem) } }) submitData.pipeList = Array.from(pipeMap.values()) delete submitData.weldList apiPromise = serve.assyFeedback(submitData) } else if (feedbackType.value == '焊接') { if (weldData.value.length == 0) { showNotify({ type: 'danger', message: '请选择焊接数据!' }) submitting.value = false return } apiPromise = serve.weldingFeedback(submitData) } apiPromise .then(() => { showNotify({ type: 'success', message: '反馈成功!' }) showFeedbackModal.value = false }) .finally(() => { submitting.value = false }) } const saveHeat = (record) => { console.log('saveHeat', record) heatData.value = {} partInfo.value = record heatNoList.value = [] serve.findHeatDropList({ heatNo: '', matNo: record.matNo }).then((res) => { heatNoList.value = res.map((item) => ({ value: item, text: item })) }) heatModal.value = true } const onHeatNoConfirm = ({ selectedOptions }) => { showHeatNoPicker.value = false heatData.value.heatNo = selectedOptions[0].value batchNoList.value = [] serve .findBatchDropList({ batchNo: '', matNo: partInfo.value.matNo, heatNo: heatData.value.heatNo }) .then((res) => { batchNoList.value = res.map((item) => ({ value: item, text: item })) }) console.log('heatData.value', heatData.value) } const onBatchNoConfirm = ({ selectedOptions }) => { showBatchNoPicker.value = false heatData.value.batchNo = selectedOptions[0].value console.log('heatData.value', heatData.value) } const commitHeat = () => { partData.value.forEach((x) => { if (x.id === partInfo.value.id) { x.heatNo = heatData.value.heatNo x.batchNo = heatData.value.batchNo } }) showNotify({ type: 'success', message: '操作成功' }) heatModal.value = false } const inputHelperNo = () => { console.log('feedbackParam.helperNo', feedbackParam.value.helperNo) feedbackParam.value.helperName = '获取失败' if (feedbackParam.value.helperNo.length >= 7) { serve.getUserByCode({ code: feedbackParam.value.helperNo }).then((res) => { console.log('res', res) if (res && res.name) { feedbackParam.value.helperName = res.name } }) } } const saveWps = (record) => { currentWeldData.value = record serve.getWldPiPeiWpsList({ weldId: record.id }).then((res) => { addWpsData.value = res showWpsModal.value = true }) } const addWps = (record) => { weldData.value.forEach((x) => { if (x.id === currentWeldData.value.id) { x.wpsNo = record.wpsNo x.weldProcess = record.process x.weldingMatSpec = record.grade x.rootGrade = record.rootGrade x.fillGrade = record.fillGrade } }) showNotify({ type: 'success', message: '操作成功' }) showWpsModal.value = false } const saveWeldHeat = (record) => { if (!record.wpsNo) { showNotify({ type: 'success', message: '请先选择wpsNo' }) return } currentWeldData.value = record serve.getQcWeldMatSnDropList({ grade: record.rootGrade }).then((res) => { rootBatchNoOldList.value = res rootBatchNoList.value = res.map((item) => ({ text: item.batchNo, value: item.batchNo })) serve.getQcWeldMatSnDropList({ grade: record.fillGrade }).then((fillRes) => { fillBatchNoOldList.value = fillRes fillBatchNoList.value = fillRes.map((item) => ({ text: item.batchNo, value: item.batchNo })) showWeldHeatModal.value = true }) }) } const onRootConfirm = ({ selectedOptions }) => { showRootPicker.value = false weldHeatData.value.rootBatchNo = selectedOptions[0].value const foundItem = rootBatchNoOldList.value.find( (item) => item.batchNo == weldHeatData.value.rootBatchNo ) if (foundItem) { weldHeatData.value.rootWeldCert = foundItem.certNo } } const onFillConfirm = ({ selectedOptions }) => { showFillPicker.value = false weldHeatData.value.fillBatchNo = selectedOptions[0].value const foundItem = fillBatchNoOldList.value.find( (item) => item.batchNo == weldHeatData.value.fillBatchNo ) if (foundItem) { weldHeatData.value.fillWeldCert = foundItem.certNo } } const commitWeldHeat = () => { weldData.value.forEach((x) => { if (x.id === currentWeldData.value.id) { x.rootBatchNo = weldHeatData.value.rootBatchNo x.fillBatchNo = weldHeatData.value.fillBatchNo x.rootWeldCert = weldHeatData.value.rootWeldCert x.fillWeldCert = weldHeatData.value.fillWeldCert } }) showNotify({ type: 'success', message: '操作成功' }) showWeldHeatModal.value = false } </script> <style lang="scss" scoped> :deep .urgentFlag-active { background: #ffb656; } :deep .abnormalFlag-active { background: #fb7171; } :deep .anticon-search { line-height: 0 !important; } @import '@/styles/common.scss'; .search-content { width: 100%; overflow: hidden; // height: 100%; .search-top { width: 100%; height: 50px; margin-top: 20px; display: flex; justify-content: center; align-content: center; .search-project-back { font-size: 14px; display: flex; align-content: center; position: absolute; left: 10px; color: #004688; } .search-titles { height: 100%; display: flex; justify-content: center; align-content: center; color: #004688; span { font-size: 15px; margin-left: 5px; } } } .search-state { width: 100%; height: calc(100% - 45px - 10px); position: absolute; bottom: 0; overflow: hidden; overflow-y: scroll; } } .action-buttons { display: flex; align-items: center; justify-content: space-around; } </style> 其中 <van-popup v-model:show="heatModal" :style="{ width: '100%', height: '100%', overflow: 'auto' }" position="right" round closeable :lock-scroll="true" @close="handleHeatClose" > <van-field v-model="heatData.heatNo" clearable @click="handleHeatNo" label="炉号" is-link readonly /> <van-field v-model="heatData.batchNo" clearable @click="handleBatchNo" label="批号" is-link readonly /> <div class="search-btn"> <van-button type="primary" @click="commitHeat" style="margin-left: 5px">提交 </van-button> </div> </van-popup>有滚动穿透的现象,向下滚动就出现背景的页面
11-13
<template> <view class="mask" :class="{ active: actives, show: show }" @tap="close" @touchmove.stop.prevent> <view class="pca-picker-box" @tap.stop> <view class="picker-head"> <text>请选择所在地区</text> <i @tap.stop="close" class="iconfont icon-guanbi"></i> </view> <view class="select-al-box"> <text v-for="(item, index) in selectAlList" :key="index" :index="item.title" :style="{ width: itemWidth + '%' }" class="select-al-item" @tap="selectAl(index)" :class="{ active: selectAlIndex === index }"> {{ item.title }} </text> </view> <swiper class="swiper-box" @change="selectAl" :current="currentIndex"> <swiper-item v-for="(item, index) in pcaList" :key="index" :index="index"> <scroll-view :scroll-into-view="'id' + item.target" class="adress-item" scroll-y="true"> <view v-for="(it, inx) in item.list" :id="'id' + it.value" class="item" :class="{ active: inx === item.selectIndex }" @tap="selectAddress(it, inx, index)"> <text class="iconfont icon-dagou-copy-copy">{{ it.text }}</text> </view> </scroll-view> </swiper-item> </swiper> </view> </view> </template> <script> // 本地数据示例 const localData = [ { text: '浙江省', value: '330000', children: [ { text: '杭州市', value: '330100', children: [ { text: '西湖区', value: '330106', children: [ { text: '文新街道', value: '330106001', children: [ { text: '星洲社区', value: '330106001001' } ] } ] } ] } ], }, { text: '江苏省', value: '320000', children: [ { text: '南京市', value: '320100', children: [ { text: '玄武区', value: '320102' } ] } ], } ]; let timmer = null; let limitRegionNum = { province: 1, city: 2, area: 3, street: 4, village: 5 }; function promiseContainer (fn, callback) { return new Promise((resolve, reject) => { fn(resolve, callback); }); } export default { props: { active: { type: Boolean, default: false }, defaultValue: { type: Object, default () { return { provinceCode: '', citiesCode: '', areasCode: '', streetsCode: '', villagesCode: '' }; } }, limitRegion: { type: String, default: 'village' } }, data () { return { itemWidth: 20, show: false, pcaList: [ { selectIndex: -1, target: '', list: [] } ], selectAlList: [ { title: '请选择' } ], selectAlIndex: 0, currentIndex: 0 }; }, created () { this.init(); this.limitMappingNum = limitRegionNum[this.limitRegion] || 5; this.itemWidth = Math.floor(100 / this.limitMappingNum); }, destroyed () { clearTimeout(timmer); }, computed: { actives: { get () { if (this.active) { timmer = setTimeout(() => { this.show = true; }, 100); } return this.active; }, set (newVal) { this.$emit('update:active', newVal); } } }, watch: { defaultValue () { this.init(); }, limitRegion (val) { this.limitMappingNum = limitRegionNum[this.limitRegion] || 5; this.itemWidth = Math.floor(100 / this.limitMappingNum); } }, methods: { async init () { let { provinceCode, citiesCode, areasCode, streetsCode, villagesCode } = this.defaultValue; let set = (index, key) => { this.pcaList[index].selectIndex = this.pcaList[index].list.findIndex(i => { if (i.value === key) { this.setAlList(index, i.text); return true; } }); }; await this.getAllProvinces(); if (!provinceCode) return; set(0, provinceCode); if (this.limitMappingNum <= 1) return; await this.getAllCities(); if (!citiesCode) return; set(1, citiesCode); if (this.limitMappingNum <= 2) return; await this.getAllAreas(); if (!areasCode) return; set(2, areasCode); if (this.limitMappingNum <= 3) return; await this.getAllStreets(); if (!streetsCode) return; set(3, streetsCode); if (this.limitMappingNum <= 4) return; await this.getAllVillages(); if (!villagesCode) return; set(4, villagesCode); }, close () { this.show = false; timmer = setTimeout(() => { this.actives = false; }, 300); }, getAllProvinces () { return promiseContainer((resolve, callback) => { this.pcaList[0].list = localData.map(item => ({ text: item.text, value: item.value, children: item.children })); resolve(); }); }, getAllCities () { return promiseContainer((resolve, callback) => { let { selectIndex, list } = this.pcaList[0]; const cities = list[selectIndex].children || []; this.pcaList.splice(1, 4, { selectIndex: -1, target: '', list: cities.map(item => ({ text: item.text, value: item.value, children: item.children })) }); this.switchSwiper(1); resolve(); }); }, getAllAreas () { return promiseContainer((resolve, callback) => { let { selectIndex, list } = this.pcaList[1]; const areas = list[selectIndex].children || []; this.pcaList.splice(2, 3, { selectIndex: -1, target: '', list: areas.map(item => ({ text: item.text, value: item.value, children: item.children })) }); this.switchSwiper(2); resolve(); }); }, getAllStreets () { return promiseContainer((resolve, callback) => { let { selectIndex, list } = this.pcaList[2]; const streets = list[selectIndex].children || []; this.pcaList.splice(3, 2, { selectIndex: -1, target: '', list: streets.map(item => ({ text: item.text, value: item.value, children: item.children })) }); this.switchSwiper(3); resolve(); }); }, getAllVillages () { return promiseContainer((resolve, callback) => { let { selectIndex, list } = this.pcaList[3]; const villages = list[selectIndex].children || []; this.pcaList.splice(4, 1, { selectIndex: -1, target: '', list: villages.map(item => ({ text: item.text, value: item.value })) }); this.switchSwiper(4); resolve(); }); }, selectAl (index) { if (typeof index === 'object') { let { detail: { current } } = index; index = current; } this.selectAlIndex = index; this.switchSwiper(index); }, switchSwiper (index) { this.$nextTick(() => { let { selectIndex, list } = this.pcaList[index]; if (~selectIndex) { let setTarget = this.pcaList[index]; setTarget.target = ''; this.$nextTick(() => { setTarget.target = list[selectIndex].value; }); } this.currentIndex = index; }); }, submit () { let result = this.pcaList.map(item => { let { selectIndex, list } = item; return { code: list[selectIndex].value, name: list[selectIndex].text }; }); this.$emit('change', result); }, setAlList (typeIndex, title) { if (typeIndex < 4 && typeIndex + 1 !== this.limitMappingNum) { this.selectAlList.splice(typeIndex, 5 - typeIndex, { title: title }, { title: '请选择' }); } else { this.selectAlList.splice(typeIndex, 5 - typeIndex, { title: title }); } }, selectAddress (item, index, typeIndex) { this.pcaList[typeIndex].selectIndex = index; this.setAlList(typeIndex, item.text); this.selectAlIndex = typeIndex + 1; switch (typeIndex) { case 0: if (this.limitMappingNum >= 2) { this.getAllCities(); } else { this.submit(); this.close(); } break; case 1: if (this.limitMappingNum >= 3) { this.getAllAreas(); } else { this.submit(); this.close(); } break; case 2: if (this.limitMappingNum >= 4) { this.getAllStreets(); } else { this.submit(); this.close(); } break; case 3: if (this.limitMappingNum >= 5) { this.getAllVillages(); } else { this.submit(); this.close(); } break; case 4: this.submit(); this.close(); break; } } } }; </script> <style lang="scss"> @import './pca-picker.scss'; </style> 主要修改点: 将数据格式调整为使用 text 和 value 字段,并支持嵌套的 children 结构 修改了所有数据处理方法,使用 text 替代原来的 name,使用 value 替代原来的 code 修改了数据获取逻辑,直接从父级的 children 属性中获取下级数据 更新了 submit 方法返回的数据结构,使用 text 和 value 字段 保留了原有的交互逻辑和样式,只修改了数据相关的部分 您可以根据实际需求扩展 localData 中的省市区数据,确保数据结构保持一致即可。 现在关闭之后就打开不了了 怎么解决 <template> <view class="mask" :class="{ active: actives, show: show }" @tap="close" @touchmove.stop.prevent> <view class="pca-picker-box" @tap.stop> <view class="picker-head"> <text>请选择所在地区</text> <i @tap.stop="close" class="iconfont icon-guanbi"></i> </view> <view class="select-al-box"> <text v-for="(item, index) in selectAlList" :key="index" :index="item.title" :style="{ width: itemWidth + '%' }" class="select-al-item" @tap="selectAl(index)" :class="{ active: selectAlIndex === index }"> {{ item.title }} </text> </view> <swiper class="swiper-box" @change="selectAl" :current="currentIndex"> <swiper-item v-for="(item, index) in pcaList" :key="index" :index="index"> <scroll-view :scroll-into-view="'id' + item.target" class="adress-item" scroll-y="true"> <view v-for="(it, inx) in item.list" :id="'id' + it.value" class="item" :class="{ active: inx === item.selectIndex }" @tap="selectAddress(it, inx, index)"> <text class="iconfont icon-dagou-copy-copy">{{ it.text }}</text> </view> </scroll-view> </swiper-item> </swiper> </view> </view> </template> <script> // 本地数据示例 const localData = [ { text: '浙江省', value: '330000', children: [ { text: '杭州市', value: '330100', children: [ { text: '西湖区', value: '330106', children: [ { text: '文新街道', value: '330106001', children: [ { text: '星洲社区', value: '330106001001' } ] } ] } ] } ], }, { text: '江苏省', value: '320000', children: [ { text: '南京市', value: '320100', children: [ { text: '玄武区', value: '320102' } ] } ], } ]; let timmer = null; let limitRegionNum = { province: 1, city: 2, area: 3, street: 4, village: 5 }; function promiseContainer (fn, callback) { return new Promise((resolve, reject) => { fn(resolve, callback); }); } export default { props: { active: { type: Boolean, default: false }, defaultValue: { type: Object, default () { return { provinceCode: '', citiesCode: '', areasCode: '', streetsCode: '', villagesCode: '' }; } }, limitRegion: { type: String, default: 'village' } }, data () { return { itemWidth: 20, show: false, pcaList: [ { selectIndex: -1, target: '', list: [] } ], selectAlList: [ { title: '请选择' } ], selectAlIndex: 0, currentIndex: 0 }; }, created () { this.init(); this.limitMappingNum = limitRegionNum[this.limitRegion] || 5; this.itemWidth = Math.floor(100 / this.limitMappingNum); }, destroyed () { clearTimeout(timmer); }, computed: { actives: { get () { if (this.active) { timmer = setTimeout(() => { this.show = true; }, 100); } return this.active; }, set (newVal) { this.$emit('update:active', newVal); } } }, watch: { defaultValue () { this.init(); }, limitRegion (val) { this.limitMappingNum = limitRegionNum[this.limitRegion] || 5; this.itemWidth = Math.floor(100 / this.limitMappingNum); } }, methods: { async init () { let { provinceCode, citiesCode, areasCode, streetsCode, villagesCode } = this.defaultValue; let set = (index, key) => { this.pcaList[index].selectIndex = this.pcaList[index].list.findIndex(i => { if (i.value === key) { this.setAlList(index, i.text); return true; } }); }; await this.getAllProvinces(); if (!provinceCode) return; set(0, provinceCode); if (this.limitMappingNum <= 1) return; await this.getAllCities(); if (!citiesCode) return; set(1, citiesCode); if (this.limitMappingNum <= 2) return; await this.getAllAreas(); if (!areasCode) return; set(2, areasCode); if (this.limitMappingNum <= 3) return; await this.getAllStreets(); if (!streetsCode) return; set(3, streetsCode); if (this.limitMappingNum <= 4) return; await this.getAllVillages(); if (!villagesCode) return; set(4, villagesCode); }, close () { this.show = false; timmer = setTimeout(() => { this.actives = false; }, 300); }, getAllProvinces () { return promiseContainer((resolve, callback) => { this.pcaList[0].list = localData.map(item => ({ text: item.text, value: item.value, children: item.children })); resolve(); }); }, getAllCities () { return promiseContainer((resolve, callback) => { let { selectIndex, list } = this.pcaList[0]; const cities = list[selectIndex].children || []; this.pcaList.splice(1, 4, { selectIndex: -1, target: '', list: cities.map(item => ({ text: item.text, value: item.value, children: item.children })) }); this.switchSwiper(1); resolve(); }); }, getAllAreas () { return promiseContainer((resolve, callback) => { let { selectIndex, list } = this.pcaList[1]; const areas = list[selectIndex].children || []; this.pcaList.splice(2, 3, { selectIndex: -1, target: '', list: areas.map(item => ({ text: item.text, value: item.value, children: item.children })) }); this.switchSwiper(2); resolve(); }); }, getAllStreets () { return promiseContainer((resolve, callback) => { let { selectIndex, list } = this.pcaList[2]; const streets = list[selectIndex].children || []; this.pcaList.splice(3, 2, { selectIndex: -1, target: '', list: streets.map(item => ({ text: item.text, value: item.value, children: item.children })) }); this.switchSwiper(3); resolve(); }); }, getAllVillages () { return promiseContainer((resolve, callback) => { let { selectIndex, list } = this.pcaList[3]; const villages = list[selectIndex].children || []; this.pcaList.splice(4, 1, { selectIndex: -1, target: '', list: villages.map(item => ({ text: item.text, value: item.value })) }); this.switchSwiper(4); resolve(); }); }, selectAl (index) { if (typeof index === 'object') { let { detail: { current } } = index; index = current; } this.selectAlIndex = index; this.switchSwiper(index); }, switchSwiper (index) { this.$nextTick(() => { let { selectIndex, list } = this.pcaList[index]; if (~selectIndex) { let setTarget = this.pcaList[index]; setTarget.target = ''; this.$nextTick(() => { setTarget.target = list[selectIndex].value; }); } this.currentIndex = index; }); }, submit () { let result = this.pcaList.map(item => { let { selectIndex, list } = item; return { code: list[selectIndex].value, name: list[selectIndex].text }; }); this.$emit('change', result); }, setAlList (typeIndex, title) { if (typeIndex < 4 && typeIndex + 1 !== this.limitMappingNum) { this.selectAlList.splice(typeIndex, 5 - typeIndex, { title: title }, { title: '请选择' }); } else { this.selectAlList.splice(typeIndex, 5 - typeIndex, { title: title }); } }, selectAddress (item, index, typeIndex) { this.pcaList[typeIndex].selectIndex = index; this.setAlList(typeIndex, item.text); this.selectAlIndex = typeIndex + 1; switch (typeIndex) { case 0: if (this.limitMappingNum >= 2) { this.getAllCities(); } else { this.submit(); this.close(); } break; case 1: if (this.limitMappingNum >= 3) { this.getAllAreas(); } else { this.submit(); this.close(); } break; case 2: if (this.limitMappingNum >= 4) { this.getAllStreets(); } else { this.submit(); this.close(); } break; case 3: if (this.limitMappingNum >= 5) { this.getAllVillages(); } else { this.submit(); this.close(); } break; case 4: this.submit(); this.close(); break; } } } }; </script> <style lang="scss"> @import './pca-picker.scss'; </style> 现在弹窗关闭之后 就无法在打开 怎么解决 然后需要把没用的代码删掉
06-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值