xsh_1997 2 weken geleden
bovenliggende
commit
617148aee9

+ 107 - 0
doc/产业数据模型及服务/草畜失衡预警/草畜失衡预警前端技术方案.md

@@ -0,0 +1,107 @@
1
+# 草畜失衡预警 — 前端技术方案
2
+
3
+> 依据:同目录功能需求、技术方案;交互对齐牦牛疾病预警(只读列表 + 详情);字段 **小驼峰**。
4
+
5
+---
6
+
7
+## 1. 页面与路由
8
+
9
+| 项 | 说明 |
10
+| --- | --- |
11
+| **Vue 路径** | `ruoyi-ui/src/views/dataModel/grassLivestockImbalanceWarning/index.vue` |
12
+| **组件名** | `GrassLivestockImbalanceWarning` |
13
+| **菜单配置** | 组件路径:`dataModel/grassLivestockImbalanceWarning/index` |
14
+| **权限前缀** | `dataModel:grassLivestockImbalanceWarning:list\|query` |
15
+
16
+本期 **无** 新增 / 修改 / 删除 / 同步;写入由家庭牧场、农牧户、养殖大户填报后端自动触发。
17
+
18
+---
19
+
20
+## 2. API 模块
21
+
22
+| 项 | 说明 |
23
+| --- | --- |
24
+| **文件** | `ruoyi-ui/src/api/dataModel/grassLivestockImbalanceWarning.js` |
25
+| **Base** | `/dataModel/grassLivestockImbalanceWarning` |
26
+
27
+| 方法 | 路径 | 说明 |
28
+| --- | --- | --- |
29
+| `listGrassLivestockImbalanceWarning` | GET `/list` | 分页;筛选见下 |
30
+| `getGrassLivestockImbalanceWarning` | GET `/{id}` | 详情 |
31
+
32
+**列表 Query**
33
+
34
+| 参数 | 说明 |
35
+| --- | --- |
36
+| `startDate` / `endDate` | 预警日期(`yyyy-MM-dd`) |
37
+| `dataSource` | `family_ranch` / `farmer_household` / `large_livestock_farmer` |
38
+| `subjectName` | 主体名称模糊 |
39
+| `pageNum` / `pageSize` | 分页(默认 20) |
40
+
41
+---
42
+
43
+## 3. 页面结构
44
+
45
+1. **筛选**:预警日期范围、数据来源、主体名称;搜索、重置。  
46
+2. **列表**:预警时间、数据来源、年、月、乡镇、村、主体、核定载畜量、年底存栏、预警信息、操作(查看)。  
47
+3. **详情**:只读分区;含业务键 `sourceKey`;载畜量/存栏带「绵羊单位」。
48
+
49
+### 详情分区
50
+
51
+| 分区 | 内容 |
52
+| --- | --- |
53
+| 基本信息 | 预警时间、数据来源、业务键、年月、乡镇村、主体名称 |
54
+| 草畜失衡情况 | 核定载畜量、年底存栏、预警信息 |
55
+
56
+---
57
+
58
+## 4. 业务规则
59
+
60
+| 规则 | 实现 |
61
+| --- | --- |
62
+| 只读 | 无增删改入口 |
63
+| 日期筛选 | `startDate`/`endDate`;开始晚于结束前端提示并阻断 |
64
+| 来源文案 | 枚举映射中文/藏文标签,未知码原样展示 |
65
+| 空值 | 展示「—」(`dataModel.status.dash`) |
66
+| 排序 | 后端 `alert_time DESC, id DESC` |
67
+
68
+### 数据来源映射
69
+
70
+| `dataSource` | 界面 |
71
+| --- | --- |
72
+| `family_ranch` | 家庭牧场 |
73
+| `farmer_household` | 农牧户 |
74
+| `large_livestock_farmer` | 养殖大户 |
75
+
76
+---
77
+
78
+## 5. 国际化
79
+
80
+`dataModel.grassLivestockImbalanceWarning`(`lang/zh|bo/dataModel.js`);页面 `dmNs = 'grassLivestockImbalanceWarning'`,复用 `dataModelLocaleMixin`(`dmT` / `dmCommon` / `formatWithUnit`)。查看表单使用 `dm-view-form`。
81
+
82
+---
83
+
84
+## 6. 联调说明
85
+
86
+1. 执行 `sql/biz_grass_livestock_imbalance_warning.sql`。  
87
+2. 菜单组件 `dataModel/grassLivestockImbalanceWarning/index`,权限见 §1。  
88
+3. 验证:三处填报失衡后列表可见;按来源/主体/日期筛选;详情只读;恢复平衡或删除源记录后预警消失。
89
+
90
+---
91
+
92
+## 7. 文件清单
93
+
94
+| 类型 | 路径 |
95
+| --- | --- |
96
+| 页面 | `ruoyi-ui/src/views/dataModel/grassLivestockImbalanceWarning/index.vue` |
97
+| API | `ruoyi-ui/src/api/dataModel/grassLivestockImbalanceWarning.js` |
98
+| i18n | `lang/zh/dataModel.js`、`lang/bo/dataModel.js` → `grassLivestockImbalanceWarning` |
99
+| 前端技术方案 | 本文档 |
100
+
101
+---
102
+
103
+## 8. 修订记录
104
+
105
+| 版本 | 说明 |
106
+| --- | --- |
107
+| 1.0 | 初版:只读列表 + 详情;来源三枚举;无手工写入 |

