index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. <template>
  2. <u-navbar :autoBack="false" :placeholder="true" :safeAreaInsetTop="true" :bgColor="proxy.$settingStore.themeColor.color">
  3. <template #left>
  4. <view class="u-navbar__content__left__item">
  5. <view class="u-navbar__content__left__item__title">应用中心</view>
  6. </view>
  7. </template>
  8. <template #center>
  9. <view class="u-navbar__content__left__item"> </view>
  10. </template>
  11. <template #right>
  12. <view class="u-navbar__content__left__item">
  13. <text class="iconfont oaIcon-jiahao font20" @click="rightButtonClick()"></text>
  14. </view>
  15. </template>
  16. </u-navbar>
  17. <!-- <u-no-network :zIndex="10080" @disconnected="disconnected" @connected="connected" @retry="retry"></u-no-network> -->
  18. <oa-scroll
  19. customClass="scroll-height"
  20. :customStyle="{ height: `calc(100vh - (104px + ${proxy.$settingStore.StatusBarHeight} + ${proxy.$settingStore.tabBarHeight}))` }"
  21. :refresherLoad="false"
  22. :refresherEnabled="true"
  23. :refresherEnabledTitle="false"
  24. :refresherDefaultStyle="'none'"
  25. :refresherThreshold="44"
  26. :refresherBackground="'#f5f6f7'"
  27. @refresh="refresh"
  28. >
  29. <template #default>
  30. <view class="home-container">
  31. <!-- 右侧弹窗 -->
  32. <u-transition :show="dialogFlag" :duration="200" mode="fade">
  33. <view class="transition" @click="rightButtonClick()">
  34. <view class="transition-section" :style="{ top: `calc(44px + ${proxy.$settingStore.StatusBarHeight})` }">
  35. <view class="transition-section-content" @click="scanCode()">
  36. <text class="transition-section-content-icon iconfont oaIcon-saoyisao"></text>
  37. <view class="transition-section-content-text"> 扫一扫 </view>
  38. </view>
  39. </view>
  40. </view>
  41. </u-transition>
  42. <!-- 轮播图 -->
  43. <u-swiper v-if="state.swiperBool" :list="state.swiperList" :interval="state.swiperTime" indicatorMode="line" radius="0" height="160" indicator circular keyName="url" @click="swiperClick">
  44. </u-swiper>
  45. <image v-if="!state.swiperBool" style="width: 100%; height: 160px" src="@/static/images/index/banner1.png"></image>
  46. <!-- 天气 -->
  47. <!-- #ifdef APP-PLUS || MP-WEIXIN || H5 -->
  48. <oa-weather ref="oaWeatherRef"></oa-weather>
  49. <!-- #endif -->
  50. <!-- 最近使用宫格 -->
  51. <view class="grid-area bg-white" v-if="state.recentlyUsed.length > 0">
  52. <view class="grid-area_title">最近使用</view>
  53. <view class="grid-area_center cu-list grid col-5 no-border">
  54. <view class="grid-area_center_item cu-item justify-center align-center" @tap="navItemClick(item)" v-for="(item, index) in state.recentlyUsed.slice(0, 5)" :key="index">
  55. <image class="grid-area_center_item_image" :src="item.meta.icon"></image>
  56. <text class="grid-area_center_item_title">{{ item.meta.aliasTitle ? item.meta.aliasTitle : item.meta.title }}</text>
  57. </view>
  58. </view>
  59. </view>
  60. <!-- 常用功能宫格 -->
  61. <view class="grid-area bg-white">
  62. <view class="grid-area_title">常用功能</view>
  63. <view class="grid-area_center cu-list grid col-5 no-border">
  64. <view class="grid-area_center_item cu-item justify-center align-center" @tap="navItemClick(item)" v-for="(item, index) in state.cuIconList" :key="index">
  65. <image class="grid-area_center_item_image" :src="item.meta.icon"></image>
  66. <text class="grid-area_center_item_title">{{ item.meta.aliasTitle ? item.meta.aliasTitle : item.meta.title }}</text>
  67. </view>
  68. </view>
  69. </view>
  70. </view>
  71. </template>
  72. </oa-scroll>
  73. <oa-tabbar :tabbarValue="0" :tabbarList="proxy.$constData.homeTabbar"></oa-tabbar>
  74. </template>
  75. <script setup>
  76. /*----------------------------------依赖引入-----------------------------------*/
  77. import { onReady, onLoad, onShow, onNavigationBarButtonTap, onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
  78. import { ref, onMounted, inject, shallowRef, reactive, getCurrentInstance, toRefs, nextTick } from "vue";
  79. /*----------------------------------接口引入-----------------------------------*/
  80. import { scan_push, getHomePageData, getFunctionalModuleStatistics, getAppRouters, qrCodeSend, getMobileBanner } from "@/api/index";
  81. /*----------------------------------组件引入-----------------------------------*/
  82. /*----------------------------------store引入-----------------------------------*/
  83. import { useStores } from "@/store/modules/index";
  84. /*----------------------------------公共方法引入-----------------------------------*/
  85. import * as jwx from "@/utils/jssdk.js"; //引入js sdk的封装
  86. import { getToken, setToken, removeToken } from "@/utils/auth";
  87. import { storage, storageSystem } from "@/utils/storage"; // 公共方法引用
  88. /*----------------------------------公共变量-----------------------------------*/
  89. const { proxy } = getCurrentInstance();
  90. const useStore = useStores();
  91. /*----------------------------------变量声明-----------------------------------*/
  92. const state = reactive({
  93. dialogFlag: false,
  94. swiperBool: false,
  95. swiperIndex: 0,
  96. swiperTime: 5000,
  97. swiperList: [],
  98. cuIconList: [],
  99. recentlyUsed: [],
  100. });
  101. const { dialogFlag } = toRefs(state);
  102. /**
  103. * @初始化
  104. */
  105. async function init(options) {
  106. //#ifdef H5
  107. await useStore.GetWxOpenId(2, options); //调用获取微信公众号openId
  108. //#endif
  109. setTimeout(() => {
  110. getAppRoutersData(); //调用路由信息接口
  111. getMobileBannerApi(); //调用banner图接口
  112. getLocation(); //调用获取地理位置方法
  113. }, 1000);
  114. //#ifdef APP-PLUS
  115. proxy.$settingStore.baseAppInfo(), setInterval(proxy.$settingStore.baseAppInfo, 1000 * 60 * 5); //动态获取用户设备信息
  116. proxy.$settingStore.openWebSocket(); //开启WebSocket
  117. //#endif
  118. }
  119. /**
  120. * @轮播图点击事件
  121. */
  122. function swiperClick(list) {
  123. if (typeof state.swiperList[list] == "object") {
  124. let linkType = state.swiperList[list].linkType;
  125. let url = state.swiperList[list].link;
  126. if (url) {
  127. if (linkType == 1) {
  128. uni.navigateTo({
  129. url: url,
  130. });
  131. } else {
  132. uni.navigateTo({
  133. url: "/pages/common/webview/index?url=" + url,
  134. });
  135. }
  136. }
  137. }
  138. }
  139. /**
  140. * @九宫格页面跳转
  141. */
  142. function navItemClick(item) {
  143. if (item.path) {
  144. item.sort = 0;
  145. state.recentlyUsed.push(item);
  146. state.recentlyUsed = proxy.$common.uniq(state.recentlyUsed, "path");
  147. state.recentlyUsed.filter((el) => {
  148. if (el.path === item.path) {
  149. el.meta.icon = item.meta.icon;
  150. el.sort++;
  151. }
  152. });
  153. state.recentlyUsed = proxy.$common.sortEvent(state.recentlyUsed, 1);
  154. storageSystem.set("homeList", state);
  155. if (item.path.indexOf("http") != -1) {
  156. uni.navigateTo({
  157. url: "/pages/common/webview/index?url=" + item.path,
  158. });
  159. } else {
  160. uni.navigateTo({
  161. url: item.path,
  162. });
  163. }
  164. } else {
  165. uni.showModal({
  166. title: "Tips",
  167. content: "此模块开发中~",
  168. showCancel: false,
  169. success: function (res) {
  170. if (res.confirm) {
  171. } else if (res.cancel) {
  172. }
  173. },
  174. });
  175. }
  176. }
  177. // function connected() {
  178. // refresh();
  179. // uni.setNavigationBarColor({
  180. // frontColor: "#FFFFFF", //字体颜色
  181. // });
  182. // }
  183. // function disconnected() {
  184. // uni.setNavigationBarColor({
  185. // frontColor: "#000000", //字体颜色
  186. // });
  187. // }
  188. /**
  189. * @scrollView刷新数据
  190. */
  191. function refresh() {
  192. getAppRoutersData(); //调用路由信息接口
  193. getMobileBannerApi(); //调用banner图接口
  194. getLocation(); //调用获取地理位置方法
  195. }
  196. /**
  197. * @扫码功能
  198. */
  199. function scanCode() {
  200. //#ifdef H5 || MP-WEIXIN
  201. jwx.configWeiXin((jweixin) => {
  202. jweixin.scanQRCode({
  203. needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
  204. scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
  205. success: function (res) {
  206. setTimeout(function () {
  207. scan_push({ ercode: res.resultStr }).then((res) => {
  208. if (res.data.flag) {
  209. uni.showToast({
  210. title: "扫码成功",
  211. icon: "none",
  212. });
  213. }
  214. });
  215. }, 1000);
  216. },
  217. });
  218. });
  219. //#endif
  220. //#ifdef APP-PLUS
  221. uni.scanCode({
  222. autoZoom: false,
  223. scanType: ["qrCode"],
  224. success: (res) => {
  225. let list = JSON.parse(res.result);
  226. uni.showToast({
  227. title: "扫码成功",
  228. icon: "none",
  229. });
  230. qrCodeSend({
  231. qrCode: list.uid,
  232. tenantId: useStore.tenantId,
  233. userName: useStore.name,
  234. }).then((res) => {});
  235. },
  236. fail: (err) => {
  237. console.log("扫码失败", err);
  238. },
  239. complete: () => {
  240. console.log("扫码结束");
  241. },
  242. });
  243. //#endif
  244. }
  245. /**
  246. * @获取地理位置
  247. */
  248. function getLocation() {
  249. var latitude = proxy.$settingStore.deviceList.latitude;
  250. var longitude = proxy.$settingStore.deviceList.longitude;
  251. //#ifdef H5 || MP-WEIXIN
  252. // jwx.configWeiXin((jweixin) => {
  253. // // 微信公众号获取位置
  254. // jweixin.getLocation({
  255. // type: "gcj02", // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
  256. // success: function (res) {
  257. // alert(res.longitude);
  258. // },
  259. // });
  260. // });
  261. proxy.$refs["oaWeatherRef"].getWeather("上海");
  262. //#endif
  263. //#ifdef APP-PLUS
  264. if (latitude && longitude) {
  265. proxy.$refs["oaWeatherRef"].getWeather(latitude + ":" + longitude);
  266. } else {
  267. proxy.$refs["oaWeatherRef"].getWeather("上海");
  268. }
  269. //#endif
  270. }
  271. /**
  272. * @右侧按钮点击事件
  273. */
  274. function rightButtonClick() {
  275. dialogFlag.value = !dialogFlag.value;
  276. }
  277. /**
  278. * @轮播图
  279. * @api接口请求
  280. */
  281. function getMobileBannerApi() {
  282. getMobileBanner({
  283. tenantId: useStore.tenantId,
  284. }).then((res) => {
  285. if (res.data.length > 0) {
  286. state.swiperList = [];
  287. state.swiperBool = res.data[0].openNot == 1 ? true : false;
  288. state.swiperTime = res.data[0].carouselTime * 1000;
  289. for (let i = 1; i <= 5; i++) {
  290. if (res.data[0]["bannerPath" + i]) {
  291. state.swiperList.push({
  292. url: res.data[0]["bannerPath" + i],
  293. link: res.data[0]["linkUrl" + i],
  294. linkType: res.data[0]["linkType" + i],
  295. type: "image",
  296. });
  297. }
  298. }
  299. }
  300. });
  301. }
  302. /**
  303. * @获取路由信息
  304. * @api接口请求
  305. */
  306. function getAppRoutersData() {
  307. getAppRouters().then((res) => {
  308. state.cuIconList = res.data;
  309. storageSystem.set("homeList", state);
  310. });
  311. }
  312. onLoad((options) => {
  313. uni.hideTabBar(); //隐藏自带tabbar
  314. init(options);
  315. });
  316. onShow(() => {
  317. var storages = storageSystem.get("homeList");
  318. Object.keys(storages).forEach((key) => {
  319. state[key] = storages[key];
  320. });
  321. });
  322. </script>
  323. <style lang="scss" scoped>
  324. .home-container {
  325. .transition {
  326. position: fixed;
  327. top: 0;
  328. left: 0;
  329. right: 0;
  330. bottom: 0;
  331. z-index: 1100;
  332. &-section {
  333. position: absolute;
  334. top: 10px;
  335. right: 15px;
  336. background-color: #fff;
  337. border-radius: 10px;
  338. box-shadow: 0px 0px 15px 0 rgba(0, 0, 0, 0.2);
  339. &-divider {
  340. border-bottom: 0.5px rgba(0, 0, 0, 0.1) solid;
  341. margin: 0 20px;
  342. }
  343. &-content {
  344. display: flex;
  345. padding: 15px 20px;
  346. &-icon {
  347. font-size: 18px;
  348. color: #000;
  349. }
  350. &-text {
  351. margin: 0 20px;
  352. }
  353. }
  354. &-content:first-child {
  355. padding-top: 15px;
  356. border-radius: 10px 10px 0 0;
  357. }
  358. &-content:last-child {
  359. padding-bottom: 15px;
  360. border-radius: 0 0 10px 10px;
  361. }
  362. &-content:hover {
  363. // transform: 3s;
  364. // transition: all 600ms cubic-bezier(0.3, 1, 0.2, 1);
  365. transition: all 3s cubic-bezier(0.7, -0.5, 0.2, 2);
  366. background-color: rgba(0, 0, 0, 0.1);
  367. }
  368. }
  369. }
  370. .grid-area {
  371. margin-bottom: 10px;
  372. &_title {
  373. padding: 10px 10px 5px 10px;
  374. color: #000000;
  375. font-size: $uni-font-size-base;
  376. }
  377. &_center {
  378. &_item {
  379. &_image {
  380. width: 40px;
  381. height: 40px;
  382. }
  383. &_title {
  384. font-size: $uni-font-size-sm;
  385. }
  386. }
  387. }
  388. }
  389. }
  390. </style>