850 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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

<template>
<div>
<el-card shadow="hover">
<QueryForm
v-model="searchForm"
:fields="searchFields"
@search="onSearch"
@reset="onReset"
:label-width="'140px'"
ref="queryFormRef"
/>
<el-row :gutter="10" style="padding-bottom: 10px">
<el-col :span="1.5">
<el-button
type="primary"
@click="handleAdd"
v-auth="'api/v1/businesses/speciesSurvey/add'"
><el-icon><ele-Plus /></el-icon>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
:disabled="multiple"
@click="handleDelete(null)"
v-auth="'api/v1/businesses/speciesSurvey/delete'"
><el-icon><ele-Delete /></el-icon>删除</el-button
>
</el-col>
</el-row>
<ProTable
v-if="columns.length > 0"
ref="proTableRef"
:columns="columns"
:data="tableData.data"
:loading="loading"
:show-selection="true"
@selection-change="handleSelectionChange"
:heightOffset="400"
:action-width="280"
@cell-click="handleCellClick"
>
<template #actions="{ row }">
<el-button
type="primary"
@click="handleUpdate(row)"
size="small"
v-auth="'api/v1/businesses/speciesSurvey/edit'"
v-if="row.auditStatus != 1"
><el-icon><ele-EditPen /></el-icon>修改</el-button
>
<el-button
type="danger"
size="small"
@click="handleDelete(row)"
v-auth="'api/v1/businesses/speciesSurvey/delete'"
><el-icon><ele-DeleteFilled /></el-icon>删除</el-button
>
<el-button
type="warning"
size="small"
@click="handleAudit(row)"
v-if="row.auditStatus == 0"
v-auth="'api/v1/businesses/speciesSurvey/audit'"
><el-icon><ele-Check /></el-icon>审核</el-button
>
</template>
</ProTable>
<pagination
v-show="tableData.total > 0"
:total="tableData.total"
v-model:page="tableData.param.pageNum"
v-model:limit="tableData.param.pageSize"
@pagination="speciesNameList"
/>
</el-card>
<ModalForm
v-model:visible="showDialog"
:title="formTitle"
:fields="formFields"
v-model:modelValue="formData"
:type="formType"
:show-footer="true"
:label-width="'150px'"
:width="'50%'"
@submit="handleFormSubmit"
@cancel="handleCancel"
ref="modalFormRef"
>
</ModalForm>
<AuditForm
ref="auditFormRef"
v-model="showAuditDialog"
title="审核数据"
@submit="onAuditSubmit"
/>
<ImagesPreview ref="imgsPreviewRef" />
</div>
</template>
<script setup lang="ts">
import { toRefs, reactive, onMounted, ref, computed ,defineAsyncComponent} from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { reqAdd, reqAudit, reqDel, reqEdit, reqList } from './api';
import { Columns, InfoData, State } from '/@/views/businesses/speciesSurvey/type';
import { baseURL } from '/@/utils/gfast';
const ImagesPreview = defineAsyncComponent(() => import('/@/components/imgsPreview/index.vue'));
import QueryForm from '/@/components/dynamicpage/queryForm/index.vue';
import ProTable from '/@/components/dynamicpage/ProTable/index.vue';
import ModalForm from '/@/components/dynamicpage/modalForm/index.vue';
import AuditForm from '/@/components/dynamicpage/auditForm/index.vue';
import { QueryFormField, TableColumn, PopupFormField } from '/@/components/dynamicpage/type';
import { getUserList } from '/@/api/system/user/index';
import { UserItem, VersionMap } from '/@/types';
import { parseTime } from '/@/utils/gfast';
import { cloneDeep } from 'lodash';
import { listSpeciesName } from '../speciesName/api';
import { SpeciesNameInfoData } from '../speciesName/type';
defineOptions({ name: 'BusinessesSpeciesSurveyList' });
const loading = ref(false);
// 非单个禁用
const single = ref(true);
// 非多个禁用
const multiple = ref(true);
const userOptions = ref<UserItem[]>([]);
const state = reactive<State>({
ids: [],
tableData: {
data: [],
total: 0,
loading: false,
param: {
pageNum: 1,
pageSize: 10,
},
},
});
const versionMap = ref<VersionMap>({} as VersionMap);
const proTableRef = ref();
const { tableData } = toRefs(state);
const columns: TableColumn[] = [
{ label: '调查记录编码', prop: 'speciesCode', minWidth: 140 },
{ label: '物种名称', prop: 'speciesName', minWidth: 100 },
{ label: '省(自治区、直辖市)', prop: 'province', minWidth: 160 },
{ label: '市(地、州、盟)', prop: 'city', minWidth: 140 },
{ label: '县(区、市、旗)', prop: 'county', minWidth: 140 },
{ label: '区划代码', prop: 'code', minWidth: 100 },
{ label: '踏查路线名称', prop: 'courseName', minWidth: 120 },
{ label: '踏查总面积(平方千米)', prop: 'markArea', minWidth: 160 },
{ label: '踏查点名称', prop: 'markName', minWidth: 100 },
{ label: '经度', prop: 'longitude', minWidth: 100 },
{ label: '纬度', prop: 'dimensionality', minWidth: 100 },
{ label: '海拔', prop: 'elevation', minWidth: 100 },
{ label: '温度', prop: 'temperature', minWidth: 100 },
{ label: '降水', prop: 'precipitation', minWidth: 100 },
{ label: '踏查点面积(亩)', prop: 'markAreaM', minWidth: 120 },
{ label: '生境类型', prop: 'habitatType', minWidth: 100 },
{ label: '土壤类型', prop: 'soilType', minWidth: 100 },
{ label: '危害对象', prop: 'harmObject', minWidth: 100 },
{ label: '发生面积(亩)', prop: 'happenArea', minWidth: 120 },
{ label: '治理措施(有 无)', prop: 'treatment', minWidth: 140 },
{
label: '是否设置标准样地',
prop: 'isStandard',
minWidth: 140,
isFormater: true,
formater(row, column, cellValue, index) {
return cellValue == 0 ? '否' : '是';
},
},
{ label: '标准样地编号', prop: 'standardCode', minWidth: 140 },
{
label: '是否采集标本',
prop: 'isSpecimen',
minWidth: 140,
isFormater: true,
formater(row, column, cellValue, index) {
return cellValue == 0 ? '否' : '是';
},
},
{ label: '标本编号', prop: 'specimenCode', minWidth: 100 },
{
label: '图片',
prop: 'img',
minWidth: 100,
isFormater: true,
formater(row, column, cellValue, index) {
const files = cellValue && typeof cellValue === 'string' ? JSON.parse(cellValue) : cellValue;
return files
.map((i: any) => {
return i.name;
})
.join(` , `);
},
},
{ label: '数据来源', prop: 'sourcesData', minWidth: 100 },
{
label: '数据采集人',
prop: 'createUser',
isFormater: true,
minWidth: 100,
formater(row, column, cellValue, index) {
const user = userOptions.value.find((i) => i.id === cellValue);
return user ? user.userNickname : '';
},
},
{
label: '数据采集日期',
minWidth: 120,
prop: 'createDate',
isFormater: true,
formater(_, col: any, val: string) {
return parseTime(val, '{y}-{m}-{d}');
},
},
{
label: '数据核查人',
prop: 'auditUser',
minWidth: 100,
isFormater: true,
formater(row, column, cellValue, index) {
const user = userOptions.value.find((i) => i.id === cellValue);
return user ? user.userNickname : '';
},
},
{
label: '数据核查日期',
prop: 'auditDate',
minWidth: 120,
isFormater: true,
formater(_, col: any, val: string) {
return parseTime(val, '{y}-{m}-{d}');
},
},
{
label: '状态',
prop: 'auditStatus',
minWidth: 100,
isFormater: true,
formater(row, column, cellValue, index) {
return cellValue == 0 ? '待审核' : cellValue == 1 ? '通过' : '不通过';
},
},
{ label: '核查意见', prop: 'auditView', minWidth: 100 },
{ label: '备注', prop: 'remark', minWidth: 100 },
];
const onSearch = async (val: Record<string, any>) => {
let newVal: Record<string, any> = {};
for (const v in val) {
if (val[v] || val[v] === 0) {
newVal[v] = val[v];
}
}
state.tableData.param = { ...state.tableData.param, ...newVal };
speciesNameList();
};
const onReset = () => {
state.tableData.param = {
pageNum: 1,
pageSize: 10,
};
speciesNameList();
};
const searchForm = ref<Partial<InfoData>>({
speciesCode: undefined,
province: undefined,
city: undefined,
county: undefined,
code: undefined,
courseName: undefined,
markName: undefined,
habitatType: undefined,
soilType: undefined,
speciesName: undefined,
standardCode: undefined,
specimenCode: undefined,
sourcesData: undefined,
createUser: undefined,
harmObject: undefined,
});
const searchFields = computed<QueryFormField[]>(() => [
{
label: '调查记录编码',
prop: 'speciesCode',
type: 'input',
placeholder: '请输入调查记录编码',
},
{
label: '省(自治区、直辖市)',
prop: 'province',
type: 'input',
placeholder: '请输入省(自治区、直辖市)',
},
{
label: '市(地、州、盟)',
prop: 'city',
type: 'input',
placeholder: '请输入市(地、州、盟)',
},
{ label: '县(区、市、旗)', prop: 'county', type: 'input', placeholder: '请输入县(区、市、旗)' },
{ label: '区划代码', prop: 'code', type: 'input', placeholder: '请输入区划代码' },
{ label: '踏查路线名称', prop: 'courseName', type: 'input', placeholder: '请输入踏查路线名称' },
{ label: '踏查点名称', prop: 'markName', type: 'input', placeholder: '请输入踏查点名称' },
{ label: '生境类型', prop: 'habitatType', type: 'input', placeholder: '请输入生境类型' },
{ label: '土壤类型', prop: 'soilType', type: 'input', placeholder: '请输入土壤类型' },
{ label: '物种名称', prop: 'speciesName', type: 'input', placeholder: '请输入物种名称' },
{ label: '标准样地编号', prop: 'standardCode', type: 'input', placeholder: '请输入标准样地编号' },
{ label: '标本编号', prop: 'specimenCode', type: 'input', placeholder: '请输入标本编号' },
{ label: '数据来源', prop: 'sourcesData', type: 'input', placeholder: '请输入数据来源' },
{ label: '危害对象', prop: 'harmObject', type: 'input', placeholder: '请输入危害对象' },
{
label: '数据采集人',
prop: 'createUser',
type: 'select',
options: userOptions.value.map((i) => {
return {
label: i.userNickname,
value: i.id,
};
}),
placeholder: '请选择数据采集人',
},
]);
const specieslist = ref<SpeciesNameInfoData[]>([]);
/**获取物种列表 */
const reqListSpeciesName = async () => {
if (userOptions.value.length > 0) return;
const res = await listSpeciesName({ pageSize: 9999, pageNum: 1 });
specieslist.value = res.data.list;
};
// 页面加载时
onMounted(() => {
initTableData();
reqListSpeciesName();
});
// 初始化表格数据
const initTableData = () => {
speciesNameList();
reqGetUserList();
};
// 获取列表数据
const speciesNameList = async () => {
loading.value = true;
const res = await reqList(state.tableData.param);
let list = res.data.list ?? [];
state.tableData.data = list;
versionMap.value = list.reduce((acc: any, cur: any) => {
acc[cur.id] = cur.version;
return acc;
}, {});
state.tableData.total = res.data.total;
loading.value = false;
};
const reqGetUserList = async () => {
if (userOptions.value.length > 0) return;
const res = await getUserList({ pageSize: 9999, pageNum: 1 });
userOptions.value = res.data.userList;
};
// 多选框选中数据
const handleSelectionChange = (selection: Array<InfoData>) => {
state.ids = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
const imgsPreviewRef = ref();
const handleCellClick = (row: InfoData, col: any) => {
if (col.property != 'img') return;
const { img } = row;
const files = img && JSON.parse(img);
imgsPreviewRef.value.openDialog(files);
};
const showDialog = ref(false);
const formTitle = ref('');
const formFields = computed<PopupFormField[]>(() => [
{
label: '调查记录编码',
prop: 'speciesCode',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入调查记录编码', trigger: 'blur' }],
componentProps: {
placeholder: '请选择调查记录编码',
},
},
{
label: '物种名称',
prop: 'speciesName',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入物种名称', trigger: 'blur' }],
componentProps: {
placeholder: '请输入物种名称',
},
},
{
label: '省(自治区、直辖市)',
prop: 'province',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入省(自治区、直辖市)', trigger: 'blur' }],
componentProps: {
placeholder: '请输入省(自治区、直辖市)',
},
},
{
label: '市(地、州、盟)',
prop: 'city',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入市(地、州、盟)', trigger: 'blur' }],
componentProps: {
placeholder: '请输入市(地、州、盟)',
},
},
{
label: '县(区、市、旗)',
prop: 'county',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入县(区、市、旗)', trigger: 'blur' }],
componentProps: {
placeholder: '请输入县(区、市、旗)',
},
},
{
label: '区划代码',
prop: 'code',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入区划代码', trigger: 'blur' }],
componentProps: {
placeholder: '请输入区划代码',
},
},
{
label: '踏查路线名称',
prop: 'courseName',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入踏查路线名称', trigger: 'blur' }],
componentProps: {
placeholder: '请输入踏查路线名称',
},
},
{
label: '踏查总面积',
prop: 'markArea',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入踏查总面积(平方千米)', trigger: 'blur' }],
componentProps: {
placeholder: '请输入踏查总面积(平方千米)',
},
},
{
label: '踏查点名称',
prop: 'markName',
type: 'input',
span: 12,
componentProps: {
placeholder: '请输入踏查点名称',
},
rules: [{ required: true, message: '请输入踏查点名称', trigger: 'blur' }],
},
{
label: '经度',
prop: 'longitude',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入经度', trigger: 'blur' }],
componentProps: {
placeholder: '请输入经度',
},
},
{
label: '纬度',
prop: 'dimensionality',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入纬度', trigger: 'blur' }],
componentProps: {
placeholder: '请输入纬度',
},
},
{
label: '海拔',
prop: 'elevation',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入海拔', trigger: 'blur' }],
componentProps: {
placeholder: '请输入海拔',
},
},
{
label: '气温',
prop: 'temperature',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入气温', trigger: 'blur' }],
componentProps: {
placeholder: '请输入气温',
},
},
{
label: '降水量',
prop: 'precipitation',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入降水量', trigger: 'blur' }],
componentProps: {
placeholder: '请输入降水量',
},
},
{
label: '踏查点面积(亩)',
prop: 'markAreaM',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入踏查点面积(亩)', trigger: 'blur' }],
componentProps: {
placeholder: '请输入踏查点面积(亩)',
},
},
{
label: '生境类型',
prop: 'habitatType',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入生境类型', trigger: 'blur' }],
componentProps: {
placeholder: '请输入生境类型',
},
},
{
label: '土壤类型',
prop: 'soilType',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入土壤类型', trigger: 'blur' }],
componentProps: {
placeholder: '请输入土壤类型',
},
},
{
label: '危害对象',
prop: 'harmObject',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入危害对象', trigger: 'blur' }],
componentProps: {
placeholder: '请输入危害对象',
},
},
{
label: '发生面积(亩)',
prop: 'happenArea',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入发生面积(亩)', trigger: 'blur' }],
componentProps: {
placeholder: '请输入发生面积(亩)',
},
},
{
label:'治理措施',
prop: 'treatment',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入治理措施(有 无)', trigger: 'blur' }],
componentProps: {
placeholder: '请输入治理措施(有 无)',
},
},
{
label: '是否设置标准样地',
prop: 'isStandard',
type: 'radio',
span: 12,
rules: [{ required: true, message: '请输入是否设置标准样地', trigger: 'change' }],
options: [
{ label: '是', value: 1 },
{ label: '否', value: 0 },
],
},
{
label: '标准样地编号',
prop: 'standardCode',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入标准样地编号', trigger: 'blur' }],
componentProps: {
placeholder: '请输入标准样地编号',
},
},
{
label:"是否采集标本",
prop: 'isSpecimen',
type: 'radio',
span: 12,
rules: [{ required: true, message: '请输入是否采集标本', trigger: 'change' }],
options: [
{ label: '是', value: 1 },
{ label: '否', value: 0 },
],
},
{
label: '标本编号',
prop: 'specimenCode',
type: 'input',
span: 12,
rules: [{ required: true, message: '请输入标本编号', trigger: 'blur' }],
componentProps: {
placeholder: '请输入标本编号',
},
},
{
label: '图片',
prop: 'img',
type: 'upload',
span: 24,
componentProps: {
action: baseURL + 'api/v1/system/upload/singleImg',
limit: 3,
accept: '.jpg,.jpeg,.png,.gif',
uploadSize: 5, // 文件大小限制单位MB
listType: 'picture-card',
},
},
{
label: '数据来源',
prop: 'sourcesData',
span: 24,
type: 'input',
rules: [{ required: true, message: '请输入数据来源', trigger: 'blur' }],
componentProps: {
placeholder: '请输入数据来源',
},
},
{
label: '数据采集人',
span: 12,
prop: 'createUser',
type: 'select',
rules: [{ required: true, message: '请选择数据采集人', trigger: 'change' }],
componentProps: {
placeholder: '请选择数据采集人',
},
options: userOptions.value.map((i) => {
return {
label: i.userNickname,
value: i.id,
};
}),
},
{
label: '数据采集日期',
span: 12,
prop: 'createDate',
type: 'date',
rules: [{ required: true, message: '请选择数据采集日期', trigger: 'change' }],
componentProps: {
style: 'width: 100%',
placeholder: '请选择数据采集日期',
},
},
{
label: '备注',
prop: 'remark',
span: 24,
type: 'input',
componentProps: {
placeholder: '请输入备注',
type: 'textarea',
},
},
]);
const formData = ref<InfoData>({
id: undefined,
speciesCode: undefined,
province: undefined,
city: undefined,
county: undefined,
code: undefined,
courseName: undefined,
markArea: undefined,
markName: undefined,
longitude: undefined,
dimensionality: undefined,
elevation: undefined,
temperature: undefined,
precipitation: undefined,
markAreaM: undefined,
habitatType: undefined,
soilType: undefined,
speciesName: undefined,
harmObject: undefined,
happenArea: undefined,
treatment: undefined,
isStandard: undefined,
standardCode: undefined,
img: undefined,
sourcesData: undefined,
createUser: undefined,
createDate: undefined,
auditUser: undefined,
auditDate: undefined,
auditView: undefined,
auditStatus: undefined,
remark: undefined,
version: undefined,
isSpecimen: undefined,
specimenCode: undefined,
});
const formType = ref<'add' | 'edit'>('add');
const handleFormSubmit = (form: InfoData) => {
if (formType.value === 'add') {
reqAdd(form).then(() => {
ElMessage.success('新增成功');
handleCancel();
speciesNameList();
});
} else {
form.auditStatus = 0;
reqEdit(form).then(() => {
ElMessage.success('编辑成功');
handleCancel();
speciesNameList();
});
}
};
const handleCancel = () => {
showDialog.value = false;
formTitle.value = '';
formType.value = 'add';
formData.value = {
id: undefined,
speciesCode: undefined,
province: undefined,
city: undefined,
county: undefined,
code: undefined,
courseName: undefined,
markArea: undefined,
markName: undefined,
longitude: undefined,
dimensionality: undefined,
elevation: undefined,
temperature: undefined,
precipitation: undefined,
markAreaM: undefined,
habitatType: undefined,
soilType: undefined,
speciesName: undefined,
harmObject: undefined,
happenArea: undefined,
treatment: undefined,
isStandard: undefined,
standardCode: undefined,
img: undefined,
sourcesData: undefined,
createUser: undefined,
createDate: undefined,
auditUser: undefined,
auditDate: undefined,
auditView: undefined,
auditStatus: undefined,
remark: undefined,
version: undefined,
isSpecimen: undefined,
specimenCode: undefined,
};
};
const handleAdd = () => {
showDialog.value = true;
formTitle.value = '新增物种调查';
formType.value = 'add';
};
const handleUpdate = (row: InfoData) => {
showDialog.value = true;
formTitle.value = '编辑物种调查';
formType.value = 'edit';
formData.value = cloneDeep(row);
formData.value.img = JSON.parse(row.img as any);
};
const handleDelete = (row: Columns | null) => {
let msg = '你确定要删除所选数据?';
let id: number[] = [];
if (row) {
msg = `此操作将永久删除数据,是否继续?`;
id = [row.id];
} else {
id = state.ids;
}
if (id.length === 0) {
ElMessage.error('请选择要删除的数据。');
return;
}
ElMessageBox.confirm(msg, '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
reqDel(
id,
id.map((i) => versionMap.value[i])
).then(() => {
ElMessage.success('删除成功');
speciesNameList();
});
})
.catch(() => {});
};
const auditFormRef = ref();
const showAuditDialog = ref(false);
const handleAudit = (row: Columns) => {
const val = cloneDeep(row);
val.auditUser = '';
auditFormRef.value.open(val, userOptions.value);
};
const onAuditSubmit = (val: Columns) => {
reqAudit(val).then(() => {
ElMessage.success('审核成功');
showAuditDialog.value = false;
speciesNameList();
});
};
</script>