Merge remote-tracking branch 'origin/main'

This commit is contained in:
zyk 2025-09-07 12:21:45 +08:00
commit 2910577a01
32 changed files with 2141 additions and 427 deletions

View File

@ -25,7 +25,7 @@
"echarts": "5.5.1",
"element-china-area-data": "^6.1.0",
"element-plus": "^2.7.6",
"file-saver": "2.0.5",
"file-saver": "^2.0.5",
"fuse.js": "6.6.2",
"js-beautify": "1.14.11",
"js-cookie": "3.0.5",
@ -37,7 +37,8 @@
"vue-cropper": "1.1.1",
"vue-router": "4.4.0",
"vuedraggable": "4.1.0",
"vuex": "^4.0.2"
"vuex": "^4.0.2",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.0.5",

View File

@ -1,4 +1,3 @@
// src/api/dairyProducts/sheepMilkAnalysis/sheepMilkAnalysis.js
import request from '@/utils/request'
// 查询羊奶产量分析列表(分页 + 条件)
@ -16,14 +15,4 @@ export function getSheepMilkAnalysis(sheepId) {
url: '/dairyProducts/sheepMilkAnalysis/' + sheepId,
method: 'get'
})
}
// 导出羊奶产量分析 Excel
export function exportSheepMilkAnalysis(query) {
return request({
url: '/dairyProducts/sheepMilkAnalysis/export',
method: 'get',
params: query,
responseType: 'blob' // 返回二进制流
})
}
}

View File

@ -61,3 +61,12 @@ export function addByEarTags(data) {
data
})
}
// 树形分组
export const listGroupTree = () =>
request({
url: '/sheep_grouping/sheep_grouping/group/tree',
method: 'get'
})

View File

@ -55,3 +55,11 @@ export function checkSheepfoldNoExist(ranchId, sheepfoldTypeId, sheepfoldNo) {
}
})
}
// 获取树形座位图(牧场 → 类型 → 羊舍 → 排栏)
export function getSeatMap() {
return request({
url: '/sheepfold_management/sheepfold_management/seatMap',
method: 'get'
})
}

View File

@ -303,6 +303,7 @@ function reset() {
id: null,
treatId: null,
sheepId: null,
sheepNo: null,
datetime: null,
sheepType: null,
gender: null,

View File

@ -471,7 +471,7 @@ function handleDelete(row) {
}
function handleExport() {
proxy.download('biosafety/disinfect/export', { ...queryParams }, `disinfect_${Date.now()}.xlsx`)
proxy.download('biosafety/disinfect/export', { ...queryParams }, `消毒_${Date.now()}.xlsx`)
}
/* ---------- 下拉数据 ---------- */

View File

@ -490,7 +490,7 @@ function handleDelete(row) {
}
function handleExport() {
proxy.download('biosafety/deworm/export', { ...queryParams }, `deworm_${Date.now()}.xlsx`)
proxy.download('biosafety/health/export', { ...queryParams }, `保健_${Date.now()}.xlsx`)
}
/* ------------------ 药品/处方/下拉 ------------------ */

View File

@ -489,7 +489,7 @@ function handleDelete(row) {
}
function handleExport() {
proxy.download('biosafety/deworm/export', { ...queryParams }, `deworm_${Date.now()}.xlsx`)
proxy.download('biosafety/immunity/export', { ...queryParams }, `免疫_${Date.now()}.xlsx`)
}
/* ------------------ 药品/处方/下拉 ------------------ */

View File

@ -238,7 +238,7 @@ function handleDelete(row) {
}
function handleExport() {
proxy.download('system/medicine/export', { ...queryParams.value }, `medicine_${new Date().getTime()}.xlsx`)
proxy.download('system/medicine/export', { ...queryParams.value }, `药品_${new Date().getTime()}.xlsx`)
}
getList()

View File

@ -220,7 +220,7 @@ function handleDelete(row) {
function handleExport() {
proxy.download('biosafety/type/export', {
...queryParams.value
}, `type_${new Date().getTime()}.xlsx`)
}, `药品类型_${new Date().getTime()}.xlsx`)
}
getList()

View File

@ -180,7 +180,7 @@ function handleDelete(row) {
function handleExport() {
proxy.download('biosafety/unit/export', {
...queryParams.value
}, `unit_${new Date().getTime()}.xlsx`)
}, `药品计量单位_${new Date().getTime()}.xlsx`)
}
getList()

View File

@ -220,7 +220,7 @@ function handleDelete(row) {
function handleExport() {
proxy.download('biosafety/usage/export', {
...queryParams.value
}, `usage_${new Date().getTime()}.xlsx`)
}, `药品使用方法_${new Date().getTime()}.xlsx`)
}
getList()

View File

