index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. <template>
  2. <div class="mine-index">
  3. <div class="mine-header">
  4. <div class="user-info-box" @click="handleUserInfoClick">
  5. <el-avatar class="avatar" :size="54" :src="userInfo?.icon" />
  6. <div class="user-info">
  7. <div class="user-name">
  8. <span v-if="curRole === 0">{{ userInfo?.nickname }}</span>
  9. <span v-else>{{ userInfo?.name }}</span>
  10. <span class="score" v-if="curRole !== 0">5.0分</span>
  11. </div>
  12. <div class="user-day">这是您使用飞鸟管家的第{{ daysSinceCreation }}天</div>
  13. </div>
  14. </div>
  15. <div class="code-icon" v-if="curRole === 1">
  16. <img src="@/assets/img/mine/code-icon.png" alt="" />
  17. </div>
  18. <!-- <div class="switch-role-btn" v-if="roles && roles.length > 1" @click="changeToggle">
  19. <span>切换身份</span>
  20. <el-icon><Switch /></el-icon>
  21. </div> -->
  22. </div>
  23. <div class="mine-content">
  24. <div class="garden-info" v-if="curRole !== 0">
  25. <div class="item" v-for="(item, index) in gardenInfoItems" :key="index">
  26. <span class="num">{{ item.num }}</span>
  27. <span>{{ item.label }}</span>
  28. </div>
  29. </div>
  30. <!-- <div class="grid-group">
  31. <div class="grid-item" v-for="(item, index) in gridItems" :key="index" @click="handleGridClick(item)">
  32. <div class="grid-title">
  33. <span>{{ item.title }}</span>
  34. <el-icon><ArrowRight /></el-icon>
  35. </div>
  36. <span class="grid-desc">{{ item.desc }}</span>
  37. </div>
  38. </div> -->
  39. <div class="cell-group">
  40. <div class="cell-item" v-for="(item, index) in cellItems" :key="index" @click="handleCellClick(item)">
  41. <span class="item-title">{{ item.title }}</span>
  42. <el-icon class="item-arrow"><ArrowRight /></el-icon>
  43. </div>
  44. </div>
  45. </div>
  46. <!-- 角色切换 -->
  47. <action-sheet :style="{ bottom: 50 + 'px' }" v-model:show="show" :actions="actions" @select="onSelect" />
  48. <!-- 问题提醒 -->
  49. <tip-popup
  50. v-model:show="showTipPopup"
  51. type="warning"
  52. text="请设置"
  53. highlightText="种植方案"
  54. buttonText="去设置"
  55. @confirm="handleBtn"
  56. :closeOnClickOverlay="false"
  57. />
  58. </div>
  59. </template>
  60. <script setup>
  61. import { onActivated, ref, computed, onMounted } from "vue";
  62. import { useRouter } from "vue-router";
  63. import { useStore } from "vuex";
  64. import wx from "weixin-js-sdk";
  65. import { ActionSheet } from "vant";
  66. import { SET_USER_CUR_ROLE } from "@/store/modules/app/type";
  67. import tipPopup from "@/components/popup/tipPopup.vue";
  68. const store = useStore();
  69. const router = useRouter();
  70. const showTipPopup = ref(false);
  71. const handleBtn = () => {
  72. router.push("/plan?pageType=plant&headerTitle=请设置您的种植方案");
  73. };
  74. // 0: 农户, 1: 专家, 2:农资农服
  75. const curRole = ref(Number(localStorage.getItem("SET_USER_CUR_ROLE")));
  76. const roles = ref(JSON.parse(store.state.app.roles));
  77. const userInfo = JSON.parse(localStorage.getItem("localUserInfo") || "{}");
  78. // 计算从创建时间到现在经过的天数
  79. const daysSinceCreation = computed(() => {
  80. if (!userInfo?.createTime) {
  81. return 0;
  82. }
  83. try {
  84. // 将创建时间字符串转换为日期对象
  85. const createDate = new Date(userInfo.createTime);
  86. // 获取当前日期
  87. const currentDate = new Date();
  88. // 将两个日期都设置为当天的 00:00:00,只比较日期部分
  89. const createDateOnly = new Date(createDate.getFullYear(), createDate.getMonth(), createDate.getDate());
  90. const currentDateOnly = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
  91. // 计算日期差(毫秒)
  92. const timeDiff = currentDateOnly.getTime() - createDateOnly.getTime();
  93. // 转换为天数
  94. const days = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
  95. // 加1,因为创建当天算作第1天
  96. return days + 1;
  97. } catch (error) {
  98. console.error("计算天数失败:", error);
  99. return 0;
  100. }
  101. });
  102. // const roles = ref([0,1,2,3])
  103. const actions = ref([]);
  104. // 网格项数据
  105. const gridItems = ref([]);
  106. const objects = [
  107. { name: "农户", id: 0, text: "NH" },
  108. { name: "农资", id: 2, text: "NZ" },
  109. ];
  110. onMounted(() => {
  111. // 仅保留 objects 中存在的角色
  112. actions.value = objects.filter((obj) => roles.value && roles.value.includes(obj.id));
  113. });
  114. const show = ref(false);
  115. // 切换身份角色
  116. const onSelect = async (item) => {
  117. show.value = false;
  118. store.dispatch(`app/${SET_USER_CUR_ROLE}`, item.id);
  119. localStorage.setItem("SET_USER_CUR_ROLE", item.id);
  120. // 保存到 session
  121. try {
  122. await VE_API.mine.saveSessionStore({
  123. val: item.id,
  124. key: "cur_role",
  125. });
  126. } catch (error) {
  127. console.error("保存角色到 session 失败:", error);
  128. }
  129. window.location.reload();
  130. };
  131. onActivated(() => {
  132. // if (curRole.value === 0) {
  133. // gridItems.value = [
  134. // {
  135. // title: "我的农场",
  136. // desc: "查看农场列表",
  137. // path: "/my_farm",
  138. // },
  139. // {
  140. // title: "我的消息",
  141. // desc: "查看未读信息",
  142. // path: "/message",
  143. // },
  144. // {
  145. // title: "农事记录",
  146. // desc: "查看历史农事",
  147. // path: "/farm_records",
  148. // },
  149. // ];
  150. // } else if (curRole.value === 1) {
  151. // gridItems.value = [
  152. // {
  153. // title: "我的主页",
  154. // desc: "查看农场列表",
  155. // path: "/expert_detail",
  156. // },
  157. // {
  158. // title: "我的报价",
  159. // desc: "查看未读信息",
  160. // path: "/message",
  161. // },
  162. // {
  163. // title: "信息化档案",
  164. // desc: "查看历史农事",
  165. // path: "/archives",
  166. // },
  167. // ];
  168. // } else if (curRole.value === 2) {
  169. // gridItems.value = [
  170. // {
  171. // title: "我的主页",
  172. // desc: "查看农场列表",
  173. // path: "/my_farm",
  174. // },
  175. // {
  176. // title: "我的消息",
  177. // desc: "查看未读信息",
  178. // path: "/message",
  179. // },
  180. // {
  181. // title: "信息化档案",
  182. // desc: "查看历史农事",
  183. // path: "/archives",
  184. // },
  185. // ];
  186. // }
  187. gridItems.value = [
  188. {
  189. title: "我的主页",
  190. desc: "查看农场列表",
  191. path: "/my_farm",
  192. },
  193. {
  194. title: "我的消息",
  195. desc: "查看未读信息",
  196. path: "/message",
  197. },
  198. {
  199. title: "信息化档案",
  200. desc: "查看历史农事",
  201. path: "/archives",
  202. },
  203. ];
  204. });
  205. // 单元格项数据 - 根据角色动态显示
  206. const cellItems = computed(() => {
  207. // if (curRole.value === 0) {
  208. // return [
  209. // // {
  210. // // title: "我的农场",
  211. // // path: "/my_farm",
  212. // // },
  213. // {
  214. // title: "认证农资",
  215. // path: "/register?identity=NZ",
  216. // },
  217. // // {
  218. // // title: "退出登录",
  219. // // path: "/logout",
  220. // // },
  221. // ];
  222. // } else {
  223. // return [
  224. // {
  225. // title: "认证农资",
  226. // path: "/register?identity=NZ",
  227. // },
  228. // {
  229. // title: "系统提醒",
  230. // path: "/message",
  231. // },
  232. // {
  233. // title: "种植方案",
  234. // path: "/plan?farmId=101532&pageType=plant",
  235. // },
  236. // {
  237. // title: "服务记录",
  238. // path: "/service_records",
  239. // },
  240. // {
  241. // title: "报价维护",
  242. // path: "/offer_price",
  243. // },
  244. // {
  245. // title: "服务维护",
  246. // path: "/service_manage",
  247. // },
  248. // {
  249. // title: "团队管理",
  250. // path: "/team_manage",
  251. // },
  252. // ];
  253. // }
  254. return [
  255. {
  256. title: "认证农资",
  257. path: "/register?identity=NZ",
  258. },
  259. {
  260. title: "系统提醒",
  261. path: "/message",
  262. },
  263. {
  264. title: "种植方案",
  265. path: "/plan?pageType=plant",
  266. },
  267. {
  268. title: "服务记录",
  269. path: "/service_records",
  270. },
  271. {
  272. title: "报价维护",
  273. path: "/offer_price",
  274. },
  275. {
  276. title: "服务维护",
  277. path: "/service_manage",
  278. },
  279. {
  280. title: "团队管理",
  281. path: "/team_manage",
  282. },
  283. ];
  284. });
  285. // 花园信息项数据
  286. const gardenInfoItems = ref([
  287. { num: "--", label: "服务次数" },
  288. { num: "--", label: "累计客户" },
  289. { num: "--", label: "服务果园" },
  290. ]);
  291. onActivated(() => {
  292. if (curRole.value !== 0) {
  293. getStatistics();
  294. }
  295. });
  296. const getStatistics = () => {
  297. VE_API.z_agricultural_store.statistics().then(({ data }) => {
  298. gardenInfoItems.value[0].num = data.serviceCount || "--";
  299. gardenInfoItems.value[1].num = data.customerCount || "--";
  300. gardenInfoItems.value[2].num = data.serviceFarmCount || "--";
  301. });
  302. };
  303. // 处理网格项点击
  304. const handleGridClick = (item) => {
  305. if (item.path) {
  306. router.push(item.path);
  307. }
  308. };
  309. // 处理单元格项点击
  310. const handleCellClick = (item) => {
  311. if (item.path) {
  312. if (item.path === "/logout") {
  313. // 退出登录逻辑
  314. console.log("退出登录");
  315. // 这里可以添加退出登录的具体逻辑
  316. } else {
  317. router.push(item.path);
  318. }
  319. }
  320. };
  321. const changeToggle = () => {
  322. show.value = true;
  323. };
  324. const handleUserInfoClick = () => {
  325. wx.miniProgram.navigateTo({
  326. url: `/pages/subPages/user_info/index?route_path=/mine`,
  327. });
  328. };
  329. </script>
  330. <style lang="scss" scoped>
  331. .mine-index {
  332. width: 100%;
  333. height: 100vh;
  334. box-sizing: border-box;
  335. padding: 20px 16px;
  336. background: url("@/assets/img/mine/mine-bg.png") no-repeat center center / 100% 100%;
  337. .mine-header {
  338. width: 100%;
  339. display: flex;
  340. align-items: center;
  341. justify-content: space-between;
  342. .user-info-box {
  343. display: flex;
  344. align-items: center;
  345. .avatar {
  346. border: 1px solid #fff;
  347. margin-right: 12px;
  348. }
  349. .user-info {
  350. font-size: 20px;
  351. .user-name {
  352. font-weight: 500;
  353. display: flex;
  354. align-items: center;
  355. .score {
  356. font-size: 14px;
  357. color: #2199f8;
  358. margin-left: 6px;
  359. font-weight: 500;
  360. }
  361. }
  362. .user-day {
  363. font-size: 12px;
  364. color: rgba(0, 0, 0, 0.5);
  365. }
  366. }
  367. }
  368. .code-icon {
  369. width: 21px;
  370. height: 21px;
  371. img {
  372. width: 100%;
  373. height: 100%;
  374. }
  375. }
  376. .switch-role-btn {
  377. margin-right: -16px;
  378. display: flex;
  379. align-items: center;
  380. justify-content: center;
  381. padding: 5px 10px 6px 12px;
  382. color: #fff;
  383. background: #2199f8;
  384. border-radius: 25px 0 0 25px;
  385. gap: 5px;
  386. font-size: 13px;
  387. }
  388. }
  389. .mine-content {
  390. margin-top: 20px;
  391. .garden-info {
  392. display: flex;
  393. align-items: center;
  394. justify-content: space-between;
  395. border-radius: 8px;
  396. padding: 6px 0;
  397. background-color: rgba(255, 255, 255, 0.5);
  398. margin-bottom: 10px;
  399. .item {
  400. display: flex;
  401. flex: 1;
  402. flex-direction: column;
  403. align-items: center;
  404. justify-content: center;
  405. color: #999999;
  406. font-size: 13px;
  407. .num {
  408. font-size: 16px;
  409. color: #000;
  410. margin-bottom: 2px;
  411. }
  412. }
  413. }
  414. .grid-group {
  415. display: flex;
  416. align-items: center;
  417. .grid-item {
  418. background-color: #fff;
  419. border-radius: 14px;
  420. padding: 10px 0 10px 10px;
  421. color: #000;
  422. font-size: 16px;
  423. flex: 1;
  424. .grid-title {
  425. display: flex;
  426. align-items: center;
  427. font-weight: 500;
  428. margin-bottom: 6px;
  429. span {
  430. margin-right: 1px;
  431. }
  432. }
  433. .grid-desc {
  434. font-size: 12px;
  435. color: rgba(0, 0, 0, 0.2);
  436. }
  437. }
  438. .grid-item + .grid-item {
  439. margin-left: 10px;
  440. }
  441. }
  442. .cell-group {
  443. .cell-item {
  444. margin-top: 10px;
  445. background-color: #fff;
  446. border-radius: 14px;
  447. padding: 13px 10px;
  448. display: flex;
  449. align-items: center;
  450. justify-content: space-between;
  451. color: #000;
  452. font-size: 16px;
  453. }
  454. }
  455. }
  456. }
  457. </style>