xsh_1997 2 tygodni temu
rodzic
commit
58fb69f05b

+ 1 - 1
ruoyi-screen/.env.development

@@ -8,7 +8,7 @@ ENV=development
8 8
 VITE_APP_BASE_API=/dev-api
9 9
 
10 10
 # 仅本地 Vite 开发服务器使用,不会打进前端包
11
-VITE_PROXY_TARGET=http://192.168.1.18:8010
11
+VITE_PROXY_TARGET=http://192.168.1.6:8010
12 12
 
13 13
 # 天启气象(前端直连 gfeljm.tianqiapi.com)
14 14
 VITE_WEATHER_APP_ID=36793262

+ 390 - 13
ruoyi-screen/src/views/livestockResources/index.vue

@@ -1,29 +1,406 @@
1 1
 <template>
2
-  <div class="screen-page screen-page--placeholder">
3
-    <p class="placeholder__zh">畜牧资源大屏开发中</p>
4
-    <p class="placeholder__bo">སྐྱེས་ཁམས་ཐོན་ཁུངས་ཆེ་ཙལ་གསར་སྤེལ་བཞིན་པ།</p>
2
+  <div class="screen-page ts-page" :class="{ 'is-loading': loading }">
3
+    <div v-if="loadError" class="ts-error">{{ loadError }}</div>
4
+
5
+    <!-- <div class="ts-year-bar">
6
+      <label class="ts-year-bar__label">统计年份</label>
7
+      <select
8
+        v-model="statYear"
9
+        class="ts-year-bar__select"
10
+        :disabled="loading"
11
+        @change="onYearChange"
12
+      >
13
+        <option v-for="y in availableYears" :key="y" :value="String(y)">{{ y }}年</option>
14
+      </select>
15
+      <span v-if="statDate" class="ts-year-bar__date">统计日 {{ statDate }}</span>
16
+    </div> -->
17
+
18
+    <!-- 左栏:核心数据总览( -->
19
+    <div class="screen-page--home-column">
20
+      <div class="screen-page--home-column-top">
21
+        <div class="top_title">核心数据总览 གཙོ་བོའི་གནས་ཚད་བསྡུས་གསལ།</div>
22
+        <div class="ts-overview-grid">
23
+          <div
24
+            v-for="item in liveStock"
25
+            :key="item.key"
26
+            class="ts-overview-cell"
27
+            :class="{ 'ts-overview-cell--placeholder': item.placeholder }"
28
+          >
29
+            <div class="content_title"><div>{{ item.label }}</div></div>
30
+            <div class="content_num">
31
+              <strong class="content_num__value">{{ item.value }}</strong>
32
+              <span v-if="item.unit" class="content_num__unit">{{ item.unit }}</span>
33
+            </div>
34
+          </div>
35
+        </div>
36
+      </div>
37
+
38
+      <div class="screen-page--home-column-flex">
39
+        <div class="screen-page--home-column-flex-item">
40
+          <div class="flex_title">活跃度趋势 འགྲོ་འདུག་གོམ་སྟངས་རྒྱུན་སྟངས།</div>
41
+          <div class="flex_content flex_content--quote">
42
+           
43
+            <div class="quote-chart">
44
+              
45
+            </div>
46
+          </div>
47
+        </div>
48
+        <div class="screen-page--home-column-flex-item">
49
+          <div class="flex_title">用户结构分析 སྤྱོད་མིའི་གོ་སྐབས་དཔྱད་པ།</div>
50
+          <div class="flex_content">
51
+           
52
+          </div>
53
+        </div>
54
+      </div>
55
+
56
+      <div class="screen-page--home-column-flex">
57
+        <div class="screen-page--home-column-flex-item">
58
+          <div class="flex_title">提问分类占比 དྲིས་ལན་དབྱེ་རྩིས་བགོ་སྟངས།</div>
59
+          <div class="flex_content">
60
+          
61
+          </div>
62
+        </div>
63
+        <div class="screen-page--home-column-flex-item">
64
+          <div class="flex_title">模型调用分析 དཔེ་གཞི་འབྲི་རྩོམ་དཔྱད་པ།</div>
65
+          <div class="flex_content">
66
+           
67
+          </div>
68
+        </div>
69
+      </div>
70
+    </div>
71
+
72
+    <!-- 右栏:农资商城本期不实现,保留占位 -->
73
+    <div class="screen-page--home-column">
74
+      <div class="screen-page--home-column-right ts-mall-panel">
75
+        <div class="top_title">分时使用热度 དུས་སྐོར་སྤྱོད་སྟོབས་ཚད།</div>
76
+        
77
+      </div>
78
+      <div class="screen-page--home-column-flex">
79
+        <div class="screen-page--home-column-flex-item">
80
+          <div class="flex_title">会话提问数量分布 གོ་སྐབས་དྲིས་གྲངས་ཁྱབ་སྤེལ།</div>
81
+          <div class="flex_content flex_content--placeholder">
82
+          
83
+          </div>
84
+        </div>
85
+        <div class="screen-page--home-column-flex-item">
86
+          <div class="flex_title">会话状态分布 གོ་སྐབས་གནས་སྟངས་ཁྱབ་སྤེལ།</div>
87
+          <div class="flex_content flex_content--placeholder">
88
+          
89
+          </div>
90
+        </div>
91
+      </div>
92
+      <div class="screen-page--home-column-flex">
93
+        <div class="screen-page--home-column-flex-item">
94
+          <div class="flex_title">热门问题榜单 ཡོངས་གྲགས་དྲིས་ལན་གསལ་ཐོ།</div>
95
+          <div class="flex_content flex_content--placeholder">
96
+           
97
+          </div>
98
+        </div>
99
+        <div class="screen-page--home-column-flex-item">
100
+          <div class="flex_title">高频关键词 མང་དུ་སྦྱོང་བའི་ཚིག་གཙོ།</div>
101
+          <div class="flex_content flex_content--placeholder">
102
+           
103
+          </div>
104
+        </div>
105
+      </div>
106
+    </div>
5 107
   </div>
6 108
 </template>
7 109
 
110
+<script setup>
111
+import { computed, onMounted, ref } from 'vue'
112
+import ScreenChart from '@/components/ScreenChart.vue'
113
+
114
+const loading = ref(false)
115
+const loadError = ref('')
116
+const statYear = ref(String(new Date().getFullYear()))
117
+const statDate = ref('')
118
+
119
+const liveStock = ref([])
120
+
121
+
122
+</script>
123
+
8 124
 <style scoped>
9
-.screen-page--placeholder {
125
+.ts-page {
126
+  position: relative;
127
+  width: 100%;
128
+  height: 100%;
129
+  box-sizing: border-box;
130
+  padding: 20px;
131
+  display: flex;
132
+  flex-direction: row;
133
+  justify-content: space-between;
134
+}
135
+
136
+.ts-page.is-loading {
137
+  opacity: 0.92;
138
+}
139
+
140
+.ts-error {
141
+  position: absolute;
142
+  top: 4px;
143
+  left: 50%;
144
+  transform: translateX(-50%);
145
+  z-index: 10;
146
+  padding: 4px 12px;
147
+  font-size: 12px;
148
+  color: #ffb4b4;
149
+  background: rgba(80, 20, 20, 0.75);
150
+  border-radius: 4px;
151
+}
152
+
153
+.ts-year-bar {
154
+  position: absolute;
155
+  top: 8px;
156
+  right: 24px;
157
+  z-index: 5;
158
+  display: flex;
159
+  align-items: center;
160
+  gap: 8px;
161
+}
162
+
163
+.ts-year-bar__label {
164
+  font-size: 12px;
165
+  color: var(--screen-text-secondary, #a8d4c8);
166
+}
167
+
168
+.ts-year-bar__select {
169
+  min-width: 88px;
170
+  height: 28px;
171
+  padding: 0 8px;
172
+  font-size: 13px;
173
+  color: #e8eef5;
174
+  background: rgba(4, 48, 40, 0.85);
175
+  border: 1px solid var(--screen-line-dim, rgba(61, 217, 176, 0.42));
176
+  border-radius: 4px;
177
+  outline: none;
178
+}
179
+
180
+.ts-year-bar__date {
181
+  font-size: 11px;
182
+  color: rgba(168, 212, 200, 0.75);
183
+}
184
+
185
+.screen-page--home-column {
186
+  width: 617px;
187
+  height: 100%;
188
+  display: flex;
189
+  flex-direction: column;
190
+  justify-content: space-between;
191
+}
192
+
193
+.screen-page--home-column-top {
194
+  width: 617px;
195
+  height: 201px;
196
+  display: flex;
197
+  flex-direction: column;
198
+  box-sizing: border-box;
199
+  background: url('../../assets/sale/sale.png') no-repeat center center;
200
+  background-size: 100% 100%;
201
+}
202
+
203
+.screen-page--home-column-right {
204
+  width: 617px;
205
+  height: 201px;
206
+  background: url('../../assets/pro/pro.png') no-repeat center center;
207
+  background-size: 100% 100%;
208
+}
209
+
210
+.ts-mall-panel {
211
+  display: flex;
212
+  flex-direction: column;
213
+}
214
+
215
+.ts-placeholder {
216
+  flex: 1;
217
+  display: flex;
218
+  align-items: center;
219
+  justify-content: center;
220
+  padding: 0 24px;
221
+  text-align: center;
222
+  font-size: 14px;
223
+  color: rgba(168, 212, 200, 0.75);
224
+}
225
+
226
+.ts-placeholder--sm {
227
+  font-size: 13px;
228
+}
229
+
230
+.screen-page--home-column-flex {
231
+  width: 617px;
232
+  height: 223px;
233
+  display: flex;
234
+  justify-content: space-between;
235
+}
236
+
237
+.screen-page--home-column-flex-item {
238
+  width: 304px;
239
+  height: 223px;
240
+  background: url('../../assets/home/mini_box.png') no-repeat center center;
241
+  background-size: 100% 100%;
242
+}
243
+
244
+.top_title {
245
+  width: 100%;
246
+  height: 35px;
247
+  box-sizing: border-box;
248
+  font-size: 18px;
249
+  color: #fff;
250
+  line-height: 35px;
251
+  padding-left: 100px;
252
+  margin-bottom: 8px;
253
+  flex-shrink: 0;
254
+}
255
+
256
+.ts-overview-grid {
257
+  flex: 1;
258
+  min-height: 0;
259
+  box-sizing: border-box;
260
+  padding: 6px 20px 14px 32px;
261
+  display: grid;
262
+  grid-template-columns: repeat(3, 1fr);
263
+  grid-template-rows: repeat(2, 1fr);
264
+  gap: 4px 40px;
265
+}
266
+
267
+.ts-overview-cell {
268
+  display: flex;
269
+  flex-direction: column;
270
+  align-items: flex-end;
271
+  justify-content: center;
272
+  min-height: 0;
273
+  width: 100%;
274
+  text-align: right;
275
+  box-sizing: border-box;
276
+  padding-right: 10px;
277
+}
278
+
279
+.ts-overview-cell .content_title {
280
+  width: 100%;
281
+  text-align: right;
282
+}
283
+
284
+.ts-overview-cell .content_num {
285
+  width: 100%;
286
+  display: flex;
287
+  align-items: baseline;
288
+  justify-content: flex-end;
289
+  gap: 6px;
290
+  margin: 4px 0 0;
291
+  line-height: 1.3;
292
+}
293
+
294
+.content_num__value {
295
+  flex: 1;
296
+  min-width: 0;
297
+  text-align: right;
298
+  font-size: 24px;
299
+  font-weight: 600;
300
+  background: linear-gradient(to bottom, #98e9aa, #ecd27b);
301
+  -webkit-background-clip: text;
302
+  background-clip: text;
303
+  color: transparent;
304
+}
305
+
306
+.content_num__unit {
307
+  flex-shrink: 0;
308
+  font-size: 12px;
309
+  color: #a8d4c8;
310
+  line-height: 1.2;
311
+  text-align: right;
312
+}
313
+
314
+.ts-overview-cell--placeholder .content_num__value {
315
+  font-size: 18px;
316
+  background: none;
317
+  -webkit-background-clip: unset;
318
+  background-clip: unset;
319
+  color: #6a9f90;
320
+}
321
+
322
+.content_title {
323
+
324
+  font-size: 11px;
325
+  color: #a8d4c8;
326
+  line-height: 1.3;
327
+}
328
+
329
+.flex_title {
330
+  width: 100%;
331
+  box-sizing: border-box;
332
+  height: 35px;
333
+  font-size: 16px;
334
+  color: #fff;
335
+  line-height: 35px;
336
+  padding-left: 45px;
337
+  margin-bottom: 5px;
338
+}
339
+
340
+.flex_content {
341
+  width: 100%;
342
+  height: 180px;
343
+  box-sizing: border-box;
344
+  padding: 5px;
345
+}
346
+
347
+.flex_content--quote {
348
+  display: flex;
349
+  flex-direction: column;
350
+  padding: 4px 6px;
351
+}
352
+
353
+.quote-summary {
354
+  display: flex;
355
+  flex-direction: row;
356
+  gap: 6px;
357
+  height: 42px;
358
+  flex-shrink: 0;
359
+}
360
+
361
+.quote-summary__item {
10 362
   flex: 1;
11 363
   display: flex;
12 364
   flex-direction: column;
13 365
   align-items: center;
14 366
   justify-content: center;
15
-  gap: 8px;
16
-  color: #9aa8b4;
367
+  background: rgba(4, 48, 40, 0.45);
368
+  border-radius: 4px;
369
+  border: 1px solid rgba(61, 217, 176, 0.2);
17 370
 }
18 371
 
19
-.placeholder__zh {
20
-  margin: 0;
21
-  font-size: 15px;
372
+.quote-summary__label {
373
+  font-size: 10px;
374
+  color: #a8d4c8;
22 375
 }
23 376
 
24
-.placeholder__bo {
25
-  margin: 0;
26
-  font-size: 13px;
27
-  color: #7d8fa3;
377
+.quote-summary__val {
378
+  font-size: 11px;
379
+  color: #fff;
380
+}
381
+
382
+.quote-summary__val strong {
383
+  font-size: 14px;
384
+  background: linear-gradient(to bottom, #98e9aa, #ecd27b);
385
+  -webkit-background-clip: text;
386
+  background-clip: text;
387
+  color: transparent;
388
+}
389
+
390
+.quote-summary__unit {
391
+  font-size: 10px;
392
+  color: #a8d4c8;
393
+  margin-left: 2px;
394
+}
395
+
396
+.quote-chart {
397
+  flex: 1;
398
+  min-height: 0;
399
+}
400
+
401
+.flex_content--placeholder {
402
+  display: flex;
403
+  align-items: center;
404
+  justify-content: center;
28 405
 }
29 406
 </style>

+ 1 - 1
ruoyi-screen/vite.config.js

@@ -10,7 +10,7 @@ export default defineConfig(({ mode }) => {
10 10
   const env = loadEnv(mode, process.cwd(), '')
11 11
 
12 12
   const baseApi = env.VITE_APP_BASE_API || '/dev-api'
13
-  const proxyTarget = (env.VITE_PROXY_TARGET || 'http://192.168.1.18:8010').replace(/\/$/, '')
13
+  const proxyTarget = (env.VITE_PROXY_TARGET || 'http://192.168.1.6:8010').replace(/\/$/, '')
14 14
 
15 15
   const proxy = {
16 16
     [baseApi]: {

+ 1 - 1
ruoyi-ui-app/config/index.js

@@ -13,7 +13,7 @@
13 13
  */
14 14
 
15 15
 /** 与 ruoyi-ui/vue.config.js 中 baseUrl 一致 */
16
-export const DEV_API_HOST = 'http://192.168.1.10:8010'
16
+export const DEV_API_HOST = 'http://192.168.1.6:8010'
17 17
 
18 18
 /**
19 19
  * H5 是否走 /dev-api 开发代理(需 vite.config.js 的 rewrite,manifest 的 pathRewrite 在 Vue3 常不生效)

+ 3 - 0
ruoyi-ui-app/locale/bo.js

@@ -131,6 +131,9 @@ export default {
131 131
     modelFeeding: 'ཟས་སྦྱོར་ལག་རོགས',
132 132
     modelFeedingShort: 'ཟས་སྦྱོར',
133 133
     modelFeedingDesc: 'ཟས་སྦྱོར་གཞི་སྒྲིག',
134
+    modelGrowth: 'འཕེལ་རྒྱས་ལག་རོགས',
135
+    modelGrowthShort: 'འཕེལ་རྒྱས',
136
+    modelGrowthDesc: 'འབྲོང་སྐྱེས་སྟོབས་འཕེལ་རྒྱས་བརྟག་ཞིབ་དང་སྔོན་དཔྱད',
134 137
     pickModel: 'དཔེ་གཞི་འདེམས'
135 138
   },
136 139
   messagePage: {

+ 3 - 0
ruoyi-ui-app/locale/zh.js

@@ -126,6 +126,9 @@ export default {
126 126
     modelFeeding: '饲喂决策助手',
127 127
     modelFeedingShort: '饲喂',
128 128
     modelFeedingDesc: '饲喂方案与营养决策',
129
+    modelGrowth: '养殖生长助手',
130
+    modelGrowthShort: '生长',
131
+    modelGrowthDesc: '牦牛生长发育监测与预测',
129 132
     pickModel: '选择模型'
130 133
   },
131 134
   messagePage: {

+ 2 - 1
ruoyi-ui-app/utils/aiLlmChat.js

@@ -7,7 +7,8 @@ export const MODEL_OPTION_DEFS = [
7 7
   { value: 'auto', labelKey: 'modelAuto', shortKey: 'modelAutoShort', descKey: 'modelAutoDesc', icon: 'grid-fill' },
8 8
   { value: 'yak-disease', labelKey: 'modelDisease', shortKey: 'modelDiseaseShort', descKey: 'modelDiseaseDesc', icon: 'order' },
9 9
   { value: 'yak-general', labelKey: 'modelGeneral', shortKey: 'modelGeneralShort', descKey: 'modelGeneralDesc', icon: 'chat' },
10
-  { value: 'yak-feeding', labelKey: 'modelFeeding', shortKey: 'modelFeedingShort', descKey: 'modelFeedingDesc', icon: 'shopping-cart' }
10
+  { value: 'yak-feeding', labelKey: 'modelFeeding', shortKey: 'modelFeedingShort', descKey: 'modelFeedingDesc', icon: 'shopping-cart' },
11
+  { value: 'yak-growth', labelKey: 'modelGrowth', shortKey: 'modelGrowthShort', descKey: 'modelGrowthDesc', icon: 'chat' }
11 12
 ]
12 13
 
13 14
 export const MEDIA_RULES = {

+ 4 - 1
ruoyi-ui/src/lang/bo/diseaseTreatment.js

@@ -203,7 +203,10 @@ export default {
203 203
     modelGeneralDesc: "སྤྱིར་བཏང་ལན་འདྲི",
204 204
     modelFeeding: "ཟས་ལག་རོགས",
205 205
     modelFeedingShort: "ཟས",
206
-    modelFeedingDesc: "ཟས་སྦྱོར་གཞི་ཀློག"
206
+    modelFeedingDesc: "ཟས་སྦྱོར་གཞི་ཀློག",
207
+    modelGrowth: "འཕེལ་རྒྱས་ལག་རོགས",
208
+    modelGrowthShort: "འཕེལ་རྒྱས",
209
+    modelGrowthDesc: "འབྲོང་སྐྱེས་སྟོབས་འཕེལ་རྒྱས་བརྟག་ཞིབ་དང་སྔོན་དཔྱད"
207 210
   },
208 211
   vetOnlineConsult: {
209 212
     queryAskerName: "བརྟག་དཔྱད་མཁན།",

+ 4 - 1
ruoyi-ui/src/lang/zh/diseaseTreatment.js

@@ -203,7 +203,10 @@ export default {
203 203
     modelGeneralDesc: "日常养殖与综合问答",
204 204
     modelFeeding: "饲喂决策助手",
205 205
     modelFeedingShort: "饲喂",
206
-    modelFeedingDesc: "饲喂方案与营养决策"
206
+    modelFeedingDesc: "饲喂方案与营养决策",
207
+    modelGrowth: "养殖生长助手",
208
+    modelGrowthShort: "生长",
209
+    modelGrowthDesc: "牦牛生长发育监测与预测",
207 210
   },
208 211
   vetOnlineConsult: {
209 212
     queryAskerName: "问诊人",

+ 9 - 2
ruoyi-ui/src/views/diseaseTreatment/onlineConsult/ai/index.vue

@@ -311,7 +311,8 @@ const MODEL_OPTION_DEFS = [
311 311
   { value: "auto", labelKey: "modelAuto", shortKey: "modelAutoShort", descKey: "modelAutoDesc", icon: "el-icon-cpu" },
312 312
   { value: "yak-disease", labelKey: "modelDisease", shortKey: "modelDiseaseShort", descKey: "modelDiseaseDesc", icon: "el-icon-s-flag" },
313 313
   { value: "yak-general", labelKey: "modelGeneral", shortKey: "modelGeneralShort", descKey: "modelGeneralDesc", icon: "el-icon-chat-dot-round" },
314
-  { value: "yak-feeding", labelKey: "modelFeeding", shortKey: "modelFeedingShort", descKey: "modelFeedingDesc", icon: "el-icon-s-goods" }
314
+  { value: "yak-feeding", labelKey: "modelFeeding", shortKey: "modelFeedingShort", descKey: "modelFeedingDesc", icon: "el-icon-s-goods" },
315
+  { value: "yak-growth", labelKey: "modelGrowth", shortKey: "modelGrowth", descKey: "modelGrowthDesc", icon: "el-icon-s-flag" },
315 316
 ]
316 317
 
317 318
 
@@ -1542,24 +1543,30 @@ export default {
1542 1543
 }
1543 1544
 
1544 1545
 .chat-bubble {
1545
-  max-width: 72%;
1546
+  box-sizing: border-box;
1546 1547
   padding: 8px 12px;
1547 1548
   border-radius: 10px;
1548 1549
   font-size: 14px;
1549 1550
   line-height: 1.5;
1550 1551
 
1551 1552
   &.is-ai {
1553
+    width: 680px;
1554
+    max-width: calc(100% - 46px);
1552 1555
     background: #e8f4ff;
1553 1556
     color: #1d3a5c;
1554 1557
     border: 1px solid #b3d8ff;
1555 1558
   }
1556 1559
 
1557 1560
   &.is-user {
1561
+    width: 360px;
1562
+    max-width: calc(100% - 46px);
1558 1563
     background: #52c41a;
1559 1564
     color: #fff;
1560 1565
   }
1561 1566
 
1562 1567
   &.chat-bubble--thinking {
1568
+    width: auto;
1569
+    max-width: none;
1563 1570
     min-width: 72px;
1564 1571
     min-height: 40px;
1565 1572
     display: flex;

+ 1 - 1
ruoyi-ui/vue.config.js

@@ -9,7 +9,7 @@ const CompressionPlugin = require('compression-webpack-plugin')
9 9
 
10 10
 const name = process.env.VUE_APP_TITLE || '巴青管理系统' // 网页标题
11 11
 
12
-const baseUrl = 'http://192.168.1.10:8010' // 后端接口
12
+const baseUrl = 'http://192.168.1.6:8010' // 后端接口
13 13
 
14 14
 const port = process.env.port || process.env.npm_config_port || 80 // 端口
15 15