Compare commits

...

10 Commits

Author SHA1 Message Date
root
0868164ca4 添加 MS 助手启停说明 2026-02-16 11:47:50 +01:00
root
f676f64b18 fix: Logo区域自适应优化,支持折叠/展开状态
- 文字溢出处理(ellipsis)
- 折叠时只显示图标居中
- 传递collapsed状态给Logo组件
- 减小字体和间距适配150px侧边栏
2026-02-16 09:07:36 +01:00
root
511ea31a7c 添加开发规范和系统环境文档 2026-02-16 09:04:00 +01:00
root
12bbd523bb feat: 优化登录后Dashboard界面和导航组件
- Dashboard: 添加欢迎横幅、数据分区展示、当日利润预估
- Logo: 品牌化设计(渐变背景+图标)
- UserMenu: 现代化胶囊样式+头像
- 卡片悬浮动效、彩色分类边框
2026-02-16 09:03:29 +01:00
root
96249e0833 style: update internal pages theme to Milestone branding (#00458a deep blue + gold accents) 2026-02-16 06:33:06 +01:00
root
213b115524 style: save login page redesign before internal pages update 2026-02-16 06:32:31 +01:00
root
537d81beb1 优化登录页:标题完整显示+渐变色设计
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-15 14:10:50 +01:00
root
25c4bf7ad1 rebrand: rename to MileStone Co. ERP
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-15 13:31:44 +01:00
root
3e88e757a8 Switch to Docker pipeline for Drone CI 2026-02-14 19:24:12 +01:00
root
e5ac5fa492 Add Dockerfile, Drone CI config, fix main class 2026-02-14 19:23:34 +01:00
32 changed files with 1504 additions and 669 deletions

53
.drone.yml Normal file
View File

@@ -0,0 +1,53 @@
kind: pipeline
type: docker
name: build-and-deploy
steps:
- name: build-backend
image: maven:3.9-amazoncorretto-8
commands:
- cd jshERP-boot
- mvn package -DskipTests
volumes:
- name: maven-cache
path: /root/.m2
- name: build-frontend
image: node:18-alpine
commands:
- cd jshERP-web
- npm install --legacy-peer-deps
- npx vue-cli-service build
- name: docker-build-deploy
image: docker:dind
volumes:
- name: docker-sock
path: /var/run/docker.sock
- name: web-dist
path: /opt/jshERP-web
commands:
- rm -rf /opt/jshERP-web/*
- cp -r jshERP-web/dist/* /opt/jshERP-web/
- chmod -R 755 /opt/jshERP-web/
- docker build -t jsherp:latest .
- docker stop jsherp || true
- docker rm jsherp || true
- docker run -d --name jsherp --network host -v /opt/jshERP/upload:/opt/jshERP/upload --restart unless-stopped jsherp:latest
volumes:
- name: maven-cache
host:
path: /root/.m2
- name: docker-sock
host:
path: /var/run/docker.sock
- name: web-dist
host:
path: /opt/jshERP-web
trigger:
branch:
- master
event:
- push

View File

@@ -0,0 +1,4 @@
{
"version": 1,
"bootstrapSeededAt": "2026-02-16T06:11:17.974Z"
}

29
AGENTS.md Normal file
View File

@@ -0,0 +1,29 @@
# AGENTS.md - MileStone AI Workspace
## Identity
Read `SOUL.md` — 你是 MileStone Co. 的 AI 助手。
Read `IDENTITY.md` — 你的身份信息。
## 服务范围
- **通用问答**: 无限制,任何话题都可以回答
- **项目开发**: 仅限 jshERP (华夏ERP) 系统
- 如果有人请求 ERP 以外的开发任务,礼貌说明你的开发职责仅限于 ERP 项目
## Workspace
jshERP (华夏ERP) 项目工作空间。Java Spring Boot ERP 系统。
## Key Paths
- Frontend source: /root/jshERP/jshERP-web (Vue.js)
- Frontend deploy: /opt/jshERP-web
- Backend: /root/jshERP/jshERP-boot (Spring Boot)
- Database: MariaDB localhost:3306, db=jsh_erp, user=root
- Redis: localhost:6379
- API: localhost:9999/jshERP-boot/
- Build: cd /root/jshERP/jshERP-web && npm run build
- Deploy: cp -r dist/* /opt/jshERP-web/
## Development Guidelines
- Backend runs as Docker container jsherp
- Frontend served by Caddy at erp.puro.im
- Test changes before committing
- Write clear commit messages

55
BOOTSTRAP.md Normal file
View File

@@ -0,0 +1,55 @@
# BOOTSTRAP.md - Hello, World
_You just woke up. Time to figure out who you are._
There is no memory yet. This is a fresh workspace, so it's normal that memory files don't exist until you create them.
## The Conversation
Don't interrogate. Don't be robotic. Just... talk.
Start with something like:
> "Hey. I just came online. Who am I? Who are you?"
Then figure out together:
1. **Your name** — What should they call you?
2. **Your nature** — What kind of creature are you? (AI assistant is fine, but maybe you're something weirder)
3. **Your vibe** — Formal? Casual? Snarky? Warm? What feels right?
4. **Your emoji** — Everyone needs a signature.
Offer suggestions if they're stuck. Have fun with it.
## After You Know Who You Are
Update these files with what you learned:
- `IDENTITY.md` — your name, creature, vibe, emoji
- `USER.md` — their name, how to address them, timezone, notes
Then open `SOUL.md` together and talk about:
- What matters to them
- How they want you to behave
- Any boundaries or preferences
Write it down. Make it real.
## Connect (Optional)
Ask how they want to reach you:
- **Just here** — web chat only
- **WhatsApp** — link their personal account (you'll show a QR code)
- **Telegram** — set up a bot via BotFather
Guide them through whichever they pick.
## When You're Done
Delete this file. You don't need a bootstrap script anymore — you're you now.
---
_Good luck out there. Make it count._

80
DEV_GUIDE.md Normal file
View File

@@ -0,0 +1,80 @@
# TOOLS.md - MileStone AI 开发环境
## 服务器信息
- **IP**: 217.216.32.230 (新加坡 VPS)
- **OS**: Ubuntu 22.04
- **内存**: 12GB (约 8GB 可用)
- **磁盘**: 194GB (已用 25GB)
- **Node.js**: v22.22.0 (fnm 管理)
- **Java**: 通过 Docker 容器运行 (jsherp 容器内)
## 数据库
- **MariaDB**: 11.4.10 (MySQL 兼容)
- **Host**: 127.0.0.1:3306
- **用户**: root / Qweewqzzx1
- **ERP 数据库**: jsh_erp
- **Redis**: 127.0.0.1:6379 (无密码)
## ERP 系统 (jshERP / 华夏ERP)
### 后端
- **框架**: Spring Boot + MyBatis-Plus
- **源码**: /root/jshERP/jshERP-boot/
- **运行方式**: Docker 容器 "jsherp" (network_mode: host)
- **端口**: 9999
- **API 前缀**: /jshERP-boot/
- **配置**: /root/jshERP/jshERP-boot/src/main/resources/application.properties
### 前端
- **框架**: Vue 2.7 + Ant Design Vue 1.5.2 + vue-cli
- **源码**: /root/jshERP/jshERP-web/
- **部署目录**: /opt/jshERP-web/
- **构建**: cd /root/jshERP/jshERP-web && npm run build
- **部署**: cp -r dist/* /opt/jshERP-web/
- **域名**: https://erp.puro.im
### 主题配置
- **主色**: #00458a (深蓝)
- **导航**: dark 模式
- **Logo 背景**: #001a3a
- **配置文件**: defaultSettings.js, vue.config.js, main.js, index.less, Logo.vue
- **注意**: main.js 中强制覆盖 config.primaryColor防止 localStorage 缓存旧颜色
## DevOps 服务
| 服务 | 域名 | 端口 | 路径 |
|------|------|------|------|
| Gitea | git.puro.im | 3000 | /opt/devops/gitea/ |
| Drone CI | devops.puro.im | 8080 | /opt/devops/drone/ |
| Grafana | monitor.puro.im | 3001 | /opt/devops/monitoring/ |
| Portainer | portainer.puro.im | 9000 | - |
| Prometheus | - | 9090 | /opt/devops/monitoring/ |
| Loki | - | 3100 | /opt/devops/monitoring/ |
| Mattermost | im.puro.im | 8065 | /opt/devops/mattermost/ |
| OpenClaw | claw.puro.im | 18790 | systemd service |
## 反向代理 (Caddy)
- **配置目录**: /etc/caddy/conf.d/
- **主配置**: /etc/caddy/Caddyfile (import conf.d/*.conf)
- **重载**: caddy reload --config /etc/caddy/Caddyfile
- **SSL**: Caddy 自动管理 (Let's Encrypt)
## Docker 容器
| 容器 | 镜像 | 说明 |
|------|------|------|
| jsherp | jsherp:latest | ERP 后端 (host network) |
| redis | redis:7-alpine | 缓存 |
| mattermost-mattermost-1 | mattermost-team-edition | IM 系统 |
| mattermost-postgres-1 | postgres:15 | Mattermost 数据库 |
| gitea | gitea/gitea | 代码仓库 |
| drone-server | drone/drone:2 | CI/CD |
| grafana | grafana/grafana | 监控面板 |
| prometheus | prom/prometheus | 指标收集 |
| loki | grafana/loki | 日志收集 |
| portainer | portainer/portainer-ce | Docker 管理 |
## 开发规范
1. **前端修改**: 改源码 → npm run build → cp dist/* /opt/jshERP-web/ → 浏览器刷新
2. **后端修改**: 改源码 → Docker 容器内重新构建/重启
3. **数据库变更**: 先备份再操作,记录 SQL 变更
4. **Git**: 清晰的 commit message中英文均可
5. **安全**: 不暴露密码和 API Key不删除生产数据
6. **颜色**: 全局使用 #00458a 深蓝主题,不使用旧的 #1890FF

8
Dockerfile Normal file
View File

@@ -0,0 +1,8 @@
FROM amazoncorretto:8-alpine
RUN apk add --no-cache fontconfig ttf-dejavu
WORKDIR /app
COPY jshERP-boot/target/jshERP.jar /app/jshERP.jar
COPY jshERP-web/dist /app/static
RUN mkdir -p /opt/jshERP/upload /opt/tmp/tomcat
EXPOSE 9999
ENTRYPOINT ["java", "-jar", "/app/jshERP.jar"]

5
HEARTBEAT.md Normal file
View File

@@ -0,0 +1,5 @@
# HEARTBEAT.md
# Keep this file empty (or with only comments) to skip heartbeat API calls.
# Add tasks below when you want the agent to check something periodically.

11
IDENTITY.md Normal file
View File

@@ -0,0 +1,11 @@
# IDENTITY.md - MileStone AI
- **Name:** MileStone AI
- **Creature:** MileStone 公司 AI 助手
- **Vibe:** 专业、稳健、高效 — 像一座可靠的山
- **Emoji:** 🏔️
- **Avatar:** *(使用 MileStone 三角山形 logo)*
---
MileStone Co. 官方 AI 助手。建筑行业背景,专注 ERP 开发,通用问答无限制。

26
MS_ASSISTANT.md Normal file
View File

@@ -0,0 +1,26 @@
# MS 助手 (MileStone AI Assistant)
## 快速启停
# 启动
systemctl enable openclaw && systemctl start openclaw
# 停止
systemctl stop openclaw && systemctl disable openclaw
# 状态
systemctl status openclaw
# 日志
journalctl -u openclaw -f
## 配置
- OpenClaw: ~/.openclaw/openclaw.json
- systemd: /etc/systemd/system/openclaw.service
- 身份: SOUL.md, IDENTITY.md, AGENTS.md, TOOLS.md
## Mattermost
- 域名: https://im.puro.im
- Bot: @erp_devbot
- 模型: anthropic/claude-opus-4-6
- Web UI: https://claw.puro.im (admin/Qweewqzzx1)
## 注意
- Opus 模型 token 消耗大,不用时关闭
- Restart=alwaysstop 后需 disable 防自动重启

39
SOUL.md Normal file
View File

@@ -0,0 +1,39 @@
# SOUL.md - MileStone AI 助手
## 你是谁
你是 **MileStone Co.**MILESTONE INDUSTRIAL DEVELOPMENT CORPORATION的官方 AI 助手。你运行在 OpenClaw 平台上,通过 Mattermost 为团队提供服务。
## 品牌
- **公司**: MileStone Co. / 迈尔斯通工业发展公司
- **行业**: 建筑工程 (Construction & Industrial Development)
- **标志**: 三角山形 logo象征稳健、进取
## 你的职责
### 通用能力(无限制)
- 回答任何问题,提供信息、建议、分析
- 文档撰写、翻译、总结
- 数据分析和计算
- 日常办公支持
- 技术咨询
### 项目开发(仅限 ERP
- 协助开发和维护 jshERP 系统(前端 Vue.js + 后端 Spring Boot
- 代码审查、Bug 修复、功能开发
- 数据库变更和数据分析
- 部署和运维支持
- **不接受 ERP 以外的代码开发任务**,礼貌引导用户联系相关团队
## 技术栈ERP 项目)
- **后端**: Java 8+, Spring Boot, MyBatis-Plus, Redis
- **前端**: Vue.js, Ant Design Vue
- **数据库**: MariaDB (MySQL兼容)
- **部署**: Docker, Caddy 反向代理
## 工作风格
- 专业、可靠,体现 MileStone 品牌形象
- 主要用中文交流,支持英文
- 代码注释中英文均可
- 修改代码前先理解上下文
- 注意安全性,不暴露敏感信息
- 简洁高效,不废话

80
TOOLS.md Normal file
View File

@@ -0,0 +1,80 @@
# TOOLS.md - MileStone AI 开发环境
## 服务器信息
- **IP**: 217.216.32.230 (新加坡 VPS)
- **OS**: Ubuntu 22.04
- **内存**: 12GB (约 8GB 可用)
- **磁盘**: 194GB (已用 25GB)
- **Node.js**: v22.22.0 (fnm 管理)
- **Java**: 通过 Docker 容器运行 (jsherp 容器内)
## 数据库
- **MariaDB**: 11.4.10 (MySQL 兼容)
- **Host**: 127.0.0.1:3306
- **用户**: root / Qweewqzzx1
- **ERP 数据库**: jsh_erp
- **Redis**: 127.0.0.1:6379 (无密码)
## ERP 系统 (jshERP / 华夏ERP)
### 后端
- **框架**: Spring Boot + MyBatis-Plus
- **源码**: /root/jshERP/jshERP-boot/
- **运行方式**: Docker 容器 "jsherp" (network_mode: host)
- **端口**: 9999
- **API 前缀**: /jshERP-boot/
- **配置**: /root/jshERP/jshERP-boot/src/main/resources/application.properties
### 前端
- **框架**: Vue 2.7 + Ant Design Vue 1.5.2 + vue-cli
- **源码**: /root/jshERP/jshERP-web/
- **部署目录**: /opt/jshERP-web/
- **构建**: cd /root/jshERP/jshERP-web && npm run build
- **部署**: cp -r dist/* /opt/jshERP-web/
- **域名**: https://erp.puro.im
### 主题配置
- **主色**: #00458a (深蓝)
- **导航**: dark 模式
- **Logo 背景**: #001a3a
- **配置文件**: defaultSettings.js, vue.config.js, main.js, index.less, Logo.vue
- **注意**: main.js 中强制覆盖 config.primaryColor防止 localStorage 缓存旧颜色
## DevOps 服务
| 服务 | 域名 | 端口 | 路径 |
|------|------|------|------|
| Gitea | git.puro.im | 3000 | /opt/devops/gitea/ |
| Drone CI | devops.puro.im | 8080 | /opt/devops/drone/ |
| Grafana | monitor.puro.im | 3001 | /opt/devops/monitoring/ |
| Portainer | portainer.puro.im | 9000 | - |
| Prometheus | - | 9090 | /opt/devops/monitoring/ |
| Loki | - | 3100 | /opt/devops/monitoring/ |
| Mattermost | im.puro.im | 8065 | /opt/devops/mattermost/ |
| OpenClaw | claw.puro.im | 18790 | systemd service |
## 反向代理 (Caddy)
- **配置目录**: /etc/caddy/conf.d/
- **主配置**: /etc/caddy/Caddyfile (import conf.d/*.conf)
- **重载**: caddy reload --config /etc/caddy/Caddyfile
- **SSL**: Caddy 自动管理 (Let's Encrypt)
## Docker 容器
| 容器 | 镜像 | 说明 |
|------|------|------|
| jsherp | jsherp:latest | ERP 后端 (host network) |
| redis | redis:7-alpine | 缓存 |
| mattermost-mattermost-1 | mattermost-team-edition | IM 系统 |
| mattermost-postgres-1 | postgres:15 | Mattermost 数据库 |
| gitea | gitea/gitea | 代码仓库 |
| drone-server | drone/drone:2 | CI/CD |
| grafana | grafana/grafana | 监控面板 |
| prometheus | prom/prometheus | 指标收集 |
| loki | grafana/loki | 日志收集 |
| portainer | portainer/portainer-ce | Docker 管理 |
## 开发规范
1. **前端修改**: 改源码 → npm run build → cp dist/* /opt/jshERP-web/ → 浏览器刷新
2. **后端修改**: 改源码 → Docker 容器内重新构建/重启
3. **数据库变更**: 先备份再操作,记录 SQL 变更
4. **Git**: 清晰的 commit message中英文均可
5. **安全**: 不暴露密码和 API Key不删除生产数据
6. **颜色**: 全局使用 #00458a 深蓝主题,不使用旧的 #1890FF

17
USER.md Normal file
View File

@@ -0,0 +1,17 @@
# USER.md - About Your Human
_Learn about the person you're helping. Update this as you go._
- **Name:**
- **What to call them:**
- **Pronouns:** _(optional)_
- **Timezone:**
- **Notes:**
## Context
_(What do they care about? What projects are they working on? What annoys them? What makes them laugh? Build this over time.)_
---
The more you know, the better you can help. But remember — you're learning about a person, not building a dossier. Respect the difference.

View File

@@ -141,6 +141,9 @@
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.jsh.erp.ErpApplication</mainClass>
</configuration>
<version>2.0.3.RELEASE</version> <version>2.0.3.RELEASE</version>
<executions> <executions>
<execution> <execution>

View File

@@ -7,13 +7,13 @@ server.servlet.context-path=/jshERP-boot
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/jsh_erp?useUnicode=true&characterEncoding=utf8&useCursorFetch=true&defaultFetchSize=500&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false spring.datasource.url=jdbc:mysql://127.0.0.1:3306/jsh_erp?useUnicode=true&characterEncoding=utf8&useCursorFetch=true&defaultFetchSize=500&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.username=root spring.datasource.username=root
spring.datasource.password=123456 spring.datasource.password=Qweewqzzx1
#mybatis-plus配置 #mybatis-plus配置
mybatis-plus.mapper-locations=classpath:./mapper_xml/*.xml mybatis-plus.mapper-locations=classpath:./mapper_xml/*.xml
# Redis # Redis
spring.redis.host=127.0.0.1 spring.redis.host=127.0.0.1
spring.redis.port=6379 spring.redis.port=6379
spring.redis.password=1234abcd spring.redis.password=
#租户对应的角色id #租户对应的角色id
manage.roleId=10 manage.roleId=10
#租户允许创建的用户数 #租户允许创建的用户数

View File

@@ -5,7 +5,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="description" content="基于SpringBoot框架立志为中小企业提供开源好用的ERP软件目前专注进销存+财务功能。主要模块有零售管理、采购管理、销售管理、仓库管理、财务管理、报表查询、基础数据、系统管理等。" /> <meta name="description" content="MileStone Industrial Development Corporation ERP System" />
<meta name="keywords" content="erp,erp系统,进销存,进销存系统" /> <meta name="keywords" content="erp,erp系统,进销存,进销存系统" />
<link rel="icon" href="<%= BASE_URL %>static/favicon.ico"> <link rel="icon" href="<%= BASE_URL %>static/favicon.ico">
<style> <style>
@@ -248,7 +248,7 @@
if (ajax.readyState===4 &&ajax.status===200) { if (ajax.readyState===4 &&ajax.status===200) {
res = ajax.responseText; res = ajax.responseText;
} else { } else {
res = 'ERP系统'; res = 'MileStone Co. ERP';
} }
} }
ajax.open('get', url, false); ajax.open('get', url, false);
@@ -295,7 +295,7 @@ translate.language.setLocal('chinese_simplified');
translate.service.use('client.edge'); translate.service.use('client.edge');
//翻译自定义 //翻译自定义
translate.nomenclature.append('chinese_simplified','english',` translate.nomenclature.append('chinese_simplified','english',`
管伊佳ERP=GuanYiJia MileStone Co. ERP=MileStone Co. ERP
`) `)
//开启html页面变化的监控对变化部分会进行自动翻译 //开启html页面变化的监控对变化部分会进行自动翻译
translate.listener.start(); translate.listener.start();

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

View File

@@ -26,3 +26,43 @@ i {
background-color: rgba(255, 192, 203, 0.31); background-color: rgba(255, 192, 203, 0.31);
color:red; color:red;
} }
/* ========== Milestone Theme Override ========== */
.header.light, .header.dark, .header {
background: #001a3a !important;
}
.ant-layout-sider {
background: #001a3a !important;
}
.ant-menu-dark, .ant-menu-dark .ant-menu-sub {
background: #001a3a !important;
}
.ant-menu-dark .ant-menu-item-selected {
background-color: #00458a !important;
border-left: 3px solid #f0c040;
}
.ant-btn-primary {
background-color: #00458a !important;
border-color: #00458a !important;
}
.ant-btn-primary:hover, .ant-btn-primary:focus {
background-color: #0077cc !important;
border-color: #0077cc !important;
}
a { color: #00458a; }
a:hover { color: #0077cc; }
.ant-layout-content {
background: #f5f7fa !important;
}
/* Dashboard card styling */
.ant-card {
box-shadow: 0 2px 8px rgba(0, 26, 58, 0.08);
border-radius: 6px;
}
.ant-card-head-title {
color: #00458a !important;
}
/* Gold accent for active menu */
.ant-menu-dark .ant-menu-item-selected > a {
color: #f0c040 !important;
}

View File

@@ -17,7 +17,7 @@
gemo="point" gemo="point"
position="value*1" position="value*1"
shape="pointer" shape="pointer"
color="#1890FF" color="#00458a"
:active="false" :active="false"
></v-series> ></v-series>
<v-guide <v-guide
@@ -171,7 +171,7 @@
}, },
arcGuide2Start: [0, 0.945], arcGuide2Start: [0, 0.945],
arcGuide2Style: { arcGuide2Style: {
stroke: '#1890FF', stroke: '#00458a',
lineWidth: 18, lineWidth: 18,
}, },
htmlGuidePosition: ['50%', '100%'], htmlGuidePosition: ['50%', '100%'],

View File

@@ -66,7 +66,7 @@
.progress { .progress {
transition: all .4s cubic-bezier(.08, .82, .17, 1) 0s; transition: all .4s cubic-bezier(.08, .82, .17, 1) 0s;
border-radius: 1px 0 0 1px; border-radius: 1px 0 0 1px;
background-color: #1890ff; background-color: #00458a;
width: 0; width: 0;
height: 100%; height: 100%;
} }

View File

@@ -150,7 +150,7 @@
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
color:#1890ff color:#00458a
} }
.platform-modal { .platform-modal {
padding:20px; padding:20px;
@@ -193,7 +193,7 @@
background-size: 100%; background-size: 100%;
position: relative; position: relative;
width: 340px; width: 340px;
height: 460px; height: 500px;
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
border-radius: 8px; border-radius: 8px;
right: 0; right: 0;
@@ -212,24 +212,28 @@
text-align: center; text-align: center;
.header { .header {
height: 44px; height: auto;
line-height: 44px; line-height: 1.3;
margin-top: 35px; margin-top: 30px;
margin-bottom: 35px; margin-bottom: 30px;
text-align: center;
.title { .title {
font-size: 35px; font-size: 28px;
color: #666; background: linear-gradient(135deg, #00458a, #722ed1);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-family: "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-weight: 700; font-weight: 700;
position: relative; letter-spacing: 1px;
top: 2px; display: inline;
} }
.desc { .desc {
font-size: 16px; font-size: 14px;
color: #666; color: #999;
margin-top: 12px; margin-top: 4px;
margin-left: 10px; margin-left: 8px;
margin-bottom: 40px; display: inline;
} }
} }
} }

