2025-03-27 15:56:05 +08:00

606 lines
15 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>
<section class="custom-page">
<h2>农药基本信息</h2>
<TypeMenu v-if="materialTypes[1].length > 1" v-model:type="_type" :types="materialTypes['1']" />
<br />
<avue-crud
ref="crud"
v-model:page="pageData"
v-model:search="searchCondition"
:table-loading="_loading"
:data="data"
:option="option"
:before-close="handleCloseDialog"
@search-change="
(form, done) => {
getData(1);
done();
}
"
@search-reset="getData(1)"
@refresh-change="getData"
@current-change="getData"
@size-change="getData(1)"
@row-save="handleRowSave"
@row-update="handleRowUpdate"
>
<template #menu="{ row }">
<el-button type="primary" @click="handleEdit(row)">上传报告</el-button>
<el-button @click="handleInfo(row)">详情</el-button>
</template>
<template #photoUrl-form="{ type }">
<Attrs v-model:attrs="attrs" :type="type == 'add' ? 'add' : 'view'" :limit="2" />
</template>
<template #checkInfo-form="{ row }">
<section style="text-align: center; line-height: 58px">
<el-button @click="handleCheckInfo('open')">查看报告</el-button>
</section>
</template>
<template #detectionReport-form="{ type }">
<Attrs v-model:attrs="reportAttrs" :type="type" :up-btn="reportAttrs.length < 1" :file-num="reportAttrs.length > 0 ? 1 : 3" :limit="2" />
</template>
<template #productSpecification-form="{ value, type }">
<NumberSelect v-if="type == 'add'" v-model:value="productSpecification" :options="goodsUnitOptions" />
<span v-if="type == 'view'">{{ value }}</span>
</template>
<template #dosage-form="{ value, type }">
<NumberSelect v-if="type == 'add'" v-model:value="useDosage" :options="useDosageUnit" />
<span v-if="type == 'view'">{{ value }}</span>
</template>
<template #checkBtn-form>
<section style="text-align: center; line-height: 58px">
<el-button @click="handleCheckInfo('close')">关闭</el-button>
</section>
</template>
</avue-crud>
</section>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
import TypeMenu from '../../common/TypeMenu.vue';
import { CRUD_OPTIONS, customRules } from '@/config';
import { useBasicInfo } from '@/views/inputSuppliesManage/hooks/useBasicInfo';
import Attrs from '@/views/inputSuppliesManage/common/Attrs.vue';
import NumberSelect from '@/views/inputSuppliesManage/common/NumberSelect.vue';
import inputSuppliesApi from '@/apis/inputSuppliesApi';
import { ElMessage } from 'element-plus';
const { defaultGet, loadFinish, materialTypes, materialTwoLevel, goodsUnitOptions, useDosageUnit, targetName, filterTypes } = useBasicInfo({
moduleType: '1',
});
const { getPesticideList, addPesticide, pesticideReportSave } = inputSuppliesApi;
/* --------------- data --------------- */
// #region
const _type = ref('0');
watch(
() => _type.value,
() => getData(1),
{
deep: true,
}
);
const searchCondition = ref({
keywords: '',
});
const crud = ref();
const _loading = ref(true);
const data = ref([]);
const pageData = ref({
total: 0,
currentPage: 1,
size: 10,
});
const dicDatas = ref({
_targetPests: {
one: '1',
two: '1',
dic: [],
},
_mainComponent: {
one: '1',
two: '2',
dic: [],
},
_produceDosage: {
one: '1',
two: '3',
dic: [],
},
});
const option = ref({
...CRUD_OPTIONS,
selection: false,
labelWidth: 124,
editBtn: false,
delBtn: false,
menuWidth: 220,
dialogWidth: '60%',
editBtnText: '上传报告',
column: [
{
hide: true,
label: '关键字',
prop: 'keywords',
search: true,
addDisplay: false,
editDisplay: false,
searchPlaceholder: '输入肥料名称',
viewDisplay: false,
},
// {
// prop: 'id',
// label: '农药编号',
// addDisplay: false,
// editDisplay: false,
// },
{
prop: 'pesticideName',
label: '名称',
width: '120',
editDisplay: false,
rules: customRules({ msg: '请输入农药名称' }),
},
{
hide: true,
prop: 'productStandCode',
label: '产品标准证号',
width: '120',
viewDisplay: false,
editDisplay: false,
rules: customRules({ msg: '请输入产品标准证号' }),
},
{
hide: true,
prop: 'photoUrl',
label: '农药图片',
span: 24,
editDisplay: false,
},
{
hide: true,
prop: 'pesticideRegistCode',
label: '农药登记证号',
width: '120',
viewDisplay: false,
editDisplay: false,
rules: customRules({ msg: '请输登记证号' }),
},
{
prop: 'manufacturer',
label: '生产厂家',
width: '120',
editDisplay: false,
rules: customRules({ msg: '请输入生产厂家' }),
},
{
prop: 'distributor',
width: '120',
label: '经销商',
editDisplay: false,
},
{
prop: 'productSpecification',
width: '100',
label: '产品规格',
editDisplay: false,
},
{
prop: 'toxicityLevel',
width: '100',
label: '毒性',
editDisplay: false,
value: '无毒',
},
{
prop: 'dosage',
width: '100',
label: '建议用量',
editDisplay: false,
},
{
prop: 'expiryDate',
label: '保质期',
addDisplay: false,
editDisplay: false,
},
{
prop: 'targetPests',
width: '200',
label: '防治对象',
addDisplay: false,
editDisplay: false,
},
{
prop: 'mainComponent',
width: '200',
label: '化学成分',
addDisplay: false,
editDisplay: false,
},
{
prop: 'produceDosage',
width: '200',
label: '加工剂型',
addDisplay: false,
editDisplay: false,
},
{
hide: true,
prop: '_targetPests',
label: '防治对象',
type: 'cascader',
multiple: true,
dicData: [],
value: [],
span: 24,
viewDisplay: false,
editDisplay: false,
rules: customRules({ msg: '请选择防治对象' }),
},
{
hide: true,
prop: '_mainComponent',
label: '化学成分',
type: 'cascader',
multiple: true,
dicData: [],
value: [],
span: 24,
viewDisplay: false,
editDisplay: false,
rules: customRules({ msg: '请选择主要成分' }),
},
{
hide: true,
prop: '_produceDosage',
label: '加工剂型',
type: 'cascader',
multiple: true,
dicData: [],
value: [],
span: 24,
viewDisplay: false,
editDisplay: false,
rules: customRules({ msg: '加工剂型' }),
},
{
hide: true,
prop: 'usageMethod',
label: '使用方法',
type: 'textarea',
span: 24,
viewDisplay: false,
editDisplay: false,
},
{
hide: true,
prop: 'precautions',
label: '注意事项',
type: 'textarea',
span: 24,
viewDisplay: false,
editDisplay: false,
},
{
labelWidth: 0,
border: false,
prop: 'checkInfo',
span: 24,
addDisplay: false,
editDisplay: false,
},
],
group: [
{
label: '农药基本信息',
prop: 'basic_info',
addDisplay: false,
viewDisplay: false,
column: [
{
prop: 'pesticideName',
label: '农药名称',
editDisabled: true,
span: 24,
},
{
prop: 'manufacturer',
label: '生产商',
editDisabled: true,
span: 24,
},
{
prop: 'distributor',
label: '经销商',
editDisabled: true,
span: 24,
},
{
prop: 'photoUrl',
label: '农药图片',
editDisabled: true,
span: 24,
},
],
},
{
label: '农药检测信息',
prop: 'check_info',
addDisplay: false,
viewDisplay: false,
column: [
{
prop: 'detectionTime',
label: '检测时间',
type: 'date',
valueFormat: 'YYYY-MM-DD',
rules: customRules({ msg: '请选择检测时间' }),
},
{
prop: 'detectionResult',
label: '检测结果',
type: 'select',
clearable: false,
rules: customRules({ msg: '请选择检测结果' }),
dicData: [
{ value: '0', label: '合格' },
{ value: '1', label: '不合格' },
],
value: '0',
},
{
prop: 'detectionUnit',
label: '检测单位',
rules: customRules({ msg: '请输入检测单位' }),
},
{
prop: 'detectionConclusion',
label: '检测结论',
rules: customRules({ msg: '请输入检测结论' }),
},
{
prop: 'detectionReport',
label: '质检报告',
span: 24,
rules: [
{
required: true,
trigger: ['blur', 'change'],
validator: (rule, value, callback) => {
if (!reportAttrs.value.length) {
callback(new Error('请上传检测报告'));
} else {
callback();
}
},
},
],
},
{
labelWidth: 0,
prop: 'checkBtn',
span: 24,
editDisplay: false,
},
],
},
],
});
watch(
() => loadFinish.value,
() => {
if (loadFinish.value) {
for (let key in dicDatas.value) {
option.value.column.forEach((item) => {
if (item.prop === key) {
let dic = materialTwoLevel?.[dicDatas.value[key].one]?.[dicDatas.value[key].two] ?? [];
dicDatas.value[key].dic = dic;
item.dicData = dic;
}
});
}
}
}
);
const attrs = ref([]);
const reportAttrs = ref([]);
const productSpecification = ref({
num: 1,
type: '1',
});
const useDosage = ref({
num: 1,
type: '1',
});
// #endregion
/* --------------- methods --------------- */
// #region
defaultGet(getData);
async function getData(reset) {
_loading.value = true;
reset == 1 && (pageData.value.currentPage = 1);
let params = {
current: pageData.value.currentPage,
size: pageData.value.size,
pesticideName: searchCondition.value.keywords,
};
_type.value != '0' && (params.classifyId = _type.value);
let res = await getPesticideList(params);
console.log('res --- ', res);
_loading.value = false;
if (res && res.code === 200) {
data.value = res.data.records;
data.value.forEach((v) => {
v.productSpecification = `${v.productSpecification}${goodsUnitOptions.find((_v) => _v.value == v.productUnit).label}`;
v.dosage = `${v.suggestDosage}${useDosageUnit.find((_v) => _v.value == v.suggestUnit).label}`;
v.targetPests = handleShowName(v.targetPests);
v.mainComponent = handleShowName(v.mainComponent);
v.produceDosage = handleShowName(v.produceDosage);
});
pageData.value.total = res.data.total;
}
}
function handleCloseDialog(done) {
delete option.value.column[1].span;
resetOtherInfo();
handleCheckInfoChange();
done();
}
async function handleRowSave(form, done, loading) {
let data = {
pesticideName: form.pesticideName,
productStandCode: form.productStandCode,
pesticideRegistCode: form.pesticideRegistCode,
manufacturer: form.manufacturer,
distributor: form.distributor,
toxicityLevel: form.toxicityLevel,
usageMethod: form.usageMethod,
precautions: form.precautions,
expiryDate: form.expiryDate,
productSpecification: productSpecification.value.num,
productUnit: productSpecification.value.type,
suggestDosage: useDosage.value.num,
suggestUnit: useDosage.value.type,
};
if (attrs.value.length) {
data.photoUrl = attrs.value.map((v) => v.url).join();
}
if (form._targetPests.length) {
let names = [];
form._targetPests.forEach((item) => {
names.push(targetName(dicDatas.value._targetPests.dic, item, ''));
});
data.targetPests = JSON.stringify(form._targetPests) + '|' + JSON.stringify(names);
}
if (form._mainComponent.length) {
let names = [];
form._mainComponent.forEach((item) => {
names.push(targetName(dicDatas.value._mainComponent.dic, item, ''));
});
data.mainComponent = JSON.stringify(form._mainComponent) + '|' + JSON.stringify(names);
}
if (form._produceDosage.length) {
let names = [];
form._produceDosage.forEach((item) => {
names.push(targetName(dicDatas.value._produceDosage.dic, item, ''));
});
data.produceDosage = JSON.stringify(form._produceDosage) + '|' + JSON.stringify(names);
}
let res = await addPesticide(data);
loading();
if (res.code == 200) {
ElMessage.success('保存成功');
getData();
resetOtherInfo();
done();
}
}
function resetOtherInfo() {
let obj = { num: 1, type: '1' };
attrs.value = [];
reportAttrs.value = [];
productSpecification.value = obj;
useDosage.value = obj;
}
function handleEdit(row) {
handleAttrs(row);
option.value.group[1].column[0].value = row.detectionTime;
option.value.group[1].column[1].value = row.detectionResult;
option.value.group[1].column[2].value = row.detectionUnit;
option.value.group[1].column[3].value = row.detectionConclusion;
handleCheckInfoChange('open');
crud.value.rowEdit(row);
}
function handleInfo(row) {
handleAttrs(row);
option.value.column[1].span = 24;
crud.value.rowView(row);
}
/* 处理展示附件 */
function handleAttrs(row = {}) {
if (!row) {
return;
}
if (row.photoUrl) {
attrs.value = row.photoUrl.split(',').map((v, i) => {
return {
url: v,
uid: `photo_${i}_${Date.now()}`,
};
});
}
if (row.detectionReport) {
reportAttrs.value = row.detectionReport.split(',').map((v, i) => {
return {
url: v,
uid: `report_${i}_${Date.now()}`,
};
});
}
}
function handleCheckInfo(type) {
handleCheckInfoChange(type == 'open');
}
/* bol && 查看检测报告关闭其他信息 !bol && 关闭检测报告打开其他信息 */
function handleCheckInfoChange(bol = false) {
option.value.group.forEach((v) => {
v.viewDisplay = bol;
});
if (bol) {
option.value.column.forEach((v) => {
v.viewDisplay = false;
});
} else {
option.value.column.forEach((v) => {
if (!v.hide || v.prop == 'photoUrl') {
v.viewDisplay = true;
}
});
}
}
async function handleRowUpdate(form, index, done, loading) {
console.log('update from -- ', form);
let data = {
id: form.id,
detectionTime: form.detectionTime,
detectionResult: form.detectionResult,
detectionUnit: form.detectionUnit,
detectionConclusion: form.detectionConclusion,
detectionReport: reportAttrs.value.map((v) => v.url).join(),
};
let res = await pesticideReportSave(data);
loading();
if (res.code == 200) {
ElMessage.success('检测报告保存成功');
getData();
done();
}
}
function handleShowName(text = '') {
if (!text || !text.includes('|')) return false;
let names = JSON.parse(text.split('|')[1]);
let _t = '';
names.forEach((v, i) => {
_t += (i == 0 ? '' : '') + v;
});
return _t;
}
// #endregion
</script>
<style lang="scss" scoped>
h2 {
font-size: 24px;
font-weight: bold;
font-family: '黑体';
}
</style>