2024-08-25

以下是一个简化的Spring Boot后端实现WebSocket聊天功能的代码示例:




import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.handler.TextWebSocketHandler;
 
import java.util.concurrent.ConcurrentHashMap;
 
public class ChatWebSocketHandler extends TextWebSocketHandler {
 
    private static final ConcurrentHashMap<String, WebSocketSession> users = new ConcurrentHashMap<>();
 
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        users.put(session.getId(), session);
        System.out.println("新用户加入:" + session.getId());
    }
 
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        System.out.println("收到消息:" + payload);
        // 广播消息
        users.values().forEach(user -> {
            try {
                user.sendMessage(new TextMessage(payload));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
 
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        users.remove(session.getId());
        System.out.println("用户已离开:" + session.getId());
    }
}

在Spring Boot中配置WebSocket的配置类:




import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.*;
 
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
 
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(chatWebSocketHandler(), "/chat-endpoint")
                .setAllowedOrigins("*");
    }
 
    @Bean
    public ChatWebSocketHandler chatWebSocketHandler() {
        return new ChatWebSocketHandler();
    }
}

前端HTML和JavaScript代码示例:




<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Chat</title>
</head>
<body>
    <div>
        <input type="text" id="messageText" />
        <button onclick="sendMessage()">Send</button>
    </div>
    <div id="chatWindow">
        <!-- Messages will appear here -->
    </div>
 
    <script>
        var ws;
        function connect() {
            ws = new WebSocket("ws://localhost:8080/chat-endpoint");
            ws.onmessage = function(event) {
2024-08-25



import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.WriterProperties;
import com.itextpdf.layout.element.IBlockElement;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.licensing.base.LicenseKey;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
 
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
 
@Service
public class PdfService {
 
    private final ResourceLoader resourceLoader;
 
    public PdfService(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
 
    public byte[] generatePdfFromHtml(String htmlTemplatePath, Map<String, Object> data) throws IOException {
        // 加载HTML模板
        Resource resource = resourceLoader.getResource("classpath:" + htmlTemplatePath);
        String htmlContent = new String(Files.readAllBytes(resource.getFile().toPath()), StandardCharsets.UTF_8);
 
        // 替换模板中的占位符
        String filledHtml = FreeMarkerTemplateUtils.processTemplateIntoString(
                new Template("templateName", new String(htmlContent)), data);
 
        // 使用iText HtmlConverter将HTML转换为PDF
        ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
        HtmlConverter.convertToPdf(filledHtml, pdfOutputStream);
 
        return pdfOutputStream.toByteArray();
    }
}

这段代码示例展示了如何在Spring Boot应用中使用iText库的HtmlConverter类将HTML转换为PDF格式。首先,代码通过Spring的ResourceLoader加载HTML模板文件,然后使用FreeMarker模板引擎进行数据替换。接下来,HtmlConverter的convertToPdf方法被调用,HTML内容被转换为PDF格式,最终以字节流的形式返回。

2024-08-25

在Visual Studio Code (VScode) 中配置 HTML 环境主要涉及以下几个步骤:

  1. 安装必要的扩展:

    打开 VScode,在左侧的扩展商店中搜索并安装以下扩展:

    • HTML Snippets:提供 HTML 的代码提示。
    • HTML CSS Support:提供 CSS 代码提示和补全。
    • Live Server:提供一个简易的本地服务器,并能够在保存文件时自动刷新页面。
  2. 配置 settings.json

    打开 VScode 的设置(快捷键 Ctrl + ,Cmd + ,),在用户设置中添加以下配置:

    
    
    
    {
        "emmet.includeLanguages": {
            "html": "html"
        },
        "files.associations": {
            "*.html": "html"
        }
    }
  3. 创建 HTML 文件并编写基本的 HTML 结构:

    在 VScode 中新建一个 .html 文件,例如 index.html,然后输入以下基本结构:

    
    
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <h1>Hello, World!</h1>
    </body>
    </html>
  4. 保存文件,并使用 Live Server 打开:

    右键点击编辑器中的 HTML 文件,选择 Open with Live Server,这样会在浏览器中打开您的页面,并且在每次保存文件时自动刷新。

以上步骤配置了一个基本的 HTML 环境,您可以开始编写和测试您的 HTML 页面。

2024-08-25

Docker的基本指令包括:

  1. 创建容器:docker run [options] image [command]
  2. 列出容器:docker ps [options]
  3. 停止容器:docker stop [options] container [container...]
  4. 删除容器:docker rm [options] container [container...]
  5. 构建镜像:docker build [options] path
  6. 列出镜像:docker images [options]
  7. 删除镜像:docker rmi [options] image [image...]

以下是使用Docker创建一个简单的Python应用的示例:

首先,创建一个名为 Dockerfile 的文件,内容如下:




# 使用官方Python运行环境作为父镜像
FROM python:3.8-slim
 
# 设置工作目录
WORKDIR /app
 
# 将当前目录内容复制到工作目录
COPY . /app
 
# 安装requirements.txt中指定的依赖
RUN pip install --no-cache-dir -r requirements.txt
 
# 设置运行时执行的命令
CMD ["python", "app.py"]

然后,在同一目录下创建一个 requirements.txt 文件,列出应用的依赖,例如:




flask

最后,创建你的Python应用程序 app.py




from flask import Flask
 
app = Flask(__name__)
 
@app.route('/')
def hello_world():
    return 'Hello, Docker!'
 
if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

构建并运行Docker容器:




docker build -t python-app .
docker run -d -p 5000:5000 python-app

访问 http://localhost:5000 查看你的应用运行情况。

对于C++应用,首先需要你有一个编译好的可执行文件,然后创建一个简单的 Dockerfile




FROM ubuntu:18.04
 
# 安装C++运行时依赖
RUN apt-get update && apt-get install -y g++
 
# 将本地的可执行文件复制到镜像中
COPY ./my_cpp_app /usr/bin/my_cpp_app
 
# 设置容器启动时执行的命令
CMD ["/usr/bin/my_cpp_app"]

构建并运行:




docker build -t cpp-app .
docker run cpp-app

对于HTML应用,你可以使用一个轻量级的HTTP服务器如 http-server 来提供静态文件:




FROM node:12-alpine
 
# 安装http-server
RUN npm install -g http-server
 
# 将HTML文件复制到镜像中
COPY ./my_html_app /usr/share/http-server/
 
# 设置工作目录
WORKDIR /usr/share/http-server/
 
# 设置容器启动时执行的命令
CMD ["http-server"]

构建并运行:




docker build -t html-app .
docker run -d -p 8080:8080 html-app

访问 http://localhost:8080 查看你的HTML应用。

2024-08-25

flex: 1; 是CSS样式中的Flexbox布局属性,用于分配容器内的可用空间。当子元素的高度较高时,父容器将会被撑开以适应子元素的高度。

如果你希望在子元素高度较高时展示滚动条而不是撑开父元素,你可以使用以下CSS样式:




.parent {
  display: flex;
  overflow: auto; /* 添加滚动条 */
}
 
.child {
  flex: 1;
  min-height: 0; /* 防止flex项目被最小高度min-height:0的项目撑开 */
}

HTML结构如下:




<div class="parent">
  <div class="child">
    <!-- 子元素内容 -->
  </div>
</div>

这样设置后,当子元素的高度超出父容器时,父容器将展示滚动条而不是撑开。

2024-08-25

在Web页面中实现动画效果,可以使用以下几种方法:

  1. CSS动画:使用CSS的@keyframes规则定义动画,然后将其应用到元素上。



@keyframes example {
  from { background-color: red; }
  to { background-color: yellow; }
}
 
@-webkit-keyframes example {
  from { background-color: red; }
  to { background-color: yellow; }
}
 
.animatedBox {
  animation-name: example;
  animation-duration: 4s;
  animation-fill-mode: forwards;
}
  1. JavaScript动画:使用JavaScript结合requestAnimationFramesetInterval来实现动画。



function animate(element, property, start, end, duration) {
  let startTime = performance.now();
  
  const step = (timestamp) => {
    if (!startTime) startTime = timestamp;
    const progress = Math.min((timestamp - startTime) / duration, 1);
    element.style[property] = (progress * (end - start)) + start + 'px';
    if (progress < 1) {
      window.requestAnimationFrame(step);
    }
  };
  
  window.requestAnimationFrame(step);
}
 
const box = document.querySelector('.box');
animate(box, 'width', 10, 200, 2000); // 动画从10px宽度变到200px宽度
  1. 使用第三方库:如GreenSock Animation Platform (GSAP)、anime.js等。



anime({
  targets: '.box',
  width: 200,
  easing: 'easeInOutQuad',
  duration: 2000
});

以上是实现动画效果的几种方法,具体使用哪种取决于项目需求和开发偏好。

2024-08-25



<template>
  <div class="transition-box" :style="{ width: boxWidth + 'px', height: boxHeight + 'px' }">
    <!-- 内容 -->
  </div>
</template>
 
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
 
const boxWidth = ref(200);
const boxHeight = ref(200);
 
function handleResize() {
  boxWidth.value = window.innerWidth / 2;
  boxHeight.value = window.innerHeight / 2;
}
 
onMounted(() => {
  window.addEventListener('resize', handleResize);
  handleResize(); // 初始化尺寸
});
 
onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
});
</script>
 
<style>
.transition-box {
  transition: width 0.3s, height 0.3s;
  background-color: #42b983;
}
</style>

这段代码使用Vue 3的Composition API创建了一个响应窗口尺寸变化的方形div。当窗口大小变化时,handleResize函数会更新boxWidthboxHeight的值,并且Vue的响应式系统会自动更新DOM。CSS中的过渡效果会让尺寸的变化看起来平滑自然。

2024-08-25

在Vue中,你可以使用内置指令如v-ifv-show来创建类似于collapse的左侧菜单栏。以下是一个简单的例子:




<template>
  <div>
    <div :class="{'sidebar-collapsed': isCollapsed}" class="sidebar">
      <!-- 菜单内容 -->
      <div class="menu-items">
        <button @click="toggleMenu">Toggle Menu</button>
        <!-- 菜单项 -->
        <div v-show="!isCollapsed">
          <p>Menu Item 1</p>
          <p>Menu Item 2</p>
          <p>Menu Item 3</p>
        </div>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      isCollapsed: false
    };
  },
  methods: {
    toggleMenu() {
      this.isCollapsed = !this.isCollapsed;
    }
  }
};
</script>
 
