diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue
index 1d326a0..648eba2 100644
--- a/src/layout/components/Sidebar/SidebarItem.vue
+++ b/src/layout/components/Sidebar/SidebarItem.vue
@@ -16,6 +16,7 @@
+ {{ total }}
-
+
diff --git a/src/views/design/volumeCatalog/index.vue b/src/views/design/volumeCatalog/index.vue
index 660782d..93e36e9 100644
--- a/src/views/design/volumeCatalog/index.vue
+++ b/src/views/design/volumeCatalog/index.vue
@@ -55,7 +55,9 @@
-
+ 未出图
+ 已出图
+
diff --git a/src/views/materials/batchPlan/index.vue b/src/views/materials/batchPlan/index.vue
index 115763f..b301a4e 100644
--- a/src/views/materials/batchPlan/index.vue
+++ b/src/views/materials/batchPlan/index.vue
@@ -70,10 +70,11 @@
>修改
-
- 审核
+
+ 审核
+
+
+ 查看流程
@@ -125,9 +126,9 @@
-
+
- selectNameVersion(val, scope.row, scope.$index)">
+ selectNameVersion(val, scope.row, scope.$index)">
@@ -136,7 +137,7 @@
selectName(val, scope.row, scope.$index)"
@@ -197,7 +198,7 @@
-
+
@@ -257,8 +258,9 @@ interface PlanListItem {
remark?: string | undefined;
Remaining: number; // 剩余量(必存在)
quantityError: string; // 数量错误提示
- versions?: string | undefined; // 版本号
+ batchNumber?: string | undefined; // 版本号
duplicateError: string; // 重复错误提示
+ mrpBaseId?: number | undefined;
}
interface FormData {
@@ -321,8 +323,9 @@ const initFormData: FormData = {
remark: undefined,
Remaining: 0, // 初始化剩余量
quantityError: '', // 初始化数量错误提示
- versions: undefined, // 初始化版本号
- duplicateError: '' // 初始化重复错误提示
+ batchNumber: undefined, // 初始化版本号
+ duplicateError: '', // 初始化重复错误提示
+ mrpBaseId: undefined
}
]
};
@@ -435,14 +438,14 @@ const checkDuplicate = () => {
for (let i = 0; i < planList.length; i++) {
const current = planList[i];
// 跳过版本号或物资名称为空的行
- if (!current.versions || !current.suppliespriceId) continue;
+ if (!current.batchNumber || !current.suppliespriceId) continue;
for (let j = i + 1; j < planList.length; j++) {
const compare = planList[j];
- if (!compare.versions || !compare.suppliespriceId) continue;
+ if (!compare.batchNumber || !compare.suppliespriceId) continue;
// 版本号和物资ID都相同则判定为重复
- if (current.versions === compare.versions && current.suppliespriceId === compare.suppliespriceId) {
+ if (current.batchNumber === compare.batchNumber && current.suppliespriceId === compare.suppliespriceId) {
current.duplicateError = `与第${j + 1}行重复(同版本+同物资)`;
compare.duplicateError = `与第${i + 1}行重复(同版本+同物资)`;
hasDuplicate = true;
@@ -455,6 +458,8 @@ const checkDuplicate = () => {
/** 选择物资名称触发(新增索引参数,用于触发重复校验) */
const selectName = (val: number, row: PlanListItem, index: number) => {
+ console.log(row);
+
// 1. 获取剩余量并更新基础信息
getMrpBaseRemaining(val, row).then(() => {
const selected = nameList.value.find((item: any) => item.id === val);
@@ -524,8 +529,9 @@ const addRow = () => {
remark: undefined,
Remaining: 0,
quantityError: '',
- versions: undefined,
- duplicateError: ''
+ batchNumber: undefined,
+ duplicateError: '',
+ mrpBaseId: undefined
};
form.value.planList.push(newRow);
};
@@ -569,13 +575,14 @@ const handleUpdata = () => {
if (!queryParams.value.mainData.mrpBaseId) {
return proxy?.$modal.msgError('请先选择批次');
}
-
+ // 1. 获取对应版本的物资列表
reset();
loading.value = true;
getCailiaoshebei(queryParams.value.mainData.mrpBaseId)
.then((res: any) => {
// 1. 更新基础信息
form.value.mrpBaseBo = res.data.mrpBaseBo || initFormData.mrpBaseBo;
+
// 2. 更新表格数据(补充缺失字段)
form.value.planList = (res.data.planList || []).map((item: any) => ({
id: item.id,
@@ -589,8 +596,9 @@ const handleUpdata = () => {
remark: item.remark,
Remaining: item.Remaining || 0,
quantityError: '',
- versions: item.versions,
- duplicateError: ''
+ batchNumber: item.batchNumber,
+ duplicateError: '',
+ mrpBaseId: item.mrpBaseId
}));
// 3. 打开对话框
dialog.visible = true;
@@ -682,7 +690,7 @@ function validateAndClean(arr: PlanListItem[]) {
const item = cleanedArr[idx];
// 校验版本号
- if (!item.versions) {
+ if (!item.batchNumber) {
return { valid: false, message: `第${idx + 1}行:版本号不能为空`, data: cleanedArr };
}
@@ -764,7 +772,7 @@ const getVersion = () => {
/** 选择版本号触发(新增索引参数,用于触发重复校验) */
const selectNameVersion = (val: string, row: PlanListItem, index: number) => {
- row.versions = val;
+ row.batchNumber = val;
row.suppliespriceId = undefined; // 切换版本号时清空物资选择
row.name = undefined;
row.specification = undefined;
@@ -775,6 +783,7 @@ const selectNameVersion = (val: string, row: PlanListItem, index: number) => {
row.demandQuantity = undefined;
row.quantityError = '';
row.duplicateError = '';
+ row.mrpBaseId = '';
// 1. 获取对应版本的物资列表
getNameList(val);
diff --git a/src/views/project/landTransfer/BusinessLedger/landTransferLedger/index.vue b/src/views/project/landTransfer/BusinessLedger/landTransferLedger/index.vue
index 8cfc84e..bebbe31 100644
--- a/src/views/project/landTransfer/BusinessLedger/landTransferLedger/index.vue
+++ b/src/views/project/landTransfer/BusinessLedger/landTransferLedger/index.vue
@@ -12,8 +12,9 @@
-
+
+
+
@@ -88,90 +89,107 @@
-
+
+
+
-
+
+
+
-
+
+
+
+
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
@@ -197,6 +215,20 @@ import { listEnterRoad } from '@/api/system/landTransfer/enterRoad';
import { LandTransferLedgerVO, LandTransferLedgerQuery, LandTransferLedgerForm } from '@/api/system/landTransfer/landTransferLedger/types';
import { useUserStoreHook } from '@/store/modules/user';
import { listLandBlock } from '@/api/system/landTransfer/landBlock';
+import { getCurrentInstance, ComponentInternalInstance, watch, onUnmounted, onMounted } from 'vue';
+import { ElFormInstance } from 'element-plus';
+
+// 类型定义补充
+interface DialogOption {
+ visible: boolean;
+ title: string;
+}
+interface PageData {
+ form: T;
+ queryParams: Q;
+ rules: Record;
+}
+
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
// 获取用户 store
const userStore = useUserStoreHook();
@@ -214,6 +246,7 @@ const landBlockList = ref([]);
const queryFormRef = ref();
const landTransferLedgerFormRef = ref();
const enterRoadList = ref([]);
+// 字典数据
const { land_type, land_transfer_status } = toRefs(proxy?.useDict('land_type', 'land_transfer_status'));
const dialog = reactive({
@@ -221,7 +254,8 @@ const dialog = reactive({
title: ''
});
-const initFormData = {
+// 表单初始数据
+const initFormData: LandTransferLedgerForm = {
id: undefined,
projectId: currentProject.value?.id,
landType: undefined,
@@ -244,6 +278,8 @@ const initFormData = {
noSurveyArea: undefined,
nonTransferReason: undefined
};
+
+// 核心数据响应式对象
const data = reactive>({
form: { ...initFormData },
queryParams: {
@@ -273,21 +309,38 @@ const data = reactive>
projectId: [{ required: true, message: '项目ID不能为空', trigger: 'blur' }],
landType: [{ required: true, message: '土地类型不能为空', trigger: 'change' }],
transferRatio: [
- { required: true, message: '流转比例不能为空', trigger: ['blur', 'change'] }, // 必填
+ // 动态校验:仅已流转状态下必填
+ {
+ required: true,
+ message: '流转比例不能为空',
+ trigger: ['blur', 'change'],
+ validator: (rule, value, callback) => {
+ if (data.form.transferStatus !== '1') {
+ callback(); // 非已流转状态跳过校验
+ return;
+ }
+ if (value === undefined || value === null || value === '') {
+ callback(new Error('流转比例不能为空'));
+ } else {
+ callback();
+ }
+ }
+ },
+ // 比例范围校验(0-100)
{
validator: (rule, value, callback) => {
- // 校验数值是否在 0-100 之间(包含0和100)
if (value < 0 || value > 100) {
callback(new Error('流转比例必须在 0-100 之间'));
} else {
- callback(); // 校验通过
+ callback();
}
},
- trigger: 'blur' // 失去焦点时触发校验
+ trigger: 'blur'
}
]
}
});
+
const detailInfo = ref({
transferAea: 0,
transferRatio: 0,
@@ -295,18 +348,53 @@ const detailInfo = ref({
});
const { queryParams, form, rules } = toRefs(data);
+/**
+ * 自动计算流转比例:(已流转面积 / 设计面积) × 100,保留2位小数,最大100%
+ */
+const calcTransferRatio = () => {
+ // 仅已流转状态下计算
+ if (form.value.transferStatus !== '1') {
+ form.value.transferRatio = undefined;
+ return;
+ }
+
+ // 转换为数字(避免字符串计算)
+ const designArea = Number(form.value.designArea) || 0;
+ const transferAea = Number(form.value.transferAea) || 0;
+
+ // 边界处理:设计面积为0时避免报错
+ if (designArea === 0) {
+ form.value.transferRatio = 0;
+ return;
+ }
+
+ // 核心计算:限制最大100%,保留2位小数
+ const ratio = Math.min((transferAea / designArea) * 100, 100);
+ form.value.transferRatio = Number(ratio.toFixed(2));
+};
+
/** 查询项目土地流转台账列表 */
const getList = async () => {
loading.value = true;
- const res = await listLandTransferLedger(queryParams.value);
- landTransferLedgerList.value = res.rows;
- total.value = res.total;
- loading.value = false;
+ try {
+ const res = await listLandTransferLedger(queryParams.value);
+ landTransferLedgerList.value = res.rows;
+ total.value = res.total;
+ } finally {
+ loading.value = false;
+ }
};
+
+/** 获取地块统计信息 */
const getLandBlockList = async () => {
- let res = await landTransferLedgerCount(currentProject.value?.id);
- detailInfo.value = res.data;
+ try {
+ const res = await landTransferLedgerCount(currentProject.value?.id);
+ detailInfo.value = res.data;
+ } catch (error) {
+ console.error('获取地块统计信息失败:', error);
+ }
};
+
/** 取消按钮 */
const cancel = () => {
dialog.visible = false;
@@ -334,92 +422,143 @@ const resetQuery = () => {
/** 多选框选中数据 */
const handleSelectionChange = (selection: LandTransferLedgerVO[]) => {
ids.value = selection.map((item) => item.id);
- single.value = selection.length != 1;
- multiple.value = !selection.length;
+ single.value = selection.length !== 1;
+ multiple.value = selection.length === 0;
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
- form.value.transferStatus = '0';
- dialog.visible = true;
+ form.value.transferStatus = '0'; // 默认待流转
enterRoadList.value = [];
dialog.title = '添加项目土地流转台账';
+ dialog.visible = true;
};
/** 修改按钮操作 */
const handleUpdate = async (row?: LandTransferLedgerVO) => {
reset();
- form.value.landBlockId = row?.landBlockId;
- getListRoad();
const _id = row?.id || ids.value[0];
- const res = await getLandTransferLedger(_id);
- Object.assign(form.value, res.data);
- console.log(form.value);
+ if (!_id) return;
- dialog.visible = true;
- dialog.title = '修改项目土地流转台账';
+ try {
+ // 获取编辑数据
+ const res = await getLandTransferLedger(_id);
+ Object.assign(form.value, res.data);
+ // 回显地块对应的道路列表
+ form.value.landBlockId = row?.landBlockId;
+ await getListRoad();
+ // 初始化计算流转比例
+ calcTransferRatio();
+ // 打开弹窗
+ dialog.title = '修改项目土地流转台账';
+ dialog.visible = true;
+ } catch (error) {
+ console.error('获取编辑数据失败:', error);
+ proxy?.$modal.msgError('加载数据失败,请重试');
+ }
};
/** 提交按钮 */
const submitForm = () => {
landTransferLedgerFormRef.value?.validate(async (valid: boolean) => {
- if (valid) {
- buttonLoading.value = true;
+ if (!valid) return;
+
+ buttonLoading.value = true;
+ try {
if (form.value.id) {
- await updateLandTransferLedger(form.value).finally(() => (buttonLoading.value = false));
+ await updateLandTransferLedger(form.value);
} else {
- await addLandTransferLedger(form.value).finally(() => (buttonLoading.value = false));
+ await addLandTransferLedger(form.value);
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
+ await getLandBlockList(); // 刷新统计信息
+ } catch (error) {
+ proxy?.$modal.msgError('操作失败,请重试');
+ console.error('提交表单失败:', error);
+ } finally {
+ buttonLoading.value = false;
}
});
};
+
/** 删除按钮操作 */
const handleDelete = async (row?: LandTransferLedgerVO) => {
const _ids = row?.id || ids.value;
- await proxy?.$modal.confirm('是否确认删除项目土地流转台账编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
- await delLandTransferLedger(_ids);
- proxy?.$modal.msgSuccess('删除成功');
- await getList();
+ if (!_ids.length) return;
+
+ try {
+ await proxy?.$modal.confirm(`是否确认删除项目土地流转台账编号为"${_ids}"的数据项?`);
+ await delLandTransferLedger(_ids);
+ proxy?.$modal.msgSuccess('删除成功');
+ await getList();
+ await getLandBlockList(); // 刷新统计信息
+ } catch (error) {
+ console.error('删除数据失败:', error);
+ if (error !== 'cancel') {
+ // 排除用户取消确认的情况
+ proxy?.$modal.msgError('删除失败,请重试');
+ }
+ } finally {
+ loading.value = false;
+ }
};
-// 选择地块
-const handleLandBlockChange = (val) => {
- getListRoad();
+
+/** 选择地块后加载对应道路 */
+const handleLandBlockChange = async () => {
+ await getListRoad();
};
-/** 查询地块信息列表 */
+
+/** 查询地块列表 */
const getListLand = async () => {
- const res = await listLandBlock({
- pageNum: 1,
- pageSize: 10000,
- projectId: currentProject.value?.id
- });
- landBlockList.value = res.rows;
+ try {
+ const res = await listLandBlock({
+ pageNum: 1,
+ pageSize: 10000,
+ projectId: currentProject.value?.id
+ });
+ landBlockList.value = res.rows;
+ } catch (error) {
+ console.error('获取地块列表失败:', error);
+ }
};
-/** 查询进场道路信息列表 */
+
+/** 查询进场道路列表(按地块筛选) */
const getListRoad = async () => {
- const res = await listEnterRoad({ pageNum: 1, pageSize: 10000, projectId: currentProject.value?.id, landBlockId: form.value.landBlockId });
- enterRoadList.value = res.rows;
+ try {
+ const res = await listEnterRoad({
+ pageNum: 1,
+ pageSize: 10000,
+ projectId: currentProject.value?.id,
+ landBlockId: form.value.landBlockId
+ });
+ enterRoadList.value = res.rows;
+ } catch (error) {
+ console.error('获取进场道路列表失败:', error);
+ }
};
-//监听项目id刷新数据
+
+/** 监听项目切换,刷新数据 */
const listeningProject = watch(
() => currentProject.value?.id,
- (nid, oid) => {
- queryParams.value.projectId = nid;
- getLandBlockList();
- getListLand();
- getList();
- }
+ async (newId) => {
+ if (newId) {
+ queryParams.value.projectId = newId;
+ await Promise.all([getLandBlockList(), getListLand(), getList()]);
+ }
+ },
+ { immediate: true } // 初始加载时触发
);
+/** 组件卸载时清理监听 */
onUnmounted(() => {
listeningProject();
});
+
+/** 组件挂载时初始化数据 */
onMounted(() => {
- getLandBlockList();
- getList();
- getListLand();
+ Promise.all([getLandBlockList(), getListLand(), getList()]);
});