+ 1 - 0
doc/产业数据模型及服务/草畜失衡预警/草畜失衡预警功能需求.md

@@ -42,6 +42,7 @@
42 42
 ## 5. 相关文档
43 43
 
44 44
 - [草畜失衡预警技术方案.md](./草畜失衡预警技术方案.md)
45
+- [草畜失衡预警前端技术方案.md](./草畜失衡预警前端技术方案.md)
45 46
 - [草畜失衡预警测试用例.md](./草畜失衡预警测试用例.md)
46 47
 
47 48
 ---

+ 2 - 0
doc/产业数据模型及服务/草畜失衡预警/草畜失衡预警技术方案.md

@@ -114,6 +114,8 @@ Base Path:`/dataModel/grassLivestockImbalanceWarning`
114 114
 
115 115
 ## 5. 前端
116 116
 
117
+详见同目录 **[草畜失衡预警前端技术方案.md](./草畜失衡预警前端技术方案.md)**。
118
+
117 119
 | 项 | 路径 |
118 120
 | --- | --- |
119 121
 | 页面 | `ruoyi-ui/src/views/dataModel/grassLivestockImbalanceWarning/index.vue` |

+ 18 - 0
ruoyi-ui/src/api/dataModel/grassLivestockImbalanceWarning.js

@@ -0,0 +1,18 @@
1
+import request from "@/utils/request"
2
+
3
+/** 草畜失衡预警分页列表 */
4
+export function listGrassLivestockImbalanceWarning(query) {
5
+  return request({
6
+    url: "/dataModel/grassLivestockImbalanceWarning/list",
7
+    method: "get",
8
+    params: query
9
+  })
10
+}
11
+
12
+/** 预警详情 */
13
+export function getGrassLivestockImbalanceWarning(id) {
14
+  return request({
15
+    url: "/dataModel/grassLivestockImbalanceWarning/" + id,
16
+    method: "get"
17
+  })
18
+}

+ 39 - 0
ruoyi-ui/src/lang/bo/dataModel.js

