rkljw 8 ay önce
ebeveyn
işleme
73ed647a18

+ 1 - 0
.htaccess

@@ -0,0 +1 @@
+ 

+ 26 - 0
404.html

@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>404</title>
+<style>
+	body{
+		background-color:#444;
+		font-size:14px;
+	}
+	h3{
+		font-size:60px;
+		color:#eee;
+		text-align:center;
+		padding-top:30px;
+		font-weight:normal;
+	}
+</style>
+</head>
+
+<body>
+<h3>404锛屾偍璇锋眰鐨勬枃浠朵笉瀛樺湪!</h3>
+</body>
+</html>

+ 40 - 0
index.html

@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>恭喜,站点创建成功!</title>
+    <style>
+
+        .container {
+            width: 60%;
+            margin: 10% auto 0;
+            background-color: #f0f0f0;
+            padding: 2% 5%;
+            border-radius: 10px
+        }
+
+        ul {
+            padding-left: 20px;
+        }
+
+            ul li {
+                line-height: 2.3
+            }
+
+        a {
+            color: #20a53a
+        }
+    </style>
+</head>
+<body>
+    <div class="container">
+        <h1>恭喜, 站点创建成功!</h1>
+        <h3>这是默认index.html,本页面由系统自动生成</h3>
+        <ul>
+            <li>本页面在FTP根目录下的index.html</li>
+            <li>您可以修改、删除或覆盖本页面</li>
+            <li>FTP相关信息,请到“面板系统后台 > FTP” 查看</li>
+        </ul>
+    </div>
+</body>
+</html>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1273 - 1628
package-lock.json


+ 1 - 6
package.json