<style>
.sidebar {
  width: 200px; /* 左侧菜单宽度 */
  height: 100vh; /* 左侧菜单高度 */
  background-color: #3498db; /* 左侧菜单背景色 */
  transition: width 0.3s; /* 过渡动画 */
}
 
.sidebar-collapsed {
  width: 50px; /* 菜单折叠后的宽度 */
}
 
.menu-items {
  padding: 20px;
}
</style>

在这个例子中,我们定义了一个名为isCollapsed的数据属性来控制菜单的折叠状态。通过点击按钮,触发toggleMenu方法来切换isCollapsed的值,从而实现菜单栏的折叠和展开。CSS部分定义了折叠和展开两种状态下的样式。

你可以根据自己的需求调整样式和内容。

2024-08-25

在Vue 3中,内置的<Transition>组件可以用来包装需要过渡效果的元素,它会在元素的出现和消失过程中自动应用CSS效果。

下面是一个简单的例子,展示如何使用<Transition>组件:




<template>
  <button @click="show = !show">
    Toggle
  </button>
  <Transition name="fade">
    <p v-if="show">Hello World!</p>
  </Transition>
</template>
 
<script setup>
import { ref } from 'vue'
 
const show = ref(true)
</script>
 
<style>
/* 定义进入和退出的过渡效果 */
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s ease;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
</style>