@@ -1016,5 +1016,44 @@ export default {
1016 1016
     ruleCountNonNegative: "0་ཡན་གྱི་ཧྲིལ་གྲངས་དགོས།",
1017 1017
     ruleActualLeShould: "དངོས་འགོག་གྲངས་འགོག་དགོས་གྲངས་ལས་མང་མི་ཆོག",
1018 1018
     villageTreeEmpty: "གྲོང་ཚོའི་སྒྲིག་འཛུགས་མ་ལོན,ལས་ཁུངས་ནང་「ཤང་གྲོང→གྲོང་ཚོ」ཡོད་མེད་ཞིབ་རོགས།"
1019
+  },
1020
+  grassLivestockImbalanceWarning: {
1021
+    queryAlertDate: "ཉེན་བརྡ་ཚེས།",
1022
+    queryDateRangePh: "འགོ་ཚེས།",
1023
+    queryDateRangeEndPh: "མཇུག་ཚེས།",
1024
+    queryDataSource: "གཞི་གྲངས་ཁུངས།",
1025
+    querySubjectName: "གཙོ་བོའི་མིང་།",
1026
+    phSubjectName: "གཙོ་བོའི་མིང་འབྲི་རོགས།",
1027
+    colAlertTime: "ཉེན་བརྡ་དུས།",
1028
+    colDataSource: "གཞི་གྲངས་ཁུངས།",
1029
+    colStatYear: "གཏོགས་ལོ།",
1030
+    colStatMonth: "གཏོགས་ཟླ།",
1031
+    statMonthLabel: "{month}ཟླ།",
1032
+    colTownName: "ཤང་གྲོང།",
1033
+    colVillageName: "གྲོང་ཚོ།",
1034
+    colSubjectName: "གཙོ་བོའི་མིང་།",
1035
+    colApprovedCarryingCapacity: "གཏན་འཁེལ་ཁུར་ཚད།",
1036
+    colYearEndStockSheepUnit: "ལོ་མཇུག་གནས་ཚད།",
1037
+    colAlertMessage: "ཉེན་བརྡ་གནས་ཚུལ།",
1038
+    viewTitle: "ཉེན་བརྡ་ཞིབ་ཕྲ།",
1039
+    sectionBasic: "གཞི་རྩའི་གནས་ཚུལ།",
1040
+    sectionBalance: "རྩྭ་ཕྱུགས་མི་སྙོམས་གནས་ཚུལ།",
1041
+    formAlertTime: "ཉེན་བརྡ་དུས།",
1042
+    formDataSource: "གཞི་གྲངས་ཁུངས།",
1043
+    formSourceKey: "ལས་དོན་མཐེབ།",
1044
+    formStatYear: "གཏོགས་ལོ།",
1045
+    formStatMonth: "གཏོགས་ཟླ།",
1046
+    formTown: "ཤང་གྲོང།",
1047
+    formVillage: "གྲོང་ཚོ།",
1048
+    formSubjectName: "གཙོ་བོའི་མིང་།",
1049
+    formApprovedCarryingCapacity: "གཏན་འཁེལ་ལོ་མཇུག་རྩྭ་ཕྱུགས་སྙོམས་ཁུར་ཚད།",
1050
+    formYearEndStockSheepUnit: "ལོ་མཇུག་ཕྱུགས་གནས་ཚད།",
1051
+    formAlertMessage: "ཉེན་བརྡ་གནས་ཚུལ།",
1052
+    dataSourceFamilyRanch: "ཁྱིམ་ཚང་འབྲོག་ར།",
1053
+    dataSourceFarmerHousehold: "ཞིང་འབྲོག་ཁྱིམ།",
1054
+    dataSourceLargeLivestockFarmer: "གསོ་སྤེལ་ཁྱིམ་ཆེན།",
1055
+    unitSheepUnit: "ལུག་རིམ།",
1056
+    dateRangeInvalid: "འགོ་ཚེས་མཇུག་ཚེས་ལས་ཕྱི་མི་ཆོག",
1057
+    emptyList: "ཉེན་བརྡ་གཞི་གྲངས་མེད།"
1019 1058
   }
1020 1059
 }

+ 39 - 0
ruoyi-ui/src/lang/zh/dataModel.js

