problemReminder.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <template>
  2. <Popup v-model:show="show" class="problem-reminder-popup">
  3. <div class="problem-reminder">
  4. <!-- 标题区域 -->
  5. <div class="problem-reminder-header">
  6. <div class="title-section">
  7. <div class="main-title">填写以下问题</div>
  8. <div class="sub-title">为您定制农事提醒</div>
  9. </div>
  10. <img class="header-icon" src="@/assets/img/home/file-icon.png" alt="" />
  11. </div>
  12. <div class="question-section-wrapper">
  13. <div class="question-text">请问 <span style="color: #2199f8;">{{ farmName }}</span> {{ questPopupData.quest }}</div>
  14. <div class="img">
  15. <img :src="questPopupData.backgroundImage" alt="" />
  16. </div>
  17. <div class="options-section">
  18. <span class="options-label">您可以选择</span>
  19. <div class="options-buttons">
  20. <div class="option-btn" @click="toUpload">拍照识别</div>
  21. <div class="option-btn" @click="toPage" v-if="curRole == 0">咨询专家</div>
  22. </div>
  23. </div>
  24. </div>
  25. <!-- 底部按钮区域 -->
  26. <div class="bottom-buttons">
  27. <div
  28. v-for="(opt, idx) in bottomAnswerOptions"
  29. :key="idx"
  30. class="bottom-btn"
  31. :class="{ 'yes-btn': isYesOption(opt), 'no-btn': !isYesOption(opt) }"
  32. @click="onBottomOptionClick(opt)"
  33. >
  34. {{ getOptionLabel(opt) }}
  35. </div>
  36. </div>
  37. <!-- <div class="forward-btn bottom-btn" v-if="curRole == 2" @click="handleForward">转发给客户</div> -->
  38. </div>
  39. </Popup>
  40. <Popup v-model:show="noShow" class="no-popup">
  41. <div class="no-popup-title">
  42. <span>感谢您的配合</span>
  43. <div class="no-popup-title-sub">飞鸟将会记录下您当前的农场情况</div>
  44. </div>
  45. <div class="no-popup-btn" @click="noShow = false">我知道了</div>
  46. </Popup>
  47. <!-- 农事信息弹窗 -->
  48. <detail-dialog ref="detailDialogRef" showSuccessOnly @triggerFarmWork="triggerFarmWork" @noPopupBtn="noPopupBtn"></detail-dialog>
  49. <!-- 新增:激活上传弹窗 -->
  50. <active-upload-popup ref="activeUploadPopupRef" @handleUploadSuccess="handleUploadSuccess"></active-upload-popup>
  51. </template>
  52. <script setup>
  53. import { Popup } from "vant";
  54. import { ref,onActivated } from "vue";
  55. import wx from "weixin-js-sdk";
  56. import { base_img_url2 } from "@/api/config";
  57. import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
  58. import detailDialog from "@/components/detailDialog.vue";
  59. import eventBus from "@/api/eventBus";
  60. import { useRouter } from "vue-router";
  61. import { ElMessage } from "element-plus";
  62. const router = useRouter();
  63. const show = ref(false);
  64. const noShow = ref(false);
  65. const dropdownGardenItem = ref({
  66. organId: 93490,
  67. periodId: 1,
  68. wktVal: "wktVal",
  69. address: "address",
  70. district: "district",
  71. name: "荔博园",
  72. });
  73. const toUpload = () => {
  74. if(curRole == 0){
  75. wx.miniProgram.navigateTo({
  76. url: `/pages/subPages/carmera/index?gardenData=${JSON.stringify(dropdownGardenItem.value)}`,
  77. });
  78. }else{
  79. ElMessage.warning("该功能正在升级中,敬请期待");
  80. }
  81. };
  82. function toPage() {
  83. const expertId = sessionStorage.getItem('expertId');
  84. if(expertId){
  85. router.push(`/chat_frame?userId=${expertId}`);
  86. }else{
  87. ElMessage.warning("专家信息不存在,请联系管理员");
  88. }
  89. }
  90. const detailDialogRef = ref(null);
  91. const curRole = localStorage.getItem("SET_USER_CUR_ROLE");
  92. const farmName = ref('');
  93. const farmIdVal = ref(null);
  94. onActivated(() => {
  95. if(curRole == 0){
  96. if(localStorage.getItem('selectedFarmId')){
  97. farmIdVal.value = localStorage.getItem('selectedFarmId');
  98. fetchQuestPopup();
  99. }
  100. }else{
  101. fetchQuestPopup();
  102. }
  103. });
  104. const questPopupData = ref({});
  105. const bottomAnswerOptions = ref([]);
  106. //弹出问卷接口
  107. const fetchQuestPopup = () => {
  108. const api = curRole == 0 ? VE_API.home.fetchQuestPopup({ farmId: farmIdVal.value }) : VE_API.home.popupByAgriculturalUserFarms();
  109. api.then(({ data }) => {
  110. if (Array.isArray(data) && data.length > 0) {
  111. show.value = true;
  112. farmName.value = data[0].farm?.name;
  113. farmIdVal.value = data[0].farm?.id;
  114. questPopupData.value = data[0];
  115. bottomAnswerOptions.value = transformAnswerOptions(questPopupData.value?.answerOptions);
  116. }
  117. })
  118. .catch(() => {});
  119. };
  120. function transformAnswerOptions(raw) {
  121. let parsed = raw;
  122. if (typeof raw === "string") {
  123. try {
  124. parsed = JSON.parse(raw);
  125. } catch (e) {
  126. parsed = [raw];
  127. }
  128. }
  129. if (Array.isArray(parsed)) {
  130. return parsed.map((item) => {
  131. if (item && typeof item === "object") {
  132. const label = item.name;
  133. const value = item.value;
  134. return { label, value };
  135. }
  136. return { label: String(item), value: item };
  137. });
  138. }
  139. return [];
  140. }
  141. function getOptionLabel(opt) {
  142. return opt?.label ?? String(opt ?? "");
  143. }
  144. function isYesOption(opt) {
  145. const label = (opt?.label ?? "").toString();
  146. const value = opt?.value;
  147. if (typeof value === "boolean") return value === true;
  148. if (typeof value === "number") return value === 1;
  149. if (typeof value === "string") {
  150. const v = value.trim().toLowerCase();
  151. if (v === "1" || v === "true" || v === "yes") return true;
  152. }
  153. const yesKeywords = ["是", "yes", "确认", "同意", "有", "发生"];
  154. return yesKeywords.some((k) => label.toLowerCase().includes(k.toLowerCase()));
  155. }
  156. const optValue = ref(null);
  157. function onBottomOptionClick(opt) {
  158. show.value = false;
  159. optValue.value = opt.value;
  160. if (opt.value == 1) {
  161. eventBus.emit("activeUpload:show", {
  162. gardenIdVal: farmIdVal.value,
  163. arrangeIdVal: questPopupData.value.arrangeId,
  164. problemTitleVal: `请选择您出现${questPopupData.value.phenologyName}的时间`,
  165. typeVal: "question",
  166. });
  167. } else {
  168. saveQuestPopup(opt.label);
  169. }
  170. }
  171. function saveQuestPopup(label) {
  172. const agriDate = getTodayStr();
  173. const params = {
  174. farmId: farmIdVal.value,
  175. phenologyId: questPopupData.value.phenologyId,
  176. indicatorId: questPopupData.value.indicatorId,
  177. answerValue: optValue.value,
  178. agriDate: agriDate,
  179. };
  180. params.imagePaths = images.value;
  181. VE_API.home.saveQuestPopup(params).then((res) => {
  182. if (res.code === 0) {
  183. show.value = false;
  184. if (optValue.value != 1 && label != '未知') {
  185. noShow.value = true;
  186. }
  187. }
  188. });
  189. }
  190. function getTodayStr() {
  191. const d = new Date();
  192. const y = d.getFullYear();
  193. const m = String(d.getMonth() + 1).padStart(2, "0");
  194. const day = String(d.getDate()).padStart(2, "0");
  195. return `${y}-${m}-${day}`;
  196. }
  197. const images = ref([]);
  198. const currentParams = ref({});
  199. function handleUploadSuccess(params) {
  200. currentParams.value = params;
  201. images.value = params.imagePaths;
  202. detailDialogRef.value.showDialog(questPopupData.value.farmWorkLibId, "转发");
  203. }
  204. const activeUploadPopupRef = ref(null);
  205. function triggerFarmWork() {
  206. activeUploadPopupRef.value.triggerFarmWork(currentParams.value);
  207. saveQuestPopup();
  208. }
  209. // 获取触发图片
  210. const triggerImg = ref([]);
  211. const getTriggerImg = async () => {
  212. const { data } = await VE_API.z_farm_work_record.getTriggerImg({ farmWorkRecordId: questPopupData.value.id });
  213. triggerImg.value = data || [];
  214. }
  215. const noPopupBtn = async () => {
  216. // await getTriggerImg();
  217. // const query = {
  218. // askInfo: { title: "分享农事", content: "是否分享该农事给好友" },
  219. // shareText: `您的农事要做${questPopupData.value.farm}了 请查看!`,
  220. // id: questPopupData.value?.farmWorkLibId,
  221. // farmWorkOrderId: questPopupData.value?.farm?.orderId,
  222. // postImg: triggerImg.value.length ? base_img_url2 + triggerImg.value[triggerImg.value.length - 1].cloudFilename : ''
  223. // };
  224. // wx.miniProgram.navigateTo({
  225. // url: `/pages/subPages/share_page/index?pageParams=${JSON.stringify(query)}&type=priceSheet`,
  226. // });
  227. };
  228. const handleForward = () => {
  229. // noPopupBtn();
  230. };
  231. </script>
  232. <style lang="scss" scoped>
  233. .problem-reminder-popup {
  234. width: 100%;
  235. border-radius: 14px;
  236. padding: 20px 15px;
  237. box-sizing: border-box;
  238. background-image: linear-gradient(180deg, #d1e7fd 0%, #ffffff 25%);
  239. .problem-reminder {
  240. display: flex;
  241. flex-direction: column;
  242. // 标题区域样式
  243. .problem-reminder-header {
  244. display: flex;
  245. justify-content: space-between;
  246. align-items: flex-start;
  247. gap: 15px;
  248. .title-section {
  249. flex: 1;
  250. font-size: 22px;
  251. color: #1d1e1f;
  252. line-height: 1.2;
  253. div {
  254. font-family: "PangMenZhengDao";
  255. }
  256. }
  257. .header-icon {
  258. width: 88px;
  259. height: 88px;
  260. margin-top: -10px;
  261. margin-right: -5px;
  262. }
  263. }
  264. .question-section-wrapper {
  265. border: 1px solid #ececec;
  266. border-radius: 8px;
  267. padding: 10px 8px;
  268. margin-top: -10px;
  269. background-color: #fff;
  270. .question-text {
  271. font-size: 16px;
  272. color: #252525;
  273. font-weight: 500;
  274. }
  275. .img {
  276. margin: 12px 0;
  277. width: 100%;
  278. height: 140px;
  279. img {
  280. width: 100%;
  281. height: 100%;
  282. border-radius: 6px;
  283. object-fit: cover;
  284. }
  285. }
  286. .options-section {
  287. display: flex;
  288. align-items: center;
  289. justify-content: space-between;
  290. background-color: rgba(33, 153, 248, 0.1);
  291. border-radius: 8px;
  292. padding: 7px 8px;
  293. font-weight: 500;
  294. .options-label {
  295. font-size: 14px;
  296. color: #2199f8;
  297. }
  298. .options-buttons {
  299. display: flex;
  300. flex-wrap: wrap;
  301. gap: 10px;
  302. .option-btn {
  303. padding: 5px 14px;
  304. border-radius: 20px;
  305. background: #fff;
  306. color: #252525;
  307. flex: 1;
  308. }
  309. }
  310. }
  311. }
  312. // 底部按钮区域样式
  313. .bottom-buttons {
  314. display: flex;
  315. gap: 12px;
  316. margin-top: 10px;
  317. }
  318. .forward-btn{
  319. margin-top: 10px;
  320. }
  321. .bottom-btn {
  322. flex: 1;
  323. padding: 8px 0;
  324. border-radius: 25px;
  325. font-size: 16px;
  326. text-align: center;
  327. background: #fff;
  328. border: 1px solid #e5e5e5;
  329. &.yes-btn {
  330. background-image: linear-gradient(180deg, #76c3ff 0%, #2199f8 100%);
  331. color: #fff;
  332. border: none;
  333. }
  334. }
  335. }
  336. }
  337. .no-popup {
  338. width: 76%;
  339. border-radius: 14px;
  340. padding: 28px 15px 20px;
  341. box-sizing: border-box;
  342. .no-popup-title {
  343. font-size: 24px;
  344. font-weight: 500;
  345. text-align: center;
  346. .no-popup-title-sub {
  347. font-size: 16px;
  348. margin-top: 8px;
  349. }
  350. }
  351. .no-popup-btn {
  352. background-color: #2199f8;
  353. padding: 8px;
  354. border-radius: 20px;
  355. color: #fff;
  356. font-size: 16px;
  357. margin-top: 32px;
  358. text-align: center;
  359. }
  360. }
  361. </style>