生产经营主体组件替换

This commit is contained in:
沈鸿 2025-07-04 15:04:00 +08:00
parent a554d3753d
commit 38f508e043
2 changed files with 492 additions and 635 deletions

View File

@ -2,21 +2,35 @@
<section class="custom-page">
<!-- 四个固定 Tabs -->
<el-tabs v-model="activeCrudTab" @tab-click="handleTabChange">
<!-- <el-tab-pane label="待提交" name="0" /> -->
<el-tab-pane label="待审核" name="1" />
<el-tab-pane label="已通过" name="2" />
<el-tab-pane label="已驳回" name="3" />
</el-tabs>
<!-- 表格 -->
<avue-crud ref="crudRef" v-model:page="pageData" :data="crudData" :option="crudOptions" :table-loading="loading">
<template v-if="activeCrudTab === '0'" #menu-left>
<el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
</template>
<template #menu="scope">
<!-- 功能区域 -->
<section class="function-bar">
<el-button type="primary" @click="handleAdd">新增</el-button>
</section>
<!-- 表格区域 -->
<TableComponent
:loading="loading"
:columns="columns"
:table-data="tableData"
:current-page="pageData.currentPage"
:page-size="pageData.pageSize"
:total="pageData.total"
:show-pagination="true"
:show-border="true"
:show-sort="true"
style="max-height: calc(100vh - 300px)"
@page-change="handlePageChange"
>
<template #action="scope">
<custom-table-operate :actions="getActions(scope.row)" :data="scope" />
</template>
</avue-crud>
</TableComponent>
<el-dialog :key="dialogTitle" v-model="visible" :title="dialogTitle" width="60%" align-center :draggable="true">
<el-tabs v-model="activeTab" class="tabs-wrapper">
<el-tab-pane label="基础信息" name="basic">
@ -48,8 +62,7 @@
</template>
<script setup>
import { ref, reactive, watch, onMounted, computed } from 'vue';
import { CRUD_OPTIONS } from '@/config';
import { ref, reactive, computed, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import TabBasicInfo from './components/TabBasicInfo.vue';
import TabRegister from './components/TabRegister.vue';
@ -57,41 +70,47 @@ import TabBusinessInfo from './components/TabBusinessInfo.vue';
import TabCreditEvaluation from './components/TabCreditEvaluation.vue';
import TabMember from './components/TabMember.vue';
import { getEnterList, getEnterById, addEnter, updateEnter, approvalEnter, deleteEnter } from '@/apis/businessEntity';
import { useUserStore } from '@/store/modules/user';
//
//
const DIALOG_TITLE = {
VIEW: '查看',
EDIT: '编辑',
ADD: '新增',
};
const TAB_ORDER = ['basic', 'register', 'business', 'credit'];
//
const visible = ref(false);
const activeCrudTab = ref('1');
const activeTab = ref('basic');
const dialogTitle = ref('新增');
const dialogTitle = ref(DIALOG_TITLE.ADD);
const isReadonly = ref(false);
const loading = ref(false);
const tableData = ref([]);
//
const searchForm = ref({
businessName: '',
uscc: '',
productType: '',
primaryProduct: '',
const pageData = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
});
const initialSearchForm = { ...searchForm.value };
//
const formData = ref({
const initialFormData = {
id: '',
// basicInfo
businessName: '',
area: '',
contactPerson: '',
cooperativePhoto: '', //
cooperativePhoto: '',
addressArr: [],
primaryProduct: '',
phone: '',
businessLicence: '', //
businessLicence: '',
provinceCode: '',
cityCode: '',
countyCode: '',
townCode: '',
villageCode: '',
// registerInfo
// businessName: '',
legalRep: '',
comType: '',
regAuthority: '',
@ -102,77 +121,25 @@ const formData = ref({
totalCapital: '',
address: '',
businessScope: '',
//
debtFiles: [],
profitFiles: [],
cashflowFiles: [],
//
creditEvaluation: 5,
supportedFarmers: 4,
socialImpact: 3,
techApplication: 2,
productQuality: 1,
});
const initialFormData = { ...formData.value };
const resetForm = () => {
formData.value = { ...initialFormData };
};
const syncAddressToForm = () => {
const arr = Array.isArray(formData.value.addressArr) ? formData.value.addressArr : [];
formData.value.provinceCode = arr[0] || '';
formData.value.cityCode = arr[1] || '';
formData.value.countyCode = arr[2] || '';
formData.value.townCode = arr[3] || '';
formData.value.villageCode = arr[4] || '';
};
//
const handleSubmit = async () => {
try {
loading.value = true;
let response;
if (dialogTitle.value === '新增') {
formData.value.id = '';
syncAddressToForm();
response = await addEnter(formData.value);
if (response.code === 200) {
ElMessage.success('新增成功');
visible.value = false;
getData();
}
} else if (dialogTitle.value === '编辑') {
syncAddressToForm();
response = await updateEnter(formData.value);
if (response.code === 200) {
ElMessage.success('编辑成功');
visible.value = false;
getData();
}
}
} catch (e) {
ElMessage.error('保存失败');
} finally {
loading.value = false;
}
};
const formData = ref({ ...initialFormData });
const pageData = ref({
currentPage: 1,
pageSize: 10,
total: 0,
});
//
const currentTabIndex = computed(() => TAB_ORDER.indexOf(activeTab.value));
const isFirstTab = computed(() => currentTabIndex.value === 0);
const isLastTab = computed(() => currentTabIndex.value === TAB_ORDER.length - 1);
const crudData = ref([]);
const loading = ref(false);
const crudOptions = reactive({
...CRUD_OPTIONS,
addBtn: false,
searchBtn: false,
emptyBtn: false,
column: [
//
const columns = ref([
{ label: '生产经营主体编码', prop: 'id' },
{ label: '企业名称', prop: 'businessName' },
{ label: '企业负责人', prop: 'contactPerson' },
@ -188,40 +155,40 @@ const crudOptions = reactive({
// { label: '', prop: 'phone' },
{ label: '信息录入时间', prop: 'createTime' },
{ label: '信息更新时间', prop: 'updateTime' },
],
});
// watch(
// () => formData.value.addressArr,
// (newValue) => {
// if (newValue.length === 5) {
// formData.value.provinceCode = newValue[0] || '';
// formData.value.cityCode = newValue[1] || '';
// formData.value.countyCode = newValue[2] || '';
// formData.value.townCode = newValue[3] || '';
// formData.value.villageCode = newValue[4] || '';
// } else {
// ElMessageBox.alert('');
// }
// }
// );
{ label: '操作', prop: 'action', slotName: 'action', fixed: 'right' },
]);
onMounted(() => {
getData();
});
//
const userStore = useUserStore();
const user = computed(() => userStore.getUserInfo());
const isAdmin = computed(() => user.value.admin);
//
const resetForm = () => {
formData.value = { ...initialFormData };
};
const syncAddressToForm = () => {
const arr = Array.isArray(formData.value.addressArr) ? formData.value.addressArr : [];
formData.value.provinceCode = arr[0] || '';
formData.value.cityCode = arr[1] || '';
formData.value.countyCode = arr[2] || '';
formData.value.townCode = arr[3] || '';
formData.value.villageCode = arr[4] || '';
};
const getData = async () => {
loading.value = true;
try {
const response = await getEnterList({
...searchForm.value,
status: activeCrudTab.value,
page: pageData.value.currentPage,
size: pageData.value.pageSize,
page: pageData.currentPage,
size: pageData.pageSize,
});
crudData.value = response.data.records;
pageData.value.total = response.data.total;
pageData.value.currentPage = response.data.current;
pageData.value.pageSize = response.data.size;
tableData.value = response.data.records;
pageData.total = response.data.total;
pageData.currentPage = response.data.current;
pageData.pageSize = response.data.size;
} catch (error) {
ElMessage.error('加载数据失败');
} finally {
@ -235,7 +202,6 @@ const getEnterDetail = async (id) => {
const response = await getEnterById(id);
formData.value = {
...response.data,
// addressArr5
addressArr: [
response.data.provinceCode || '',
response.data.cityCode || '',
@ -246,25 +212,55 @@ const getEnterDetail = async (id) => {
};
} catch (error) {
ElMessage.error(`获取详情失败:${error.message || '请稍后重试'}`);
throw error;
}
};
function handleSearch() {
const handleSubmit = async () => {
loading.value = true;
try {
syncAddressToForm();
let response;
if (dialogTitle.value === DIALOG_TITLE.ADD) {
formData.value.id = '';
response = await addEnter(formData.value);
} else {
response = await updateEnter(formData.value);
}
if (response.code === 200) {
ElMessage.success(`${dialogTitle.value}成功`);
visible.value = false;
getData();
}
function handleTabChange(tab) {
handleSearch();
}
}
} catch (error) {
ElMessage.error(`${dialogTitle.value}失败`);
} finally {
loading.value = false;
}
};
const handlePageChange = ({ page, pageSize }) => {
pageData.currentPage = page;
pageData.pageSize = pageSize;
getData();
};
const handleTabChange = () => {
getData();
};
const handleAdd = () => {
isReadonly.value = false;
resetForm();
dialogTitle.value = '新增';
dialogTitle.value = DIALOG_TITLE.ADD;
visible.value = true;
};
//
const handleView = async (row) => {
loading.value = true;
dialogTitle.value = '查看';
dialogTitle.value = DIALOG_TITLE.VIEW;
try {
await getEnterDetail(row.id);
isReadonly.value = true;
@ -275,10 +271,9 @@ const handleView = async (row) => {
}
};
//
const handleEdit = async (row) => {
loading.value = true;
dialogTitle.value = '编辑';
dialogTitle.value = DIALOG_TITLE.EDIT;
try {
await getEnterDetail(row.id);
isReadonly.value = false;
@ -288,127 +283,97 @@ const handleEdit = async (row) => {
loading.value = false;
}
};
//
const handleSubmitApprove = async (row) => {
try {
const params = {
id: row.id,
status: '1', //
status: '1',
reason: '提交审核',
};
const res = await approvalEnter(params);
if (res.code === 200) {
ElMessage.success('提交审核成功');
row.status = '1';
getData(); //
} else {
ElMessage.error(res.msg || '提交审核失败');
getData();
}
} catch (error) {
ElMessage.error('提交审核失败');
}
};
//
function handleResubmit(row) {
ElMessageBox.confirm('确认重新提交吗?', '重新提交').then(() => {
const params = {
const handleResubmit = (row) => {
ElMessageBox.confirm('确认重新提交吗?', '重新提交')
.then(() =>
approvalEnter({
id: row.id,
status: '1', //
status: '1',
reason: '重新提交审核',
};
approvalEnter(params)
})
)
.then(() => {
console.log(`ID=${row.id} 重新提交审核`);
row.status = '1';
row.rejectReason = '';
getData();
ElMessage.success('已重新提交,状态已变为"待审核"');
})
.catch((error) => {
console.error('重新提交失败:', error);
ElMessage.error(error.response?.data?.msg || '重新提交失败');
});
});
}
.catch(() => {});
};
//
function handleWithdraw(row) {
ElMessageBox.confirm('确认撤销本次审核吗?', '撤销').then(() => {
const params = {
const handleWithdraw = (row) => {
ElMessageBox.confirm('确认撤销本次审核吗?', '撤销')
.then(() =>
approvalEnter({
id: row.id,
status: '0', //
status: '0',
reason: '用户主动撤销',
};
approvalEnter(params)
})
)
.then(() => {
console.log(`ID=${row.id} 撤销审核`);
row.status = '0';
getData();
ElMessage.success('已撤销,状态已变为"待提交"');
})
.catch((error) => {
console.error('撤销失败:', error);
ElMessage.error(error.response?.data?.msg || '撤销失败');
});
});
}
.catch(() => {});
};
//
function handleApprove(row) {
ElMessageBox.confirm('确认通过审核?', '审核通过').then(() => {
const params = {
const handleApprove = (row) => {
ElMessageBox.confirm('确认通过审核?', '审核通过')
.then(() =>
approvalEnter({
id: row.id,
status: '2', //
status: '2',
reason: '审核通过',
};
approvalEnter(params)
})
)
.then(() => {
console.log(`ID=${row.id} 审核通过`);
row.status = '2';
getData();
ElMessage.success('审核已通过');
})
.catch((error) => {
console.error('审核通过操作失败:', error);
ElMessage.error(error.response?.data?.msg || '审核操作失败');
});
});
}
.catch(() => {});
};
//
function handleReject(row) {
const handleReject = (row) => {
ElMessageBox.prompt('请输入驳回原因', '审核驳回', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /.+/, //
inputPattern: /.+/,
inputErrorMessage: '驳回原因不能为空',
})
.then(({ value }) => {
const params = {
.then(({ value }) =>
approvalEnter({
id: row.id,
status: '3', //
status: '3',
reason: value.trim(),
};
return approvalEnter(params).then(() => {
console.log(`ID=${row.id} 驳回,原因:${value.trim()}`);
row.status = '3';
row.rejectReason = value.trim();
})
)
.then(() => {
getData();
ElMessage.success('已驳回');
});
})
.catch((error) => {
if (error !== 'cancel') {
console.error('驳回操作失败:', error);
ElMessage.error(error.response?.data?.msg || '驳回操作失败');
}
});
}
// /
function showRejectReason(row) {
.catch(() => {});
};
const showRejectReason = (row) => {
ElMessageBox.alert(row.reason || '无驳回原因', '驳回原因');
}
//
};
const handleDelete = async (id) => {
try {
await ElMessageBox.confirm('确认删除该合作社信息?', '提示', {
@ -418,54 +383,40 @@ const handleDelete = async (id) => {
const res = await deleteEnter(id);
if (res.code === 200) {
ElMessage.success('删除成功');
getData(); //
} else {
ElMessage.error(res.msg || '删除失败');
getData();
}
} catch (e) {
if (e !== 'cancel') {
} catch (error) {
if (error !== 'cancel') {
ElMessage.error('删除失败');
}
} finally {
loading.value = false;
}
};
// tabs
const tabOrder = ['basic', 'register', 'business', 'credit'];
const currentTabIndex = computed(() => tabOrder.indexOf(activeTab.value));
const isFirstTab = computed(() => currentTabIndex.value === 0);
const isLastTab = computed(() => currentTabIndex.value === tabOrder.length - 1);
/** 跳转到下一 Tab */
function handleNext() {
if (currentTabIndex.value < tabOrder.length - 1) {
activeTab.value = tabOrder[currentTabIndex.value + 1];
const handleNext = () => {
if (currentTabIndex.value < TAB_ORDER.length - 1) {
activeTab.value = TAB_ORDER[currentTabIndex.value + 1];
}
}
};
/** 跳转到上一 Tab */
function handlePrev() {
const handlePrev = () => {
if (currentTabIndex.value > 0) {
activeTab.value = tabOrder[currentTabIndex.value - 1];
activeTab.value = TAB_ORDER[currentTabIndex.value - 1];
}
}
};
/** 跳过当前步骤 */
function handleSkip() {
const handleSkip = () => {
handleNext();
}
/** 跳过并保存 */
function handleSkipSave() {
};
const handleSkipSave = () => {
handleSkip();
handleSubmit();
}
import { useUserStore } from '@/store/modules/user';
const UserStore = useUserStore();
const user = UserStore.getUserInfo();
console.log('admin 属性:', user.admin);
const isAdmin = user.admin;
};
const getActions = (row) => {
const actions = [
const baseActions = [
{
name: '查看',
icon: 'view',
@ -486,7 +437,7 @@ const getActions = (row) => {
switch (row.status) {
case '0': //
actions.push(
baseActions.push(
{
name: '提交审核',
icon: 'check',
@ -501,8 +452,8 @@ const getActions = (row) => {
break;
case '1': //
if (isAdmin) {
actions.push(
if (isAdmin.value) {
baseActions.push(
{
name: '通过',
icon: 'check-circle',
@ -515,7 +466,7 @@ const getActions = (row) => {
}
);
} else {
actions.push({
baseActions.push({
name: '撤销',
icon: 'undo',
event: () => handleWithdraw(row),
@ -523,12 +474,8 @@ const getActions = (row) => {
}
break;
case '2': //
//
break;
case '3': //
actions.push({
baseActions.push({
name: '驳回原因',
icon: 'warning',
event: () => showRejectReason(row),
@ -536,8 +483,13 @@ const getActions = (row) => {
break;
}
return actions;
return baseActions;
};
//
onMounted(() => {
getData();
});
</script>
<style scoped lang="scss">
@ -545,26 +497,26 @@ const getActions = (row) => {
width: 100%;
display: flex;
align-items: center;
// background-color: #7daaaa;
:deep(.el-tabs__item) {
font-size: 16px;
color: #555555;
font-weight: 500;
// border: 1 solid #f000;
}
:deep(.el-tabs__content) {
padding: 20px;
width: 100%;
// background-color: #f5f5f5;
border-radius: 4px;
height: calc(100vh - 300px);
overflow-y: auto;
}
:deep(.el-tab-pane) {
margin: 0 auto;
width: 80%;
}
:deep(.el-tab-pane:nth-child(5)) {
margin: 0 auto;
width: 100%;

View File

@ -1,6 +1,6 @@
<template>
<div class="custom-page">
<!-- 关键词搜索 -->
<!-- 搜索区域 -->
<el-form :inline="true" :model="searchForm" class="search-bar">
<el-form-item label="关键词">
<el-input v-model="searchForm.name" placeholder="请输入关键词" clearable />
@ -11,26 +11,39 @@
</el-form-item>
</el-form>
<!-- 四个固定 Tabs -->
<!-- 状态Tabs -->
<el-tabs v-model="activeTab" @tab-click="handleTabChange">
<!-- <el-tab-pane label="待提交" name="0" /> -->
<el-tab-pane label="待审核" name="1" />
<el-tab-pane label="已通过" name="2" />
<el-tab-pane label="已驳回" name="3" />
</el-tabs>
<!-- 表格 -->
<avue-crud ref="crudRef" v-model:page="pageData" :data="crudData" :option="crudOptions" :table-loading="loading">
<template v-if="activeTab === '0'" #menu-left>
<el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
</template>
<template #menu="scope">
<!-- 功能按钮 -->
<section v-if="activeTab === '0'" class="function-bar">
<el-button type="primary" @click="handleAdd">新增</el-button>
</section>
<!-- 表格区域 -->
<TableComponent
:loading="loading"
:columns="columns"
:table-data="tableData"
:current-page="pageData.currentPage"
:page-size="pageData.pageSize"
:total="pageData.total"
:show-pagination="true"
:show-border="true"
:show-sort="true"
style="max-height: calc(100vh - 300px)"
@page-change="handlePageChange"
>
<template #action="scope">
<custom-table-operate :actions="getActions(scope.row)" :data="scope" />
</template>
</avue-crud>
</TableComponent>
<!-- 新增弹窗 -->
<el-dialog :key="dialogTitle" v-model="dialogVisible" :title="dialogTitle" width="60%" align-center :draggable="true">
<!-- 表单弹窗 -->
<el-dialog :key="dialogType" v-model="dialogVisible" :title="dialogTitle" width="60%" align-center :draggable="true">
<el-form :model="formData" label-width="120px" class="custom-form" :disabled="isReadonly">
<el-row :gutter="20">
<el-col :span="12">
@ -48,6 +61,7 @@
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="证件号码" prop="idCard">
@ -63,6 +77,7 @@
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="年龄" prop="age">
@ -75,11 +90,11 @@
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="居住地行政区划" prop="addressArr">
<area-select v-model="formData.addressArr" :label="null" />
<!-- <el-input v-model="formData.detailAddress" placeholder="请选择居住地行政区划" /> -->
</el-form-item>
</el-col>
<el-col :span="12">
@ -88,6 +103,7 @@
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="种植面积" prop="area">
@ -96,9 +112,6 @@
</el-col>
<el-col :span="12">
<el-form-item label="种植作物" prop="planCrop">
<!-- <el-select v-model="formData.planCrop" placeholder="种植作物" style="width: 380px" :clearable="true">
<el-option v-for="item in cropsOptions" :key="item.id" :label="item.cropsName" :value="item.id" />
</el-select> -->
<url-select
v-model="formData.planCrop"
url="/land-resource/crops/page"
@ -111,6 +124,7 @@
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
@ -122,62 +136,62 @@
</template>
<script setup>
import { ref, computed, reactive, onMounted, watch, nextTick } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { CRUD_OPTIONS } from '@/config';
import { ref, computed, reactive, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { fetchFarmerList, fetchFarmerById, saveFarmerList, editFarmer, approveFarmer, deleteFarmers } from '@/apis/businessEntity';
import { pageCropsList } from '@/apis/landResourceManagement/cropsManagement/index.js';
// ---------------------------------------------------------------------
// 1.
// 'superadmin''auditor''submitter'
// ---------------------------------------------------------------------
const role = ref('superadmin'); // 'superadmin' / 'auditor' / 'submitter'
// ==================== ====================
const DIALOG_TYPE = {
VIEW: 'view',
EDIT: 'edit',
ADD: 'add',
};
//
const isSuperAdmin = computed(() => role.value === 'superadmin');
const isAuditor = computed(() => role.value === 'auditor');
const STATUS = {
PENDING: '0',
REVIEWING: '1',
APPROVED: '2',
REJECTED: '3',
};
// ---------------------------------------------------------------------
// 2. Tab
// ---------------------------------------------------------------------
const activeTab = ref('1');
const dialogTitle = ref('新增');
// ==================== ====================
const loading = ref(false);
const dialogVisible = ref(false);
const dialogType = ref(DIALOG_TYPE.ADD);
const isReadonly = ref(false);
//
const searchForm = ref({
const activeTab = ref(STATUS.REVIEWING);
const cropsOptions = ref([]);
const searchForm = reactive({
name: '',
idCard: '',
phone: '',
status: '',
userId: '',
});
const loading = ref(false);
const crudRef = ref();
//
const pageData = ref({
const pageData = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
});
//
const crudData = ref([]);
//
const dialogVisible = ref(false);
//
const tableData = ref([]);
const defaultFormData = {
id: '',
name: '',
idType: '101',
idCard: '',
sex: '1',
age: '',
phone: '',
provinceCode: '', //
cityCode: '', //
countyCode: '', //
townCode: '', //
villageCode: '', //
provinceCode: '',
cityCode: '',
countyCode: '',
townCode: '',
villageCode: '',
address: '',
addressArr: [],
detailAddress: '',
@ -185,187 +199,92 @@ const defaultFormData = {
planCrop: '',
reason: '',
};
// 使
const formData = ref({ ...defaultFormData });
//
const resetForm = () => {
formData.value = { ...defaultFormData };
};
const formData = reactive({ ...defaultFormData });
// ==============================
// CRUD
// ==============================
const crudOptions = reactive({
...CRUD_OPTIONS,
addBtn: false,
searchBtn: false,
emptyBtn: false,
refreshBtn: false,
column: [
{ label: '生产经营主体编码', prop: 'id' },
{ label: '姓名', prop: 'name' },
{ label: '联系方式', prop: 'phone' },
//
{ label: '地址', prop: 'address', width: '300px' },
{ label: '地块数量', prop: 'landCount' },
{ label: '地块编号', prop: 'landNumber' },
{ label: '地块名称', prop: 'landName' },
{ label: '面积', prop: 'area', formatter: (row, column, cellValue) => `${Number(cellValue).toFixed(2)}` },
{ label: '所属行政区划', prop: 'address' },
{ label: '所属网格', prop: 'gridCode' },
{ label: '种植作物', prop: 'planCropName' },
// { label: '', prop: 'phone' },
{ label: '创建时间', prop: 'createTime' },
{ label: '更新时间', prop: 'updateTime' },
],
// ==================== ====================
const dialogTitle = computed(() => {
const titles = {
[DIALOG_TYPE.VIEW]: '查看',
[DIALOG_TYPE.EDIT]: '编辑',
[DIALOG_TYPE.ADD]: '新增',
};
return titles[dialogType.value];
});
// ---------------------------------------------------------------------
// 3. API/
// ---------------------------------------------------------------------
async function getData() {
loading.value = true;
try {
const params = {
...searchForm.value,
status: activeTab.value,
current: pageData.value.currentPage,
size: pageData.value.pageSize,
};
const response = await fetchFarmerList(params);
if (response.code === 200 && response.data) {
crudData.value = response.data.records;
console.log('获取数据成功:', crudData.value);
pageData.value = {
currentPage: response.data.current,
pageSize: response.data.size,
total: response.data.total,
};
} else {
ElMessage.error(response.msg || '获取数据失败');
}
} catch (error) {
ElMessage.error('获取数据失败,请稍后重试');
} finally {
loading.value = false;
}
}
//
const cropsOptions = ref([]);
//
const fetchCropsList = async () => {
try {
// pageCropsList
const res = await pageCropsList({ status: '0' });
if (res.code === 200) {
console.log('res :>> ', res.data.records);
cropsOptions.value = res.data.records;
console.log('object :>> ', cropsOptions.value);
}
} catch (error) {
console.error('获取种植作物列表失败:', error);
}
// ==================== ====================
const resetForm = () => {
Object.assign(formData, defaultFormData);
};
function handleSearch() {
getData();
}
function handleReset() {
searchForm.value.keyword = '';
const syncAddress = () => {
const arr = formData.addressArr || [];
formData.provinceCode = arr[0] || '';
formData.cityCode = arr[1] || '';
formData.countyCode = arr[2] || '';
formData.townCode = arr[3] || '';
formData.villageCode = arr[4] || '';
};
const handleSearch = () => {
pageData.currentPage = 1;
fetchData();
};
const handleReset = () => {
Object.assign(searchForm, {
name: '',
idCard: '',
phone: '',
status: '',
userId: '',
});
handleSearch();
}
function handleTabChange(tab) {
};
const handleTabChange = () => {
handleSearch();
}
//
};
const handleAdd = () => {
isReadonly.value = false; //
dialogType.value = DIALOG_TYPE.ADD;
isReadonly.value = false;
resetForm();
dialogTitle.value = '新增';
dialogVisible.value = true;
};
// address
watch(
() => formData.value.addressArr,
(newValue) => {
if (newValue.length === 5) {
formData.value.provinceCode = newValue[0] || '';
formData.value.cityCode = newValue[1] || '';
formData.value.countyCode = newValue[2] || '';
formData.value.townCode = newValue[3] || '';
formData.value.villageCode = newValue[4] || '';
} else {
ElMessageBox.alert('行政区划数据错误');
}
}
);
// saveFarmerList
const handleSave = async () => {
try {
syncAddress();
let response;
if (dialogTitle.value === '新增') {
console.log('新增formData.value.arr :>> ', formData.value.addressArr);
// saveFarmerList
response = await saveFarmerList(formData.value);
if (response.code === 200) {
ElMessage.success('新增成功');
}
} else if (dialogTitle.value === '编辑') {
// editFarmer
response = await editFarmer(formData.value);
if (response.code === 200) {
ElMessage.success('编辑成功');
}
if (dialogType.value === DIALOG_TYPE.ADD) {
response = await saveFarmerList(formData);
} else {
response = await editFarmer(formData);
}
if (response && response.code === 200) {
if (response?.code === 200) {
ElMessage.success(`${dialogTitle.value}成功`);
dialogVisible.value = false;
getData(); //
fetchData();
}
} catch (error) {
if (dialogTitle.value === '新增') {
ElMessage.error('新增失败,请稍后重试');
} else {
ElMessage.error('编辑失败,请稍后重试');
}
ElMessage.error(`${dialogTitle.value}失败`);
}
};
const getFarmerById = async (id) => {
try {
const response = await fetchFarmerById(id);
if (response.code === 200 && response.data) {
return response.data;
} else {
ElMessage.error(response.msg || '获取数据失败');
return null;
}
} catch (error) {
ElMessage.error('获取数据失败,请稍后重试');
return null;
}
};
//
async function handleView(row) {
dialogTitle.value = '查看';
isReadonly.value = true; //
const data = await getFarmerById(row.id);
if (data) {
const addressArr = [data.provinceCode, data.cityCode, data.countyCode, data.townCode, data.villageCode].filter(Boolean);
formData.value = {
...data,
addressArr: addressArr,
};
}
nextTick(() => {
const handleView = async (row) => {
dialogType.value = DIALOG_TYPE.VIEW;
isReadonly.value = true;
if (await getFarmerDetail(row.id)) {
dialogVisible.value = true;
});
}
}
};
// /
async function handleEdit(row) {
if (row.status === '2') {
const handleEdit = async (row) => {
if (row.status === STATUS.APPROVED) {
try {
await ElMessageBox.confirm('编辑后数据将需要重新审核,是否继续?', '确认编辑', {
confirmButtonText: '继续编辑',
@ -376,159 +295,99 @@ async function handleEdit(row) {
return;
}
}
const data = await getFarmerById(row.id);
if (data) {
const addressArr = [data.provinceCode, data.cityCode, data.countyCode, data.townCode, data.villageCode].filter(Boolean);
formData.value = {
...data,
addressArr: addressArr,
};
}
dialogTitle.value = '编辑';
dialogType.value = DIALOG_TYPE.EDIT;
isReadonly.value = false;
nextTick(() => {
if (await getFarmerDetail(row.id)) {
dialogVisible.value = true;
});
}
}
};
//
function handleSubmit(row) {
ElMessageBox.confirm('确定提交审核吗?', '提交审核').then(() => {
const handleStatusChange = async (row, newStatus, reason = '') => {
try {
const params = {
id: row.id,
status: '1',
reason: row.reason || '',
status: newStatus,
reason,
};
approveFarmer(params)
.then(() => {
row.rejectReason = ''; //
getData(); //
})
.catch(() => {
ElMessage.error('提交审核失败,请稍后重试');
});
});
}
//
function handleResubmit(row) {
ElMessageBox.confirm('确认重新提交吗?', '重新提交').then(() => {
const params = {
id: row.id,
status: '1', //
reason: '重新提交审核',
await approveFarmer(params);
fetchData();
const messages = {
[STATUS.PENDING]: '已撤销',
[STATUS.REVIEWING]: '已提交审核',
[STATUS.APPROVED]: '审核已通过',
[STATUS.REJECTED]: '已驳回',
};
approveFarmer(params)
.then(() => {
console.log(`ID=${row.id} 重新提交审核`);
row.status = '1';
row.rejectReason = '';
getData();
ElMessage.success('已重新提交,状态已变为"待审核"');
})
.catch((error) => {
console.error('重新提交失败:', error);
ElMessage.error(error.response?.data?.msg || '重新提交失败');
});
});
}
//
function handleWithdraw(row) {
ElMessageBox.confirm('确认撤销本次审核吗?', '撤销').then(() => {
const params = {
id: row.id,
status: '0', //
reason: '用户主动撤销',
};
approveFarmer(params)
.then(() => {
console.log(`ID=${row.id} 撤销审核`);
row.status = '0';
getData();
ElMessage.success('已撤销,状态已变为"待提交"');
})
.catch((error) => {
console.error('撤销失败:', error);
ElMessage.error(error.response?.data?.msg || '撤销失败');
});
});
}
ElMessage.success(messages[newStatus]);
} catch (error) {
ElMessage.error('操作失败');
}
};
//
function handleApprove(row) {
ElMessageBox.confirm('确认通过审核?', '审核通过').then(() => {
const params = {
id: row.id,
status: '2', //
reason: '审核通过',
};
approveFarmer(params)
.then(() => {
console.log(`ID=${row.id} 审核通过`);
row.status = '2';
getData();
ElMessage.success('审核已通过');
})
.catch((error) => {
console.error('审核通过操作失败:', error);
ElMessage.error(error.response?.data?.msg || '审核操作失败');
});
});
}
const handleSubmit = (row) => {
ElMessageBox.confirm('确定提交审核吗?', '提交审核').then(() => handleStatusChange(row, STATUS.REVIEWING));
};
//
function handleReject(row) {
const handleResubmit = (row) => {
ElMessageBox.confirm('确认重新提交吗?', '重新提交').then(() => handleStatusChange(row, STATUS.REVIEWING, '重新提交审核'));
};
const handleWithdraw = (row) => {
ElMessageBox.confirm('确认撤销本次审核吗?', '撤销').then(() => handleStatusChange(row, STATUS.PENDING, '用户主动撤销'));
};
const handleApprove = (row) => {
ElMessageBox.confirm('确认通过审核?', '审核通过').then(() => handleStatusChange(row, STATUS.APPROVED, '审核通过'));
};
const handleReject = (row) => {
ElMessageBox.prompt('请输入驳回原因', '审核驳回', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /.+/, //
inputPattern: /.+/,
inputErrorMessage: '驳回原因不能为空',
})
.then(({ value }) => {
const params = {
id: row.id,
status: '3', //
reason: value.trim(),
};
return approveFarmer(params).then(() => {
console.log(`ID=${row.id} 驳回,原因:${value.trim()}`);
row.status = '3';
row.rejectReason = value.trim();
getData();
ElMessage.success('已驳回');
});
})
.catch((error) => {
if (error !== 'cancel') {
console.error('驳回操作失败:', error);
ElMessage.error(error.response?.data?.msg || '驳回操作失败');
}
});
}
}).then(({ value }) => handleStatusChange(row, STATUS.REJECTED, value.trim()));
};
// /
function showRejectReason(row) {
const showRejectReason = (row) => {
ElMessageBox.alert(row.reason || '无驳回原因', '驳回原因');
}
};
async function handleDelete(row) {
const handleDelete = async (row) => {
try {
await ElMessageBox.confirm('确定删除该条记录?', '删除提示');
console.log(`删除 ID=${row.id}`);
await deleteFarmers(row.id); // ID
await getData();
await deleteFarmers(row.id);
await fetchData();
ElMessage.success('已删除');
} catch (error) {
if (error !== 'cancel') {
ElMessage.error(`删除失败: ${error.message || '请稍后重试'}`);
ElMessage.error('删除失败');
}
}
}
//
const ACTION_MAP = {
};
// ==================== ====================
const columns = ref([
{ label: '生产经营主体编码', prop: 'id' },
{ label: '姓名', prop: 'name' },
{ label: '联系方式', prop: 'phone' },
{ label: '地址', prop: 'address', width: '300px' },
{ label: '地块数量', prop: 'landCount' },
{ label: '地块编号', prop: 'landNumber' },
{ label: '地块名称', prop: 'landName' },
{ label: '面积', prop: 'area', formatter: (row, column, cellValue) => `${Number(cellValue).toFixed(2)}` },
{ label: '所属行政区划', prop: 'address' },
{ label: '所属网格', prop: 'gridCode' },
{ label: '种植作物', prop: 'planCropName' },
{ label: '创建时间', prop: 'createTime' },
{ label: '更新时间', prop: 'updateTime' },
{ label: '操作', prop: 'action', slotName: 'action', fixed: 'right' },
]);
//
const ACTION_CONFIG = {
view: { name: '查看', icon: 'view', handler: handleView },
edit: { name: '编辑', icon: 'edit', handler: handleEdit },
submit: { name: '提交审核', icon: 'submit', handler: handleSubmit },
@ -541,56 +400,100 @@ const ACTION_MAP = {
modify: { name: '修改', icon: 'edit', handler: handleEdit },
};
//
const ROLE_STATUS_ACTIONS = {
const ROLE_ACTIONS = {
superadmin: {
0: ['view', 'edit', 'submit', 'delete'],
1: ['view', 'approve', 'reject', 'withdraw', 'delete'],
2: ['view', 'modify', 'delete'],
3: ['view', 'edit', 'reason', 'resubmit', 'delete'],
[STATUS.PENDING]: ['view', 'edit', 'submit', 'delete'],
[STATUS.REVIEWING]: ['view', 'approve', 'reject', 'withdraw', 'delete'],
[STATUS.APPROVED]: ['view', 'modify', 'delete'],
[STATUS.REJECTED]: ['view', 'edit', 'reason', 'resubmit', 'delete'],
},
auditor: {
0: [],
1: ['view', 'approve', 'reject'],
2: ['view', 'delete'],
3: ['view', 'reason', 'delete'],
[STATUS.PENDING]: [],
[STATUS.REVIEWING]: ['view', 'approve', 'reject'],
[STATUS.APPROVED]: ['view', 'delete'],
[STATUS.REJECTED]: ['view', 'reason', 'delete'],
},
submitter: {
0: ['view', 'edit', 'submit', 'delete'],
1: ['view', 'withdraw', 'delete'],
2: ['view', 'modify', 'delete'],
3: ['view', 'edit', 'reason', 'resubmit', 'delete'],
[STATUS.PENDING]: ['view', 'edit', 'submit', 'delete'],
[STATUS.REVIEWING]: ['view', 'withdraw', 'delete'],
[STATUS.APPROVED]: ['view', 'modify', 'delete'],
[STATUS.REJECTED]: ['view', 'edit', 'reason', 'resubmit', 'delete'],
},
};
//
function getActions(row) {
const currentRole = role.value;
const status = row.status;
const actionKeys = ROLE_STATUS_ACTIONS[currentRole]?.[status] || [];
const getActions = (row) => {
const role = 'superadmin'; // TODO:
const actions = ROLE_ACTIONS[role]?.[row.status] || [];
return actionKeys.map((key) => {
const action = ACTION_MAP[key];
return {
...action,
event: () => action.handler(row),
return actions.map((key) => ({
...ACTION_CONFIG[key],
event: () => ACTION_CONFIG[key].handler(row),
}));
};
// ==================== ====================
const handlePageChange = ({ page, pageSize }) => {
pageData.currentPage = page;
pageData.pageSize = pageSize;
fetchData();
};
// ==================== ====================
const fetchData = async () => {
loading.value = true;
try {
const params = {
...searchForm,
status: activeTab.value,
current: pageData.currentPage,
size: pageData.pageSize,
};
});
}
// ---------------------------------------------------------------------
// 4. crudData
// ---------------------------------------------------------------------
const response = await fetchFarmerList(params);
if (response.code === 200 && response.data) {
tableData.value = response.data.records;
pageData.total = response.data.total;
pageData.currentPage = response.data.current;
pageData.pageSize = response.data.size;
}
} catch (error) {
ElMessage.error('获取数据失败');
} finally {
loading.value = false;
}
};
const fetchCropsData = async () => {
try {
const res = await pageCropsList({ status: '0' });
if (res.code === 200) {
cropsOptions.value = res.data.records;
}
} catch (error) {
console.error('获取种植作物列表失败:', error);
}
};
const getFarmerDetail = async (id) => {
try {
const response = await fetchFarmerById(id);
if (response.code === 200 && response.data) {
const data = response.data;
const addressArr = [data.provinceCode, data.cityCode, data.countyCode, data.townCode, data.villageCode].filter(Boolean);
Object.assign(formData, data, { addressArr });
return true;
}
} catch (error) {
ElMessage.error('获取详情失败');
return false;
}
};
// ==================== ====================
onMounted(() => {
getData();
fetchCropsList(); //
fetchData();
fetchCropsData();
});
</script>
<style scoped lang="scss">
// :deep(.avue-crud__header) {
// display: none;
// }
.custom-page {
padding: 20px;
height: calc(100vh - 150px);
@ -600,6 +503,7 @@ onMounted(() => {
margin-bottom: 20px;
}
}
:deep(.el-dialog__body) {
padding: 20px;
height: calc(100vh - 300px);
@ -612,13 +516,14 @@ onMounted(() => {
.el-form-item {
margin-bottom: 22px;
}
.el-input,
.el-select,
.el-cascader,
.el-date-picker {
width: 500px;
max-width: 100%; //
box-sizing: border-box; // padding/border
max-width: 100%;
box-sizing: border-box;
}
}
</style>