@@ -1016,5 +1016,44 @@ export default {
1016 1016
     ruleCountNonNegative: "须为大于等于 0 的整数",
1017 1017
     ruleActualLeShould: "实免数不能大于应免数",
1018 1018
     villageTreeEmpty: "未加载到村级组织数据,请确认系统部门已维护「乡镇→村」"
1019
+  },
1020
+  grassLivestockImbalanceWarning: {
1021
+    queryAlertDate: "预警日期",
1022
+    queryDateRangePh: "开始日期",
1023
+    queryDateRangeEndPh: "结束日期",
1024
+    queryDataSource: "数据来源",
1025
+    querySubjectName: "主体名称",
1026
+    phSubjectName: "请输入主体名称",
1027
+    colAlertTime: "预警时间",
1028
+    colDataSource: "数据来源",
1029
+    colStatYear: "所属年份",
1030
+    colStatMonth: "所属月份",
1031
+    statMonthLabel: "{month}月",
1032
+    colTownName: "所属乡镇",
1033
+    colVillageName: "所属村",
1034
+    colSubjectName: "主体名称",
1035
+    colApprovedCarryingCapacity: "核定载畜量",
1036
+    colYearEndStockSheepUnit: "年底存栏",
1037
+    colAlertMessage: "预警信息",
1038
+    viewTitle: "预警详情",
1039
+    sectionBasic: "基本信息",
1040
+    sectionBalance: "草畜失衡情况",
1041
+    formAlertTime: "预警时间",
1042
+    formDataSource: "数据来源",
1043
+    formSourceKey: "业务键",
1044
+    formStatYear: "所属年份",
1045
+    formStatMonth: "所属月份",
1046
+    formTown: "所属乡镇",
1047
+    formVillage: "所属村",
1048
+    formSubjectName: "主体名称",
1049
+    formApprovedCarryingCapacity: "核定年末草畜平衡载畜量",
1050
+    formYearEndStockSheepUnit: "年底牲畜存栏",
1051
+    formAlertMessage: "预警信息",
1052
+    dataSourceFamilyRanch: "家庭牧场",
1053
+    dataSourceFarmerHousehold: "农牧户",
1054
+    dataSourceLargeLivestockFarmer: "养殖大户",
1055
+    unitSheepUnit: "绵羊单位",
1056
+    dateRangeInvalid: "开始日期不能晚于结束日期",
1057
+    emptyList: "暂无预警数据"
1019 1058
   }
1020 1059
 }

+ 292 - 0
ruoyi-ui/src/views/dataModel/grassLivestockImbalanceWarning/index.vue

