|
@@ -18,33 +18,33 @@
|
|
|
正在识别,请稍后...
|
|
正在识别,请稍后...
|
|
|
</div>
|
|
</div>
|
|
|
<img class="card-bg" :src="displayUrls[index]" />
|
|
<img class="card-bg" :src="displayUrls[index]" />
|
|
|
- <div class="card-content" v-if="!isRecognize && resultsByIndex[index]?.status === 'ok'">
|
|
|
|
|
|
|
+ <div class="card-content" v-if="!isRecognize">
|
|
|
<div class="title-ques">
|
|
<div class="title-ques">
|
|
|
- <div class="ques-text">病虫名称:{{ resultsByIndex[index]?.data?.name }}</div>
|
|
|
|
|
|
|
+ <div class="ques-text">病虫名称:{{ recognizeResult[index]?.diseaseName }}</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="dialog-famous">管理方法:</div>
|
|
<div class="dialog-famous">管理方法:</div>
|
|
|
<div class="dialog-answer">
|
|
<div class="dialog-answer">
|
|
|
- {{ resultsByIndex[index]?.data?.cure }}
|
|
|
|
|
|
|
+ {{ recognizeResult[index]?.managementMethod }}
|
|
|
</div>
|
|
</div>
|
|
|
- <div v-if="resultsByIndex[index]?.data?.info" class="advice-wrap">
|
|
|
|
|
|
|
+ <div v-if="recognizeResult[index]?.basicInfo" class="advice-wrap">
|
|
|
<div class="item-tag">基本信息</div>
|
|
<div class="item-tag">基本信息</div>
|
|
|
- <div v-html="resultsByIndex[index]?.data?.info"></div>
|
|
|
|
|
|
|
+ <div v-html="recognizeResult[index]?.basicInfo"></div>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="famous-info" @click="toDetail(index)">
|
|
|
|
|
|
|
+ <!-- <div class="famous-info" @click="toDetail(index)">
|
|
|
<img src="@/assets/img/home/link-icon.png" />
|
|
<img src="@/assets/img/home/link-icon.png" />
|
|
|
<span>点击查看农事详情</span>
|
|
<span>点击查看农事详情</span>
|
|
|
- </div>
|
|
|
|
|
|
|
+ </div> -->
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="card-content no-data" v-if="!isRecognize && resultsByIndex[index]?.status === 'nodata'">
|
|
|
|
|
|
|
+ <!-- <div class="card-content no-data" v-if="!isRecognize && recognizeResult[index]?.status === 'nodata'">
|
|
|
<img src="@/assets/img/home/good-fill.png" />
|
|
<img src="@/assets/img/home/good-fill.png" />
|
|
|
长势良好,并未发现病虫害
|
|
长势良好,并未发现病虫害
|
|
|
- </div>
|
|
|
|
|
|
|
+ </div> -->
|
|
|
</div>
|
|
</div>
|
|
|
</SwipeItem>
|
|
</SwipeItem>
|
|
|
</Swipe>
|
|
</Swipe>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="btn-wrap" v-if="!isRecognize">
|
|
<div class="btn-wrap" v-if="!isRecognize">
|
|
|
- <div class="btn primary" @click="goBack">咨询专家</div>
|
|
|
|
|
|
|
+ <div class="btn share" @click="toConsult">咨询专家</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -60,134 +60,37 @@ import { Swipe, SwipeItem } from "vant";
|
|
|
import { useRouter, useRoute } from "vue-router";
|
|
import { useRouter, useRoute } from "vue-router";
|
|
|
import { base_img_url2 } from "@/api/config.js";
|
|
import { base_img_url2 } from "@/api/config.js";
|
|
|
import { ElMessage } from "element-plus";
|
|
import { ElMessage } from "element-plus";
|
|
|
-import MqttClient from "@/mqtt/MqttClient";
|
|
|
|
|
import detailDialog from "@/components/detailDialog.vue";
|
|
import detailDialog from "@/components/detailDialog.vue";
|
|
|
import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
|
|
import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
|
|
|
|
|
+import { toRaw } from 'vue'
|
|
|
|
|
|
|
|
let resize = "?x-oss-process=image/resize,w_300";
|
|
let resize = "?x-oss-process=image/resize,w_300";
|
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
|
-const json = JSON.parse(route.query.json || "{}");
|
|
|
|
|
|
|
+const miniJson = toRaw(route.query.miniJson);
|
|
|
|
|
+const json = JSON.parse(miniJson || "{}");
|
|
|
// const json = JSON.parse(
|
|
// const json = JSON.parse(
|
|
|
// `{"imgKey":["birdseye-look-mini/766/1761968109259.png","birdseye-look-mini/766/1761968110225.png"],"farmId":766,"id":"65","imageIds":["772470289337421824","772470289337421825"],"token":"bcc0e12d-bff6-4f1f-8edc-2ab80b19af41"}`)
|
|
// `{"imgKey":["birdseye-look-mini/766/1761968109259.png","birdseye-look-mini/766/1761968110225.png"],"farmId":766,"id":"65","imageIds":["772470289337421824","772470289337421825"],"token":"bcc0e12d-bff6-4f1f-8edc-2ab80b19af41"}`)
|
|
|
-const imgKey = json.imgKey;
|
|
|
|
|
-const farmId = json.farmId;
|
|
|
|
|
-const imageIds = json.imageIds || [];
|
|
|
|
|
|
|
+const imgKey = json.imgKey?.split(",") || [];
|
|
|
|
|
|
|
|
const isRecognize = ref(true);
|
|
const isRecognize = ref(true);
|
|
|
-const noData = ref(false);
|
|
|
|
|
-const resultsByIndex = ref({});
|
|
|
|
|
|
|
|
|
|
// 存储每张图片的 farmWorkLibId,用于后续接口请求
|
|
// 存储每张图片的 farmWorkLibId,用于后续接口请求
|
|
|
const farmWorkLibIdsByIndex = ref({});
|
|
const farmWorkLibIdsByIndex = ref({});
|
|
|
|
|
|
|
|
// 预置显示地址:默认使用传入的 cloudFilename
|
|
// 预置显示地址:默认使用传入的 cloudFilename
|
|
|
-const displayUrls = ref(imgKey.map((p) => base_img_url2 + p + resize));
|
|
|
|
|
|
|
+const displayUrls = imgKey.map((p) => base_img_url2 + p + resize);
|
|
|
const detailDialogRef = ref(null);
|
|
const detailDialogRef = ref(null);
|
|
|
|
|
+
|
|
|
|
|
+const recognizeResult = ref([]);
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
- const mqttClient = new MqttClient(["farm/pest_recognition/task/" + farmId], mqttListener);
|
|
|
|
|
- mqttClient.connect();
|
|
|
|
|
|
|
+ VE_API.ali.AIRecognize({
|
|
|
|
|
+ imageUrls: displayUrls,
|
|
|
|
|
+ }).then(({data}) => {
|
|
|
|
|
+ recognizeResult.value = data;
|
|
|
|
|
+ isRecognize.value = false;
|
|
|
|
|
+ });
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const mqttListener = (topic, message) => {
|
|
|
|
|
- let resData = JSON.parse(message);
|
|
|
|
|
- if (json.id == resData.taskId) {
|
|
|
|
|
- if (resData.status === 1) {
|
|
|
|
|
- const resultMap = resData.result || {};
|
|
|
|
|
- // 初始化每张图片的结果状态
|
|
|
|
|
- const fetchPromises = [];
|
|
|
|
|
- imageIds.forEach((imgId, index) => {
|
|
|
|
|
- const resultData = resultMap[imgId];
|
|
|
|
|
- // 新数据结构:可能是 null 或数组,数组中的对象包含 farmWorkLibId 和 pestDiseaseId
|
|
|
|
|
- if (Array.isArray(resultData) && resultData.length > 0) {
|
|
|
|
|
- // 提取 pestDiseaseId 和 farmWorkLibId
|
|
|
|
|
- const pestDiseaseIds = [];
|
|
|
|
|
- const farmWorkLibIdList = [];
|
|
|
|
|
-
|
|
|
|
|
- resultData.forEach((item) => {
|
|
|
|
|
- if (item && item.pestDiseaseId) {
|
|
|
|
|
- pestDiseaseIds.push(item.pestDiseaseId);
|
|
|
|
|
- }
|
|
|
|
|
- if (item && item.farmWorkLibId) {
|
|
|
|
|
- farmWorkLibIdList.push(item.farmWorkLibId);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 按索引保存 farmWorkLibId 数组
|
|
|
|
|
- if (farmWorkLibIdList.length > 0) {
|
|
|
|
|
- farmWorkLibIdsByIndex.value[index] = farmWorkLibIdList;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 使用 pestDiseaseId 调用病虫详情接口
|
|
|
|
|
- if (pestDiseaseIds.length > 0) {
|
|
|
|
|
- const p = VE_API.home.fetchDiseaseDetail(pestDiseaseIds).then(({ data, code: respCode }) => {
|
|
|
|
|
- if (respCode === 0) {
|
|
|
|
|
- const detail = Array.isArray(data) ? data[0] : data;
|
|
|
|
|
- resultsByIndex.value = {
|
|
|
|
|
- ...resultsByIndex.value,
|
|
|
|
|
- [index]: { status: 'ok', data: detail }
|
|
|
|
|
- };
|
|
|
|
|
- } else {
|
|
|
|
|
- resultsByIndex.value = {
|
|
|
|
|
- ...resultsByIndex.value,
|
|
|
|
|
- [index]: { status: 'nodata' }
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
- }).catch(() => {
|
|
|
|
|
- resultsByIndex.value = {
|
|
|
|
|
- ...resultsByIndex.value,
|
|
|
|
|
- [index]: { status: 'nodata' }
|
|
|
|
|
- };
|
|
|
|
|
- });
|
|
|
|
|
- fetchPromises.push(p);
|
|
|
|
|
- } else {
|
|
|
|
|
- // 没有 pestDiseaseId,但有 farmWorkLibId,可能只有农事信息
|
|
|
|
|
- resultsByIndex.value = {
|
|
|
|
|
- ...resultsByIndex.value,
|
|
|
|
|
- [index]: { status: 'nodata' }
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- // 结果为 null 或空数组
|
|
|
|
|
- resultsByIndex.value = {
|
|
|
|
|
- ...resultsByIndex.value,
|
|
|
|
|
- [index]: { status: 'nodata' }
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- VE_API.farm.listByIds(resData.imageIds).then(({ data, code: respCode }) => {
|
|
|
|
|
- if (respCode === 0) {
|
|
|
|
|
- // 按 imageIds 顺序,为每张图优先选择 cloudResFilename,否则 cloudFilename
|
|
|
|
|
- const idToRecord = {};
|
|
|
|
|
- (data || []).forEach((item) => {
|
|
|
|
|
- if (item && item.id) idToRecord[item.id] = item;
|
|
|
|
|
- });
|
|
|
|
|
- const urls = [...displayUrls.value];
|
|
|
|
|
- imageIds.forEach((id, idx) => {
|
|
|
|
|
- const rec = idToRecord[id];
|
|
|
|
|
- if (rec) {
|
|
|
|
|
- const path = (rec.cloudResFilename && rec.cloudResFilename.trim() !== '')
|
|
|
|
|
- ? rec.cloudResFilename
|
|
|
|
|
- : (rec.cloudFilename || imgKey[idx]);
|
|
|
|
|
- urls[idx] = base_img_url2 + path + resize;
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- displayUrls.value = urls;
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- if (fetchPromises.length > 0) {
|
|
|
|
|
- Promise.allSettled(fetchPromises).finally(() => {
|
|
|
|
|
- isRecognize.value = false;
|
|
|
|
|
- });
|
|
|
|
|
- } else {
|
|
|
|
|
- // 全部无病虫
|
|
|
|
|
- noData.value = true;
|
|
|
|
|
- isRecognize.value = false;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
|
|
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
|
const goBack = () => {
|
|
const goBack = () => {
|
|
@@ -209,6 +112,25 @@ const toDetail = (index) => {
|
|
|
ElMessage.warning('暂无农事详情');
|
|
ElMessage.warning('暂无农事详情');
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+const currentFarmId = localStorage.getItem('selectedFarmId')
|
|
|
|
|
+const toConsult = async () => {
|
|
|
|
|
+ const userId = await getNearStore();
|
|
|
|
|
+ console.log("userId", userId);``
|
|
|
|
|
+ router.push(`/chat_frame?userId=${userId}&farmId=${currentFarmId}`);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+async function getNearStore() {
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ point: localStorage.getItem('MINI_USER_LOCATION_POINT'),
|
|
|
|
|
+ page: 1,
|
|
|
|
|
+ limit: 1,
|
|
|
|
|
+ };
|
|
|
|
|
+ const res = await VE_API.farm.getStoreList(params);
|
|
|
|
|
+ if(res.data.length > 0){
|
|
|
|
|
+ return res.data[0].miniUserIds[0];
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
@@ -404,11 +326,14 @@ const toDetail = (index) => {
|
|
|
background: #2199f8;
|
|
background: #2199f8;
|
|
|
}
|
|
}
|
|
|
&.share {
|
|
&.share {
|
|
|
|
|
+ flex: 1;
|
|
|
background: #fff;
|
|
background: #fff;
|
|
|
- width: 20%;
|
|
|
|
|
|
|
+ // width: 20%;
|
|
|
min-width: 80px;
|
|
min-width: 80px;
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
- border: 1px solid #8e8e8e;
|
|
|
|
|
|
|
+ border: 1px solid #8E8E8E;
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ border-radius: 20px;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
.btn + .btn {
|
|
.btn + .btn {
|