在这个例子中,一个段落(<p>)通过v-if指令与show变量绑定,show变量的值通过按钮点击事件进行切换。<Transition>组件包裹了这个段落,并通过name属性指定了过渡的效果类名前缀"fade"。CSS中定义了两个类:.fade-enter-active.fade-leave-active用于指定进入和退出过渡的状态,而.fade-enter-from.fade-leave-to定义了初始状态和结束状态的样式。当show变量为true时显示段落,为false时段落消失,并应用淡入淡出的过渡效果。

2024-08-25

要使用原生JavaScript实现抽屉动画,你可以创建一个函数,该函数使用setIntervalrequestAnimationFrame来逐渐改变元素的CSS属性,从而创建平滑的动画效果。

以下是一个简单的例子,演示了如何使用requestAnimationFrame来实现一个抽屉动画:

HTML:




<div id="drawer" style="width: 200px; height: 100px; background-color: blue; transition: transform 0.5s; transform: translateX(0);">
  <!-- 抽屉内容 -->
</div>
<button id="toggleButton">Toggle Drawer</button>

CSS:




#drawer {
  transform: translateX(-200px); /* 初始时抽屉在容器外 */
}

JavaScript:




const drawer = document.getElementById('drawer');
const toggleButton = document.getElementById('toggleButton');
let isOpen = false;
 
toggleButton.addEventListener('click', () => {
  isOpen = !isOpen;
  animateDrawer(isOpen);
});
 
function animateDrawer(isOpen) {
  const start = isOpen ? -200 : 0; // 抽屉的起始和结束位置
  const end = isOpen ? 0 : -200;
  const distance = end - start;
  let isAnimating = true;
 
  requestAnimationFrame(function animate(time) {
    if (!isAnimating) return;
 
    const progress = (time - lastTime) / duration; // 使用当前时间和起始时间计算进度
    const position = start + distance * easeInOutQuad(progress); // 应用缓动函数计算当前位置
    drawer.style.transform = `translateX(${position}px)`;
 
    if (progress < 1) {
      requestAnimationFrame(animate); // 如果动画未完成,继续调用requestAnimationFrame
    } else {
      isAnimating = false; // 动画完成
    }
  });
}
 
// 缓动函数,控制动画的加速和减速
function easeInOutQuad(t) {
  return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}

在这个例子中,我们定义了一个animateDrawer函数,它接受一个布尔值isOpen来确定抽屉是打开还是关闭。使用requestAnimationFrame来迭代变换抽屉的transform属性,从而创建平滑的动画效果。我们还定义了一个easeInOutQuad函数来实现缓动效果,这样抽屉的打开和关闭就会有一个更自然的感觉。