全栈工作笔记
1.el-select
聚焦问题 + 点两次才可以选择选项
<el-select name="XXX"
v-model="form.XXX" clearable style="width: 100%"
:popper-append-to-body="false" popper-class="popper-select-class"
@change="XXX">
<el-option
v-for="item in XXX"
:key="item.XXX"
:label="item.XXX"
:value="item.XXX">
</el-option>
</el-select>
如果多选框因为配置了fastclick会出现ios系统打开点击bug,这个是fastclick的错误配置 可以用如下配置在main.js中
import FastClick from 'fastclick'
// 解决手指轻触输入框不聚焦的问题
try {
let versionNumber = navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?) like mac os/)[1].replace(/_/g, '.')
if (!(/iphone|ipod|ipad/i.test(navigator.appVersion)) || Number(versionNumber) < 11) {
// 解决手指轻触输入框不聚焦的问题
var deviceIsWindowsPhone = navigator.userAgent.indexOf('Windows Phone') >= 0
var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone
FastClick.prototype.focus = function (targetElement) {
var length
// Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') {
length = targetElement.value.length
targetElement.setSelectionRange(length, length)
targetElement.focus()
} else {
targetElement.focus()
}
}
FastClick.attach(document.body)
}
} catch (e) {
console.log(e)
}
另外还需要配置一个css在对应组件的style中
.el-input .el-input__suffix {
display: none;
}
.popper-select-class{
&.el-popper{
.el-scrollbar {
> .el-scrollbar__bar {
opacity: 1 !important;
}
}
}
}
这样就能轻松解决选择框在ios的兼容性问题
Elementui的回到顶部不能用怎么办?
在入口处准备一个盒子并命名id
如
<div id="aboutUs"> <div id="top"></div> <mbAboutUsIndex v-show="this.device.isPhone"/> <!-- --> <PcIndexAboutUs v-show="this.device.isPc"/> </div>
然后在入口的vue.js中
mounted() {
document.querySelector("#top").scrollIntoView({
behavior: "smooth", // 平滑过渡
block: "start" //
});
}
不能写在
created
一定要写在
mounted才会生效
整体页面:
<script>
import MbAboutUsIndex from "@/views/FrontDesk/aboutUs/mbIndex/mbIndex.vue";
import PcIndexAboutUs from "@/views/FrontDesk/aboutUs/pcIndex/pcIndex.vue";
export default {
name:"aboutUsEntrance",
components: {PcIndexAboutUs, MbAboutUsIndex},
data(){
return{
device:{}
}
},
methods:{
getUserAgent() {
var ua = navigator.userAgent,
isWindowsPhone = /(?:Windows Phone)/.test(ua),
isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
isAndroid = /(?:Android)/.test(ua),
isFireFox = /(?:Firefox)/.test(ua),
isChrome = /(?:Chrome|CriOS)/.test(ua),
isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) ||
(isFireFox && /(?:Tablet)/.test(ua)),
isPhone = /(?:iPhone)/.test(ua) && !isTablet,
isPc = !isPhone && !isAndroid && !isSymbian;
return {
isChrome:isChrome,
isTablet: isTablet,
isPhone: isPhone,
isAndroid: isAndroid,
isPc: isPc,
};
},
},
created() {
this.device = this.getUserAgent();
},
mounted() {
document.querySelector("#top").scrollIntoView({
behavior: "smooth", // 平滑过渡
block: "start" //
});
}
}
</script>
<template>
<div id="aboutUs">
<div id="top"></div>
<mbAboutUsIndex v-show="this.device.isPhone"/>
<!-- -->
<PcIndexAboutUs v-show="this.device.isPc"/>
</div>
</template>
<style scoped lang="scss">
</style>
后端问题:
如果出现
relying upon circular references is discouraged and they are prohibited by default. update your application to remove the dependency cycle between beans. as a last resort, it may be possible to break the cycle automatically by setting spring.main.all
请不要依赖循环注入了
解决方法
OrderListService orderListService = SpringUtil.getBean(OrderListService.class)
用hutool工具包的这个方法
<!-- hutool工具 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
怎么样在没有用插槽的条件下获得el-dialog头部的按钮
this.$refs.JDialog.$el.querySelector('.el-dialog__headerbtn')
JDialog是给el-dialog的ref
2.怎么样实现滚动条定位?
如

