123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703 |
- <template>
- <div>
- <div class="top">
- <div class="topBlock">
- <div class="topTit" style="display: flex;">
- <div>欢迎使用</div>
- <div style="color: #0354D7;margin: 0 15px;"><span v-if="userinfo.orgName">{{userinfo.orgName}}—</span>{{ userinfo.schoolName }}</div>
- <div>AI平台!</div>
- </div>
- <div class="topDetail">
- <!-- 探索AI教育的无限可能,提升教学效率与学习体验 -->
- {{ fromL.basics.brief }}
- </div>
- </div>
- <img style="width: 96px;height: 96px;" src="../assets/img/root.png" alt="">
- </div>
- <!-- 平台应用 -->
- <div class="TabList">
- <div
- @mouseenter="setHovered(index, true)"
- @mouseleave="setHovered(index, false)"
- style="position: relative;"
- @click="openApp(item)"
- v-for="(item,index) in appSignL(fromL.admin.index.list)"
- :key="index+'1p'">
- <div class="TabListCon">
- <div v-for="(p,pin) in AppCon(item.url)" :key="pin+'p'">
- <img class="imgApp" :src="hovList[index] ? p.hoverIcon : p.platformIcon" alt="">
- <div class="TabListName">
- {{ p.name }}
- </div>
- </div>
- <div class="TabListBri">
- <el-tooltip class="item" effect="light" :content="item.description" placement="bottom">
- <span>
- {{ item.description }}
- </span>
- </el-tooltip>
- </div>
- </div>
-
- </div>
- </div>
- <!-- 常见应用 -->
- <div class="footCon">
- <div class="footConLeft">
- <img src="../assets/img/dong.png" alt="">
- </div>
- <div class="footList">
- <div class="footListCon" v-for="(item,index) in admincocoFlow" @click="openNewWindow(item)" :key="index+'2p'">
- <div class="footListConimg"><img style="margin-bottom: 12px;height: 24px;width: 22px;" :src="JSON.parse(item.json).icon" alt=""></div>
- <div class="TabListName">{{ item.name }}</div>
- <div class="TabListBri">
- <el-tooltip class="item" effect="light" :content="item.detail" placement="bottom">
- <span>
- {{ item.detail }}
- </span>
- </el-tooltip>
- </div>
- <!-- <div class="cha" @click.stop="delApp(item.lid)">
- <img style="width: 20px;" src="../assets/img/cha.svg" alt="">
- </div> -->
- </div>
- </div>
- <div class="footList2">
- <div class="footList2Tit">
- 常见应用
- </div>
- <div v-for="(i,index) in (4 - CocoFlowList.length)" @click="openUsuallyApp"
- :key="index+'3p'" class="footListCon2">
- <div style="margin-bottom: 8px;font-size: 40px;color: #0354D7;">
- <img src="../assets//img/add.svg" alt="">
- </div>
- </div>
- <div class="footListCon" v-for="(item,index) in CocoFlowList" @click="openNewWindow(item)" :key="index+'4p'">
- <div class="footListConimg">
- <img style="margin-bottom: 12px;height: 24px;width: 22px;" :src="JSON.parse(item.json).icon" alt="">
- </div>
- <div class="TabListName">{{ item.name }}</div>
- <div class="TabListBri">
- <el-tooltip class="item" effect="light" :content="item.detail" placement="bottom">
- <span>
- {{ item.detail }}
- </span>
- </el-tooltip>
- </div>
- <div class="cha" @click.stop="delApp(item.lid)">
- <img style="width: 20px;" src="../assets/img/cha.svg" alt="">
- </div>
- </div>
- </div>
- </div>
- <!-- 常见应用弹框 -->
- <el-dialog
- title="应用列表"
- :visible.sync="dialogVisible"
- class="moreDia"
- :close-on-click-modal="false"
- :modal="false"
- width="60%"
- :before-close="handleClose">
- <div v-loading="loading" style="display: grid;grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));gap: 16px;height: 300px;overflow: auto;">
- <div v-for="(item,index) in isAdd(usuallyList)" class="tabCon" @click="addApp(item.id)" :key="index+'6p'" style="min-width: 308px;">
- <div class="AppList">
- <img class="appImg" :src="JSON.parse(item.json).icon" alt="">
- <div class="con">
- <div class="tit">{{ item.name }}</div>
- <div class="bri">
- <el-tooltip class="item" effect="light" :content="item.detail" placement="bottom">
- <span>
- {{ item.detail }}
- </span>
- </el-tooltip>
- </div>
- </div>
- <div style="position: absolute;top: 6px;right: 15px;" v-if="tab.includes(item.id)">
- ✔
- </div>
- </div>
- </div>
- </div>
- <div style="height: 45px;line-height: 45px;text-align: end;">
- <el-button @click="handleClose">取消</el-button>
- <el-button @click="addUsuallyApp" type="primary">确认</el-button>
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- import { mapGetters } from 'vuex';
- import store from '../store'
- import { API_CONFIG } from "@/common/apiConfig";
- export default {
- computed: {
- ...mapGetters(['userinfo','fromL']),
- // 如果hk,com没有图标,默认使用cn的
- AppCon(){
- return function(c) {
- let k = JSON.parse(JSON.stringify(c))
- let data = k.filter(e=>{
- return e.region == this.userinfo.schoolArea || e.region == this.userinfo.orgArea
- })
- let data2 = k.filter(e=>{
- return e.region == 'cn'
- })
-
- // 如果hk,com没有图标,默认使用cn的
- if (!data[0].icon){
- data[0].icon = data2[0].icon
- data[0].activeIcon = data2[0].activeIcon
- }
- return data
- };
- },
- // 筛选是否为管理员可见,是否被删除
- appSignL(){
- return function(val){
- let data = []
- if (this.userinfo.type == 1 && this.userinfo.role == 1) {
- val.forEach( e =>{
- if (e.menuName || e.status == 0) {
- data.push(e)
- }
- })
- } else {
- val.forEach( e =>{
- if (e.menuName || (e.isAdmin == '0' && e.status == 0)) {
- data.push(e)
- }
- })
- }
- return data
- }
- },
- // 判断是否被添加过
- isAdd(){
- return function(val){
- const difference = val.filter(item1 =>
- !this.CocoFlowList.some(item2 => item1.id === item2.id)
- );
- return difference
- }
- }
- },
- data() {
- return {
- dialogVisible:false,
- //常见ai应用列表(添加弹框)
- usuallyList:[],
- loading:false,
- //选中应用列表
- tab:[],
- // 管理平台添加常见cocoFlow应用
- admincocoFlow:[],
- // 用户ai应用数组
- CocoFlowList:[],
- hovList:[],
- }
- },
- methods: {
- setHovered(index, value) {
- this.hovList.splice(index,1,value)
- },
- // 删除应用
- delApp(val){
- this.$confirm('确定删除吗', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(async () => {
- let params = [
- {
- functionName: API_CONFIG.ajax_del_usuallyApp.functionName,
- aid: val,
- },
- ];
-
- this.$ajax
- .post(API_CONFIG.baseUrl, params)
- .then(() => {
- this.$message.success('删除成功')
- this.getData()
- })
- .catch((err) => {
- console.log(err);
- this.$message.error("删除失败");
- });
-
- }).catch(() => {
- // 取消操作
- });
-
-
- },
- handleClose(){
- this.usuallyList= []
- this.tab= []
- this.dialogVisible = false
- },
- // 弹框选择添加应用
- addApp(val){
- // let data = this.CocoFlowList.filter(e=>{
- // return e.id == val
- // })
- // if (data.length != 0) return this.$message.info('常用列表已添加')
- let kpl = [...this.tab,...this.CocoFlowList]
- // console.log(kpl);
-
- const index = this.tab.indexOf(val);
- if (index !== -1) {
- this.tab.splice(index, 1); // 删除第一个匹配项
- } else {
- if (kpl.length > 3) return this.$message.info('只能添加四个常用应用哦')
- this.tab.push(val); // 添加元素到末尾
- }
- },
- // 打开常见应用弹框
- openUsuallyApp(){
- this.dialogVisible = true
- this.loading = true
- let params = [
- {
- functionName: API_CONFIG.ajax_usuallyApp.functionName,
- uid: this.userinfo.userid,
- cn: this.userinfo.schoolArea ? this.userinfo.schoolArea : this.userinfo.orgArea, //学校id
- },
- ];
-
- this.$ajax
- .post(API_CONFIG.baseUrl, params)
- .then((res) => {
- this.usuallyList = res.data[0]
- this.loading = false
- })
- .catch((err) => {
- console.log(err);
- this.loading = false
- this.$message.error("获取工具数据失败");
- });
- },
- // 添加常用确定按钮
- async addUsuallyApp(){
- const uploadYn = async files => {
- for (let index = 0; index < files.length; index++) {
- await this.XAdd(files[index]);
- console.log(index);
- }
- }
- await uploadYn(this.tab);
- console.log('完成了');
- this.getData()
- this.handleClose()
- },
- // 循环添加用户选择常见应用
- XAdd(val){
- return new Promise((resolve) => {
- let params = [
- {
- functionName: API_CONFIG.ajax_add_usuallyApp.functionName,
- oid:this.userinfo.organizeid,
- aid: val,
- uid: this.userinfo.userid,
- },
- ];
-
- this.$ajax
- .post(API_CONFIG.baseUrl, params)
- .then(() => {
- resolve(1)
- })
- .catch((err) => {
- console.log(err);
- });
- })
- },
- // 获取已添加cocoFlow应用
- getData(){
- let params = [
- {
- functionName: API_CONFIG.ajax_addedUsuallyApp.functionName,
- uid: this.userinfo.userid,
- },
- ];
-
- this.$ajax
- .post(API_CONFIG.baseUrl, params)
- .then((res) => {
- this.CocoFlowList = res.data[0]
- })
- .catch((err) => {
- console.log(err);
- this.$message.error("获取工具数据失败");
- });
- },
- getAdmincocoFlow(){
- // console.log('getAdmincocoFlow',this.fromL);
-
- // 如果后台预设常用ai工具为0则不执行
- if (this.fromL.admin.cocoFlow.length == 0) return
- let params = [
- {
- functionName: API_CONFIG.ajax_AdminApp.functionName,
- con: this.fromL.admin.cocoFlow.join(','),
- },
- ];
-
- this.$ajax
- .post(API_CONFIG.baseUrl, params)
- .then((res) => {
- this.admincocoFlow = res.data[0]
- })
- .catch((err) => {
- console.log(err);
- this.$message.error("获取工具数据失败");
- });
- },
- // 打开平台应用
- async openApp(val){
- // 点击相同应用不刷新
- if (this.appSign == val.toolId) return
- // 更新标识
- await store.commit('user/SET_AppSIGN', val.toolId)
-
- let url = ''
- val.url.forEach(e => {
- // if (e.region == this.userinfo.schoolArea || e.region == this.userinfo.orgArea) {
- if (e.region == this.$region) {
- url = e.url
- }
- });
- let _userinfo = this.userinfo, //登录用户信息
- { userid: _userid, organizeid: _oid, type: _type, org: _org, role: _role, classid: _classId } = _userinfo; // 解构赋值获取用户信息
- const _TscreenType = 1, _SscreenType = 3; // 常量定义
- let queryString = ''
- if(val.argumentList && val.argumentList.length){
- const paramsMap = {
- userid: _userid,
- org: _org,
- oid: _oid,
- tType: _type,
- role: _role,
- classId: _classId,
- TscreenType: _TscreenType,
- SscreenType: _SscreenType
- };
- const canshu = val.argumentList
- .filter(param => paramsMap[param] !== undefined)
- .map(param => `${param}=${paramsMap[param]}`);
- queryString = canshu.length ? (url.includes('?') ? '&' : '?') + canshu.join('&') : ''; // 生成查询字符串
- }
- let _url = url + queryString
- console.log('_url',_url);
- let kpl = ` <iframe
- v-if="appSign && urlAddress"
- allow= "camera *; microphone *;display-capture;midi;encrypted-media;"
- frameborder="no"
- border="0"
- style="border:0;width:100%;height:100%;"
- src="${_url}"
- ref="pageCon"
- >
- </iframe>`
- let pl = {json:kpl ,stateL :true,toolId :val.toolId}
- // this.$emit('AddAppJson',pl)
-
- this.$emit('cutUrl',pl)
-
- // document.querySelector('#pageCon').innerHTML = '';
-
- // window.topU.U.MD.D.I.openApplicationWai(val.toolId, url, dom,val.argumentList)
-
- },
- // 打开CocoFlow应用
- openNewWindow(val) {
- console.log(val);
-
- // // 基本用法:打开指定 URL
- window.open(val.url, "_blank");
- },
- },
- }
- </script>
- <style scoped>
- /* 顶部区域 */
- .topBlock{
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- }
- .topTit{
- font-size: 30px;
- height: 100%;
- color: #000;
- font-weight: 600;
- }
- .topDetail{
- color: #64748B;
- margin-top: 16px;
- }
- /* 平台应用 */
- .TabList{
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 106px; /* 网格间距 */
- margin-bottom: 16px;
- }
- .imgApp{
- width: 120px;
- height: 140px;
- object-fit: contain;
- position: absolute;
- top: 50%;
- transform: translate(0,-50%);
- left: -50px;
- }
- .TabListCon{
- width: 170px;
- height: 140px;
- padding: 24px;
- box-sizing: border-box;
- background-color: #fff;
- border-radius: 10px;
- width: 100%;
- transition: all 0.3s ease; /* 统一过渡效果 */
- /* background-image: radial-gradient(#E6F0FF 1px, transparent 1px); */
- background-size: 20px 20px;
- cursor: pointer;
- box-shadow: 0px 4px 10px 0px #0000000D;
- display: flex;
- flex-direction: column;
- justify-content: flex-end;
- align-items: end;
- }
- .TabListCon:hover{
- transform: translate(-5px,-10px); /* 向上位移 */
- box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
- }
- .TabListCon:hover TabListBri{
- -webkit-line-clamp: 2;
- width: 150px;
- }
- .TabListName{
- color: #1f2937;
- font-size: 16px;
- font-weight: 600;
- padding: 5px 0;
- margin-bottom: 4px;
- -webkit-line-clamp: 2;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .TabListBri{
- color: #4b5563;
- font-size: 12px;
- -webkit-line-clamp: 1;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .tabCon{
- transition: all 0.3s ease; /* 统一过渡效果 */
- border-radius: 10px;
- cursor: pointer;
- }
- /* 常见应用样式 */
- .footCon{
- display: flex;
- justify-content: space-between;
- box-sizing: border-box;
- border-radius: 10px;
- gap: 30px;
- margin: 80px 0;
- /* background-image: radial-gradient(#E6F0FF 1px, transparent 1px); */
- background-size: 20px 20px;
- }
- /* 图片 */
- .footConLeft{
- /* width: 360px; */
- flex: 1;
- box-sizing: border-box;
- }
- .footConLeft img{
- width: 100%;
- }
- /* 中间后面设置应用 */
- .footList{
- display: grid;
- grid-template-columns: repeat(4, 1fr);
- gap: 16px; /* 网格间距 */
- flex: 2;
- }
- .footListCon{
- background-color: #fff;
- border-radius: 10px;
- padding: 16px;
- box-sizing: border-box;
- transition: all 0.3s ease; /* 统一过渡效果 */
- height: 10vw;
- width: 10vw;
- min-height: 146px;
- max-width: 175px;
- max-height: 175px;
- background-size: 20px 20px;
- cursor: pointer;
- position: relative;
- }
- .footListCon:hover{
- transform: translate(-5px,-10px); /* 向上位移 */
- box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
- }
- .footListConimg{
- height: 40%;
- }
- .cha{
- display: none;position: absolute;top: 10px;right: 10px;
- }
- .footListCon:hover .cha{
- display: block;
- }
- /* 添加常见应用区域 */
- .footList2{
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 16px;
- flex: 1;
- position: relative;
- }
- .footList2Tit{
- position: absolute;
- top: -30px;
- left: 0;
- font-family: PingFang SC;
- color: #000;
- }
- .footListCon2{
- display: flex;
- cursor: pointer;
- justify-content: center;
- flex-direction: column;
- align-items: center;
- border: 1px dashed #000000;
- width: 10vw;
- height: 10vw;
- min-height: 146px;
- box-sizing: border-box;
- max-width: 175px;
- max-height: 175px;
- border-radius: 12px;
- border-width: 1px;
- background-color: #E5E5E5;
- }
- /* 弹框 */
- .moreDia >>> .el-dialog{
- border-radius: 10px;
- }
- .moreDia >>> .el-dialog__body{
- height: 345px;
- /* overflow: auto; */
- border-top: 1px #e7e7e7 solid;
- }
- /* 对号 */
- .top{
- display: flex;
- min-height: 144px;
- justify-content: space-between;
- background-color: #fff;
- align-items: center;
- padding: 24px;
- box-sizing: border-box;
- margin-bottom: 32px;
- border-radius: 10px;
- box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)
- }
- .AppList{
- flex-wrap: wrap;display: flex;
- justify-content: space-between;
- border: 1px rgb(243 244 246 / var(--tw-border-opacity, 1)) solid;
- border-radius: 10px;padding: 16px;box-sizing: border-box;
- position: relative;
- }
- .appImg{
- width: 48px;
- height: 48px;
- border-radius: 50%;
- object-fit: cover;
- }
- .con{
- flex: 1;
- margin-left: 12px;
- display: flex;
- flex-direction: column;
- justify-content: center;
- }
- .tit{
- color: #1f2937;font-size: 16px;height: 24px;line-height: 24px;
- -webkit-line-clamp: 1;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .bri{
- color: #6b7280;font-size: 12px;height: 16px;line-height: 16px;
- overflow: hidden;
- -webkit-line-clamp: 1;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- </style>
|