@@ -13,20 +13,15 @@
   "dependencies": {
     "@element-plus/icons": "0.0.11",
     "@element-plus/icons-vue": "^0.2.4",
-    "@wangeditor/editor": "^5.1.23",
-    "@wangeditor/editor-for-vue": "^1.0.2",
     "axios": "^0.24.0",
     "can-autoplay": "^3.0.2",
     "element-plus": "^1.2.0-beta.3",
     "element-resize-detector": "^1.2.4",
-    "element-tiptap": "^2.2.1",
     "element-ui": "^2.15.10",
     "less": "^4.1.2",
     "lodash": "^4.17.21",
     "moment": "^2.29.2",
-    "quill": "^2.0.2",
-    "quill-image-drop-module": "^1.0.3",
-    "quill-image-resize-module": "^3.0.0",
+    "socket.io-client": "^4.7.5",
     "sortablejs": "^1.15.0",
     "speak-tts": "^2.0.8",
     "unplugin-vue-components": "^0.17.2",

+ 1 - 0
public/index.html

@@ -5,6 +5,7 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <script src="https://cdn.bootcdn.net/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
     <title><%= htmlWebpackPlugin.options.title %></title>
       <style>
           #app{

+ 6 - 7
src/App.vue

@@ -28,17 +28,16 @@ export default {
     },
     activity() {
       return this.$route.meta.activity
-    },
-    // action(){
-    //   return this.$route.meta.action
-    // }
-
+    }
   },
   watch: {
         $route(to, from) {
+            console.log("to:::::::::::",to)
             // to 和 from 都是 路由信息对象
-            if(to.path!='/login'){
-                this.action = true
+            if(to.path=='/login'){
+                this.action = false
+            }else{
+              this.action = true
             }
   
         } 

+ 9 - 0
src/api/chat.js

@@ -0,0 +1,9 @@
+import { request } from '@/axios/request'
+
+export default {
+
+  getTalkSessionList (parames) {
+    return request.get("/chat/getTalkSessionList",parames)
+  },
+
+}

+ 2 - 0
src/api/index.js

@@ -9,6 +9,7 @@ import publicApi from "@/api/public"
 import news from "@/api/news"
 import link from "@/api/link"
 import ad from "@/api/ad"
+import chat from "@/api/chat"
 export default {
     user,//用户已
     login, //登录
@@ -19,4 +20,5 @@ export default {
     news,// 资讯
     link,//友情链接
     ad,//广告位
+    chat,//会话
 }

+ 3 - 1
src/api/pub.js

@@ -3,6 +3,8 @@ import {request} from '@/axios/request'
 export default {
     getMenuList(){
         return request.get("/authority/getRecursionMenu")
+    },
+    verifyCode(){
+        return request.get("/verifyCode")
     }
-    
 }

+ 2 - 1
src/components/PageHeader.vue

@@ -92,7 +92,8 @@ export default {
   methods: {
     logoutClick() {
       document.setCookie("token",'',0)
-      this.$router.push("/login")
+      window.location.href="/#/login";
+      
       // popup.postMessage({ type: 'layOut' }, '/')
     },
     // goChat() {

+ 13 - 3
src/router/index.js

@@ -141,7 +141,7 @@ const routes = [{
             } ,
             {
                 meta: {
-                    action: "adList/:pid?",
+                    action: "adList",
                     title: '广告'
                 },
                 path: 'adList/:pid?',
@@ -149,7 +149,16 @@ const routes = [{
                 component: () =>
                     import ('@views/ad/index.vue')
             } ,
-           
+            {
+                meta: {
+                    action: "chat",
+                    title: '聊天'
+                },
+                path: 'chat',
+                name: 'chat',
+                component: () =>
+                    import ('@views/chat/index.vue')
+            } ,
            
         ]
     },
@@ -165,7 +174,8 @@ const routes = [{
         path: '/login',
         name: 'login',
         component: () =>
-            import ('@views/login/index.vue')
+            import ('@views/login/index.vue'),
+    
     }
 ]
 

+ 23 - 4
src/utils/config.js

@@ -1,13 +1,12 @@
 // 根据打包环境配置接口地址
 let reqSmbUrl
-export let javaUrl
-export let javaApi
+export let websocketUrl
 export let appKey
-export let phpApi
-export let phpAdmin
+
 console.log('判断接口地址',process.env.NODE_ENV, process.env)
 if (process.env.NODE_ENV) {
     if (process.env.VUE_APP_FLAG == 'development') {
+<<<<<<< HEAD
         reqSmbUrl = 'http://192.168.1.102:9501'
         appKey = 'cpj2xarlcmmpn'
        
@@ -21,10 +20,30 @@ if (process.env.NODE_ENV) {
         
     } else if (process.env.VUE_APP_FLAG == 'testsec') {
         reqSmbUrl = 'http://192.168.1.102:9501'
+=======
+        reqSmbUrl = 'http://192.168.1.193:9501'
+        websocketUrl = 'ws://192.168.1.193:9506'
+        appKey = 'cpj2xarlcmmpn'
+       
+    } else if (process.env.VUE_APP_FLAG == 'test') {
+        reqSmbUrl = 'http://192.168.1.193:9501'
+        websocketUrl = 'ws://192.168.1.193:9506'
+        appKey = 'cpj2xarlcmmpn'
+       
+    } else if (process.env.VUE_APP_FLAG == 'uat') {
+        reqSmbUrl = 'http://192.168.1.193:9501'
+        websocketUrl = 'ws://192.168.1.193:9506'
+        appKey = 'pkfcgjstp8zy8'
+        
+    } else if (process.env.VUE_APP_FLAG == 'testsec') {
+        reqSmbUrl = 'http://192.168.1.193:9501'
+        websocketUrl = 'ws://192.168.1.193:9506'
+>>>>>>> 2260fe8b50d15849a1178fe770c9b1bba517afb6
         appKey = 'cpj2xarlcmmpn'
         
     } else if (process.env.VUE_APP_FLAG == 'prod') {
         reqSmbUrl = '/'
+        websocketUrl = 'ws://192.168.1.193:9506'
         appKey = 'pkfcgjstp8zy8'
        
     }

+ 145 - 0
src/views/chat/index.vue

@@ -0,0 +1,145 @@
+<template>
+  <el-container style="height: 100vh;">
+    <el-aside width="300px" style="background: #f2f2f2;">
+      <el-menu>
+        <div class="conversation-list">会话记录(100)</div>
+        <el-menu-item 
+          v-for="conversation in conversations" 
+          :key="conversation.session_id"
+          @click="selectConversation(conversation)"
+          :class="{ 'is-active': activeConversation && activeConversation.session_id === conversation.session_id }">
+          <div v-if="conversation.talk_type==1">
+            <el-avatar :src=conversation.user_avatar>{{ conversation.nickname }}</el-avatar> {{ conversation.nickname }}
+          </div>
+          <div v-if="conversation.talk_type==2">
+            <el-avatar :src=conversation.group_avatar>{{ conversation.group_name }}</el-avatar> {{ conversation.group_name }}
+          </div>
+         
+        </el-menu-item>
+      </el-menu>
+    </el-aside>
+
+    <el-container>
+      <el-main style="padding: 20px;">
+        <div v-if="activeConversation">
+          <div v-for="(message, index) in activeConversation.messages" :key="index"  class="message">
+            <div v-if="message.is_me==1" :class="{'is_me':message.is_me==1}">
+               {{ message.content }} <el-avatar :src=message.user_avatar>{{ message.nickname }}</el-avatar>
+            </div>
+            <div  v-else>
+              <el-avatar :src=message.user_avatar>{{ message.nickname }}</el-avatar>{{ message.content }}
+
+            </div>
+          </div> 
+        </div>
+        <div v-else>
+          请选择一个会话
+        </div>
+      </el-main>
+
+      <el-footer height="60px" style="padding: 10px; background: #fff;">
+        <el-input 
+          v-model="newMessage" 
+          placeholder="输入消息..."
+          @keyup.enter="sendMessage"
+          style="width: calc(100% - 100px); margin-right: 10px;">
+        </el-input>
+        <el-button @click="sendMessage" type="primary">发送</el-button>
+      </el-footer>
+    </el-container>
+  </el-container>
+</template>
+
+<script>
+import { websocketUrl } from '../../utils/config'
+export default {
+  data() {
+    return {
+      activeConversation: null,
+      newMessage: '',
+      conversations: [
+       
+      ],
+      ws: null
+    };
+  },
+  methods: {
+    selectConversation(conversation) {
+      this.activeConversation = conversation;
+    },
+    sendMessage() {
+      if (this.newMessage.trim() !== '') {
+
+        //msg_type 消息类型  talk_type:聊天类型 1单聊 2群聊
+        const message = { msg_type:1,
+          talk_type:this.activeConversation.talk_type,
+          content:this.newMessage,
+          session_id:this.activeConversation.session_id,
+          msg_type:1,
+          receiver_id:this.activeConversation.user_id?this.activeConversation.user_id:this.activeConversation.group_id
+        };
+        // this.activeConversation.messages.push(message);
+        console.log("发送消息",this.ws,WebSocket.OPEN)
+        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
+          this.ws.send(JSON.stringify(message));
+        }
+        this.newMessage = '';
+      }
+    },
+    handleIncomingMessage(event) {
+      const message = JSON.parse(event.data);
+      console.log("监听消息:",message)
+      const conversation = this.conversations.find(conv => conv.session_id === message.session_id); // 假设所有消息都发送给Alice
+      if (conversation) {
+        conversation.messages.push(message);
+      }
+    },
+    //获取会话列表
+    getTalkSessionList(){
+      let parames  = {
+        'page':1,
+        'pageSize':10
+      }
+      this.$api.chat.getTalkSessionList(parames).then(res=>{
+          this.conversations =  res.data.row
+      });
+    },
+  },
+  mounted() {
+    let websocketNewUrl = websocketUrl+"?token="+decodeURIComponent(document.getCookie("token"))
+    this.ws = new WebSocket(websocketNewUrl);
+    this.ws.addEventListener('message', this.handleIncomingMessage);
+
+    this.ws.addEventListener('close', function (event) {
+        // 连接关闭时执行的操作
+        console.log("关闭链接",event)
+      });
+
+      this.getTalkSessionList()
+  },
+  beforeDestroy() {
+    if (this.ws) {
+      this.ws.removeEventListener('message', this.handleIncomingMessage);
+      this.ws.close();
+    }
+  }
+};
+</script>
+
+<style>
+body {
+  margin: 0;
+}
+.message {
+  margin: 10px 0;
+}
+.conversation-list{
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+
+}
+.is_me{
+  text-align:right;
+}
+</style>

+ 24 - 7
src/views/login/index.vue

@@ -9,8 +9,10 @@
           <el-input type="password" v-model="loginForm.password"></el-input>  
         </el-form-item>  
         <el-form-item label="验证码" prop="captcha">  
-          <el-input v-model="loginForm.captcha"></el-input>  
-          <!-- <img class="captcha-img" src="your-captcha-api-url" alt="captcha" @click="getCaptcha" />   -->
+          <div class="codeDiv">
+          <el-input v-model="loginForm.captcha" class="code"></el-input>  
+          <img class="captcha-img" :src="imgUrl" alt="点击验证码" @click="getCaptcha" />  
+          </div>
         </el-form-item>  
         <el-form-item>  
           <el-button type="primary" @click="handleSubmit">登录</el-button>  
@@ -24,6 +26,7 @@
   export default {  
     data() {  
       return {  
+        imgUrl:'',
         loginForm: {  
           username: '',  
           password: '',  
@@ -42,11 +45,11 @@
         }  
       }  
     },  
+
     methods: {  
       handleSubmit() {  
         this.$refs.loginForm.validate(valid => {  
           if (valid) {  
-
             let parames={
                 username:this.loginForm.username,
                 password:this.loginForm.password,
@@ -62,7 +65,7 @@
                   this.$message.success('登录成功')
                    this.$router.push("/left/websiteList")
                 }else{
-                    this.$message.error("登录失败")
+                    this.$message.error(res.message)
                 }
             })
             // 这里可以添加登录逻辑,例如发送请求到后端进行验证  
@@ -77,8 +80,15 @@
         // 这里添加获取新验证码的逻辑,通常会调用后端API来获取新验证码图片并更新img的src  
         // 例如: this.captchaImgSrc = 'your-new-captcha-api-url';  
         // 注意:为了简单起见,这里没有直接实现这个逻辑  
+
+        this.$api.pub.verifyCode().then(res=>{
+            this.imgUrl = res
+        })
       }  
-    }  
+    },
+    created () {
+      this.getCaptcha()
+    } 
   }  
   </script>  
     
@@ -95,13 +105,20 @@
   .login-title {  
     margin-bottom: 20px;  
   }  
-    
+  .codeDiv {
+    display: flex;
+  }
+
   .login-form {  
     margin-bottom: 20px;  
   }  
-    
+  .login-form .code{
+    width: 100px;
+  }
   .captcha-img {  
     cursor: pointer;  
     margin-left: 10px;  
+    width: 96px;
+    height: 40px;;
   }  
   </style>

+ 41 - 2
src/views/role/components/authority.vue

@@ -9,10 +9,12 @@
         show-checkbox
         node-key="id"
         ref="tree"
+        check-strictly="true"
         highlight-current
         default-expand-all="true"
         :props="defaultProps"
         :default-checked-keys="rule"
+        @check="handleCheck"
         >
         </el-tree>
     </el-form-item>
@@ -73,8 +75,8 @@
       },
       authorityList(){
         let _t= this
-      let parames = {}
-      this.$api.authority.getRecursionMenu(parames).then(res=>{
+        let parames = {}
+        this.$api.authority.getRecursionMenu(parames).then(res=>{
                 if(res.code==200){
                    console.log(res.data)
                   _t.data = res.data
@@ -82,7 +84,44 @@
                     this.$message.error("查询失败")
                 }
             })
+      },
+      handleCheck(data, checked, indeterminate) {
+      const checkedKeys = this.$refs.tree.getCheckedKeys();
+      // const halfCheckedKeys = this.$refs.tree.getHalfCheckedKeys();
+      // 将所有选中的节点的父节点也选中
+      checkedKeys.forEach(key => {
+        const parent = this.findParent(key, this.data);
+        if (parent) {
+          checkedKeys.push(parent.id);
+        }
+      });
+      // 将所有半选中的节点的父节点也选中
+      halfCheckedKeys.forEach(key => {
+        const parent = this.findParent(key, this.data);
+        if (parent) {
+          checkedKeys.push(parent.id);
+        }
+      });
+      // 去除重复的节点
+      const uniqueKeys = [...new Set(checkedKeys)];
+      // 处理uniqueKeys,进行后续操作,例如传递值等
+      console.log(uniqueKeys);
+      this.data = uniqueKeys
+    },
+    findParent(id, data) {
+      for (let i = 0; i < data.length; i++) {
+        if (data[i].id === id) {
+          return null;
+        }
+        if (data[i].children) {
+          const parent = this.findParent(id, data[i].children);
+          if (parent) {
+            return parent;
+          }
+        }
       }
+      return null;
+    }
     }
   }
   </script>

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor