titles.map(item => ({title: item}))

本文介绍了一个使用JavaScript将数组元素转换为对象数组的例子。通过`map`函数遍历字符串数组,构造出具有`name`属性的对象数组,并展示了如何利用`console.log`输出最终结果。
   <script>
        var titles=['kity','xiaohua','caimiao']
        const vtabs = titles.map(item => ({'name': item}))
        console.log(vtabs);
        // [ {name: "kity"}, {name: "xiaohua"},{name: "caimiao"}]
    </script>
<template> <div class="pending-approvals-panel"> <el-table :data="tableData" style="width: 100%"> <!-- 序号 --> <el-table-column type="index" :label="t('序号')" width="80" /> <!-- 申请人 --> <el-table-column :label="t('申请人')" prop="applicant" column-key="applicant" :filters="applicants" :filter-method="filterApplicant" /> <!-- 工单号 --> <el-table-column :label="t('工单号')" prop="ticketId" column-key="ticketId" :filters="ticketIds" :filter-method="filterTicketId" /> <!-- 工单标题 --> <el-table-column :label="t('工单标题')" prop="title" column-key="title" :filters="titles" :filter-method="filterTitle" /> <!-- 状态 --> <el-table-column :label="t('状态')" prop="status" column-key="status" :filters="statusFilters" :filter-method="filterStatus" ></el-table-column> <!-- 当前处理人 --> <el-table-column :label="t('当前处理人')" prop="currentHandler" column-key="currentHandler" :filters="handlers" :filter-method="filterHandler" /> </el-table> <!-- 操作按钮 --> <div style="margin-top: 20px; text-align: center"> <el-button type="primary" @click="handleSubmit">{{ t('提交') }}</el-button> <el-button @click="handleCancel">{{ t('取消') }}</el-button> </div> </div> </template> <script setup> import { computed, ref } from 'vue'; import { ElMessage, ElMessageBox } from 'element-plus'; import { useI18n } from 'vue-i18n'; // 国际化 // 国际化 const { t } = useI18n(); // 表格数据 const tableData = ref([ { id: 1, applicant: '张三', ticketId: 'WT202409001', title: '申请ECS权限', status: 'pending', currentHandler: '李四', }, { id: 2, applicant: '王五', ticketId: 'WT202409002', title: 'OSS读写权限', status: 'approved', currentHandler: '系统', }, { id: 3, applicant: '赵六', ticketId: 'WT202409003', title: '数据库访问', status: 'rejected', currentHandler: '陈七', }, ]); // 动态生成过滤器选项(去重后映射为 { text, value }) const applicants = computed(() => [...new Set(tableData.value.map(item => item.applicant))].map(val => ({ text: val, value: val })) ); const ticketIds = computed(() => [...new Set(tableData.value.map(item => item.ticketId))].map(val => ({ text: val, value: val })) ); const titles = computed(() => [...new Set(tableData.value.map(item => item.title))].map(val => ({ text: val, value: val })) ); const handlers = computed(() => [...new Set(tableData.value.map(item => item.currentHandler))].map(val => ({ text: val, value: val, })) ); const statusFilters = [ { text: '待审批', value: 'pending' }, { text: '已通过', value: 'approved' }, { text: '已拒绝', value: 'rejected' }, ]; // 过滤方法(必须返回 boolean) const filterApplicant = (value, row) => row.applicant === value; const filterTicketId = (value, row) => row.ticketId === value; const filterTitle = (value, row) => row.title === value; const filterStatus = (value, row) => row.status === value; const filterHandler = (value, row) => row.currentHandler === value; // 提交与取消事件 const handleSubmit = () => { ElMessage.success(t('提交成功')); }; const handleCancel = () => { ElMessageBox.confirm(t('确定要取消吗?'), t('提示'), { confirmButtonText: t('确定'), cancelButtonText: t('取消'), type: 'warning', }) .then(() => { ElMessage.info(t('已取消')); }) .catch(() => { // 取消时静默 }); }; </script>表格列中的过滤功能的图标,我想要换成这个<el-icon><Filter /></el-icon>
10-22
return Array.from(sectionMap).map(([name, settings]) => ({ sectionName: name, settings }));这里有报错:Destructuring parameter declarations are not supported (arkts-no-destruct-params) <ArkTSCheck> ; const value = rawItem[key]; 这里 Use explicit types instead of "any", "unknown" (arkts-no-any-unknown) <ArkTSCheck> Indexed access is not supported for fields (arkts-no-props-by-index) <ArkTSCheck> , value: value.map((nestedItem: any) => {:Use explicit types instead of "any", "unknown" (arkts-no-any-unknown) <ArkTSCheck> ; const titles: Partial<Record<SettingKeys, string>> = { :Some of utility types are not supported (arkts-no-utility-types) <ArkTSCheck> ,Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals) <ArkTSCheck>;return titles[key] || key.toString(); :Indexed access is not supported for fields (arkts-no-props-by-index) <ArkTSCheck> ; private getTypeByKey(key: SettingKeys): UISettingItem['type'] { :Indexed access types are not supported (arkts-no-aliases-by-index) <ArkTSCheck> ; const descriptions: Partial<Record<SettingKeys, string>> = { captureLinkage: '抓拍时自动生成一段关联视频', speedOsd: '数据来源于GPS,设备需内置或扩展GPS模块', parkingMonitoringEnable: '停车后自动启动监控功能', parkingSensitivity: '灵敏度设置越高,监测越敏感但电池消耗更快', ADAS: '高级驾驶辅助系统设置', GPS: '全球定位系统配置', cellular: '移动网络配置', parkingMonitoringTime: '设置停车监控的最长持续时间', cloudBox: '云存储服务设置' }; return descriptions[key]; :Some of utility types are not supported (arkts-no-utility-types) <ArkTSCheck> Indexed access is not supported for fields (arkts-no-props-by-index) <ArkTSCheck> ; const newSections = this.sections.map(section => ({ ...section, settings: section.settings.map(item => item.key === key ? { ...item, value } : item :Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals) <ArkTSCheck> ,It is possible to spread only arrays or classes derived from arrays into the rest parameter or array literals (arkts-no-spread) <ArkTSCheck> ; Section({ :Cannot find name 'Section'. Did you mean 'section'? <ArkTSCheck> ; this.SettingGroup({ title: item.title, description: item.description, items: item.value as UISettingItem[] }) Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals) <ArkTSCheck>;:Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals) <ArkTSCheck> ; this.SettingItem({ item: item, onChange: (value) => this.handleSettingChange(item.key, value) }) 'this.SettingItem({ item: item, onChange: (value) => this.handleSettingChange(item.key, value) })' does not comply with the UI component syntax. <ArkTSCheck> Property 'SettingItem' does not exist on type 'Configure'. <ArkTSCheck> ,请帮我修改,并给我完整代码
06-11
<template> <div class="sec-container"> <van-popup v-model:show="showDetailModal" :style="{ width: '100%', height: '100%', overflow: 'auto' }" position="right" round closeable @close="handleDetailClose" > <van-form ref="addCommentsFormRef" @submit="handleSave"> <!-- 检验单信息 --> <van-cell-group title="检验单信息" v-if="showType === 'qcOrder'"> <!-- <van-field--> <!-- v-model="saveData.applyDate"--> <!-- is-link--> <!-- readonly--> <!-- clearable--> <!-- @click="handleDate"--> <!-- placeholder="请选择提出时间"--> <!-- />--> <van-field v-model="saveData.applyDate" is-link readonly label="提出时间" placeholder="点击选择日期" @click="showPicker = true" /> <van-popup v-model:show="showDatePicker" round position="bottom"> <van-date-picker v-model="saveData.applyDate" @confirm="onConfirm" @cancel="showDatePicker = false" /> </van-popup> </van-cell-group> <!-- 编辑/新增时的表单 --> <van-cell-group title="检验单信息" v-if="showType === 'show' || showType === 'result'"> <van-field name="radio" label="检验状态" v-if="showType === 'result'"> <template #input> <van-radio-group v-model="saveData.status" direction="horizontal"> <van-radio name="0">新建</van-radio> <van-radio name="1">检验中</van-radio> <van-radio name="2">合格</van-radio> <van-radio name="-1">不合格</van-radio> </van-radio-group> </template> </van-field> <van-field name="projectNo" label="项目"> <template #input> {{saveData.projectNo}} </template> </van-field> <van-field name="inspClass" label="检验大类" :rules="[{ required: true, message: '请填写检验大类!' }]"> <template #input> {{saveData.inspClassStr}} </template> </van-field> <van-field name="inspType" label="检验类型" :rules="[{ required: true, message: '请填写检验类型!' }]"> <template #input> {{saveData.inspTypeName}} </template> </van-field> <van-field name="orgNo" label="基地" :rules="[{ required: true, message: '请选择基地!' }]"> <template #input> {{saveData.orgName}} </template> </van-field> <van-field name="workzone" label="作业区" :rules="[{ required: true, message: '请填写作业区!' }]"> <template #input> {{saveData.workzoneName}} </template> </van-field> <van-field name="inspLoc" label="检验地点" :rules="[{ required: true, message: '请填写检验地点!' }]"> <template #input> {{saveData.inspLoc}} </template> </van-field> <van-field name="mainUserNo" label="负责人" :rules="[{ required: true, message: '请填写负责人!' }]"> <template #input> {{saveData.mainUserName}} </template> </van-field> <van-field name="tel" label="联系方式"> <template #input> {{saveData.tel}} </template> </van-field> </van-cell-group> <!-- 管路信息 --> <van-cell-group title="管路信息"> <!-- 简化显示 --> <div class="search-btn" v-if="showType === 'result'"> <van-button type="primary" @click="changeStatus(1,'pipe')" style="margin-right:10px">合格</van-button> <van-button type="primary" @click="changeStatus(-1,'pipe')" style="margin-right:10px">不合格 </van-button> <van-button type="primary" @click="changeStatus(2,'pipe')" style="margin-right:10px">取消 </van-button> </div> <a-table sticky v-if="showType == 'show'" :scroll="{ x: '100%' }" :columns="pipeTable.columns" :dataSource="pipeTable.dataSource" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" ref="pipeTableRef" > </a-table> <a-table sticky v-if="showType == 'result'" :scroll="{ x: '100%' }" :columns="pipeTable.resColumns" :dataSource="pipeTable.dataSource" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" ref="pipeTableRef" :row-selection="{ selectedRowKeys: pipeTable.selectedRowKeys, onChange: onSelectChange }" > </a-table> </van-cell-group> <!-- 焊缝信息 --> <van-cell-group title="焊缝信息"> <div class="search-btn" v-if="showType === 'result'"> <van-button type="primary" @click="changeStatus(1,'weld')" style="margin-right:10px">合格</van-button> <van-button type="primary" @click="changeStatus(-1,'weld')" style="margin-right:10px">不合格 </van-button> <van-button type="primary" @click="changeStatus(2,'weld')" style="margin-right:10px">取消 </van-button> </div> <a-table sticky v-if="showType == 'show'" :scroll="{ x: '100%' }" :columns="weldTable.columns" :dataSource="weldTable.dataSource" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" ref="weldTableRef" > </a-table> <a-table sticky v-if="showType == 'result'" :scroll="{ x: '100%' }" :columns="weldTable.resColumns" :dataSource="weldTable.dataSource" bordered size="middle" :loading="loading" :pagination="false" rowKey="id" ref="weldTableRef" :row-selection="{ selectedRowKeys: weldTable.selectedRowKeys, onChange: onWeldSelectChange }" > </a-table> </van-cell-group> <!-- 提交按钮 --> <div style="margin: 16px;"> <van-button round block type="default" @click="handleDetailClose">取消</van-button> <van-button round block type="primary" native-type="submit" v-if="showType === 'edit' || showType === 'add' || showType === 'result'">提交</van-button> </div> </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/insp/order', method: 'POST' }]">查看</a-button> <a-button type="link" @click="showData(record,'result')" v-resource="[{ url: '/service-piping/cp/insp/order', method: 'POST' }]">结果维护</a-button> <a-button type="link" @click="showLog(record)" v-resource="[{ url: '/service-piping/cp/insp/order', method: 'POST' }]">查看日志</a-button> <a-button type="link" @click="handleApplyOrder(record)" v-if="record.applyFlag!='Y'" >申请检验</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 placeholder="单击选择项目" @click="handleProject" /> <van-field v-model="searchState.orderNo" clearable label="检验单号" placeholder="请输入检验单号" /> <van-field v-model="searchState.inspClass" clearable @click="handleInspClass" label="检验大类" placeholder="请选择检验大类" is-link readonly /> </van-cell-group> <van-popup v-model:show="showPicker" round position="bottom"> <van-picker :columns="inspColumns" @cancel="showPicker = false" @confirm="onInspClassConfirm" /> </van-popup> <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/pipeInspection' import ProjectPanel from '@/components/ProjectPanel.vue' import dayjs from 'dayjs' import { Buffer } from 'buffer' import { useRouter } from 'vue-router' import localforage from 'localforage' import { useHomePage } from '@/stores/homePage' import { Modal } from 'ant-design-vue' import {getBuildBases} from "@/api/common/index.js"; import {showNotify} from "vant"; const showDatePicker = ref(false); const onSelectChange = (keys, rows) => { pipeTable.selectedRowKeys = keys pipeTable.selectedRows = rows } const onWeldSelectChange = (keys, rows) => { weldTable.selectedRowKeys = keys weldTable.selectedRows = rows } const workZoneNos = ref([]) const statusOptions = [ { value: -1, text: "不合格" }, { value: 0, text: "新建" }, { value: 1, text: "合格" }, { value: 2, text: "取消" } ] // const inspClassOptions = [ // { text: '焊前检验', value: 'HQ' }, // { text: '焊后检验', value: 'HH' }, // { text: '压力检验', value: 'PT' }, // { text: '完工检验', value: 'HP' }, // { text: '其他检验', value: 'JY' }, // ] const currProjectNo =ref(null) const selectInsp = ref([]) 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 showType = ref('') window.Buffer = Buffer const router = useRouter() 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 inspColumns = ref([ { value: 'HQ', text: "焊前检验" }, { value: 'HH', text: "焊后检验" }, { value: 'PT', text: "压力检验" }, { value: 'HP', text: "完工检验" }, { value: 'JY', text: "其他检验" }, ]) const showPicker = ref(false) const buildBaseList = ref([]) const data = 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 statusList = ref([ { text: '新建', value: 0 }, { text: '进行中', value: 1 }, { text: '已完成', value: 2 } ]) const pipeTable = reactive({ toolbar: { buttons: [{ code: "addPipe", name: "添加物料" }] }, resToolbar: { buttons: [{ code: "qualifiedPipe", name: "合格" },{ code: "unqualifiedPipe", name: "不合格" },{ code: "cancelPipe", name: "取消" }] }, selectedRowKeys: [], selectedRows: [], columns: [ { title: "图号", dataIndex: "drawNo", width: 120, }, { title: "作业对象", dataIndex: "block", width: 150, }, { title: "托盘号", dataIndex: "instPalletNo", width: 150, }, { title: "管号", dataIndex: "pipeNo", width: 120, }, { title: "页号", dataIndex: "pageNo", width: 80, }, { title: "暂停", dataIndex: "isPause", width: 80, }, { title: "删除", dataIndex: "isDelete", width: 80, }, { title: "最新版", dataIndex: "isTopVersion", width: 80, }, { title: "装配承包商", dataIndex: "assyCoopName", width: 150, }, { title: "焊接承包商", dataIndex: "weldingCoopName", width: 150, }, { title: "焊前检验单", dataIndex: "weldingPreOrderNo", width: 150, }, { title: "焊后检验单", dataIndex: "weldingPostOrderNo", width: 150, }, { title: "压力检验单", dataIndex: "ptOrderNo", width: 150, }, { title: "完工/预制放行检验单", dataIndex: "preFinishOrderNo", width: 150, }, { title: "PMI检验单", dataIndex: "pmiOrderNo", width: 150, }, { title: "焊后热处理检验单", dataIndex: "pwhtOrderNo", width: 150, }, { title: "硬度检验单", dataIndex: "hardnessOrderNo", width: 150, }, { title: "铁素体检验单", dataIndex: "ferriteOrderNo", width: 150, }, // { // title: "操作", // key: "action", // align: "center", // 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: 80, }, { title: "删除", dataIndex: "isDelete", width: 80, }, { title: "暂停", dataIndex: "isPause", width: 80, }, { title: "最新版", dataIndex: "isTopVersion", width: 80, }, { title: "检验结果", dataIndex: "status", type: "select", width: 80, customRender: function (text) { if (text.record.status) { return statusOptions.value.find( (item) => item.value == text.record.status ).text } else { return '新建' } } }, { title: "操作", key: "action", align: "center", width: 200, sorter: false, scopedSlots: { customRender: "action" }, fixed: "right", formInvisible: true } ], dataSource: [] }) const columns = computed(() => { return [ { title: '项目号', dataIndex: 'projectNo', width: 120 }, { title: "基地", dataIndex: "orgNo", condition: true, width: 90, customRender: function (text) { if (text.record.orgNo) return buildBaseList.value.find( (item) => item.value == text.record.orgNo ).text }, }, { title: "检验单号", dataIndex: "orderNo", condition: true, width: 150 }, { dataIndex: "workzoneName", title: "作业区", width: 150, }, { title: "QC单号", dataIndex: "qcOrderNo", condition: true, width: 150 }, { title: "申请检验时间", dataIndex: "createDate", width: 150, type: "datetime", align: "center", customRender: function (text) { if (text.record.createDate) return dayjs(text.record.createDate).format('YYYY-MM-DD HH:mm:ss') }, }, { title: "检验大类", dataIndex: "inspClass", type: "select", width: 100, condition: true, customRender: function (text) { if (text.record.inspClass) return inspColumns.value.find( (item) => item.value == text.record.inspClass ).text }, }, { title: "检验类型", dataIndex: "inspTypeName", width: 150, }, { title: "创建时间", dataIndex: "createDate", width: 150, type: "datetime", customRender: function (text) { if (text.record.createDate) return dayjs(text.record.createDate).format('YYYY-MM-DD HH:mm:ss') }, }, { title: "创建人", dataIndex: "createUserId", width: 120, type: "employeeDescription", options: { fieldNames: { label: "createUserName", value: "createUserId" } } }, { title: "管数量", dataIndex: "pipeNum", width: 80 }, { title: "状态", dataIndex: "status", type: "select", width: 80, condition: true, customRender: function (text) { if (text.record.status) { return statusOptions.value.find( (item) => item.value == text.record.status ).text } else { return '新建' } } }, { title: '操作', dataIndex: 'action', width: 140, key: 'action' } ] }) const loadData = (type) => { loading.value = true serve.getOrderList(searchState.value).then(async (res) => { for (let item of res.content) { item.targetStorageDate = item.targetStorageDate ? dayjs(item.targetStorageDate).format('YYYY-MM-DD') : '' item.isDownload = false let value = await localforage.getItem(item.id.toString()) if (value instanceof Blob && value.size > 0 && value.type === 'application/pdf') { item.isDownload = true } } 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 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() } } ) const onInspClassConfirm = ({ selectedOptions }) => { showPicker.value = false searchState.value.inspClass = selectedOptions[0].value } const handleInspClass = () => { showPicker.value = true } onMounted(() => { getBuildBase() serve.getWorkZone({majors:'管路'}).then((res) => { workZoneNos.value = res.status == 200 ? res.data.map((item) => { return { label: item.name, value: item.code, } }) : []; }) if (homePage.isOnline) { loadData() } 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 showData = (record,showTypeStr) => { serve.getOrderList({id:record.id}).then((res) => { console.log('res.data',res) console.log('res.data',res.data) console.log('res.data.content',res.content) saveData.value = res.content[0] saveData.value.mainUserNo = { label: saveData.value.mainUserName, value: saveData.value.mainUserNo } saveData.value.status = saveData.value.status+'' pipeTable.dataSource = res.content[0].pipeList console.log('pipeTable.dataSource',pipeTable.dataSource) weldTable.dataSource = res.content[0].weldList currProjectNo.value = res.content[0].projectNo showDetailModal.value = true showType.value = showTypeStr saveData.value.inspClassStr = inspColumns.value.find( (item) => item.value == saveData.value.inspClass ).text saveData.value.orgName = buildBaseList.value.find( (item) => item.value == saveData.value.orgNo ).text serve.getInsp({ projName: res.content[0].projectNo, professionNo: "CP" }).then((res) => { selectInsp.value = res.map((item) => { return { label: item.MSVALUE+"", value: item.MSKEY+"", } }) }) }) } const onConfirm = ({ selectedValues }) => { saveData.applyDate = selectedValues.join('-'); console.log('saveData.applyDate',saveData.applyDate) console.log('selectedValues',selectedValues) showDatePicker.value = false; }; const changeStatus = (stateNum,type)=>{ console.log('pipeTable',pipeTable.selectedRows) console.log('weldTable',weldTable.selectedRows) if(type === 'pipe' ){ if(pipeTable.selectedRows.length === 0 ){ showNotify({ type: 'danger', message: '请选择一条数据' }) return } } if(type === 'weld'){ if(weldTable.selectedRows.length === 0 ){ showNotify({ type: 'danger', message: '请选择一条数据' }) return } } } </script> <style lang="scss" scoped> :deep .urgentFlag-active { background: #ffb656; } :deep .abnormalFlag-active { background: #fb7171; } :deep .anticon-search { line-height: 0 !important; } </style> <style lang="scss" scoped> @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>这里有问题 { title: "状态", dataIndex: "status", type: "select", width: 80, condition: true, customRender: function (text) { if (text.record.status) { return statusOptions.value.find( (item) => item.value == text.record.status ).text } else { return '新建' } } }, 提示The script has an unsupported MIME type ('text/html'). pipeInspection:1 Uncaught (in promise) DOMException: Failed to register a ServiceWorker for scope ('http://localhost:5173/') with script ('http://localhost:5173/sw.js'): The script has an unsupported MIME type ('text/html'). pipeInspection.vue:762 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'find') at customRender (pipeInspection.vue:762:38) at Proxy.<anonymous> (index.js:143:30) at renderComponentRoot (runtime-core.esm-bundler.js:6502:16) at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js:5319:46) at ReactiveEffect.run (reactivity.esm-bundler.js:225:19) at setupRenderEffect (runtime-core.esm-bundler.js:5454:5) at mountComponent (runtime-core.esm-bundler.js:5229:7) at processComponent (runtime-core.esm-bundler.js:5182:9) at patch (runtime-core.esm-bundler.js:4700:11) at mountChildren (runtime-core.esm-bundler.js:4932:7) customRender @ pipeInspection.vue:762 (anonymous) @ index.js:143 renderComponentRoot @ runtime-core.esm-bundler.js:6502 componentUpdateFn @ runtime-core.esm-bundler.js:5319 run @ reactivity.esm-bundler.js:225 setupRenderEffect @ runtime-core.esm-bundler.js:5454 mountComponent @ runtime-core.esm-bundler.js:5229 processComponent @ runtime-core.esm-bundler.js:5182 patch @ runtime-core.esm-bundler.js:4700 mountChildren @ runtime-core.esm-bundler.js:4932 processFragment @ runtime-core.esm-bundler.js:5112 patch @ runtime-core.esm-bundler.js:4674 mountChildren @ runtime-core.esm-bundler.js:4932 mountElement @ runtime-core.esm-bundler.js:4855 processElement @ runtime-core.esm-bundler.js:4820 patch @ runtime-core.esm-bundler.js:4688 mountChildren @ runtime-core.esm-bundler.js:4932 processFragment @ runtime-core.esm-bundler.js:5112 patch @ runtime-core.esm-bundler.js:4674 componentUpdateFn @ runtime-core.esm-bundler.js:5326 run @ reactivity.esm-bundler.js:225 setupRenderEffect @ runtime-core.esm-bundler.js:5454 mountComponent @ runtime-core.esm-bundler.js:5229 processComponent @ runtime-core.esm-bundler.js:5182 patch @ runtime-core.esm-bundler.js:4700 mountChildren @ runtime-core.esm-bundler.js:4932 processFragment @ runtime-core.esm-bundler.js:5112 patch @ runtime-core.esm-bundler.js:4674 patchKeyedChildren @ runtime-core.esm-bundler.js:5729 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 updateComponent @ runtime-core.esm-bundler.js:5258 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 processFragment @ runtime-core.esm-bundler.js:5156 patch @ runtime-core.esm-bundler.js:4674 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 updateComponent @ runtime-core.esm-bundler.js:5258 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 updateComponent @ runtime-core.esm-bundler.js:5258 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 processFragment @ runtime-core.esm-bundler.js:5156 patch @ runtime-core.esm-bundler.js:4674 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 updateComponent @ runtime-core.esm-bundler.js:5258 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 updateComponent @ runtime-core.esm-bundler.js:5258 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 updateComponent @ runtime-core.esm-bundler.js:5258 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 patchBlockChildren @ runtime-core.esm-bundler.js:5054 patchElement @ runtime-core.esm-bundler.js:4972 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 runIfDirty @ reactivity.esm-bundler.js:263 callWithErrorHandling @ runtime-core.esm-bundler.js:199 flushJobs @ runtime-core.esm-bundler.js:408 Promise.then (async) queueFlush @ runtime-core.esm-bundler.js:322 queueJob @ runtime-core.esm-bundler.js:317 effect2.scheduler @ runtime-core.esm-bundler.js:5448 trigger @ reactivity.esm-bundler.js:253 endBatch @ reactivity.esm-bundler.js:311 notify @ reactivity.esm-bundler.js:597 trigger @ reactivity.esm-bundler.js:571 set value @ reactivity.esm-bundler.js:1448 (anonymous) @ pipeInspection.vue:798 Promise.then (async) loadData @ pipeInspection.vue:781 (anonymous) @ pipeInspection.vue:924 (anonymous) @ runtime-core.esm-bundler.js:2815 callWithErrorHandling @ runtime-core.esm-bundler.js:199 callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:206 hook.__weh.hook.__weh @ runtime-core.esm-bundler.js:2795 flushPostFlushCbs @ runtime-core.esm-bundler.js:385 flushJobs @ runtime-core.esm-bundler.js:427 Promise.then (async) queueFlush @ runtime-core.esm-bundler.js:322 queueJob @ runtime-core.esm-bundler.js:317 effect2.scheduler @ runtime-core.esm-bundler.js:5448 trigger @ reactivity.esm-bundler.js:253 endBatch @ reactivity.esm-bundler.js:311 notify @ reactivity.esm-bundler.js:597 trigger @ reactivity.esm-bundler.js:571 set value @ reactivity.esm-bundler.js:1448 finalizeNavigation @ vue-router.mjs:3498 (anonymous) @ vue-router.mjs:3363 Promise.then (async) pushWithRedirect @ vue-router.mjs:3330 push @ vue-router.mjs:3255 install @ vue-router.mjs:3699 use @ runtime-core.esm-bundler.js:3863 (anonymous) @ main.js:70 Show 141 more frames runtime-core.esm-bundler.js:6678 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'emitsOptions') at shouldUpdateComponent (runtime-core.esm-bundler.js:6678:27) at updateComponent (runtime-core.esm-bundler.js:5246:9) at processComponent (runtime-core.esm-bundler.js:5193:7) at patch (runtime-core.esm-bundler.js:4700:11) at patchKeyedChildren (runtime-core.esm-bundler.js:5597:9) at patchChildren (runtime-core.esm-bundler.js:5511:11) at processFragment (runtime-core.esm-bundler.js:5156:9) at patch (runtime-core.esm-bundler.js:4674:9) at patchKeyedChildren (runtime-core.esm-bundler.js:5597:9) at patchChildren (runtime-core.esm-bundler.js:5511:11) shouldUpdateComponent @ runtime-core.esm-bundler.js:6678 updateComponent @ runtime-core.esm-bundler.js:5246 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 processFragment @ runtime-core.esm-bundler.js:5156 patch @ runtime-core.esm-bundler.js:4674 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 updateComponent @ runtime-core.esm-bundler.js:5258 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 processFragment @ runtime-core.esm-bundler.js:5156 patch @ runtime-core.esm-bundler.js:4674 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 updateComponent @ runtime-core.esm-bundler.js:5258 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 updateComponent @ runtime-core.esm-bundler.js:5258 processComponent @ runtime-core.esm-bundler.js:5193 patch @ runtime-core.esm-bundler.js:4700 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 processFragment @ runtime-core.esm-bundler.js:5156 patch @ runtime-core.esm-bundler.js:4674 patchKeyedChildren @ runtime-core.esm-bundler.js:5597 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 patchKeyedChildren @ runtime-core.esm-bundler.js:5617 patchChildren @ runtime-core.esm-bundler.js:5511 patchElement @ runtime-core.esm-bundler.js:4985 processElement @ runtime-core.esm-bundler.js:4831 patch @ runtime-core.esm-bundler.js:4688 componentUpdateFn @ runtime-core.esm-bundler.js:5406 run @ reactivity.esm-bundler.js:225 runIfDirty @ reactivity.esm-bundler.js:263 callWithErrorHandling @ runtime-core.esm-bundler.js:199 flushJobs @ runtime-core.esm-bundler.js:408 Promise.then (async) queueFlush @ runtime-core.esm-bundler.js:322 queueJob @ runtime-core.esm-bundler.js:317 effect2.scheduler @ runtime-core.esm-bundler.js:5448 trigger @ reactivity.esm-bundler.js:253 endBatch @ reactivity.esm-bundler.js:311 notify @ reactivity.esm-bundler.js:597 trigger @ reactivity.esm-bundler.js:571 set value @ reactivity.esm-bundler.js:1448 (anonymous) @ Spin.js:66 exec @ throttle.js:71 setTimeout (async) wrapper @ throttle.js:123 watch.immediate @ Spin.js:68 callWithErrorHandling @ runtime-core.esm-bundler.js:199 callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:206 baseWatchOptions.call @ runtime-core.esm-bundler.js:6193 job @ reactivity.esm-bundler.js:1813 flushPostFlushCbs @ runtime-core.esm-bundler.js:385 flushJobs @ runtime-core.esm-bundler.js:427 Promise.then (async) queueFlush @ runtime-core.esm-bundler.js:322 queueJob @ runtime-core.esm-bundler.js:317 effect2.scheduler @ runtime-core.esm-bundler.js:5448 trigger @ reactivity.esm-bundler.js:253 endBatch @ reactivity.esm-bundler.js:311 notify @ reactivity.esm-bundler.js:597 trigger @ reactivity.esm-bundler.js:571 set value @ reactivity.esm-bundler.js:1448 (anonymous) @ pipeInspection.vue:798 Promise.then (async) loadData @ pipeInspection.vue:781 (anonymous) @ pipeInspection.vue:924 (anonymous) @ runtime-core.esm-bundler.js:2815 callWithErrorHandling @ runtime-core.esm-bundler.js:199 callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:206 hook.__weh.hook.__weh @ runtime-core.esm-bundler.js:2795 flushPostFlushCbs @ runtime-core.esm-bundler.js:385 flushJobs @ runtime-core.esm-bundler.js:427 Promise.then (async) queueFlush @ runtime-core.esm-bundler.js:322 queueJob @ runtime-core.esm-bundler.js:317 effect2.scheduler @ runtime-core.esm-bundler.js:5448 trigger @ reactivity.esm-bundler.js:253 endBatch @ reactivity.esm-bundler.js:311 notify @ reactivity.esm-bundler.js:597 trigger @ reactivity.esm-bundler.js:571 set value @ reactivity.esm-bundler.js:1448 finalizeNavigation @ vue-router.mjs:3498 (anonymous) @ vue-router.mjs:3363 Promise.then (async) pushWithRedirect @ vue-router.mjs:3330 push @ vue-router.mjs:3255 install @ vue-router.mjs:3699 use @ runtime-core.esm-bundler.js:3863 (anonymous) @ main.js:70 Show 113 more frames
09-17
<template> <el-dialog center width="600px" :title="title" v-model="visible" :close-on-click-modal="false" draggable :lock-scroll="false"> <div class="signerInfo"> <div ref="signerInfoRight" class="signerInfoRight"> <el-form ref="dataFormRef" :model="form" :disabled="readonly" label-position="left" label-width="80px"> <!-- 公告标题(必填) --> <el-form-item label="公告标题" prop="title" class="required-item"> <template #label> <span class="required-mark">*</span> <span>公告标题</span> </template> <el-input v-model="form.title" placeholder="请输入公告标题(限20字)" maxlength="20" show-word-limit /> </el-form-item> <!-- 公告内容(可选) --> <el-form-item label="公告内容" prop="content"> <el-input v-model="form.content" type="textarea" placeholder="请输入公告内容(限200字)" maxlength="200" show-word-limit rows="4" /> </el-form-item> <!-- 关联内容(必填) --> <el-form-item label="关联内容" prop="bizType" class="no-label required-item"> <template #label> <span class="required-mark">*</span> <span>关联内容</span> </template> <el-select v-model="form.bizType" placeholder="请选择关联类型" @change="handleBizTypeChange" style="width: 220px"> <el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in bizTypeOptions" /> </el-select> <!-- 朋友圈下拉(bizType=1) --> <el-select style="width: 220px; margin-left: 7px" v-model="form.bizId" placeholder="请选择朋友圈关联内容" v-if="form.bizType == 1"> <el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in relatedList" /> </el-select> <!-- 课程下拉(bizType=3) --> <el-select style="width: 220px; margin-left: 7px" v-model="form.bizId" placeholder="请选择课程关联内容" v-if="form.bizType == 3"> <el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in relatedList" /> </el-select> <!-- 知识库下拉(bizType=6) --> <el-select style="width: 220px; margin-left: 7px" v-model="form.bizId" placeholder="请选择知识库关联内容" v-if="form.bizType == 6"> <el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in relatedList" /> </el-select> </el-form-item> <!-- 发送用户(必填) --> <div style="display: flex"> <el-form-item label="发送用户" prop="userType" class="no-label required-item"> <template #label> <span class="required-mark">*</span> <span>发送用户</span> </template> <el-select v-model="form.userType" placeholder="全部" @change="handleUserTypeChange" style="width: 220px"> <el-option :key="item.value" :label="item.label" :value="item.value" v-for="item in userTypeOptions" /> </el-select> <el-select v-if="form.userType == 3" v-model="form.groupTeamList" filterable multiple :clearable="true" placeholder="请选择团队" style="width: 220px; margin-left: 7px" > <el-option :key="item.account" :label="item.name" :value="item.account + ''" v-for="item in groupTeamList" /> </el-select> <el-select v-model="form.groupRoleList" filterable multiple :clearable="true" v-if="form.userType == 2" placeholder="请选择角色" style="width: 220px; margin-left: 7px" > <el-option :key="item.account" :label="item.name" :value="item.account + ''" v-for="item in groupRoleList" /> </el-select> </el-form-item> <el-form-item v-if="form.userType == 4" label="指定用户" prop="groupUsrList" style="margin-left: 7px"> <div> <el-tag style="margin-right: 4px; margin-bottom: 4px" v-for="tag in form.groupUsrList" :key="tag.userId" closable @close="handleRemoveUse(tag)" > {{ tag.nickName || tag.name }} </el-tag> </div> </el-form-item> </div> <div v-if="form.userType == 4" style="width: 27%; margin-left: 115px; margin-bottom: 13px"> <div class=""> <CustomerDragUpload class="fileItemUpload" action="/admin/v1/tenant/user/analysis" :limit="1" @singleSuccess="(val) => handleUploadSuccess('fileItemUpload', val)" > 上传用户名单 </CustomerDragUpload> </div> <div class="downTemplate" @click="fileTemplate('user')">下载用户名单模版</div> </div> <!-- 发送时间(可选) --> <el-form-item label="发送时间" prop="sendTime"> <template #label> <span class="required-mark"> </span> <span>发送时间</span> </template> <el-date-picker v-model="form.sendTime" type="datetime" placeholder="不填写默认立即发送" value-format="yyyy-mm-dd HH:mm:ss" style="width: 220px" /> </el-form-item> </el-form> </div> </div> <template #footer> <span class="dialog-footer"> <el-button @click="close">取消</el-button> <el-button type="primary" :loading="submitting" @click="preSubmit" :disabled="loading"> 提交 </el-button> </span> </template> </el-dialog> </template> <script setup lang="ts" name="NoticeFormDialog"> import { useMessage } from '@/hooks/message'; import { useI18n } from 'vue-i18n'; import { useFormModal } from '@/hooks/useFormModal'; import { ref } from 'vue'; import { getFriendList, getCourseList, getKnowledgeList, saveNotice } from '@/api/admin/notice'; import { pageList as teamConfigPageList } from '@/api/admin/teamConfig'; import { pageFormList } from '@/api/admin/roleConfig'; import { downExcelTemp } from '@/api/admin/tool'; import CustomerDragUpload from '@/components/customerDragUpload/index.vue'; const emit = defineEmits(['refresh']); const { t } = useI18n(); const dataFormRef = ref(); const message = useMessage(); // 响应式数据 const groupTeamList = ref<{ account: string; name: string }[]>([]); const groupRoleList = ref<{ account: string; name: string }[]>([]); const relatedList = ref<any[]>([]); interface NoticeForm { id?: number; noticeId?: number; // 统一为 noticeId(大写I),和列表、接口一致 title: string; content: string; bizType: number | ''; bizId: number | ''; userType: number | ''; groupTeamList: string[]; groupRoleList: string[]; groupUsrList: any[]; audienceIds: number[]; sendTime?: string; } // 关联类型选项 const bizTypeOptions = ref([ { label: '朋友圈', value: 1 }, { label: '课程', value: 3 }, { label: '知识库', value: 6 }, ]); // 发送用户类型选项 const userTypeOptions = ref([ { label: '全员', value: 1 }, { label: '指定角色', value: 2 }, { label: '指定团队', value: 3 }, { label: '指定用户', value: 4 }, ]); /** * 关联类型变更:加载对应下拉列表 */ const handleBizTypeChange = async () => { form.value.bizId = ''; relatedList.value = []; try { if (form.value.bizType === 1) { const res = await getFriendList({ pageNum: 1, pageSize: 100, bizType: 1 }); relatedList.value = res.data.list.map((item: any) => ({ id: item.articleId, name: item.content || '无内容', })); } else if (form.value.bizType === 3) { const res = await getCourseList({ pageNum: 1, pageSize: 100, bizType: 3 }); relatedList.value = res.data.list.map((item: any) => ({ id: item.id, name: item.title || '无课程名称', })); } else if (form.value.bizType === 6) { const res = await getKnowledgeList({ pageNum: 1, pageSize: 100, bizType: 6 }); relatedList.value = res.data.list.map((item: any) => ({ id: item.articleId, name: item.title || '无知识库标题', })); } } catch (err) { const typeName = form.value.bizType === 1 ? '朋友圈' : form.value.bizType === 3 ? '课程' : '知识库'; message.error(`获取${typeName}列表失败,请重试`); } }; /** * 发送用户类型变更:重置选择项 */ const handleUserTypeChange = () => { form.value.groupTeamList = []; form.value.groupRoleList = []; form.value.groupUsrList = []; form.value.audienceIds = []; }; /** * 初始化团队/角色列表 */ const init = async () => { teamConfigPageList({ pageNum: 1, pageSize: 1000 }).then((res) => { groupTeamList.value = res.data.list.map((ele) => ({ account: ele.teamId, name: ele.teamName, })); }); pageFormList({ pageNum: 1, pageSize: 1000 }).then((res) => { groupRoleList.value = res.data.list.map((ele) => ({ account: ele.roleId, name: ele.roleName, })); }); }; /** * 编辑回显:强制给 form.noticeId 赋值(核心修复) */ const initDetail = async (row: any): Promise<NoticeForm> => { console.log('列表传递的row(编辑回显)1111:', row); console.log('row.noticeId(大写I)的值1111:', row.noticeId); // 验证row是否有noticeId debugger; const detail = row; let groupTeamList: string[] = []; let groupRoleList: string[] = []; let groupUsrList: any[] = []; const sendUserDesc = detail.sendUserDesc || ''; // 关联内容回显 if (detail.bizType) { form.value.bizType = detail.bizType; await handleBizTypeChange(); form.value.bizId = detail.bizId; } // 发送用户回显 const sendUserList = detail.sendUserList || []; // 从row中获取sendUserList if (detail.userType == 2) { // 指定角色:取sendUserList里的audienceId(对应角色ID) groupRoleList = sendUserList.map((item) => item.audienceId + ''); } else if (detail.userType == 3) { // 指定团队:取sendUserList里的audienceId(对应团队ID) groupTeamList = sendUserList.map((item) => item.audienceId + ''); } else if (detail.userType == 4) { groupUsrList = detail.userList || []; } // 【强制赋值】确保 noticeId 被赋值到表单 const noticeIdVal = detail.id; // 从row读取noticeId(大写I) console.log('赋值给form.noticeId的值:', noticeIdVal); // 验证赋值结果 return { id: detail.id, noticeId: noticeIdVal, // 明确赋值,避免遗漏 title: detail.title || '', content: detail.content || '', bizType: detail.bizType || '', bizId: detail.bizId || '', userType: detail.userType || '', groupTeamList, groupRoleList, groupUsrList, audienceIds: detail.audienceIds || [], sendTime: detail.sendTime || '', } as NoticeForm; }; /** * 新增公告:不传递 noticeId */ const createApi = async (data: NoticeForm) => { const submitData = { title: data.title, content: data.content || '', bizType: Number(data.bizType), bizId: Number(data.bizId), userType: Number(data.userType), audienceIds: data.audienceIds, sendTime: data.sendTime || '', }; console.log('新增提交数据(无noticeId):', submitData); const res = await saveNotice(submitData); return res.data; }; /** * 编辑公告:强制携带 noticeId(大写I) */ const updateApi = async (id: any, data: NoticeForm) => { // 【双重保险】如果data.noticeId为空,直接从form取(避免fetchById赋值失败) const finalNoticeId = data.noticeId || form.value.noticeId; if (!finalNoticeId) { message.error('noticeId缺失,无法提交编辑'); throw new Error('noticeId is required for update'); } const submitData = { id: data.id, noticeId: finalNoticeId, // 强制携带,确保传参 title: data.title, content: data.content || '', bizType: Number(data.bizType), bizId: Number(data.bizId), userType: Number(data.userType), audienceIds: data.audienceIds, sendTime: data.sendTime || '', }; // 【关键日志】打印提交数据,让你直观看到noticeId是否存在 console.log('编辑提交数据(含noticeId):', submitData); const res = await saveNotice(submitData); return res.data; }; // 表单模态框初始化:确保initForm包含noticeId const { visible, title, form, readonly, loading, submitting, openDialog, close, submit } = useFormModal<NoticeForm, any>({ initForm: () => ({ id: undefined, noticeId: undefined, // 必须包含,保持响应式 title: '', content: '', bizType: '', bizId: '', userType: 1, groupTeamList: [], groupRoleList: [], groupUsrList: [], audienceIds: [], sendTime: '', }), initDetail, create: createApi, update: updateApi, titles: { create: t('添加通告'), edit: t('编辑通告'), }, afterSubmit: () => { message.success(t('common.optSuccessText')); emit('refresh'); }, beforeOpen: init, }); /** * 下载用户模板 */ const fileTemplate = (type: string) => { downExcelTemp('/admin/v1/system/template/getTemplate', { key: type }); }; /** * 上传用户名单成功回调 */ const handleUploadSuccess = (key: string, data: any) => { if (key === 'fileItemUpload') { form.value.groupUsrList = data; } }; /** * 移除指定用户 */ const handleRemoveUse = (item: any) => { const findIndex = form.value.groupUsrList.findIndex((sitem: any) => sitem.userId === item.userId); if (findIndex > -1) { form.value.groupUsrList.splice(findIndex, 1); } }; /** * 表单校验 */ const validateForm = (): boolean => { if (!form.value.title.trim()) { message.error('请输入公告标题'); return false; } if (form.value.title.length > 20) { message.error('公告标题不能超过20字'); return false; } if (!form.value.bizType) { message.error('请选择关联类型'); return false; } if (!form.value.bizId || isNaN(Number(form.value.bizId))) { const typeName = form.value.bizType === 1 ? '朋友圈' : form.value.bizType === 3 ? '课程' : '知识库'; message.error(`请选择有效的${typeName}关联内容`); return false; } if (!form.value.userType) { message.error('请选择发送用户类型'); return false; } if (form.value.userType === 2 && !form.value.groupRoleList.length) { message.error('请选择指定角色'); return false; } if (form.value.userType === 3 && !form.value.groupTeamList.length) { message.error('请选择指定团队'); return false; } if (form.value.userType === 4 && !form.value.groupUsrList.length) { message.error('请上传指定用户名单'); return false; } // 编辑时校验noticeId(双重保险) // if (title.value === t('编辑通告') && !form.value.noticeId) { // message.error('公告ID缺失,无法编辑'); // return false; // } return true; }; /** * 提交前预处理 */ const preSubmit = async () => { if (!validateForm()) return; // 组装受众ID if (form.value.userType === 2) { form.value.audienceIds = form.value.groupRoleList.map((id) => Number(id)); } else if (form.value.userType === 3) { form.value.audienceIds = form.value.groupTeamList.map((id) => Number(id)); } else if (form.value.userType === 4) { form.value.audienceIds = form.value.groupUsrList.map((item) => item.userId); } else { form.value.audienceIds = []; } // 转换字段类型 form.value.bizType = Number(form.value.bizType); form.value.bizId = Number(form.value.bizId); form.value.userType = Number(form.value.userType); // 打印form完整数据,确认noticeId存在 console.log('提交前form数据:', form.value); submit(form.value); }; // 暴露方法给父组件 defineExpose({ openDialog }); </script> <style scoped lang="scss"> .signerInfoRight { padding: 10px 0; } .dialog-footer { display: flex; justify-content: center; gap: 10px; } .required-mark { color: #ff4d4f; margin-right: 4px; font-size: 14px; } .required-item .el-form-item__label { display: flex; align-items: center; } .no-label.required-item .el-form-item__label { padding-right: 12px; } .downTemplate { margin-top: 10px; color: blue; cursor: pointer; } ::v-deep .el-form .el-form-item:last-of-type { margin-bottom: 17px !important; } </style> 为啥下拉角色和团队,指定用户 没有返显点编辑的时候
最新发布
12-03
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值