botPage.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <template>
  2. <div style="width: 100%;">
  3. <div style="color: #1f2937;font-weight: 600;font-size: 20px;margin-bottom: 16px;">
  4. 热门应用
  5. </div>
  6. <div class="hotAppBlo" >
  7. <div class="BigBlo" v-for="(k,ind) in hotApp" :key="ind+'p'" >
  8. <div :class="['conBlock',ind % 2 == 0 ? 'conBlock1':'conBlock2']">
  9. <div class="conBlockOne" @click="openNewWindow(k[0])" :class="[ind % 2 == 0 ? 'conW1':'conW2']">
  10. <div class="conBlockTwo" :style="{bottom : ind % 2 == 0 ? '':'16px'}">
  11. <img class="appImg" :src="JSON.parse(k[0].json).icon" alt="">
  12. <div class="con">
  13. <div class="tit">{{ k[0].name }}</div>
  14. <div class="bri">
  15. <el-tooltip class="item" effect="light" :content="k[0].detail" placement="bottom">
  16. <span>
  17. {{ k[0].detail }}
  18. </span>
  19. </el-tooltip>
  20. </div>
  21. </div>
  22. </div>
  23. <img class="hg" style="width: 20px;" src="../assets/img/hg1.svg" alt="">
  24. </div>
  25. <div style="display: flex;" :class="[ind % 2 == 0 ? 'conBlock2':'conBlock1']">
  26. <div v-for="(item,index) in list(k)" class="tabCon" @click="openNewWindow(item)" :key="index">
  27. <div style="display: flex;flex-direction: column; gap: 12px;">
  28. <img class="appImg" :src="JSON.parse(item.json).icon" alt="">
  29. <div class="con">
  30. <div class="tit">{{ item.name }}</div>
  31. <div class="bri">
  32. <el-tooltip class="item" effect="light" :content="item.detail" placement="bottom">
  33. <span>
  34. {{ item.detail }}
  35. </span>
  36. </el-tooltip>
  37. </div>
  38. </div>
  39. <img class="hg" style="width: 20px;" v-if="index == 0" src="../assets/img/hg2.svg" alt="">
  40. <img class="hg" style="width: 20px;" v-if="index == 1" src="../assets/img/hg3.svg" alt="">
  41. </div>
  42. </div>
  43. </div>
  44. </div>
  45. <div style="display: flex;justify-content: space-between;">
  46. <div class="AppTit">{{ tab[ind].name }}</div>
  47. <div class="AppBri" @click="lookMore(ind)">查看全部</div>
  48. </div>
  49. </div>
  50. </div>
  51. <el-dialog
  52. :title="diaTit"
  53. :visible.sync="dialogVisible"
  54. class="moreDia"
  55. :close-on-click-modal="false"
  56. :modal="false"
  57. width="60%"
  58. :before-close="handleClose">
  59. <div v-loading="loading" style="display: grid;grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));gap: 16px;">
  60. <div v-for="(item,index) in moreList"
  61. class="tabCon" @click="openNewWindow(item)"
  62. :key="index" style="min-width: 308px;border: 1px #e7e7e7 solid;">
  63. <div>
  64. <img class="appImg" :src="JSON.parse(item.json).icon" alt="">
  65. <div class="con">
  66. <div class="tit">{{ item.name }}</div>
  67. <div class="bri">
  68. <el-tooltip class="item" effect="light" :content="item.detail" placement="bottom">
  69. <span>
  70. {{ item.detail }}
  71. </span>
  72. </el-tooltip>
  73. </div>
  74. </div>
  75. </div>
  76. <img class="hg" style="width: 20px;" v-if="index == 0" src="../assets/img/hg1.svg" alt="">
  77. <img class="hg" style="width: 20px;" v-if="index == 1" src="../assets/img/hg2.svg" alt="">
  78. <img class="hg" style="width: 20px;" v-if="index == 2" src="../assets/img/hg3.svg" alt="">
  79. </div>
  80. </div>
  81. </el-dialog>
  82. </div>
  83. </template>
  84. <script>
  85. import { API_CONFIG } from "@/common/apiConfig";
  86. import { mapGetters } from 'vuex';
  87. export default {
  88. props:['hotApp'],
  89. computed: {
  90. ...mapGetters(['userinfo']),
  91. list(){
  92. return function(val) {
  93. console.log(val);
  94. let newArr = val.slice(1)
  95. return newArr
  96. }
  97. }
  98. },
  99. data() {
  100. return {
  101. tab:[
  102. {name:'项目式学习',type:'63915be8-cefa-11ef-a2d1-005056b86db5'},
  103. {name:'教学工具',type:'38111096-cc11-11ef-a2d1-005056b86db5'},
  104. {name:'学习工具',type:'917a5a56-abd5-11ef-b887-005056b86db5'},
  105. {name:'效率工具',type:'9b257041-abd5-11ef-b887-005056b86db5'},
  106. ],
  107. // 控制弹框展开
  108. dialogVisible:false,
  109. // 查看更多标题
  110. diaTit:'',
  111. // 查看更多弹框list
  112. moreList:[],
  113. loading:false
  114. }
  115. },
  116. methods: {
  117. openNewWindow(val) {
  118. console.log(val);
  119. // // 基本用法:打开指定 URL
  120. window.open(val.url, "_blank");
  121. },
  122. handleClose(){
  123. this.dialogVisible = false
  124. },
  125. lookMore(index){
  126. this.dialogVisible = true
  127. this.diaTit = this.tab[index].name
  128. this.loading = true
  129. let params = [
  130. {
  131. functionName: API_CONFIG.ajax_morHotApp.functionName,
  132. uid: this.userinfo.userid,
  133. type: this.tab[index].type,
  134. cn: this.userinfo.schoolArea ? this.userinfo.schoolArea : this.userinfo.orgArea, //学校id
  135. },
  136. ];
  137. this.$ajax
  138. .post(API_CONFIG.baseUrl, params)
  139. .then((res) => {
  140. this.moreList = res.data[0]
  141. this.loading = false
  142. })
  143. .catch((err) => {
  144. console.log(err);
  145. this.loading = false
  146. this.$message.error("获取工具数据失败");
  147. });
  148. }
  149. },
  150. }
  151. </script>
  152. <style scoped>
  153. .hotAppBlo{
  154. /* display: grid;
  155. grid-template-columns: repeat(4, 1fr);
  156. gap: 5%; 网格间距 */
  157. display: flex;
  158. justify-content: space-between;
  159. }
  160. .BigBlo{
  161. background-color: #EFEFEF;
  162. border-radius: 10px;
  163. padding: 20px;
  164. border: 1px solid #BDBDBD;
  165. box-shadow: 0px 0px 40px 0px #0000000D;
  166. }
  167. .conBlock{
  168. display: flex;
  169. box-sizing: border-box;
  170. margin-bottom: 10px;
  171. border-radius: 10px;
  172. height: calc(100% - 20px);
  173. gap: 10px;
  174. }
  175. .conBlock1{
  176. flex: 1;
  177. flex-direction: column;
  178. justify-content: space-around;
  179. gap: 10px;
  180. }
  181. .AppBri{
  182. font-family: PingFang SC;
  183. font-weight: 600;
  184. font-size: 14px;
  185. line-height: 100%;
  186. letter-spacing: 0%;
  187. text-align: right;
  188. color: #969BA3;
  189. cursor: pointer;
  190. }
  191. .AppTit{
  192. font-family: PingFang SC;
  193. font-weight: 600;
  194. font-size: 16px;
  195. line-height: 100%;
  196. }
  197. .conBlockOne{
  198. background-color: #fff;
  199. border-radius: 10px;
  200. padding: 16px;
  201. box-sizing: border-box;
  202. position: relative;
  203. overflow: hidden;
  204. justify-content: flex-start;
  205. position: relative;
  206. cursor: pointer;
  207. transition: all 0.3s ease; /* 统一过渡效果 */
  208. }
  209. .conBlockOne:hover{
  210. transform: translateY(-5px); /* 向上位移 */
  211. box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  212. }
  213. .conBlockTwo{
  214. width: 91px;
  215. height: 90px;
  216. display: flex;
  217. flex-direction: column;
  218. position: absolute;
  219. gap: 12px;
  220. }
  221. .conBlock2{
  222. justify-content: space-between;
  223. gap: 10px;
  224. }
  225. .moreDia >>> .el-dialog{
  226. border-radius: 10px;
  227. }
  228. .moreDia >>> .el-dialog__body{
  229. height: 300px;
  230. overflow: auto;
  231. border-top: 1px #e7e7e7 solid;
  232. }
  233. .AppList{
  234. position: relative;
  235. flex-wrap: wrap;display: flex;
  236. justify-content: space-between;
  237. overflow: hidden;
  238. background: #fff;
  239. border: 1px rgb(243 244 246 / var(--tw-border-opacity, 1)) solid;
  240. border-radius: 10px;
  241. padding: 16px;box-sizing: border-box;
  242. }
  243. .conW1{
  244. /* height: 100%; */
  245. width: 100%;
  246. height: 50%;
  247. min-width: 100px;
  248. min-height: 100px;
  249. justify-content: flex-start;
  250. }
  251. .conW2{
  252. height: 100%;
  253. width: 7vw;
  254. min-width: 100px;
  255. justify-content: flex-end !important;
  256. }
  257. .tabCon{
  258. transition: all 0.3s ease; /* 统一过渡效果 */
  259. border-radius: 10px;
  260. cursor: pointer;
  261. display: flex;
  262. width: 7vw;
  263. height: 7vw;
  264. min-width: 100px;
  265. min-height: 100px;
  266. background: #fff;
  267. padding: 26px 14px;
  268. box-sizing: border-box;
  269. position: relative;
  270. overflow: hidden;
  271. }
  272. .tabCon:hover{
  273. transform: translateY(-5px); /* 向上位移 */
  274. box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  275. }
  276. .hg {
  277. width: 28px !important;
  278. height: 28px;
  279. position: absolute;
  280. top: 0;
  281. right: 0;
  282. }
  283. .con{
  284. flex: 1;
  285. display: flex;
  286. flex-direction: column;
  287. gap: 6px;
  288. height: 54px;
  289. justify-content: flex-end;
  290. }
  291. .appImg{
  292. width: 32px;
  293. height: 32px;
  294. border-radius: 50%;
  295. object-fit: cover;
  296. }
  297. .tit{
  298. color: #000000;
  299. -webkit-line-clamp: 1;
  300. display: -webkit-box;
  301. -webkit-box-orient: vertical;
  302. overflow: hidden;
  303. text-overflow: ellipsis;
  304. font-family: PingFang SC;
  305. font-weight: 500;
  306. font-size: 14px;
  307. line-height: 100%;
  308. }
  309. .bri{
  310. color: #969BA3;
  311. -webkit-line-clamp: 1;
  312. display: -webkit-box;
  313. -webkit-box-orient: vertical;
  314. overflow: hidden;
  315. text-overflow: ellipsis;
  316. font-family: PingFang SC;
  317. font-weight: 300;
  318. font-size: 10px;
  319. line-height: 12px;
  320. letter-spacing: 0%;
  321. }
  322. </style>