topPage.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. <template>
  2. <div>
  3. <div class="top" v-if="fromL.admin.banner && fromL.admin.banner.length == 0">
  4. <div class="topBlock">
  5. <div class="topTit" style="display: flex;">
  6. <div>欢迎使用</div>
  7. <div style="color: #0354D7;margin: 0 15px;"><span v-if="userinfo.orgName">{{userinfo.orgName}}—</span>{{ userinfo.schoolName }}</div>
  8. <div>AI平台!</div>
  9. </div>
  10. <div class="topDetail">
  11. {{ fromL.basics.brief }}
  12. </div>
  13. </div>
  14. <img style="width: 96px;height: 96px;" src="../assets/img/root.png" alt="">
  15. </div>
  16. <div style="width: 100%;height: 100%;object-fit: cover;border-radius: 10px;height: 300px;"
  17. v-if="fromL.admin.banner && fromL.admin.banner.length == 1"
  18. >
  19. <img style="width: 100%;height: 100%;object-fit: cover;border-radius: 10px;"
  20. :src="fromL.admin.banner[0].src" alt="" @click="gotoBanner(fromL.admin.banner[0].url)">
  21. </div>
  22. <div style="border-radius: 10px;overflow: hidden;" v-if="fromL.admin.banner && fromL.admin.banner.length > 1">
  23. <el-carousel style="width: 100%;" indicator-position="outside">
  24. <el-carousel-item v-for="(i,index) in fromL.admin.banner" :key="index">
  25. <img style="width: 100%;height: 100%;object-fit: cover;border-radius: 10px;"
  26. @click="gotoBanner(i.url)"
  27. :src="i.src" alt="">
  28. </el-carousel-item>
  29. </el-carousel>
  30. </div>
  31. <!-- 平台应用 -->
  32. <div class="TabList">
  33. <div
  34. @mouseenter="setHovered(index, true)"
  35. @mouseleave="setHovered(index, false)"
  36. class="TabListAll"
  37. @click="openApp(item)"
  38. v-for="(item,index) in tabList"
  39. :key="index+'1p'">
  40. <div class="TabListCon">
  41. <div v-for="(p,pin) in AppCon(item.url)" :key="pin+'p'">
  42. <img class="imgApp" v-if="tabList[index].hovered ? p.hoverIcon : p.platformIcon" :src="tabList[index].hovered ? p.hoverIcon : p.platformIcon" alt="">
  43. <div class="TabListName">
  44. {{ p.name }}
  45. </div>
  46. </div>
  47. <div class="TabListBri">
  48. <el-tooltip class="item" effect="light" :content="item.description" placement="bottom">
  49. <span>
  50. {{ item.description }}
  51. </span>
  52. </el-tooltip>
  53. </div>
  54. </div>
  55. </div>
  56. </div>
  57. <!-- 常见应用 -->
  58. <div class="footCon">
  59. <div class="footConLeft">
  60. <img src="../assets/img/dong.png" alt="">
  61. </div>
  62. <div style="display: flex;gap: 16px;flex: 1;">
  63. <div class="footList">
  64. <div class="footListCon" v-for="(item,index) in admincocoFlow" @click="openNewWindow(item)" :key="index+'2p'">
  65. <div class="footListConimg">
  66. <img v-if="!fromL.admin.cocoFlow.length"
  67. style="margin-bottom: 12px;height: 24px;width: 22px;"
  68. :src="appImgList[index]" alt="">
  69. <img
  70. style="margin-bottom: 12px;height: 24px;width: 22px;"
  71. v-else :src="JSON.parse(item.json).icon" alt="">
  72. </div>
  73. <div class="TabListName">{{ item.name }}</div>
  74. <div class="TabListBri">
  75. <el-tooltip class="item" effect="light" :content="item.detail" placement="bottom">
  76. <span>
  77. {{ item.detail }}
  78. </span>
  79. </el-tooltip>
  80. </div>
  81. <!-- <div class="cha" @click.stop="delApp(item.lid)">
  82. <img style="width: 20px;" src="../assets/img/cha.svg" alt="">
  83. </div> -->
  84. </div>
  85. </div>
  86. <div class="footList2">
  87. <div class="footList2Tit">
  88. 常见应用
  89. </div>
  90. <div v-for="(i,index) in (4 - CocoFlowList.length)" @click="openUsuallyApp"
  91. :key="index+'3p'" class="footListCon2">
  92. <div style="margin-bottom: 8px;font-size: 40px;color: #0354D7;">
  93. <img src="../assets/img/add.svg" alt="">
  94. </div>
  95. </div>
  96. <div class="footListCon6" v-for="(item,index) in CocoFlowList" @click="openNewWindow(item)" :key="index+'4p'">
  97. <div class="footListConimg">
  98. <img style="margin-bottom: 12px;height: 24px;width: 22px;" :src="JSON.parse(item.json).icon" alt="">
  99. </div>
  100. <div class="TabListName">{{ item.name }}</div>
  101. <div class="TabListBri">
  102. <el-tooltip class="item" effect="light" :content="item.detail" placement="bottom">
  103. <span>
  104. {{ item.detail }}
  105. </span>
  106. </el-tooltip>
  107. </div>
  108. <div class="cha" @click.stop="delApp(item.lid)">
  109. <img style="width: 20px;" src="../assets/img/cha.svg" alt="">
  110. </div>
  111. </div>
  112. </div>
  113. </div>
  114. </div>
  115. <!-- 常见应用弹框 -->
  116. <el-dialog
  117. title="应用列表"
  118. :visible.sync="dialogVisible"
  119. class="moreDia"
  120. :close-on-click-modal="false"
  121. :modal="false"
  122. width="60%"
  123. :before-close="handleClose">
  124. <div v-loading="loading" style="display: grid;grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));gap: 16px;height: 300px;overflow: auto;">
  125. <div v-for="(item,index) in isAdd(usuallyList)" class="tabCon" @click="addApp(item.id)" :key="index+'6p'" style="min-width: 308px;">
  126. <div class="AppList">
  127. <img class="appImg" :src="JSON.parse(item.json).icon" alt="">
  128. <div class="con">
  129. <div class="tit">{{ item.name }}</div>
  130. <div class="bri">
  131. <el-tooltip class="item" effect="light" :content="item.detail" placement="bottom">
  132. <span>
  133. {{ item.detail }}
  134. </span>
  135. </el-tooltip>
  136. </div>
  137. </div>
  138. <div style="position: absolute;top: 6px;right: 15px;" v-if="tab.includes(item.id)">
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. <div style="height: 45px;line-height: 45px;text-align: end;">
  144. <el-button @click="handleClose">取消</el-button>
  145. <el-button @click="addUsuallyApp" style="background-color: #0663FE;" type="primary">确认</el-button>
  146. </div>
  147. </el-dialog>
  148. </div>
  149. </template>
  150. <script>
  151. import { mapGetters } from 'vuex';
  152. import store from '../store'
  153. import { API_CONFIG } from "@/common/apiConfig";
  154. export default {
  155. computed: {
  156. ...mapGetters(['userinfo','fromL']),
  157. // banner循环图
  158. // bannerL(){
  159. // return function(val){
  160. // console.log('val',val);
  161. // return val.split(',')
  162. // }
  163. // },
  164. // 如果hk,com没有图标,默认使用cn的
  165. AppCon(){
  166. return function(c) {
  167. let k = JSON.parse(JSON.stringify(c))
  168. let data = k.filter(e=>{
  169. return e.region == this.userinfo.schoolArea || e.region == this.userinfo.orgArea
  170. })
  171. let data2 = k.filter(e=>{
  172. return e.region == 'cn'
  173. })
  174. // 如果hk,com没有图标,默认使用cn的
  175. if (!data[0].icon){
  176. data[0].icon = data2[0].icon
  177. data[0].activeIcon = data2[0].activeIcon
  178. }
  179. return data
  180. };
  181. },
  182. // 筛选是否为管理员可见,是否被删除
  183. appSignL(){
  184. return function(val){
  185. let data = []
  186. if (this.userinfo.type == 1 && this.userinfo.role == 1) {
  187. val.forEach( e =>{
  188. if (e.menuName || e.status == 0) {
  189. data.push(e)
  190. }
  191. })
  192. } else {
  193. val.forEach( e =>{
  194. if (e.menuName || (e.isAdmin == '0' && e.status == 0)) {
  195. data.push(e)
  196. }
  197. })
  198. }
  199. return data
  200. }
  201. },
  202. // 判断是否被添加过
  203. isAdd(){
  204. return function(val){
  205. const difference = val.filter(item1 =>
  206. !this.CocoFlowList.some(item2 => item1.id === item2.id)
  207. );
  208. return difference
  209. }
  210. }
  211. },
  212. data() {
  213. return {
  214. dialogVisible:false,
  215. //常见ai应用列表(添加弹框)
  216. usuallyList:[],
  217. loading:false,
  218. //选中应用列表
  219. tab:[],
  220. // 管理平台添加常见cocoFlow应用
  221. admincocoFlow:[],
  222. // 用户ai应用数组
  223. CocoFlowList:[],
  224. // 平台工具
  225. tabList:[],
  226. appImgList:[
  227. require('../assets/img/img4.svg'),
  228. require('../assets/img/img1.svg'),
  229. require('../assets/img/img3.svg'),
  230. require('../assets/img/img5.svg'),
  231. require('../assets/img/img8.svg'),
  232. require('../assets/img/img2.svg'),
  233. require('../assets/img/img7.svg'),
  234. require('../assets/img/img6.svg'),
  235. ],
  236. hovList:[],
  237. }
  238. },
  239. methods: {
  240. gotoBanner(val){
  241. if (val == '') return
  242. window.open(val, "_blank");
  243. },
  244. // 首页平台应用浮动效果
  245. setHovered(index, value) {
  246. // console.log(index, value);
  247. this.tabList[index].hovered = value;
  248. // console.log('this.tabList',this.tabList[index].hovered);
  249. },
  250. // 删除应用
  251. delApp(val){
  252. this.$confirm('确定删除吗', '提示', {
  253. confirmButtonText: '确定',
  254. cancelButtonText: '取消',
  255. type: 'warning'
  256. }).then(async () => {
  257. let params = [
  258. {
  259. functionName: API_CONFIG.ajax_del_usuallyApp.functionName,
  260. aid: val,
  261. },
  262. ];
  263. this.$ajax
  264. .post(API_CONFIG.baseUrl, params)
  265. .then(() => {
  266. this.$message.success('删除成功')
  267. this.getData()
  268. })
  269. .catch((err) => {
  270. console.log(err);
  271. this.$message.error("删除失败");
  272. });
  273. }).catch(() => {
  274. // 取消操作
  275. });
  276. },
  277. handleClose(){
  278. this.usuallyList= []
  279. this.tab= []
  280. this.dialogVisible = false
  281. },
  282. // 弹框选择添加应用
  283. addApp(val){
  284. // let data = this.CocoFlowList.filter(e=>{
  285. // return e.id == val
  286. // })
  287. // if (data.length != 0) return this.$message.info('常用列表已添加')
  288. let kpl = [...this.tab,...this.CocoFlowList]
  289. // console.log(kpl);
  290. const index = this.tab.indexOf(val);
  291. if (index !== -1) {
  292. this.tab.splice(index, 1); // 删除第一个匹配项
  293. } else {
  294. if (kpl.length > 3) return this.$message.info('只能添加四个常用应用哦')
  295. this.tab.push(val); // 添加元素到末尾
  296. }
  297. },
  298. // 打开常见应用弹框
  299. openUsuallyApp(){
  300. this.dialogVisible = true
  301. this.loading = true
  302. let params = [
  303. {
  304. functionName: API_CONFIG.ajax_usuallyApp.functionName,
  305. uid: this.userinfo.userid,
  306. cn: this.userinfo.schoolArea ? this.userinfo.schoolArea : this.userinfo.orgArea, //学校id
  307. },
  308. ];
  309. this.$ajax
  310. .post(API_CONFIG.baseUrl, params)
  311. .then((res) => {
  312. this.usuallyList = res.data[0]
  313. this.loading = false
  314. })
  315. .catch((err) => {
  316. console.log(err);
  317. this.loading = false
  318. this.$message.error("获取工具数据失败");
  319. });
  320. },
  321. // 添加常用确定按钮
  322. async addUsuallyApp(){
  323. const uploadYn = async files => {
  324. for (let index = 0; index < files.length; index++) {
  325. await this.XAdd(files[index]);
  326. console.log(index);
  327. }
  328. }
  329. await uploadYn(this.tab);
  330. console.log('完成了');
  331. this.getData()
  332. this.handleClose()
  333. },
  334. // 循环添加用户选择常见应用
  335. XAdd(val){
  336. return new Promise((resolve) => {
  337. let params = [
  338. {
  339. functionName: API_CONFIG.ajax_add_usuallyApp.functionName,
  340. oid:this.userinfo.organizeid,
  341. aid: val,
  342. uid: this.userinfo.userid,
  343. },
  344. ];
  345. this.$ajax
  346. .post(API_CONFIG.baseUrl, params)
  347. .then(() => {
  348. resolve(1)
  349. })
  350. .catch((err) => {
  351. console.log(err);
  352. });
  353. })
  354. },
  355. // 获取已添加cocoFlow应用
  356. getData(){
  357. let params = [
  358. {
  359. functionName: API_CONFIG.ajax_addedUsuallyApp.functionName,
  360. uid: this.userinfo.userid,
  361. },
  362. ];
  363. this.$ajax
  364. .post(API_CONFIG.baseUrl, params)
  365. .then((res) => {
  366. this.CocoFlowList = res.data[0]
  367. })
  368. .catch((err) => {
  369. console.log(err);
  370. this.$message.error("获取工具数据失败");
  371. });
  372. },
  373. siftCoco(){
  374. let data = []
  375. let val = JSON.parse(JSON.stringify(this.fromL.admin.index.list))
  376. // 用户是管理员全部展示
  377. if (this.userinfo.type == 1 && this.userinfo.role == 1) {
  378. val.forEach( e =>{
  379. if (e.menuName || e.status == 0) {
  380. data.push(e)
  381. }
  382. })
  383. } else {
  384. // 用户不是管理员,判断是否为用户可见 isAdmin 0普通用户 status是否被删除
  385. val.forEach( e =>{
  386. if (e.menuName || (e.isAdmin == '0' && e.status == 0)) {
  387. data.push(e)
  388. }
  389. })
  390. }
  391. this.tabList = data
  392. console.log('this.tabList',this.tabList);
  393. },
  394. getAdmincocoFlow(){
  395. // 筛选可用平台工具,判断是否管理员可见,去除已删除工具
  396. this.siftCoco()
  397. // console.log('getAdmincocoFlow',this.fromL);
  398. let appList=["2d05a12a-f0e7-11ef-b508-005056924926",
  399. "38ee6402-0539-11f0-b508-005056924926",
  400. "1c83613c-ffb7-11ef-b508-005056924926",
  401. "0d3d87bd-00b6-11f0-b508-005056924926",
  402. "ee61f383-0311-11f0-b508-005056924926",
  403. "701615ab-ffe8-11ef-b508-005056924926",
  404. "d1edef14-ef6f-11ef-b508-005056924926",
  405. "a8781a86-00d8-11f0-b508-005056924926"]
  406. let params = [
  407. {
  408. functionName: API_CONFIG.ajax_AdminApp.functionName,
  409. con: this.fromL.admin.cocoFlow.length == 0 ? appList.join(',') : this.fromL.admin.cocoFlow.join(','),
  410. },
  411. ];
  412. this.$ajax
  413. .post(API_CONFIG.baseUrl, params)
  414. .then((res) => {
  415. this.admincocoFlow = res.data[0]
  416. })
  417. .catch((err) => {
  418. console.log(err);
  419. this.$message.error("获取工具数据失败");
  420. });
  421. },
  422. // 打开平台应用
  423. async openApp(val){
  424. // 点击相同应用不刷新
  425. if (this.appSign == val.toolId) return
  426. // 更新标识
  427. await store.commit('user/SET_AppSIGN', val.toolId)
  428. let url = ''
  429. val.url.forEach(e => {
  430. // if (e.region == this.userinfo.schoolArea || e.region == this.userinfo.orgArea) {
  431. if (e.region == this.$region) {
  432. url = e.url
  433. }
  434. });
  435. let _userinfo = this.userinfo, //登录用户信息
  436. { userid: _userid, organizeid: _oid, type: _type, org: _org, role: _role, classid: _classId } = _userinfo; // 解构赋值获取用户信息
  437. const _TscreenType = 1, _SscreenType = 3; // 常量定义
  438. let queryString = ''
  439. if(val.argumentList && val.argumentList.length){
  440. const paramsMap = {
  441. userid: _userid,
  442. org: _org,
  443. oid: _oid,
  444. tType: _type,
  445. role: _role,
  446. classId: _classId,
  447. TscreenType: _TscreenType,
  448. SscreenType: _SscreenType
  449. };
  450. const canshu = val.argumentList
  451. .filter(param => paramsMap[param] !== undefined || param === 'type')
  452. .map(param => param === 'type' ? `tType=${paramsMap['tType']}` : `${param}=${paramsMap[param]}`);
  453. queryString = canshu.length ? (url.includes('?') ? '&' : '?') + canshu.join('&') : ''; // 生成查询字符串
  454. }
  455. let _url = url + queryString
  456. console.log('_url',_url);
  457. let kpl = ` <iframe
  458. v-if="appSign && urlAddress"
  459. allow= "camera *; microphone *;display-capture;midi;encrypted-media;"
  460. frameborder="no"
  461. border="0"
  462. style="border:0;width:100%;height:100%;"
  463. src="${_url}"
  464. ref="pageCon"
  465. >
  466. </iframe>`
  467. let pl = {json:kpl ,stateL :true,toolId :val.toolId}
  468. // this.$emit('AddAppJson',pl)
  469. this.$emit('cutUrl',pl)
  470. // document.querySelector('#pageCon').innerHTML = '';
  471. // window.topU.U.MD.D.I.openApplicationWai(val.toolId, url, dom,val.argumentList)
  472. },
  473. // 打开CocoFlow应用
  474. openNewWindow(val) {
  475. console.log(val);
  476. // // 基本用法:打开指定 URL
  477. window.open(val.url, "_blank");
  478. },
  479. },
  480. }
  481. </script>
  482. <style scoped>
  483. /* 顶部区域 */
  484. .topBlock{
  485. display: flex;
  486. flex-direction: column;
  487. justify-content: space-between;
  488. }
  489. .topTit{
  490. font-size: 30px;
  491. height: 100%;
  492. color: #000;
  493. font-weight: 600;
  494. }
  495. .topDetail{
  496. color: #64748B;
  497. margin-top: 16px;
  498. }
  499. /* 平台应用 */
  500. .TabList{
  501. display: grid;
  502. grid-template-columns: repeat(3, 1fr);
  503. gap: 20px; /* 网格间距 */
  504. margin-top: 10px;
  505. }
  506. .TabListAll{
  507. position: relative !important;
  508. display: flex;
  509. height: 140px;
  510. justify-content: flex-end;
  511. }
  512. .imgApp{
  513. width: 120px;
  514. height: 140px;
  515. object-fit: contain;
  516. position: absolute;
  517. top: 50%;
  518. transform: translate(0,-50%) !important;
  519. left: 0px;
  520. }
  521. .TabListCon{
  522. width: 170px;
  523. height: 140px;
  524. padding: 24px;
  525. box-sizing: border-box;
  526. background-color: #fff;
  527. border-radius: 10px;
  528. width: calc(100% - 60px);
  529. transition: all 0.3s ease; /* 统一过渡效果 */
  530. background-size: 20px 20px;
  531. cursor: pointer;
  532. box-shadow: 0px 4px 10px 0px #0000000D;
  533. display: flex;
  534. flex-direction: column;
  535. justify-content: flex-end;
  536. align-items: end;
  537. }
  538. .TabListCon:hover{
  539. width: calc(100% - 50px);
  540. height: 125px;
  541. margin-right: 10px;
  542. box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  543. }
  544. .TabListCon:hover TabListBri{
  545. -webkit-line-clamp: 2;
  546. width: 150px;
  547. }
  548. .TabListName{
  549. color: #1f2937;
  550. font-size: 16px;
  551. font-weight: 600;
  552. padding: 5px 0;
  553. margin-bottom: 4px;
  554. -webkit-line-clamp: 2;
  555. display: -webkit-box;
  556. -webkit-box-orient: vertical;
  557. overflow: hidden;
  558. text-overflow: ellipsis;
  559. }
  560. .TabListBri{
  561. color: #4b5563;
  562. font-size: 12px;
  563. -webkit-line-clamp: 1;
  564. display: -webkit-box;
  565. -webkit-box-orient: vertical;
  566. overflow: hidden;
  567. text-overflow: ellipsis;
  568. }
  569. .tabCon{
  570. transition: all 0.3s ease; /* 统一过渡效果 */
  571. border-radius: 10px;
  572. cursor: pointer;
  573. }
  574. /* 常见应用样式 */
  575. .footCon{
  576. display: flex;
  577. height: 350px;
  578. justify-content: space-between;
  579. box-sizing: border-box;
  580. border-radius: 10px;
  581. margin: 80px 0;
  582. /* background-image: radial-gradient(#E6F0FF 1px, transparent 1px); */
  583. background-size: 20px 20px;
  584. }
  585. /* 图片 */
  586. .footConLeft{
  587. width: 400px;
  588. min-width: 150px;
  589. box-sizing: border-box;
  590. display: flex;
  591. align-items: center;
  592. }
  593. .footConLeft img{
  594. min-width: 150px;
  595. object-view-box: inset(0% 0% 0% 30px);
  596. }
  597. /* 中间后面设置应用 */
  598. .footList{
  599. display: grid;
  600. grid-template-columns: repeat(4, 1fr);
  601. grid-template-rows: repeat(2, 1fr); /* 创建两行,每行高度相等 */
  602. gap: 16px; /* 网格间距 */
  603. flex: 2;
  604. }
  605. .footListCon{
  606. background-color: #fff;
  607. border-radius: 10px;
  608. box-shadow: 0px 0px 22.4px 0px #0000000D;
  609. padding: 16px;
  610. box-sizing: border-box;
  611. transition: all 0.3s ease; /* 统一过渡效果 */
  612. cursor: pointer;
  613. }
  614. .footListCon6{
  615. background-color: #fff;
  616. border-radius: 10px;
  617. box-shadow: 0px 0px 22.4px 0px #0000000D;
  618. padding: 16px;
  619. box-sizing: border-box;
  620. cursor: pointer;
  621. position: relative;
  622. }
  623. .footListCon6:hover .cha{
  624. display: block;
  625. }
  626. .footListCon:hover{
  627. transform: translate(-5px,-10px); /* 向上位移 */
  628. box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  629. }
  630. .footListConimg{
  631. height: 40%;
  632. padding-top: 8px;
  633. box-sizing: border-box;
  634. }
  635. .cha{
  636. display: none;position: absolute;top: 10px;right: 10px;
  637. }
  638. .footListCon:hover .cha{
  639. display: block;
  640. }
  641. /* 添加常见应用区域 */
  642. .footList2{
  643. display: grid;
  644. grid-template-columns: repeat(2, 1fr);
  645. grid-template-rows: repeat(2, 1fr); /* 创建两行,每行高度相等 */
  646. gap: 16px;
  647. flex: 1;
  648. position: relative;
  649. }
  650. .footList2Tit{
  651. position: absolute;
  652. top: -30px;
  653. left: 0;
  654. font-family: PingFang SC;
  655. color: #000;
  656. }
  657. .footListCon2{
  658. display: flex;
  659. cursor: pointer;
  660. justify-content: center;
  661. flex-direction: column;
  662. align-items: center;
  663. border: 1px dashed #000000;
  664. box-sizing: border-box;
  665. border-radius: 12px;
  666. border-width: 1px;
  667. background-color: #E5E5E5;
  668. }
  669. .footListCon2:hover {
  670. background: #C9C9C9;
  671. }
  672. /* 弹框 */
  673. .moreDia >>> .el-dialog{
  674. border-radius: 10px;
  675. }
  676. .moreDia >>> .el-dialog__body{
  677. height: 345px;
  678. /* overflow: auto; */
  679. border-top: 1px #e7e7e7 solid;
  680. }
  681. /* 对号 */
  682. .top{
  683. display: flex;
  684. height: 154px;
  685. justify-content: space-between;
  686. background-color: #fff;
  687. align-items: center;
  688. padding: 24px;
  689. box-sizing: border-box;
  690. margin-bottom: 32px;
  691. border-radius: 10px;
  692. box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)
  693. }
  694. .AppList{
  695. flex-wrap: wrap;display: flex;
  696. justify-content: space-between;
  697. border: 1px rgb(243 244 246 / var(--tw-border-opacity, 1)) solid;
  698. border-radius: 10px;padding: 16px;box-sizing: border-box;
  699. position: relative;
  700. }
  701. .appImg{
  702. width: 48px;
  703. height: 48px;
  704. border-radius: 50%;
  705. object-fit: cover;
  706. }
  707. .con{
  708. flex: 1;
  709. margin-left: 12px;
  710. display: flex;
  711. flex-direction: column;
  712. justify-content: center;
  713. }
  714. .tit{
  715. color: #1f2937;font-size: 16px;height: 24px;line-height: 24px;
  716. -webkit-line-clamp: 1;
  717. display: -webkit-box;
  718. -webkit-box-orient: vertical;
  719. overflow: hidden;
  720. text-overflow: ellipsis;
  721. }
  722. .bri{
  723. color: #6b7280;font-size: 12px;height: 16px;line-height: 16px;
  724. overflow: hidden;
  725. -webkit-line-clamp: 1;
  726. display: -webkit-box;
  727. -webkit-box-orient: vertical;
  728. overflow: hidden;
  729. text-overflow: ellipsis;
  730. }
  731. </style>