我点第12集

怎么让右边滚动条定位到第12的索引
<div style="margin-top: 20px">
<div class="listbox1">
<span class="listbox-btn"></span>
<div class="list-hide1" ref="indexToTop">
<div class="list" v-for="(item,index) in videoList" :key='index'>
<div class="indexClass1" @click="toViewVideo(item,item.videoId)">
<div :ref="'indexToTop'+index">
<img
style="width: 5rem;height: 140px;background-color: #e5e5e5; border-bottom: 1px #92da5a solid;margin-left: .2rem"
src="http://edfront.yjkjrj.com:9000/document/img/%E5%B0%81%E9%9D%A2/default_poster.png">
<div class="text" :class="{'textAction':isAction===item.videoId}"
style="width: 5.1rem;white-space:pre-line ">{{ item.videoName }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
这是右边滚动栏的html代码
做法是给需要循环打印出来的对象,加上一个带ref的div 每个ref不同

然后上图是父类传递过来的index,就是我们需要打开的index,可以在父元素带index过来
通过refs拿到需要的index
然后设置定时器,使用this.$nextTick 保证元素在全部渲染后 this.$refs[`indexToTop${index}`][0].scrollIntoView() 这个是核心 其他的代码是我额外的需求
setTimeout(() => {
this.$nextTick(() => {
this.$refs[`indexToTop${index}`][0].scrollIntoView()
if(this.device.isPhone || this.device.isAndroid){
this.$refs.indexToTop.style.marginLeft = 50 + "px"
this.$refs.JDialog.$el.style.marginTop = 20 + "px"
if(document.documentElement.clientWidth <= 400){
this.$refs.JVideo.style.marginTop = 4.2+ "rem"
//拿到elDialog头部关闭按钮
this.$refs.JDialog.$el.querySelector('.el-dialog__headerbtn').style.marginTop = 4.2 + "rem"
}else {
this.$refs.JVideo.style.marginTop = 3.8+ "rem"
//拿到elDialog头部关闭按钮
this.$refs.JDialog.$el.querySelector('.el-dialog__headerbtn').style.marginTop = 3.8 + "rem"
}
}
})
}, 0)
3.如何阻止浏览器返回上一步,并且自定义函数(在本来要触发返回上一步的时候阻止,并且使用自己的逻辑代替返回上一步)
在需要的组件当中
mounted() {
//1.绑定事件
if (window.history && window.history.pushState) {
history.pushState(null, null, document.URL)
window.addEventListener('popstate', this.onReturnBack, false)
}
},
// 2:需要在退出页面的时候销毁这个监听事件
destroyed() {
window.removeEventListener('popstate', this.onReturnBack, false)
},
写在方法区
onReturnBack() {
// 销毁并再次创建防止多次触发 方法无效问题
window.removeEventListener('popstate', this.onReturnBack, false)
// 在 DOM 更新后执行操作
if (this.device.isPc) {
const isFlag = this.$refs.JDialogForWindow.visible
console.log(isFlag)
if (isFlag) {
this.$refs.JDialogForWindow.handlerDialogClose()
} else {
window.history.back()
}
}
if (this.device.isPhone || this.device.isAndroid) {
const isFlag = this.$refs.JDialog.visible
if (isFlag) {
this.$refs.JDialog.handlerDialogClose()
} else {
window.history.back()
}
}
//再次创建确保 多次返回上一部 不触发方法问题
history.pushState(null, null, document.URL)
window.addEventListener('popstate', this.onReturnBack, false)
}
4.minio配置https
docker run -p 9000:9000 --name minio -di --restart=always -e "MINIO_ROOT_USER=minioadmin" -e "MINIO_ROOT_PASSWORD=minioadmin" -v /usr/local/minio/data:/data -v /usr/local/minio/config:/root/.minio minio/minio:RELEASE.2021-06-17T00-10-46Z server /data
在阿里云中申请证书并且下载

此时注意,申请的证书必须和访问的域名一样
比如:申请ssl.com 则访问minio时候得用 www.ssl.com:端口号 否则会出现证书不安全情况
然后注意我们在docker中部署的minio中的一句话/usr/local/minio/config:/root/.minio
这个里面的config里面 有一个文件夹certs linux中 /根目录/usr/local/minio/config/certs
申请的证书为:

红线为:
生成域名对应的 SSL证书,并将私钥和证书重命名为 private.key 和 public.crt ,即将XXX.key和XXX.crt改为 private.key 和 public.crt 。
并将放入private.key 和 public.crt放/usr/local/minio/config/certs 然后重启minio即可
如何修改ollama配置
sudo vim /etc/systemd/system/ollama.service
前端后端怎么docker部署?
linux中文件:
![]()
config中:

Dockerfile:
# 使用官方的OpenJDK 17镜像作为基础镜像
FROM openjdk:17
# 系统工作目录
RUN mkdir -p /data/testCase/
RUN chmod -R 777 /data/testCase/
# 管理后台工作目录
RUN mkdir -p /data/testCase
RUN chmod -R 777 /data/testCase
# 设置工作目录
WORKDIR /data/testCase
# 为JAR包运行命令
CMD ["java","-Dspring.profiles.active=prod", "-jar","-Duser.timezone=Asia/Shanghai","testCase-0.0.1-SNAPSHOT.jar"]
docker-compose.yml
services:
main:
image: testcase-backend:latest
network_mode: "host"
privileged: true
volumes:
- /data/testCase/:/data/testCase/
- /data/testCase/logs/:/data/testCase/logs/
readme.md
cd /data/testCase/
sudo docker build -f Dockerfile -t testcase-backend .
cd /data/testCase/
sudo docker-compose up -d
```
后端路径

其中logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!-- 定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
<property name="LOG_HOME" value="./logs"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天和大小生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名格式 -->
<fileNamePattern>${LOG_HOME}/app-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!-- 单个日志文件最大大小 -->
<maxFileSize>10MB</maxFileSize>
<!-- 日志文件保留天数 -->
<maxHistory>30</maxHistory>
<!-- 所有日志文件的总大小上限 -->
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
前端:
![]()
其中nginx中

default.conf
server {
listen 8888;
server_name localhost;
charset utf-8;
access_log /var/log/nginx/host.access.log main;
error_log /var/log/nginx/error.log error;
client_max_body_size 1024m;
# 安全头配置
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
# 主要 location 块 - 修复权限和路径问题
location / {
# CORS 配置
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
# 关键修复:确保路径正确且有权限
root /data/testCaseVue/dist;
index index.html index.htm;
# 单页应用路由支持 - 修复 try_files
try_files $uri $uri/ /index.html;
}
# Assets 配置 - 简化并确保正确
location /assets/ {
alias /data/testCaseVue/dist/assets/;
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
# 确保能正确处理文件
try_files $uri $uri/ =404;
}
# 后端 API 代理配置
location ^~/api/ {
proxy_pass http://localhost:9090/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache off;
proxy_buffering off;
chunked_transfer_encoding on;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
proxy_intercept_errors on;
}
# 错误页面配置
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 静态文件缓存优化 - 修复正则表达式
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
root /data/testCaseVue/dist;
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
# 确保能找到文件
try_files $uri =404;
}
}
nginx.conf
server {
listen 80;
server_name localhost;
charset utf-8;
error_page 500 502 503 504 /50x.html;
location / {
root /etc/nginx/html/;
try_files $uri /index.html;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
dockerfile:
FROM nginx:latest
# COPY dist/ /usr/share/nginx/html/
# COPY nginx/default.conf /etc/nginx/conf.d/testCase.conf
RUN mkdir -p /data/testCaseVue/
RUN chmod -R 777 /data/testCaseVue/
docker-compose.yml
services:
main:
image: test-case-vue:latest
network_mode: "host"
privileged: true
volumes:
- ./:/data/testCaseVue/
- ./nginx/default.conf:/etc/nginx/conf.d/testCase.conf
然后在 /etc/nginx/conf.d中,目前我是让这个尽量和default.conf保持一样的内容
![]()
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)