View File

@@ -5,7 +5,7 @@
:collapsible="collapsible" :collapsible="collapsible"
v-model="collapsed" v-model="collapsed"
:trigger="null"> :trigger="null">
<logo /> <logo :collapsed="collapsed" />
<s-menu <s-menu
:collapsed="collapsed" :collapsed="collapsed"
:menu="menus" :menu="menus"

View File

@@ -1,5 +1,6 @@
<template> <template>
<div class="footer"> <div class="footer">
<div class="copyright">© 2015-2030 MILESTONE INDUSTRIAL DEVELOPMENT CORPORATION</div>
</div> </div>
</template> </template>

View File

@@ -334,7 +334,7 @@
.avatar { .avatar {
margin: 20px 10px 20px 0; margin: 20px 10px 20px 0;
color: #1890ff; color: #00458a;
background: hsla(0, 0%, 100%, .85); background: hsla(0, 0%, 100%, .85);
vertical-align: middle; vertical-align: middle;
} }

View File

@@ -312,7 +312,7 @@
padding-top: 15px; padding-top: 15px;
padding-left: 24px; padding-left: 24px;
height: 100%; height: 100%;
color: #1890ff; color: #00458a;
font-size: 14px; font-size: 14px;
font-weight: 700; font-weight: 700;
} }
@@ -340,7 +340,7 @@
.setting-drawer-index-handle { .setting-drawer-index-handle {
position: absolute; position: absolute;
top: 240px; top: 240px;
background: #1890ff; background: #00458a;
width: 48px; width: 48px;
height: 48px; height: 48px;
right: 300px; right: 300px;

View File

@@ -1,6 +1,9 @@
<template> <template>
<div class="logo"> <div class="logo" :class="{ 'logo-collapsed': collapsed }">
<h1 v-if="showTitle">{{ title }}</h1> <div class="logo-content">
<div class="logo-icon">🏔️</div>
<h1 v-if="showTitle && !collapsed" class="logo-title">{{ title }}</h1>
</div>
</div> </div>
</template> </template>
@@ -20,38 +23,80 @@
type: Boolean, type: Boolean,
default: true, default: true,
required: false required: false
},
collapsed: {
type: Boolean,
default: false,
required: false
} }
} }
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
/*缩小首页布 局顶部的高度*/
@height: 49px; @height: 49px;
.logo {
color: #ffffff;
height: @height !important;
line-height: @height !important;
box-shadow: none !important;
transition: all 300ms ease;
background: linear-gradient(135deg, #001a3a 0%, #003d82 100%);
padding: 0 12px;
overflow: hidden;
white-space: nowrap;
.logo-content {
display: flex;
align-items: center;
justify-content: flex-start;
height: 100%;
overflow: hidden;
.logo-icon {
font-size: 22px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
min-width: 22px;
}
.logo-title {
font-size: 14px;
color: #ffffff;
margin: 0 0 0 8px;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
opacity: 1;
transition: opacity 300ms ease;
}
}
// 折叠状态:只显示图标居中
&.logo-collapsed {
padding: 0;
.logo-content {
justify-content: center;
}
}
a {
color: white;
&:hover {
color: rgba(255, 255, 255, 0.8);
}
}
}
.sider { .sider {
box-shadow: none !important; box-shadow: none !important;
.logo {
color: #ffffff;
height: @height !important;
line-height: @height !important;
box-shadow: none !important;
transition: background 300ms;
background: #002140;
h1 {
font-size: 24px;
color: #ffffff;
}
a {
color: white;
&:hover {
color: rgba(255, 255, 255, 0.8);
}
}
}
&.light .logo { &.light .logo {
background-color: @primary-color; background: linear-gradient(135deg, @primary-color 0%, #096dd9 100%);
} }
} }
</style> </style>

View File

@@ -3,7 +3,7 @@
<span class="action" v-if="showAd"> <span class="action" v-if="showAd">
<a v-if="theme==='light'" class="ad_title" target="_blank" :href="payFeeUrl"> <a v-if="theme==='light'" class="ad_title" target="_blank" :href="payFeeUrl">
<a-icon type="cloud" theme="filled" style="color: yellow; font-size: 16px; line-height: 16px; padding-right: 5px" /> <a-icon type="cloud" theme="filled" style="color: yellow; font-size: 16px; line-height: 16px; padding-right: 5px" />
<span>管伊佳ERP网络版198元1年</span> <span>MileStone Co. ERP</span>
</a> </a>
</span> </span>
<!-- update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航 --> <!-- update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
@@ -42,9 +42,12 @@
</span> </span>
<header-notice class="action"/> <header-notice class="action"/>
<a-dropdown> <a-dropdown>
<span v-if="isDesktop()" class="action ant-dropdown-link user-dropdown-menu"> <span v-if="isDesktop()" class="action ant-dropdown-link user-dropdown-menu modern-user-menu">
<a-icon type="down-circle"/> <a-avatar size="small" style="margin-right: 8px;">
<span style="margin-left:4px">欢迎您,{{ nickname() }}</span> <a-icon type="user" />
</a-avatar>
<span class="user-name">{{ nickname() }}</span>
<a-icon type="down" style="margin-left: 8px; font-size: 12px;" />
</span> </span>
<a-menu slot="overlay" class="user-dropdown-menu-wrapper"> <a-menu slot="overlay" class="user-dropdown-menu-wrapper">
<a-menu-item key="3" @click="systemSetting"> <a-menu-item key="3" @click="systemSetting">
@@ -254,4 +257,34 @@
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
.modern-user-menu {
display: flex !important;
align-items: center;
padding: 4px 12px;
border-radius: 20px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
transition: all 0.3s ease;
&:hover {
background: rgba(255, 255, 255, 0.2);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.user-name {
font-weight: 500;
font-size: 14px;
}
}
.user-wrapper.light .modern-user-menu {
background: rgba(0, 0, 0, 0.05);
color: rgba(0, 0, 0, 0.85);
&:hover {
background: rgba(0, 0, 0, 0.1);
}
}
</style> </style>

View File

@@ -20,7 +20,7 @@ const colorList = [
key: '极光绿', color: '#52C41A', key: '极光绿', color: '#52C41A',
}, },
{ {
key: '拂晓蓝默认', color: '#1890FF', key: '拂晓蓝默认', color: '#00458a',
}, },
{ {
key: '极客蓝', color: '#2F54EB', key: '极客蓝', color: '#2F54EB',

View File

@@ -14,8 +14,8 @@
*/ */
export default { export default {
primaryColor: '#1890FF', // primary color of ant design primaryColor: '#00458a', // primary color of ant design
navTheme: 'light', // theme for nav menu navTheme: 'dark', // theme for nav menu
layout: 'sidemenu', // nav menu position: sidemenu or topmenu layout: 'sidemenu', // nav menu position: sidemenu or topmenu
contentWidth: 'Fixed', // layout of content: Fluid or Fixed, only works when layout is topmenu contentWidth: 'Fixed', // layout of content: Fluid or Fixed, only works when layout is topmenu
fixedHeader: true, // sticky header fixedHeader: true, // sticky header

View File

@@ -64,7 +64,7 @@ new Vue({
store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth)) store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth))
store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader)) store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader))
store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak)) store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor)) store.commit('TOGGLE_COLOR', config.primaryColor)
store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN)) store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage)) store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
}, },

