Compare commits

...

2 Commits

Author SHA1 Message Date
ll
6338cfb518 Merge branch 'main' of http://e19510c831.iok.la/admin/zhyc-sheep-ui 2025-12-05 17:51:33 +08:00
ll
75e9787950 新需求修改 2025-12-05 17:51:26 +08:00
12 changed files with 808 additions and 822 deletions

View File

@ -1,17 +1,18 @@
<template> <template>
<div class="app-container"> <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">
<el-form-item label="年月" prop="datetime"> <el-form-item label="年月" style="width: 308px">
<el-date-picker clearable <el-date-picker
v-model="queryParams.datetime" v-model="dateRange"
type="month" type="monthrange"
value-format="YYYY-MM" value-format="YYYY-MM-DD"
placeholder="请选择年月"> range-separator="-"
</el-date-picker> start-placeholder="开始月份"
end-placeholder="结束月份"
></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="厂区" prop="factory"> <el-form-item label="厂区" prop="factory">
<el-select v-model="queryParams.factory" placeholder="请选择厂区" clearable> <el-select v-model="queryParams.factory" placeholder="请选择厂区" clearable style="width: 240px">
<el-option <el-option
v-for="dict in da_ranch" v-for="dict in da_ranch"
:key="dict.value" :key="dict.value"
@ -26,7 +27,6 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 操作按钮区域 -->
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -69,14 +69,13 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<!-- 数据表格 -->
<el-table <el-table
v-loading="loading" v-loading="loading"
:data="dryMatterCorrectionList" :data="dryMatterCorrectionList"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
style="width: 100%"> style="width: 100%">
<el-table-column type="selection" align="center" /> <el-table-column type="selection" align="center" />
<el-table-column label="年月" align="center" prop="datetime"> <el-table-column label="年月" align="center" prop="datetime" sortable>
<template #default="scope"> <template #default="scope">
<span>{{ parseTime(scope.row.datetime, '{y}-{m}') }}</span> <span>{{ parseTime(scope.row.datetime, '{y}-{m}') }}</span>
</template> </template>
@ -86,11 +85,10 @@
<dict-tag :options="da_ranch" :value="scope.row.factory"/> <dict-tag :options="da_ranch" :value="scope.row.factory"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="干物质含量" align="center" prop="content" /> <el-table-column label="干物质含量" align="center" prop="content" sortable />
<el-table-column label="干物质标准" align="center" prop="standard" /> <el-table-column label="干物质标准" align="center" prop="standard" sortable />
<el-table-column label="干物质系数" align="center" prop="coefficient"> <el-table-column label="干物质系数" align="center" prop="coefficient" sortable>
<template #default="scope"> <template #default="scope">
<!-- 修复确保显示两位小数 -->
<span>{{ formatCoefficient(scope.row.coefficient) }}</span> <span>{{ formatCoefficient(scope.row.coefficient) }}</span>
</template> </template>
</el-table-column> </el-table-column>
@ -102,16 +100,15 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 分页组件 -->
<pagination <pagination
v-show="total>0" v-show="total>0"
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pageSize"
:page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
@pagination="getList" @pagination="getList"
/> />
<!-- 添加/修改对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="dryMatterCorrectionRef" :model="form" :rules="rules" label-width="100px"> <el-form ref="dryMatterCorrectionRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="年月" prop="datetime"> <el-form-item label="年月" prop="datetime">
@ -140,7 +137,6 @@
<el-input v-model="form.standard" placeholder="请输入干物质标准" @input="calculateCoefficient" /> <el-input v-model="form.standard" placeholder="请输入干物质标准" @input="calculateCoefficient" />
</el-form-item> </el-form-item>
<el-form-item label="干物质系数"> <el-form-item label="干物质系数">
<!-- 修复确保显示两位小数 -->
<el-input :value="formatCoefficient(form.coefficient)" placeholder="自动计算" readonly> <el-input :value="formatCoefficient(form.coefficient)" placeholder="自动计算" readonly>
</el-input> </el-input>
</el-form-item> </el-form-item>
@ -156,7 +152,6 @@
</template> </template>
<script setup name="DryMatterCorrection"> <script setup name="DryMatterCorrection">
// API
import { import {
listDryMatterCorrection, listDryMatterCorrection,
getDryMatterCorrection, getDryMatterCorrection,
@ -164,11 +159,11 @@ import {
addDryMatterCorrection, addDryMatterCorrection,
updateDryMatterCorrection updateDryMatterCorrection
} from "@/api/dairyProducts/dryMatterCorrection/dryMatterCorrection.js" } from "@/api/dairyProducts/dryMatterCorrection/dryMatterCorrection.js"
import { getCurrentInstance, ref, reactive, toRefs } from 'vue'
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const { da_ranch } = proxy.useDict('da_ranch') const { da_ranch } = proxy.useDict('da_ranch')
//
const dryMatterCorrectionList = ref([]) const dryMatterCorrectionList = ref([])
const open = ref(false) const open = ref(false)
const loading = ref(true) const loading = ref(true)
@ -178,59 +173,51 @@ const single = ref(true)
const multiple = ref(true) const multiple = ref(true)
const total = ref(0) const total = ref(0)
const title = ref("") const title = ref("")
const dateRange = ref([]) //
// 使reactive // 使 reactive queryParams
const data = reactive({ const queryParams = reactive({
form: { pageNum: 1,
coefficient: null, pageSize: 20, // 20
standard: 18 // 18 factory: null,
}, // datetime 使 params.beginTime params.endTime
queryParams: {
pageNum: 1,
pageSize: 10,
datetime: null,
factory: null,
},
rules: {
datetime: [{
required: true,
message: "年月不能为空",
trigger: "blur"
}],
factory: [{
required: true,
message: "厂区不能为空",
trigger: "blur"
}],
content: [
{ required: true, message: "干物质含量不能为空", trigger: "blur" },
{ pattern: /^\d+(\.\d+)?$/, message: "请输入有效数字", trigger: "blur" }
],
standard: [
{ required: true, message: "干物质标准不能为空", trigger: "blur" },
{ pattern: /^\d+(\.\d+)?$/, message: "请输入有效数字", trigger: "blur" },
{ validator: (rule, value, callback) => {
if (value == 0) {
callback(new Error("干物质标准不能为零"));
} else {
callback();
}
}, trigger: "blur" }
]
}
}) })
const { queryParams, form, rules } = toRefs(data) const form = ref({
id: null,
datetime: null,
factory: null,
content: null,
standard: 18,
coefficient: null
})
const rules = {
datetime: [{ required: true, message: "年月不能为空", trigger: "blur" }],
factory: [{ required: true, message: "厂区不能为空", trigger: "blur" }],
content: [
{ required: true, message: "干物质含量不能为空", trigger: "blur" },
{ pattern: /^\d+(\.\d+)?$/, message: "请输入有效数字", trigger: "blur" }
],
standard: [
{ required: true, message: "干物质标准不能为空", trigger: "blur" },
{ pattern: /^\d+(\.\d+)?$/, message: "请输入有效数字", trigger: "blur" },
{ validator: (rule, value, callback) => {
if (value == 0) {
callback(new Error("干物质标准不能为零"));
} else {
callback();
}
}, trigger: "blur" }
]
}
/** 格式化系数显示,保留两位小数 */
function formatCoefficient(value) { function formatCoefficient(value) {
if (value === null || value === undefined) return ''; if (value === null || value === undefined) return '';
//
const num = typeof value === 'string' ? parseFloat(value) : value; const num = typeof value === 'string' ? parseFloat(value) : value;
return !isNaN(num) ? num.toFixed(2) : ''; return !isNaN(num) ? num.toFixed(2) : '';
} }
/** 计算干物质系数 - 保留两位小数 */
function calculateCoefficient() { function calculateCoefficient() {
if (form.value.content && form.value.standard && form.value.standard != 0) { if (form.value.content && form.value.standard && form.value.standard != 0) {
const content = parseFloat(form.value.content); const content = parseFloat(form.value.content);
@ -244,66 +231,65 @@ function calculateCoefficient() {
/** 查询干物质校正列表 */ /** 查询干物质校正列表 */
function getList() { function getList() {
loading.value = true loading.value = true
listDryMatterCorrection(queryParams.value).then(response => { //
// SQL DATE_FORMAT
proxy.addDateRange(queryParams, dateRange.value)
listDryMatterCorrection(queryParams).then(response => {
dryMatterCorrectionList.value = response.rows dryMatterCorrectionList.value = response.rows
total.value = response.total total.value = response.total
loading.value = false loading.value = false
}) })
} }
//
function cancel() { function cancel() {
open.value = false open.value = false
reset() reset()
} }
//
function reset() { function reset() {
form.value = { form.value = {
id: null, id: null,
datetime: null, datetime: null,
factory: null, factory: null,
content: null, content: null,
standard: 18, // 18 standard: 18,
coefficient: null coefficient: null
} }
proxy.resetForm("dryMatterCorrectionRef") proxy.resetForm("dryMatterCorrectionRef")
} }
/** 搜索按钮操作 */ /** 搜索按钮操作 */
function handleQuery() { function handleQuery() {
queryParams.value.pageNum = 1 queryParams.pageNum = 1
getList() getList()
} }
/** 重置按钮操作 */ /** 重置按钮操作 */
function resetQuery() { function resetQuery() {
dateRange.value = [] //
queryParams.factory = null //
proxy.resetForm("queryRef") proxy.resetForm("queryRef")
handleQuery() handleQuery()
} }
//
function handleSelectionChange(selection) { function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id) ids.value = selection.map(item => item.id)
single.value = selection.length != 1 single.value = selection.length != 1
multiple.value = !selection.length multiple.value = !selection.length
} }
/** 新增按钮操作 */
function handleAdd() { function handleAdd() {
reset() reset()
open.value = true open.value = true
title.value = "添加干物质校正" title.value = "添加干物质校正"
} }
/** 修改按钮操作 */
function handleUpdate(row) { function handleUpdate(row) {
reset() reset()
const _id = row.id || ids.value const _id = row.id || ids.value
getDryMatterCorrection(_id).then(response => { getDryMatterCorrection(_id).then(response => {
form.value = response.data form.value = response.data
//
if (form.value.content && form.value.standard) { if (form.value.content && form.value.standard) {
form.value.coefficient = form.value.content / form.value.standard; form.value.coefficient = form.value.content / form.value.standard;
} }
@ -316,49 +302,33 @@ function handleUpdate(row) {
}) })
} }
/** 提交按钮 */
function submitForm() { function submitForm() {
proxy.$refs["dryMatterCorrectionRef"].validate(valid => { proxy.$refs["dryMatterCorrectionRef"].validate(valid => {
if (valid) { if (valid) {
// //
if (form.value.content && form.value.standard && form.value.standard != 0) { if (form.value.content && form.value.standard && form.value.standard != 0) {
const content = parseFloat(form.value.content); const content = parseFloat(form.value.content);
const standard = parseFloat(form.value.standard); const standard = parseFloat(form.value.standard);
form.value.coefficient = Math.round((content / standard) * 100) / 100; form.value.coefficient = Math.round((content / standard) * 100) / 100;
} }
if (form.value.id != null) { const request = form.value.id ? updateDryMatterCorrection(form.value) : addDryMatterCorrection(form.value);
updateDryMatterCorrection(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功") request.then(response => {
open.value = false proxy.$modal.msgSuccess(form.value.id ? "修改成功" : "新增成功");
getList() open.value = false;
}).catch(error => { getList();
// }).catch(error => {
if (error.message && error.message.includes("已存在记录")) { if (error.message && error.message.includes("已存在记录")) {
proxy.$modal.msgError(error.message); proxy.$modal.msgError(error.message);
} else { } else {
proxy.$modal.msgError("修改失败:" + (error.message || "未知错误")); proxy.$modal.msgError((form.value.id ? "修改" : "新增") + "失败:" + (error.message || "未知错误"));
} }
}) });
} else {
addDryMatterCorrection(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
}).catch(error => {
//
if (error.message && error.message.includes("已存在记录")) {
proxy.$modal.msgError(error.message);
} else {
proxy.$modal.msgError("新增失败:" + (error.message || "未知错误"));
}
})
}
} }
}) })
} }
/** 删除按钮操作 */
function handleDelete(row) { function handleDelete(row) {
const _ids = row.id || ids.value const _ids = row.id || ids.value
proxy.$modal.confirm('是否确认删除干物质校正编号为"' + _ids + '"的数据项?').then(function() { proxy.$modal.confirm('是否确认删除干物质校正编号为"' + _ids + '"的数据项?').then(function() {
@ -369,10 +339,9 @@ function handleDelete(row) {
}).catch(() => {}) }).catch(() => {})
} }
/** 导出按钮操作 */
function handleExport() { function handleExport() {
proxy.download('dryMatterCorrection/dryMatterCorrection/export', { proxy.download('dryMatterCorrection/dryMatterCorrection/export', {
...queryParams.value ...queryParams
}, `干物质校正数据_${new Date().getTime()}.xlsx`) }, `干物质校正数据_${new Date().getTime()}.xlsx`)
} }
@ -380,36 +349,27 @@ getList()
</script> </script>
<style scoped> <style scoped>
/* 添加表格样式 */
.el-table { .el-table {
font-size: 14px; font-size: 14px;
} }
.el-table th { .el-table th {
background-color: #f5f7fa; background-color: #f5f7fa;
color: #606266; color: #606266;
font-weight: bold; font-weight: bold;
} }
.el-table td, .el-table th { .el-table td, .el-table th {
padding: 12px 0; padding: 12px 0;
} }
.el-table .cell { .el-table .cell {
padding: 0 15px; padding: 0 15px;
} }
/* 调整操作列按钮间距 */
.el-button + .el-button { .el-button + .el-button {
margin-left: 5px; margin-left: 5px;
} }
/* 确保表单元素宽度一致 */
/* 调整表单元素宽度 */
.el-input, .el-select { .el-input, .el-select {
width: 100%; width: 100%;
} }
/* 调整搜索表单布局 */
.el-form-item { .el-form-item {
margin-bottom: 15px; margin-bottom: 15px;
} }

View File

@ -1,6 +1,5 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- 简化查询表单 -->
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="80px"> <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="80px">
<el-form-item label="来源" prop="source"> <el-form-item label="来源" prop="source">
<el-input <el-input
@ -10,13 +9,15 @@
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="检测日期" prop="datetime"> <el-form-item label="检测日期" style="width: 308px">
<el-date-picker clearable <el-date-picker
v-model="queryParams.datetime" v-model="dateRange"
type="date"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
placeholder="请选择检测日期"> type="daterange"
</el-date-picker> range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@ -74,7 +75,6 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<!-- 表格显示使用列选择功能 -->
<el-table v-loading="loading" :data="freshMilkTestList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="freshMilkTestList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column <el-table-column
@ -87,71 +87,86 @@
align="center" align="center"
prop="datetime" prop="datetime"
width="180" width="180"
v-if="selectedColumns.includes('datetime')"> v-if="selectedColumns.includes('datetime')"
sortable>
<template #default="scope"> <template #default="scope">
<span>{{ formatDate(scope.row.datetime) }}</span> <span>{{ formatDate(scope.row.datetime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="脂肪g/100g" label="脂肪g/100g"
align="center" align="center"
prop="fat" prop="fat"
v-if="selectedColumns.includes('fat')" /> v-if="selectedColumns.includes('fat')"
sortable />
<el-table-column <el-table-column
label="蛋白质g/100g" label="蛋白质g/100g"
align="center" align="center"
prop="protein" prop="protein"
v-if="selectedColumns.includes('protein')" /> v-if="selectedColumns.includes('protein')"
sortable />
<el-table-column <el-table-column
label="非脂g/100g" label="非脂g/100g"
align="center" align="center"
prop="nonFat" prop="nonFat"
v-if="selectedColumns.includes('nonFat')" /> v-if="selectedColumns.includes('nonFat')"
sortable />
<el-table-column <el-table-column
label="酸度oT" label="酸度oT"
align="center" align="center"
prop="acidity" prop="acidity"
v-if="selectedColumns.includes('acidity')" /> v-if="selectedColumns.includes('acidity')"
sortable />
<el-table-column <el-table-column
label="菌落总数1" label="菌落总数1"
align="center" align="center"
prop="bacterialColony1" prop="bacterialColony1"
v-if="selectedColumns.includes('bacterialColony1')" /> v-if="selectedColumns.includes('bacterialColony1')"
sortable />
<el-table-column <el-table-column
label="菌落总数2" label="菌落总数2"
align="center" align="center"
prop="bacterialColony2" prop="bacterialColony2"
v-if="selectedColumns.includes('bacterialColony2')" /> v-if="selectedColumns.includes('bacterialColony2')"
sortable />
<el-table-column <el-table-column
label="菌落总数3" label="菌落总数3"
align="center" align="center"
prop="bacterialColony3" prop="bacterialColony3"
v-if="selectedColumns.includes('bacterialColony3')" /> v-if="selectedColumns.includes('bacterialColony3')"
sortable />
<el-table-column <el-table-column
label="菌落总数4" label="菌落总数4"
align="center" align="center"
prop="bacterialColony4" prop="bacterialColony4"
v-if="selectedColumns.includes('bacterialColony4')" /> v-if="selectedColumns.includes('bacterialColony4')"
sortable />
<el-table-column <el-table-column
label="菌落总数5" label="菌落总数5"
align="center" align="center"
prop="bacterialColony5" prop="bacterialColony5"
v-if="selectedColumns.includes('bacterialColony5')" /> v-if="selectedColumns.includes('bacterialColony5')"
sortable />
<el-table-column <el-table-column
label="大肠菌群(CFU/ml)" label="大肠菌群(CFU/ml)"
align="center" align="center"
prop="coli" prop="coli"
v-if="selectedColumns.includes('coli')" /> v-if="selectedColumns.includes('coli')"
sortable />
<el-table-column <el-table-column
label="乳铁蛋白(mg/L)" label="乳铁蛋白(mg/L)"
align="center" align="center"
prop="lactoferrin" prop="lactoferrin"
v-if="selectedColumns.includes('lactoferrin')" /> v-if="selectedColumns.includes('lactoferrin')"
sortable />
<el-table-column <el-table-column
label="免疫球蛋白(mg/L)" label="免疫球蛋白(mg/L)"
align="center" align="center"
prop="ig" prop="ig"
v-if="selectedColumns.includes('ig')" /> v-if="selectedColumns.includes('ig')"
sortable />
<el-table-column <el-table-column
label="备注" label="备注"
align="center" align="center"
@ -167,7 +182,8 @@
align="center" align="center"
prop="createTime" prop="createTime"
width="180" width="180"
v-if="selectedColumns.includes('createTime')"> v-if="selectedColumns.includes('createTime')"
sortable>
<template #default="scope"> <template #default="scope">
<span>{{ formatDateTime(scope.row.createTime) }}</span> <span>{{ formatDateTime(scope.row.createTime) }}</span>
</template> </template>
@ -185,10 +201,10 @@
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pageSize"
:page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
@pagination="getList" @pagination="getList"
/> />
<!-- 新增/修改对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="freshMilkTestRef" :model="form" :rules="rules" label-width="120px"> <el-form ref="freshMilkTestRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="来源" prop="source"> <el-form-item label="来源" prop="source">
@ -257,7 +273,6 @@
</template> </template>
</el-dialog> </el-dialog>
<!-- 列显示设置对话框 -->
<el-dialog title="列显示设置" v-model="columnShowDialogVisible" width="500px"> <el-dialog title="列显示设置" v-model="columnShowDialogVisible" width="500px">
<el-checkbox-group v-model="selectedColumns"> <el-checkbox-group v-model="selectedColumns">
<el-checkbox label="source">来源</el-checkbox> <el-checkbox label="source">来源</el-checkbox>
@ -288,13 +303,14 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, onMounted } from 'vue'; import { ref, reactive, onMounted, getCurrentInstance } from 'vue';
import { listFreshMilkTest, getFreshMilkTest, delFreshMilkTest, addFreshMilkTest, updateFreshMilkTest } from "@/api/dairyProducts/freshMilkTest/freshMilkTest.js"; import { listFreshMilkTest, getFreshMilkTest, delFreshMilkTest, addFreshMilkTest, updateFreshMilkTest } from "@/api/dairyProducts/freshMilkTest/freshMilkTest.js";
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
// xlsxfile-saver
import * as XLSX from 'xlsx'; import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
const { proxy } = getCurrentInstance(); // proxy
const freshMilkTestList = ref([]); const freshMilkTestList = ref([]);
const open = ref(false); const open = ref(false);
const loading = ref(true); const loading = ref(true);
@ -306,6 +322,7 @@ const total = ref(0);
const title = ref(""); const title = ref("");
const columnShowDialogVisible = ref(false); const columnShowDialogVisible = ref(false);
const freshMilkTestRef = ref(null); const freshMilkTestRef = ref(null);
const dateRange = ref([]); //
// //
const columnConfig = [ const columnConfig = [
@ -339,9 +356,9 @@ const selectedColumns = ref([
// //
const queryParams = reactive({ const queryParams = reactive({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 20, //
source: null, source: null,
datetime: null, // datetime 使 dateRange
}); });
// //
@ -385,6 +402,8 @@ const getCurrentUsername = () => {
/** 查询列表 */ /** 查询列表 */
function getList() { function getList() {
loading.value = true; loading.value = true;
//
proxy.addDateRange(queryParams, dateRange.value);
listFreshMilkTest(queryParams).then(response => { listFreshMilkTest(queryParams).then(response => {
freshMilkTestList.value = response.rows || []; freshMilkTestList.value = response.rows || [];
total.value = response.total || 0; total.value = response.total || 0;
@ -471,9 +490,9 @@ function handleQuery() {
/** 重置按钮操作 */ /** 重置按钮操作 */
function resetQuery() { function resetQuery() {
dateRange.value = []; //
Object.assign(queryParams, { Object.assign(queryParams, {
source: null, source: null,
datetime: null,
}); });
handleQuery(); handleQuery();
} }

View File

@ -1,35 +1,42 @@
<template> <template>
<div> <div class="app-container">
<el-form :inline="true" :model="queryParams" class="mb-4"> <el-form :inline="true" :model="queryParams" class="mb-4">
<el-form-item label="开始日期"> <el-form-item label="日期范围">
<el-date-picker v-model="queryParams.datetimeStart" type="date" value-format="YYYY-MM-DD"/> <el-date-picker
v-model="dateRange"
type="daterange"
value-format="YYYY-MM-DD"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
style="width: 260px"
/>
</el-form-item> </el-form-item>
<el-form-item label="结束日期"> <el-form-item>
<el-date-picker v-model="queryParams.datetimeEnd" type="date" value-format="YYYY-MM-DD"/> <el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
<el-button type="primary" @click="getList">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form> </el-form>
<el-row :gutter="10" style="margin-bottom: 16px;"> <el-row :gutter="10" style="margin-bottom: 16px;">
<el-col :span="24"> <el-col :span="24">
<el-upload :before-upload="beforeUpload" :show-file-list="false" style="display: inline-block; margin: 0 8px;"> <el-upload :before-upload="beforeUpload" :show-file-list="false" style="display: inline-block; margin: 0 8px;">
<el-button type="primary">导入</el-button> <el-button type="info" plain icon="Upload">导入</el-button>
</el-upload> </el-upload>
<el-button type="success" @click="handleExport">导出</el-button> <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
<el-button @click="openColDialog">列设置</el-button> <el-button type="primary" plain icon="Menu" @click="openColDialog">列设置</el-button>
</el-col> </el-col>
</el-row> </el-row>
<el-dialog v-model="colDialog" title="选择展示列"> <el-dialog v-model="colDialog" title="选择展示列" width="600px">
<div> <div>
<strong>饲喂来源</strong> <div style="margin-bottom: 10px; font-weight: bold;">饲喂来源</div>
<el-checkbox-group v-model="selectedFeed"> <el-checkbox-group v-model="selectedFeed">
<el-checkbox v-for="f in allCols.feed" :key="f" :label="f">{{ f }}</el-checkbox> <el-checkbox v-for="f in allCols.feed" :key="f" :label="f">{{ f }}</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</div> </div>
<div style="margin-top:1em"> <div style="margin-top: 20px;">
<strong>销售去向</strong> <div style="margin-bottom: 10px; font-weight: bold;">销售去向</div>
<el-checkbox-group v-model="selectedSale"> <el-checkbox-group v-model="selectedSale">
<el-checkbox v-for="s in allCols.sale" :key="s" :label="s">{{ s }}</el-checkbox> <el-checkbox v-for="s in allCols.sale" :key="s" :label="s">{{ s }}</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
@ -42,43 +49,45 @@
</template> </template>
</el-dialog> </el-dialog>
<el-table :data="rows" border style="margin-top:16px"> <el-table :data="rows" border style="margin-top:16px" v-loading="loading">
<!-- 前面的固定列 --> <el-table-column prop="datetime" label="日期" width="120" sortable fixed="left">
<el-table-column prop="datetime" label="日期"/> <template #default="{ row }">
<el-table-column prop="num" label="羊数"/> {{ row.datetime ? row.datetime.substring(0, 10) : '' }}
<el-table-column prop="colostSheep" label="初乳羊"/> </template>
<el-table-column prop="commercialIntake" label="商乳入库"/> </el-table-column>
<el-table-column prop="antiIntake" label="抗乳入库"/>
<el-table-column prop="colostIntake" label="初乳入库"/>
<el-table-column prop="intakeTotal" label="入库小计"/>
<el-table-column prop="commercialTest" label="商乳实验用奶"/>
<el-table-column prop="colostTest" label="初乳实验用奶"/>
<el-table-column prop="transferCommercial" label="商乳调拨出库"/>
<el-table-column prop="transferAnti" label="抗乳调拨出库"/>
<el-table-column prop="transferColost" label="初乳调拨出库"/>
<el-table-column prop="transferTotal" label="调拨小计"/>
<el-table-column prop="loss" label="损耗"/>
<!-- 动态饲喂来源列插入到这里 --> <el-table-column prop="num" label="羊数" sortable width="100" />
<el-table-column v-for="f in selectedFeed" :key="'feed-'+f" :prop="f" :label="f"/> <el-table-column prop="colostSheep" label="初乳羊" sortable width="100" />
<!-- 动态销售去向列 --> <el-table-column prop="commercialIntake" label="商乳入库" sortable width="120" />
<el-table-column v-for="s in selectedSale" :key="'sale-'+s" :prop="s" :label="s"/> <el-table-column prop="antiIntake" label="抗乳入库" sortable width="120" />
<el-table-column prop="colostIntake" label="初乳入库" sortable width="120" />
<el-table-column prop="intakeTotal" label="入库小计" sortable width="120" />
<el-table-column prop="commercialTest" label="商乳实验用奶" sortable width="140" />
<el-table-column prop="colostTest" label="初乳实验用奶" sortable width="140" />
<el-table-column prop="transferCommercial" label="商乳调拨出库" sortable width="140" />
<el-table-column prop="transferAnti" label="抗乳调拨出库" sortable width="140" />
<el-table-column prop="transferColost" label="初乳调拨出库" sortable width="140" />
<el-table-column prop="transferTotal" label="调拨小计" sortable width="120" />
<el-table-column prop="loss" label="损耗" sortable width="100" />
<!-- 后面的固定列 --> <el-table-column v-for="f in selectedFeed" :key="'feed-'+f" :prop="f" :label="f" sortable width="120" />
<el-table-column prop="stockCommercial" label="商乳库存"/> <el-table-column v-for="s in selectedSale" :key="'sale-'+s" :prop="s" :label="s" sortable width="120" />
<el-table-column prop="stockAnti" label="抗乳库存"/>
<el-table-column prop="colost" label="初乳库存"/> <el-table-column prop="stockCommercial" label="商乳库存" sortable width="120" />
<el-table-column prop="returnFresh" label="爱特退回鲜奶"/> <el-table-column prop="stockAnti" label="抗乳库存" sortable width="120" />
<el-table-column prop="returnYogurt" label="爱特退回酸奶"/> <el-table-column prop="colost" label="初乳库存" sortable width="120" />
<el-table-column prop="returnFresh" label="爱特退回鲜奶" sortable width="140" />
<el-table-column prop="returnYogurt" label="爱特退回酸奶" sortable width="140" />
</el-table> </el-table>
<el-pagination <pagination
style="margin-top:16px; text-align:right" v-show="total>0"
:total="total" :total="total"
v-model:page-size="queryParams.pageSize" v-model:page="queryParams.pageNum"
v-model:current-page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
@current-change="getList"> :page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
</el-pagination> @pagination="getList"
/>
</div> </div>
</template> </template>
@ -88,12 +97,14 @@ import { ref, reactive, onMounted } from 'vue'
import { getList as fetchList, importExcel, exportExcel, getColumns } from '@/api/dairyProducts/milkInOutStore/milkInOutStore.js' import { getList as fetchList, importExcel, exportExcel, getColumns } from '@/api/dairyProducts/milkInOutStore/milkInOutStore.js'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
const loading = ref(false)
const queryParams = reactive({ const queryParams = reactive({
datetimeStart: null, datetimeStart: null,
datetimeEnd: null, datetimeEnd: null,
pageNum: 1, pageNum: 1,
pageSize: 10 pageSize: 20 // 20
}) })
const dateRange = ref([]) //
const rows = ref([]) const rows = ref([])
const total = ref(0) const total = ref(0)
const allCols = reactive({ feed: [], sale: [] }) const allCols = reactive({ feed: [], sale: [] })
@ -102,13 +113,34 @@ const selectedSale = ref([])
const colDialog = ref(false) const colDialog = ref(false)
function getList() { function getList() {
loading.value = true
//
if (dateRange.value && dateRange.value.length === 2) {
queryParams.datetimeStart = dateRange.value[0];
queryParams.datetimeEnd = dateRange.value[1];
} else {
queryParams.datetimeStart = null;
queryParams.datetimeEnd = null;
}
fetchList(queryParams).then(res => { fetchList(queryParams).then(res => {
rows.value = res.rows rows.value = res.rows
total.value = res.total total.value = res.total
loading.value = false
}).catch(err => {
loading.value = false
console.error(err)
}) })
} }
function handleQuery() {
queryParams.pageNum = 1
getList()
}
function resetQuery() { function resetQuery() {
dateRange.value = [] //
queryParams.datetimeStart = null queryParams.datetimeStart = null
queryParams.datetimeEnd = null queryParams.datetimeEnd = null
queryParams.pageNum = 1 queryParams.pageNum = 1
@ -120,9 +152,13 @@ function openColDialog() {
const d = res.data[0] const d = res.data[0]
allCols.feed = d.feed || [] allCols.feed = d.feed || []
allCols.sale = d.sale || [] allCols.sale = d.sale || []
// /
selectedFeed.value = [...allCols.feed] //
selectedSale.value = [...allCols.sale] if (selectedFeed.value.length === 0 && selectedSale.value.length === 0) {
selectedFeed.value = [...allCols.feed]
selectedSale.value = [...allCols.sale]
}
colDialog.value = true colDialog.value = true
}) })
} }
@ -143,15 +179,44 @@ function beforeUpload(file) {
} }
function handleExport() { function handleExport() {
//
if (dateRange.value && dateRange.value.length === 2) {
queryParams.datetimeStart = dateRange.value[0];
queryParams.datetimeEnd = dateRange.value[1];
} else {
queryParams.datetimeStart = null;
queryParams.datetimeEnd = null;
}
exportExcel(queryParams).then(blob => { exportExcel(queryParams).then(blob => {
const link = document.createElement('a') const link = document.createElement('a')
link.href = URL.createObjectURL(blob) link.href = URL.createObjectURL(blob)
link.download = `milk_in_out_store_${Date.now()}.xlsx` link.download = `milk_in_out_store_${Date.now()}.xlsx`
link.click() link.click()
URL.revokeObjectURL(link.href)
}).catch(err => { }).catch(err => {
ElMessage.error('导出失败:' + (err.message || err)) ElMessage.error('导出失败:' + (err.message || err))
}) })
} }
onMounted(() => getList()) onMounted(() => {
</script> //
getColumns().then(res => {
const d = res.data[0]
allCols.feed = d.feed || []
allCols.sale = d.sale || []
selectedFeed.value = [...allCols.feed]
selectedSale.value = [...allCols.sale]
getList()
})
})
</script>
<style scoped>
.app-container {
padding: 20px;
}
.mb-4 {
margin-bottom: 16px;
}
</style>

View File

@ -1,26 +1,23 @@
<!-- index.vue (前端视图仅保留单日查询功能) -->
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form ref="queryRef" :model="queryParams" inline label-width="80px"> <el-form ref="queryRef" :model="queryParams" inline label-width="80px">
<!-- 单日查询 --> <el-form-item label="查询日期" style="width: 308px">
<el-form-item label="查询日期">
<el-date-picker <el-date-picker
v-model="queryDate" v-model="dateRange"
type="date" type="daterange"
placeholder="选择查询日期" range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
clearable /> clearable />
</el-form-item> </el-form-item>
<!-- 管理耳号输入框 -->
<el-form-item label="管理耳号"> <el-form-item label="管理耳号">
<el-input v-model="queryParams.manageEarNo" placeholder="请输入管理耳号" clearable /> <el-input v-model="queryParams.manageEarNo" placeholder="请输入管理耳号" clearable />
</el-form-item> </el-form-item>
<!-- 厂区下拉框 -->
<el-form-item label="厂区"> <el-form-item label="厂区">
<el-select v-model="queryParams.factory" clearable placeholder="请选择"> <el-select v-model="queryParams.factory" clearable placeholder="请选择" style="width: 180px">
<el-option <el-option
v-for="d in ranchOptions" v-for="d in ranchOptions"
:key="d.value" :key="d.value"
@ -29,42 +26,50 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 班次下拉框 -->
<el-form-item label="班次"> <el-form-item label="班次">
<el-select v-model="queryParams.classes" clearable placeholder="请选择"> <el-select v-model="queryParams.classes" clearable placeholder="请选择" style="width: 120px">
<el-option :value="1" label="1" /> <el-option :value="1" label="1" />
<el-option :value="2" label="2" /> <el-option :value="2" label="2" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="getList">查询</el-button> <el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button> <el-button @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-row> <el-row :gutter="10" class="mb8">
<el-button type="info" plain @click="handleImport" v-hasPermi="['milkProdclasses:milkProdclasses:import']"> <el-col :span="1.5">
<el-icon><Upload /></el-icon> 导入 <el-button type="info" plain @click="handleImport" v-hasPermi="['milkProdclasses:milkProdclasses:import']">
</el-button> <el-icon><Upload /></el-icon> 导入
<el-button type="warning" plain @click="handleExport" v-hasPermi="['milkProdclasses:milkProdclasses:export']"> </el-button>
<el-icon><Download /></el-icon> 导出 </el-col>
</el-button> <el-col :span="1.5">
<el-button type="warning" plain @click="handleExport" v-hasPermi="['milkProdclasses:milkProdclasses:export']">
<el-icon><Download /></el-icon> 导出
</el-button>
</el-col>
</el-row> </el-row>
<el-table :data="tableData" v-loading="loading"> <el-table :data="tableData" v-loading="loading">
<el-table-column prop="datetime" label="日期" width="110" /> <el-table-column prop="datetime" label="日期" width="110" sortable>
<template #default="{ row }">
{{ parseTime(row.datetime, '{y}-{m}-{d}') }}
</template>
</el-table-column>
<el-table-column prop="manageEarNo" label="管理耳号" /> <el-table-column prop="manageEarNo" label="管理耳号" />
<el-table-column prop="electronicEarNo" label="电子耳号" /> <el-table-column prop="electronicEarNo" label="电子耳号" />
<el-table-column prop="parity" label="胎次" /> <el-table-column prop="parity" label="胎次" sortable />
<el-table-column prop="factory" label="厂区" /> <el-table-column prop="factory" label="厂区" />
<el-table-column prop="classes" label="班次" /> <el-table-column prop="classes" label="班次" sortable />
<el-table-column prop="milk" label="班次产奶量" >
<el-table-column prop="milk" label="班次产奶量" sortable>
<template #default="{ row }"> <template #default="{ row }">
{{ row.milk ? Number(row.milk).toFixed(2) : '-' }} {{ row.milk ? Number(row.milk).toFixed(2) : '-' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="correctedMilk" label="班次校正奶量" > <el-table-column prop="correctedMilk" label="班次校正奶量" sortable>
<template #default="{ row }"> <template #default="{ row }">
{{ row.correctedMilk ? Number(row.correctedMilk).toFixed(2) : '-' }} {{ row.correctedMilk ? Number(row.correctedMilk).toFixed(2) : '-' }}
</template> </template>
@ -74,9 +79,9 @@
<pagination v-show="total>0" :total="total" <pagination v-show="total>0" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pageSize"
:page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
@pagination="getList" /> @pagination="getList" />
<!-- 导入弹窗 -->
<el-dialog title="Excel导入" v-model="openImport" width="400px"> <el-dialog title="Excel导入" v-model="openImport" width="400px">
<el-upload drag :action="uploadUrl" :headers="headers" <el-upload drag :action="uploadUrl" :headers="headers"
accept=".xls,.xlsx" :on-success="uploadSuccess" :on-error="uploadError"> accept=".xls,.xlsx" :on-success="uploadSuccess" :on-error="uploadError">
@ -88,13 +93,15 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, onMounted } from 'vue' import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import { listMilkProdclasses, importMilkProdclasses, exportMilkProdclasses } from '@/api/dairyProducts/milkProdclasses/milkProdclasses' import { listMilkProdclasses, importMilkProdclasses, exportMilkProdclasses } from '@/api/dairyProducts/milkProdclasses/milkProdclasses'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { getRanchList } from '@/api/dairyProducts/ranch/ranch.js' import { getRanchList } from '@/api/dairyProducts/ranch/ranch.js'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { Upload, Download, UploadFilled } from '@element-plus/icons-vue'; import { Upload, Download, UploadFilled } from '@element-plus/icons-vue';
import { parseTime } from '@/utils/ruoyi'
const { proxy } = getCurrentInstance()
const ranchOptions = ref([]) const ranchOptions = ref([])
onMounted(() => { onMounted(() => {
@ -110,14 +117,14 @@ onMounted(() => {
const queryParams = reactive({ const queryParams = reactive({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 20, // 20
datetimeStart: null, // datetimeStart: null, //
datetimeEnd: null, // datetimeEnd: null, //
manageEarNo: '', // manageEarNo: '', //
factory: null, // factory: null, //
classes: null // classes: null //
}) })
const queryDate = ref(null) // const dateRange = ref([]) //
const tableData = ref([]) // const tableData = ref([]) //
const total = ref(0) // const total = ref(0) //
const loading = ref(false) // const loading = ref(false) //
@ -129,24 +136,16 @@ const headers = { Authorization: 'Bearer ' + getToken() };
function getList() { function getList() {
loading.value = true loading.value = true
// //
if (queryDate.value) { if (dateRange.value && dateRange.value.length === 2) {
queryParams.datetimeStart = queryDate.value; queryParams.datetimeStart = dateRange.value[0];
queryParams.datetimeEnd = queryDate.value; queryParams.datetimeEnd = dateRange.value[1];
} else { } else {
queryParams.datetimeStart = null; queryParams.datetimeStart = null;
queryParams.datetimeEnd = null; queryParams.datetimeEnd = null;
} }
listMilkProdclasses({ listMilkProdclasses(queryParams).then(res => {
datetimeStart: queryParams.datetimeStart,
datetimeEnd: queryParams.datetimeEnd,
manageEarNo: queryParams.manageEarNo,
factory: queryParams.factory,
classes: queryParams.classes,
pageNum: queryParams.pageNum,
pageSize: queryParams.pageSize
}).then(res => {
tableData.value = res.rows tableData.value = res.rows
total.value = res.total total.value = res.total
loading.value = false loading.value = false
@ -156,16 +155,20 @@ function getList() {
}); });
} }
function handleQuery() {
queryParams.pageNum = 1;
getList();
}
function resetQuery() { function resetQuery() {
Object.assign(queryParams, { dateRange.value = []; //
pageNum: 1, //
datetimeStart: null, queryParams.datetimeStart = null;
datetimeEnd: null, queryParams.datetimeEnd = null;
manageEarNo: '', queryParams.manageEarNo = '';
factory: null, queryParams.factory = null;
classes: null queryParams.classes = null;
}); queryParams.pageNum = 1;
queryDate.value = null;
getList(); getList();
} }
@ -186,41 +189,30 @@ function uploadError(err) {
} }
function handleExport() { function handleExport() {
// //
if (queryDate.value) { if (dateRange.value && dateRange.value.length === 2) {
queryParams.datetimeStart = queryDate.value; queryParams.datetimeStart = dateRange.value[0];
queryParams.datetimeEnd = queryDate.value; queryParams.datetimeEnd = dateRange.value[1];
} else { } else {
queryParams.datetimeStart = null; queryParams.datetimeStart = null;
queryParams.datetimeEnd = null; queryParams.datetimeEnd = null;
} }
exportMilkProdclasses({ exportMilkProdclasses(queryParams).then(response => {
datetimeStart: queryParams.datetimeStart,
datetimeEnd: queryParams.datetimeEnd,
manageEarNo: queryParams.manageEarNo,
factory: queryParams.factory,
classes: queryParams.classes
}).then(response => {
// Blob
const blob = new Blob([response], { const blob = new Blob([response], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
}); });
//
const downloadElement = document.createElement('a'); const downloadElement = document.createElement('a');
const href = window.URL.createObjectURL(blob); const href = window.URL.createObjectURL(blob);
downloadElement.href = href; downloadElement.href = href;
//
const now = new Date(); const now = new Date();
const dateStr = `${now.getFullYear()}${(now.getMonth()+1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}`; const dateStr = `${now.getFullYear()}${(now.getMonth()+1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}`;
downloadElement.download = `班次产奶数据_${dateStr}.xlsx`; downloadElement.download = `班次产奶数据_${dateStr}.xlsx`;
document.body.appendChild(downloadElement); document.body.appendChild(downloadElement);
//
downloadElement.click(); downloadElement.click();
// URL
document.body.removeChild(downloadElement); document.body.removeChild(downloadElement);
window.URL.revokeObjectURL(href); window.URL.revokeObjectURL(href);

View File

@ -1,7 +1,6 @@
<template> <template>
<div class="app-container"> <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">
<!-- 搜索条件 只保留胎次 -->
<el-form-item label="胎次" prop="parity"> <el-form-item label="胎次" prop="parity">
<el-input <el-input
v-model="queryParams.parity" v-model="queryParams.parity"
@ -46,15 +45,15 @@
v-hasPermi="['parityCorrection:parityCorrection:remove']" v-hasPermi="['parityCorrection:parityCorrection:remove']"
>删除</el-button> >删除</el-button>
</el-col> </el-col>
<!-- 去掉导出按钮 -->
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<el-table v-loading="loading" :data="parityCorrectionList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="parityCorrectionList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<!-- 去掉 ${comment} -->
<el-table-column label="胎次" align="center" prop="parity" /> <el-table-column label="胎次" align="center" prop="parity" sortable />
<el-table-column label="系数" align="center" prop="coef" /> <el-table-column label="系数" align="center" prop="coef" sortable />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['parityCorrection:parityCorrection:edit']">修改</el-button> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['parityCorrection:parityCorrection:edit']">修改</el-button>
@ -68,10 +67,10 @@
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pageSize"
:page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
@pagination="getList" @pagination="getList"
/> />
<!-- 添加或修改胎次校正对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="parityCorrectionRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="parityCorrectionRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="胎次" prop="parity"> <el-form-item label="胎次" prop="parity">
@ -92,7 +91,8 @@
</template> </template>
<script setup name="ParityCorrection"> <script setup name="ParityCorrection">
import { listParityCorrection, getParityCorrection, delParityCorrection, addParityCorrection, updateParityCorrection } from "@/api/dairyProducts/parityCorrection/parityCorrection" import { listParityCorrection, getParityCorrection, delParityCorrection, addParityCorrection, updateParityCorrection } from "@/api/dairyProducts/parityCorrection/parityCorrection.js"
import { getCurrentInstance, ref, reactive, toRefs } from 'vue'
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
@ -110,8 +110,8 @@ const data = reactive({
form: {}, form: {},
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 20, // 20
parity: null // parity: null
}, },
rules: {} rules: {}
}) })
@ -214,4 +214,4 @@ function handleDelete(row) {
} }
getList() getList()
</script> </script>

View File

@ -1,13 +1,15 @@
<template> <template>
<div class="app-container"> <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">
<el-form-item label="检测日期" prop="datetime"> <el-form-item label="检测日期" style="width: 308px">
<el-date-picker clearable <el-date-picker
v-model="queryParams.datetime" v-model="dateRange"
type="date"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
placeholder="请选择检测日期"> type="daterange"
</el-date-picker> range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="来源" prop="source"> <el-form-item label="来源" prop="source">
<el-input <el-input
@ -75,32 +77,34 @@
<el-table v-loading="loading" :data="rawMilkTestList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="rawMilkTestList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="检测日期" align="center" prop="datetime" width="180" v-if="visibleColumns.datetime"> <el-table-column label="检测日期" align="center" prop="datetime" width="180" v-if="visibleColumns.datetime" sortable>
<template #default="scope"> <template #default="scope">
<span>{{ parseTime(scope.row.datetime, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.datetime, '{y}-{m}-{d}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="来源" align="center" prop="source" v-if="visibleColumns.source" /> <el-table-column label="来源" align="center" prop="source" v-if="visibleColumns.source" />
<el-table-column label="冰点" align="center" prop="freeze" v-if="visibleColumns.freeze" />
<el-table-column label="相对密度" align="center" prop="density" v-if="visibleColumns.density" /> <el-table-column label="冰点" align="center" prop="freeze" v-if="visibleColumns.freeze" sortable />
<el-table-column label="脂肪g/100g" align="center" prop="fat" v-if="visibleColumns.fat" /> <el-table-column label="相对密度" align="center" prop="density" v-if="visibleColumns.density" sortable />
<el-table-column label="蛋白质g/100g" align="center" prop="protein" v-if="visibleColumns.protein" /> <el-table-column label="脂肪g/100g" align="center" prop="fat" v-if="visibleColumns.fat" sortable />
<el-table-column label="非脂g/100g" align="center" prop="nonFat" v-if="visibleColumns.nonFat" /> <el-table-column label="蛋白质g/100g" align="center" prop="protein" v-if="visibleColumns.protein" sortable />
<el-table-column label="干物质mg/100g" align="center" prop="dryMatter" v-if="visibleColumns.dryMatter" /> <el-table-column label="非脂g/100g" align="center" prop="nonFat" v-if="visibleColumns.nonFat" sortable />
<el-table-column label="杂质度mg/100g" align="center" prop="impurityDegree" v-if="visibleColumns.impurityDegree" /> <el-table-column label="干物质mg/100g" align="center" prop="dryMatter" v-if="visibleColumns.dryMatter" sortable />
<el-table-column label="乳糖g/100g" align="center" prop="lactose" v-if="visibleColumns.lactose" /> <el-table-column label="杂质度mg/100g" align="center" prop="impurityDegree" v-if="visibleColumns.impurityDegree" sortable />
<el-table-column label="灰度g/100g" align="center" prop="ashContent" v-if="visibleColumns.ashContent" /> <el-table-column label="乳糖g/100g" align="center" prop="lactose" v-if="visibleColumns.lactose" sortable />
<el-table-column label="酸度" align="center" prop="acidity" v-if="visibleColumns.acidity" /> <el-table-column label="灰度g/100g" align="center" prop="ashContent" v-if="visibleColumns.ashContent" sortable />
<el-table-column label="ph" align="center" prop="ph" v-if="visibleColumns.ph" /> <el-table-column label="酸度" align="center" prop="acidity" v-if="visibleColumns.acidity" sortable />
<el-table-column label="菌落总数" align="center" prop="bacterialColony" v-if="visibleColumns.bacterialColony" /> <el-table-column label="ph" align="center" prop="ph" v-if="visibleColumns.ph" sortable />
<el-table-column label="乳铁蛋白" align="center" prop="lactoferrin" v-if="visibleColumns.lactoferrin" /> <el-table-column label="菌落总数" align="center" prop="bacterialColony" v-if="visibleColumns.bacterialColony" sortable />
<el-table-column label="免疫球蛋白" align="center" prop="ig" v-if="visibleColumns.ig" /> <el-table-column label="乳铁蛋白" align="center" prop="lactoferrin" v-if="visibleColumns.lactoferrin" sortable />
<el-table-column label="体细胞" align="center" prop="somaticCell" v-if="visibleColumns.somaticCell" /> <el-table-column label="免疫球蛋白" align="center" prop="ig" v-if="visibleColumns.ig" sortable />
<el-table-column label="尿素氮" align="center" prop="usea" v-if="visibleColumns.usea" /> <el-table-column label="体细胞" align="center" prop="somaticCell" v-if="visibleColumns.somaticCell" sortable />
<el-table-column label="脂蛋比" align="center" prop="fatRatio" v-if="visibleColumns.fatRatio" /> <el-table-column label="尿素氮" align="center" prop="usea" v-if="visibleColumns.usea" sortable />
<el-table-column label="脂蛋比" align="center" prop="fatRatio" v-if="visibleColumns.fatRatio" sortable />
<el-table-column label="备注" align="center" prop="comment" v-if="visibleColumns.comment" /> <el-table-column label="备注" align="center" prop="comment" v-if="visibleColumns.comment" />
<el-table-column label="创建人" align="center" prop="createBy" v-if="visibleColumns.createBy" /> <el-table-column label="创建人" align="center" prop="createBy" v-if="visibleColumns.createBy" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180" v-if="visibleColumns.createTime"> <el-table-column label="创建时间" align="center" prop="createTime" width="180" v-if="visibleColumns.createTime" sortable>
<template #default="scope"> <template #default="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template> </template>
@ -118,10 +122,10 @@
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pageSize"
:page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
@pagination="getList" @pagination="getList"
/> />
<!-- 添加或修改生乳检验记录对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="rawMilkTestRef" :model="form" :rules="rules" label-width="120px"> <el-form ref="rawMilkTestRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="检测日期" prop="datetime"> <el-form-item label="检测日期" prop="datetime">
@ -216,7 +220,6 @@
</template> </template>
</el-dialog> </el-dialog>
<!-- 字段选择对话框 -->
<el-dialog title="字段显示设置" v-model="showColumnSelector" width="600px" append-to-body> <el-dialog title="字段显示设置" v-model="showColumnSelector" width="600px" append-to-body>
<el-checkbox-group v-model="selectedColumns"> <el-checkbox-group v-model="selectedColumns">
<el-row> <el-row>
@ -236,9 +239,7 @@
</template> </template>
<script setup name="RawMilkTest"> <script setup name="RawMilkTest">
// xlsx
import * as XLSX from 'xlsx'; import * as XLSX from 'xlsx';
// file-saver
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
import { listRawMilkTest, getRawMilkTest, delRawMilkTest, addRawMilkTest, updateRawMilkTest } from "@/api/dairyProducts/rawMilkTest/rawMilkTest.js" import { listRawMilkTest, getRawMilkTest, delRawMilkTest, addRawMilkTest, updateRawMilkTest } from "@/api/dairyProducts/rawMilkTest/rawMilkTest.js"
import { getCurrentInstance, ref, reactive, toRefs, onMounted } from 'vue' import { getCurrentInstance, ref, reactive, toRefs, onMounted } from 'vue'
@ -246,7 +247,6 @@ import { parseTime } from '@/utils/ruoyi'
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
//
const getCurrentUsername = () => { const getCurrentUsername = () => {
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}') const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
return userInfo.userName || userInfo.username || userInfo.nickName || 'admin' return userInfo.userName || userInfo.username || userInfo.nickName || 'admin'
@ -262,8 +262,8 @@ const multiple = ref(true)
const total = ref(0) const total = ref(0)
const title = ref("") const title = ref("")
const showColumnSelector = ref(false) const showColumnSelector = ref(false)
const dateRange = ref([]) //
//
const allColumns = ref([ const allColumns = ref([
{ prop: 'datetime', label: '检测日期' }, { prop: 'datetime', label: '检测日期' },
{ prop: 'source', label: '来源' }, { prop: 'source', label: '来源' },
@ -289,7 +289,6 @@ const allColumns = ref([
{ prop: 'createTime', label: '创建时间' } { prop: 'createTime', label: '创建时间' }
]) ])
//
const selectedColumns = ref([ const selectedColumns = ref([
'datetime', 'source', 'freeze', 'density', 'fat', 'protein', 'nonFat', 'datetime', 'source', 'freeze', 'density', 'fat', 'protein', 'nonFat',
'dryMatter', 'impurityDegree', 'lactose', 'ashContent', 'acidity', 'ph', 'dryMatter', 'impurityDegree', 'lactose', 'ashContent', 'acidity', 'ph',
@ -297,10 +296,8 @@ const selectedColumns = ref([
'comment', 'createBy', 'createTime' 'comment', 'createBy', 'createTime'
]) ])
//
const visibleColumns = ref({}) const visibleColumns = ref({})
//
const initVisibleColumns = () => { const initVisibleColumns = () => {
allColumns.value.forEach(column => { allColumns.value.forEach(column => {
visibleColumns.value[column.prop] = selectedColumns.value.includes(column.prop) visibleColumns.value[column.prop] = selectedColumns.value.includes(column.prop)
@ -311,9 +308,9 @@ const data = reactive({
form: {}, form: {},
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 20, // 20
datetime: null,
source: null source: null
// datetime 使 dateRange
}, },
rules: { rules: {
datetime: [ datetime: [
@ -321,27 +318,24 @@ const data = reactive({
], ],
source: [ source: [
{ required: true, message: "来源不能为空", trigger: "blur" } { required: true, message: "来源不能为空", trigger: "blur" }
], ]
//
} }
}) })
const { queryParams, form, rules } = toRefs(data) const { queryParams, form, rules } = toRefs(data)
//
const applyColumnSelection = () => { const applyColumnSelection = () => {
initVisibleColumns() initVisibleColumns()
showColumnSelector.value = false showColumnSelector.value = false
} }
//
const calculateFatRatio = () => { const calculateFatRatio = () => {
try { try {
const fat = parseFloat(form.value.fat) const fat = parseFloat(form.value.fat)
const protein = parseFloat(form.value.protein) const protein = parseFloat(form.value.protein)
if (!isNaN(fat) && !isNaN(protein) && protein !== 0) { if (!isNaN(fat) && !isNaN(protein) && protein !== 0) {
form.value.fatRatio = (fat / protein).toFixed(4) // 4 form.value.fatRatio = (fat / protein).toFixed(4)
} else { } else {
form.value.fatRatio = "" form.value.fatRatio = ""
} }
@ -353,6 +347,8 @@ const calculateFatRatio = () => {
/** 查询生乳检验记录列表 */ /** 查询生乳检验记录列表 */
function getList() { function getList() {
loading.value = true loading.value = true
//
proxy.addDateRange(queryParams.value, dateRange.value)
listRawMilkTest(queryParams.value).then(response => { listRawMilkTest(queryParams.value).then(response => {
rawMilkTestList.value = response.rows rawMilkTestList.value = response.rows
total.value = response.total total.value = response.total
@ -362,13 +358,11 @@ function getList() {
}) })
} }
//
function cancel() { function cancel() {
open.value = false open.value = false
reset() reset()
} }
//
function reset() { function reset() {
form.value = { form.value = {
id: null, id: null,
@ -404,11 +398,11 @@ function handleQuery() {
/** 重置按钮操作 */ /** 重置按钮操作 */
function resetQuery() { function resetQuery() {
dateRange.value = [] //
proxy.resetForm("queryRef") proxy.resetForm("queryRef")
handleQuery() handleQuery()
} }
//
function handleSelectionChange(selection) { function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id) ids.value = selection.map(item => item.id)
single.value = selection.length != 1 single.value = selection.length != 1
@ -420,8 +414,6 @@ function handleAdd() {
reset() reset()
open.value = true open.value = true
title.value = "添加生乳检验记录" title.value = "添加生乳检验记录"
// YYYY-MM-DD HH:mm:ss
form.value.createBy = getCurrentUsername() form.value.createBy = getCurrentUsername()
form.value.createTime = new Date().toLocaleString('zh-CN', { form.value.createTime = new Date().toLocaleString('zh-CN', {
year: 'numeric', year: 'numeric',
@ -431,8 +423,6 @@ function handleAdd() {
minute: '2-digit', minute: '2-digit',
second: '2-digit' second: '2-digit'
}).replace(/\//g, '-') }).replace(/\//g, '-')
//
form.value.fatRatio = "" form.value.fatRatio = ""
} }
@ -442,7 +432,6 @@ function handleUpdate(row) {
const _id = row.id || ids.value const _id = row.id || ids.value
getRawMilkTest(_id).then(response => { getRawMilkTest(_id).then(response => {
form.value = response.data form.value = response.data
//
calculateFatRatio() calculateFatRatio()
open.value = true open.value = true
title.value = "修改生乳检验记录" title.value = "修改生乳检验记录"
@ -455,7 +444,6 @@ function handleUpdate(row) {
function submitForm() { function submitForm() {
proxy.$refs["rawMilkTestRef"].validate(valid => { proxy.$refs["rawMilkTestRef"].validate(valid => {
if (valid) { if (valid) {
//
if (form.value.id == null) { if (form.value.id == null) {
form.value.createBy = getCurrentUsername() form.value.createBy = getCurrentUsername()
form.value.createTime = new Date().toLocaleString('zh-CN', { form.value.createTime = new Date().toLocaleString('zh-CN', {
@ -500,16 +488,13 @@ function handleDelete(row) {
/** 导出按钮操作 */ /** 导出按钮操作 */
function handleExport() { function handleExport() {
//
const visibleColumnsConfig = allColumns.value.filter( const visibleColumnsConfig = allColumns.value.filter(
col => visibleColumns.value[col.prop] col => visibleColumns.value[col.prop]
); );
//
const exportData = rawMilkTestList.value.map(item => { const exportData = rawMilkTestList.value.map(item => {
const rowData = {}; const rowData = {};
visibleColumnsConfig.forEach(col => { visibleColumnsConfig.forEach(col => {
//
if (col.prop === 'datetime' || col.prop === 'createTime') { if (col.prop === 'datetime' || col.prop === 'createTime') {
rowData[col.label] = parseTime(item[col.prop]); rowData[col.label] = parseTime(item[col.prop]);
} else { } else {
@ -519,18 +504,15 @@ function handleExport() {
return rowData; return rowData;
}); });
// 簿
const worksheet = XLSX.utils.json_to_sheet(exportData); const worksheet = XLSX.utils.json_to_sheet(exportData);
const workbook = XLSX.utils.book_new(); const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, '生乳检验记录'); XLSX.utils.book_append_sheet(workbook, worksheet, '生乳检验记录');
// Excel
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], { const blob = new Blob([excelBuffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
}); });
// 使file-saver
saveAs(blob, `生乳检验记录_${new Date().getTime()}.xlsx`); saveAs(blob, `生乳检验记录_${new Date().getTime()}.xlsx`);
} }

View File

@ -1,9 +1,8 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- 查询条件 -->
<el-form :inline="true" :model="queryParams" class="filter-form"> <el-form :inline="true" :model="queryParams" class="filter-form">
<el-form-item label="耳号"> <el-form-item label="耳号">
<el-input v-model="queryParams.manageEarTag" placeholder="请输入耳号" /> <el-input v-model="queryParams.manageEarTag" placeholder="请输入耳号" clearable />
</el-form-item> </el-form-item>
<el-form-item label="筛选天数"> <el-form-item label="筛选天数">
<el-input-number v-model="queryParams.screenDays" :min="1" placeholder="请输入天数" /> <el-input-number v-model="queryParams.screenDays" :min="1" placeholder="请输入天数" />
@ -14,21 +13,18 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 操作按钮行 -->
<div class="button-group"> <div class="button-group">
<el-popover placement="bottom" width="400" trigger="click"> <el-popover placement="bottom" width="400" trigger="click">
<el-checkbox-group v-model="selectedFields" class="checkbox-columns"> <el-checkbox-group v-model="selectedFields" class="checkbox-columns">
<!-- 使用 :value 替代 :label -->
<el-checkbox v-for="col in allColumns" :key="col.prop" :value="col.prop">{{ col.label }}</el-checkbox> <el-checkbox v-for="col in allColumns" :key="col.prop" :value="col.prop">{{ col.label }}</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
<template #reference> <template #reference>
<el-button type="info">展示列</el-button> <el-button type="info" icon="Menu">展示列</el-button>
</template> </template>
</el-popover> </el-popover>
<el-button type="success" @click="handleExport">导出</el-button> <el-button type="success" icon="Download" @click="handleExport">导出</el-button>
</div> </div>
<!-- 数据表格 -->
<el-table :data="list" border style="width: 100%" v-loading="loading" :row-key="row => row.sheepId"> <el-table :data="list" border style="width: 100%" v-loading="loading" :row-key="row => row.sheepId">
<el-table-column <el-table-column
v-for="col in visibleColumns" v-for="col in visibleColumns"
@ -36,11 +32,11 @@
:label="col.label" :label="col.label"
:prop="col.prop" :prop="col.prop"
:min-width="col.minWidth || 120" :min-width="col.minWidth || 120"
:sortable="col.sortable || false"
:formatter="col.formatter || undefined" :formatter="col.formatter || undefined"
/> />
</el-table> </el-table>
<!-- 分页 -->
<el-pagination <el-pagination
v-show="total > 0" v-show="total > 0"
:total="total" :total="total"
@ -49,7 +45,7 @@
@current-change="handlePageChange" @current-change="handlePageChange"
@size-change="handleSizeChange" @size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper" layout="total, sizes, prev, pager, next, jumper"
:page-sizes="[10, 20, 50, 100]" :page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
/> />
</div> </div>
</template> </template>
@ -68,49 +64,50 @@ export default {
list: [], list: [],
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 20, //
manageEarTag: null, manageEarTag: null,
screenDays: 100 // screenDays: 100 //
}, },
selectedFields: [], selectedFields: [],
// sortable: true
allColumns: [ allColumns: [
{ label: "耳号", prop: "manageEarTag" }, { label: "耳号", prop: "manageEarTag" },
{ label: "品种", prop: "variety" }, { label: "品种", prop: "variety" },
{ label: "挤奶开始时间", prop: "milkingStartTime", formatter: row => row.milkingStartTime ? format(new Date(row.milkingStartTime),'yyyy-MM-dd') : '' }, { label: "挤奶开始时间", prop: "milkingStartTime", formatter: row => row.milkingStartTime ? format(new Date(row.milkingStartTime),'yyyy-MM-dd') : '' },
{ label: "干奶时间", prop: "dryEndTime", formatter: row => row.dryEndTime ? format(new Date(row.dryEndTime),'yyyy-MM-dd') : '' }, { label: "干奶时间", prop: "dryEndTime", formatter: row => row.dryEndTime ? format(new Date(row.dryEndTime),'yyyy-MM-dd') : '' },
{ label: "筛选天数", prop: "screenDays" }, { label: "筛选天数", prop: "screenDays", sortable: true },
{ label: "挤奶天数", prop: "milkingDays" }, { label: "挤奶天数", prop: "milkingDays", sortable: true },
{ label: "校正后最大胎次", prop: "maxParity" }, { label: "校正后最大胎次", prop: "maxParity", sortable: true },
{ label: "系统奶量之合计", prop: "sumSystemMilk" }, { label: "系统奶量之合计", prop: "sumSystemMilk", sortable: true },
{ label: "校正奶量之合计", prop: "sumCorrectedMilk" }, { label: "校正奶量之合计", prop: "sumCorrectedMilk", sortable: true },
{ label: "校正日平均奶量", prop: "avgCorrectedDaily" }, { label: "校正日平均奶量", prop: "avgCorrectedDaily", sortable: true },
{ label: "胎次1的总奶量", prop: "sumParity1Milk" }, { label: "胎次1的总奶量", prop: "sumParity1Milk", sortable: true },
{ label: "胎次2的总奶量", prop: "sumParity2Milk" }, { label: "胎次2的总奶量", prop: "sumParity2Milk", sortable: true },
{ label: "胎次3的总奶量", prop: "sumParity3Milk" }, { label: "胎次3的总奶量", prop: "sumParity3Milk", sortable: true },
{ label: "胎次4的总奶量", prop: "sumParity4Milk" }, { label: "胎次4的总奶量", prop: "sumParity4Milk", sortable: true },
{ label: "胎次1日平均", prop: "avgParity1Daily" }, { label: "胎次1日平均", prop: "avgParity1Daily", sortable: true },
{ label: "胎次2日平均", prop: "avgParity2Daily" }, { label: "胎次2日平均", prop: "avgParity2Daily", sortable: true },
{ label: "胎次3日平均", prop: "avgParity3Daily" }, { label: "胎次3日平均", prop: "avgParity3Daily", sortable: true },
{ label: "胎次4日平均", prop: "avgParity4Daily" }, { label: "胎次4日平均", prop: "avgParity4Daily", sortable: true },
{ label: "泌乳天数", prop: "lactationDays" }, { label: "泌乳天数", prop: "lactationDays", sortable: true },
{ label: "过去7日均奶量", prop: "avgLast7Milk" }, { label: "过去7日均奶量", prop: "avgLast7Milk", sortable: true },
{ label: "校正过去7日均", prop: "avgLast7Corrected" }, { label: "校正过去7日均", prop: "avgLast7Corrected", sortable: true },
{ label: "过去14日均奶量", prop: "avgLast14Milk" }, { label: "过去14日均奶量", prop: "avgLast14Milk", sortable: true },
{ label: "过去30日均奶量", prop: "avgLast30Milk" }, { label: "过去30日均奶量", prop: "avgLast30Milk", sortable: true },
{ label: "羊只类别", prop: "sheepCategory" }, { label: "羊只类别", prop: "sheepCategory" },
{ label: "生日", prop: "birthday", formatter: row => row.birthday ? format(new Date(row.birthday),'yyyy-MM-dd') : '' }, { label: "生日", prop: "birthday", formatter: row => row.birthday ? format(new Date(row.birthday),'yyyy-MM-dd') : '' },
{ label: "当前胎次", prop: "parity" }, { label: "当前胎次", prop: "parity", sortable: true },
{ label: "月龄", prop: "monthAge" }, { label: "月龄", prop: "monthAge", sortable: true },
{ label: "当前体重", prop: "currentWeight" }, { label: "当前体重", prop: "currentWeight", sortable: true },
{ label: "繁育状态", prop: "breedStatus" }, { label: "繁育状态", prop: "breedStatus" },
{ label: "父号", prop: "fatherManageTags" }, { label: "父号", prop: "fatherManageTags" },
{ label: "母号", prop: "motherManageTags" }, { label: "母号", prop: "motherManageTags" },
{ label: "牧场", prop: "ranchName" }, { label: "牧场", prop: "ranchName" },
{ label: "家系", prop: "family" }, { label: "家系", prop: "family" },
{ label: "母亲挤奶天数", prop: "motherMilkingDays" }, { label: "母亲挤奶天数", prop: "motherMilkingDays", sortable: true },
{ label: "母亲校正奶量之合计", prop: "motherSumCorrected" }, { label: "母亲校正奶量之合计", prop: "motherSumCorrected", sortable: true },
{ label: "母亲校正后最大胎次", prop: "motherMaxParity" }, { label: "母亲校正后最大胎次", prop: "motherMaxParity", sortable: true },
{ label: "母亲校正日平均奶量", prop: "motherAvgCorrectedDaily" } { label: "母亲校正日平均奶量", prop: "motherAvgCorrectedDaily", sortable: true }
] ]
}; };
}, },
@ -120,6 +117,7 @@ export default {
}, },
computed: { computed: {
visibleColumns() { visibleColumns() {
//
return this.allColumns.filter(col => this.selectedFields.includes(col.prop)); return this.allColumns.filter(col => this.selectedFields.includes(col.prop));
} }
}, },
@ -140,7 +138,7 @@ export default {
resetQuery() { resetQuery() {
this.queryParams = { this.queryParams = {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 20,
manageEarTag: null, manageEarTag: null,
screenDays: 100 screenDays: 100
}; };

View File

@ -1,16 +1,18 @@
<template> <template>
<div class="app-container"> <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">
<el-form-item label="日期" prop="datetime"> <el-form-item label="日期" style="width: 308px">
<el-date-picker clearable <el-date-picker
v-model="queryParams.datetime" v-model="dateRange"
type="date"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
placeholder="请选择日期"> type="daterange"
</el-date-picker> range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="厂区" prop="factory"> <el-form-item label="厂区" prop="factory">
<el-select v-model="queryParams.factory" placeholder="请选择厂区" clearable> <el-select v-model="queryParams.factory" placeholder="请选择厂区" clearable style="width: 240px">
<el-option <el-option
v-for="dict in da_ranch" v-for="dict in da_ranch"
:key="dict.value" :key="dict.value"
@ -69,7 +71,7 @@
<el-table v-loading="loading" :data="weightCorrectionList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="weightCorrectionList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="日期" align="center" prop="datetime" width="180"> <el-table-column label="日期" align="center" prop="datetime" width="180" sortable>
<template #default="scope"> <template #default="scope">
<span>{{ parseTime(scope.row.datetime, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.datetime, '{y}-{m}-{d}') }}</span>
</template> </template>
@ -79,11 +81,11 @@
<dict-tag :options="da_ranch" :value="scope.row.factory"/> <dict-tag :options="da_ranch" :value="scope.row.factory"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="实际奶量" align="center" prop="actual" /> <el-table-column label="实际奶量" align="center" prop="actual" sortable />
<el-table-column label="系统奶量" align="center" prop="systemMilk" /> <!-- 修改这里 --> <el-table-column label="系统奶量" align="center" prop="systemMilk" sortable />
<el-table-column label="称重系数" align="center" prop="coefficient"> <el-table-column label="称重系数" align="center" prop="coefficient" sortable>
<template #default="scope"> <template #default="scope">
<span>{{ scope.row.coefficient.toFixed(2) }}</span> <span>{{ scope.row.coefficient ? scope.row.coefficient.toFixed(2) : '' }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
@ -99,10 +101,10 @@
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pageSize"
:page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
@pagination="getList" @pagination="getList"
/> />
<!-- 添加或修改称重校正对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="weightCorrectionRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="weightCorrectionRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="日期" prop="datetime"> <el-form-item label="日期" prop="datetime">
@ -114,7 +116,7 @@
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="厂区" prop="factory"> <el-form-item label="厂区" prop="factory">
<el-select v-model="form.factory" placeholder="请选择厂区"> <el-select v-model="form.factory" placeholder="请选择厂区" style="width: 100%">
<el-option <el-option
v-for="dict in da_ranch" v-for="dict in da_ranch"
:key="dict.value" :key="dict.value"
@ -126,7 +128,7 @@
<el-form-item label="实际奶量" prop="actual"> <el-form-item label="实际奶量" prop="actual">
<el-input v-model="form.actual" placeholder="请输入实际奶量" type="number" step="0.01" min="0" /> <el-input v-model="form.actual" placeholder="请输入实际奶量" type="number" step="0.01" min="0" />
</el-form-item> </el-form-item>
<el-form-item label="系统奶量" prop="systemMilk"> <!-- 修改这里 --> <el-form-item label="系统奶量" prop="systemMilk">
<el-input v-model="form.systemMilk" placeholder="请输入系统奶量" type="number" step="0.01" min="0" /> <el-input v-model="form.systemMilk" placeholder="请输入系统奶量" type="number" step="0.01" min="0" />
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -141,7 +143,8 @@
</template> </template>
<script setup name="WeightCorrection"> <script setup name="WeightCorrection">
import { listWeightCorrection, getWeightCorrection, delWeightCorrection, addWeightCorrection, updateWeightCorrection } from "@/api/dairyProducts/weightCorrection/weightCorrection.js" import { listWeightCorrection, getWeightCorrection, delWeightCorrection, addWeightCorrection, updateWeightCorrection } from "@/api/dairyProducts/weightCorrection/weightCorrection.js"
import { getCurrentInstance, ref, reactive } from 'vue'
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const { da_ranch } = proxy.useDict('da_ranch') const { da_ranch } = proxy.useDict('da_ranch')
@ -155,35 +158,42 @@ const single = ref(true)
const multiple = ref(true) const multiple = ref(true)
const total = ref(0) const total = ref(0)
const title = ref("") const title = ref("")
const dateRange = ref([]) //
const data = reactive({ // 使 reactive queryParams
form: {}, const queryParams = reactive({
queryParams: { pageNum: 1,
pageNum: 1, pageSize: 20, // 20
pageSize: 10, factory: null
datetime: null,
factory: null
},
rules: {
datetime: [{ required: true, message: "日期不能为空", trigger: "blur" }],
factory: [{ required: true, message: "厂区不能为空", trigger: "change" }],
actual: [
{ required: true, message: "实际奶量不能为空", trigger: "blur" },
{ type: 'number', min: 0, message: "实际奶量必须大于0", trigger: "blur", transform: value => Number(value) }
],
systemMilk: [ //
{ required: true, message: "系统奶量不能为空", trigger: "blur" },
{ type: 'number', min: 0, message: "系统奶量必须大于0", trigger: "blur", transform: value => Number(value) }
]
}
}) })
const { queryParams, form, rules } = toRefs(data) const form = ref({
id: null,
datetime: null,
factory: null,
actual: null,
systemMilk: null
})
const rules = {
datetime: [{ required: true, message: "日期不能为空", trigger: "blur" }],
factory: [{ required: true, message: "厂区不能为空", trigger: "change" }],
actual: [
{ required: true, message: "实际奶量不能为空", trigger: "blur" },
{ type: 'number', min: 0, message: "实际奶量必须大于0", trigger: "blur", transform: value => Number(value) }
],
systemMilk: [
{ required: true, message: "系统奶量不能为空", trigger: "blur" },
{ type: 'number', min: 0, message: "系统奶量必须大于0", trigger: "blur", transform: value => Number(value) }
]
}
/** 查询称重校正列表 */ /** 查询称重校正列表 */
function getList() { function getList() {
loading.value = true loading.value = true
listWeightCorrection(queryParams.value).then(response => { //
proxy.addDateRange(queryParams, dateRange.value)
listWeightCorrection(queryParams).then(response => {
weightCorrectionList.value = response.rows weightCorrectionList.value = response.rows
total.value = response.total total.value = response.total
loading.value = false loading.value = false
@ -203,19 +213,21 @@ function reset() {
datetime: null, datetime: null,
factory: null, factory: null,
actual: null, actual: null,
systemMilk: null // systemMilk: null
} }
proxy.resetForm("weightCorrectionRef") proxy.resetForm("weightCorrectionRef")
} }
/** 搜索按钮操作 */ /** 搜索按钮操作 */
function handleQuery() { function handleQuery() {
queryParams.value.pageNum = 1 queryParams.pageNum = 1
getList() getList()
} }
/** 重置按钮操作 */ /** 重置按钮操作 */
function resetQuery() { function resetQuery() {
dateRange.value = [] //
queryParams.factory = null //
proxy.resetForm("queryRef") proxy.resetForm("queryRef")
handleQuery() handleQuery()
} }
@ -253,25 +265,15 @@ function submitForm() {
form.value.actual = parseFloat(form.value.actual) form.value.actual = parseFloat(form.value.actual)
form.value.systemMilk = parseFloat(form.value.systemMilk) form.value.systemMilk = parseFloat(form.value.systemMilk)
if (form.value.id != null) { const req = form.value.id ? updateWeightCorrection(form.value) : addWeightCorrection(form.value);
updateWeightCorrection(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功") req.then(response => {
open.value = false proxy.$modal.msgSuccess(form.value.id ? "修改成功" : "新增成功")
getList() open.value = false
}).catch(error => { getList()
// }).catch(error => {
proxy.$modal.msgError(error.response.data.msg || "修改失败") proxy.$modal.msgError(error.response ? error.response.data.msg : "操作失败")
}) })
} else {
addWeightCorrection(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
}).catch(error => {
//
proxy.$modal.msgError(error.response.data.msg || "新增失败")
})
}
} }
}) })
} }
@ -290,9 +292,36 @@ function handleDelete(row) {
/** 导出按钮操作 */ /** 导出按钮操作 */
function handleExport() { function handleExport() {
proxy.download('weightCorrection/weightCorrection/export', { proxy.download('weightCorrection/weightCorrection/export', {
...queryParams.value ...queryParams
}, `weightCorrection_${new Date().getTime()}.xlsx`) }, `weightCorrection_${new Date().getTime()}.xlsx`)
} }
getList() getList()
</script> </script>
<style scoped>
.el-table {
font-size: 14px;
}
.el-table th {
background-color: #f5f7fa;
color: #606266;
font-weight: bold;
}
.el-table td, .el-table th {
padding: 12px 0;
}
.el-table .cell {
padding: 0 15px;
}
.el-button + .el-button {
margin-left: 5px;
}
/* 确保表单元素宽度一致 */
.el-input, .el-select {
width: 100%;
}
.el-form-item {
margin-bottom: 15px;
}
</style>

View File

@ -9,13 +9,15 @@
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="检测日期" prop="datetime"> <el-form-item label="检测日期" style="width: 308px">
<el-date-picker clearable <el-date-picker
v-model="queryParams.datetime" v-model="dateRange"
type="date"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
placeholder="请选择检测日期"> type="daterange"
</el-date-picker> range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@ -85,71 +87,86 @@
align="center" align="center"
prop="datetime" prop="datetime"
width="180" width="180"
v-if="selectedColumns.includes('datetime')"> v-if="selectedColumns.includes('datetime')"
sortable>
<template #default="scope"> <template #default="scope">
<span>{{ formatDate(scope.row.datetime) }}</span> <span>{{ formatDate(scope.row.datetime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="脂肪g/100g" label="脂肪g/100g"
align="center" align="center"
prop="fat" prop="fat"
v-if="selectedColumns.includes('fat')" /> v-if="selectedColumns.includes('fat')"
sortable />
<el-table-column <el-table-column
label="蛋白质g/100g" label="蛋白质g/100g"
align="center" align="center"
prop="protein" prop="protein"
v-if="selectedColumns.includes('protein')" /> v-if="selectedColumns.includes('protein')"
sortable />
<el-table-column <el-table-column
label="非脂g/100g" label="非脂g/100g"
align="center" align="center"
prop="nonFat" prop="nonFat"
v-if="selectedColumns.includes('nonFat')" /> v-if="selectedColumns.includes('nonFat')"
sortable />
<el-table-column <el-table-column
label="酸度oT" label="酸度oT"
align="center" align="center"
prop="acidity" prop="acidity"
v-if="selectedColumns.includes('acidity')" /> v-if="selectedColumns.includes('acidity')"
sortable />
<el-table-column <el-table-column
label="菌落总数1" label="菌落总数1"
align="center" align="center"
prop="bacterialColony1" prop="bacterialColony1"
v-if="selectedColumns.includes('bacterialColony1')" /> v-if="selectedColumns.includes('bacterialColony1')"
sortable />
<el-table-column <el-table-column
label="菌落总数2" label="菌落总数2"
align="center" align="center"
prop="bacterialClony2" prop="bacterialClony2"
v-if="selectedColumns.includes('bacterialClony2')" /> v-if="selectedColumns.includes('bacterialClony2')"
sortable />
<el-table-column <el-table-column
label="菌落总数3" label="菌落总数3"
align="center" align="center"
prop="bacterialClony3" prop="bacterialClony3"
v-if="selectedColumns.includes('bacterialClony3')" /> v-if="selectedColumns.includes('bacterialClony3')"
sortable />
<el-table-column <el-table-column
label="菌落总数4" label="菌落总数4"
align="center" align="center"
prop="bacterialClony4" prop="bacterialClony4"
v-if="selectedColumns.includes('bacterialClony4')" /> v-if="selectedColumns.includes('bacterialClony4')"
sortable />
<el-table-column <el-table-column
label="菌落总数5" label="菌落总数5"
align="center" align="center"
prop="bacterialClony5" prop="bacterialClony5"
v-if="selectedColumns.includes('bacterialClony5')" /> v-if="selectedColumns.includes('bacterialClony5')"
sortable />
<el-table-column <el-table-column
label="酵母菌(CFU/g)" label="酵母菌(CFU/g)"
align="center" align="center"
prop="yeast" prop="yeast"
v-if="selectedColumns.includes('yeast')" /> v-if="selectedColumns.includes('yeast')"
sortable />
<el-table-column <el-table-column
label="霉菌(CFU/g)" label="霉菌(CFU/g)"
align="center" align="center"
prop="mould" prop="mould"
v-if="selectedColumns.includes('mould')" /> v-if="selectedColumns.includes('mould')"
sortable />
<el-table-column <el-table-column
label="乳酸菌(CFU/g)" label="乳酸菌(CFU/g)"
align="center" align="center"
prop="lacto" prop="lacto"
v-if="selectedColumns.includes('lacto')" /> v-if="selectedColumns.includes('lacto')"
sortable />
<el-table-column <el-table-column
label="备注" label="备注"
align="center" align="center"
@ -165,7 +182,8 @@
align="center" align="center"
prop="createTime" prop="createTime"
width="180" width="180"
v-if="selectedColumns.includes('createTime')"> v-if="selectedColumns.includes('createTime')"
sortable>
<template #default="scope"> <template #default="scope">
<span>{{ formatDateTime(scope.row.createTime) }}</span> <span>{{ formatDateTime(scope.row.createTime) }}</span>
</template> </template>
@ -183,6 +201,7 @@
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pageSize"
:page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
@pagination="getList" @pagination="getList"
/> />
@ -284,13 +303,14 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, onMounted } from 'vue'; import { ref, reactive, onMounted, getCurrentInstance } from 'vue';
import { listYogurtTest, getYogurtTest, delYogurtTest, addYogurtTest, updateYogurtTest } from "@/api/dairyProducts/yogurtTest/yogurtTest.js"; import { listYogurtTest, getYogurtTest, delYogurtTest, addYogurtTest, updateYogurtTest } from "@/api/dairyProducts/yogurtTest/yogurtTest.js";
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
// xlsxfile-saver
import * as XLSX from 'xlsx'; import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
const { proxy } = getCurrentInstance(); // proxy
// //
const yogurtTestList = ref([]); const yogurtTestList = ref([]);
const open = ref(false); const open = ref(false);
@ -303,6 +323,7 @@ const total = ref(0);
const title = ref(""); const title = ref("");
const columnShowDialogVisible = ref(false); const columnShowDialogVisible = ref(false);
const yogurtTestRef = ref(null); const yogurtTestRef = ref(null);
const dateRange = ref([]); //
// //
const columnConfig = [ const columnConfig = [
@ -336,9 +357,9 @@ const selectedColumns = ref([
// //
const queryParams = reactive({ const queryParams = reactive({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 20, //
source: null, source: null,
datetime: null, // datetime 使 dateRange
}); });
// //
@ -382,6 +403,8 @@ const getCurrentUsername = () => {
/** 查询列表 */ /** 查询列表 */
function getList() { function getList() {
loading.value = true; loading.value = true;
//
proxy.addDateRange(queryParams, dateRange.value);
listYogurtTest(queryParams).then(response => { listYogurtTest(queryParams).then(response => {
yogurtTestList.value = response.rows || []; yogurtTestList.value = response.rows || [];
total.value = response.total || 0; total.value = response.total || 0;
@ -468,9 +491,9 @@ function handleQuery() {
/** 重置按钮操作 */ /** 重置按钮操作 */
function resetQuery() { function resetQuery() {
dateRange.value = []; //
Object.assign(queryParams, { Object.assign(queryParams, {
source: null, source: null,
datetime: null,
}); });
handleQuery(); handleQuery();
} }

View File

@ -57,10 +57,10 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<el-table v-loading="loading" :data="customerList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="customerList" @selection-change="handleSelectionChange" @sort-change="handleSortChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="客户名称" align="center" prop="name" /> <el-table-column label="客户名称" align="center" prop="name" />
<el-table-column label="客户电话" align="center" prop="phone" /> <el-table-column label="客户电话" align="center" prop="phone" sortable="custom" />
<el-table-column label="客户地址" align="center"> <el-table-column label="客户地址" align="center">
<template #default="scope"> <template #default="scope">
{{ scope.row.province }}{{ scope.row.city }}{{ scope.row.district }}{{ scope.row.address }} {{ scope.row.province }}{{ scope.row.city }}{{ scope.row.district }}{{ scope.row.address }}
@ -80,10 +80,10 @@
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pageSize"
:page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
@pagination="getList" @pagination="getList"
/> />
<!-- 添加或修改客户管理对话框 -->
<el-dialog :title="title" v-model="open" width="700px" append-to-body> <el-dialog :title="title" v-model="open" width="700px" append-to-body>
<el-form ref="customerRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="customerRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="客户名称" prop="name"> <el-form-item label="客户名称" prop="name">
@ -120,7 +120,7 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, getCurrentInstance, onMounted } from 'vue' import { ref, reactive, getCurrentInstance, onMounted, toRefs } from 'vue'
import { listCustomer, getCustomer, delCustomer, addCustomer, updateCustomer } from "@/api/sale/customer/customer" import { listCustomer, getCustomer, delCustomer, addCustomer, updateCustomer } from "@/api/sale/customer/customer"
import { regionData } from 'element-china-area-data' import { regionData } from 'element-china-area-data'
@ -149,8 +149,10 @@ const data = reactive({
form: {}, form: {},
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 20, // 20
name: null, name: null,
orderByColumn: null, //
isAsc: null //
}, },
rules: { rules: {
name: [{ required: true, message: "客户名称不能为空", trigger: "blur" }], name: [{ required: true, message: "客户名称不能为空", trigger: "blur" }],
@ -173,6 +175,13 @@ function getList() {
}) })
} }
//
function handleSortChange({ column, prop, order }) {
queryParams.value.orderByColumn = prop
queryParams.value.isAsc = order === 'ascending' ? 'asc' : 'desc'
getList()
}
function cancel() { function cancel() {
open.value = false open.value = false
reset() reset()
@ -200,6 +209,10 @@ function handleQuery() {
function resetQuery() { function resetQuery() {
proxy.resetForm("queryRef") proxy.resetForm("queryRef")
//
queryParams.value.orderByColumn = null
queryParams.value.isAsc = null
// el-tableUIclearSort
handleQuery() handleQuery()
} }
@ -282,4 +295,4 @@ function handleExport() {
...queryParams.value ...queryParams.value
}, `customer_${new Date().getTime()}.xlsx`) }, `customer_${new Date().getTime()}.xlsx`)
} }
</script> </script>

View File

@ -1,27 +1,15 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- 面包屑导航 -->
<el-breadcrumb separator="/" class="breadcrumb"> <el-breadcrumb separator="/" class="breadcrumb">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item> <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>销售管理</el-breadcrumb-item> <el-breadcrumb-item>销售管理</el-breadcrumb-item>
<el-breadcrumb-item>销售记录</el-breadcrumb-item> <el-breadcrumb-item>销售记录</el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
<!-- 搜索区域 --> <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="88px">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form-item label="销售日期">
<el-form-item label="耳号" prop="bsManageTags">
<el-input
v-model="queryParams.bsManageTags"
placeholder="请输入耳号"
clearable
size="small"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="销售日期" prop="saleDate">
<el-date-picker <el-date-picker
v-model="queryParams.saleDate" v-model="dateRange"
type="daterange" type="daterange"
range-separator="至" range-separator="至"
start-placeholder="开始日期" start-placeholder="开始日期"
@ -31,15 +19,24 @@
/> />
</el-form-item> </el-form-item>
<el-form-item label="销售类别" prop="saleType"> <el-form-item label="客户名称" prop="customerName">
<el-select v-model="queryParams.saleType" clearable placeholder="请选择" size="small" style="width: 180px"> <el-input
<el-option v-model="queryParams.customerName"
v-for="d in saleTypeOptions" placeholder="请输入客户名称"
:key="d.dictValue" clearable
:label="d.dictLabel" size="small"
:value="d.dictValue" @keyup.enter="handleQuery"
/> />
</el-select> </el-form-item>
<el-form-item label="销售人员" prop="salesPersonName">
<el-input
v-model="queryParams.salesPersonName"
placeholder="请输入销售人员姓名"
clearable
size="small"
@keyup.enter="handleQuery"
/>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@ -48,7 +45,6 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 操作按钮区域 -->
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -92,16 +88,31 @@
v-hasPermi="['saleRecord:saleRecord:export']" v-hasPermi="['saleRecord:saleRecord:export']"
>导出</el-button> >导出</el-button>
</el-col> </el-col>
<!-- 修复使用 v-model:showSearch 替代 :showSearch.sync -->
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" /> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" />
</el-row> </el-row>
<!-- 表格区域 --> <el-table
<el-table v-loading="loading" :data="saleRecordList" @selection-change="handleSelectionChange" style="width: 100%"> v-loading="loading"
:data="saleRecordList"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange"
style="width: 100%"
>
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" type="index" width="50" align="center" /> <el-table-column label="序号" type="index" width="50" align="center" />
<el-table-column label="耳号" align="center" prop="bsManageTags" width="120" show-overflow-tooltip /> <el-table-column label="耳号" align="center" prop="bsManageTags" width="120" show-overflow-tooltip />
<el-table-column label="品种" align="center" prop="variety" width="100" show-overflow-tooltip /> <el-table-column label="品种" align="center" prop="variety" width="100" show-overflow-tooltip />
<el-table-column
label="羊舍"
align="center"
prop="sheepfoldId"
width="120"
:formatter="sheepfoldFormat"
show-overflow-tooltip
/>
<el-table-column label="事件类型" align="center" prop="eventType" width="100" show-overflow-tooltip /> <el-table-column label="事件类型" align="center" prop="eventType" width="100" show-overflow-tooltip />
<el-table-column label="销售日期" align="center" prop="saleDate" width="120"> <el-table-column label="销售日期" align="center" prop="saleDate" width="120">
<template #default="scope"> <template #default="scope">
@ -110,34 +121,37 @@
</el-table-column> </el-table-column>
<el-table-column label="羊只类别" align="center" prop="sheepName" width="100" show-overflow-tooltip /> <el-table-column label="羊只类别" align="center" prop="sheepName" width="100" show-overflow-tooltip />
<el-table-column label="性别" align="center" prop="gender" width="80" /> <el-table-column label="性别" align="center" prop="gender" width="80" />
<el-table-column label="月龄" align="center" prop="monthAge" width="80" />
<el-table-column label="胎次" align="center" prop="parity" width="80" /> <el-table-column label="月龄" align="center" prop="monthAge" width="80" sortable="custom" />
<el-table-column label="胎次" align="center" prop="parity" width="80" sortable="custom" />
<el-table-column label="计价方式" align="center" prop="pricingMethod" width="100" show-overflow-tooltip /> <el-table-column label="计价方式" align="center" prop="pricingMethod" width="100" show-overflow-tooltip />
<el-table-column label="单价" align="center" prop="unitPrice" width="100">
<el-table-column label="单价" align="center" prop="unitPrice" width="100" sortable="custom">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.unitPrice !== null && scope.row.unitPrice !== undefined">{{ scope.row.unitPrice }}</span> <span v-if="scope.row.unitPrice !== null">{{ scope.row.unitPrice }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="总价" align="center" prop="totalPrice" width="100"> <el-table-column label="总价" align="center" prop="totalPrice" width="100" sortable="custom">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.totalPrice !== null && scope.row.totalPrice !== undefined">{{ scope.row.totalPrice }}</span> <span v-if="scope.row.totalPrice !== null">{{ scope.row.totalPrice }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="总体重" align="center" prop="totalWeight" width="100"> <el-table-column label="总体重" align="center" prop="totalWeight" width="100" sortable="custom">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.totalWeight">{{ scope.row.totalWeight }}kg</span> <span v-if="scope.row.totalWeight">{{ scope.row.totalWeight }}kg</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="平均体重" align="center" prop="avgWeight" width="100"> <el-table-column label="平均体重" align="center" prop="avgWeight" width="100" sortable="custom">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.avgWeight">{{ scope.row.avgWeight }}kg</span> <span v-if="scope.row.avgWeight">{{ scope.row.avgWeight }}kg</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="平均单只价格" align="center" prop="avgPricePerSheep" width="120"> <el-table-column label="平均单只价格" align="center" prop="avgPricePerSheep" width="120" sortable="custom">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.avgPricePerSheep">{{ scope.row.avgPricePerSheep }}</span> <span v-if="scope.row.avgPricePerSheep">{{ scope.row.avgPricePerSheep }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="销售类别" align="center" prop="saleType" width="120" :formatter="saleTypeFormat" show-overflow-tooltip /> <el-table-column label="销售类别" align="center" prop="saleType" width="120" :formatter="saleTypeFormat" show-overflow-tooltip />
<el-table-column label="客户名称" align="center" prop="customerName" width="140" show-overflow-tooltip /> <el-table-column label="客户名称" align="center" prop="customerName" width="140" show-overflow-tooltip />
<el-table-column label="客户电话" align="center" prop="customerPhone" width="130" show-overflow-tooltip /> <el-table-column label="客户电话" align="center" prop="customerPhone" width="130" show-overflow-tooltip />
@ -147,12 +161,13 @@
<el-table-column label="审批编号" align="center" prop="approvalNo" width="130" show-overflow-tooltip /> <el-table-column label="审批编号" align="center" prop="approvalNo" width="130" show-overflow-tooltip />
<el-table-column label="疾病类型" align="center" prop="diseaseType" width="120" :formatter="diseaseTypeFormat" show-overflow-tooltip /> <el-table-column label="疾病类型" align="center" prop="diseaseType" width="120" :formatter="diseaseTypeFormat" show-overflow-tooltip />
<el-table-column label="次要原因" align="center" prop="secondaryReason" width="120" show-overflow-tooltip /> <el-table-column label="次要原因" align="center" prop="secondaryReason" width="120" show-overflow-tooltip />
<el-table-column label="羊舍" align="center" prop="sheepfoldName" width="120" show-overflow-tooltip />
<el-table-column label="班组" align="center" prop="groupCode" width="100" :formatter="groupFormat" /> <el-table-column label="班组" align="center" prop="groupCode" width="100" :formatter="groupFormat" />
<el-table-column label="繁育状态" align="center" prop="breed" width="100" show-overflow-tooltip /> <el-table-column label="繁育状态" align="center" prop="breed" width="100" show-overflow-tooltip />
<el-table-column label="产后天数" align="center" prop="postLambingDay" width="90" />
<el-table-column label="泌乳天数" align="center" prop="lactationDay" width="90" /> <el-table-column label="产后天数" align="center" prop="postLambingDay" width="90" sortable="custom" />
<el-table-column label="怀孕天数" align="center" prop="lambingDay" width="90" /> <el-table-column label="泌乳天数" align="center" prop="lactationDay" width="90" sortable="custom" />
<el-table-column label="怀孕天数" align="center" prop="lambingDay" width="90" sortable="custom" />
<el-table-column label="创建人" align="center" prop="createdByName" width="120" show-overflow-tooltip /> <el-table-column label="创建人" align="center" prop="createdByName" width="120" show-overflow-tooltip />
<el-table-column label="创建日期" align="center" prop="createdAt" width="120"> <el-table-column label="创建日期" align="center" prop="createdAt" width="120">
<template #default="scope"> <template #default="scope">
@ -187,11 +202,10 @@
:total="total" :total="total"
:page="queryParams.pageNum" :page="queryParams.pageNum"
:limit="queryParams.pageSize" :limit="queryParams.pageSize"
:page-sizes="[20, 50, 100, 200, 500, 1000, 2000]"
@pagination="getList" @pagination="getList"
/> />
<!-- 添加或修改羊只销售记录对话框 -->
<!-- 修复使用 v-model 替代 :visible.sync -->
<el-dialog :title="title" v-model="open" width="1200px" append-to-body> <el-dialog :title="title" v-model="open" width="1200px" append-to-body>
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
<el-row :gutter="20"> <el-row :gutter="20">
@ -213,10 +227,8 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-col :span="12">
<el-form-item label="耳号" prop="bsManageTagsList"> <el-form-item label="耳号" prop="bsManageTagsList">
<!-- 通过 allow-create + 回车新增耳号使用 watch 捕捉新增项并拉取详情 -->
<el-select <el-select
v-model="form.bsManageTagsList" v-model="form.bsManageTagsList"
multiple multiple
@ -235,239 +247,10 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<!-- 自动填充展示 -->
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"><el-form-item label="品种">{{ form.variety }}</el-form-item></el-col> </el-row>
<el-col :span="8"><el-form-item label="羊只类别">{{ form.sheepName }}</el-form-item></el-col>
<el-col :span="8"><el-form-item label="性别">{{ form.gender }}</el-form-item></el-col>
<el-col :span="8"><el-form-item label="月龄">{{ form.monthAge }}</el-form-item></el-col>
<el-col :span="8"><el-form-item label="胎次">{{ form.parity }}</el-form-item></el-col>
<el-col :span="8"><el-form-item label="繁育状态">{{ form.breed }}</el-form-item></el-col>
<el-col :span="8"><el-form-item label="产后天数">{{ form.postLambingDay }}</el-form-item></el-col>
<el-col :span="8"><el-form-item label="泌乳天数">{{ form.lactationDay }}</el-form-item></el-col>
<el-col :span="8"><el-form-item label="怀孕天数">{{ form.lambingDay }}</el-form-item></el-col>
</el-row>
<el-divider />
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="事件类型" prop="eventType">
<el-input v-model="form.eventType" placeholder="默认为销售" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="销售日期" prop="saleDate">
<el-date-picker
v-model="form.saleDate"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"
style="width: 100%"
:disabled-date="disabledDate"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计价方式" prop="pricingMethod">
<el-select
v-model="form.pricingMethod"
placeholder="请选择计价方式"
@change="handlePricingMethodChange"
style="width: 100%"
>
<el-option label="按个体" value="按个体" />
<el-option label="按体重" value="按体重" />
</el-select>
</el-form-item>
</el-col>
<!-- 动态字段按个体 -->
<template v-if="form.pricingMethod === '按个体'">
<el-col :span="8">
<el-form-item label="单价(元/只)" prop="unitPrice">
<el-input v-model="form.unitPrice" placeholder="请输入单价" @input="calculateIndividualPrice">
<template #append></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总价" prop="totalPrice">
<el-input v-model="form.totalPrice" placeholder="自动计算" readonly>
<template #append></template>
</el-input>
</el-form-item>
</el-col>
</template>
<!-- 动态字段按体重 -->
<template v-if="form.pricingMethod === '按体重'">
<el-col :span="8">
<el-form-item label="总重量" prop="totalWeight">
<el-input v-model="form.totalWeight" placeholder="请输入总重量" @input="calculateWeightPrice">
<template #append>kg</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="单价(元/kg)" prop="unitPrice">
<el-input v-model="form.unitPrice" placeholder="请输入单价" @input="calculateWeightPrice">
<template #append></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总价" prop="totalPrice">
<el-input v-model="form.totalPrice" placeholder="自动计算" readonly>
<template #append></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="平均体重">
<el-input v-model="form.avgWeight" placeholder="自动计算" readonly>
<template #append>kg</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="平均单只价格">
<el-input v-model="form.avgPricePerSheep" placeholder="自动计算" readonly>
<template #append></template>
</el-input>
</el-form-item>
</el-col>
</template>
</el-row>
<el-divider />
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="销售类别" prop="saleType">
<el-select
v-model="form.saleType"
placeholder="请选择销售类别"
@change="handleSaleTypeChange"
style="width: 100%"
>
<el-option
v-for="dict in saleTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户名称" prop="customerId">
<el-select
v-model="form.customerId"
filterable
remote
reserve-keyword
placeholder="请输入客户名称"
:remote-method="remoteMethodGetCustomer"
:loading="customerLoading"
@change="handleCustomerChange"
style="width: 100%"
>
<!-- 使用 sx_customer.name 作为显示字段 -->
<el-option
v-for="item in customerOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<!-- 淘汰相关仅在 销售类别=淘汰销售/淘汰屠宰 时显示 -->
<template v-if="isEliminationSale">
<el-col :span="12">
<el-form-item label="疾病类型" prop="diseaseType">
<el-select v-model="form.diseaseType" placeholder="请选择疾病类型" @change="handleDiseaseTypeChange" style="width: 100%">
<el-option
v-for="dict in diseaseTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="班组" prop="groupCode">
<el-select v-model="form.groupCode" placeholder="请选择班组" style="width: 100%">
<el-option
v-for="dict in groupOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" v-if="diseaseTypeLabel === '病残羊'">
<el-form-item label="次要原因" prop="secondaryReason">
<el-input v-model="form.secondaryReason" placeholder="请输入次要原因" />
</el-form-item>
</el-col>
</template>
<el-col :span="12">
<el-form-item label="销售人员" prop="salesPersonId">
<el-select v-model="form.salesPersonId" placeholder="请选择销售人员" style="width: 100%">
<el-option v-for="user in userOptions" :key="user.userId" :label="user.nickName" :value="user.userId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="检疫证号" prop="quarantineNo">
<el-input v-model="form.quarantineNo" placeholder="请输入检疫证号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="审批编号" prop="approvalNo">
<el-input v-model="form.approvalNo" placeholder="请输入审批编号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="技术员" prop="technicianId">
<el-select v-model="form.technicianId" placeholder="请选择技术员" style="width: 100%">
<el-option v-for="user in userOptions" :key="user.userId" :label="user.nickName" :value="user.userId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="处理人" prop="handlerId">
<el-select v-model="form.handlerId" placeholder="请选择处理人" style="width: 100%">
<el-option v-for="user in userOptions" :key="user.userId" :label="user.nickName" :value="user.userId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :rows="2" />
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button> <el-button type="primary" @click="submitForm"> </el-button>
@ -496,7 +279,6 @@ export default {
name: 'SxSheepSale', name: 'SxSheepSale',
data() { data() {
return { return {
//
loading: true, loading: true,
ids: [], ids: [],
single: true, single: true,
@ -506,37 +288,27 @@ export default {
saleRecordList: [], saleRecordList: [],
title: '', title: '',
open: false, open: false,
dateRange: [],
//
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 20,
bsManageTags: null, customerName: null,
sheepfoldId: null, salesPersonName: null,
saleDate: null, orderByColumn: null,
saleType: null, isAsc: null
}, },
//
form: {}, form: {},
//
saleTypeOptions: [], saleTypeOptions: [],
diseaseTypeOptions: [], diseaseTypeOptions: [],
groupOptions: [], groupOptions: [],
//
sheepfoldOptions: [], sheepfoldOptions: [],
earTagOptions: [], earTagOptions: [],
userOptions: [], userOptions: [],
customerOptions: [], customerOptions: [],
customerLoading: false, customerLoading: false,
//
_prevTags: [], _prevTags: [],
// validator
rules: { rules: {
// ... rules ...
sheepfoldId: [{ required: true, message: '羊舍不能为空', trigger: 'change' }], sheepfoldId: [{ required: true, message: '羊舍不能为空', trigger: 'change' }],
bsManageTagsList: [{ type: 'array', required: true, message: '至少需要一个耳号', trigger: 'change' }], bsManageTagsList: [{ type: 'array', required: true, message: '至少需要一个耳号', trigger: 'change' }],
saleDate: [{ required: true, message: '销售日期不能为空', trigger: 'change' }], saleDate: [{ required: true, message: '销售日期不能为空', trigger: 'change' }],
@ -545,38 +317,11 @@ export default {
saleType: [{ required: true, message: '销售类别不能为空', trigger: 'change' }], saleType: [{ required: true, message: '销售类别不能为空', trigger: 'change' }],
customerId: [{ required: true, message: '客户不能为空', trigger: 'change' }], customerId: [{ required: true, message: '客户不能为空', trigger: 'change' }],
salesPersonId: [{ required: true, message: '销售人员不能为空', trigger: 'change' }], salesPersonId: [{ required: true, message: '销售人员不能为空', trigger: 'change' }],
diseaseType: [ // ...
{
validator: (rule, val, cb) => {
if (this.isEliminationSale && !val) return cb(new Error('淘汰销售必须选择疾病类型'))
cb()
},
trigger: 'change',
},
],
groupCode: [
{
validator: (rule, val, cb) => {
if (this.isEliminationSale && !val) return cb(new Error('淘汰销售必须选择班组'))
cb()
},
trigger: 'change',
},
],
secondaryReason: [
{
validator: (rule, val, cb) => {
if (this.diseaseTypeLabel === '病残羊' && !val) return cb(new Error('疾病类型为病残羊时必须填写次要原因'))
cb()
},
trigger: 'blur',
},
],
}, },
} }
}, },
computed: { computed: {
// "(label)" dictValue
isEliminationSale() { isEliminationSale() {
const opt = this.saleTypeOptions.find(o => o.dictValue === this.form.saleType) const opt = this.saleTypeOptions.find(o => o.dictValue === this.form.saleType)
const label = opt ? opt.dictLabel : '' const label = opt ? opt.dictLabel : ''
@ -588,7 +333,6 @@ export default {
}, },
}, },
watch: { watch: {
// ""
'form.bsManageTagsList'(val = []) { 'form.bsManageTagsList'(val = []) {
const added = Array.isArray(val) ? val.filter(v => !this._prevTags.includes(v)) : [] const added = Array.isArray(val) ? val.filter(v => !this._prevTags.includes(v)) : []
if (added.length > 0) { if (added.length > 0) {
@ -596,7 +340,6 @@ export default {
} }
this._prevTags = Array.isArray(val) ? [...val] : [] this._prevTags = Array.isArray(val) ? [...val] : []
//
if (this.form.pricingMethod === '按个体') { if (this.form.pricingMethod === '按个体') {
this.calculateIndividualPrice() this.calculateIndividualPrice()
} else if (this.form.pricingMethod === '按体重') { } else if (this.form.pricingMethod === '按体重') {
@ -619,18 +362,24 @@ export default {
this.getDictsData() this.getDictsData()
this.getSheepfoldOptions() this.getSheepfoldOptions()
this.getUserOptions() this.getUserOptions()
this.remoteMethodGetCustomer('') // this.remoteMethodGetCustomer('')
}, },
methods: { methods: {
/** 禁用未来日期 */
disabledDate(time) { disabledDate(time) {
return time.getTime() > Date.now() return time.getTime() > Date.now()
}, },
/** 查询列表 */
getList() { getList() {
this.loading = true this.loading = true
listSaleRecord(this.queryParams) const params = { ...this.queryParams }
if (this.dateRange && this.dateRange.length === 2) {
params.params = {
beginSaleDate: this.dateRange[0],
endSaleDate: this.dateRange[1]
}
}
listSaleRecord(params)
.then(res => { .then(res => {
this.saleRecordList = res.rows || [] this.saleRecordList = res.rows || []
this.total = res.total || 0 this.total = res.total || 0
@ -638,7 +387,26 @@ export default {
.finally(() => (this.loading = false)) .finally(() => (this.loading = false))
}, },
// handleSortChange({ column, prop, order }) {
this.queryParams.orderByColumn = prop
this.queryParams.isAsc = order === 'ascending' ? 'asc' : 'desc'
this.getList()
},
// sheepfoldId
sheepfoldFormat(row) {
if (!row.sheepfoldId) return '';
// sheepfoldOptions
// id/name sheepfoldId/sheepfoldName
const found = this.sheepfoldOptions.find(item =>
(item.id == row.sheepfoldId) || (item.sheepfoldId == row.sheepfoldId)
);
if (found) {
return found.sheepfoldName || found.name;
}
return row.sheepfoldId; // ID
},
saleTypeFormat(row) { saleTypeFormat(row) {
return this.selectDictLabel(this.saleTypeOptions, row.saleType) return this.selectDictLabel(this.saleTypeOptions, row.saleType)
}, },
@ -649,34 +417,35 @@ export default {
return this.selectDictLabel(this.groupOptions, row.groupCode) return this.selectDictLabel(this.groupOptions, row.groupCode)
}, },
//
handleQuery() { handleQuery() {
this.queryParams.pageNum = 1 this.queryParams.pageNum = 1
this.getList() this.getList()
}, },
resetQuery() { resetQuery() {
this.dateRange = []
this.resetForm('queryForm') this.resetForm('queryForm')
this.queryParams.orderByColumn = null
this.queryParams.isAsc = null
if (this.$refs.table) {
this.$refs.table.clearSort()
}
this.handleQuery() this.handleQuery()
}, },
//
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.ids = selection.map(item => item.id) this.ids = selection.map(item => item.id)
this.single = selection.length !== 1 this.single = selection.length !== 1
this.multiple = !selection.length this.multiple = !selection.length
}, },
//
handleAdd() { handleAdd() {
this.reset() this.reset()
this.open = true this.open = true
this.title = '添加羊只销售记录' this.title = '添加羊只销售记录'
this.form.eventType = '销售' this.form.eventType = '销售'
// ( value-format="yyyy-MM-dd" )
this.form.saleDate = new Date().toISOString().slice(0, 10) this.form.saleDate = new Date().toISOString().slice(0, 10)
}, },
//
handleUpdate(row) { handleUpdate(row) {
this.reset() this.reset()
const id = row.id || this.ids const id = row.id || this.ids
@ -691,13 +460,11 @@ export default {
}) })
}, },
//
cancel() { cancel() {
this.open = false this.open = false
this.reset() this.reset()
}, },
//
reset() { reset() {
this.form = { this.form = {
id: null, id: null,
@ -746,19 +513,14 @@ export default {
this.resetForm('formRef') this.resetForm('formRef')
}, },
/** 提交 */
submitForm() { submitForm() {
this.$refs.formRef.validate(valid => { this.$refs.formRef.validate(valid => {
if (!valid) return if (!valid) return
//
if (Array.isArray(this.form.bsManageTagsList) && this.form.bsManageTagsList.length > 0) { if (Array.isArray(this.form.bsManageTagsList) && this.form.bsManageTagsList.length > 0) {
this.form.bsManageTags = this.form.bsManageTagsList.join(',') this.form.bsManageTags = this.form.bsManageTagsList.join(',')
} else { } else {
this.form.bsManageTags = null this.form.bsManageTags = null
} }
// createdBy / createdAt
const api = this.form.id ? updateSaleRecord : addSaleRecord const api = this.form.id ? updateSaleRecord : addSaleRecord
api(this.form) api(this.form)
.then(() => { .then(() => {
@ -767,12 +529,11 @@ export default {
this.getList() this.getList()
}) })
.catch(err => { .catch(err => {
this.$modal.msgError((this.form.id ? '修改失败:' : '新增失败:') + (err.message || '未知错误')) console.error(err)
}) })
}) })
}, },
/** 删除 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids const ids = row.id || this.ids
this.$modal.confirm('是否确认删除羊只销售记录编号为"' + ids + '"的数据项?') this.$modal.confirm('是否确认删除羊只销售记录编号为"' + ids + '"的数据项?')
@ -784,35 +545,37 @@ export default {
.catch(() => {}) .catch(() => {})
}, },
/** 导出 */
handleExport() { handleExport() {
this.$modal.confirm('是否确认导出所有羊只销售记录数据项?').then(() => { this.$modal.confirm('是否确认导出所有羊只销售记录数据项?').then(() => {
this.download('/saleRecord/saleRecord/export', { ...this.queryParams }, `saleRecord_${new Date().getTime()}.xlsx`) const params = { ...this.queryParams }
if (this.dateRange && this.dateRange.length === 2) {
params.params = {
beginSaleDate: this.dateRange[0],
endSaleDate: this.dateRange[1]
}
}
this.download('/saleRecord/saleRecord/export', params, `saleRecord_${new Date().getTime()}.xlsx`)
}) })
}, },
/** 字典数据(注意 disease_type */
getDictsData() { getDictsData() {
getDicts('sale_type').then(r => (this.saleTypeOptions = r.data || [])) getDicts('sale_type').then(r => (this.saleTypeOptions = r.data || []))
getDicts('disease_type').then(r => (this.diseaseTypeOptions = r.data || [])) getDicts('disease_type').then(r => (this.diseaseTypeOptions = r.data || []))
getDicts('group').then(r => (this.groupOptions = r.data || [])) getDicts('group').then(r => (this.groupOptions = r.data || []))
}, },
/** 羊舍下拉 */
getSheepfoldOptions() { getSheepfoldOptions() {
listSheepfold_management().then(r => { listSheepfold_management().then(r => {
this.sheepfoldOptions = r.rows || r.data || [] this.sheepfoldOptions = r.rows || r.data || []
}) })
}, },
/** 用户下拉(销售人员、技术员、处理人) */
getUserOptions() { getUserOptions() {
listUser().then(r => { listUser().then(r => {
this.userOptions = r.rows || r.data || [] this.userOptions = r.rows || r.data || []
}) })
}, },
/** 客户远程搜索:使用 sx_customer.name 字段 */
remoteMethodGetCustomer(query) { remoteMethodGetCustomer(query) {
this.customerLoading = true this.customerLoading = true
const p = query ? { name: query } : {} const p = query ? { name: query } : {}
@ -823,31 +586,24 @@ export default {
.finally(() => (this.customerLoading = false)) .finally(() => (this.customerLoading = false))
}, },
/** 客户选择后回填 name/phone/address 到表单 */
handleCustomerChange(customerId) { handleCustomerChange(customerId) {
const customer = this.customerOptions.find(item => item.id === customerId) const customer = this.customerOptions.find(item => item.id === customerId)
if (customer) { if (customer) {
this.form.customerName = customer.name this.form.customerName = customer.name
this.form.customerPhone = customer.phone this.form.customerPhone = customer.phone
this.form.customerAddress = customer.address this.form.customerAddress = customer.address
} else {
this.form.customerName = null
this.form.customerPhone = null
this.form.customerAddress = null
} }
}, },
/** 羊舍改变:加载耳号(此处示例,替换成你的真实接口) */
handleSheepfoldChange(sheepfoldId) { handleSheepfoldChange(sheepfoldId) {
this.form.bsManageTagsList = [] this.form.bsManageTagsList = []
this.earTagOptions = [] this.earTagOptions = []
// TODO: getEarTagsBySheepfold(sheepfoldId)
if (sheepfoldId) { if (sheepfoldId) {
//
this.earTagOptions = ['1001', '1002', '1003', '1004', '1005'] this.earTagOptions = ['1001', '1002', '1003', '1004', '1005']
} }
}, },
/** 根据耳号查羊只信息 */
fetchSheepInfo(bsManageTags) { fetchSheepInfo(bsManageTags) {
if (!bsManageTags) return if (!bsManageTags) return
getSheepInfo(bsManageTags).then(response => { getSheepInfo(bsManageTags).then(response => {
@ -872,7 +628,6 @@ export default {
}) })
}, },
/** 计价方式切换 */
handlePricingMethodChange(method) { handlePricingMethodChange(method) {
if (method === '按个体') { if (method === '按个体') {
this.form.totalWeight = null this.form.totalWeight = null
@ -883,7 +638,6 @@ export default {
} }
}, },
/** 按个体计价 */
calculateIndividualPrice() { calculateIndividualPrice() {
if (this.form.pricingMethod !== '按个体') return if (this.form.pricingMethod !== '按个体') return
const unitPrice = parseFloat(this.form.unitPrice) || 0 const unitPrice = parseFloat(this.form.unitPrice) || 0
@ -893,7 +647,6 @@ export default {
this.form.avgPricePerSheep = Number.isFinite(unitPrice) ? Number(unitPrice.toFixed(2)) : 0 this.form.avgPricePerSheep = Number.isFinite(unitPrice) ? Number(unitPrice.toFixed(2)) : 0
}, },
/** 按体重计价 */
calculateWeightPrice() { calculateWeightPrice() {
if (this.form.pricingMethod !== '按体重') return if (this.form.pricingMethod !== '按体重') return
const unitPrice = parseFloat(this.form.unitPrice) || 0 const unitPrice = parseFloat(this.form.unitPrice) || 0
@ -907,7 +660,6 @@ export default {
this.form.avgPricePerSheep = Number.isFinite(avgP) ? Number(avgP.toFixed(2)) : 0 this.form.avgPricePerSheep = Number.isFinite(avgP) ? Number(avgP.toFixed(2)) : 0
}, },
/** 销售类别变化:清理并重新校验 */
handleSaleTypeChange() { handleSaleTypeChange() {
if (!this.isEliminationSale) { if (!this.isEliminationSale) {
this.form.diseaseType = null this.form.diseaseType = null
@ -919,7 +671,6 @@ export default {
}) })
}, },
/** 疾病类型变化:联动"次要原因" */
handleDiseaseTypeChange() { handleDiseaseTypeChange() {
if (this.diseaseTypeLabel !== '病残羊') { if (this.diseaseTypeLabel !== '病残羊') {
this.form.secondaryReason = null this.form.secondaryReason = null

File diff suppressed because one or more lines are too long