dev #12

Merged
hy merged 3 commits from dev into staging 2025-08-27 10:12:19 +08:00
4 changed files with 138 additions and 13 deletions

View File

@ -0,0 +1,41 @@
# 构建阶段
FROM m.daocloud.io/docker.io/library/node:22.14.0 AS builder
# 设置工作目录
WORKDIR /app
# 设置 npm 镜像源
RUN npm config set registry https://registry.npmmirror.com/
RUN npm config set fetch-retries 3
RUN npm config set fetch-retry-mintimeout 5000
RUN npm config set fetch-retry-maxtimeout 60000
# 安装pnpm
RUN npm install -g pnpm
# 复制源代码
COPY . .
# 设置 pnpm 下载源
RUN pnpm config set registry https://registry.npmmirror.com/
# 安装依赖
RUN pnpm i --fetch-timeout 300000
# 构建项目
RUN pnpm build
# 部署阶段
FROM m.daocloud.io/docker.io/library/nginx:alpine
# 复制构建产物到 Nginx 目录
COPY --from=builder --chown=nginx:nginx /app/dist /usr/share/nginx/html
# 复制 Nginx 配置
COPY Dockerfiles/Dockerfile-staging/default.conf /etc/nginx/conf.d/default.conf
# 暴露端口
EXPOSE 80
# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,47 @@
server {
listen 80;
server_name localhost;
# 基础设置
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
client_max_body_size 100m;
# 错误页面配置
error_page 500 502 503 504 /50x.html;
location = /50x.html {
internal; # 仅用于内部错误请求
}
# Gzip 压缩设置
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css text/javascript application/json
application/javascript application/x-javascript application/xml;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
# 静态资源缓存优化
location ~* \.(jpg|jpeg|gif|ico|css|js)$ {
expires 7d;
add_header Cache-Control "public, no-transform";
}
# API 代理配置
location /api/ {
proxy_pass http://learn-archives-api-svc:8080/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_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering on;
}
}

View File

@ -49,6 +49,27 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学生类型" prop="studentType">
<el-select
v-model="form.studentType"
filterable
placeholder="学生类型"
style="width: 180px"
>
<el-option
v-for="(item, i) in studentTypeEnum"
:key="i"
autocomplete="off"
:label="item.text"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="申请减免" prop="amountRelief">
<el-switch v-model="form.reliefApplication" />
</el-form-item>
@ -95,7 +116,7 @@
</div>
</el-col>
</el-row>
<!-- 选修方向 -->
<el-row class="pb-4.5">
<el-col :span="24">
<div style="display: flex; gap: 10px">
@ -260,6 +281,7 @@ interface FormData {
exitTime?: string;
joinTime?: string;
remark?: string;
studentType?: number;
status?: string;
amountRelief?: number;
reliefSubTime?: number;
@ -287,6 +309,7 @@ const size = "small";
const loading = ref(false);
const reliefTypeEnum = ref<ComboModel[]>();
const studentTypeEnum = ref<ComboModel[]>();
const subject1 = ref<ComboModel[]>([
{ value: 4, text: "物理" },
@ -448,21 +471,35 @@ const handleResetForm = () => {
const fetchInitData = async () => {
reliefTypeEnum.value = `
1.复读生
2.艺术生
3.春招生
4.领导承诺批准全免
5.资源班
6.国际班
7.合同制收费学校
8.渠道商家属
9.新开班但领导承诺第一学期不收费`
1.建卡贫困户
2.低保户
3.教师子女
4.孤儿
5.艺体生
6.残疾学生
7.领导特殊承诺减免`
.split("\n")
.filter((s) => s.trim())
.map((s) => {
const [value, text] = s.trim().split(".");
return { value: text.trim(), text: text.trim() };
});
studentTypeEnum.value = `
1.复读生
10.艺术生
20.春招生
30.领导承诺批准全免
40.资源班
50.国际班
60.合同制收费学校
70.渠道商家属
80.新开班但领导承诺第一学期不收费`
.split("\n")
.filter((s) => s.trim())
.map((s) => {
const [value, text] = s.trim().split(".");
return { value: parseInt(value.trim()), text: text.trim() };
});
};
const fetchFormData = async () => {

View File

@ -109,13 +109,13 @@
<div class="subjectTagEnableDiv">
<el-tag v-if="position.enable === false" type="info">已禁用</el-tag>
<el-tag>{{ position.schoolName || "-" }}</el-tag>
<el-tag type="warning">{{
position.graduationYear ? position.graduationYear + "届" : "-"
}}</el-tag>
<el-tag type="success">{{ position.grade || "-" }}</el-tag>
<el-tag type="primary" class="classTag">{{
position.className || "-"
}}</el-tag>
<el-tag v-if="scope.row.studentType" type="info">{{
scope.row.studentType
}}</el-tag>
</div>
</div>
</div>