@@ -0,0 +1,292 @@
1
+<template>
2
+  <div class="app-container">
3
+    <el-card shadow="never">
4
+      <el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
5
+        <el-form-item>
6
+          <template slot="label">{{ dmT("queryAlertDate") }}</template>
7
+          <el-date-picker
8
+            v-model="queryDateRange"
9
+            type="daterange"
10
+            value-format="yyyy-MM-dd"
11
+            range-separator="-"
12
+            :start-placeholder="dmT('queryDateRangePh')"
13
+            :end-placeholder="dmT('queryDateRangeEndPh')"
14
+            clearable
15
+            style="width: 240px"
16
+          />
17
+        </el-form-item>
18
+        <el-form-item prop="dataSource">
19
+          <template slot="label">{{ dmT("queryDataSource") }}</template>
20
+          <el-select
21
+            v-model="queryParams.dataSource"
22
+            :placeholder="dmCommon('pleaseSelect')"
23
+            clearable
24
+            style="width: 180px"
25
+          >
26
+            <el-option
27
+              v-for="item in dataSourceOptions"
28
+              :key="item.value"
29
+              :label="item.label"
30
+              :value="item.value"
31
+            />
32
+          </el-select>
33
+        </el-form-item>
34
+        <el-form-item prop="subjectName">
35
+          <template slot="label">{{ dmT("querySubjectName") }}</template>
36
+          <el-input
37
+            v-model="queryParams.subjectName"
38
+            :placeholder="dmT('phSubjectName')"
39
+            clearable
40
+            style="width: 180px"
41
+            @keyup.enter.native="handleQuery"
42
+          />
43
+        </el-form-item>
44
+        <el-form-item>
45
+          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">{{ dmCommon("search") }}</el-button>
46
+          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{ dmCommon("reset") }}</el-button>
47
+        </el-form-item>
48
+      </el-form>
49
+    </el-card>
50
+
51
+    <br />
52
+
53
+    <el-card shadow="never">
54
+      <el-table v-loading="loading" :data="tableList" border>
55
+        <template slot="empty">
56
+          <span>{{ dmT("emptyList") }}</span>
57
+        </template>
58
+        <el-table-column :label="dmT('colAlertTime')" prop="alertTime" align="center" width="170" />
59
+        <el-table-column :label="dmT('colDataSource')" align="center" min-width="110">
60
+          <template slot-scope="scope">{{ dataSourceText(scope.row.dataSource) }}</template>
61
+        </el-table-column>
62
+        <el-table-column :label="dmT('colStatYear')" prop="statYear" align="center" width="90" />
63
+        <el-table-column :label="dmT('colStatMonth')" align="center" width="80">
64
+          <template slot-scope="scope">{{ formatStatMonth(scope.row.statMonth) }}</template>
65
+        </el-table-column>
66
+        <el-table-column :label="dmT('colTownName')" prop="townName" align="center" min-width="100" :show-overflow-tooltip="true" />
67
+        <el-table-column :label="dmT('colVillageName')" prop="villageName" align="center" min-width="100" :show-overflow-tooltip="true" />
68
+        <el-table-column :label="dmT('colSubjectName')" prop="subjectName" align="center" min-width="120" :show-overflow-tooltip="true" />
69
+        <el-table-column :label="dmT('colApprovedCarryingCapacity')" align="center" min-width="130">
70
+          <template slot-scope="scope">{{ formatDecimal(scope.row.approvedCarryingCapacity) }}</template>
71
+        </el-table-column>
72
+        <el-table-column :label="dmT('colYearEndStockSheepUnit')" align="center" min-width="130">
73
+          <template slot-scope="scope">{{ formatDecimal(scope.row.yearEndStockSheepUnit) }}</template>
74
+        </el-table-column>
75
+        <el-table-column :label="dmT('colAlertMessage')" prop="alertMessage" align="center" min-width="200" :show-overflow-tooltip="true" />
76
+        <el-table-column :label="dmCommon('colOp')" align="center" class-name="small-padding fixed-width" width="100" fixed="right">
77
+          <template slot-scope="scope">
78
+            <el-button
79
+              v-hasPermi="['dataModel:grassLivestockImbalanceWarning:query']"
80
+              type="text"
81
+              size="mini"
82
+              @click="handleView(scope.row)"
83
+            >{{ dmCommon("view") }}</el-button>
84
+          </template>
85
+        </el-table-column>
86
+      </el-table>
87
+      <pagination
88
+        v-show="total > 0"
89
+        :total="total"
90
+        :page.sync="queryParams.pageNum"
91
+        :limit.sync="queryParams.pageSize"
92
+        @pagination="getList"
93
+      />
94
+    </el-card>
95
+
96
+    <el-dialog :title="dmT('viewTitle')" :visible.sync="viewOpen" width="720px" append-to-body>
97
+      <el-form class="dm-view-form gliw-form" label-width="160px" size="small">
98
+        <div class="gliw-section-title">{{ dmT("sectionBasic") }}</div>
99
+        <el-form-item :label="dmT('formAlertTime')"><span>{{ viewRow.alertTime || dash }}</span></el-form-item>
100
+        <el-form-item :label="dmT('formDataSource')"><span>{{ dataSourceText(viewRow.dataSource) }}</span></el-form-item>
101
+        <el-form-item :label="dmT('formSourceKey')"><span>{{ viewRow.sourceKey || dash }}</span></el-form-item>
102
+        <el-form-item :label="dmT('formStatYear')"><span>{{ viewRow.statYear || dash }}</span></el-form-item>
103
+        <el-form-item :label="dmT('formStatMonth')"><span>{{ formatStatMonth(viewRow.statMonth) }}</span></el-form-item>
104
+        <el-form-item :label="dmT('formTown')"><span>{{ viewRow.townName || dash }}</span></el-form-item>
105
+        <el-form-item :label="dmT('formVillage')"><span>{{ viewRow.villageName || dash }}</span></el-form-item>
106
+        <el-form-item :label="dmT('formSubjectName')"><span>{{ viewRow.subjectName || dash }}</span></el-form-item>
107
+
108
+        <div class="gliw-section-title">{{ dmT("sectionBalance") }}</div>
109
+        <el-form-item :label="dmT('formApprovedCarryingCapacity')">
110
+          <span>{{ formatWithUnit(formatDecimal(viewRow.approvedCarryingCapacity), "unitSheepUnit") }}</span>
111
+        </el-form-item>
112
+        <el-form-item :label="dmT('formYearEndStockSheepUnit')">
113
+          <span>{{ formatWithUnit(formatDecimal(viewRow.yearEndStockSheepUnit), "unitSheepUnit") }}</span>
114
+        </el-form-item>
115
+        <el-form-item :label="dmT('formAlertMessage')">
116
+          <span class="gliw-message-text">{{ viewRow.alertMessage || dash }}</span>
117
+        </el-form-item>
118
+      </el-form>
119
+      <div slot="footer" class="dialog-footer">
120
+        <el-button type="primary" @click="viewOpen = false">{{ dmCommon("close") }}</el-button>
121
+      </div>
122
+    </el-dialog>
123
+  </div>
124
+</template>
125
+
126
+<script>
127
+import dataModelLocaleMixin from "@/mixins/dataModelLocaleMixin"
128
+import {
129
+  listGrassLivestockImbalanceWarning,
130
+  getGrassLivestockImbalanceWarning
131
+} from "@/api/dataModel/grassLivestockImbalanceWarning"
132
+
133
+const DATA_SOURCE_FAMILY_RANCH = "family_ranch"
134
+const DATA_SOURCE_FARMER_HOUSEHOLD = "farmer_household"
135
+const DATA_SOURCE_LARGE_LIVESTOCK_FARMER = "large_livestock_farmer"
136
+
137
+export default {
138
+  name: "GrassLivestockImbalanceWarning",
139
+  mixins: [dataModelLocaleMixin],
140
+  data() {
141
+    return {
142
+      dmNs: "grassLivestockImbalanceWarning",
143
+      loading: false,
144
+      tableList: [],
145
+      total: 0,
146
+      queryDateRange: null,
147
+      queryParams: {
148
+        pageNum: 1,
149
+        pageSize: 20,
150
+        startDate: undefined,
151
+        endDate: undefined,
152
+        dataSource: undefined,
153
+        subjectName: undefined
154
+      },
155
+      viewOpen: false,
156
+      viewRow: {}
157
+    }
158
+  },
159
+  computed: {
160
+    dash() {
161
+      return this.$t("dataModel.status.dash")
162
+    },
163
+    dataSourceOptions() {
164
+      return [
165
+        { value: DATA_SOURCE_FAMILY_RANCH, label: this.dmT("dataSourceFamilyRanch") },
166
+        { value: DATA_SOURCE_FARMER_HOUSEHOLD, label: this.dmT("dataSourceFarmerHousehold") },
167
+        { value: DATA_SOURCE_LARGE_LIVESTOCK_FARMER, label: this.dmT("dataSourceLargeLivestockFarmer") }
168
+      ]
169
+    }
170
+  },
171
+  created() {
172
+    this.getList()
173
+  },
174
+  methods: {
175
+    dataSourceText(code) {
176
+      if (!code) {
177
+        return this.dash
178
+      }
179
+      const hit = this.dataSourceOptions.find((item) => item.value === code)
180
+      return hit ? hit.label : code
181
+    },
182
+    formatStatMonth(month) {
183
+      if (month == null || month === "") {
184
+        return this.dash
185
+      }
186
+      return this.dmT("statMonthLabel", { month })
187
+    },
188
+    formatDecimal(val) {
189
+      if (val == null || val === "") {
190
+        return this.dash
191
+      }
192
+      const n = Number(val)
193
+      if (!Number.isFinite(n)) {
194
+        return this.dash
195
+      }
196
+      return String(val)
197
+    },
198
+    buildListQuery() {
199
+      const q = {
200
+        pageNum: this.queryParams.pageNum,
201
+        pageSize: this.queryParams.pageSize
202
+      }
203
+      if (this.queryParams.startDate) {
204
+        q.startDate = this.queryParams.startDate
205
+      }
206
+      if (this.queryParams.endDate) {
207
+        q.endDate = this.queryParams.endDate
208
+      }
209
+      if (this.queryParams.dataSource) {
210
+        q.dataSource = this.queryParams.dataSource
211
+      }
212
+      if (this.queryParams.subjectName) {
213
+        q.subjectName = this.queryParams.subjectName
214
+      }
215
+      return q
216
+    },
217
+    checkQueryDateRange() {
218
+      if (this.queryDateRange && this.queryDateRange.length === 2) {
219
+        const [start, end] = this.queryDateRange
220
+        if (start && end && start > end) {
221
+          this.$modal.msgWarning(this.dmT("dateRangeInvalid"))
222
+          return false
223
+        }
224
+      }
225
+      return true
226
+    },
227
+    syncDateRangeToQuery() {
228
+      if (this.queryDateRange && this.queryDateRange.length === 2) {
229
+        this.queryParams.startDate = this.queryDateRange[0]
230
+        this.queryParams.endDate = this.queryDateRange[1]
231
+      } else {
232
+        this.queryParams.startDate = undefined
233
+        this.queryParams.endDate = undefined
234
+      }
235
+    },
236
+    getList() {
237
+      if (!this.checkQueryDateRange()) {
238
+        return
239
+      }
240
+      this.syncDateRangeToQuery()
241
+      this.loading = true
242
+      listGrassLivestockImbalanceWarning(this.buildListQuery())
243
+        .then((res) => {
244
+          this.tableList = res.rows || []
245
+          this.total = res.total || 0
246
+        })
247
+        .finally(() => {
248
+          this.loading = false
249
+        })
250
+    },
251
+    handleQuery() {
252
+      this.queryParams.pageNum = 1
253
+      this.getList()
254
+    },
255
+    resetQuery() {
256
+      this.queryDateRange = null
257
+      this.queryParams = {
258
+        pageNum: 1,
259
+        pageSize: 20,
260
+        startDate: undefined,
261
+        endDate: undefined,
262
+        dataSource: undefined,
263
+        subjectName: undefined
264
+      }
265
+      this.$nextTick(() => {
266
+        if (this.$refs.queryForm) {
267
+          this.$refs.queryForm.resetFields()
268
+        }
269
+      })
270
+      this.getList()
271
+    },
272
+    handleView(row) {
273
+      getGrassLivestockImbalanceWarning(row.id).then((res) => {
274
+        this.viewRow = res.data || {}
275
+        this.viewOpen = true
276
+      })
277
+    }
278
+  }
279
+}
280
+</script>
281
+
282
+<style scoped>
283
+.gliw-section-title {
284
+  margin: 4px 0 12px;
285
+  font-weight: 600;
286
+  color: #303133;
287
+}
288
+.gliw-message-text {
289
+  white-space: pre-wrap;
290
+  word-break: break-all;
291
+}
292
+</style>