diff --git a/.gitignore b/.gitignore
index e56e9a2..06d3920 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,7 +12,6 @@ lib/
lib64/
.DS_Store
docs/_build/
-.env
*.env
**/local_settings.py
static/
diff --git a/backend/Dockerfile b/backend/Dockerfile
new file mode 100644
index 0000000..ba914f8
--- /dev/null
+++ b/backend/Dockerfile
@@ -0,0 +1,21 @@
+# syntax=docker/dockerfile:1
+FROM python:3.12.2
+
+WORKDIR /app
+
+# 安装系统依赖
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
+ build-essential \
+ default-libmysqlclient-dev \
+ pkg-config \
+ && rm -rf /var/lib/apt/lists/*
+
+
+COPY requirements.txt .
+RUN pip install -r requirements.txt
+
+COPY . .
+
+# 默认命令,开发和生产通过 docker-compose 覆盖
+CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
\ No newline at end of file
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
new file mode 100644
index 0000000..c1d22c5
--- /dev/null
+++ b/docker-compose.dev.yml
@@ -0,0 +1,56 @@
+services:
+ backend:
+ build:
+ context: ./backend
+ volumes:
+ - ./backend:/app
+ ports:
+ - "48000:8000"
+ command: python manage.py runserver 0.0.0.0:8000
+ environment:
+ - DATABASE_HOST=mysql
+ networks:
+ - dj_admin_network
+ env_file:
+ - ./docker/.env.dev
+ depends_on:
+ mysql:
+ condition: service_healthy
+
+ mysql:
+ image: mysql:8
+ environment:
+ MYSQL_ROOT_PASSWORD: my-secret-pw
+ MYSQL_DATABASE: django_vue
+ ports:
+ - "43306:3306"
+ volumes:
+ - ./sql/django_vue.sql:/docker-entrypoint-initdb.d/django_vue.sql
+ networks:
+ - dj_admin_network
+ env_file:
+ - ./docker/.env.dev
+ healthcheck:
+ test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-pmy-secret-pw" ]
+ interval: 5s
+ timeout: 5s
+ retries: 10
+
+ web:
+ build:
+ context: ./web
+ target: dev
+ volumes:
+ - ./web:/app
+ - /app/node_modules
+ ports:
+ - "5678:5678"
+ command: pnpm run dev:antd
+ networks:
+ - dj_admin_network
+ env_file:
+ - ./docker/.env.dev
+
+networks:
+ dj_admin_network:
+ driver: bridge
\ No newline at end of file
diff --git a/web/Dockerfile b/web/Dockerfile
new file mode 100644
index 0000000..29d9f12
--- /dev/null
+++ b/web/Dockerfile
@@ -0,0 +1,64 @@
+# syntax=docker/dockerfile:1
+
+####################
+# 构建阶段
+####################
+FROM node:22.17.0 AS build
+
+WORKDIR /app
+
+# 先拷贝依赖文件
+COPY package.json ./
+
+# 启用 corepack + 设置 registry
+RUN corepack enable \
+ && corepack prepare pnpm@latest --activate \
+ && pnpm config set registry https://registry.npmjs.org/ \
+ && pnpm install
+
+# 再拷贝源码
+COPY . .
+
+# 编译
+RUN pnpm run build:antd
+
+####################
+# 生产阶段
+####################
+FROM nginx:alpine AS prod
+
+# 拷贝编译后的静态文件到 nginx
+COPY --from=build /app/dist /usr/share/nginx/html
+
+# 拷贝 nginx 配置
+COPY nginx.conf /etc/nginx/conf.d/default.conf
+
+
+####################
+# 开发阶段
+####################
+FROM node:22.17.0 AS dev
+
+WORKDIR /app
+
+# 拷贝项目
+COPY . .
+
+# 如果有私有 registry
+COPY .npmrc .npmrc
+
+# 安装 pnpm(官方推荐 corepack,更好)
+RUN corepack enable \
+ && corepack prepare pnpm@latest --activate
+
+# 安装依赖(一定要在 monorepo 根目录,保证 workspace 有效)
+RUN pnpm i
+
+# 设置前端工作目录(根据实际情况修改)
+WORKDIR /app/apps/web-antd
+
+# 暴露前端 dev server 端口
+EXPOSE 5678
+
+# 默认启动 dev server
+CMD ["pnpm", "run", "dev:antd"]
diff --git a/web/apps/web-antd/.env b/web/apps/web-antd/.env
new file mode 100644
index 0000000..8b4f120
--- /dev/null
+++ b/web/apps/web-antd/.env
@@ -0,0 +1,8 @@
+# 应用标题
+VITE_APP_TITLE=Django Vue Admin
+
+# 应用命名空间,用于缓存、store等功能的前缀,确保隔离
+VITE_APP_NAMESPACE=django-vue-admin
+
+# 对store进行加密的密钥,在将store持久化到localStorage时会使用该密钥进行加密
+VITE_APP_STORE_SECURE_KEY=d41d8cd98f00b204e9800998ecf8427e
diff --git a/web/apps/web-antd/src/views/system/dept/list.vue b/web/apps/web-antd/src/views/system/dept/list.vue
index 10778ed..95744cc 100644
--- a/web/apps/web-antd/src/views/system/dept/list.vue
+++ b/web/apps/web-antd/src/views/system/dept/list.vue
@@ -90,7 +90,12 @@ function onActionClick({
}
}
}
-
+const expandAll = () => {
+ gridApi.grid?.setAllTreeExpand(true);
+};
+const collapseAll = () => {
+ gridApi.grid?.setAllTreeExpand(false);
+};
const [Grid, gridApi] = useVbenVxeGrid({
gridEvents: {},
gridOptions: {
@@ -134,6 +139,12 @@ function refreshGrid() {
+
+