Files
td_official/src/views/materials/usageMaterials/material/index.vue
2025-08-20 19:25:52 +08:00

483 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="p-5">
<!-- 主要内容区 -->
<el-card class="mb-5">
<el-button
icon="Refresh"
v-hasPermi="['cailiaoshebei:physicalsupply:list']"
@click="refreshData"
class="transition-all duration-200 hover:shadow-md"
>
刷新
</el-button>
</el-card>
<!-- 数据表格 -->
<div class="bg-white rounded-lg shadow-sm overflow-hidden transition-all duration-300 hover:shadow-md">
<el-table
v-loading="loading"
:data="tableData"
border
stripe
:header-cell-style="{ 'background-color': '#f5f7fa', 'font-weight': 'bold' }"
style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)"
:row-class-name="tableRowClassName"
>
<el-table-column prop="id" label="ID" width="180" align="center"></el-table-column>
<el-table-column prop="name" label="材料名称" min-width="150"></el-table-column>
<el-table-column prop="specification" label="规格" min-width="120"></el-table-column>
<el-table-column prop="supplier" label="供应商" min-width="150"></el-table-column>
<el-table-column prop="findType" label="类型" width="100" align="center">
<template #default="scope">
<el-tag :type="scope.row.findType === '1' ? 'success' : 'info'">
{{ scope.row.findType === '1' ? '采购' : '材料' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="installationQuantity" label="安装量" width="100" align="center"></el-table-column>
<el-table-column prop="contractSigning" label="合同签订时间" width="180" align="center">
<template #default="scope">
{{ formatDate(scope.row.contractSigning) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" width="180" align="center">
<template #default="scope">
{{ formatDate(scope.row.createTime) }}
</template>
</el-table-column>
<el-table-column label="操作" width="180" align="center" fixed="right">
<template #default="scope">
<!-- <el-button size="small" icon="Plus" @click="handleAddSon(scope.row)"
class="text-blue-600 hover:text-blue-800 transition-colors"></el-button> -->
<el-button
size="small"
v-hasPermi="['cailiaoshebei:physicalsupply:edit']"
icon="Edit"
@click="handleEdit(scope.row)"
class="text-blue-600 hover:text-blue-800 transition-colors"
></el-button>
<el-button
size="small"
v-hasPermi="['cailiaoshebei:physicalsupplySon:list']"
icon="View"
@click="jumpRouter(scope.row)"
class="text-blue-600 hover:text-blue-800 transition-colors"
></el-button>
<el-button
size="small"
v-hasPermi="['cailiaoshebei:physicalsupply:remove']"
icon="Delete"
@click="handleDelete(scope.row)"
class="text-red-600 hover:text-red-800 transition-colors"
></el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="flex items-center justify-between p-4 border-t">
<div class="text-gray-500 text-sm">
{{ total }} 条记录当前显示第 {{ (currentPage - 1) * pageSize + 1 }} {{ Math.min(currentPage * pageSize, total) }}
</div>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="total"
layout="prev, pager, next, jumper, sizes"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog
v-model="dialogVisible"
:title="dialogType === 'add' ? '新增记录' : '编辑记录'"
:width="dialogWidth"
:fullscreen="isFullscreen"
:before-close="handleDialogClose"
>
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px" class="space-y-4">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="材料名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入材料名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="规格" prop="specification">
<el-input v-model="formData.specification" placeholder="请输入规格"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="供应商" prop="supplier">
<el-input v-model="formData.supplier" placeholder="请输入供应商"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="运算周期(天)" prop="executionCycle">
<el-input v-model.number="formData.executionCycle" placeholder="请输入运算周期" type="number"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="安装量" prop="installationQuantity">
<el-input v-model="formData.installationQuantity" placeholder="请输入安装量"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="安装比例" prop="installationRatio">
<el-input v-model="formData.installationRatio" placeholder="请输入安装比例" suffix="%"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="合同签订时间" prop="contractSigning">
<el-date-picker
v-model="formData.contractSigning"
type="datetime"
placeholder="选择合同签订时间"
value-format="YYYY-MM-DD HH:mm:ss"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产周期(天)" prop="productionPhase">
<el-input v-model.number="formData.productionPhase" placeholder="请输入生产周期" type="number"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="供货要求" prop="supplyRequirements">
<el-input v-model="formData.supplyRequirements" placeholder="请输入供货要求" type="textarea" rows="3"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注信息" type="textarea" rows="3"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="flex justify-end gap-2">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSave" :loading="saveLoading"> 保存 </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, computed, toRaw } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useUserStoreHook } from '@/store/modules/user';
import { useRouter } from 'vue-router';
const userStore = useUserStoreHook();
const router = useRouter();
const currentProject = computed(() => userStore.selectedProject);
import { useMaterialsQueryList, newMaterialsAdd, materialsEdit, materialsDel, queryMaterialsInfo } from '@/api/materials/usageMaterials/index';
// 表格数据相关
const tableData = ref([]);
const total = ref(0);
const currentPage = ref(1);
const pageSize = ref(10);
const loading = ref(false);
// 对话框相关
const dialogVisible = ref(false);
const dialogType = ref('add'); // add 或 edit
const dialogWidth = ref('70%');
const isFullscreen = ref(false);
const deleteDialogVisible = ref(false);
const formRef = ref(null);
const formRef2 = ref(null);
const saveLoading = ref(false);
const deleteLoading = ref(false);
const currentRow = ref(null);
const submitLoading = ref(false);
// 表单数据
const formData = reactive({
id: '',
name: '',
specification: '',
supplier: '',
findType: 2, // 默认采购
installationQuantity: '',
installationRatio: '',
contractSigning: '',
productionPhase: null,
executionCycle: null,
projectId: currentProject.value?.id,
supplyRequirements: '',
// purchaseSubmission: '',
// submissionMaterials: '',
remark: '',
createTime: '',
createBy: null,
updateTime: '',
updateBy: null
});
// 表单验证规则
const formRules = reactive({
name: [
{ required: true, message: '请输入材料名称', trigger: 'blur' },
{ max: 50, message: '材料名称不能超过50个字符', trigger: 'blur' }
],
supplier: [
{ required: true, message: '请输入供应商', trigger: 'blur' },
{ max: 100, message: '供应商名称不能超过100个字符', trigger: 'blur' }
],
findType: [{ required: true, message: '请选择类型', trigger: 'change' }]
});
// 格式化日期
const formatDate = (dateString) => {
if (!dateString) return '-';
const date = new Date(dateString);
return date
.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
})
.replace(',', ' ');
};
// 表格行样式
const tableRowClassName = ({ row, rowIndex }) => {
return rowIndex % 2 === 0 ? 'bg-white' : 'bg-gray-50';
};
// 获取数据
const fetchData = async () => {
loading.value = true;
try {
const res = await useMaterialsQueryList({
projectId: currentProject.value?.id,
findType: 2
});
tableData.value = res.rows;
total.value = res.total;
loading.value = false;
} catch (error) {
ElMessage.error('获取数据失败:' + error.message);
console.error(error);
} finally {
loading.value = false;
}
};
// 搜索
const handleSearch = () => {
currentPage.value = 1; // 重置到第一页
fetchData();
};
// 刷新数据
const refreshData = () => {
fetchData();
ElMessage.success('数据已刷新');
};
// 分页大小改变
const handleSizeChange = (val) => {
pageSize.value = val;
currentPage.value = 1;
fetchData();
};
// 当前页改变
const handleCurrentChange = (val) => {
currentPage.value = val;
fetchData();
};
// 新增
const handleAdd = () => {
dialogType.value = 'add';
resetForm();
dialogVisible.value = true;
};
// 编辑
const handleEdit = (row) => {
dialogType.value = 'edit';
currentRow.value = row;
resetForm();
// 填充表单数据
Object.keys(formData).forEach((key) => {
if (row.hasOwnProperty(key)) {
formData[key] = row[key];
}
});
dialogVisible.value = true;
};
const handleAddSon = (row) => {
ElMessageBox.confirm('确认提交', 'Warning', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
materialsEdit(formData).then((res) => {
let { code } = res;
if (code === 200) {
ElMessage({
type: 'success',
message: '提交成功'
});
}
});
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消提交'
});
});
};
// 删除
const handleDelete = (row) => {
currentRow.value = row;
ElMessageBox.confirm('确定要删除这条记录吗?此操作不可撤销,请谨慎操作', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
confirmDelete();
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消删除'
});
});
};
// 确认删除
const confirmDelete = async () => {
if (!currentRow.value) return;
deleteLoading.value = true;
try {
// 模拟API请求
const res = await materialsDel(currentRow.value.id);
const { code } = res;
if (code === 200) {
ElMessage.success('删除成功');
deleteDialogVisible.value = false;
fetchData();
} else {
ElMessage.error('删除失败');
}
} catch (error) {
ElMessage.error('删除失败:' + error.message);
console.error(error);
} finally {
deleteLoading.value = false;
}
};
//
// 保存
const handleSave = async () => {
// 表单验证
if (!formRef.value) return;
const valid = await formRef.value.validate();
if (!valid) return;
saveLoading.value = true;
try {
// 模拟API请求
if (dialogType.value === 'add') {
// 新增
formData.projectId = currentProject.value?.id;
const res = await newMaterialsAdd(formData);
let { code } = res;
if (code === 200) {
ElMessage.success('新增成功');
fetchData();
}
} else {
// 编辑
const res = await materialsEdit(formData);
let { code } = res;
if (code === 200) {
ElMessage.success('保存成功');
fetchData();
}
}
dialogVisible.value = false;
} catch (error) {
ElMessage.error('保存失败:' + error.message);
console.error(error);
} finally {
saveLoading.value = false;
}
};
// 重置表单
const resetForm = () => {
if (formRef.value) {
formRef.value.resetFields();
}
// 重置表单数据
Object.keys(formData).forEach((key) => {
formData[key] = '';
});
// 设置默认值
formData.findType = 2;
formData.id = '';
};
// 关闭对话框
const handleDialogClose = () => {
resetForm();
dialogVisible.value = false;
};
// 跳转
const jumpRouter = (row) => {
router.push({
path: `/materials/usageMaterials/materialIndexSon`,
query: {
id: row.id,
type: 'update'
}
});
};
// 初始化页面
onMounted(() => {
fetchData();
});
</script>
<style scoped></style>