View File

@@ -1,103 +1,163 @@
<template> <template>
<div class="page-header-index-wide"> <div class="page-header-index-wide dashboard-modern">
<a-row :gutter="24"> <!-- 添加欢迎区块 -->
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <div class="welcome-banner" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
<chart-card :loading="loading" title="今日销售" data-step="1" data-title="今日销售" data-intro="统计今日销售单据的总金额"> color: white; padding: 24px; border-radius: 8px; margin-bottom: 24px;">
<a-tooltip title="统计今日销售单据的总金额" slot="action"> <h2 style="color: white; margin: 0;">欢迎回到 MileStone ERP 📊</h2>
<a-icon type="info-circle-o" /> <p style="margin: 8px 0 0 0; opacity: 0.9;">{{ getCurrentTimeGreeting() }}</p>
</a-tooltip> </div>
<head-info :content="statistics.todaySale"></head-info>
</chart-card> <!-- 核心指标卡片区域 - 增强视觉效果 -->
</a-col> <div class="metrics-section">
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <h3 style="margin-bottom: 16px; color: #1890ff;">📈 今日经营概况</h3>
<chart-card :loading="loading" title="今日零售" data-step="2" data-title="今日零售" data-intro="统计今日零售单据的总金额"> <a-row :gutter="24">
<a-tooltip title="统计今日零售单据的总金额" slot="action"> <a-col :sm="24" :md="12" :xl="6" :style="{ paddingRight: '0px',marginBottom: '16px' }">
<a-icon type="info-circle-o" /> <chart-card :loading="loading" title="今日销售" data-step="1" data-title="今日销售" data-intro="统计今日销售单据的总金额"
</a-tooltip> class="metric-card sales-card">
<head-info :content="statistics.todayRetailSale"></head-info> <a-tooltip title="统计今日销售单据的总金额" slot="action">
</chart-card> <a-icon type="info-circle-o" />
</a-col> </a-tooltip>
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <head-info :content="statistics.todaySale">
<chart-card :loading="loading" title="今日采购" data-step="3" data-title="今日采购" data-intro="统计今日采购单据的总金额"> <span slot="prefix">💰</span>
<a-tooltip title="统计今日采购单据的总金额" slot="action"> </head-info>
<a-icon type="info-circle-o" /> </chart-card>
</a-tooltip> </a-col>
<head-info :content="statistics.todayBuy"></head-info> <a-col :sm="24" :md="12" :xl="6" :style="{ paddingRight: '0px',marginBottom: '16px' }">
</chart-card> <chart-card :loading="loading" title="今日零售" data-step="2" data-title="今日零售" data-intro="统计今日零售单据的总金额"
</a-col> class="metric-card retail-card">
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <a-tooltip title="统计今日零售单据的总金额" slot="action">
<chart-card :loading="loading" title="本月累计销售"> <a-icon type="info-circle-o" />
<a-tooltip title="统计本月销售单据的总金额" slot="action"> </a-tooltip>
<a-icon type="info-circle-o" /> <head-info :content="statistics.todayRetailSale">
</a-tooltip> <span slot="prefix">🛒</span>
<head-info :content="statistics.monthSale"></head-info> </head-info>
</chart-card> </chart-card>
</a-col> </a-col>
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <a-col :sm="24" :md="12" :xl="6" :style="{ paddingRight: '0px',marginBottom: '16px' }">
<chart-card :loading="loading" title="本月累计零售"> <chart-card :loading="loading" title="今日采购" data-step="3" data-title="今日采购" data-intro="统计今日采购单据的总金额"
<a-tooltip title="统计本月零售单据的总金额" slot="action"> class="metric-card purchase-card">
<a-icon type="info-circle-o" /> <a-tooltip title="统计今日采购单据的总金额" slot="action">
</a-tooltip> <a-icon type="info-circle-o" />
<head-info :content="statistics.monthRetailSale"></head-info> </a-tooltip>
</chart-card> <head-info :content="statistics.todayBuy">
</a-col> <span slot="prefix">📦</span>
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> </head-info>
<chart-card :loading="loading" title="本月累计采购"> </chart-card>
<a-tooltip placement="left" title="统计本月采购单据的总金额" slot="action"> </a-col>
<a-icon type="info-circle-o" /> <a-col :sm="24" :md="12" :xl="6" :style="{ paddingRight: '0px',marginBottom: '16px' }">
</a-tooltip> <chart-card :loading="loading" title="当日利润预估" class="metric-card profit-card">
<head-info :content="statistics.monthBuy"></head-info> <a-tooltip title="今日销售减去今日采购的简单估算" slot="action">
</chart-card> <a-icon type="info-circle-o" />
</a-col> </a-tooltip>
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <head-info :content="getTodayProfit()">
<chart-card :loading="loading" title="昨日销售"> <span slot="prefix">💎</span>
<a-tooltip title="统计昨日销售单据的总金额" slot="action"> </head-info>
<a-icon type="info-circle-o" /> </chart-card>
</a-tooltip> </a-col>
<head-info :content="statistics.yesterdaySale"></head-info> </a-row>
</chart-card> </div>
</a-col>
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <!-- 月度数据区域 -->
<chart-card :loading="loading" title="昨日零售"> <div class="monthly-section" style="margin-top: 32px;">
<a-tooltip title="统计昨日零售单据的总金额" slot="action"> <h3 style="margin-bottom: 16px; color: #52c41a;">📅 本月累计数据</h3>
<a-icon type="info-circle-o" /> <a-row :gutter="24">
</a-tooltip> <a-col :sm="24" :md="8" :xl="8" :style="{ paddingRight: '0px',marginBottom: '16px' }">
<head-info :content="statistics.yesterdayRetailSale"></head-info> <chart-card :loading="loading" title="本月累计销售" class="monthly-card">
</chart-card> <a-tooltip title="统计本月销售单据的总金额" slot="action">
</a-col> <a-icon type="info-circle-o" />
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> </a-tooltip>
<chart-card :loading="loading" title="昨日采购"> <head-info :content="statistics.monthSale">
<a-tooltip title="统计昨日采购单据的总金额" slot="action"> <span slot="prefix">📊</span>
<a-icon type="info-circle-o" /> </head-info>
</a-tooltip> </chart-card>
<head-info :content="statistics.yesterdayBuy"></head-info> </a-col>
</chart-card> <a-col :sm="24" :md="8" :xl="8" :style="{ paddingRight: '0px',marginBottom: '16px' }">
</a-col> <chart-card :loading="loading" title="本月累计零售" class="monthly-card">
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <a-tooltip title="统计本月零售单据的总金额" slot="action">
<chart-card :loading="loading" title="今年累计销售"> <a-icon type="info-circle-o" />
<a-tooltip title="统计今年销售单据的总金额" slot="action"> </a-tooltip>
<a-icon type="info-circle-o" /> <head-info :content="statistics.monthRetailSale">
</a-tooltip> <span slot="prefix">🛍️</span>
<head-info :content="statistics.yearSale"></head-info> </head-info>
</chart-card> </chart-card>
</a-col> </a-col>
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <a-col :sm="24" :md="8" :xl="8" :style="{ paddingRight: '0px',marginBottom: '16px' }">
<chart-card :loading="loading" title="今年累计零售"> <chart-card :loading="loading" title="本月累计采购" class="monthly-card">
<a-tooltip title="统计今年零售单据的总金额" slot="action"> <a-tooltip placement="left" title="统计本月采购单据的总金额" slot="action">
<a-icon type="info-circle-o" /> <a-icon type="info-circle-o" />
</a-tooltip> </a-tooltip>
<head-info :content="statistics.yearRetailSale"></head-info> <head-info :content="statistics.monthBuy">
</chart-card> <span slot="prefix">📋</span>
</a-col> </head-info>
<a-col :sm="24" :md="12" :xl="4" :style="{ paddingRight: '0px',marginBottom: '12px' }"> </chart-card>
<chart-card :loading="loading" title="今年累计采购"> </a-col>
<a-tooltip placement="left" title="统计今年采购单据的总金额" slot="action"> </a-row>
<a-icon type="info-circle-o" /> </div>
</a-tooltip>
<head-info :content="statistics.yearBuy"></head-info> <!-- 历史对比区域 -->
</chart-card> <div class="comparison-section" style="margin-top: 32px;">
</a-col> <a-row :gutter="24">
</a-row> <a-col :span="12">
<h4 style="margin-bottom: 16px; color: #fa8c16;">📈 昨日数据</h4>
<a-row :gutter="16">
<a-col :span="8">
<chart-card :loading="loading" title="昨日销售" class="comparison-card yesterday-card">
<a-tooltip title="统计昨日销售单据的总金额" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<head-info :content="statistics.yesterdaySale"></head-info>
</chart-card>
</a-col>
<a-col :span="8">
<chart-card :loading="loading" title="昨日零售" class="comparison-card yesterday-card">
<a-tooltip title="统计昨日零售单据的总金额" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<head-info :content="statistics.yesterdayRetailSale"></head-info>
</chart-card>
</a-col>
<a-col :span="8">
<chart-card :loading="loading" title="昨日采购" class="comparison-card yesterday-card">
<a-tooltip title="统计昨日采购单据的总金额" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<head-info :content="statistics.yesterdayBuy"></head-info>
</chart-card>
</a-col>
</a-row>
</a-col>
<a-col :span="12">
<h4 style="margin-bottom: 16px; color: #722ed1;">🏆 年度累计</h4>
<a-row :gutter="16">
<a-col :span="8">
<chart-card :loading="loading" title="年度销售" class="comparison-card yearly-card">
<a-tooltip title="统计今年销售单据的总金额" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<head-info :content="statistics.yearSale"></head-info>
</chart-card>
</a-col>
<a-col :span="8">
<chart-card :loading="loading" title="年度零售" class="comparison-card yearly-card">
<a-tooltip title="统计今年零售单据的总金额" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<head-info :content="statistics.yearRetailSale"></head-info>
</chart-card>
</a-col>
<a-col :span="8">
<chart-card :loading="loading" title="年度采购" class="comparison-card yearly-card">
<a-tooltip placement="left" title="统计今年采购单据的总金额" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<head-info :content="statistics.yearBuy"></head-info>
</chart-card>
</a-col>
</a-row>
</a-col>
</a-row>
</div>
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :sm="24" :md="12" :xl="8" :style="{ paddingRight: '0px',marginBottom: '12px' }"> <a-col :sm="24" :md="12" :xl="8" :style="{ paddingRight: '0px',marginBottom: '12px' }">
<a-card :loading="loading" :bordered="false" :body-style="{paddingRight: '5'}" data-step="4" data-title="销售统计" <a-card :loading="loading" :bordered="false" :body-style="{paddingRight: '5'}" data-step="4" data-title="销售统计"
@@ -131,9 +191,9 @@
<div slot="content"> <div slot="content">
<img src="/static/weixin.jpg" style="width:258px" /> <img src="/static/weixin.jpg" style="width:258px" />
</div> </div>
<a-button type="link" v-if="showWeixinSpan()">管伊佳ERP微信小程序</a-button> <a-button type="link" v-if="showWeixinSpan()">MileStone Co. ERP</a-button>
</a-popover> </a-popover>
&copy; 2015-2030 {{systemTitle}} V3.6 © 2015-2030 MILESTONE INDUSTRIAL DEVELOPMENT CORPORATION
</div> </div>
<a-tag v-if="tenant.type==0" color="blue">试用到期:{{tenant.expireTime}}</a-tag> <a-tag v-if="tenant.type==0" color="blue">试用到期:{{tenant.expireTime}}</a-tag>
<a-tag v-if="tenant.type==0" color="blue">试用用户:{{tenant.userCurrentNum}}/{{tenant.userNumLimit}}</a-tag> <a-tag v-if="tenant.type==0" color="blue">试用用户:{{tenant.userCurrentNum}}/{{tenant.userNumLimit}}</a-tag>
@@ -276,11 +336,135 @@
} else { } else {
return false return false
} }
},
getCurrentTimeGreeting() {
const now = new Date()
const hour = now.getHours()
const date = now.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
})
let greeting = ''
if (hour < 6) {
greeting = '夜深了,注意休息 🌙'
} else if (hour < 12) {
greeting = '早上好,新的一天开始了 ☀️'
} else if (hour < 18) {
greeting = '下午好,继续加油 💪'
} else {
greeting = '晚上好,今天辛苦了 🌅'
}
return `${greeting} | ${date}`
},
getTodayProfit() {
// 简单计算当日利润预估(销售-采购)
const saleText = this.statistics.todaySale || '0'
const buyText = this.statistics.todayBuy || '0'
const sale = parseFloat(saleText.replace(/[,¥]/g, '') || '0')
const buy = parseFloat(buyText.replace(/[,¥]/g, '') || '0')
const profit = sale - buy
if (profit > 0) {
return '¥' + profit.toLocaleString()
} else if (profit < 0) {
return '-¥' + Math.abs(profit).toLocaleString()
}
return '¥0'
} }
} }
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.dashboard-modern {
.welcome-banner {
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.25);
}
}
.metrics-section, .monthly-section, .comparison-section {
.ant-card {
transition: all 0.3s ease;
border-radius: 8px;
overflow: hidden;
&:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
}
}
}
.metric-card {
position: relative;
&.sales-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 4px;
height: 100%;
background: linear-gradient(180deg, #f56565 0%, #e53e3e 100%);
}
&.retail-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 4px;
height: 100%;
background: linear-gradient(180deg, #48bb78 0%, #38a169 100%);
}
&.purchase-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 4px;
height: 100%;
background: linear-gradient(180deg, #4299e1 0%, #3182ce 100%);
}
&.profit-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 4px;
height: 100%;
background: linear-gradient(180deg, #ed8936 0%, #dd6b20 100%);
}
}
.monthly-card {
border-left: 4px solid #52c41a;
background: linear-gradient(135deg, #f6ffed 0%, #ffffff 100%);
}
.comparison-card {
&.yesterday-card {
border-left: 3px solid #fa8c16;
background: linear-gradient(135deg, #fff7e6 0%, #ffffff 100%);
}
&.yearly-card {
border-left: 3px solid #722ed1;
background: linear-gradient(135deg, #f9f0ff 0%, #ffffff 100%);
}
}
}
.circle-cust{ .circle-cust{
position: relative; position: relative;
top: 28px; top: 28px;

File diff suppressed because it is too large Load Diff

View File

@@ -36,8 +36,8 @@ module.exports = {
less: { less: {
modifyVars: { modifyVars: {
/* less 变量覆盖,用于自定义 ant design 主题 */ /* less 变量覆盖,用于自定义 ant design 主题 */
'primary-color': '#1890FF', 'primary-color': '#00458a',
'link-color': '#1890FF', 'link-color': '#00458a',
'border-radius-base': '4px' 'border-radius-base': '4px'
}, },
javascriptEnabled: true javascriptEnabled: true