@ -504,7 +504,7 @@ function cancel() {
* 调用后端通用导出接口文件名带时间戳
*/
function handleExport() {
proxy.download('biosafety/prescription/export', { ...queryParams.value }, `prescription_${Date.now()}.xlsx`)
proxy.download('biosafety/prescription/export', { ...queryParams.value }, `处方_${Date.now()}.xlsx`)
}
//

View File

@ -527,9 +527,9 @@ function handleDelete(row) {
/* 导出 */
function handleExport() {
proxy.download(
'bisosafety/quarantine/export',
'/biosafety/quarantine/export',
queryParams,
`quarantine_${Date.now()}.xlsx`
`检疫_${Date.now()}.xlsx`
)
}

View File

@ -729,7 +729,7 @@ function handleDelete(row) {
.then(() => { getList(); proxy.$modal.msgSuccess('删除成功') })
}
function handleExport() {
proxy.download('treatment/treatment/export', { ...queryParams }, `treatment_${Date.now()}.xlsx`)
proxy.download('treatment/treatment/export', { ...queryParams }, `治疗记录_${Date.now()}.xlsx`)
}
function resetForm(formObj) {
Object.assign(formObj, {

View File

@ -342,7 +342,7 @@ function handleExport() {
proxy.download(
'biosafety/usageInfo/export',
{ ...queryParams.value },
`usage_${new Date().getTime()}.xlsx`
`药品使用记录_${new Date().getTime()}.xlsx`
)
}

View File

@ -291,6 +291,9 @@
import { ref, reactive, onMounted } from 'vue';
import { listFreshMilkTest, getFreshMilkTest, delFreshMilkTest, addFreshMilkTest, updateFreshMilkTest } from "@/api/dairyProducts/freshMilkTest/freshMilkTest.js";
import { ElMessage, ElMessageBox } from 'element-plus';
// xlsxfile-saver
import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver';
const freshMilkTestList = ref([]);
const open = ref(false);
@ -304,6 +307,27 @@ const title = ref("");
const columnShowDialogVisible = ref(false);
const freshMilkTestRef = ref(null);
//
const columnConfig = [
{ prop: 'source', label: '来源' },
{ prop: 'datetime', label: '检测日期' },
{ prop: 'fat', label: '脂肪g/100g' },
{ prop: 'protein', label: '蛋白质g/100g' },
{ prop: 'nonFat', label: '非脂g/100g' },
{ prop: 'acidity', label: '酸度oT' },
{ prop: 'bacterialColony1', label: '菌落总数1' },
{ prop: 'bacterialColony2', label: '菌落总数2' },
{ prop: 'bacterialColony3', label: '菌落总数3' },
{ prop: 'bacterialColony4', label: '菌落总数4' },
{ prop: 'bacterialColony5', label: '菌落总数5' },
{ prop: 'coli', label: '大肠菌群(CFU/ml)' },
{ prop: 'lactoferrin', label: '乳铁蛋白(mg/L)' },
{ prop: 'ig', label: '免疫球蛋白(mg/L)' },
{ prop: 'commnet', label: '备注' },
{ prop: 'createBy', label: '创建人' },
{ prop: 'createTime', label: '创建时间' }
];
//
const selectedColumns = ref([
'source', 'datetime', 'fat', 'protein', 'nonFat', 'acidity',
@ -545,17 +569,42 @@ function handleDelete(row) {
});
}
/** 导出按钮操作 */
/** 导出按钮操作 - 前端实现 */
function handleExport() {
const params = new URLSearchParams();
for (const key in queryParams) {
if (queryParams[key] !== null && queryParams[key] !== undefined) {
params.append(key, queryParams[key]);
}
}
//
const visibleColumnsConfig = columnConfig.filter(
col => selectedColumns.value.includes(col.prop)
);
const url = `/freshMilkTest/freshMilkTest/export?${params.toString()}`;
window.location.href = url;
//
const exportData = freshMilkTestList.value.map(item => {
const rowData = {};
visibleColumnsConfig.forEach(col => {
//
if (col.prop === 'datetime') {
rowData[col.label] = formatDate(item[col.prop]);
} else if (col.prop === 'createTime') {
rowData[col.label] = formatDateTime(item[col.prop]);
} else {
rowData[col.label] = item[col.prop];
}
});
return rowData;
});
// 簿
const worksheet = XLSX.utils.json_to_sheet(exportData);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, '鲜奶检验记录');
// Excel
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
// 使file-saver
saveAs(blob, `鲜奶检验记录_${new Date().getTime()}.xlsx`);
}
//

View File

@ -1,16 +1,24 @@
<!-- index.vue (前端视图修改 resetQuery 以匹配正确字段) -->
<!-- index.vue (前端视图仅保留单日查询功能) -->
<template>
<div class="app-container">
<el-form ref="queryRef" :model="queryParams" inline label-width="80px">
<el-form-item label="日期范围">
<el-date-picker v-model="dateRange" type="daterange" range-separator=""
start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" />
<!-- 单日查询 -->
<el-form-item label="查询日期">
<el-date-picker
v-model="queryDate"
type="date"
placeholder="选择查询日期"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
clearable />
</el-form-item>
<!-- 管理耳号变成输入框 -->
<!-- 管理耳号输入框 -->
<el-form-item label="管理耳号">
<el-input v-model="queryParams.manageEarNo" placeholder="请输入管理耳号" clearable />
</el-form-item>
<!-- 厂区下拉框数据源来自字典 da_ranch -->
<!-- 厂区下拉框 -->
<el-form-item label="厂区">
<el-select v-model="queryParams.factory" clearable placeholder="请选择">
<el-option
@ -20,13 +28,15 @@
:value="d.value" />
</el-select>
</el-form-item>
<!-- 班次只有 12 -->
<!-- 班次下拉框 -->
<el-form-item label="班次">
<el-select v-model="queryParams.classes" clearable placeholder="请选择">
<el-option :value="1" label="1" />
<el-option :value="2" label="2" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
@ -56,7 +66,7 @@
</el-table-column>
<el-table-column prop="correctedMilk" label="班次校正奶量" >
<template #default="{ row }">
{{ row.milk ? Number(row.milk).toFixed(2) : '-' }}
{{ row.correctedMilk ? Number(row.correctedMilk).toFixed(2) : '-' }}
</template>
</el-table-column>
</el-table>
@ -82,6 +92,7 @@ import { ref, reactive, onMounted } from 'vue'
import { listMilkProdclasses, importMilkProdclasses, exportMilkProdclasses } from '@/api/dairyProducts/milkProdclasses/milkProdclasses'
import { getToken } from '@/utils/auth'
import { getRanchList } from '@/api/dairyProducts/ranch/ranch.js'
import { ElMessage } from 'element-plus'
import { Upload, Download, UploadFilled } from '@element-plus/icons-vue';
const ranchOptions = ref([])
@ -100,25 +111,36 @@ onMounted(() => {
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
manageEarNo: '', //
factory: null,
classes: null
datetimeStart: null, //
datetimeEnd: null, //
manageEarNo: '', //
factory: null, //
classes: null //
})
const dateRange = ref([])
const tableData = ref([])
const total = ref(0)
const loading = ref(false)
const openImport = ref(false)
const queryDate = ref(null) //
const tableData = ref([]) //
const total = ref(0) //
const loading = ref(false) //
const openImport = ref(false) //
const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/milkProdclasses/milkProdclasses/import';
const headers = { Authorization: 'Bearer ' + getToken() };
function getList() {
loading.value = true
const [start, end] = dateRange.value || []
//
if (queryDate.value) {
queryParams.datetimeStart = queryDate.value;
queryParams.datetimeEnd = queryDate.value;
} else {
queryParams.datetimeStart = null;
queryParams.datetimeEnd = null;
}
listMilkProdclasses({
datetimeStart: start,
datetimeEnd: end,
datetimeStart: queryParams.datetimeStart,
datetimeEnd: queryParams.datetimeEnd,
manageEarNo: queryParams.manageEarNo,
factory: queryParams.factory,
classes: queryParams.classes,
@ -135,8 +157,15 @@ function getList() {
}
function resetQuery() {
Object.assign(queryParams, { pageNum: 1, manageEarNo: '', factory: null, classes: null });
dateRange.value = [];
Object.assign(queryParams, {
pageNum: 1,
datetimeStart: null,
datetimeEnd: null,
manageEarNo: '',
factory: null,
classes: null
});
queryDate.value = null;
getList();
}
@ -148,22 +177,59 @@ function uploadSuccess(response) {
console.log('上传成功:', response);
openImport.value = false;
getList();
ElMessage.success('导入成功');
}
function uploadError(err) {
console.error('上传失败:', err);
ElMessage.error('导入失败');
}
function handleExport() {
const [start, end] = dateRange.value || [];
//
if (queryDate.value) {
queryParams.datetimeStart = queryDate.value;
queryParams.datetimeEnd = queryDate.value;
} else {
queryParams.datetimeStart = null;
queryParams.datetimeEnd = null;
}
exportMilkProdclasses({
datetimeStart: start,
datetimeEnd: end,
manageEarNo: queryParams.manageEarNo, //
datetimeStart: queryParams.datetimeStart,
datetimeEnd: queryParams.datetimeEnd,
manageEarNo: queryParams.manageEarNo,
factory: queryParams.factory,
classes: queryParams.classes
}).then(response => {
// Blob
const blob = new Blob([response], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
//
const downloadElement = document.createElement('a');
const href = window.URL.createObjectURL(blob);
downloadElement.href = href;
//
const now = new Date();
const dateStr = `${now.getFullYear()}${(now.getMonth()+1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}`;
downloadElement.download = `班次产奶数据_${dateStr}.xlsx`;
document.body.appendChild(downloadElement);
//
downloadElement.click();
// URL
document.body.removeChild(downloadElement);
window.URL.revokeObjectURL(href);
ElMessage.success('导出成功');
}).catch(error => {
console.error('导出失败:', error);
ElMessage.error('导出失败: ' + (error.message || '未知错误'));
});
}
getList();
</script>
</script>

View File

@ -236,6 +236,10 @@
</template>
<script setup name="RawMilkTest">
// xlsx
import * as XLSX from 'xlsx';
// file-saver
import { saveAs } from 'file-saver';
import { listRawMilkTest, getRawMilkTest, delRawMilkTest, addRawMilkTest, updateRawMilkTest } from "@/api/dairyProducts/rawMilkTest/rawMilkTest.js"
import { getCurrentInstance, ref, reactive, toRefs, onMounted } from 'vue'
import { parseTime } from '@/utils/ruoyi'
@ -496,9 +500,38 @@ function handleDelete(row) {
/** 导出按钮操作 */
function handleExport() {
proxy.download('rawMilkTest/rawMilkTest/export', {
...queryParams.value
}, `rawMilkTest_${new Date().getTime()}.xlsx`)
//
const visibleColumnsConfig = allColumns.value.filter(
col => visibleColumns.value[col.prop]
);
//
const exportData = rawMilkTestList.value.map(item => {
const rowData = {};
visibleColumnsConfig.forEach(col => {
//
if (col.prop === 'datetime' || col.prop === 'createTime') {
rowData[col.label] = parseTime(item[col.prop]);
} else {
rowData[col.label] = item[col.prop];
}
});
return rowData;
});
// 簿
const worksheet = XLSX.utils.json_to_sheet(exportData);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, '生乳检验记录');
// Excel
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
// 使file-saver
saveAs(blob, `生乳检验记录_${new Date().getTime()}.xlsx`);
}
onMounted(() => {

View File

@ -16,16 +16,16 @@
<!-- 操作按钮行 -->
<div class="button-group">
<el-button type="success" @click="handleExport">导出</el-button>
<el-popover placement="bottom" width="400" trigger="click">
<el-checkbox-group v-model="selectedFields" class="checkbox-columns">
<el-checkbox v-for="col in allColumns" :key="col.prop" :label="col.prop">{{ col.label }}</el-checkbox>
<!-- 使用 :value 替代 :label -->
<el-checkbox v-for="col in allColumns" :key="col.prop" :value="col.prop">{{ col.label }}</el-checkbox>
</el-checkbox-group>
<template #reference>
<el-button type="info">展示列</el-button>
</template>
</el-popover>
<el-button type="success" @click="handleExport">导出</el-button>
</div>
<!-- 数据表格 -->
@ -55,8 +55,9 @@
</template>
<script>
import { listSheepMilkAnalysis, exportSheepMilkAnalysis } from "@/api/dairyProducts/sheepMilkAnalysis/sheepMilkAnalysis.js";
import { listSheepMilkAnalysis } from "@/api/dairyProducts/sheepMilkAnalysis/sheepMilkAnalysis.js";
import { format } from 'date-fns';
import * as XLSX from 'xlsx'; // xlsx
export default {
name: "SheepMilkAnalysis",
@ -126,7 +127,6 @@ export default {
getList() {
this.loading = true;
listSheepMilkAnalysis(this.queryParams).then(response => {
// axios wrapper { data: { rows, total } }, { rows, total }
const res = response && response.data ? response.data : response;
this.list = res.rows || res;
this.total = res.total || (Array.isArray(this.list) ? this.list.length : 0);
@ -155,21 +155,33 @@ export default {
this.queryParams.pageSize = pageSize;
this.getList();
},
//
handleExport() {
exportSheepMilkAnalysis(this.queryParams).then(response => {
const data = response && response.data ? response.data : response;
const blob = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', '羊奶分析数据.xlsx');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
}).catch(err => {
this.$message.error('导出失败,请检查后端是否正确返回文件流');
//
const exportData = this.list.map(item => {
const row = {};
this.visibleColumns.forEach(col => {
let value = item[col.prop];
//
if (col.formatter && typeof col.formatter === 'function') {
value = col.formatter(item);
} else if (value instanceof Date) {
value = format(new Date(value), 'yyyy-MM-dd');
}
row[col.label] = value;
});
return row;
});
// 簿
const worksheet = XLSX.utils.json_to_sheet(exportData);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "羊奶产量分析");
// Excel
XLSX.writeFile(workbook, "羊奶产量分析数据.xlsx");
this.$message.success('导出成功');
}
}
};
@ -189,4 +201,4 @@ export default {
max-height: 300px;
overflow-y: auto;
}
</style>
</style>

View File

@ -287,6 +287,9 @@
import { ref, reactive, onMounted } from 'vue';
import { listYogurtTest, getYogurtTest, delYogurtTest, addYogurtTest, updateYogurtTest } from "@/api/dairyProducts/yogurtTest/yogurtTest.js";
import { ElMessage, ElMessageBox } from 'element-plus';
// xlsxfile-saver
import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver';
//
const yogurtTestList = ref([]);
@ -301,6 +304,27 @@ const title = ref("");
const columnShowDialogVisible = ref(false);
const yogurtTestRef = ref(null);
//
const columnConfig = [
{ prop: 'source', label: '来源' },
{ prop: 'datetime', label: '检测日期' },
{ prop: 'fat', label: '脂肪g/100g' },
{ prop: 'protein', label: '蛋白质g/100g' },
{ prop: 'nonFat', label: '非脂g/100g' },
{ prop: 'acidity', label: '酸度oT' },
{ prop: 'bacterialColony1', label: '菌落总数1' },
{ prop: 'bacterialClony2', label: '菌落总数2' },
{ prop: 'bacterialClony3', label: '菌落总数3' },
{ prop: 'bacterialClony4', label: '菌落总数4' },
{ prop: 'bacterialClony5', label: '菌落总数5' },
{ prop: 'yeast', label: '酵母菌(CFU/g)' },
{ prop: 'mould', label: '霉菌(CFU/g)' },
{ prop: 'lacto', label: '乳酸菌(CFU/g)' },
{ prop: 'comment', label: '备注' },
{ prop: 'createBy', label: '创建人' },
{ prop: 'createTime', label: '创建时间' }
];
//
const selectedColumns = ref([
'source', 'datetime', 'fat', 'protein', 'nonFat', 'acidity',
@ -543,17 +567,42 @@ function handleDelete(row) {
});
}
/** 导出按钮操作 */
/** 导出按钮操作 - 前端实现 */
function handleExport() {
const params = new URLSearchParams();
for (const key in queryParams) {
if (queryParams[key] !== null && queryParams[key] !== undefined) {
params.append(key, queryParams[key]);
}
}
//
const visibleColumnsConfig = columnConfig.filter(
col => selectedColumns.value.includes(col.prop)
);
const url = `/yogurtTest/yogurtTest/export?${params.toString()}`;
window.location.href = url;
//
const exportData = yogurtTestList.value.map(item => {
const rowData = {};
visibleColumnsConfig.forEach(col => {
//
if (col.prop === 'datetime') {
rowData[col.label] = formatDate(item[col.prop]);
} else if (col.prop === 'createTime') {
rowData[col.label] = formatDateTime(item[col.prop]);
} else {
rowData[col.label] = item[col.prop];
}
});
return rowData;
});
// 簿
const worksheet = XLSX.utils.json_to_sheet(exportData);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, '酸奶检疫记录');
// Excel
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
// 使file-saver
saveAs(blob, `酸奶检疫记录_${new Date().getTime()}.xlsx`);
}
//

View File

@ -19,9 +19,9 @@
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['feed:FeedList:add']">新增</el-button>
</el-col>
</el-col> -->
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
v-hasPermi="['feed:FeedList:edit']">修改</el-button>
@ -49,11 +49,11 @@
<span>{{ scope.row.rootPlan ? parseTime(scope.row.rootPlan.planDate, '{y}-{m}-{d}') : '' }}</span>
</template>
</el-table-column>
<el-table-column label="配料日期" align="center" prop="deployDate" width="180">
<!-- <el-table-column label="配料日期" align="center" prop="deployDate" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.deployDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="View" @click="handleView(scope.row)">详情</el-button>
@ -75,11 +75,11 @@
<el-form-item label="饲草班人员" prop="zookeeper">
<el-input v-model="form.zookeeper" placeholder="请输入饲草班人员名称" />
</el-form-item>
<el-form-item label="配料日期" prop="deployDate">
<!-- <el-form-item label="配料日期" prop="deployDate">
<el-date-picker clearable v-model="form.deployDate" type="date" value-format="YYYY-MM-DD"
placeholder="请选择配料日期">
</el-date-picker>
</el-form-item>
</el-form-item> -->
</el-form>
<template #footer>
<div class="dialog-footer">
@ -102,7 +102,7 @@
<el-divider content-position="left">配料列表</el-divider>
<el-table :data="showFeedList.formulaList" stripe border style="width: 100%" max-height="300">
<el-table :data="showFeedList.rootFormula.sgFormulaList" stripe border style="width: 100%" max-height="300">
<el-table-column label="序号" type="index" width="60" align="center" />
<!-- <el-table-column label="原料编号" prop="materialId" align="center" /> -->
<el-table-column label="原料" align="center">
@ -186,6 +186,7 @@
openModel.value = "view"
title.value = "配料清单详情"
console.log("查看配料清单", row)
console.log("HandView", showFeedList.value)
}
/** 查询配料清单列表 */

View File

@ -35,7 +35,7 @@
<el-table v-loading="loading" :data="FeedStatisticList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="UUID" align="center" prop="id" />
<el-table-column label="UID" align="center" prop="id" />
<el-table-column label="配方编号" align="center" prop="formulaId" />
<el-table-column label="配方批号" align="center" prop="formulaBatchId" />
<el-table-column label="羊只数量" align="center" prop="sheepFoldCount" />
@ -93,7 +93,7 @@
<el-col :span="12">
<el-form-item label="日期" prop="planDate">
<el-date-picker clearable v-model="showFeedStatistic.feedDate" type="date" value-format="YYYY-MM-DD"
placeholder="请选择时间">
placeholder="请选择时间" @change="handleDeployDateChange(showFeedStatistic, $event)">
</el-date-picker>
</el-form-item>
</el-col>
@ -102,7 +102,11 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" icon="Plus" @click="handleAddMaterial()">添加</el-button>
<el-button type="primary" icon="Plus" @click="handleAddMaterial()"
:disabled="
showFeedStatistic.feedDate == null
|| showFeedStatistic.formulaId === null
|| showFeedStatistic.formulaBatchId == null">添加</el-button>
</el-col>
</el-row>
@ -152,7 +156,11 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" icon="Plus" @click="handleAddSheep()">添加</el-button>
<el-button type="primary" icon="Plus" @click="handleAddSheep()"
:disabled ="
showFeedStatistic.feedDate == null
|| showFeedStatistic.formulaId == null
|| showFeedStatistic.formulaBatchId == null">添加</el-button>
</el-col>
<el-table :data="showFeedStatistic.sheepFoldList" :rules="rules"
@ -231,6 +239,7 @@
const openModel = ref('')
//
const isEdit = ref(true)
const showFeedStatistic = ref({})
//
@ -362,9 +371,10 @@
// &
function handleFormulaBatchIdChange(row, $event) {
if (row.formulaId && row.formulaBatchId) {
if (row.formulaId && row.formulaBatchId && row.feedDate) {
queryParams.value.formulaId = row.formulaId
queryParams.value.formulaBatchId = row.formulaBatchId
queryParams.value.feedDate = row.feedDate
queryParams.value.id = null // ID
// console.log("", queryParams.value)
initFeedStatistic(queryParams.value).then(response => {
@ -374,6 +384,13 @@
})
}
}
function handleDeployDateChange(showFeedStatistic, event) {
//
if (showFeedStatistic.feedDate) {
handleFormulaBatchIdChange(showFeedStatistic, event);
}
}
//
function handleMaterialView(row) {
showFeedStatistic.value = row

View File

@ -4,9 +4,9 @@
<el-form-item label="饲养阶段" prop="feedStage">
<el-input v-model="queryParams.feedStage" placeholder="请输入饲养阶段" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="批号" prop="batchId">
<!-- <el-form-item label="批号" prop="batchId">
<el-input v-model="queryParams.batchId" placeholder="请输入批号" clearable @keyup.enter="handleQuery" />
</el-form-item>
</el-form-item> -->
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>

View File

@ -1,6 +1,6 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px" @submit.prevent>
<el-form-item label="分组名称" prop="groupName">
<el-input
v-model="queryParams.groupName"
@ -20,7 +20,7 @@
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button type="primary" icon="Search" @click="handleQuery" native-type="button"> 搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
@ -256,38 +256,71 @@ async function handleUpdate(row) {
})
}
/** 提交按钮 */
// function submitForm() {
// proxy.$refs["group_managementRef"].validate(valid => {
// if (valid) {
// //
// if (form.value.parentId === 0) {
// form.value.ancestors = "0"
// } else {
// const parentNode = findNode(group_managementOptions.value, form.value.parentId)
// if (parentNode) {
// form.value.ancestors = `${parentNode.ancestors},${parentNode.groupId}`
// } else {
// // 使
// form.value.ancestors = "0"
// }
// }
// if (form.value.groupId != null) {
// updateGroup_management(form.value).then(response => {
// proxy.$modal.msgSuccess("")
// open.value = false
// getList()
// })
// } else {
// addGroup_management(form.value).then(response => {
// proxy.$modal.msgSuccess("")
// open.value = false
// getList()
// })
// }
// }
// })
// }
/** 提交按钮 */
function submitForm() {
proxy.$refs["group_managementRef"].validate(valid => {
if (valid) {
//
if (form.value.parentId === 0) {
form.value.ancestors = "0"
} else {
const parentNode = findNode(group_managementOptions.value, form.value.parentId)
if (parentNode) {
form.value.ancestors = `${parentNode.ancestors},${parentNode.groupId}`
} else {
// 使
form.value.ancestors = "0"
}
}
if (!valid) return;
if (form.value.groupId != null) {
updateGroup_management(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getList()
})
} else {
addGroup_management(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
})
}
//
if (form.value.parentId === 0) {
form.value.ancestors = "0";
} else {
const parentNode = findNode(group_managementOptions.value, form.value.parentId);
form.value.ancestors = parentNode
? `${parentNode.ancestors},${parentNode.groupId}`
: "0";
}
})
const request = form.value.groupId != null
? updateGroup_management(form.value)
: addGroup_management(form.value);
request
.then(() => {
proxy.$modal.msgSuccess(form.value.groupId ? "修改成功" : "新增成功");
open.value = false;
getList();
})
.catch(error => {
//
const msg = error?.response?.data?.msg || "操作失败";
proxy.$modal.msgError(msg);
});
});
}
/** 删除按钮操作 */

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,18 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="羊只id" prop="id">
<!-- <el-form-item label="羊只id" prop="id">
<el-input
v-model="queryParams.id"
placeholder="请输入羊只id"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="管理耳号" prop="bsManageTags">
</el-form-item> -->
<el-form-item label="耳号" prop="bsManageTags">
<el-input
v-model="queryParams.bsManageTags"
placeholder="请输入管理耳号"
placeholder="请输入耳号"
clearable
@keyup.enter="handleQuery"
/>
@ -66,7 +66,7 @@
border
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column
<!-- <el-table-column
v-if="columns['id'].visible"
label="羊只id"
align="center"
@ -78,10 +78,10 @@
<template #header>
<span style="font-weight: bold; color: #333;">羊只id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['bsManageTags'].visible"
label="管理耳号"
label="耳号"
align="center"
prop="bsManageTags"
width="120"
@ -89,10 +89,10 @@
sortable
>
<template #header>
<span style="font-weight: bold; color: #333;">管理耳号</span>
<span style="font-weight: bold; color: #333;">耳号</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['ranchId'].visible"
label="牧场id"
align="center"
@ -103,7 +103,7 @@
<template #header>
<span style="font-weight: bold; color: #333;">牧场id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['drRanch'].visible"
label="牧场名称"
@ -116,7 +116,7 @@
<span style="font-weight: bold; color: #333;">牧场名称</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['sheepfoldId'].visible"
label="羊舍id"
align="center"
@ -127,7 +127,7 @@
<template #header>
<span style="font-weight: bold; color: #333;">羊舍id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['sheepfoldName'].visible"
label="羊舍名称"
@ -166,7 +166,7 @@
</el-tooltip>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['varietyId'].visible"
label="品种id"
align="center"
@ -177,7 +177,7 @@
<template #header>
<span style="font-weight: bold; color: #333;">品种id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['variety'].visible"
label="品种"
@ -346,7 +346,7 @@
<span style="font-weight: bold; color: #333;">当前体重</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['breedStatusId'].visible"
label="繁育状态id"
align="center"
@ -357,7 +357,7 @@
<template #header>
<span style="font-weight: bold; color: #333;">繁育状态id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['breed'].visible"
label="繁殖状态"
@ -370,7 +370,7 @@
<span style="font-weight: bold; color: #333;">繁殖状态</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['bsFatherId'].visible"
label="父号id"
align="center"
@ -381,20 +381,20 @@
<template #header>
<span style="font-weight: bold; color: #333;">父号id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['fatherManageTags'].visible"
label="父亲管理耳号"
label="父亲耳号"
align="center"
prop="fatherManageTags"
width="120"
sortable
>
<template #header>
<span style="font-weight: bold; color: #333;">父亲管理耳号</span>
<span style="font-weight: bold; color: #333;">父亲耳号</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['bsMotherId'].visible"
label="母号id"
align="center"
@ -405,20 +405,20 @@
<template #header>
<span style="font-weight: bold; color: #333;">母号id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['motherManageTags'].visible"
label="母亲管理耳号"
label="母亲耳号"
align="center"
prop="motherManageTags"
width="120"
sortable
>
<template #header>
<span style="font-weight: bold; color: #333;">母亲管理耳号</span>
<span style="font-weight: bold; color: #333;">母亲耳号</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['receptorId'].visible"
label="受体id"
align="center"
@ -429,20 +429,20 @@
<template #header>
<span style="font-weight: bold; color: #333;">受体id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['receptorManageTags'].visible"
label="受体管理耳号"
label="受体耳号"
align="center"
prop="receptorManageTags"
width="120"
sortable
>
<template #header>
<span style="font-weight: bold; color: #333;">受体管理耳号</span>
<span style="font-weight: bold; color: #333;">受体耳号</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['fatherFatherId'].visible"
label="祖父号id"
align="center"
@ -453,20 +453,20 @@
<template #header>
<span style="font-weight: bold; color: #333;">祖父号id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['grandfatherManageTags'].visible"
label="祖父管理耳号"
label="祖父耳号"
align="center"
prop="grandfatherManageTags"
width="120"
sortable
>
<template #header>
<span style="font-weight: bold; color: #333;">祖父管理耳号</span>
<span style="font-weight: bold; color: #333;">祖父耳号</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['fatherMotherId'].visible"
label="祖母号id"
align="center"
@ -477,20 +477,20 @@
<template #header>
<span style="font-weight: bold; color: #333;">祖母号id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['grandmotherManageTags'].visible"
label="祖母管理耳号"
label="祖母耳号"
align="center"
prop="grandmotherManageTags"
width="120"
sortable
>
<template #header>
<span style="font-weight: bold; color: #333;">祖母管理耳号</span>
<span style="font-weight: bold; color: #333;">祖母耳号</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['fatherId'].visible"
label="外祖父号id"
align="center"
@ -501,20 +501,20 @@
<template #header>
<span style="font-weight: bold; color: #333;">外祖父号id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['maternalGrandfatherManageTags'].visible"
label="外祖父管理耳号"
label="外祖父耳号"
align="center"
prop="maternalGrandfatherManageTags"
width="120"
sortable
>
<template #header>
<span style="font-weight: bold; color: #333;">外祖父管理耳号</span>
<span style="font-weight: bold; color: #333;">外祖父耳号</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['motherId'].visible"
label="外祖母号id"
align="center"
@ -525,17 +525,17 @@
<template #header>
<span style="font-weight: bold; color: #333;">外祖母号id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['maternalGrandmotherManageTags'].visible"
label="外祖母管理耳号"
label="外祖母耳号"
align="center"
prop="maternalGrandmotherManageTags"
width="120"
sortable
>
<template #header>
<span style="font-weight: bold; color: #333;">外祖母管理耳号</span>
<span style="font-weight: bold; color: #333;">外祖母耳号</span>
</template>
</el-table-column>
<el-table-column
@ -809,7 +809,7 @@
<span>{{ parseTime(scope.row.sourceDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column
<!-- <el-table-column
v-if="columns['sourceRanchId'].visible"
label="来源牧场id"
align="center"
@ -820,7 +820,7 @@
<template #header>
<span style="font-weight: bold; color: #333;">来源牧场id</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column
v-if="columns['sourceRanch'].visible"
label="来源牧场"
@ -915,14 +915,14 @@
<el-dialog v-model="columnDialogVisible" title="显示列设置" width="800px">
<div style="max-height: 400px; overflow-y: auto; ">
<el-checkbox-group v-model="selectedColumns" style="grid; grid-template-columns: repeat(3, 1fr); gap: 10px;" >
<el-checkbox label="id">羊只id</el-checkbox>
<el-checkbox label="bsManageTags">管理耳号</el-checkbox>
<el-checkbox label="ranchId">牧场id</el-checkbox>
<!-- <el-checkbox label="id">羊只id</el-checkbox> -->
<el-checkbox label="bsManageTags">耳号</el-checkbox>
<!-- <el-checkbox label="ranchId">牧场id</el-checkbox> -->
<el-checkbox label="drRanch">牧场名称</el-checkbox>
<el-checkbox label="sheepfoldId">羊舍id</el-checkbox>
<!-- <el-checkbox label="sheepfoldId">羊舍id</el-checkbox> -->
<el-checkbox label="sheepfoldName">羊舍名称</el-checkbox>
<el-checkbox label="electronicTags">电子耳号</el-checkbox>
<el-checkbox label="varietyId">品种id</el-checkbox>
<!-- <el-checkbox label="varietyId">品种id</el-checkbox> -->
<el-checkbox label="variety">品种</el-checkbox>
<el-checkbox label="family">家系</el-checkbox>
<el-checkbox label="name">羊只类型</el-checkbox>
@ -936,22 +936,22 @@
<el-checkbox label="statusId">羊只状态</el-checkbox>
<el-checkbox label="weaningWeight">断奶体重</el-checkbox>
<el-checkbox label="currentWeight">当前体重</el-checkbox>
<el-checkbox label="breedStatusId">繁育状态id</el-checkbox>
<!-- <el-checkbox label="breedStatusId">繁育状态id</el-checkbox> -->
<el-checkbox label="breed">繁殖状态</el-checkbox>
<el-checkbox label="bsFatherId">父号id</el-checkbox>
<el-checkbox label="fatherManageTags">父亲管理耳号</el-checkbox>
<el-checkbox label="bsMotherId">母号id</el-checkbox>
<el-checkbox label="motherManageTags">母亲管理耳号</el-checkbox>
<el-checkbox label="receptorId">受体id</el-checkbox>
<el-checkbox label="receptorManageTags">受体管理耳号</el-checkbox>
<el-checkbox label="fatherFatherId">祖父号id</el-checkbox>
<el-checkbox label="grandfatherManageTags">祖父管理耳号</el-checkbox>
<el-checkbox label="fatherMotherId">祖母号id</el-checkbox>
<el-checkbox label="grandmotherManageTags">祖母管理耳号</el-checkbox>
<el-checkbox label="fatherId">外祖父号id</el-checkbox>
<el-checkbox label="maternalGrandfatherManageTags">外祖父管理耳号</el-checkbox>
<el-checkbox label="motherId">外祖母号id</el-checkbox>
<el-checkbox label="maternalGrandmotherManageTags">外祖母管理耳号</el-checkbox>
<!-- <el-checkbox label="bsFatherId">父号id</el-checkbox> -->
<el-checkbox label="fatherManageTags">父亲耳号</el-checkbox>
<!-- <el-checkbox label="bsMotherId">母号id</el-checkbox> -->
<el-checkbox label="motherManageTags">母亲耳号</el-checkbox>
<!-- <el-checkbox label="receptorId">受体id</el-checkbox> -->
<el-checkbox label="receptorManageTags">受体耳号</el-checkbox>
<!-- <el-checkbox label="fatherFatherId">祖父号id</el-checkbox> -->
<el-checkbox label="grandfatherManageTags">祖父耳号</el-checkbox>
<!-- <el-checkbox label="fatherMotherId">祖母号id</el-checkbox> -->
<el-checkbox label="grandmotherManageTags">祖母耳号</el-checkbox>
<!-- <el-checkbox label="fatherId">外祖父号id</el-checkbox> -->
<el-checkbox label="maternalGrandfatherManageTags">外祖父耳号</el-checkbox>
<!-- <el-checkbox label="motherId">外祖母号id</el-checkbox> -->
<el-checkbox label="maternalGrandmotherManageTags">外祖母耳号</el-checkbox>
<el-checkbox label="matingDate">配种日期</el-checkbox>
<el-checkbox label="matingTypeId">配种类型</el-checkbox>
<el-checkbox label="pregDate">孕检日期</el-checkbox>
@ -972,7 +972,7 @@
<el-checkbox label="breast">乳房评分</el-checkbox>
<el-checkbox label="source">入群来源</el-checkbox>
<el-checkbox label="sourceDate">入群日期</el-checkbox>
<el-checkbox label="sourceRanchId">来源牧场id</el-checkbox>
<!-- <el-checkbox label="sourceRanchId">来源牧场id</el-checkbox> -->
<el-checkbox label="sourceRanch">来源牧场</el-checkbox>
<el-checkbox label="updateBy">修改人</el-checkbox>
<el-checkbox label="updateTime">修改日期</el-checkbox>

View File

@ -18,7 +18,7 @@
/>
</el-form-item>
<el-form-item label="分组" prop="groupId">
<el-select
<!-- <el-select
v-model="queryParams.groupId"
placeholder="请选择分组"
clearable
@ -30,8 +30,15 @@
:label="g.groupName"
:value="g.groupId"
/>
</el-select>
</el-form-item>
</el-select> -->
<el-tree-select v-model="queryParams.groupId" :data="groupTree" style="width: 180px;"
:props="{ value: 'groupId', label: 'groupName', children: 'children' }"
value-key="groupId" placeholder="请选择"
check-strictly
clearable
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
@ -134,14 +141,27 @@
<el-input type="textarea" :rows="4" v-model="form.earTags" :disabled="form.earTagsDisabled" placeholder="请输入耳号,多个耳号用逗号或换行分隔"/>
</el-form-item>
<el-form-item label="分组" prop="groupId">
<el-select v-model="form.groupId" placeholder="请选择分组" clearable>
<!-- <el-select v-model="form.groupId" placeholder="请选择分组" clearable>
<el-option
v-for="g in leafGroupOptions"
:key="g.groupId"
:label="g.groupName"
:value="g.groupId"
/>
</el-select>
</el-select> -->
<el-tree-select
v-model="form.groupId"
:data="groupTree"
style="width: 180px"
:props="{ value: 'groupId', label: 'groupName', children: 'children' }"
value-key="groupId"
placeholder="请选择分组"
clearable
check-strictly
:select-leaf-only="true"
/>
</el-form-item>
</el-form>
<template #footer>
@ -159,6 +179,7 @@ import { listSheep_grouping, getSheep_grouping, delSheep_grouping, addSheep_grou
import {listLeafGroup} from "@/api/fileManagement/group_management"
import {listSheep_grouping_join} from "@/api/fileManagement/sheep_grouping"
import { addByEarTags } from '@/api/fileManagement/sheep_grouping'
import { listGroupTree } from '@/api/fileManagement/sheep_grouping'
const { proxy } = getCurrentInstance()
@ -173,6 +194,8 @@ const total = ref(0)
const title = ref("")
const leafGroupOptions = ref([])
const { sheep_gender } = proxy.useDict('sheep_gender')
// data
const groupTree = ref([])
const data = reactive({
form: {
@ -390,17 +413,33 @@ loadLeafGroups()
getList()
// //
// function loadLeafGroups() {
// listLeafGroup().then(res => {
// leafGroupOptions.value = res.data
// })
// }
//
function loadLeafGroups() {
listLeafGroup().then(res => {
leafGroupOptions.value = res.data
listGroupTree().then(res => {
groupTree.value = res.data
console.log(groupTree.value)
})
}
// groupId
// function getGroupName(id) {
// const group = leafGroupOptions.value.find(g => g.groupId === id)
// return group ? group.groupName : ''
// }
function getGroupName(id) {
const group = leafGroupOptions.value.find(g => g.groupId === id)
return group ? group.groupName : ''
const flatten = (arr) =>
arr.reduce((acc, cur) => acc.concat(cur, flatten(cur.children || [])), [])
const node = flatten(groupTree.value).find(n => n.groupId === id)
return node ? node.groupName : ''
}
</script>

View File

@ -103,6 +103,86 @@
@pagination="getList"
/>
<!-- ===== 图形化展示区域 ===== -->
<el-divider>牧场羊舍示意图</el-divider>
<el-collapse
v-model="activeNames"
accordion
style="margin-top: 16px; max-width: 100%; overflow-x: auto"
>
<!-- 一级牧场 -->
<el-collapse-item
v-for="ranch in seatMapTree"
:key="ranch.ranchId"
:title="ranch.ranchName"
:name="ranch.ranchId"
>
<!-- 二级羊舍类型 -->
<el-collapse accordion>
<el-collapse-item
v-for="type in ranch.types"
:key="type.typeId"
:title="`${type.typeName} (${type.folds.length}个)`"
>
<!-- 三级羊舍卡片 -->
<el-row :gutter="16">
<el-col
v-for="fold in type.folds"
:key="fold.foldNo"
:xs="24"
:sm="12"
:md="8"
:lg="6"
:xl="4"
style="margin-bottom: 16px"
>
<el-card shadow="hover">
<template #header>
<span>{{ fold.foldNo }}{{type.typeName}}</span>
</template>
<!-- 四级 -->
<div
v-for="row in fold.rows"
:key="row.rowNo"
class="seat-block"
>
<div class="row-label">{{ row.rowNo }}</div>
<div class="seat-row">
<!-- 五级栏位 -->
<div
v-for="col in row.columns"
:key="col"
class="seat"
:class="{ occupied: isOccupied(fold.foldNo, row.rowNo, col) }"
@click="toggleSeat(fold.foldNo, row.rowNo, col)"
>
{{ col }}
</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</el-collapse-item>
</el-collapse>
</el-collapse-item>
</el-collapse>
<!-- 添加或修改羊舍管理对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="sheepfold_managementRef" :model="form" :rules="rules" label-width="80px">
@ -190,7 +270,7 @@
</template>
<script setup name="Sheepfold_management">
import { listSheepfold_management, getSheepfold_management, delSheepfold_management, addSheepfold_management, updateSheepfold_management,checkSheepfoldNoExist } from "@/api/fileManagement/sheepfold_management"
import { getSeatMap,listSheepfold_management, getSheepfold_management, delSheepfold_management, addSheepfold_management, updateSheepfold_management,checkSheepfoldNoExist } from "@/api/fileManagement/sheepfold_management"
const { proxy } = getCurrentInstance()
const { bas_sheepfold_type, da_ranch } = proxy.useDict('bas_sheepfold_type', 'da_ranch')
@ -206,6 +286,7 @@ const total = ref(0)
const title = ref("")
const sheepfoldNoExists = ref(false) //
const data = reactive({
form: {
id: null,
@ -295,6 +376,7 @@ function reset() {
function handleQuery() {
queryParams.value.pageNum = 1
getList()
loadSeatMap()
}
/** 重置按钮操作 */
@ -388,6 +470,7 @@ function submitForm() {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getList()
loadSeatMap()
})
} else {
// -
@ -423,6 +506,7 @@ function submitForm() {
proxy.$modal.msgSuccess(`新增成功,共添加${requests.length}条记录`)
open.value = false
getList()
loadSeatMap()
})
.catch(error => {
proxy.$modal.msgError("部分记录添加失败:" + error.message)
@ -439,6 +523,7 @@ function handleDelete(row) {
return delSheepfold_management(_ids)
}).then(() => {
getList()
loadSeatMap();
proxy.$modal.msgSuccess("删除成功")
}).catch(() => {})
}
@ -450,7 +535,46 @@ function handleExport() {
}, `sheepfold_management_${new Date().getTime()}.xlsx`)
}
/* ===== 图形化展示所需变量和方法 ===== */
const activeNames = ref([]) //
const seatMapTree = ref([]) //
const loadSeatMap = () => {
getSeatMap()
.then(res => (seatMapTree.value = res.data))
.catch(err => proxy.$modal.msgError('加载座位图失败:' + err.message))
}
/* 演示:点击栏位切换颜色 */
const occupied = ref(new Set())
const isOccupied = (foldNo, rowNo, col) =>
occupied.value.has(`${foldNo}-${rowNo}-${col}`)
const toggleSeat = (foldNo, rowNo, col) => {
const key = `${foldNo}-${rowNo}-${col}`
occupied.value.has(key)
? occupied.value.delete(key)
: occupied.value.add(key)
}
/* 页面加载时拉取数据 */
onMounted(() => {
getList()
loadSeatMap()
})
getList()
loadSeatMap()
</script>
@ -462,4 +586,34 @@ getList()
border-radius: 4px;
background-color: #f5f7fa;
}
/* ===== 图形化展示样式 ===== */
.seat-block {
margin-bottom: 8px;
}
.row-label {
font-weight: bold;
margin-bottom: 4px;
}
.seat-row {
display: flex;
flex-wrap: wrap;
gap: 4px;
}
.seat {
width: 32px;
height: 32px;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
cursor: pointer;
background: #f2f6fc;
}
.seat.occupied {
background: #67c23a;
color: #fff;
}
</style>

View File

@ -2,7 +2,10 @@
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="单据日期" prop="docDate">
<el-input v-model="queryParams.docDate" placeholder="请输入单据日期" clearable @keyup.enter="handleQuery" />
<!-- <el-input v-model="queryParams.docDate" placeholder="请输入单据日期" clearable @keyup.enter="handleQuery" /> -->
<el-date-picker clearable v-model="queryParams.docDate" type="date" value-format="YYYY-MM-DD"
placeholder="请选择时间" @change="handleQuery">
</el-date-picker>
</el-form-item>
<el-form-item label="业务类型" prop="businessType">
<el-input v-model="queryParams.businessType" placeholder="请输入业务类型" clearable @keyup.enter="handleQuery" />
@ -20,8 +23,9 @@
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5" >
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['stock:in:add']" v-show="false">新增</el-button>
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['stock:in:add']"
v-show="false">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
@ -119,7 +123,7 @@
<script setup name="In">
import { listIn, getIn, delIn, addIn, updateIn } from "@/api/stock/in"
import { getToken } from "@/utils/auth"
import { isVisible } from "element-plus/es/utils/index.mjs"
import { isVisible } from "element-plus/es/utils/index.mjs"
const { proxy } = getCurrentInstance()
const inList = ref([])

View File

@ -2,20 +2,13 @@
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="存货" prop="materialName">
<el-input
v-model="queryParams.materialName"
placeholder="请输入存货"
clearable
@keyup.enter="handleQuery"
/>
<el-input v-model="queryParams.materialName" placeholder="请输入存货" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="生产日期" prop="productionDate">
<el-input
v-model="queryParams.productionDate"
placeholder="请输入生产日期"
clearable
@keyup.enter="handleQuery"
/>
<!-- <el-input v-model="queryParams.productionDate" placeholder="请输入生产日期" clearable @keyup.enter="handleQuery" /> -->
<el-date-picker clearable v-model="queryParams.productionDate" type="date" value-format="YYYY-MM-DD"
placeholder="请输入生产日期" @change="handleQuery">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@ -25,45 +18,24 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['stock:management:add']"
>新增</el-button>
<el-button type="primary" plain icon="Plus" @click="handleAdd"
v-hasPermi="['stock:management:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['stock:management:edit']"
>修改</el-button>
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
v-hasPermi="['stock:management:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['stock:management:remove']"
>删除</el-button>
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
v-hasPermi="['stock:management:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['stock:management:export']"
>导出</el-button>
<el-button type="warning" plain icon="Download" @click="handleExport"
v-hasPermi="['stock:management:export']">导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['stock:management:import']">导入</el-button>
<el-button type="info" plain icon="Upload" @click="handleImport"
v-hasPermi="['stock:management:import']">导入</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
@ -83,19 +55,16 @@
<el-table-column label="失效预警" align="center" prop="expirationAlarm" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['stock:management:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['stock:management:remove']">删除</el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
v-hasPermi="['stock:management:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
v-hasPermi="['stock:management:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
@pagination="getList" />
<!-- 添加或修改饲喂计划对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
@ -119,18 +88,12 @@
<el-input v-model="form.currentStock" placeholder="请输入现存量" />
</el-form-item>
<el-form-item label="生产日期" prop="productionDate">
<el-date-picker clearable
v-model="form.productionDate"
type="date"
value-format="YYYY-MM-DD"
<el-date-picker clearable v-model="form.productionDate" type="date" value-format="YYYY-MM-DD"
placeholder="请选择生产日期">
</el-date-picker>
</el-form-item>
<el-form-item label="失效日期" prop="expirationDate">
<el-date-picker clearable
v-model="form.expirationDate"
type="date"
value-format="YYYY-MM-DD"
<el-date-picker clearable v-model="form.expirationDate" type="date" value-format="YYYY-MM-DD"
placeholder="请选择失效日期">
</el-date-picker>
</el-form-item>
@ -169,37 +132,37 @@
</template>
<script setup name="Management">
import { listManagement, getManagement, delManagement, addManagement, updateManagement } from "@/api/stock/management"
import { getToken } from "@/utils/auth"
const { proxy } = getCurrentInstance()
import { listManagement, getManagement, delManagement, addManagement, updateManagement } from "@/api/stock/management"
import { getToken } from "@/utils/auth"
const { proxy } = getCurrentInstance()
const managementList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref("")
const managementList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref("")
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
materialName: null,
productionDate: null,
},
rules: {
materialId: [
{ required: true, message: "存货编码不能为空", trigger: "blur" }
],
materialName: [
{ required: true, message: "存货不能为空", trigger: "blur" }
],
}
})
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
materialName: null,
productionDate: null,
},
rules: {
materialId: [
{ required: true, message: "存货编码不能为空", trigger: "blur" }
],
materialName: [
{ required: true, message: "存货不能为空", trigger: "blur" }
],
}
})
/*** 用户导入参数 */
const upload = reactive({
@ -228,129 +191,129 @@ const data = reactive({
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true
}
/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {
upload.open = false
upload.isUploading = false
proxy.$refs["uploadRef"].handleRemove(file)
proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true })
getList()
}
const { queryParams, form, rules } = toRefs(data)
/** 查询物资管理列表 */
function getList() {
loading.value = true
listManagement(queryParams.value).then(response => {
managementList.value = response.rows
total.value = response.total
loading.value = false
})
}
//
function cancel() {
open.value = false
reset()
}
//
function reset() {
form.value = {
materialManagementCode: null,
materialId: null,
materialName: null,
batchId: null,
materialSpecification: null,
materialUnit: null,
currentStock: null,
stockAlarm: null,
productionDate: null,
expirationDate: null,
expirationAlarm: null
const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true
}
proxy.resetForm("managementRef")
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef")
handleQuery()
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.materialManagementCode)
single.value = selection.length != 1
multiple.value = !selection.length
}
/** 新增按钮操作 */
function handleAdd() {
reset()
open.value = true
title.value = "添加物资管理"
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
const _materialManagementCode = row.materialManagementCode || ids.value
getManagement(_materialManagementCode).then(response => {
form.value = response.data
open.value = true
title.value = "修改物资管理"
})
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["managementRef"].validate(valid => {
if (valid) {
if (form.value.materialManagementCode != null) {
updateManagement(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getList()
})
} else {
addManagement(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
})
}
}
})
}
/** 删除按钮操作 */
function handleDelete(row) {
const _materialManagementCodes = row.materialManagementCode || ids.value
proxy.$modal.confirm('是否确认删除物资管理编号为"' + _materialManagementCodes + '"的数据项?').then(function() {
return delManagement(_materialManagementCodes)
}).then(() => {
/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {
upload.open = false
upload.isUploading = false
proxy.$refs["uploadRef"].handleRemove(file)
proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true })
getList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => {})
}
}
const { queryParams, form, rules } = toRefs(data)
/** 导出按钮操作 */
function handleExport() {
proxy.download('stock/management/export', {
...queryParams.value
}, `management_${new Date().getTime()}.xlsx`)
}
/** 查询物资管理列表 */
function getList() {
loading.value = true
listManagement(queryParams.value).then(response => {
managementList.value = response.rows
total.value = response.total
loading.value = false
})
}
getList()
//
function cancel() {
open.value = false
reset()
}
//
function reset() {
form.value = {
materialManagementCode: null,
materialId: null,
materialName: null,
batchId: null,
materialSpecification: null,
materialUnit: null,
currentStock: null,
stockAlarm: null,
productionDate: null,
expirationDate: null,
expirationAlarm: null
}
proxy.resetForm("managementRef")
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef")
handleQuery()
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.materialManagementCode)
single.value = selection.length != 1
multiple.value = !selection.length
}
/** 新增按钮操作 */
function handleAdd() {
reset()
open.value = true
title.value = "添加物资管理"
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
const _materialManagementCode = row.materialManagementCode || ids.value
getManagement(_materialManagementCode).then(response => {
form.value = response.data
open.value = true
title.value = "修改物资管理"
})
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["managementRef"].validate(valid => {
if (valid) {
if (form.value.materialManagementCode != null) {
updateManagement(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getList()
})
} else {
addManagement(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
})
}
}
})
}
/** 删除按钮操作 */
function handleDelete(row) {
const _materialManagementCodes = row.materialManagementCode || ids.value
proxy.$modal.confirm('是否确认删除物资管理编号为"' + _materialManagementCodes + '"的数据项?').then(function () {
return delManagement(_materialManagementCodes)
}).then(() => {
getList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => { })
}
/** 导出按钮操作 */
function handleExport() {
proxy.download('stock/management/export', {
...queryParams.value
}, `management_${new Date().getTime()}.xlsx`)
}
getList()
</script>

View File

@ -42,7 +42,7 @@ export default defineConfig(({ mode, command }) => {
},
// vite 相关配置
server: {
port: 80,
port: 82,
host: true,
open: true,
proxy: {