From e4aabe6b45fa6f35e075c0845c76fc2f2da7344a Mon Sep 17 00:00:00 2001 From: 祖安之光 <11848914+light-of-zuan@user.noreply.gitee.com> Date: 星期五, 22 八月 2025 10:44:10 +0800 Subject: [PATCH] 修改新增 --- src/views/work/qualityInfo/infrastructureMng/maintainPlan/index.vue | 2 src/views/work/qualityInfo/inventoryRecord/components/editDialog.vue | 391 ++++++++++++++++++++++++++++++++ src/api/outsourcingCooperate/outsourcingCooperate.js | 33 ++ src/views/work/qualityInfo/inventoryRecord/index.vue | 293 ++++++++++++++++++++++++ 4 files changed, 717 insertions(+), 2 deletions(-) diff --git a/src/api/outsourcingCooperate/outsourcingCooperate.js b/src/api/outsourcingCooperate/outsourcingCooperate.js index 05bceac..4647c0b 100644 --- a/src/api/outsourcingCooperate/outsourcingCooperate.js +++ b/src/api/outsourcingCooperate/outsourcingCooperate.js @@ -103,3 +103,36 @@ data: data }) } + + +export function getWarehousingRecordList(query) { + return request({ + url: '/system/warehousingRecord/selectWarehousingRecordList', + method: 'get', + params: query + }) +} + +export function delWarehousingRecord(query) { + return request({ + url: '/system/warehousingRecord/deletedWarehousingRecord', + method: 'get', + params: query + }) +} + +export function getWarehousingRecordDetail(query) { + return request({ + url: '/system/warehousingRecord/getWarehousingRecord', + method: 'get', + params: query + }) +} + +export function updateWarehousingRecord(data) { + return request({ + url: '/system/warehousingRecord/saveWarehousingRecord', + method: 'post', + data: data + }) +} diff --git a/src/views/work/qualityInfo/infrastructureMng/maintainPlan/index.vue b/src/views/work/qualityInfo/infrastructureMng/maintainPlan/index.vue index 674d657..ed5a45a 100644 --- a/src/views/work/qualityInfo/infrastructureMng/maintainPlan/index.vue +++ b/src/views/work/qualityInfo/infrastructureMng/maintainPlan/index.vue @@ -428,8 +428,6 @@ // 导出Excel文件 writeFile(wb, `${tableData.companyName}${tableData.year}年度基础设施维护计划.xlsx`); - - }else{ ElMessage.warning('暂无数据') } diff --git a/src/views/work/qualityInfo/inventoryRecord/components/editDialog.vue b/src/views/work/qualityInfo/inventoryRecord/components/editDialog.vue new file mode 100644 index 0000000..b269e44 --- /dev/null +++ b/src/views/work/qualityInfo/inventoryRecord/components/editDialog.vue @@ -0,0 +1,391 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="75%" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" :disabled="state.title =='查看'" clearable @change="getDeptList"> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="记录名称:" prop="recordName"> + <el-input v-model.trim="state.form.recordName" :readonly="state.title =='查看'" placeholder="文件名称"></el-input> + </el-form-item> + <el-form-item label="材料清单:" prop="warehousingRecordDetails"> + <el-button + type="primary" + plain + icon="Plus" + @click="addLine" + style="margin-bottom: 10px" + v-if="state.title !=='查看'" + >新增</el-button> + </el-form-item> + <el-table :data="state.form.warehousingRecordDetails" class="customedTable" :border="true"> + <el-table-column label="序号" type="index" width="80" align="center"> + </el-table-column> + <el-table-column label="登记时间" prop="boardingTime" align="center"> + <template #default="scope"> + <el-date-picker + v-model="scope.row.boardingTime" + type="datetime" + value-format="YYYY-MM-DD HH:mm" + placeholder="请选择时间" + :disabled="state.title =='查看'" + /> + </template> + </el-table-column> + <el-table-column label="名称" prop="name" align="center"> + <template #default="scope"> + <el-input + v-model.trim="scope.row.name" + size="large" + type="textarea" + style="width: 100%;" + clearable + :readonly="state.title =='查看'" + > + </el-input> + </template> + </el-table-column> + <el-table-column label="入库-单位" prop="enterCompany" align="center"> + <template #default="scope"> + <el-input + v-model.trim="scope.row.enterCompany" + size="large" + type="textarea" + style="width: 100%;" + clearable + :readonly="state.title =='查看'" + > + </el-input> + </template> + </el-table-column> + <el-table-column label="入库数量" prop="enterNum" align="center"> + <template #default="scope"> + <el-input + v-model.trim.number="scope.row.enterNum" + size="large" + type="number" + style="width: 100%;" + clearable + :readonly="state.title =='查看'" + > + </el-input> + </template> + </el-table-column> + <el-table-column label="入库-入库经手人" prop="enterPerson" align="center"> + <template #default="scope"> + <el-input + v-model.trim="scope.row.enterPerson" + size="large" + type="textarea" + style="width: 100%;" + clearable + :readonly="state.title =='查看'" + > + </el-input> + </template> + </el-table-column> + <el-table-column label="出库-出库单位" prop="outboundCompany" align="center"> + <template #default="scope"> + <el-input + v-model.trim="scope.row.outboundCompany" + size="large" + type="textarea" + style="width: 100%;" + clearable + :readonly="state.title =='查看'" + > + </el-input> + </template> + </el-table-column> + <el-table-column label="出库-出库数量" prop="outboundNum" align="center"> + <template #default="scope"> + <el-input + v-model.trim.number="scope.row.outboundNum" + size="large" + type="number" + style="width: 100%;" + clearable + :readonly="state.title =='查看'" + > + </el-input> + </template> + </el-table-column> + <el-table-column label="出库-出库经手人" prop="outboundPerson" align="center"> + <template #default="scope"> + <el-input + v-model.trim="scope.row.outboundPerson" + size="large" + type="textarea" + style="width: 100%;" + clearable + :readonly="state.title =='查看'" + > + </el-input> + </template> + </el-table-column> + <el-table-column label="库存数量" prop="amount" align="center"> + <template #default="scope"> + <el-input + v-model.trim.number="scope.row.amount" + size="large" + type="number" + style="width: 100%;" + clearable + :readonly="state.title =='查看'" + > + </el-input> + </template> + </el-table-column> + <el-table-column label="备注" prop="remark" align="center"> + <template #default="scope"> + <el-input + v-model.trim="scope.row.remark" + size="large" + type="textarea" + style="width: 100%;" + clearable + :readonly="state.title =='查看'" + > + </el-input> + </template> + </el-table-column> + <el-table-column label="操作" align="center" width="70" v-if="state.title !=='查看'"> + <template #default="scope"> + <el-button link type="danger" @click="handleDelete(scope.$index)">删除</el-button> + </template> + </el-table-column> + </el-table> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {getToken} from "@/utils/auth"; +import { + updateMaintenanceEvaluate, + getMaintenanceEvaluateDetail +} from "@/api/infrastructureMng/ledger"; + +import {listUser} from "@/api/system/user"; +import {getWarehousingRecordDetail, updateWarehousingRecord} from "@/api/outsourcingCooperate/outsourcingCooperate"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkList = (rule, value, callback) => { + if (state.form.warehousingRecordDetails.length == 0) { + callback(new Error('材料清单不可为空')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + companyId: null, + recordName: '', + warehousingRecordDetails: [], + delDetails: [] + }, + oldDeviceList: [], + formRules:{ + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + recordName: [{ required: true, message: '请填写记录名称', trigger: 'blur' }], + warehousingRecordDetails: [{ required: true, validator: checkList, trigger: 'blur' }], + }, + isAdmin: false, + companyList: [] +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + await getInfo(value.id) + } + dialogVisible.value = true +} + +const addLine = () => { + const obj = { + id: null, + recordId: null, + boardingTime: '', + name: '', + enterCompany: '', + enterNum: null, + enterPerson: '', + outboundCompany: '', + outboundNum: null, + outboundPerson: '', + amount: null, + remark: '' + } + state.form.warehousingRecordDetails.push(obj); +} + +const handleDelete = (i) =>{ + state.form.warehousingRecordDetails = state.form.warehousingRecordDetails.filter((item,index) => index != i) +} + +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + const data = JSON.parse(JSON.stringify(state.form)) + console.log(data,'return') + // return + data.delDetails = state.oldDeviceList.filter(i =>!data.warehousingRecordDetails.some(item=>item.id == i.id)).map(i=>i.id) + if(state.title == '新增'){ + delete data.id + const res = await updateWarehousingRecord(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await updateWarehousingRecord(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const getInfo = async (id)=> { + const res = await getWarehousingRecordDetail({id: id}) + if(res.code == 200){ + Object.keys(state.form).forEach(key => { + if (key in res.data) { + state.form[key] = res.data[key] + } + }) + state.form.warehousingRecordDetails = res.data.warehousingRecordDetails?.map(item=>{ + return { + id: item.id, + recordId: item.recordId, + boardingTime: item.boardingTime, + name: item.name, + enterCompany: item.enterCompany, + enterNum: item.enterNum, + enterPerson: item.enterPerson, + outboundCompany: item.outboundCompany, + outboundNum: item.outboundNum, + outboundPerson: item.outboundPerson, + amount: item.amount, + remark: item.remark + } + }) + state.oldDeviceList = state.form.warehousingRecordDetails + }else{ + ElMessage.warning(res.message) + } +} + +const getDeptList = async ()=>{ + // state.form.establishmentId = null + // state.form.processId = null + // state.form.approvalId = null + // await getUserList(state.form.companyId) +} + +const getUserList = async (companyId)=> { + const res = await listUser({pageIndex: 1,pageSize: 999,companyId: companyId}) + if(res.code == 200){ + state.userList = res.data.list?res.data.list.map(item=>{ + const user = item.id + const {id, ...data} = item + return { + ...data, + userId: user + } + }):[] + }else{ + ElMessage.warning(res.message) + } +} + +const handleClose = () => { + state.form = { + id: null, + companyId: null, + recordName: '', + warehousingRecordDetails: [], + delDetails: [] + } + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> +<style lang="scss"> +.customedTable{ + width: calc(100% - 150px); + margin-left: 150px; + margin-bottom: 30px; + .el-table__cell{ + padding: 2px 0 !important; + font-size: 14px !important; + } + .cell{ + padding: 0 2px !important; + font-size: 14px !important; + } +} +</style> diff --git a/src/views/work/qualityInfo/inventoryRecord/index.vue b/src/views/work/qualityInfo/inventoryRecord/index.vue new file mode 100644 index 0000000..93797ad --- /dev/null +++ b/src/views/work/qualityInfo/inventoryRecord/index.vue @@ -0,0 +1,293 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item > + <el-button v-if="isAdmin" type="primary" @click="getList">查询</el-button> + <el-button v-if="isAdmin" type="primary" plain @click="reset">重置</el-button> +<!-- <el-button type="primary">导出</el-button>--> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column type="index" label="序号"></el-table-column> + <el-table-column prop="recordName" align="center" label="记录名称" v-if="isAdmin"></el-table-column> + <el-table-column label="操作" align="center"> + <template #default="scope"> + <el-button link type="primary" @click="openDialog('view',scope.row)">查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="primary" @click="downloadFile(scope.row)">导出</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import useUserStore from "@/store/modules/user"; +import { utils, writeFile } from 'xlsx-js-style'; +import { + delWarehousingRecord, + getWarehousingRecordDetail, + getWarehousingRecordList +} from "@/api/outsourcingCooperate/outsourcingCooperate"; + + +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null + }, + total: 0, + dataList: [], + companyList: [], + isAdmin: false, +}); + +const { queryParams, total, dataList,companyList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getList() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getWarehousingRecordList(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list || [] + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const downloadFile = async (val)=>{ + const res = await getWarehousingRecordDetail({id: val.id}) + if(res.code == 200){ + if(res.data){ + const jsonData = res.data + const columns = [ + { label: '序号', key: 'index' }, + { label: '登记时间', key: 'boardingTime' }, + { label: '名称', key: 'name' }, + { label: '入库单位', key: 'enterCompany' }, + { label: '入库数量', key: 'enterNum' }, + { label: '入库经手人', key: 'enterPerson' }, + { label: '出库单位', key: 'outboundCompany' }, + { label: '出库数量', key: 'outboundNum' }, + { label: '出库经手人', key: 'outboundPerson' }, + { label: '库存数量', key: 'amount' }, + { label: '备注', key: 'remark' } + ]; + + // 样式定义 + const headerStyle = { + font: { bold: true, sz: 12, color: { rgb: "FFFFFF" } }, + fill: { fgColor: { rgb: "3498DB" } }, + alignment: { horizontal: "center", vertical: "center" }, + border: { + top: { style: "thin", color: { rgb: "000000" } }, + bottom: { style: "thin", color: { rgb: "000000" } }, + left: { style: "thin", color: { rgb: "000000" } }, + right: { style: "thin", color: { rgb: "000000" } } + } + }; + + const dataStyle = { + font: { sz: 11 }, + alignment: { vertical: "center" }, + border: { + top: { style: "thin", color: { rgb: "000000" } }, + bottom: { style: "thin", color: { rgb: "000000" } }, + left: { style: "thin", color: { rgb: "000000" } }, + right: { style: "thin", color: { rgb: "000000" } } + } + }; + + const titleStyle = { + font: { bold: true, sz: 16, color: { rgb: "2C3E50" } }, + alignment: { horizontal: "center", vertical: "center" } + }; + + // 处理数据,添加序号 + const processData = () => { + return jsonData.warehousingRecordDetails.map((item, index) => { + return { + index: index + 1, + ...item + }; + }); + }; + // 创建工作簿 + const wb = utils.book_new(); + const wsData = []; + + // 添加标题行(合并所有列) + const titleRow = [{ + v: jsonData.recordName, + t: 's', + s: titleStyle + }]; + // 填充空单元格以匹配列数 + for (let i = 1; i < columns.length; i++) { + titleRow.push({ v: '', t: 's', s: titleStyle }); + } + wsData.push(titleRow); + + // 添加表头 + const headerRow = columns.map(col => ({ + v: col.label, + t: 's', + s: headerStyle + })); + wsData.push(headerRow); + + // 添加数据行 + const processedData = processData(); + processedData.forEach(item => { + const row = columns.map(col => ({ + v: item[col.key], + t: typeof item[col.key] === 'number' ? 'n' : 's', + s: dataStyle + })); + wsData.push(row); + }); + + // 创建工作表 + const ws = utils.aoa_to_sheet(wsData); + + // 设置合并单元格(标题行) + ws['!merges'] = [ + { s: { r: 0, c: 0 }, e: { r: 0, c: columns.length - 1 } } + ]; + + // 设置列宽 + const colWidths = [ + { wch: 8 }, // 序号 + { wch: 20 }, // 登记时间 + { wch: 15 }, // 名称 + { wch: 15 }, // 入库单位 + { wch: 12 }, // 入库数量 + { wch: 15 }, // 入库经手人 + { wch: 15 }, // 出库单位 + { wch: 12 }, // 出库数量 + { wch: 15 }, // 出库经手人 + { wch: 12 }, // 库存数量 + { wch: 20 } // 备注 + ]; + ws['!cols'] = colWidths; + + // 添加工作表到工作簿 + utils.book_append_sheet(wb, ws, jsonData.recordName); + + // 生成Excel文件并下载 + writeFile(wb, `${jsonData.recordName}.xlsx`); + }else{ + ElMessage.warning('暂无数据') + } + }else{ + ElMessage.warning(res.message) + } +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null + } + await getCompanyList() + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delWarehousingRecord({id: val.id}) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> -- Gitblit v1.9.2