6/12
This commit is contained in:
parent
1726b0f662
commit
26e4c8c528
@ -59,7 +59,7 @@ export function fetchFarmerById(id) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除农户接口(严格匹配文档规范)
|
||||
* 农户-删除
|
||||
* @param {string|string[]} ids - 单个ID或ID数组(会自动转为逗号分隔字符串)
|
||||
* @returns {Promise} 请求Promise
|
||||
*/
|
||||
@ -75,29 +75,10 @@ export function deleteFarmers(ids) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产经营主体 - 审核
|
||||
* @param {Object} data 审核数据
|
||||
*/
|
||||
export function checkBusinessSubject(data) {
|
||||
return request({
|
||||
url: '/product-business/business/businessCheck',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 经营主体审核 - 分页查询
|
||||
* 企业管理 - 列表查询
|
||||
* @param {Object} params 查询参数
|
||||
* @returns {Promise} 请求Promise
|
||||
*/
|
||||
export function fetchBusinessCheckList(params) {
|
||||
return request({
|
||||
url: '/product-business/business/businessCheckPage',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
// 农企合作社-列表查询/product-business/business/enter/businessPage
|
||||
export function getEnterList(params) {
|
||||
return request({
|
||||
url: '/product-business/business/enter/businessPage',
|
||||
@ -105,3 +86,115 @@ export function getEnterList(params) {
|
||||
params,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 企业管理 - 详情查询
|
||||
* @param {string} id 企业I
|
||||
* @returns {Promise} 请求Promise
|
||||
*/
|
||||
export function getEnterById(id) {
|
||||
return request({
|
||||
url: `/product-business/business/enter/businessInfo/${id}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 企业管理 - 新增
|
||||
* @param {Object} data 企业数据
|
||||
* @returns {Promise} 请求Promise
|
||||
*/
|
||||
export function addEnter(data) {
|
||||
return request({
|
||||
url: '/product-business/business/enter/businessSave',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 企业管理 - 编辑
|
||||
* @param {Object} data 企业数据
|
||||
* @returns {Promise} 请求Promise
|
||||
*/
|
||||
export function updateEnter(data) {
|
||||
return request({
|
||||
url: '/product-business/business/enter/businessEdit',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 企业管理 - 审核
|
||||
* @param {Object} data 审核数据
|
||||
*/
|
||||
export function approvalEnter(data) {
|
||||
return request({
|
||||
url: '/product-business/business/enter/businessApproval',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 企业管理 - 删除
|
||||
* @param {string|string[]} ids - 单个ID或ID数组(会自动转为逗号分隔字符串)
|
||||
* @returns {Promise} 请求Promise
|
||||
*/
|
||||
export function deleteEnter(ids) {
|
||||
// 统一参数格式:数组转逗号分隔字符串,非数组直接使用
|
||||
const idStr = Array.isArray(ids) ? ids.join(',') : ids;
|
||||
|
||||
return request({
|
||||
url: '/product-business/business/enter/deleteBusiness',
|
||||
method: 'delete',
|
||||
params: { businessId: idStr },
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 社员列表查询
|
||||
* @param {Object} params 查询参数
|
||||
*/
|
||||
export function getMemberList(params) {
|
||||
return request({
|
||||
url: '/product-business/business/member/memberPage',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 社员新增
|
||||
* @param {Object} data 社员数据
|
||||
*/
|
||||
export function addMember(data) {
|
||||
return request({
|
||||
url: '/product-business/business/member/businessSave',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 社员编辑
|
||||
* @param {Object} data 社员数据
|
||||
*/
|
||||
export function updateMember(data) {
|
||||
return request({
|
||||
url: '/product-business/business/member/memberEdit',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 社员删除
|
||||
* @param {string|string[]} ids - 单个ID或ID数组(会自动转为逗号分隔字符串)
|
||||
* @returns {Promise} 请求Promise
|
||||
*/
|
||||
export function deleteMembers(ids) {
|
||||
// 统一参数格式:数组转逗号分隔字符串,非数组直接使用
|
||||
const idStr = Array.isArray(ids) ? ids.join(',') : ids;
|
||||
|
||||
return request({
|
||||
url: '/product-business/business/member/deleteMember',
|
||||
method: 'delete',
|
||||
params: { ids: idStr },
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
import request from '@/utils/axios';
|
||||
/* 查询土地违法处理 */
|
||||
export function getLandIllegal(params = {}) {
|
||||
return request('land-resource/landViolation/page', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
/* 新增土地违法处理 */
|
||||
export function createLandIllegal(data = {}) {
|
||||
return request('land-resource/landViolation/save', {
|
||||
method: 'POST',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/* 登记处理 */
|
||||
export function registerLandIllegal(data = {}) {
|
||||
return request('land-resource/landViolation/registResult', {
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
/* 违法详情 */
|
||||
export function illegalInfo(id = '') {
|
||||
return request('land-resource/landViolation/detail/' + id, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
// api/landInspection.js
|
||||
import request from '@/utils/axios';
|
||||
|
||||
// 新增(POST)
|
||||
export function createLandInspection(data) {
|
||||
return request('land-resource/landInspection/save', {
|
||||
method: 'POST',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除(DELETE)
|
||||
export function deleteLandInspection(id) {
|
||||
return request(`land-resource/landInspection/${id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
// 修改(PUT)
|
||||
export function updateLandInspection(data = {}) {
|
||||
return request('/land-resource/landInspection/update', {
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 修改状态(PUT)
|
||||
export function updateLandInspectionStatus(data = {}) {
|
||||
return request('/land-resource/landInspection/updateStatus', {
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 查询详情(GET)
|
||||
export function getLandInspectionDetail(id) {
|
||||
return request(`land-resource/landInspection/${id}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
||||
// 查询列表 admin (GET)
|
||||
export function fetchLandInspectionList(params = {}) {
|
||||
return request('land-resource/landInspection/page', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
// 查询列表 执行人员 (GET)
|
||||
export function fetchLandInspectionGen(params = {}) {
|
||||
return request('/land-resource/landInspection/page/general', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
// 导出(GET + Blob)
|
||||
export function exportLandInspection(params = {}) {
|
||||
return request('/land-resource/landInspection/export', {
|
||||
method: 'GET',
|
||||
params,
|
||||
responseType: 'blob',
|
||||
});
|
||||
}
|
||||
// 巡查结果-新增(POST)
|
||||
export function createInspectionResult(data) {
|
||||
return request('/land-resource/inspection/result/save', {
|
||||
method: 'POST',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 巡查结果-删除(DELETE)
|
||||
export function deleteInspectionResult(id) {
|
||||
return request(`/land-resource/inspection/result/${id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
// 巡查结果-违法事件查看(GET)
|
||||
export function getInspectionResultDetail(id) {
|
||||
return request(`/land-resource/inspection/result/${id}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
@ -65,18 +65,19 @@ const fetchAreaData = async () => {
|
||||
},
|
||||
});
|
||||
areaOptions.value = res.data ?? [];
|
||||
console.log('AreaSelect区域数据', areaOptions.value);
|
||||
} catch (err) {
|
||||
console.error('加载行政区域失败', err);
|
||||
}
|
||||
};
|
||||
|
||||
// 外部更新 => 内部同步
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
selectedAreaPath.value = [...val];
|
||||
}
|
||||
);
|
||||
// // 外部更新 => 内部同步
|
||||
// watch(
|
||||
// () => props.modelValue,
|
||||
// (val) => {
|
||||
// selectedAreaPath.value = [...val];
|
||||
// }
|
||||
// );
|
||||
|
||||
// 内部更新 => 外部同步
|
||||
watch(selectedAreaPath, (val) => {
|
||||
|
@ -54,6 +54,10 @@ const props = defineProps({
|
||||
type: String,
|
||||
default: 'value',
|
||||
},
|
||||
responseParser: {
|
||||
type: Function,
|
||||
default: (res) => res.data.records, // 默认解析函数
|
||||
},
|
||||
});
|
||||
|
||||
// -------------- ② 定义要透传回父组件的 Events --------------
|
||||
@ -83,13 +87,13 @@ async function fetchOptions() {
|
||||
if (!props.url) return;
|
||||
const res = await request.get(props.url, { params: props.params });
|
||||
|
||||
const records = res.data.records;
|
||||
const records = props.responseParser(res);
|
||||
if (Array.isArray(records)) {
|
||||
options.value = records;
|
||||
// console.log('option', options.value);
|
||||
} else {
|
||||
options.value = [];
|
||||
console.log('UrlSelect:接口返回数据格式不是数组,无法解析成 options');
|
||||
console.error('UrlSelect:解析后的数据不是数组');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,35 @@
|
||||
// src/hooks/useActionPermissions.js
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
function getBaseRoles(role, permissionMap) {
|
||||
// 允许角色继承(如 admin 自动继承其他角色权限)
|
||||
const inherited = permissionMap[role];
|
||||
return inherited && Array.isArray(inherited) ? inherited : [role];
|
||||
}
|
||||
|
||||
function getAllowedKeys(role, status, permissionMap, statusMap) {
|
||||
const baseRoles = getBaseRoles(role, permissionMap);
|
||||
const roleKeys = new Set(baseRoles.flatMap((r) => permissionMap[r] || []));
|
||||
const statusKeys = new Set(statusMap[status] || []);
|
||||
return [...roleKeys].filter((key) => statusKeys.has(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用权限控制 Hook
|
||||
* @param {Ref<String>} roleRef 用户角色 ref
|
||||
* @param {Ref<String>} statusRef 当前状态 ref
|
||||
* @param {Array} actions 操作项列表,必须含 key 字段
|
||||
* @param {Object} permissionMap 角色权限表,如:{ operator: ['edit', ...] }
|
||||
* @param {Object} statusMap 状态权限表,如:{ '00': ['edit', ...] }
|
||||
*/
|
||||
export function useActionPermissions(roleRef, statusRef, actions, permissionMap, statusMap) {
|
||||
const filteredActions = computed(() => {
|
||||
const allowedKeys = getAllowedKeys(roleRef.value, statusRef.value, permissionMap, statusMap);
|
||||
return actions.filter((action) => allowedKeys.includes(action.key));
|
||||
});
|
||||
|
||||
return {
|
||||
actions: filteredActions,
|
||||
};
|
||||
}
|
@ -1,26 +1,26 @@
|
||||
import Views from '@/layouts/Views.vue';
|
||||
// import Views from '@/layouts/Views.vue';
|
||||
|
||||
const annualplanRoutes = [
|
||||
{
|
||||
path: '/sub-government-affairs-service/annualPlan',
|
||||
name: 'annualPlan',
|
||||
component: Views,
|
||||
redirect: '/sub-government-affairs-service/annualPlans',
|
||||
meta: { title: '种植进度网格化管理', icon: '' },
|
||||
children: [
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/annualPlans',
|
||||
// name: 'annualPlans',
|
||||
// component: () => import('@/views/annualPlan/component/annualPlans/index.vue'),
|
||||
// meta: { title: '年度种植计划', icon: '' },
|
||||
// },
|
||||
{
|
||||
path: '/sub-government-affairs-service/annualPlans',
|
||||
name: 'annualPlans',
|
||||
component: () => import('@/views/annualPlan/component/annualPlans/index.vue'),
|
||||
meta: { title: '种植进度网格化管理', icon: 'Memo' },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
export default annualplanRoutes;
|
||||
// const annualplanRoutes = [
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/annualPlan',
|
||||
// name: 'annualPlan',
|
||||
// component: Views,
|
||||
// redirect: '/sub-government-affairs-service/annualPlans',
|
||||
// meta: { title: '种植进度网格化管理', icon: '' },
|
||||
// children: [
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/annualPlans',
|
||||
// name: 'annualPlans',
|
||||
// component: () => import('@/views/annualPlan/component/annualPlans/index.vue'),
|
||||
// meta: { title: '年度种植计划', icon: '' },
|
||||
// },
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/annualPlans',
|
||||
// name: 'annualPlans',
|
||||
// component: () => import('@/views/annualPlan/component/annualPlans/index.vue'),
|
||||
// meta: { title: '种植进度网格化管理', icon: 'Memo' },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ];
|
||||
// export default annualplanRoutes;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Layout from '@/layouts/index.vue';
|
||||
import annualplanRouters from './annualplan';
|
||||
// import annualplanRouters from './annualplan';
|
||||
import statisticsRoutes from './statisticAnalysis';
|
||||
import landsRoutes from './lands';
|
||||
import dictRoutes from './dict';
|
||||
@ -29,13 +29,13 @@ export default [
|
||||
path: '/sub-government-affairs-service/add-grid',
|
||||
component: () => import('@/views/resource/grid/AddGrid.vue'),
|
||||
name: 'add',
|
||||
meta: { title: '新增网格', icon: '' },
|
||||
meta: { title: '网格管理', icon: '' },
|
||||
},
|
||||
{
|
||||
path: '/sub-government-affairs-service/add--grid-member',
|
||||
component: () => import('@/views/resource/grid/GridMember.vue'),
|
||||
name: 'member',
|
||||
meta: { title: '新增网格员', icon: '' },
|
||||
meta: { title: '网格员管理', icon: '' },
|
||||
},
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/grid--management',
|
||||
|
@ -1,659 +0,0 @@
|
||||
<template>
|
||||
<div class="custom-page">
|
||||
<avue-crud
|
||||
ref="crudRef"
|
||||
v-model="state.form"
|
||||
v-model:page="state.pageData"
|
||||
:table-loading="state.loading"
|
||||
:data="state.data"
|
||||
:option="state.options"
|
||||
@refresh-change="refreshChange"
|
||||
@selection-change="selectionChange"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
>
|
||||
<template #menu-left>
|
||||
<el-button type="primary" icon="Plus" @click="onAdd">新增</el-button>
|
||||
<el-button type="success" icon="download" @click="onExport">导出</el-button>
|
||||
</template>
|
||||
<template #menu="{ row }">
|
||||
<custom-table-operate :actions="state.options.actions" :data="{ row }" />
|
||||
</template>
|
||||
|
||||
<template #search>
|
||||
<div class="custom-search">
|
||||
<div class="search-fields">
|
||||
<div class="search-item">
|
||||
<AreaCascader
|
||||
v-model:region-code="areaQuery.regionCode"
|
||||
v-model:grid-id="areaQuery.gridId"
|
||||
placeholder="选择行政区域与网格"
|
||||
:show-separator="true"
|
||||
:width="500"
|
||||
/>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span>种植作物:</span>
|
||||
<el-select v-model="state.query.cropsId" placeholder="种植作物" :clearable="true">
|
||||
<el-option v-for="item in cropsOptions" :key="item.id" :label="item.cropsName" :value="item.id" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span>计划编号:</span>
|
||||
<el-input v-model="state.query.id" placeholder="计划编号" :clearable="true" />
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span>计划名称:</span>
|
||||
<el-input v-model="state.query.planName" placeholder="计划名称" :clearable="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-buttons">
|
||||
<el-button type="primary" @click="searchChange"> 查询 </el-button>
|
||||
<el-button @click="resetSearch"> 重置 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<el-dialog v-model="detailDialogVisible" title="年度种植计划详情页" width="800" class="detail-dialog">
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tab-pane label="年度种植计划" name="basic">
|
||||
<h3>{{ currentDetailRow.planName }}</h3>
|
||||
<div>所属行政区域:{{ currentDetailRow.regionName }}</div>
|
||||
<div>所属网格:{{ currentDetailRow.gridName }}</div>
|
||||
<div>计划编号:{{ currentDetailRow.id }}</div>
|
||||
<div>计划名称:{{ currentDetailRow.planName }}</div>
|
||||
<div>种植作物:{{ currentDetailRow.cropsName }}</div>
|
||||
<div>种植面积:{{ currentDetailRow.planParameters?.plantingArea }}</div>
|
||||
<div>种植月份:{{ currentDetailRow.planParameters?.plantingMonths }}</div>
|
||||
<div>
|
||||
生长周期:{{ currentDetailRow.planParameters?.growthCycle }}
|
||||
{{ getGrowthCycleUnitName(currentDetailRow.planParameters?.growthCycleUnit) }}
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="实际种植情况" name="planting">
|
||||
<h3>{{ currentDetailRow.planName }}</h3>
|
||||
<div>所属行政区域:{{ currentDetailRow.regionName }}</div>
|
||||
<div>所属网格:{{ currentDetailRow.gridName }}</div>
|
||||
<div>计划编号:{{ currentDetailRow.id }}</div>
|
||||
<div>计划名称:{{ currentDetailRow.planName }}</div>
|
||||
<div>种植作物:{{ currentDetailRow.cropsName }}</div>
|
||||
<div>种植面积:{{ currentDetailRow.actualParameters?.plantingArea }}</div>
|
||||
<div>种植月份:{{ currentDetailRow.actualParameters?.plantingMonths }}</div>
|
||||
<div>
|
||||
生长周期:{{ currentDetailRow.actualParameters?.growthCycle }}
|
||||
{{ getGrowthCycleUnitName(currentDetailRow.actualParameters?.growthCycleUnit) }}
|
||||
</div>
|
||||
<div>当前进度:{{ currentDetailRow.currentProgress }}%</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 新增、重新制定计划和填写实际种植信息操作的共用弹窗 -->
|
||||
<el-dialog v-model="commonDialogVisible" :title="dialogTitle">
|
||||
<template #default>
|
||||
<el-form ref="planForm" :model="formData" :rules="formRules" label-width="120px" class="common-dialog">
|
||||
<el-form-item label="" label-width="0px">
|
||||
<AreaCascader v-model:value="areaFormData" split-rows label="所属行政区域-网格" :width="500" />
|
||||
</el-form-item>
|
||||
<!-- <AreaCascader v-model:value="areaFormData" split-rows label="所属行政区域-网格" :width="500" /> -->
|
||||
<el-form-item label="计划名称">
|
||||
<el-input v-model="formData.planName" style="width: 380px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="种植作物" prop="cropsName">
|
||||
<el-select v-model="formData.cropsId" placeholder="种植作物" style="width: 380px" :clearable="true">
|
||||
<el-option v-for="item in cropsOptions" :key="item.id" :label="item.cropsName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="种植面积" prop="plantingArea">
|
||||
<el-input v-model="formData.plantingArea" style="width: 380px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="种植月份" prop="plantingMonths">
|
||||
<el-select v-model="formData.plantingMonths" placeholder="请选择月份" style="width: 380px" :clearable="true">
|
||||
<el-option v-for="item in monthsOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="生长周期" prop="growthCycle">
|
||||
<el-input-number v-model="formData.growthCycle" :min="1" style="width: 300px" />
|
||||
<el-select v-model="formData.growthCycleUnit" disabled style="width: 68px; margin: 0; padding: 0">
|
||||
<el-option label="天" value="1" />
|
||||
<el-option label="周" value="2" />
|
||||
<el-option label="月" value="3" />
|
||||
<el-option label="年" value="4" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="commonDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, computed, onMounted, watch } from 'vue';
|
||||
import { useApp } from '@/hooks';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { isEmpty, downloadFile } from '@/utils';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { getAnnualList, examineAnnual, delAnnual, exportAnnua } from '@/apis/land.js';
|
||||
import { pageCropsList } from '@/apis/landResourceManagement/cropsManagement/index.js';
|
||||
import { saveAnnual, editAnnual, saveActualProgress, getAnnualDetail } from '@/apis/landResourceManagement/plantingPlan/index.js';
|
||||
|
||||
const app = useApp();
|
||||
const crudRef = ref(null);
|
||||
const userStore = useUserStore();
|
||||
// 用于 AreaCascader 绑定的对象
|
||||
const areaFormData = ref({
|
||||
regionCode: '',
|
||||
gridName: '',
|
||||
gridId: '',
|
||||
});
|
||||
watch(
|
||||
areaFormData,
|
||||
(newVal) => {
|
||||
formData.value.regionCode = newVal.regionCode;
|
||||
formData.value.gridName = newVal.gridName;
|
||||
formData.value.gridId = newVal.gridId;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
const formRules = reactive({
|
||||
// planName: [{ required: true, message: '请输入计划名称', trigger: 'blur' }],
|
||||
// cropsId: [{ required: true, message: '请选择种植作物', trigger: 'change' }],
|
||||
// plantingArea: [
|
||||
// { required: true, message: '请输入种植面积', trigger: 'blur' },
|
||||
// { type: 'number', message: '种植面积必须为数字', trigger: 'blur' },
|
||||
// ],
|
||||
// plantingMonths: [{ required: true, message: '请选择种植月份', trigger: 'change' }],
|
||||
// growthCycle: [
|
||||
// { required: true, message: '请输入生长周期', trigger: 'blur' },
|
||||
// { type: 'number', message: '生长周期必须为数字', trigger: 'blur' },
|
||||
// ],
|
||||
});
|
||||
// 存储种植作物列表
|
||||
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) {
|
||||
app.$message.error('获取种植作物列表失败');
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
fetchCropsList();
|
||||
});
|
||||
|
||||
// 根据单位值获取单位名称
|
||||
const getGrowthCycleUnitName = (unit) => {
|
||||
const unitMap = {
|
||||
1: '天',
|
||||
2: '周',
|
||||
3: '月',
|
||||
4: '年',
|
||||
};
|
||||
return unitMap[unit] || '';
|
||||
};
|
||||
// 获取详情数据
|
||||
const fetchDetailData = async (id) => {
|
||||
try {
|
||||
const res = await getAnnualDetail(id);
|
||||
if (res.code === 200) {
|
||||
currentDetailRow.value = res.data;
|
||||
} else {
|
||||
app.$message.error(res.msg || '获取详情数据失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取详情数据出错:', error);
|
||||
app.$message.error('获取详情数据失败,请稍后重试');
|
||||
}
|
||||
};
|
||||
const openDetailDialog = async (row) => {
|
||||
detailDialogVisible.value = true;
|
||||
await fetchDetailData(row.id);
|
||||
};
|
||||
// 详情弹窗
|
||||
const detailDialogVisible = ref(false);
|
||||
// 详情弹窗当前激活的标签页
|
||||
const activeTab = ref('basic');
|
||||
const currentDetailRow = ref({});
|
||||
// 共用弹窗
|
||||
const commonDialogVisible = ref(false);
|
||||
// 当前操作类型,跟弹窗标题一致
|
||||
const currentAction = ref('');
|
||||
// 弹窗标题
|
||||
const dialogTitle = computed(() => {
|
||||
if (currentAction.value === 'reCreate') {
|
||||
return '重新制定计划';
|
||||
} else if (currentAction.value === 'fillActual') {
|
||||
return '填写实际种植信息';
|
||||
} else if (currentAction.value === 'add') {
|
||||
return '新增年度种植计划';
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
const monthsOptions = ref([
|
||||
{ value: 1, label: '1月' },
|
||||
{ value: 2, label: '2月' },
|
||||
{ value: 3, label: '3月' },
|
||||
{ value: 4, label: '4月' },
|
||||
{ value: 5, label: '5月' },
|
||||
{ value: 6, label: '6月' },
|
||||
{ value: 7, label: '7月' },
|
||||
{ value: 8, label: '8月' },
|
||||
{ value: 9, label: '9月' },
|
||||
{ value: 10, label: '10月' },
|
||||
{ value: 11, label: '11月' },
|
||||
{ value: 12, label: '12月' },
|
||||
]);
|
||||
// 表单引用
|
||||
const planForm = ref(null);
|
||||
// 判断当前用户是否是网格员
|
||||
const isGridMember = computed(() => {
|
||||
const userRoles = userStore.getUserInfo().roles;
|
||||
console.log('当前用户角色:', userRoles);
|
||||
return userRoles.some((role) => role.roleKey === 'gridMember');
|
||||
// return true;
|
||||
});
|
||||
|
||||
// 级联选择器查询参数,必须使用 ref ,否则无法使用 v-model:value 更新
|
||||
const areaQuery = ref({
|
||||
regionCode: '',
|
||||
gridName: '',
|
||||
gridId: '',
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
query: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
id: '',
|
||||
planName: '',
|
||||
cropsName: '',
|
||||
cropsId: '',
|
||||
},
|
||||
form: {},
|
||||
selection: [],
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
addBtnText: '',
|
||||
addBtn: false,
|
||||
searchBtn: false,
|
||||
emptyBtn: false,
|
||||
fit: true,
|
||||
column: [
|
||||
{ label: '计划编号', prop: 'id', minWidth: 100 },
|
||||
{ label: '计划名称', prop: 'planName' },
|
||||
{ label: '种植作物', prop: 'cropsName' },
|
||||
{ label: '种植面积', prop: 'plantingArea', formatter: (row, column, cellValue) => `${cellValue} 亩` },
|
||||
{ label: '种植月份', prop: 'plantingMonths', formatter: (row, column, cellValue) => `${cellValue} 月` },
|
||||
{
|
||||
label: '生长周期',
|
||||
prop: 'growthCycle',
|
||||
formatter: (row, column, cellValue) => {
|
||||
const unitMap = { 1: '天', 2: '周', 3: '月', 4: '年' };
|
||||
const unit = unitMap[row.growthCycleUnit] || '';
|
||||
return `${cellValue} ${unit}`;
|
||||
},
|
||||
},
|
||||
{ label: '所属行政区域', prop: 'regionName' },
|
||||
{ label: '所属网格', prop: 'gridName' },
|
||||
{ label: '当前进度', prop: 'currentProgress' },
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
name: '查看',
|
||||
icon: 'view',
|
||||
event: ({ row }) => {
|
||||
openDetailDialog(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '重新制定计划',
|
||||
icon: 'edit',
|
||||
event: ({ row }) => {
|
||||
currentAction.value = 'reCreate';
|
||||
formData.value = { ...row };
|
||||
if (isGridMember.value) {
|
||||
formData.value.regionName = row.regionName;
|
||||
formData.value.gridName = row.gridName;
|
||||
}
|
||||
formData.value.growthCycleUnit = row.growthCycleUnit || '1';
|
||||
commonDialogVisible.value = true;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '填写实际种植信息',
|
||||
icon: 'edit',
|
||||
event: ({ row }) => {
|
||||
currentAction.value = 'fillActual';
|
||||
formData.value = { ...row };
|
||||
if (isGridMember.value) {
|
||||
formData.value.regionName = row.regionName;
|
||||
formData.value.gridName = row.gridName;
|
||||
}
|
||||
formData.value.growthCycleUnit = row.growthCycleUnit || '1';
|
||||
commonDialogVisible.value = true;
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'danger',
|
||||
name: '删除',
|
||||
icon: 'delete',
|
||||
event: ({ row }) => rowDel(row),
|
||||
},
|
||||
],
|
||||
},
|
||||
pageData: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
data: [],
|
||||
currentRow: {},
|
||||
});
|
||||
|
||||
const formData = ref({
|
||||
year: '',
|
||||
regionCode: '',
|
||||
gridId: '',
|
||||
regionName: '',
|
||||
gridName: '',
|
||||
planName: '', // 必填
|
||||
cropsId: null,
|
||||
cropsName: '',
|
||||
plantingArea: null,
|
||||
plantingMonths: '',
|
||||
growthCycle: '',
|
||||
growthCycleUnit: '1', // 默认单位为周
|
||||
note: '',
|
||||
});
|
||||
// 提交计划表单
|
||||
const submitForm = async () => {
|
||||
try {
|
||||
// 表单验证
|
||||
await planForm.value.validate();
|
||||
// 验证通过,提交表单
|
||||
console.log('表单数据:', formData.value);
|
||||
|
||||
if (currentAction.value === 'reCreate') {
|
||||
// 重新制定计划的提交逻辑
|
||||
await editAnnual(formData.value);
|
||||
app.$message.success('重新制定计划成功');
|
||||
} else if (currentAction.value === 'fillActual') {
|
||||
// 填写实际种植信息的提交逻辑
|
||||
await saveActualProgress(formData.value);
|
||||
app.$message.success('填写实际种植信息成功');
|
||||
} else if (currentAction.value === 'add') {
|
||||
// 新增计划的提交逻辑
|
||||
await saveAnnual(formData.value);
|
||||
app.$message.success('新增年度种植计划成功');
|
||||
}
|
||||
|
||||
commonDialogVisible.value = false;
|
||||
loadData();
|
||||
} catch (error) {
|
||||
console.error('表单提交失败:', error);
|
||||
if (error.errors) {
|
||||
// 表单验证失败
|
||||
app.$message.error('请填写完整且正确的表单信息');
|
||||
} else {
|
||||
// API 调用失败
|
||||
app.$message.error('操作失败,请稍后重试');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onAdd = () => {
|
||||
currentAction.value = 'add';
|
||||
formData.value = {
|
||||
regionName: '',
|
||||
gridName: '',
|
||||
planName: '',
|
||||
cropsName: '',
|
||||
plantingArea: '',
|
||||
plantingMonths: '',
|
||||
growthCycle: '',
|
||||
growthCycleUnit: '1',
|
||||
};
|
||||
commonDialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 加载
|
||||
const loadData = () => {
|
||||
state.loading = true;
|
||||
getAnnualList(state.query)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
const { current, size, total, records } = res.data;
|
||||
state.data = records;
|
||||
state.pageData = {
|
||||
currentPage: current || 1,
|
||||
pageSize: size || 10,
|
||||
total: total,
|
||||
};
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
state.data = [];
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
// 页数
|
||||
const currentChange = (current) => {
|
||||
state.query.current = current;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 条数
|
||||
const sizeChange = (size) => {
|
||||
state.query.size = size;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const searchChange = () => {
|
||||
state.query = {
|
||||
...state.query,
|
||||
...areaQuery.value,
|
||||
current: 1,
|
||||
};
|
||||
console.log('搜索参数', state.query);
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 重置搜索
|
||||
const resetSearch = () => {
|
||||
state.query = {
|
||||
current: 1,
|
||||
size: 10,
|
||||
id: '',
|
||||
planName: '',
|
||||
cropsName: '',
|
||||
cropsId: '',
|
||||
};
|
||||
areaQuery.value.regionCode = '';
|
||||
areaQuery.value.gridName = '';
|
||||
areaQuery.value.gridId = '';
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 刷新
|
||||
const refreshChange = () => {
|
||||
loadData();
|
||||
app.$message.success('刷新成功');
|
||||
};
|
||||
|
||||
// 选择
|
||||
const selectionChange = (rows) => {
|
||||
state.selection = rows;
|
||||
};
|
||||
|
||||
// 删除
|
||||
const rowDel = (row, index, done) => {
|
||||
if (isEmpty(row)) return;
|
||||
app
|
||||
.$confirm(`删除后信息将不可查看,确认要删除吗?`, '确定删除', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
console.info('删除');
|
||||
delAnnual({ id: row.id })
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('删除成功!');
|
||||
// done();
|
||||
loadData();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
// 导出
|
||||
const onExport = () => {
|
||||
if (isEmpty(state.data)) {
|
||||
app.$message.error('当前暂时没有可供导出的数据!');
|
||||
return;
|
||||
}
|
||||
state.loading = true;
|
||||
const fileName = '年度计划明细表';
|
||||
exportAnnua(state.query)
|
||||
.then((res) => {
|
||||
if (res.status === 200) {
|
||||
downloadFile(res.data, `${fileName}.xlsx`, 'blob');
|
||||
app.$message.success('导出成功!');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error('导出失败!');
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.custom-page {
|
||||
/* 详情弹窗样式 */
|
||||
|
||||
/* 表单弹窗样式 */
|
||||
.el-dialog {
|
||||
.el-form {
|
||||
padding: 0 20px;
|
||||
width: 100%;
|
||||
// background-color: aqua;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
&-item {
|
||||
margin-bottom: 18px;
|
||||
width: 60%;
|
||||
// background-color: #606266;
|
||||
|
||||
&__label {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
/* 输入框和选择器统一宽度 */
|
||||
.el-input,
|
||||
.el-select,
|
||||
.el-cascader {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
/* 数字输入框和单位选择器组合 */
|
||||
.el-input-number {
|
||||
margin-right: 10px;
|
||||
|
||||
& + .el-select {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 按钮样式微调 */
|
||||
.el-button {
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
|
||||
& + .el-button {
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 搜索区域样式 */
|
||||
.custom-search {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
// background-color: #f5f7fa;
|
||||
|
||||
.search-fields {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
width: 100%;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.search-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.el-input,
|
||||
.el-select,
|
||||
.el-cascader {
|
||||
width: 200px;
|
||||
}
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
.search-buttons {
|
||||
display: flex;
|
||||
align-self: center;
|
||||
gap: 12px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<div class="grid-records"></div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const records = ref([
|
||||
{
|
||||
createTime: '2025-05-26 09:58:29',
|
||||
createUser: '1',
|
||||
updateTime: '2025-05-26T10:02:02.000+08:00',
|
||||
updateUser: '1',
|
||||
tenantId: 0,
|
||||
id: '1926820200675004417', // 计划编号
|
||||
year: null,
|
||||
regionCode: null, // 区域编码
|
||||
cropsId: null, // 作物id
|
||||
gridId: null, // 网格id
|
||||
planName: '大兴乡2025水稻种植计划', // 计划名称
|
||||
plantingArea: 120, // 计划种植面积
|
||||
plantingAreaActual: 335, // 实际种植面积
|
||||
plantingMonths: '1', // 种植月份
|
||||
growthCycle: '20', // 成长周期
|
||||
growthCycleUnit: '1', // 成长周期单位 1:天 2:周 3:月 4:年
|
||||
note: '暂无备注', // 备注
|
||||
deleteFlag: '0', // 删除标志 0:未删除 1:已删除
|
||||
cropsName: '', // 作物名称
|
||||
gridName: null, // 网格名称
|
||||
regionName: null, // 区域名称
|
||||
currentProgress: 279.17, // 当前进度
|
||||
actualFlag: '1', // 是否有实际填报内容 0:没有 1:有
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
@ -1,166 +0,0 @@
|
||||
<template>
|
||||
<div class="custom-page">
|
||||
<avue-crud
|
||||
ref="crudRef"
|
||||
v-model="state.form"
|
||||
v-model:search="state.query"
|
||||
v-model:page="state.pageData"
|
||||
:table-loading="state.loading"
|
||||
:data="state.data"
|
||||
:option="state.options"
|
||||
@refresh-change="refreshChange"
|
||||
@search-reset="searchChange"
|
||||
@search-change="searchChange"
|
||||
@selection-change="selectionChange"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@row-save="rowSave"
|
||||
@row-update="rowUpdate"
|
||||
@row-del="rowDel"
|
||||
>
|
||||
<template #menu-left>
|
||||
<el-button type="success" icon="download" @click="onExport">导出</el-button>
|
||||
</template>
|
||||
|
||||
<template #menu="scope">
|
||||
<custom-table-operate :actions="state.options.actions" :data="scope" />
|
||||
</template>
|
||||
</avue-crud>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { useApp } from '@/hooks';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { isEmpty, downloadFile } from '@/utils';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { compact } from 'lodash';
|
||||
import { GetEntityList, AddEntity, UpdateEntity, DeleteEntity, ExportEntity } from '@/apis/resource/grid';
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
const app = useApp();
|
||||
const UserStore = useUserStore();
|
||||
const crudRef = ref(null);
|
||||
const handleLandChange = async (value, form, done) => {
|
||||
if (!value) return; // 如果没有选择任何地块,则直接返回
|
||||
state.form.address = value.item?.address || '';
|
||||
};
|
||||
|
||||
const JobTypeChange = async (value, form, done) => {
|
||||
if (!value) return;
|
||||
state.form.productName = value.item?.productName || '';
|
||||
};
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
query: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
},
|
||||
form: {},
|
||||
selection: [],
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
addBtnText: '',
|
||||
addBtn: false,
|
||||
column: [
|
||||
{ label: '网格名称', prop: 'gridManager' },
|
||||
{ label: '网格管理员', prop: 'gridManager' },
|
||||
{ label: '联系方式', prop: 'gridManager' },
|
||||
{ label: '网格名称', prop: 'gridManager' },
|
||||
{ label: '网格名称', prop: 'gridManager' },
|
||||
{ label: '种植总面积(亩)', prop: 'gridManager' },
|
||||
{ label: '已种植总面积(亩)', prop: 'gridManager' },
|
||||
{ label: '进度(%)', prop: 'gridManager' },
|
||||
],
|
||||
actions: [],
|
||||
},
|
||||
pageData: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
data: [],
|
||||
currentRow: {},
|
||||
});
|
||||
|
||||
// 加载
|
||||
const loadData = () => {
|
||||
// state.loading = true;
|
||||
// GetEntityList(state.query)
|
||||
// .then((res) => {
|
||||
// if (res.code === 200) {
|
||||
// const { current, size, total, records } = res.data;
|
||||
// state.data = records;
|
||||
// state.pageData = {
|
||||
// currentPage: current || 1,
|
||||
// pageSize: size || 10,
|
||||
// total: total,
|
||||
// };
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// app.$message.error(err.msg);
|
||||
// state.data = [];
|
||||
// })
|
||||
// .finally(() => {
|
||||
// state.loading = false;
|
||||
// });
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
// 页数
|
||||
const currentChange = (current) => {
|
||||
state.query.current = current;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 条数
|
||||
const sizeChange = (size) => {
|
||||
state.query.size = size;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const searchChange = (params, done) => {
|
||||
if (done) done();
|
||||
state.query = params;
|
||||
state.query.current = 1;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 刷新
|
||||
const refreshChange = () => {
|
||||
loadData();
|
||||
app.$message.success('刷新成功');
|
||||
};
|
||||
|
||||
// 选择
|
||||
const selectionChange = (rows) => {
|
||||
state.selection = rows;
|
||||
};
|
||||
|
||||
// 导出
|
||||
const onExport = () => {
|
||||
if (isEmpty(state.data)) {
|
||||
app.$message.error('当前暂时没有可供导出的数据!');
|
||||
return;
|
||||
}
|
||||
state.loading = true;
|
||||
const fileName = '网格种植记录明细表';
|
||||
// ExportEntity(state.query)
|
||||
// .then((res) => {
|
||||
// if (res.status === 200) {
|
||||
// downloadFile(res.data, `${fileName}.xlsx`, 'blob');
|
||||
// app.$message.success('导出成功!');
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// app.$message.error('导出失败!');
|
||||
// })
|
||||
// .finally(() => {
|
||||
// state.loading = false;
|
||||
// });
|
||||
};
|
||||
</script>
|
@ -2,361 +2,529 @@
|
||||
<div class="custom-page">
|
||||
<avue-crud
|
||||
ref="crudRef"
|
||||
v-model="state.form"
|
||||
v-model:search="state.query"
|
||||
v-model:page="state.pageData"
|
||||
:table-loading="state.loading"
|
||||
:data="state.data"
|
||||
:option="state.options"
|
||||
@refresh-change="refreshChange"
|
||||
@search-reset="searchChange"
|
||||
@search-change="searchChange"
|
||||
@selection-change="selectionChange"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@row-save="rowSave"
|
||||
@row-update="rowUpdate"
|
||||
v-model:page="pageData"
|
||||
:data="crudData"
|
||||
:option="crudOptions"
|
||||
:table-loading="loading"
|
||||
@refresh-change="handleRefresh"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
>
|
||||
<template #menu-left>
|
||||
<el-button type="success" icon="download" @click="onExport">导出</el-button>
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
|
||||
<el-button type="success" icon="download" @click="handleExport">导出</el-button>
|
||||
</template>
|
||||
|
||||
<template #menu="scope">
|
||||
<custom-table-operate :actions="state.options.actions" :data="scope" />
|
||||
</template>
|
||||
|
||||
<template #isIllegal="{ row }">
|
||||
<el-tag v-if="row.isIllegal == '1'" type="danger">是</el-tag>
|
||||
<el-tag v-if="row.isIllegal == '0'" type="success">否</el-tag>
|
||||
</template>
|
||||
|
||||
<template #inspectionStatus="{ row }">
|
||||
<el-tag v-if="row.inspectionStatus == '1'" type="success">已结束</el-tag>
|
||||
<el-tag v-if="row.inspectionStatus == '0'">进行中</el-tag>
|
||||
<custom-table-operate :actions="crudOptions.actions" :data="scope" />
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<el-dialog v-model="infoVisible" title="巡查任务" width="800" center>
|
||||
<el-form ref="infoRef" :model="infoData" :rules="infoRules">
|
||||
<el-descriptions :title="infoData.planName || ''" :column="2">
|
||||
<el-descriptions-item label="任务编号">{{ infoData.id || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="任务名称">{{ infoData.planName || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="任务成员">{{ infoData.plantingArea || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="巡查类型">{{ infoData.plantingMonths || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="注意事项">{{ infoData.growthCycle || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="巡查对象">{{ infoData.note || '--' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :title="'巡查信息登记'"> </el-descriptions>
|
||||
<el-dialog :key="dialogTitle" v-model="visible" :title="dialogTitle" width="60%" align-center :draggable="true">
|
||||
<p class="form-group">任务信息</p>
|
||||
<el-form :model="taskForm" :disabled="isReadonlyInfo" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否违法:" prop="num">
|
||||
<el-radio-group v-model="radio1">
|
||||
<el-radio value="1" size="large">是</el-radio>
|
||||
<el-radio value="2" size="large">否</el-radio>
|
||||
</el-radio-group>
|
||||
<el-form-item label="任务编号" prop="taskCode">
|
||||
<el-input v-model="taskForm.taskCode" placeholder="请输入任务编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="任务成员" prop="taskUserIds">
|
||||
<!-- /land-resource/grid-member/current-user -->
|
||||
<url-select
|
||||
v-model="taskForm.taskUserIds"
|
||||
url="/land-resource/grid-member/current-user"
|
||||
placeholder="请选择任务成员"
|
||||
multiple="true"
|
||||
label-key="memberName"
|
||||
value-key="id"
|
||||
:response-parser="(res) => res.data.memberList"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="注意事项" prop="notes">
|
||||
<el-input v-model="taskForm.notes" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" placeholder="请输入注意事项" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="巡查情况" prop="gridName">
|
||||
<el-input
|
||||
v-model="infoData.mark"
|
||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||
type="textarea"
|
||||
laceholder="请输入巡查情况"
|
||||
style="width: 240px"
|
||||
></el-input>
|
||||
<el-form-item label="任务名称" prop="taskName">
|
||||
<el-input v-model="taskForm.taskName" placeholder="请输入任务名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="巡查类型" prop="inspectionTypeCode">
|
||||
<url-select
|
||||
v-model="taskForm.inspectionTypeCode"
|
||||
url="/system/dict/data/type/land_res_patrol_type"
|
||||
placeholder="请选择巡查类型"
|
||||
label-key="dictLabel"
|
||||
value-key="dictValue"
|
||||
:response-parser="(res) => res.data"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="巡查对象" prop="inspectionTarget">
|
||||
<el-input v-model="taskForm.inspectionTarget" placeholder="请输入巡查对象" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!-- 巡查信息登记,只有进行过结果登记的才显示 -->
|
||||
<template v-if="dialogTitle !== '查看' && dialogTitle !== '详情' && dialogTitle !== '新增' && dialogTitle !== '编辑'">
|
||||
<p class="form-group">巡查信息登记</p>
|
||||
|
||||
<!-- 循环渲染多个表单 -->
|
||||
<div v-for="(form, index) in illegalForms" :key="index" class="form-container">
|
||||
<div class="form-header">
|
||||
<span>记录 #{{ index + 1 }}</span>
|
||||
<el-button v-if="illegalForms.length > 1" type="danger" icon="el-icon-delete" circle size="mini" @click="handleRemoveForm(index)" />
|
||||
</div>
|
||||
|
||||
<el-form :model="form" :disabled="isReadonlyRegist" label-width="100px" class="form-item">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<!-- 选择地块 -->
|
||||
<el-form-item label="选择地块" prop="landId">
|
||||
<url-select
|
||||
v-model="form.landId"
|
||||
url="/land-resource/landManage/page"
|
||||
placeholder="请选择地块"
|
||||
label-key="landName"
|
||||
value-key="id"
|
||||
:params="{ current: 1, size: 999 }"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否违法" prop="illegalFlag">
|
||||
<el-radio-group v-model="form.illegalFlag">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<!-- 违法时间 -->
|
||||
<el-form-item label="违法时间" prop="illegalDate">
|
||||
<el-date-picker v-model="form.illegalDate" type="datetime" placeholder="选择违法时间" />
|
||||
</el-form-item>
|
||||
<!-- 违法图片 -->
|
||||
<el-form-item label="违法图片" prop="illegalImages">
|
||||
<el-upload
|
||||
action="/upload"
|
||||
list-type="picture-card"
|
||||
:on-success="(res, file) => handleUploadSuccess(res, file, index)"
|
||||
:on-error="handleUploadError"
|
||||
:on-preview="handlePreview"
|
||||
:on-remove="(file, fileList) => handleRemove(file, fileList, index)"
|
||||
>
|
||||
<i class="el-icon-plus"></i>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="违法类型" prop="illegalType">
|
||||
<url-select
|
||||
v-model="form.illegalTypeCode"
|
||||
url="/system/dict/data/type/land_inspection_illegal_type"
|
||||
placeholder="请选择违法类型"
|
||||
label-key="dictLabel"
|
||||
value-key="dictValue"
|
||||
:response-parser="(res) => res.data"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="违法行为描述" prop="desc">
|
||||
<el-input v-model="form.desc" :autosize="{ minRows: 2, maxRows: 6 }" type="textarea" placeholder="请输入违法行为描述" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div v-if="!isReadonlyRegist" class="form-footer">
|
||||
<el-button type="primary" @click="handleAddForm"> 添加记录 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="infoCancel">取消</el-button>
|
||||
<el-button type="primary" @click="subMitInfo(infoRef)"> 确认 </el-button>
|
||||
<!-- <el-button @click="infoCancel">取消</el-button> -->
|
||||
<el-button type="primary" @click="handleSubmit()"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, h } from 'vue';
|
||||
import { useApp } from '@/hooks';
|
||||
import { ref, reactive, watch, onMounted, computed, nextTick } from 'vue';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { isEmpty, downloadFile } from '@/utils';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { getlandInspection, savelandInspection, enrolllandInspection, exportlandInspection, getAddrCropByLand } from '@/apis/land';
|
||||
import { progressProps } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { useActionPermissions } from '@/hooks/useActionPermissions';
|
||||
import {
|
||||
createLandInspection,
|
||||
deleteLandInspection,
|
||||
updateLandInspection,
|
||||
updateLandInspectionStatus,
|
||||
getLandInspectionDetail,
|
||||
fetchLandInspectionList,
|
||||
exportLandInspection,
|
||||
createInspectionResult,
|
||||
deleteInspectionResult,
|
||||
getInspectionResultDetail,
|
||||
} from '@/apis/landResourceManagement/landInspection/index';
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
const app = useApp();
|
||||
const UserStore = useUserStore();
|
||||
const crudRef = ref(null);
|
||||
const handleLandChange = async (value, form, done) => {
|
||||
if (!value || !value.item || !value.item.id) return; // 如果没有选择任何地块,则直接返回
|
||||
let val = {};
|
||||
getAddrCropByLand(value.item?.id || '')
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
val = res.data || {};
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
val = {};
|
||||
})
|
||||
.finally(() => {});
|
||||
state.form.crop = val?.crop || value.item?.crop;
|
||||
state.form.address = val?.county + val?.town + val?.village || value.item?.address;
|
||||
};
|
||||
const dialogTitle = ref('新增');
|
||||
const visible = ref(false);
|
||||
const isReadonlyInfo = ref(false);
|
||||
const isReadonlyRegist = ref(false);
|
||||
|
||||
const jobTypeOptions = reactive([
|
||||
{ label: '施肥', value: '0' },
|
||||
{ label: '杀虫', value: '1' },
|
||||
{ label: '灌溉', value: '2' },
|
||||
]);
|
||||
const isDisabled = ref(false);
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
query: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
taskCode: '',
|
||||
taskName: '',
|
||||
taskMembers: '',
|
||||
},
|
||||
form: {},
|
||||
selection: [],
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
addBtnText: '新增',
|
||||
updateBtnText: '确定',
|
||||
searchSpan: 6,
|
||||
searchGutter: 80,
|
||||
searchMenuPosition: 'center',
|
||||
index: true,
|
||||
column: [
|
||||
{
|
||||
label: '任务编号',
|
||||
prop: 'taskCode',
|
||||
},
|
||||
{
|
||||
label: '任务名称',
|
||||
prop: 'taskName',
|
||||
},
|
||||
{
|
||||
label: '任务成员',
|
||||
prop: 'taskMembers',
|
||||
},
|
||||
{
|
||||
label: '巡查类型',
|
||||
prop: 'inspectionType',
|
||||
},
|
||||
{
|
||||
label: '巡查对象',
|
||||
prop: 'inspectionTarget',
|
||||
},
|
||||
{
|
||||
label: '注意事项',
|
||||
prop: 'notes',
|
||||
},
|
||||
{
|
||||
label: '是否违法',
|
||||
prop: 'isIllegal',
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
prop: 'inspectionStatus',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
name: '登记结果',
|
||||
icon: 'edit',
|
||||
event: ({ row }) => doEnroll(row),
|
||||
},
|
||||
],
|
||||
},
|
||||
pageData: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
data: [],
|
||||
currentRow: {},
|
||||
const pageData = ref({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
const infoVisible = ref(false);
|
||||
const infoRef = ref();
|
||||
const infoData = reactive({
|
||||
num: '',
|
||||
name: '',
|
||||
member: [],
|
||||
type: '',
|
||||
mark: '',
|
||||
target: '',
|
||||
const searchForm = ref({
|
||||
taskCode: '',
|
||||
taskName: '',
|
||||
userId: '',
|
||||
inspectionTypeCode: '',
|
||||
gridId: '',
|
||||
});
|
||||
|
||||
const infoRules = reactive({
|
||||
num: [{ required: true, message: '请选择是否违法', trigger: 'blur' }],
|
||||
mark: [{ required: true, message: '请输入巡查情况', trigger: 'blur' }],
|
||||
const taskForm = ref({
|
||||
id: '', // 任务ID
|
||||
taskCode: '', // 任务编号
|
||||
taskName: '', // 任务名称
|
||||
taskUserIds: [], // 任务成员ID列表
|
||||
taskMembers: '', // 任务成员
|
||||
inspectionTypeCode: '', // 巡查类型代码
|
||||
inspectionType: '', // 巡查类型
|
||||
inspectionTarget: '', // 巡查对象
|
||||
inspectionStatus: '', // 巡查状态
|
||||
notes: '', // 注意事项
|
||||
inspectionResults: [], // 巡查结果列表
|
||||
});
|
||||
const illegalForm = ref({
|
||||
id: '', // 登记ID
|
||||
inspectionId: '', // 任务ID
|
||||
inspectionTaskName: '', // 巡查任务名称
|
||||
landId: '', // 地块ID
|
||||
landName: '', // 地块名称
|
||||
illegalFlag: 0, // 是否违法
|
||||
illegalDate: '', // 违法时间
|
||||
illegalTypeCode: '', // 违法类型代码
|
||||
illegalTypeName: '', // 违法类型名称
|
||||
desc: '', // 违法描述
|
||||
img: '111', // 违法图片
|
||||
status: '', // 状态
|
||||
});
|
||||
const illegalForms = ref([{ ...illegalForm.value }]);
|
||||
const crudData = ref([]);
|
||||
const loading = ref(false);
|
||||
const crudOptions = reactive({
|
||||
...CRUD_OPTIONS,
|
||||
addBtn: false,
|
||||
searchBtn: false,
|
||||
emptyBtn: false,
|
||||
column: [
|
||||
{ label: '任务编号', prop: 'taskCode' },
|
||||
{ label: '任务名称', prop: 'taskName' },
|
||||
{ label: '任务成员', prop: 'taskMembers' },
|
||||
{ label: '巡查类型', prop: 'inspectionType' },
|
||||
{ label: '巡查对象', prop: 'inspectionTarget' },
|
||||
{ label: '注意事项', prop: 'notes' },
|
||||
{ label: '是否违法', prop: 'isIllegal' },
|
||||
{ label: '状态', prop: 'inspectionStatus' },
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
name: '查看',
|
||||
icon: 'view',
|
||||
event: ({ row }) => handleView(row.id),
|
||||
},
|
||||
{
|
||||
name: '编辑',
|
||||
icon: 'edit',
|
||||
event: ({ row }) => handleEdit(row.id),
|
||||
},
|
||||
{
|
||||
type: 'danger',
|
||||
name: '删除',
|
||||
icon: 'delete',
|
||||
event: ({ row }) => handleDelete(row.id),
|
||||
},
|
||||
// 结果登记
|
||||
{
|
||||
name: '结果登记',
|
||||
icon: 'result',
|
||||
event: ({ row }) => handleResult(row.id),
|
||||
},
|
||||
// 收回任务
|
||||
{
|
||||
name: '收回任务',
|
||||
icon: 'back',
|
||||
event: ({ row }) => handleBack(row.id),
|
||||
},
|
||||
// 发布任务
|
||||
{
|
||||
name: '发布任务',
|
||||
icon: 'publish',
|
||||
event: ({ row }) => handlePublish(row.id),
|
||||
},
|
||||
// 重新发布
|
||||
{
|
||||
name: '重新发布',
|
||||
icon: 're-publish',
|
||||
event: ({ row }) => handleRePublish(row.id),
|
||||
},
|
||||
// 查看登记结果
|
||||
{
|
||||
name: '查看登记结果',
|
||||
icon: 'view-result',
|
||||
event: ({ row }) => handleViewResult(row),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// 加载
|
||||
const loadData = () => {
|
||||
state.loading = true;
|
||||
getlandInspection(state.query)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
const { current, size, total, records } = res.data;
|
||||
state.data = records;
|
||||
state.pageData = {
|
||||
currentPage: current || 1,
|
||||
pageSize: size || 10,
|
||||
total: total,
|
||||
};
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
state.data = [];
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
onMounted(() => {
|
||||
getData();
|
||||
});
|
||||
const getData = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await fetchLandInspectionList({
|
||||
current: pageData.value.currentPage,
|
||||
size: pageData.value.pageSize,
|
||||
...searchForm.value,
|
||||
});
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
// 页数
|
||||
const currentChange = (current) => {
|
||||
state.query.current = current;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 条数
|
||||
const sizeChange = (size) => {
|
||||
state.query.size = size;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const searchChange = (params, done) => {
|
||||
if (done) done();
|
||||
state.query = params;
|
||||
state.query.current = 1;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 刷新
|
||||
const refreshChange = () => {
|
||||
loadData();
|
||||
app.$message.success('刷新成功');
|
||||
};
|
||||
|
||||
// 选择
|
||||
const selectionChange = (rows) => {
|
||||
state.selection = rows;
|
||||
};
|
||||
|
||||
// 新增
|
||||
const rowSave = (row, done, loading) => {
|
||||
// console.info('新增', row);
|
||||
savelandInspection(row)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('添加成功!');
|
||||
done();
|
||||
loadData();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
loading();
|
||||
});
|
||||
};
|
||||
|
||||
// 编辑
|
||||
const doEnroll = (row) => {
|
||||
console.info('doEnroll', row);
|
||||
// infoVisible.value = true;
|
||||
isDisabled.value = row.inspectionStatus == '1';
|
||||
crudRef.value.rowEdit(row);
|
||||
};
|
||||
|
||||
const rowUpdate = (row, index, done, loading) => {
|
||||
console.info('登记结果');
|
||||
let parmer = {
|
||||
id: row.id || '',
|
||||
isIllegal: row.isIllegal || '0', //巡查结果是否违法(0 否,1 是)
|
||||
inspectionSituation: row.inspectionSituation || '', //巡查情况
|
||||
};
|
||||
enrolllandInspection(parmer)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('登记结果成功!');
|
||||
done();
|
||||
loadData();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
loading();
|
||||
});
|
||||
};
|
||||
|
||||
// 导出
|
||||
const onExport = () => {
|
||||
if (isEmpty(state.data)) {
|
||||
app.$message.error('当前暂时没有可供导出的数据!');
|
||||
return;
|
||||
crudData.value = response.data.records;
|
||||
pageData.value.total = response.data.total;
|
||||
pageData.value.currentPage = response.data.current;
|
||||
pageData.value.pageSize = response.data.size;
|
||||
} catch (error) {
|
||||
ElMessage.error('加载数据失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
const handleAdd = () => {
|
||||
isReadonlyInfo.value = false;
|
||||
// resetForm();
|
||||
dialogTitle.value = '新增';
|
||||
visible.value = true;
|
||||
};
|
||||
const handleEdit = async (id) => {
|
||||
console.log('编辑行:', id);
|
||||
isReadonlyInfo.value = false;
|
||||
const response = await getLandInspectionDetail(id);
|
||||
taskForm.value = response.data;
|
||||
// 处理返回的任务成员数组inspectionUsers[]数据为选择器需要的id数组taskUserIds[]
|
||||
if (taskForm.value.inspectionUsers && Array.isArray(taskForm.value.inspectionUsers)) {
|
||||
taskForm.value.taskUserIds = taskForm.value.inspectionUsers.map((user) => user.userId);
|
||||
} else {
|
||||
taskForm.value.taskUserIds = [];
|
||||
}
|
||||
dialogTitle.value = '编辑';
|
||||
visible.value = true;
|
||||
};
|
||||
const handleView = async (id) => {
|
||||
console.log('查看行:', id);
|
||||
const response = await getLandInspectionDetail(id);
|
||||
taskForm.value = response.data;
|
||||
const arr = response.data.inspectionResults;
|
||||
if (arr && Array.isArray(arr)) {
|
||||
illegalForms.value = arr;
|
||||
}
|
||||
isReadonlyInfo.value = true;
|
||||
if (taskForm.value.inspectionUsers && Array.isArray(taskForm.value.inspectionUsers)) {
|
||||
taskForm.value.taskUserIds = taskForm.value.inspectionUsers.map((user) => user.userId);
|
||||
} else {
|
||||
taskForm.value.taskUserIds = [];
|
||||
}
|
||||
dialogTitle.value = '查看';
|
||||
visible.value = true;
|
||||
};
|
||||
const handleDelete = async (id) => {
|
||||
console.log('删除ID:', id);
|
||||
const response = await deleteLandInspection(id);
|
||||
if (response?.code === 200) {
|
||||
ElMessage.success(response?.msg || '删除成功');
|
||||
getData(); // 刷新数据
|
||||
}
|
||||
state.loading = true;
|
||||
const fileName = '土地巡查明细表';
|
||||
exportlandInspection(state.query)
|
||||
.then((res) => {
|
||||
if (res.status === 200) {
|
||||
downloadFile(res.data, `${fileName}.xlsx`, 'blob');
|
||||
app.$message.success('导出成功!');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error('导出失败!');
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
const subMitInfo = (formEl) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
infoHide();
|
||||
console.log('submit!');
|
||||
} else {
|
||||
console.log('error submit!');
|
||||
}
|
||||
const handleResult = async (id) => {
|
||||
console.log('结果登记ID:', id);
|
||||
await handleView(id);
|
||||
isReadonlyRegist.value = false;
|
||||
dialogTitle.value = '结果登记';
|
||||
illegalForm.value.inspectionId = id;
|
||||
nextTick(() => {
|
||||
visible.value = true;
|
||||
});
|
||||
};
|
||||
const handleBack = async (id) => {
|
||||
console.log('收回任务ID:', id);
|
||||
const response = await updateLandInspectionStatus({
|
||||
id,
|
||||
status: '02',
|
||||
});
|
||||
ElMessage.success(response?.msg || '发布成功');
|
||||
await getData();
|
||||
};
|
||||
const handlePublish = async (id) => {
|
||||
console.log('发布任务ID:', id);
|
||||
// updateLandInspectionStatus : status -1 => 00
|
||||
const response = await updateLandInspectionStatus({
|
||||
id,
|
||||
status: '00',
|
||||
});
|
||||
ElMessage.success(response?.msg || '发布成功');
|
||||
await getData();
|
||||
};
|
||||
const handleRePublish = async (id) => {
|
||||
console.log('重新发布ID:', id);
|
||||
const response = await updateLandInspectionStatus({
|
||||
id,
|
||||
status: '00',
|
||||
});
|
||||
ElMessage.success(response?.msg || '发布成功');
|
||||
await getData();
|
||||
};
|
||||
const handleViewResult = async (row) => {
|
||||
console.log('查看登记结果ID:', row.id);
|
||||
await handleView(row.id);
|
||||
isReadonlyRegist.value = true;
|
||||
// const response = await getInspectionResultDetail(row.id);
|
||||
// illegalForm.value = response.data;
|
||||
dialogTitle.value = '查看登记结果';
|
||||
nextTick(() => {
|
||||
visible.value = true;
|
||||
});
|
||||
};
|
||||
|
||||
const infoCancel = () => {
|
||||
infoHide();
|
||||
// 删除表单
|
||||
const handleRemoveForm = (index) => {
|
||||
illegalForms.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const infoHide = () => {
|
||||
infoRef.value && infoRef.value.resetFields();
|
||||
infoVisible.value = false;
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
console.log('表单数据:', taskForm.value);
|
||||
console.log('表单数据:', illegalForm.value);
|
||||
// 1. 表单验证(如果有refName)
|
||||
loading.value = true;
|
||||
let response;
|
||||
// 2. 提交数据
|
||||
if (dialogTitle.value === '新增') {
|
||||
taskForm.value.id = '';
|
||||
response = await createLandInspection(taskForm.value);
|
||||
// 3. 处理成功响应(拦截器已处理200状态码)
|
||||
ElMessage.success(response?.msg || '新增成功');
|
||||
visible.value = false;
|
||||
await getData();
|
||||
} else if (dialogTitle.value === '编辑') {
|
||||
response = await updateLandInspection(taskForm.value);
|
||||
// 3. 处理成功响应(拦截器已处理200状态码)
|
||||
ElMessage.success(response?.msg || '编辑成功');
|
||||
visible.value = false;
|
||||
await getData();
|
||||
} else if (dialogTitle.value === '结果登记') {
|
||||
response = await createInspectionResult(illegalForm.value);
|
||||
ElMessage.success(response?.msg || '结果登记成功');
|
||||
await getData();
|
||||
}
|
||||
// 可刷新表格数据
|
||||
} catch (e) {
|
||||
ElMessage.error('保存失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
/* 使用 ::v-deep 深度选择器来穿透 scoped 样式 */
|
||||
::v-deep .el-table .el-table__row {
|
||||
height: 50px; /* 调整行高,间接控制行间距 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const response = await exportLandInspection(searchForm.value);
|
||||
if (response?.code === 200) {
|
||||
// 假设返回的是文件下载链接
|
||||
const link = document.createElement('a');
|
||||
link.href = response.data; // 假设data是下载链接
|
||||
link.download = 'land_inspection_export.xlsx'; // 设置下载文件名
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
ElMessage.success('导出成功');
|
||||
} else {
|
||||
ElMessage.error(response?.msg || '导出失败');
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('导出失败,请稍后重试');
|
||||
}
|
||||
};
|
||||
function handleRefresh() {
|
||||
console.log('刷新数据');
|
||||
}
|
||||
function handleAddForm() {
|
||||
console.log('添加记录');
|
||||
illegalForms.value.push({ ...illegalForm.value });
|
||||
}
|
||||
function handleCurrentChange(val) {
|
||||
console.log('当前页:', val);
|
||||
}
|
||||
function handleSizeChange(val) {
|
||||
console.log('每页显示条数:', val);
|
||||
}
|
||||
// ---------------------------------------------------------------------
|
||||
// 页面权限控制相关
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
::v-deep .el-table .el-table__row td {
|
||||
padding: 8px 0; /* 调整单元格内边距,进一步微调行间距 */
|
||||
const role = ref('operator');
|
||||
// 所有操作项
|
||||
const allActions = [
|
||||
{ name: '查看', icon: 'view', key: 'view', event: ({ row }) => handleView(row.id) },
|
||||
{ name: '编辑', icon: 'edit', key: 'edit', event: ({ row }) => handleEdit(row.id) },
|
||||
{ name: '删除', icon: 'delete', key: 'delete', type: 'danger', event: ({ row }) => handleDelete(row.id) },
|
||||
{ name: '结果登记', icon: 'result', key: 'result', event: ({ row }) => handleResult(row.id) },
|
||||
{ name: '收回任务', icon: 'back', key: 'back', event: ({ row }) => handleBack(row.id) },
|
||||
{ name: '发布任务', icon: 'publish', key: 'publish', event: ({ row }) => handlePublish(row.id) },
|
||||
{ name: '重新发布', icon: 're-publish', key: 'rePublish', event: ({ row }) => handleRePublish(row.id) },
|
||||
{ name: '查看登记结果', icon: 'view-result', key: 'viewResult', event: ({ row }) => handleViewResult(row) },
|
||||
];
|
||||
// 权限表(角色 -> 可操作项)
|
||||
const permissionMap = {
|
||||
admin: ['operator', 'inspector'], // 继承 operator 和 inspector 的权限
|
||||
operator: ['view', 'edit', 'delete', 'publish', 'back', 'rePublish', 'result', 'viewResult'],
|
||||
inspector: ['result', 'viewResult'],
|
||||
};
|
||||
// 状态控制表(状态码 -> 可操作项)
|
||||
const statusMap = {
|
||||
'-1': ['view', 'edit', 'delete', 'publish'],
|
||||
'00': ['result', 'back', 'viewResult'],
|
||||
'01': ['viewResult'],
|
||||
'02': ['view', 'edit', 'delete', 'rePublish'],
|
||||
};
|
||||
// 使用封装 Hook
|
||||
// const { actions } = useActionPermissions(role, status, allActions, permissionMap, statusMap);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 20px;
|
||||
height: calc(100vh - 300px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
.form-container {
|
||||
position: relative;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.form-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.form-footer {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.form-group {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin: 30px 0;
|
||||
color: #333333;
|
||||
}
|
||||
</style>
|
||||
|
@ -0,0 +1,362 @@
|
||||
<template>
|
||||
<div class="custom-page">
|
||||
<avue-crud
|
||||
ref="crudRef"
|
||||
v-model="state.form"
|
||||
v-model:search="state.query"
|
||||
v-model:page="state.pageData"
|
||||
:table-loading="state.loading"
|
||||
:data="state.data"
|
||||
:option="state.options"
|
||||
@refresh-change="refreshChange"
|
||||
@search-reset="searchChange"
|
||||
@search-change="searchChange"
|
||||
@selection-change="selectionChange"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@row-save="rowSave"
|
||||
@row-update="rowUpdate"
|
||||
>
|
||||
<template #menu-left>
|
||||
<el-button type="success" icon="download" @click="onExport">导出</el-button>
|
||||
</template>
|
||||
|
||||
<template #menu="scope">
|
||||
<custom-table-operate :actions="state.options.actions" :data="scope" />
|
||||
</template>
|
||||
|
||||
<template #isIllegal="{ row }">
|
||||
<el-tag v-if="row.isIllegal == '1'" type="danger">是</el-tag>
|
||||
<el-tag v-if="row.isIllegal == '0'" type="success">否</el-tag>
|
||||
</template>
|
||||
|
||||
<template #inspectionStatus="{ row }">
|
||||
<el-tag v-if="row.inspectionStatus == '1'" type="success">已结束</el-tag>
|
||||
<el-tag v-if="row.inspectionStatus == '0'">进行中</el-tag>
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<el-dialog v-model="infoVisible" title="巡查任务" width="800" center>
|
||||
<el-form ref="infoRef" :model="infoData" :rules="infoRules">
|
||||
<el-descriptions :title="infoData.planName || ''" :column="2">
|
||||
<el-descriptions-item label="任务编号">{{ infoData.id || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="任务名称">{{ infoData.planName || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="任务成员">{{ infoData.plantingArea || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="巡查类型">{{ infoData.plantingMonths || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="注意事项">{{ infoData.growthCycle || '--' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="巡查对象">{{ infoData.note || '--' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :title="'巡查信息登记'"> </el-descriptions>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否违法:" prop="num">
|
||||
<el-radio-group v-model="radio1">
|
||||
<el-radio value="1" size="large">是</el-radio>
|
||||
<el-radio value="2" size="large">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="巡查情况" prop="gridName">
|
||||
<el-input
|
||||
v-model="infoData.mark"
|
||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||
type="textarea"
|
||||
laceholder="请输入巡查情况"
|
||||
style="width: 240px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="infoCancel">取消</el-button>
|
||||
<el-button type="primary" @click="subMitInfo(infoRef)"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, h } from 'vue';
|
||||
import { useApp } from '@/hooks';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { isEmpty, downloadFile } from '@/utils';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { getlandInspection, savelandInspection, enrolllandInspection, exportlandInspection, getAddrCropByLand } from '@/apis/land';
|
||||
import { progressProps } from 'element-plus';
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
const app = useApp();
|
||||
const UserStore = useUserStore();
|
||||
const crudRef = ref(null);
|
||||
const handleLandChange = async (value, form, done) => {
|
||||
if (!value || !value.item || !value.item.id) return; // 如果没有选择任何地块,则直接返回
|
||||
let val = {};
|
||||
getAddrCropByLand(value.item?.id || '')
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
val = res.data || {};
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
val = {};
|
||||
})
|
||||
.finally(() => {});
|
||||
state.form.crop = val?.crop || value.item?.crop;
|
||||
state.form.address = val?.county + val?.town + val?.village || value.item?.address;
|
||||
};
|
||||
|
||||
const jobTypeOptions = reactive([
|
||||
{ label: '施肥', value: '0' },
|
||||
{ label: '杀虫', value: '1' },
|
||||
{ label: '灌溉', value: '2' },
|
||||
]);
|
||||
const isDisabled = ref(false);
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
query: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
taskCode: '',
|
||||
taskName: '',
|
||||
taskMembers: '',
|
||||
},
|
||||
form: {},
|
||||
selection: [],
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
addBtnText: '新增',
|
||||
updateBtnText: '确定',
|
||||
searchSpan: 6,
|
||||
searchGutter: 80,
|
||||
searchMenuPosition: 'center',
|
||||
index: true,
|
||||
column: [
|
||||
{
|
||||
label: '任务编号',
|
||||
prop: 'taskCode',
|
||||
},
|
||||
{
|
||||
label: '任务名称',
|
||||
prop: 'taskName',
|
||||
},
|
||||
{
|
||||
label: '任务成员',
|
||||
prop: 'taskMembers',
|
||||
},
|
||||
{
|
||||
label: '巡查类型',
|
||||
prop: 'inspectionType',
|
||||
},
|
||||
{
|
||||
label: '巡查对象',
|
||||
prop: 'inspectionTarget',
|
||||
},
|
||||
{
|
||||
label: '注意事项',
|
||||
prop: 'notes',
|
||||
},
|
||||
{
|
||||
label: '是否违法',
|
||||
prop: 'isIllegal',
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
prop: 'inspectionStatus',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
name: '登记结果',
|
||||
icon: 'edit',
|
||||
event: ({ row }) => doEnroll(row),
|
||||
},
|
||||
],
|
||||
},
|
||||
pageData: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
data: [],
|
||||
currentRow: {},
|
||||
});
|
||||
const infoVisible = ref(false);
|
||||
const infoRef = ref();
|
||||
const infoData = reactive({
|
||||
num: '',
|
||||
name: '',
|
||||
member: [],
|
||||
type: '',
|
||||
mark: '',
|
||||
target: '',
|
||||
});
|
||||
|
||||
const infoRules = reactive({
|
||||
num: [{ required: true, message: '请选择是否违法', trigger: 'blur' }],
|
||||
mark: [{ required: true, message: '请输入巡查情况', trigger: 'blur' }],
|
||||
});
|
||||
|
||||
// 加载
|
||||
const loadData = () => {
|
||||
state.loading = true;
|
||||
getlandInspection(state.query)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
const { current, size, total, records } = res.data;
|
||||
state.data = records;
|
||||
state.pageData = {
|
||||
currentPage: current || 1,
|
||||
pageSize: size || 10,
|
||||
total: total,
|
||||
};
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
state.data = [];
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
// 页数
|
||||
const currentChange = (current) => {
|
||||
state.query.current = current;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 条数
|
||||
const sizeChange = (size) => {
|
||||
state.query.size = size;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const searchChange = (params, done) => {
|
||||
if (done) done();
|
||||
state.query = params;
|
||||
state.query.current = 1;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 刷新
|
||||
const refreshChange = () => {
|
||||
loadData();
|
||||
app.$message.success('刷新成功');
|
||||
};
|
||||
|
||||
// 选择
|
||||
const selectionChange = (rows) => {
|
||||
state.selection = rows;
|
||||
};
|
||||
|
||||
// 新增
|
||||
const rowSave = (row, done, loading) => {
|
||||
// console.info('新增', row);
|
||||
savelandInspection(row)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('添加成功!');
|
||||
done();
|
||||
loadData();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
loading();
|
||||
});
|
||||
};
|
||||
|
||||
// 编辑
|
||||
const doEnroll = (row) => {
|
||||
console.info('doEnroll', row);
|
||||
// infoVisible.value = true;
|
||||
isDisabled.value = row.inspectionStatus == '1';
|
||||
crudRef.value.rowEdit(row);
|
||||
};
|
||||
|
||||
const rowUpdate = (row, index, done, loading) => {
|
||||
console.info('登记结果');
|
||||
let parmer = {
|
||||
id: row.id || '',
|
||||
isIllegal: row.isIllegal || '0', //巡查结果是否违法(0 否,1 是)
|
||||
inspectionSituation: row.inspectionSituation || '', //巡查情况
|
||||
};
|
||||
enrolllandInspection(parmer)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('登记结果成功!');
|
||||
done();
|
||||
loadData();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
loading();
|
||||
});
|
||||
};
|
||||
|
||||
// 导出
|
||||
const onExport = () => {
|
||||
if (isEmpty(state.data)) {
|
||||
app.$message.error('当前暂时没有可供导出的数据!');
|
||||
return;
|
||||
}
|
||||
state.loading = true;
|
||||
const fileName = '土地巡查明细表';
|
||||
exportlandInspection(state.query)
|
||||
.then((res) => {
|
||||
if (res.status === 200) {
|
||||
downloadFile(res.data, `${fileName}.xlsx`, 'blob');
|
||||
app.$message.success('导出成功!');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error('导出失败!');
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
const subMitInfo = (formEl) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
infoHide();
|
||||
console.log('submit!');
|
||||
} else {
|
||||
console.log('error submit!');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const infoCancel = () => {
|
||||
infoHide();
|
||||
};
|
||||
|
||||
const infoHide = () => {
|
||||
infoRef.value && infoRef.value.resetFields();
|
||||
infoVisible.value = false;
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
/* 使用 ::v-deep 深度选择器来穿透 scoped 样式 */
|
||||
::v-deep .el-table .el-table__row {
|
||||
height: 50px; /* 调整行高,间接控制行间距 */
|
||||
}
|
||||
|
||||
::v-deep .el-table .el-table__row td {
|
||||
padding: 8px 0; /* 调整单元格内边距,进一步微调行间距 */
|
||||
}
|
||||
</style>
|
@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<section class="custom_attrs_upload_content_lx" :style="{ '--columns': props.fileNum }">
|
||||
<el-upload
|
||||
v-if="props.type != 'view'"
|
||||
class="custom-form__uploader"
|
||||
action=""
|
||||
:show-file-list="false"
|
||||
:accept="props.accept"
|
||||
:limit="props.limit"
|
||||
:http-request="rowUploadPicture"
|
||||
:disabled="attrs_.length >= props.limit"
|
||||
>
|
||||
<el-icon class="custom-form__uploader__icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<div v-for="item in attrs_" :key="`attr_${item.uid}`" class="attrs_content__item">
|
||||
<video v-if="isMP4(item.url)" :src="item.url" controls />
|
||||
<img v-else :src="item.url" :alt="item.name" @click="handlePreview(i)" />
|
||||
<el-icon v-if="props.type != 'view'" class="clear_btn" @click="handleClearAttr(item.uid)"><CircleCloseFilled /></el-icon>
|
||||
</div>
|
||||
<el-image-viewer v-if="previewShow" :url-list="srcList" :initial-index="index" @close="previewShow = false" />
|
||||
</section>
|
||||
</template>
|
||||
<script setup>
|
||||
import { nextTick, ref, watch } from 'vue';
|
||||
import { CommonUpload } from '@/apis';
|
||||
|
||||
const emit = defineEmits(['update:attrs']);
|
||||
const props = defineProps({
|
||||
accept: {
|
||||
type: String,
|
||||
default: 'image/*',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'view',
|
||||
},
|
||||
attrs: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
fileNum: {
|
||||
type: Number,
|
||||
default: 4,
|
||||
},
|
||||
});
|
||||
const attrs_ = ref([]);
|
||||
const srcList = ref([]);
|
||||
srcList.value = attrs_.value.map((item) => item.url);
|
||||
watch(
|
||||
() => props.attrs,
|
||||
(val) => {
|
||||
attrs_.value = val;
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
const index = ref(0);
|
||||
const previewShow = ref(false);
|
||||
|
||||
function handleClearAttr(uid) {
|
||||
attrs_.value = attrs_.value.filter((item) => item.uid !== uid);
|
||||
emit('update:attrs', attrs_.value);
|
||||
}
|
||||
async function rowUploadPicture({ file }) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const res = await CommonUpload(formData);
|
||||
if (res.code === 200) {
|
||||
attrs_.value.push({
|
||||
...res.data,
|
||||
uid: 'id_' + Date.now(),
|
||||
});
|
||||
emit('update:attrs', attrs_.value);
|
||||
}
|
||||
}
|
||||
function isMP4(filePath) {
|
||||
// 使用正则表达式检查文件路径是否以 .mp4 结尾(不区分大小写)
|
||||
const regex = /\.mp4$/i;
|
||||
return regex.test(filePath);
|
||||
}
|
||||
function handlePreview(i) {
|
||||
previewShow.value = false;
|
||||
nextTick(() => {
|
||||
index.value = i;
|
||||
previewShow.value = true;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.custom_attrs_upload_content_lx {
|
||||
display: grid;
|
||||
flex-wrap: wrap;
|
||||
grid-template-columns: repeat(var(--columns), 1fr);
|
||||
box-sizing: border-box;
|
||||
gap: 20px;
|
||||
> div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.attrs_content__item {
|
||||
aspect-ratio: 1 / 1;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
padding: 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
img,
|
||||
video {
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.clear_btn {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
font-size: 18px;
|
||||
color: #f15c5c;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
&:hover {
|
||||
.clear_btn {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,12 +1,10 @@
|
||||
<template>
|
||||
<el-form :model="localForm" label-width="120px" :disabled="readonly">
|
||||
<h3>经营主体信息</h3>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<h3>经营主体信息</h3>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="农企/合作社名称">
|
||||
<el-input v-model="localForm.name" placeholder="请输入" />
|
||||
<el-input v-model="localForm.businessName" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="面积">
|
||||
<el-input v-model="localForm.area" placeholder="请输入" />
|
||||
@ -15,7 +13,16 @@
|
||||
<el-input v-model="localForm.contactPerson" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="农企/合作社照片">
|
||||
<el-upload action="#" list-type="picture-card" :disabled="readonly" :auto-upload="false">
|
||||
<el-upload
|
||||
action="#"
|
||||
:http-request="customUploadRequest"
|
||||
:on-success="(res, file) => handleUploadSuccess(res, file, 'cooperativePhoto')"
|
||||
:file-list="cooperativePhotoList"
|
||||
list-type="picture-card"
|
||||
:limit="1"
|
||||
:on-exceed="handleExceed"
|
||||
:on-remove="() => handleRemove('cooperativePhoto')"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
@ -23,19 +30,31 @@
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="地址">
|
||||
<el-cascader v-model="localForm.address" :options="regionOptions" placeholder="请选择" />
|
||||
<area-select v-model="localForm.addressArr" :disabled="readonly" :label="null" />
|
||||
</el-form-item>
|
||||
<el-form-item label="经营产品">
|
||||
<el-input v-model="localForm.product" placeholder="请输入" />
|
||||
<el-input v-model="localForm.primaryProduct" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="localForm.phone" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<h3>证件资料</h3>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<h3>证件资料</h3>
|
||||
<el-form-item label="营业执照">
|
||||
<el-upload action="#" list-type="picture-card" :disabled="readonly" :auto-upload="false">
|
||||
<el-upload
|
||||
action="#"
|
||||
:http-request="customUploadRequest"
|
||||
:on-success="(res, file) => handleUploadSuccess(res, file, 'businessLicence')"
|
||||
:file-list="businessLicenceList"
|
||||
list-type="picture-card"
|
||||
:limit="1"
|
||||
:on-exceed="handleExceed"
|
||||
:on-remove="() => handleRemove('businessLicence')"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
@ -45,8 +64,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, watch } from 'vue';
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { CommonUpload } from '@/apis/index';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import Attrs from './Attrs.vue';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@ -57,10 +80,14 @@ const props = defineProps({
|
||||
readonly: Boolean,
|
||||
});
|
||||
|
||||
const ossUrl = 'http://gov-cloud.oss-cn-chengdu.aliyuncs.com/';
|
||||
const cooperativePhotoList = ref([]);
|
||||
const businessLicenceList = ref([]);
|
||||
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
// 建立本地副本,避免直接修改 props
|
||||
const localForm = reactive({ ...props.modelValue });
|
||||
const localForm = ref({ ...props.modelValue });
|
||||
|
||||
// 深度监听本地副本的变化,实时更新父组件
|
||||
watch(
|
||||
@ -70,18 +97,87 @@ watch(
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
// watch(
|
||||
// () => props.modelValue,
|
||||
// (newVal) => {
|
||||
// Object.assign(localForm, cloneDeep(newVal));
|
||||
// },
|
||||
// { deep: true }
|
||||
// );
|
||||
|
||||
const regionOptions = [
|
||||
{
|
||||
label: '耿马县',
|
||||
value: '耿马县',
|
||||
children: [
|
||||
{
|
||||
label: '耿马镇',
|
||||
value: '耿马镇',
|
||||
children: [{ label: '新城村', value: '新城村' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const customUploadRequest = async (options) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', options.file);
|
||||
|
||||
try {
|
||||
const response = await CommonUpload(formData);
|
||||
options.onSuccess(response, options.file);
|
||||
return response;
|
||||
} catch (err) {
|
||||
console.error('上传失败', err);
|
||||
options.onError(err);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
const handleUploadSuccess = (res, file, fieldName) => {
|
||||
localForm[fieldName] = res.data.url;
|
||||
// 更新预览列表
|
||||
const previewItem = {
|
||||
name: res.data.name,
|
||||
url: ossUrl + res.data.url, // 确保这是完整的可访问URL
|
||||
status: 'success',
|
||||
};
|
||||
if (fieldName === 'cooperativePhoto') {
|
||||
cooperativePhotoList.value = [previewItem];
|
||||
} else {
|
||||
businessLicenceList.value = [previewItem];
|
||||
}
|
||||
};
|
||||
// 处理移除图片
|
||||
const handleRemove = (fieldName) => {
|
||||
localForm[fieldName] = '';
|
||||
if (fieldName === 'cooperativePhoto') {
|
||||
cooperativePhotoList.value = [];
|
||||
} else {
|
||||
businessLicenceList.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
// 处理文件超出限制
|
||||
const handleExceed = () => {
|
||||
ElMessage.warning('只能上传一张图片,请先删除当前图片');
|
||||
};
|
||||
|
||||
// 初始化时如果有图片,设置预览
|
||||
if (localForm.value.cooperativePhoto) {
|
||||
cooperativePhotoList.value = [
|
||||
{
|
||||
name: '合作社照片',
|
||||
url: ossUrl + localForm.value.cooperativePhoto,
|
||||
status: 'success',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (localForm.value.businessLicence) {
|
||||
businessLicenceList.value = [
|
||||
{
|
||||
name: '营业执照',
|
||||
url: ossUrl + localForm.value.businessLicence,
|
||||
status: 'success',
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
h3 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
width: 110px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,71 +1,76 @@
|
||||
<template>
|
||||
<div class="tab-business">
|
||||
<el-form :model="localForm" label-width="140px">
|
||||
<el-form :model="localForm" label-width="0">
|
||||
<el-row :gutter="24">
|
||||
<!-- 负债表 -->
|
||||
<el-col :span="24">
|
||||
<el-form-item label="负债表">
|
||||
<el-button type="text" @click="downloadTemplate('debt')"> 下载模板 </el-button>
|
||||
<el-upload
|
||||
class="upload-btn"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
:file-list="localForm.debtFiles"
|
||||
:before-upload="(file) => handleImport('debt', file)"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-button size="small" :disabled="readonly">导入表格</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-col :span="8">
|
||||
<h3>负债表</h3>
|
||||
<!-- <el-upload
|
||||
class="upload-btn"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
:file-list="localForm.debtFiles"
|
||||
:before-upload="(file) => handleImport('debt', file)"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
<el-button size="small" :disabled="readonly">导入表格</el-button>
|
||||
</el-upload> -->
|
||||
<div class="view-file"></div>
|
||||
<div class="upload-btn">
|
||||
<el-button type="primary" :disabled="readonly">导入表格</el-button>
|
||||
<el-button type="success" @click="downloadTemplate('debt')"> 下载模板 </el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 利润表 -->
|
||||
<el-col :span="24">
|
||||
<el-form-item label="利润表">
|
||||
<el-button type="text" @click="downloadTemplate('profit')"> 下载模板 </el-button>
|
||||
<el-upload
|
||||
class="upload-btn"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
:file-list="localForm.profitFiles"
|
||||
:before-upload="(file) => handleImport('profit', file)"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-button size="small" :disabled="readonly">导入表格</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-col :span="8">
|
||||
<h3>利润表</h3>
|
||||
<!-- <el-upload
|
||||
class="upload-btn"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
:file-list="localForm.profitFiles"
|
||||
:before-upload="(file) => handleImport('profit', file)"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-button size="small" :disabled="readonly">导入表格</el-button>
|
||||
</el-upload> -->
|
||||
<div class="view-file"></div>
|
||||
<div class="upload-btn">
|
||||
<el-button type="primary" :disabled="readonly">导入表格</el-button>
|
||||
<el-button type="success" @click="downloadTemplate('profit')"> 下载模板 </el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 现金流量表 -->
|
||||
<el-col :span="24">
|
||||
<el-form-item label="现金流量表">
|
||||
<el-button type="text" @click="downloadTemplate('cashflow')"> 下载模板 </el-button>
|
||||
<el-upload
|
||||
class="upload-btn"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
:file-list="localForm.cashflowFiles"
|
||||
:before-upload="(file) => handleImport('cashflow', file)"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-button size="small" :disabled="readonly">导入表格</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-col :span="8">
|
||||
<h3>现金流量表</h3>
|
||||
<!-- <el-upload
|
||||
class="upload-btn"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
:file-list="localForm.cashflowFiles"
|
||||
:before-upload="(file) => handleImport('cashflow', file)"
|
||||
:disabled="readonly"
|
||||
>
|
||||
<el-button size="small" :disabled="readonly">导入表格</el-button>
|
||||
</el-upload> -->
|
||||
<div class="view-file"></div>
|
||||
<div class="upload-btn">
|
||||
<el-button type="primary" :disabled="readonly">导入表格</el-button>
|
||||
<el-button type="success" @click="downloadTemplate('cashflow')"> 下载模板 </el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<div class="business-footer" style="text-align: right; margin-top: 20px">
|
||||
<el-button :disabled="readonly" @click="$emit('prev')">上一步</el-button>
|
||||
<el-button v-if="!readonly" type="primary" @click="$emit('next', localForm)"> 下一步 </el-button>
|
||||
<el-button v-if="readonly" type="warning" @click="$emit('edit')"> 修改 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, watch } from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@ -78,19 +83,10 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:modelValue',
|
||||
'prev', // 点击“上一步”
|
||||
'next', // 点击“下一步”
|
||||
'edit', // 点击“修改”
|
||||
]);
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
// 本地副本,存放各表的文件列表
|
||||
const localForm = reactive({
|
||||
debtFiles: props.modelValue.debtFiles || [],
|
||||
profitFiles: props.modelValue.profitFiles || [],
|
||||
cashflowFiles: props.modelValue.cashflowFiles || [],
|
||||
});
|
||||
const localForm = reactive(cloneDeep(props.modelValue));
|
||||
|
||||
// watch 同步回父组件
|
||||
watch(
|
||||
@ -100,6 +96,13 @@ watch(
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
Object.assign(localForm, cloneDeep(newVal));
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 下载模板(可替换为真实下载地址)
|
||||
function downloadTemplate(type) {
|
||||
@ -130,10 +133,31 @@ function handleImport(type, file) {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.upload-btn {
|
||||
margin-left: 16px;
|
||||
margin: 20px 0;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.business-footer el-button + el-button {
|
||||
margin-left: 8px;
|
||||
}
|
||||
.view-file {
|
||||
height: 400px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #909399;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,35 +1,33 @@
|
||||
<template>
|
||||
<el-form :model="localForm" label-width="160px" :disabled="readonly">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="信用评价">
|
||||
<el-rate v-model="localForm.creditRating" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
<div class="credit-evaluation">
|
||||
<h3>信用评级</h3>
|
||||
<el-form-item label="信用评价">
|
||||
<el-rate v-model="localForm.creditEvaluation" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="带动周边农户">
|
||||
<el-rate v-model="localForm.farmersSupport" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
<el-form-item label="带动周边农户">
|
||||
<el-rate v-model="localForm.supportedFarmers" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="社会效益">
|
||||
<el-rate v-model="localForm.socialBenefit" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-form-item label="社会效益">
|
||||
<el-rate v-model="localForm.socialImpact" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="高新技术应用">
|
||||
<el-rate v-model="localForm.techApplication" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
<el-form-item label="高新技术应用">
|
||||
<el-rate v-model="localForm.techApplication" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="产品质量及服务保障">
|
||||
<el-rate v-model="localForm.qualityService" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="产品质量及服务保障">
|
||||
<el-rate v-model="localForm.productQuality" allow-half show-score score-template="{value} 分" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, watch } from 'vue';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@ -42,13 +40,43 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const localForm = reactive({ ...props.modelValue });
|
||||
const localForm = reactive(cloneDeep(props.modelValue));
|
||||
|
||||
watch(
|
||||
localForm,
|
||||
(val) => {
|
||||
emit('update:modelValue', { ...val });
|
||||
(newVal) => {
|
||||
emit('update:modelValue', { ...newVal });
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
Object.assign(localForm, cloneDeep(newVal));
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.credit-evaluation {
|
||||
width: 600px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
|
||||
.el-rate {
|
||||
font-size: 16px;
|
||||
color: #f90;
|
||||
}
|
||||
}
|
||||
h3 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
width: 110px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
@ -0,0 +1,323 @@
|
||||
<template>
|
||||
<div>
|
||||
<avue-crud ref="crudRef" v-model:page="pageData" :data="crudData" :option="crudOptions" :table-loading="loading">
|
||||
<template #menu-left>
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</template>
|
||||
<template #menu="scope">
|
||||
<custom-table-operate :actions="crudOptions.actions" :data="scope" />
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<el-dialog :key="dialogTitle" v-model="dialogVisible" :title="dialogTitle" width="80%">
|
||||
<el-form :model="formData" label-width="120px" class="custom-form" :disabled="isReadonly">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="证件类型" prop="idType">
|
||||
<el-select v-model="formData.idType" placeholder="请选择证件类型" disabled>
|
||||
<el-option label="身份证" value="101" />
|
||||
<el-option label="护照" value="2" />
|
||||
<el-option label="港澳身份证" value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="证件号码" prop="idCard">
|
||||
<el-input v-model="formData.idCard" placeholder="请输入证件号码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-radio-group v-model="formData.sex">
|
||||
<el-radio label="1">男</el-radio>
|
||||
<el-radio label="0">女</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="年龄" prop="age">
|
||||
<el-input v-model="formData.age" placeholder="请输入年龄" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系方式" prop="phone">
|
||||
<el-input v-model="formData.phone" placeholder="请输入联系方式" />
|
||||
</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">
|
||||
<el-form-item label="具体地址" prop="detailAddress">
|
||||
<el-input v-model="formData.detailAddress" placeholder="请输入具体地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="种植面积" prop="area">
|
||||
<el-input v-model="formData.area" placeholder="请输入种植面积" />
|
||||
</el-form-item>
|
||||
</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"
|
||||
:params="{ status: '0' }"
|
||||
label-key="cropsName"
|
||||
value-key="id"
|
||||
placeholder="请选择种植作物"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button v-if="!isReadonly" type="primary" @click="handleSave">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, computed } from 'vue';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
import { getMemberList, addMember, updateMember, deleteMembers } from '@/apis/businessEntity';
|
||||
|
||||
const dialogTitle = ref('新增');
|
||||
const dialogVisible = ref(false);
|
||||
const isReadonly = ref(false);
|
||||
|
||||
const loading = ref(false);
|
||||
const crudRef = ref();
|
||||
// 分页数据
|
||||
const pageData = ref({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
const searchForm = ref({
|
||||
entId: '',
|
||||
userId: '',
|
||||
});
|
||||
const crudData = ref([]);
|
||||
// 定义默认表单数据
|
||||
const defaultFormData = {
|
||||
id: '',
|
||||
entId: '',
|
||||
name: '',
|
||||
idType: '101',
|
||||
idCard: '',
|
||||
sex: '1',
|
||||
age: '',
|
||||
phone: '',
|
||||
provinceCode: '', // 省
|
||||
cityCode: '', // 市
|
||||
countyCode: '', // 区县
|
||||
townCode: '', // 镇
|
||||
street: '', // 村
|
||||
addressArr: [],
|
||||
detailAddress: '',
|
||||
area: '',
|
||||
planCrop: '',
|
||||
planCropName: '',
|
||||
address: '',
|
||||
createTime: '',
|
||||
createUser: '',
|
||||
updateTime: '',
|
||||
updateUser: '',
|
||||
};
|
||||
// 新增表单数据,使用默认数据初始化
|
||||
const formData = ref({ ...defaultFormData });
|
||||
const resetForm = () => {
|
||||
formData.value = { ...defaultFormData };
|
||||
};
|
||||
|
||||
const crudOptions = reactive({
|
||||
...CRUD_OPTIONS,
|
||||
addBtn: false,
|
||||
searchBtn: false,
|
||||
emptyBtn: false,
|
||||
refreshBtn: false,
|
||||
column: [
|
||||
{ label: '姓名', prop: 'name' },
|
||||
{
|
||||
label: '证件类型',
|
||||
prop: 'idType',
|
||||
formatter: (row, column, cellValue) => {
|
||||
return cellValue === '101' ? '身份证' : cellValue === '2' ? '护照' : cellValue === '3' ? '港澳身份证' : '';
|
||||
},
|
||||
},
|
||||
{ label: '证件号码', prop: 'idCardEncrypt' },
|
||||
{
|
||||
label: '性别',
|
||||
prop: 'sex',
|
||||
formatter: (row, column, cellValue) => {
|
||||
return cellValue === '1' ? '男' : cellValue === '0' ? '女' : '';
|
||||
},
|
||||
},
|
||||
{ label: '年龄', prop: 'age' },
|
||||
{ label: '联系方式', prop: 'phone' },
|
||||
{ label: '居住地行政区划', prop: 'address' },
|
||||
{ label: '种植作物', prop: 'planCrop' },
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
name: '查看',
|
||||
icon: 'view',
|
||||
event: ({ row }) => handleView(row),
|
||||
},
|
||||
{
|
||||
name: '编辑',
|
||||
icon: 'edit',
|
||||
event: ({ row }) => handleEdit(row),
|
||||
},
|
||||
{
|
||||
type: 'danger',
|
||||
name: '删除',
|
||||
icon: 'delete',
|
||||
event: ({ row }) => handleDelete(row),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
async function getData() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
...searchForm.value,
|
||||
current: pageData.value.currentPage,
|
||||
size: pageData.value.pageSize,
|
||||
};
|
||||
const response = await getMemberList(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;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
});
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
let response;
|
||||
if (dialogTitle.value === '新增') {
|
||||
// 新增操作调用 saveFarmerList 接口
|
||||
response = await addMember(formData.value);
|
||||
if (response.code === 200) {
|
||||
ElMessage.success('新增成功');
|
||||
}
|
||||
} else if (dialogTitle.value === '编辑') {
|
||||
// 编辑操作调用 editFarmer 接口
|
||||
response = await updateMember(formData.value);
|
||||
if (response.code === 200) {
|
||||
ElMessage.success('编辑成功');
|
||||
}
|
||||
}
|
||||
|
||||
if (response && response.code === 200) {
|
||||
dialogVisible.value = false;
|
||||
getData(); // 重新获取数据
|
||||
}
|
||||
} catch (error) {
|
||||
if (dialogTitle.value === '新增') {
|
||||
ElMessage.error('新增失败,请稍后重试');
|
||||
} else {
|
||||
ElMessage.error('编辑失败,请稍后重试');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => formData.value.addressArr,
|
||||
(newValue) => {
|
||||
if (newValue.length <= 3) {
|
||||
formData.value.provinceCode = '530000';
|
||||
formData.value.cityCode = '530900';
|
||||
formData.value.countyCode = newValue[0];
|
||||
formData.value.townCode = newValue[1];
|
||||
formData.value.street = newValue[2];
|
||||
}
|
||||
}
|
||||
);
|
||||
const handleAdd = () => {
|
||||
isReadonly.value = false; // 设置为可编辑模式
|
||||
resetForm();
|
||||
dialogTitle.value = '新增';
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
function handleView(row) {
|
||||
console.log('查看', row);
|
||||
dialogTitle.value = '查看';
|
||||
isReadonly.value = true; // 设置为只读模式
|
||||
dialogVisible.value = true;
|
||||
const addressArr = [row.countyCode, row.townCode, row.street].filter(Boolean);
|
||||
formData.value = {
|
||||
...row,
|
||||
addressArr,
|
||||
};
|
||||
// 清空驳回原因
|
||||
}
|
||||
async function handleEdit(row) {
|
||||
dialogTitle.value = '编辑';
|
||||
isReadonly.value = false;
|
||||
dialogVisible.value = true;
|
||||
const addressArr = [row.countyCode, row.townCode, row.street].filter(Boolean);
|
||||
formData.value = {
|
||||
...row,
|
||||
addressArr,
|
||||
};
|
||||
}
|
||||
async function handleDelete(row) {
|
||||
try {
|
||||
await ElMessageBox.confirm('确定删除该条记录?', '删除提示');
|
||||
|
||||
console.log(`删除 ID=${row.id}`);
|
||||
await deleteMembers(row.id); // 直接传递单ID
|
||||
await getData();
|
||||
ElMessage.success('已删除');
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error(`删除失败: ${error.message || '请稍后重试'}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
@ -1,46 +1,58 @@
|
||||
<template>
|
||||
<el-form :model="localForm" label-width="150px" :disabled="readonly">
|
||||
<h3>登记注册信息</h3>
|
||||
<el-row :gutter="20">
|
||||
<!-- 左列 -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="企业名称">
|
||||
<el-input v-model="localForm.companyName" placeholder="请输入" />
|
||||
<el-input v-model="localForm.businessName" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="法定代表人">
|
||||
<el-input v-model="localForm.legalPerson" placeholder="请输入" />
|
||||
<el-input v-model="localForm.legalRep" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="企业类型">
|
||||
<el-select v-model="localForm.companyType" placeholder="请选择">
|
||||
<el-select v-model="localForm.comType" placeholder="请选择">
|
||||
<el-option label="农民专业合作社" value="农民专业合作社" />
|
||||
<el-option label="农业公司" value="农业公司" />
|
||||
<el-option label="个体工商户" value="个体工商户" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="登记机关">
|
||||
<el-input v-model="localForm.registerOrg" placeholder="请输入" />
|
||||
<el-input v-model="localForm.regAuthority" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="核准日期">
|
||||
<el-date-picker v-model="localForm.approvalDate" type="date" placeholder="请选择" format="YYYY年MM月DD日" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
<el-form-item label="经营范围">
|
||||
<el-input v-model="localForm.businessScope" type="textarea" placeholder="请输入" :rows="4" />
|
||||
<el-date-picker
|
||||
v-model="localForm.approveDate"
|
||||
style="width: 100%"
|
||||
type="date"
|
||||
placeholder="请选择"
|
||||
format="YYYY年MM月DD日"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- 右列 -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="统一社会信用代码">
|
||||
<el-input v-model="localForm.creditCode" placeholder="请输入" />
|
||||
<el-input v-model="localForm.uscc" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="登记状态">
|
||||
<el-select v-model="localForm.registerStatus" placeholder="请选择">
|
||||
<el-select v-model="localForm.registrationStatus" placeholder="请选择">
|
||||
<el-option label="存续" value="存续" />
|
||||
<el-option label="注销" value="注销" />
|
||||
<el-option label="吊销" value="吊销" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="成立日期">
|
||||
<el-date-picker v-model="localForm.establishDate" type="date" placeholder="请选择" format="YYYY年MM月DD日" value-format="YYYY-MM-DD" />
|
||||
<el-date-picker
|
||||
v-model="localForm.estDate"
|
||||
style="width: 100%"
|
||||
type="date"
|
||||
placeholder="请选择"
|
||||
format="YYYY年MM月DD日"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="成员出资总额">
|
||||
<el-input v-model="localForm.totalCapital" placeholder="请输入" />
|
||||
@ -49,12 +61,18 @@
|
||||
<el-input v-model="localForm.address" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="经营范围">
|
||||
<el-input v-model="localForm.businessScope" type="businessScope" placeholder="请输入" :rows="4" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, watch } from 'vue';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@ -68,7 +86,7 @@ const props = defineProps({
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
// 创建本地副本(为了避免直接修改 props)
|
||||
const localForm = reactive({ ...props.modelValue });
|
||||
const localForm = reactive(cloneDeep(props.modelValue));
|
||||
|
||||
// 监听本地副本的变化,自动回传给父组件
|
||||
watch(
|
||||
@ -78,4 +96,23 @@ watch(
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
Object.assign(localForm, cloneDeep(newVal));
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
h3 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
width: 110px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,35 +1,47 @@
|
||||
<template>
|
||||
<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">
|
||||
<custom-table-operate :actions="crudOptions.actions" :data="scope" />
|
||||
</template>
|
||||
</avue-crud>
|
||||
<el-dialog v-model="visible" title="农企合作社详情" width="80%" :draggable="true">
|
||||
<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="1. 基础信息" name="basic">
|
||||
<TabBasicInfo v-model="formData.basicInfo" :readonly="isReadonly" />
|
||||
<el-tab-pane label="基础信息" name="basic">
|
||||
<TabBasicInfo v-model="formData" :readonly="isReadonly" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="2. 登记注册信息" name="register">
|
||||
<TabRegister v-model="formData.registerInfo" />
|
||||
<el-tab-pane label="登记注册信息" name="register">
|
||||
<TabRegister v-model="formData" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="3. 经营信息" name="business">
|
||||
<TabBusinessInfo
|
||||
v-model="formData.business"
|
||||
:readonly="isReadonly"
|
||||
@prev="activeTab = 'register'"
|
||||
@next="handleNext"
|
||||
@edit="isReadonly = false"
|
||||
/>
|
||||
<el-tab-pane label="经营信息" name="business">
|
||||
<TabBusinessInfo v-model="formData" :readonly="isReadonly" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="4. 信用评级" name="credit">
|
||||
<TabCreditEvaluation v-model="formData.credit" :readonly="isReadonly" />
|
||||
<el-tab-pane label="信用评级" name="credit">
|
||||
<TabCreditEvaluation v-model="formData" :readonly="isReadonly" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="dialogTitle === '查看'" label="职工/社员管理" name="employee">
|
||||
<TabMember :readonly="isReadonly" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">关闭</el-button>
|
||||
<el-button v-if="!isReadonly" type="primary" @click="handleSubmit">保存</el-button>
|
||||
<template v-if="dialogTitle !== '查看'" #footer>
|
||||
<el-button v-if="!isFirstTab" type="primary" @click="handlePrev">上一步</el-button>
|
||||
<el-button v-if="!isLastTab" type="primary" @click="handleNext">下一步</el-button>
|
||||
<el-button v-if="!isFirstTab && !isLastTab" type="info" @click="handleSkip">跳过</el-button>
|
||||
<el-button v-if="isLastTab" type="primary" @click="handleSubmit">保存</el-button>
|
||||
<el-button v-if="isLastTab" type="info" @click="handleSkipSave">跳过并保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</section>
|
||||
@ -43,65 +55,86 @@ import TabBasicInfo from './components/TabBasicInfo.vue';
|
||||
import TabRegister from './components/TabRegister.vue';
|
||||
import TabBusinessInfo from './components/TabBusinessInfo.vue';
|
||||
import TabCreditEvaluation from './components/TabCreditEvaluation.vue';
|
||||
import { getEnterList } from '@/apis/businessEntity';
|
||||
import TabMember from './components/TabMember.vue';
|
||||
import { getEnterList, getEnterById, addEnter, updateEnter, approvalEnter, deleteEnter } from '@/apis/businessEntity';
|
||||
import { cloneDeep } from 'lodash';
|
||||
|
||||
// 控制弹窗显示
|
||||
const visible = ref(false);
|
||||
// 当前 tab
|
||||
const activeCrudTab = ref('0');
|
||||
const activeTab = ref('basic');
|
||||
const dialogTitle = ref('新增');
|
||||
const isReadonly = ref(false);
|
||||
|
||||
// 搜索表单模型
|
||||
const searchForm = ref({
|
||||
businessName: '',
|
||||
uscc: '',
|
||||
productType: '',
|
||||
primaryProduct: '',
|
||||
});
|
||||
// 数据和状态
|
||||
const formData = ref({
|
||||
// 基础信息
|
||||
basicInfo: {
|
||||
name: '',
|
||||
area: '',
|
||||
contactPerson: '',
|
||||
address: [],
|
||||
product: '',
|
||||
phone: '',
|
||||
photoUrl: '',
|
||||
businessLicenseUrl: '',
|
||||
},
|
||||
// 其他信息根据注册、经营、信用评级模块添加
|
||||
registerInfo: {
|
||||
companyName: '',
|
||||
legalPerson: '',
|
||||
companyType: '',
|
||||
registerOrg: '',
|
||||
approvalDate: '',
|
||||
creditCode: '',
|
||||
registerStatus: '',
|
||||
establishDate: '',
|
||||
totalCapital: '',
|
||||
address: '',
|
||||
businessScope: '',
|
||||
},
|
||||
business: {
|
||||
debtFiles: [],
|
||||
profitFiles: [],
|
||||
cashflowFiles: [],
|
||||
},
|
||||
credit: {
|
||||
creditRating: 5,
|
||||
farmersSupport: 4,
|
||||
socialBenefit: 3,
|
||||
techApplication: 2,
|
||||
qualityService: 1,
|
||||
},
|
||||
id: '',
|
||||
// 基础信息 basicInfo
|
||||
businessName: '',
|
||||
area: '',
|
||||
contactPerson: '',
|
||||
cooperativePhoto: '', // 合作社照片
|
||||
addressArr: [],
|
||||
primaryProduct: '',
|
||||
phone: '',
|
||||
businessLicence: '', // 营业执照
|
||||
provinceCode: '',
|
||||
cityCode: '',
|
||||
countyCode: '',
|
||||
townCode: '',
|
||||
villageCode: '',
|
||||
// 登记注册信息 registerInfo
|
||||
// businessName: '',
|
||||
legalRep: '',
|
||||
comType: '',
|
||||
regAuthority: '',
|
||||
approveDate: '',
|
||||
uscc: '',
|
||||
registrationStatus: '',
|
||||
estDate: '',
|
||||
totalCapital: '',
|
||||
address: '',
|
||||
businessScope: '',
|
||||
// 经营信息
|
||||
debtFiles: [],
|
||||
profitFiles: [],
|
||||
cashflowFiles: [],
|
||||
// 信用评价
|
||||
creditEvaluation: 5,
|
||||
supportedFarmers: 4,
|
||||
socialImpact: 3,
|
||||
techApplication: 2,
|
||||
productQuality: 1,
|
||||
});
|
||||
|
||||
// 是否查看模式
|
||||
const isReadonly = ref(false);
|
||||
|
||||
// 保存处理
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
// 假设当前编辑的数据 ID 是 formData.value.id(你可能需要从原始行中传入)
|
||||
await api.updateById(formData.value.id, formData.value);
|
||||
ElMessage.success('保存成功');
|
||||
visible.value = false;
|
||||
let response;
|
||||
if (dialogTitle.value === '新增') {
|
||||
formData.value.id = '';
|
||||
response = await addEnter(formData.value);
|
||||
if (response.code === 200) {
|
||||
ElMessage.success('新增成功');
|
||||
visible.value = false;
|
||||
getData(); // 刷新表格数据
|
||||
}
|
||||
} else if (dialogTitle.value === '编辑') {
|
||||
response = await updateEnter(formData.value);
|
||||
if (response.code === 200) {
|
||||
ElMessage.success('编辑成功');
|
||||
visible.value = false;
|
||||
getData(); // 刷新表格数据
|
||||
}
|
||||
}
|
||||
// 可刷新表格数据
|
||||
} catch (e) {
|
||||
ElMessage.error('保存失败');
|
||||
@ -116,68 +149,7 @@ const pageData = ref({
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const crudData = ref([
|
||||
{
|
||||
cooperativeName: '华祥种植专业合作社',
|
||||
location: '耿马县/耿马镇/新城村',
|
||||
area: '300亩',
|
||||
products: '小葱、大白菜',
|
||||
contactPerson: '张强',
|
||||
contactPhone: '13384041642',
|
||||
employeeCount: '50人',
|
||||
status: '待审核',
|
||||
createTime: '2024年8月21日16:20:41',
|
||||
updateTime: '2024年8月21日16:20:51',
|
||||
},
|
||||
{
|
||||
cooperativeName: '春林农业合作社',
|
||||
location: '耿马县/耿马镇/和平村',
|
||||
area: '200亩',
|
||||
products: '西红柿、黄瓜',
|
||||
contactPerson: '李梅',
|
||||
contactPhone: '13812345678',
|
||||
employeeCount: '30人',
|
||||
status: '审核通过',
|
||||
createTime: '2024年7月15日09:30:12',
|
||||
updateTime: '2024年7月15日10:02:00',
|
||||
},
|
||||
{
|
||||
cooperativeName: '绿源蔬菜种植基地',
|
||||
location: '耿马县/芒洪乡/新村',
|
||||
area: '150亩',
|
||||
products: '辣椒、豆角',
|
||||
contactPerson: '王伟',
|
||||
contactPhone: '13987654321',
|
||||
employeeCount: '25人',
|
||||
status: '待审核',
|
||||
createTime: '2024年9月01日14:45:20',
|
||||
updateTime: '2024年9月01日14:46:30',
|
||||
},
|
||||
{
|
||||
cooperativeName: '金丰农作物专业合作社',
|
||||
location: '耿马县/勐简乡/丰收村',
|
||||
area: '400亩',
|
||||
products: '玉米、大豆',
|
||||
contactPerson: '赵敏',
|
||||
contactPhone: '13699887766',
|
||||
employeeCount: '60人',
|
||||
status: '待审核',
|
||||
createTime: '2024年6月10日08:10:50',
|
||||
updateTime: '2024年6月10日08:12:20',
|
||||
},
|
||||
{
|
||||
cooperativeName: '恒泰水果种植农场',
|
||||
location: '耿马县/勐永镇/红星村',
|
||||
area: '500亩',
|
||||
products: '香蕉、芒果',
|
||||
contactPerson: '周强',
|
||||
contactPhone: '13711223344',
|
||||
employeeCount: '80人',
|
||||
status: '审核不通过',
|
||||
createTime: '2024年5月25日11:20:15',
|
||||
updateTime: '2024年5月25日11:22:00',
|
||||
},
|
||||
]);
|
||||
const crudData = ref([]);
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
@ -187,13 +159,13 @@ const crudOptions = reactive({
|
||||
searchBtn: false,
|
||||
emptyBtn: false,
|
||||
column: [
|
||||
{ label: '农企/合作社名称', prop: 'cooperativeName' },
|
||||
{ label: '地点', prop: 'location' },
|
||||
{ label: '农企/合作社名称', prop: 'businessName' },
|
||||
{ label: '地点', prop: 'regAddress' },
|
||||
{ label: '面积', prop: 'area' },
|
||||
{ label: '经营产品', prop: 'products' },
|
||||
{ label: '经营产品', prop: 'businessScope' },
|
||||
{ label: '联系人', prop: 'contactPerson' },
|
||||
{ label: '联系电话', prop: 'contactPhone' },
|
||||
{ label: '聘工人数', prop: 'employeeCount' },
|
||||
{ label: '联系电话', prop: 'phone' },
|
||||
{ label: '聘工人数', prop: 'villageCount' },
|
||||
{ label: '状态', prop: 'status' },
|
||||
{ label: '信息录入时间', prop: 'createTime' },
|
||||
{ label: '信息更新时间', prop: 'updateTime' },
|
||||
@ -215,16 +187,94 @@ const crudOptions = reactive({
|
||||
icon: 'delete',
|
||||
event: ({ row }) => handleDelete(row.id),
|
||||
},
|
||||
// 驳回原因 showRejectReason (仅显示)
|
||||
{
|
||||
name: '驳回原因',
|
||||
icon: 'warning',
|
||||
event: ({ row }) => {
|
||||
showRejectReason(row);
|
||||
},
|
||||
},
|
||||
|
||||
// 提交审核 handleSubmit
|
||||
{
|
||||
name: '提交审核',
|
||||
icon: 'check',
|
||||
event: ({ row }) => {
|
||||
if (row.status === '待提交') {
|
||||
handleSubmit();
|
||||
} else {
|
||||
ElMessage.warning('当前状态不允许提交审核');
|
||||
}
|
||||
},
|
||||
},
|
||||
// 撤销(待审核 → 待提交),超级管理员和提交人拥有撤销 handleWithdraw
|
||||
{
|
||||
name: '撤销',
|
||||
icon: 'undo',
|
||||
event: ({ row }) => {
|
||||
handleWithdraw(row);
|
||||
},
|
||||
},
|
||||
// 重新提交 handleResubmit
|
||||
{
|
||||
name: '重新提交',
|
||||
icon: 'resubmit',
|
||||
event: (row) => {
|
||||
handleResubmit(row);
|
||||
},
|
||||
},
|
||||
// 通过(待审核 → 已通过) handleApprove
|
||||
{
|
||||
name: '通过',
|
||||
icon: 'check-circle',
|
||||
event: ({ row }) => {
|
||||
handleApprove(row);
|
||||
},
|
||||
},
|
||||
// 驳回(待审核 → 已驳回) handleReject
|
||||
{
|
||||
name: '驳回',
|
||||
icon: 'close-circle',
|
||||
event: ({ row }) => {
|
||||
handleReject(row);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
// 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('行政区划数据错误');
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
});
|
||||
|
||||
// 页面加载时获取数据
|
||||
const getData = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await getEnterList(pageData.value.currentPage, pageData.value.pageSize);
|
||||
crudData.value = response.data;
|
||||
pageData.value.total = response.total;
|
||||
const response = await getEnterList({
|
||||
...searchForm.value,
|
||||
status: activeCrudTab.value,
|
||||
page: pageData.value.currentPage,
|
||||
size: pageData.value.pageSize,
|
||||
});
|
||||
console.log('response', response);
|
||||
crudData.value = response.data.records;
|
||||
pageData.value.total = response.data.total;
|
||||
pageData.value.currentPage = response.data.current;
|
||||
pageData.value.pageSize = response.data.size;
|
||||
} catch (error) {
|
||||
ElMessage.error('加载数据失败');
|
||||
} finally {
|
||||
@ -232,12 +282,72 @@ const getData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const getEnterDetail = async (id) => {
|
||||
try {
|
||||
const response = await getEnterById(id);
|
||||
if (response?.code === 200 && response.data) {
|
||||
// 使用深拷贝避免污染原始数据
|
||||
formData.value = {
|
||||
...cloneDeep(response.data),
|
||||
// 确保addressArr始终是5个元素,不足的用空字符串填充
|
||||
addressArr: [
|
||||
response.data.provinceCode || '',
|
||||
response.data.cityCode || '',
|
||||
response.data.countyCode || '',
|
||||
response.data.townCode || '',
|
||||
response.data.villageCode || '',
|
||||
],
|
||||
};
|
||||
|
||||
// // 初始化图片预览(如果之前实现了图片预览功能)
|
||||
// if (response.data.cooperativePhoto) {
|
||||
// cooperativePhotoList.value = [
|
||||
// {
|
||||
// name: '合作社照片',
|
||||
// url: response.data.cooperativePhoto,
|
||||
// status: 'success',
|
||||
// },
|
||||
// ];
|
||||
// }
|
||||
// if (response.data.businessLicence) {
|
||||
// businessLicenceList.value = [
|
||||
// {
|
||||
// name: '营业执照',
|
||||
// url: response.data.businessLicence,
|
||||
// status: 'success',
|
||||
// },
|
||||
// ];
|
||||
// }
|
||||
|
||||
console.log('详情数据加载完成', formData.value);
|
||||
} else {
|
||||
ElMessage.error(response?.msg || '获取详情失败:服务器未返回有效数据');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取详情失败:', error);
|
||||
ElMessage.error(`获取详情失败:${error.message || '请稍后重试'}`);
|
||||
}
|
||||
};
|
||||
function handleSearch() {
|
||||
getData();
|
||||
}
|
||||
function handleTabChange(tab) {
|
||||
handleSearch();
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
isReadonly.value = false;
|
||||
// resetForm();
|
||||
dialogTitle.value = '新增';
|
||||
visible.value = true;
|
||||
};
|
||||
// 查看详情(只读模式)
|
||||
const handleView = async (row) => {
|
||||
loading.value = true;
|
||||
dialogTitle.value = '查看';
|
||||
formData.value = null;
|
||||
try {
|
||||
const data = await api.getDetailById(row.id);
|
||||
formData.value = data;
|
||||
await getEnterDetail(row.id);
|
||||
isReadonly.value = true;
|
||||
activeTab.value = 'basic';
|
||||
visible.value = true;
|
||||
@ -249,9 +359,9 @@ const handleView = async (row) => {
|
||||
// 编辑详情(可修改)
|
||||
const handleEdit = async (row) => {
|
||||
loading.value = true;
|
||||
dialogTitle.value = '编辑';
|
||||
try {
|
||||
const data = await api.getDetailById(row.id);
|
||||
formData.value = data;
|
||||
await getEnterById(row.id);
|
||||
isReadonly.value = false;
|
||||
activeTab.value = 'basic';
|
||||
visible.value = true;
|
||||
@ -259,7 +369,106 @@ const handleEdit = async (row) => {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
// 重新提交(被驳回 → 待审核)
|
||||
function handleResubmit(row) {
|
||||
ElMessageBox.confirm('确认重新提交吗?', '重新提交').then(() => {
|
||||
const params = {
|
||||
id: row.id,
|
||||
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 || '重新提交失败');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 撤销(待审核 → 待提交),超级管理员和提交人拥有撤销
|
||||
function handleWithdraw(row) {
|
||||
ElMessageBox.confirm('确认撤销本次审核吗?', '撤销').then(() => {
|
||||
const params = {
|
||||
id: row.id,
|
||||
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 || '撤销失败');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 审核通过(待审核 → 已通过)
|
||||
function handleApprove(row) {
|
||||
ElMessageBox.confirm('确认通过审核?', '审核通过').then(() => {
|
||||
const params = {
|
||||
id: row.id,
|
||||
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 || '审核操作失败');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 审核驳回(待审核 → 已驳回),需要填写驳回原因
|
||||
function handleReject(row) {
|
||||
ElMessageBox.prompt('请输入驳回原因', '审核驳回', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
inputPattern: /.+/, // 必须输入内容
|
||||
inputErrorMessage: '驳回原因不能为空',
|
||||
})
|
||||
.then(({ value }) => {
|
||||
const params = {
|
||||
id: row.id,
|
||||
status: '3', // 已驳回
|
||||
reason: value.trim(),
|
||||
};
|
||||
return approvalEnter(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 || '驳回操作失败');
|
||||
}
|
||||
});
|
||||
}
|
||||
// 查看/弹窗 驳回原因
|
||||
function showRejectReason(row) {
|
||||
ElMessageBox.alert(row.reason || '无驳回原因', '驳回原因');
|
||||
}
|
||||
// 删除操作
|
||||
const handleDelete = async (id) => {
|
||||
try {
|
||||
@ -267,9 +476,13 @@ const handleDelete = async (id) => {
|
||||
type: 'warning',
|
||||
});
|
||||
loading.value = true;
|
||||
await api.deleteById(id);
|
||||
ElMessage.success('删除成功');
|
||||
// 这里可以重新刷新表格数据,比如调用接口或分页更新
|
||||
const res = await deleteEnter(id);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('删除成功');
|
||||
getData(); // 刷新数据
|
||||
} else {
|
||||
ElMessage.error(res.msg || '删除失败');
|
||||
}
|
||||
} catch (e) {
|
||||
if (e !== 'cancel') {
|
||||
ElMessage.error('删除失败');
|
||||
@ -278,63 +491,35 @@ const handleDelete = async (id) => {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
// 新增 tabs 顺序列表
|
||||
const tabOrder = ['basic', 'register', 'business', 'credit'];
|
||||
|
||||
// 假设的 API 模块
|
||||
const api = {
|
||||
// 获取详情
|
||||
getDetailById: async (id) => {
|
||||
// 模拟请求,返回结构应与 formData 保持一致
|
||||
return {
|
||||
basicInfo: {
|
||||
name: '绿源蔬菜种植基地',
|
||||
area: '150亩',
|
||||
contactPerson: '王伟',
|
||||
address: ['耿马县', '芒洪乡', '新村'],
|
||||
product: '辣椒、豆角',
|
||||
phone: '13987654321',
|
||||
photoUrl: '',
|
||||
businessLicenseUrl: '',
|
||||
},
|
||||
registerInfo: {
|
||||
companyName: '绿源蔬菜种植基地',
|
||||
legalPerson: '王伟',
|
||||
companyType: '合作社',
|
||||
registerOrg: '耿马县工商局',
|
||||
approvalDate: '2022-03-01',
|
||||
creditCode: '123456789000000000',
|
||||
registerStatus: '存续',
|
||||
establishDate: '2020-01-01',
|
||||
totalCapital: '200万',
|
||||
address: '耿马县芒洪乡新村',
|
||||
businessScope: '蔬菜种植销售',
|
||||
},
|
||||
business: {
|
||||
debtFiles: [],
|
||||
profitFiles: [],
|
||||
cashflowFiles: [],
|
||||
},
|
||||
credit: {
|
||||
creditRating: 4,
|
||||
farmersSupport: 3,
|
||||
socialBenefit: 4,
|
||||
techApplication: 3,
|
||||
qualityService: 4,
|
||||
},
|
||||
};
|
||||
},
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
// 更新
|
||||
updateById: async (id, data) => {
|
||||
console.log('更新请求', id, data);
|
||||
return true;
|
||||
},
|
||||
/** 跳转到上一 Tab */
|
||||
function handlePrev() {
|
||||
if (currentTabIndex.value > 0) {
|
||||
activeTab.value = tabOrder[currentTabIndex.value - 1];
|
||||
}
|
||||
}
|
||||
|
||||
// 删除
|
||||
deleteById: async (id) => {
|
||||
console.log('删除请求', id);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
/** 跳过当前步骤 */
|
||||
function handleSkip() {
|
||||
handleNext();
|
||||
}
|
||||
/** 跳过并保存 */
|
||||
function handleSkipSave() {
|
||||
handleSkip();
|
||||
handleSubmit();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -342,12 +527,29 @@ const api = {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
// background-color: #7daaaa;
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
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%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -20,7 +20,7 @@
|
||||
</el-tabs>
|
||||
|
||||
<!-- 表格 -->
|
||||
<avue-crud ref="crudRef" v-model:page="pageData" :data="filteredData" :option="crudOptions" :table-loading="loading">
|
||||
<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>
|
||||
@ -30,7 +30,7 @@
|
||||
</avue-crud>
|
||||
|
||||
<!-- 新增弹窗 -->
|
||||
<el-dialog :key="dialogTitle" v-model="dialogVisible" :title="dialogTitle" width="80%">
|
||||
<el-dialog :key="dialogTitle" v-model="dialogVisible" :title="dialogTitle" width="80%" align-center :draggable="true">
|
||||
<el-form :model="formData" label-width="120px" class="custom-form" :disabled="isReadonly">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
@ -57,8 +57,8 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-radio-group v-model="formData.sex">
|
||||
<el-radio label="1">男</el-radio>
|
||||
<el-radio label="0">女</el-radio>
|
||||
<el-radio value="1">男</el-radio>
|
||||
<el-radio value="0">女</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -77,8 +77,8 @@
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="居住地行政区划" prop="address">
|
||||
<area-select v-model="formData.address" :label="null" />
|
||||
<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>
|
||||
@ -122,7 +122,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, reactive, onMounted, watch } from 'vue';
|
||||
import { ref, computed, reactive, onMounted, watch, nextTick } from 'vue';
|
||||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { fetchFarmerList, fetchFarmerById, saveFarmerList, editFarmer, approveFarmer, deleteFarmers } from '@/apis/businessEntity';
|
||||
@ -161,7 +161,7 @@ const pageData = ref({
|
||||
total: 0,
|
||||
});
|
||||
// 模拟的原始数据列表(通常从后端接口拿到)
|
||||
const allData = ref([]);
|
||||
const crudData = ref([]);
|
||||
|
||||
// 新增弹窗显示状态
|
||||
const dialogVisible = ref(false);
|
||||
@ -177,8 +177,9 @@ const defaultFormData = {
|
||||
cityCode: '', // 市
|
||||
countyCode: '', // 区县
|
||||
townCode: '', // 镇
|
||||
street: '', // 村
|
||||
address: [],
|
||||
villageCode: '', // 村
|
||||
address: '',
|
||||
addressArr: [],
|
||||
detailAddress: '',
|
||||
area: '',
|
||||
planCrop: '',
|
||||
@ -192,20 +193,6 @@ const resetForm = () => {
|
||||
formData.value = { ...defaultFormData };
|
||||
};
|
||||
|
||||
// 根据当前选中 tab + 关键词来过滤数据
|
||||
const filteredData = computed(() => {
|
||||
return allData.value.filter((row) => {
|
||||
// 只展示当前状态的数据
|
||||
if (String(row.status) !== activeTab.value) return false;
|
||||
|
||||
// 如果有关键词,则姓名/证件号/联系方式 任意包含即显示
|
||||
const kw = searchForm.value.name.trim();
|
||||
if (kw) {
|
||||
return row.name.includes(kw) || row.idCard.includes(kw) || row.phone.includes(kw);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
// ==============================
|
||||
// CRUD 配置
|
||||
// ==============================
|
||||
@ -255,8 +242,8 @@ async function getData() {
|
||||
};
|
||||
const response = await fetchFarmerList(params);
|
||||
if (response.code === 200 && response.data) {
|
||||
allData.value = response.data.records;
|
||||
console.log('获取数据成功:', allData.value);
|
||||
crudData.value = response.data.records;
|
||||
console.log('获取数据成功:', crudData.value);
|
||||
pageData.value = {
|
||||
currentPage: response.data.current,
|
||||
pageSize: response.data.size,
|
||||
@ -288,9 +275,6 @@ const fetchCropsList = async () => {
|
||||
}
|
||||
};
|
||||
function handleSearch() {
|
||||
// 这里直接触发 filteredData 重新计算即可
|
||||
// 如果是后端分页,则要带上 activeTab + keyword 去请求
|
||||
console.log('搜索关键词:', searchForm.value.keyword);
|
||||
getData();
|
||||
}
|
||||
function handleReset() {
|
||||
@ -309,14 +293,16 @@ const handleAdd = () => {
|
||||
};
|
||||
// 根据address解构行政区划数据
|
||||
watch(
|
||||
() => formData.value.address,
|
||||
() => formData.value.addressArr,
|
||||
(newValue) => {
|
||||
if (newValue.length <= 3) {
|
||||
formData.value.provinceCode = '530000';
|
||||
formData.value.cityCode = '530900';
|
||||
formData.value.countyCode = newValue[0];
|
||||
formData.value.townCode = newValue[1];
|
||||
formData.value.street = newValue[2];
|
||||
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('行政区划数据错误');
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -326,6 +312,7 @@ const handleSave = async () => {
|
||||
try {
|
||||
let response;
|
||||
if (dialogTitle.value === '新增') {
|
||||
console.log('新增formData.value.arr :>> ', formData.value.addressArr);
|
||||
// 新增操作调用 saveFarmerList 接口
|
||||
response = await saveFarmerList(formData.value);
|
||||
if (response.code === 200) {
|
||||
@ -366,26 +353,29 @@ const getFarmerById = async (id) => {
|
||||
}
|
||||
};
|
||||
// 查看
|
||||
function handleView(row) {
|
||||
async function handleView(row) {
|
||||
console.log('查看', row);
|
||||
dialogTitle.value = '查看';
|
||||
isReadonly.value = true; // 设置为只读模式
|
||||
dialogVisible.value = true;
|
||||
getFarmerById(row.id).then((data) => {
|
||||
if (data) {
|
||||
const address = [data.countyCode, data.townCode, data.street].filter(Boolean);
|
||||
formData.value = {
|
||||
...data,
|
||||
address,
|
||||
};
|
||||
}
|
||||
|
||||
const data = await getFarmerById(row.id);
|
||||
if (data) {
|
||||
console.log('data :>> ', data);
|
||||
const addressArr = [data.provinceCode, data.cityCode, data.countyCode, data.townCode, data.villageCode].filter(Boolean);
|
||||
console.log('addressArr :>> ', addressArr);
|
||||
formData.value = {
|
||||
...data,
|
||||
addressArr: addressArr,
|
||||
};
|
||||
}
|
||||
console.log('cc formData.value :>> ', formData.value.addressArr);
|
||||
nextTick(() => {
|
||||
dialogVisible.value = true;
|
||||
});
|
||||
// 清空驳回原因
|
||||
}
|
||||
|
||||
// 编辑(修改/填写)
|
||||
async function handleEdit(row) {
|
||||
// 已通过状态的数据,点击编辑之后提示:编辑之后需要重新提交审核,是否确认的确认框
|
||||
if (row.status === '2') {
|
||||
try {
|
||||
await ElMessageBox.confirm('编辑后数据将需要重新审核,是否继续?', '确认编辑', {
|
||||
@ -394,7 +384,7 @@ async function handleEdit(row) {
|
||||
type: 'warning',
|
||||
});
|
||||
} catch {
|
||||
return; // 用户取消则直接返回
|
||||
return;
|
||||
}
|
||||
}
|
||||
dialogTitle.value = '编辑';
|
||||
@ -402,10 +392,8 @@ async function handleEdit(row) {
|
||||
dialogVisible.value = true;
|
||||
getFarmerById(row.id).then((data) => {
|
||||
if (data) {
|
||||
const address = [data.countyCode, data.townCode, data.street].filter(Boolean);
|
||||
formData.value = {
|
||||
...data,
|
||||
address,
|
||||
};
|
||||
}
|
||||
});
|
||||
@ -431,7 +419,6 @@ function handleSubmit(row) {
|
||||
});
|
||||
}
|
||||
|
||||
// 重新提交(被驳回 → 待审核)
|
||||
// 重新提交(被驳回 → 待审核)
|
||||
function handleResubmit(row) {
|
||||
ElMessageBox.confirm('确认重新提交吗?', '重新提交').then(() => {
|
||||
@ -601,7 +588,7 @@ function getActions(row) {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 4. 示例:页面加载时可以从后端获取 allData
|
||||
// 4. 示例:页面加载时可以从后端获取 crudData
|
||||
// ---------------------------------------------------------------------
|
||||
onMounted(() => {
|
||||
getData();
|
||||
@ -622,6 +609,11 @@ onMounted(() => {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 20px;
|
||||
height: calc(100vh - 300px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.custom-form {
|
||||
padding: 20px;
|
||||
|
@ -1,254 +0,0 @@
|
||||
<template>
|
||||
<div class="custom-page">
|
||||
<avue-crud
|
||||
ref="crudRef"
|
||||
v-model="state.form"
|
||||
v-model:page="state.pageData"
|
||||
:table-loading="state.loading"
|
||||
:data="state.data"
|
||||
:option="state.options"
|
||||
@refresh-change="refreshChange"
|
||||
@selection-change="selectionChange"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@row-save="rowSave"
|
||||
@row-update="rowUpdate"
|
||||
@row-del="rowDel"
|
||||
>
|
||||
<template #menu-left>
|
||||
<!-- <el-button type="primary" icon="Upload" @click="onImport">导入</el-button> -->
|
||||
<!-- <el-button type="danger" icon="Delete" @click="onBatchDel">批量删除</el-button> -->
|
||||
</template>
|
||||
|
||||
<!-- <template #operationDate-search>
|
||||
<el-date-picker v-model="timeVal" type="daterange" style="width: 230px" start-placeholder="开始" end-placeholder="结束" />
|
||||
</template> -->
|
||||
|
||||
<template #menu="scope">
|
||||
<custom-table-operate :actions="state.options.actions" :data="scope" />
|
||||
</template>
|
||||
</avue-crud>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { useApp } from '@/hooks';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { isEmpty, downloadFile } from '@/utils';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
import {
|
||||
fetchBusinessSubjectList,
|
||||
saveBusinessSubject,
|
||||
editBusinessSubject,
|
||||
deleteBusinessSubject,
|
||||
fetchBusinessSubjectInfo,
|
||||
} from '@/apis/businessEntity';
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
const app = useApp();
|
||||
const UserStore = useUserStore();
|
||||
const crudRef = ref(null);
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
query: { current: 1, size: 10, businessType: 0 },
|
||||
form: {},
|
||||
selection: [],
|
||||
pageData: { currentPage: 1, pageSize: 10, total: 0 },
|
||||
data: [],
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
addBtnText: '添加',
|
||||
column: [
|
||||
{ label: '主体代码', prop: 'id' },
|
||||
{ label: '主体名称', prop: 'businessName' },
|
||||
{
|
||||
label: '经营产品种类',
|
||||
prop: 'productType',
|
||||
type: 'select',
|
||||
dicData: [
|
||||
{ label: '蔬菜', value: '0' },
|
||||
{ label: '水果', value: '1' },
|
||||
{ label: '畜产品', value: '2' },
|
||||
{ label: '水产品', value: '3' },
|
||||
{ label: '谷物', value: '4' },
|
||||
{ label: '农资', value: '5' },
|
||||
{ label: '种源', value: '6' },
|
||||
{ label: '农产品加工', value: '7' },
|
||||
{ label: '其他', value: '8' },
|
||||
],
|
||||
},
|
||||
{ label: '主要经营产品', prop: 'primaryProduct' },
|
||||
{ label: '户主身份证号', prop: 'idCard' },
|
||||
{
|
||||
label: '联系地址',
|
||||
prop: 'address',
|
||||
type: 'cascader',
|
||||
props: { label: 'areaName', value: 'areaCode', children: 'areaChildVOS' },
|
||||
dicUrl: `${VITE_APP_BASE_API}/system/area/region?areaCode=530000`,
|
||||
dicHeaders: { authorization: UserStore.token },
|
||||
},
|
||||
{ label: '详细地址', prop: 'detailAddress' },
|
||||
{ label: '联系电话', prop: 'phone' },
|
||||
{
|
||||
label: '审核状态',
|
||||
prop: 'status',
|
||||
type: 'select',
|
||||
dicData: [
|
||||
{ label: '未审核', value: 0 },
|
||||
{ label: '通过', value: 1 },
|
||||
{ label: '拒绝', value: 2 },
|
||||
],
|
||||
},
|
||||
{ label: '审核意见', prop: 'reviewSuggestion' },
|
||||
{ label: '创建时间', prop: 'createTime', type: 'datetime', format: 'YYYY-MM-DD HH:mm:ss' },
|
||||
],
|
||||
actions: [
|
||||
{ name: '详情', event: ({ row }) => viewRow(row) },
|
||||
{ name: '编辑', event: ({ row }) => editRow(row) },
|
||||
{ type: 'danger', name: '删除', event: ({ row }) => deleteRow(row) },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
// 加载
|
||||
const loadData = () => {
|
||||
state.loading = true;
|
||||
fetchBusinessSubjectList(state.query)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
const { current, size, total, records } = res.data;
|
||||
state.data = records;
|
||||
state.pageData = {
|
||||
currentPage: current || 1,
|
||||
pageSize: size || 10,
|
||||
total: total,
|
||||
};
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
state.data = [];
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
const editRow = (row) => {
|
||||
fetchBusinessSubjectInfo(row.id).then((res) => {
|
||||
crudRef.value.rowEdit(res.data);
|
||||
});
|
||||
};
|
||||
|
||||
const viewRow = (row) => {
|
||||
fetchBusinessSubjectInfo(row.id).then((res) => {
|
||||
crudRef.value.rowView(res.data);
|
||||
});
|
||||
};
|
||||
|
||||
const deleteRow = (row) => {
|
||||
app
|
||||
.$confirm('确认删除?', '删除', { type: 'warning' })
|
||||
.then(() =>
|
||||
deleteBusinessSubject(row.id).then(() => {
|
||||
app.$message.success('删除成功');
|
||||
loadData();
|
||||
})
|
||||
)
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 页数
|
||||
const currentChange = (current) => {
|
||||
state.query.current = current;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 条数
|
||||
const sizeChange = (size) => {
|
||||
state.query.size = size;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const searchChange = (params, done) => {
|
||||
if (done) done();
|
||||
state.query = params;
|
||||
state.query.current = 1;
|
||||
loadData();
|
||||
};
|
||||
|
||||
// 刷新
|
||||
const refreshChange = () => {
|
||||
loadData();
|
||||
app.$message.success('刷新成功');
|
||||
};
|
||||
|
||||
// 选择
|
||||
const selectionChange = (rows) => {
|
||||
state.selection = rows;
|
||||
};
|
||||
|
||||
const handleIds = () => {
|
||||
let datalist = state.selection.map((m) => {
|
||||
return { landId: m.landId, landName: m.landName };
|
||||
});
|
||||
|
||||
let selectIdlist = uniqueObjects(datalist, 'landId');
|
||||
let selectIdsVal = selectIdlist.map((n) => {
|
||||
return n.landId;
|
||||
});
|
||||
|
||||
return selectIdsVal.toString() || '';
|
||||
};
|
||||
|
||||
function uniqueObjects(arr, key) {
|
||||
return arr.reduce((acc, current) => {
|
||||
const duplicate = acc.find((element) => element[key] === current[key]);
|
||||
if (!duplicate) {
|
||||
acc.push(current);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
// 新增
|
||||
const rowSave = (row, done, loading) => {
|
||||
saveBusinessSubject(row)
|
||||
.then(() => {
|
||||
app.$message.success('添加成功');
|
||||
done();
|
||||
loadData();
|
||||
})
|
||||
.catch((e) => app.$message.error(e.msg))
|
||||
.finally(() => loading());
|
||||
};
|
||||
|
||||
const rowUpdate = (row, index, done, loading) => {
|
||||
console.info('更新');
|
||||
editBusinessSubject(row)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('更新成功!');
|
||||
done();
|
||||
loadData();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
loading();
|
||||
});
|
||||
};
|
||||
|
||||
const onBatchDel = () => {
|
||||
let ids = handleIds();
|
||||
if (!ids.length || ids.length <= 0) {
|
||||
return app.$message.error('请先选择要删除的数据');
|
||||
}
|
||||
};
|
||||
</script>
|
@ -38,7 +38,7 @@ const res = [
|
||||
name: `1号基地`,
|
||||
area: 100,
|
||||
status: 1,
|
||||
location: '东经 92°45′至 99°23′,北纬 20°27′至 18°35′F',
|
||||
location: '99°24\'31.280"E, 23°31\'39.990"N',
|
||||
type: 1,
|
||||
p1: 1,
|
||||
p2: 100,
|
||||
@ -52,7 +52,7 @@ const res = [
|
||||
name: `2号基地`,
|
||||
area: 211,
|
||||
status: 1,
|
||||
location: '东经 92°44′至 99°24′,北纬 20°23′至 18°31′F',
|
||||
location: '99°23\'56.224"E, 23°32\'8.225"N',
|
||||
type: 1,
|
||||
p1: 1,
|
||||
p2: 120,
|
||||
@ -66,7 +66,7 @@ const res = [
|
||||
name: `3号基地`,
|
||||
area: 121,
|
||||
status: 1,
|
||||
location: '东经 92°43′至 99°25′,北纬 20°21′至 18°31′F',
|
||||
location: '99°25\'32.574"E, 23°38\'23.701"N',
|
||||
type: 1,
|
||||
p1: 1,
|
||||
p2: 56,
|
||||
@ -80,7 +80,7 @@ const res = [
|
||||
name: `4号基地`,
|
||||
area: 231,
|
||||
status: 2,
|
||||
location: '东经 92°42′至 99°26′,北纬 21°20′至 18°32′F',
|
||||
location: '99°25\'19.027"E, 23°31\'59.693"N',
|
||||
type: 2,
|
||||
p1: 2,
|
||||
p2: 145,
|
||||
@ -94,7 +94,7 @@ const res = [
|
||||
name: `5号基地`,
|
||||
area: 231,
|
||||
status: 2,
|
||||
location: '东经 92°43′至 99°26′,北纬 21°21′至 18°22′F',
|
||||
location: '99°30\'50.886"E, 23°37\'14.542"N',
|
||||
type: 2,
|
||||
p1: 2,
|
||||
p2: 145,
|
||||
@ -177,6 +177,9 @@ const state = reactive({
|
||||
message: '请输入',
|
||||
trigger: 'blur',
|
||||
},
|
||||
formatter: (row) => {
|
||||
return row.location.replace(',', '\n'); // 将空格替换为换行
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '土壤类型',
|
||||
|
Loading…
x
Reference in New Issue
Block a user