feat: 福安德智慧报价平台 - 完整业务模块

基于RuoYi-Vue2构建的智慧采购报价平台,包含:

后端(Spring Boot + MyBatis):
- 物料管理 (BizMaterial)
- 供应商管理 (BizSupplier)
- 报价请求RFQ (BizRfq)
- 供应商报价单 (BizQuotation)
- 智慧比价分析 (BizComparison)
- 采购单 (BizPurchaseOrder)
- 供应商评价 (BizSupplierEvaluation)
- 订单异议 (BizOrderObjection)
- 交易记录 (BizTransaction)
- 租户管理-SaaS数据隔离 (BizTenant)

前端(Vue2 + Element UI):
- 10个业务模块完整页面
- ERPNext风格主题(蓝色系)
- 福安德品牌logo

部署:
- Docker Compose一键部署
- MySQL 8.0 + Redis 7 + Nginx
- 前端端口 10031
This commit is contained in:
2026-05-22 09:36:01 +08:00
parent 7da12b0c07
commit 2941cd23c4
106 changed files with 5511 additions and 92 deletions

75
.gitignore vendored
View File

@@ -1,47 +1,28 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml
# Maven
target/
*.jar
*.war
*.ear
!deploy/*.jar
# Node
node_modules/
npm-debug.log*
dist/
# IDE
.idea/
*.iml
.vscode/
.DS_Store
# Logs
*.log
logs/
# Spring Boot
*.pid
# Docker local build artifacts
deploy/dist-ui/
deploy/ruoyi-admin.jar

19
deploy/Dockerfile Normal file
View File

@@ -0,0 +1,19 @@
# Multi-stage: build backend JAR
FROM maven:3.8.6-openjdk-8 AS backend-builder
WORKDIR /build
COPY ruoyi-bid/ .
RUN mvn clean package -DskipTests -pl ruoyi-admin -am -q
# Build frontend
FROM node:20-alpine AS frontend-builder
WORKDIR /ui
COPY ruoyi-bid/ruoyi-ui/ .
RUN npm config set registry https://registry.npmmirror.com && npm install --legacy-peer-deps && npm run build:prod
# Final runtime image
FROM openjdk:8-jre-slim
WORKDIR /app
COPY --from=backend-builder /build/ruoyi-admin/target/ruoyi-admin.jar app.jar
COPY --from=frontend-builder /ui/dist /app/dist-ui
EXPOSE 8080
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar", "--spring.profiles.active=druid,prod"]

38
deploy/deploy.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
set -e
cd /home/userroot/bid-deploy
echo '=== 福安德智慧报价平台 - Docker部署 ==='
# Build frontend first (outside Docker for speed, using local node)
echo '[1/4] 构建前端...'
cd /home/userroot/ruoyi-bid/ruoyi-ui
npm config set registry https://registry.npmmirror.com
npm install --legacy-peer-deps
npm run build:prod
echo '前端构建完成'
# Copy dist to deploy dir (for nginx volume mount approach)
cp -r dist /home/userroot/bid-deploy/dist-ui
cd /home/userroot/bid-deploy
echo '[2/4] 构建后端JAR...'
cd /home/userroot/ruoyi-bid
mvn clean package -DskipTests -pl ruoyi-admin -am -q
cp ruoyi-admin/target/ruoyi-admin.jar /home/userroot/bid-deploy/
cd /home/userroot/bid-deploy
echo '[3/4] 构建Docker镜像并启动...'
docker compose down --remove-orphans 2>/dev/null || true
docker compose up -d --build
echo '[4/4] 等待服务启动...'
sleep 15
docker compose ps
echo ''
echo '======================================'
echo '✓ 部署完成!'
echo '访问地址: http://49.232.154.205:10031'
echo '默认账号: admin / admin123'
echo '======================================'

75
deploy/docker-compose.yml Normal file
View File

@@ -0,0 +1,75 @@
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: bid-mysql
environment:
MYSQL_ROOT_PASSWORD: bid123456@
MYSQL_DATABASE: ry-vue
MYSQL_CHARACTER_SET_SERVER: utf8mb4
MYSQL_COLLATION_SERVER: utf8mb4_unicode_ci
volumes:
- bid-mysql-data:/var/lib/mysql
- ./init-sql/02-ry-vue.sql:/docker-entrypoint-initdb.d/02-ry-vue.sql:ro
- ./init-sql/03-bid-tables.sql:/docker-entrypoint-initdb.d/03-bid-tables.sql:ro
networks:
- bid-net
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-pbid123456@"]
interval: 10s
timeout: 5s
retries: 15
redis:
image: redis:7-alpine
container_name: bid-redis
command: redis-server --requirepass bid123456@
networks:
- bid-net
restart: unless-stopped
backend:
image: openjdk:8-jre-slim
container_name: bid-backend
working_dir: /app
command: java -Djava.security.egd=file:/dev/./urandom -jar app.jar --spring.profiles.active=druid,prod
volumes:
- ./ruoyi-admin.jar:/app/app.jar:ro
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=bid123456@
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PASSWORD=bid123456@
- SPRING_REDIS_PORT=6379
networks:
- bid-net
restart: unless-stopped
nginx:
image: nginx:alpine
container_name: bid-nginx
ports:
- '10031:80'
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./dist-ui:/usr/share/nginx/html:ro
depends_on:
- backend
networks:
- bid-net
restart: unless-stopped
volumes:
bid-mysql-data:
networks:
bid-net:
driver: bridge

7
deploy/init-sql/01-init.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
# Wait for MySQL to be ready - handled by healthcheck
echo 'Running RuoYi system SQL...'
mysql -u root -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE" < /docker-entrypoint-initdb.d/02-ry-vue.sql
echo 'Running bid tables SQL...'
mysql -u root -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE" < /docker-entrypoint-initdb.d/03-bid-tables.sql
echo 'Init complete.'

View File

@@ -0,0 +1,723 @@
-- ----------------------------
-- 1、部门表
-- ----------------------------
drop table if exists sys_dept;
create table sys_dept (
dept_id bigint(20) not null auto_increment comment '部门id',
parent_id bigint(20) default 0 comment '父部门id',
ancestors varchar(50) default '' comment '祖级列表',
dept_name varchar(30) default '' comment '部门名称',
order_num int(4) default 0 comment '显示顺序',
leader varchar(20) default null comment '负责人',
phone varchar(11) default null comment '联系电话',
email varchar(50) default null comment '邮箱',
status char(1) default '0' comment '部门状态0正常 1停用',
del_flag char(1) default '0' comment '删除标志0代表存在 2代表删除',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
primary key (dept_id)
) engine=innodb auto_increment=200 comment = '部门表';
-- ----------------------------
-- 初始化-部门表数据
-- ----------------------------
insert into sys_dept values(100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
insert into sys_dept values(101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null);
-- ----------------------------
-- 2、用户信息表
-- ----------------------------
drop table if exists sys_user;
create table sys_user (
user_id bigint(20) not null auto_increment comment '用户ID',
dept_id bigint(20) default null comment '部门ID',
user_name varchar(30) not null comment '用户账号',
nick_name varchar(30) not null comment '用户昵称',
user_type varchar(2) default '00' comment '用户类型00系统用户',
email varchar(50) default '' comment '用户邮箱',
phonenumber varchar(11) default '' comment '手机号码',
sex char(1) default '0' comment '用户性别0男 1女 2未知',
avatar varchar(100) default '' comment '头像地址',
password varchar(100) default '' comment '密码',
status char(1) default '0' comment '账号状态0正常 1停用',
del_flag char(1) default '0' comment '删除标志0代表存在 2代表删除',
login_ip varchar(128) default '' comment '最后登录IP',
login_date datetime comment '最后登录时间',
pwd_update_date datetime comment '密码最后更新时间',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default null comment '备注',
primary key (user_id)
) engine=innodb auto_increment=100 comment = '用户信息表';
-- ----------------------------
-- 初始化-用户信息表数据
-- ----------------------------
insert into sys_user values(1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), sysdate(), 'admin', sysdate(), '', null, '管理员');
insert into sys_user values(2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), sysdate(), 'admin', sysdate(), '', null, '测试员');
-- ----------------------------
-- 3、岗位信息表
-- ----------------------------
drop table if exists sys_post;
create table sys_post
(
post_id bigint(20) not null auto_increment comment '岗位ID',
post_code varchar(64) not null comment '岗位编码',
post_name varchar(50) not null comment '岗位名称',
post_sort int(4) not null comment '显示顺序',
status char(1) not null comment '状态0正常 1停用',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default null comment '备注',
primary key (post_id)
) engine=innodb comment = '岗位信息表';
-- ----------------------------
-- 初始化-岗位信息表数据
-- ----------------------------
insert into sys_post values(1, 'ceo', '董事长', 1, '0', 'admin', sysdate(), '', null, '');
insert into sys_post values(2, 'se', '项目经理', 2, '0', 'admin', sysdate(), '', null, '');
insert into sys_post values(3, 'hr', '人力资源', 3, '0', 'admin', sysdate(), '', null, '');
insert into sys_post values(4, 'user', '普通员工', 4, '0', 'admin', sysdate(), '', null, '');
-- ----------------------------
-- 4、角色信息表
-- ----------------------------
drop table if exists sys_role;
create table sys_role (
role_id bigint(20) not null auto_increment comment '角色ID',
role_name varchar(30) not null comment '角色名称',
role_key varchar(100) not null comment '角色权限字符串',
role_sort int(4) not null comment '显示顺序',
data_scope char(1) default '1' comment '数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限',
menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示',
dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示',
status char(1) not null comment '角色状态0正常 1停用',
del_flag char(1) default '0' comment '删除标志0代表存在 2代表删除',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default null comment '备注',
primary key (role_id)
) engine=innodb auto_increment=100 comment = '角色信息表';
-- ----------------------------
-- 初始化-角色信息表数据
-- ----------------------------
insert into sys_role values('1', '超级管理员', 'admin', 1, 1, 1, 1, '0', '0', 'admin', sysdate(), '', null, '超级管理员');
insert into sys_role values('2', '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', sysdate(), '', null, '普通角色');
-- ----------------------------
-- 5、菜单权限表
-- ----------------------------
drop table if exists sys_menu;
create table sys_menu (
menu_id bigint(20) not null auto_increment comment '菜单ID',
menu_name varchar(50) not null comment '菜单名称',
parent_id bigint(20) default 0 comment '父菜单ID',
order_num int(4) default 0 comment '显示顺序',
path varchar(200) default '' comment '路由地址',
component varchar(255) default null comment '组件路径',
query varchar(255) default null comment '路由参数',
route_name varchar(50) default '' comment '路由名称',
is_frame int(1) default 1 comment '是否为外链0是 1否',
is_cache int(1) default 0 comment '是否缓存0缓存 1不缓存',
menu_type char(1) default '' comment '菜单类型M目录 C菜单 F按钮',
visible char(1) default 0 comment '菜单状态0显示 1隐藏',
status char(1) default 0 comment '菜单状态0正常 1停用',
perms varchar(100) default null comment '权限标识',
icon varchar(100) default '#' comment '菜单图标',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default '' comment '备注',
primary key (menu_id)
) engine=innodb auto_increment=2000 comment = '菜单权限表';
-- ----------------------------
-- 初始化-菜单信息表数据
-- ----------------------------
-- 一级菜单
insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录');
insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录');
insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null, '', '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址');
-- 二级菜单
insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单');
insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单');
insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单');
insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单');
insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单');
insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单');
insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单');
insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单');
insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单');
insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单');
insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单');
insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单');
insert into sys_menu values('112', '服务监控', '2', '4', 'server', 'monitor/server/index', '', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单');
insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单');
insert into sys_menu values('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', sysdate(), '', null, '缓存列表菜单');
insert into sys_menu values('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单');
insert into sys_menu values('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单');
insert into sys_menu values('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单');
-- 三级菜单
insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单');
insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单');
-- 用户管理按钮
insert into sys_menu values('1000', '用户查询', '100', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1001', '用户新增', '100', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1002', '用户修改', '100', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1003', '用户删除', '100', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1004', '用户导出', '100', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1005', '用户导入', '100', '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1006', '重置密码', '100', '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, '');
-- 角色管理按钮
insert into sys_menu values('1007', '角色查询', '101', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1008', '角色新增', '101', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1009', '角色修改', '101', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1010', '角色删除', '101', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1011', '角色导出', '101', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, '');
-- 菜单管理按钮
insert into sys_menu values('1012', '菜单查询', '102', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1013', '菜单新增', '102', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1014', '菜单修改', '102', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1015', '菜单删除', '102', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, '');
-- 部门管理按钮
insert into sys_menu values('1016', '部门查询', '103', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1017', '部门新增', '103', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1018', '部门修改', '103', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1019', '部门删除', '103', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, '');
-- 岗位管理按钮
insert into sys_menu values('1020', '岗位查询', '104', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1021', '岗位新增', '104', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1022', '岗位修改', '104', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1023', '岗位删除', '104', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1024', '岗位导出', '104', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, '');
-- 字典管理按钮
insert into sys_menu values('1025', '字典查询', '105', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1026', '字典新增', '105', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1027', '字典修改', '105', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1028', '字典删除', '105', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1029', '字典导出', '105', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, '');
-- 参数设置按钮
insert into sys_menu values('1030', '参数查询', '106', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1031', '参数新增', '106', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1032', '参数修改', '106', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1033', '参数删除', '106', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1034', '参数导出', '106', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, '');
-- 通知公告按钮
insert into sys_menu values('1035', '公告查询', '107', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1036', '公告新增', '107', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1037', '公告修改', '107', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1038', '公告删除', '107', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, '');
-- 操作日志按钮
insert into sys_menu values('1039', '操作查询', '500', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1040', '操作删除', '500', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1041', '日志导出', '500', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, '');
-- 登录日志按钮
insert into sys_menu values('1042', '登录查询', '501', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1043', '登录删除', '501', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1044', '日志导出', '501', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1045', '账户解锁', '501', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, '');
-- 在线用户按钮
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, '');
-- 定时任务按钮
insert into sys_menu values('1049', '任务查询', '110', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1050', '任务新增', '110', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1051', '任务修改', '110', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1052', '任务删除', '110', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1053', '状态修改', '110', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1054', '任务导出', '110', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', sysdate(), '', null, '');
-- 代码生成按钮
insert into sys_menu values('1055', '生成查询', '116', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1056', '生成修改', '116', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1057', '生成删除', '116', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1058', '导入代码', '116', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1059', '预览代码', '116', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1060', '生成代码', '116', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, '');
-- ----------------------------
-- 6、用户和角色关联表 用户N-1角色
-- ----------------------------
drop table if exists sys_user_role;
create table sys_user_role (
user_id bigint(20) not null comment '用户ID',
role_id bigint(20) not null comment '角色ID',
primary key(user_id, role_id)
) engine=innodb comment = '用户和角色关联表';
-- ----------------------------
-- 初始化-用户和角色关联表数据
-- ----------------------------
insert into sys_user_role values ('1', '1');
insert into sys_user_role values ('2', '2');
-- ----------------------------
-- 7、角色和菜单关联表 角色1-N菜单
-- ----------------------------
drop table if exists sys_role_menu;
create table sys_role_menu (
role_id bigint(20) not null comment '角色ID',
menu_id bigint(20) not null comment '菜单ID',
primary key(role_id, menu_id)
) engine=innodb comment = '角色和菜单关联表';
-- ----------------------------
-- 初始化-角色和菜单关联表数据
-- ----------------------------
insert into sys_role_menu values ('2', '1');
insert into sys_role_menu values ('2', '2');
insert into sys_role_menu values ('2', '3');
insert into sys_role_menu values ('2', '4');
insert into sys_role_menu values ('2', '100');
insert into sys_role_menu values ('2', '101');
insert into sys_role_menu values ('2', '102');
insert into sys_role_menu values ('2', '103');
insert into sys_role_menu values ('2', '104');
insert into sys_role_menu values ('2', '105');
insert into sys_role_menu values ('2', '106');
insert into sys_role_menu values ('2', '107');
insert into sys_role_menu values ('2', '108');
insert into sys_role_menu values ('2', '109');
insert into sys_role_menu values ('2', '110');
insert into sys_role_menu values ('2', '111');
insert into sys_role_menu values ('2', '112');
insert into sys_role_menu values ('2', '113');
insert into sys_role_menu values ('2', '114');
insert into sys_role_menu values ('2', '115');
insert into sys_role_menu values ('2', '116');
insert into sys_role_menu values ('2', '117');
insert into sys_role_menu values ('2', '500');
insert into sys_role_menu values ('2', '501');
insert into sys_role_menu values ('2', '1000');
insert into sys_role_menu values ('2', '1001');
insert into sys_role_menu values ('2', '1002');
insert into sys_role_menu values ('2', '1003');
insert into sys_role_menu values ('2', '1004');
insert into sys_role_menu values ('2', '1005');
insert into sys_role_menu values ('2', '1006');
insert into sys_role_menu values ('2', '1007');
insert into sys_role_menu values ('2', '1008');
insert into sys_role_menu values ('2', '1009');
insert into sys_role_menu values ('2', '1010');
insert into sys_role_menu values ('2', '1011');
insert into sys_role_menu values ('2', '1012');
insert into sys_role_menu values ('2', '1013');
insert into sys_role_menu values ('2', '1014');
insert into sys_role_menu values ('2', '1015');
insert into sys_role_menu values ('2', '1016');
insert into sys_role_menu values ('2', '1017');
insert into sys_role_menu values ('2', '1018');
insert into sys_role_menu values ('2', '1019');
insert into sys_role_menu values ('2', '1020');
insert into sys_role_menu values ('2', '1021');
insert into sys_role_menu values ('2', '1022');
insert into sys_role_menu values ('2', '1023');
insert into sys_role_menu values ('2', '1024');
insert into sys_role_menu values ('2', '1025');
insert into sys_role_menu values ('2', '1026');
insert into sys_role_menu values ('2', '1027');
insert into sys_role_menu values ('2', '1028');
insert into sys_role_menu values ('2', '1029');
insert into sys_role_menu values ('2', '1030');
insert into sys_role_menu values ('2', '1031');
insert into sys_role_menu values ('2', '1032');
insert into sys_role_menu values ('2', '1033');
insert into sys_role_menu values ('2', '1034');
insert into sys_role_menu values ('2', '1035');
insert into sys_role_menu values ('2', '1036');
insert into sys_role_menu values ('2', '1037');
insert into sys_role_menu values ('2', '1038');
insert into sys_role_menu values ('2', '1039');
insert into sys_role_menu values ('2', '1040');
insert into sys_role_menu values ('2', '1041');
insert into sys_role_menu values ('2', '1042');
insert into sys_role_menu values ('2', '1043');
insert into sys_role_menu values ('2', '1044');
insert into sys_role_menu values ('2', '1045');
insert into sys_role_menu values ('2', '1046');
insert into sys_role_menu values ('2', '1047');
insert into sys_role_menu values ('2', '1048');
insert into sys_role_menu values ('2', '1049');
insert into sys_role_menu values ('2', '1050');
insert into sys_role_menu values ('2', '1051');
insert into sys_role_menu values ('2', '1052');
insert into sys_role_menu values ('2', '1053');
insert into sys_role_menu values ('2', '1054');
insert into sys_role_menu values ('2', '1055');
insert into sys_role_menu values ('2', '1056');
insert into sys_role_menu values ('2', '1057');
insert into sys_role_menu values ('2', '1058');
insert into sys_role_menu values ('2', '1059');
insert into sys_role_menu values ('2', '1060');
-- ----------------------------
-- 8、角色和部门关联表 角色1-N部门
-- ----------------------------
drop table if exists sys_role_dept;
create table sys_role_dept (
role_id bigint(20) not null comment '角色ID',
dept_id bigint(20) not null comment '部门ID',
primary key(role_id, dept_id)
) engine=innodb comment = '角色和部门关联表';
-- ----------------------------
-- 初始化-角色和部门关联表数据
-- ----------------------------
insert into sys_role_dept values ('2', '100');
insert into sys_role_dept values ('2', '101');
insert into sys_role_dept values ('2', '105');
-- ----------------------------
-- 9、用户与岗位关联表 用户1-N岗位
-- ----------------------------
drop table if exists sys_user_post;
create table sys_user_post
(
user_id bigint(20) not null comment '用户ID',
post_id bigint(20) not null comment '岗位ID',
primary key (user_id, post_id)
) engine=innodb comment = '用户与岗位关联表';
-- ----------------------------
-- 初始化-用户与岗位关联表数据
-- ----------------------------
insert into sys_user_post values ('1', '1');
insert into sys_user_post values ('2', '2');
-- ----------------------------
-- 10、操作日志记录
-- ----------------------------
drop table if exists sys_oper_log;
create table sys_oper_log (
oper_id bigint(20) not null auto_increment comment '日志主键',
title varchar(50) default '' comment '模块标题',
business_type int(2) default 0 comment '业务类型0其它 1新增 2修改 3删除',
method varchar(200) default '' comment '方法名称',
request_method varchar(10) default '' comment '请求方式',
operator_type int(1) default 0 comment '操作类别0其它 1后台用户 2手机端用户',
oper_name varchar(50) default '' comment '操作人员',
dept_name varchar(50) default '' comment '部门名称',
oper_url varchar(255) default '' comment '请求URL',
oper_ip varchar(128) default '' comment '主机地址',
oper_location varchar(255) default '' comment '操作地点',
oper_param varchar(2000) default '' comment '请求参数',
json_result varchar(2000) default '' comment '返回参数',
status int(1) default 0 comment '操作状态0正常 1异常',
error_msg varchar(2000) default '' comment '错误消息',
oper_time datetime comment '操作时间',
cost_time bigint(20) default 0 comment '消耗时间',
primary key (oper_id),
key idx_sys_oper_log_bt (business_type),
key idx_sys_oper_log_s (status),
key idx_sys_oper_log_ot (oper_time)
) engine=innodb auto_increment=100 comment = '操作日志记录';
-- ----------------------------
-- 11、字典类型表
-- ----------------------------
drop table if exists sys_dict_type;
create table sys_dict_type
(
dict_id bigint(20) not null auto_increment comment '字典主键',
dict_name varchar(100) default '' comment '字典名称',
dict_type varchar(100) default '' comment '字典类型',
status char(1) default '0' comment '状态0正常 1停用',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default null comment '备注',
primary key (dict_id),
unique (dict_type)
) engine=innodb auto_increment=100 comment = '字典类型表';
insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate(), '', null, '用户性别列表');
insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate(), '', null, '菜单状态列表');
insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate(), '', null, '系统开关列表');
insert into sys_dict_type values(4, '任务状态', 'sys_job_status', '0', 'admin', sysdate(), '', null, '任务状态列表');
insert into sys_dict_type values(5, '任务分组', 'sys_job_group', '0', 'admin', sysdate(), '', null, '任务分组列表');
insert into sys_dict_type values(6, '系统是否', 'sys_yes_no', '0', 'admin', sysdate(), '', null, '系统是否列表');
insert into sys_dict_type values(7, '通知类型', 'sys_notice_type', '0', 'admin', sysdate(), '', null, '通知类型列表');
insert into sys_dict_type values(8, '通知状态', 'sys_notice_status', '0', 'admin', sysdate(), '', null, '通知状态列表');
insert into sys_dict_type values(9, '操作类型', 'sys_oper_type', '0', 'admin', sysdate(), '', null, '操作类型列表');
insert into sys_dict_type values(10, '系统状态', 'sys_common_status', '0', 'admin', sysdate(), '', null, '登录状态列表');
-- ----------------------------
-- 12、字典数据表
-- ----------------------------
drop table if exists sys_dict_data;
create table sys_dict_data
(
dict_code bigint(20) not null auto_increment comment '字典编码',
dict_sort int(4) default 0 comment '字典排序',
dict_label varchar(100) default '' comment '字典标签',
dict_value varchar(100) default '' comment '字典键值',
dict_type varchar(100) default '' comment '字典类型',
css_class varchar(100) default null comment '样式属性(其他样式扩展)',
list_class varchar(100) default null comment '表格回显样式',
is_default char(1) default 'N' comment '是否默认Y是 N否',
status char(1) default '0' comment '状态0正常 1停用',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default null comment '备注',
primary key (dict_code)
) engine=innodb auto_increment=100 comment = '字典数据表';
insert into sys_dict_data values(1, 1, '', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', sysdate(), '', null, '性别男');
insert into sys_dict_data values(2, 2, '', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别女');
insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别未知');
insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '显示菜单');
insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '隐藏菜单');
insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态');
insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态');
insert into sys_dict_data values(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态');
insert into sys_dict_data values(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态');
insert into sys_dict_data values(10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', sysdate(), '', null, '默认分组');
insert into sys_dict_data values(11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', sysdate(), '', null, '系统分组');
insert into sys_dict_data values(12, 1, '', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '系统默认是');
insert into sys_dict_data values(13, 2, '', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '系统默认否');
insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate(), '', null, '通知');
insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告');
insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态');
insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态');
insert into sys_dict_data values(18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '其他操作');
insert into sys_dict_data values(19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作');
insert into sys_dict_data values(20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作');
insert into sys_dict_data values(21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作');
insert into sys_dict_data values(22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '授权操作');
insert into sys_dict_data values(23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导出操作');
insert into sys_dict_data values(24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导入操作');
insert into sys_dict_data values(25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '强退操作');
insert into sys_dict_data values(26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '生成操作');
insert into sys_dict_data values(27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '清空操作');
insert into sys_dict_data values(28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '正常状态');
insert into sys_dict_data values(29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态');
-- ----------------------------
-- 13、参数配置表
-- ----------------------------
drop table if exists sys_config;
create table sys_config (
config_id int(5) not null auto_increment comment '参数主键',
config_name varchar(100) default '' comment '参数名称',
config_key varchar(100) default '' comment '参数键名',
config_value varchar(500) default '' comment '参数键值',
config_type char(1) default 'N' comment '系统内置Y是 N否',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default null comment '备注',
primary key (config_id)
) engine=innodb auto_increment=100 comment = '参数配置表';
insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' );
insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' );
insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark浅色主题theme-light' );
insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', sysdate(), '', null, '是否开启验证码功能true开启false关闭');
insert into sys_config values(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能true开启false关闭');
insert into sys_config values(6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', sysdate(), '', null, '设置登录IP黑名单限制多个匹配项以;分隔,支持匹配(*通配、网段)');
insert into sys_config values(7, '用户管理-初始密码修改策略', 'sys.account.initPasswordModify', '1', 'Y', 'admin', sysdate(), '', null, '0初始密码修改策略关闭没有任何提示1提醒用户如果未修改初始密码则在登录时就会提醒修改密码对话框');
insert into sys_config values(8, '用户管理-账号密码更新周期', 'sys.account.passwordValidateDays', '0', 'Y', 'admin', sysdate(), '', null, '密码更新周期填写数字数据初始化值为0不限制若修改必须为大于0小于365的正整数如果超过这个周期登录系统时则在登录时就会提醒修改密码对话框');
insert into sys_config values(9, '用户管理-密码字符范围', 'sys.account.chrtype', '0', 'Y', 'admin', sysdate(), '', null, '默认任意字符范围0任意密码可以输入任意字符1数字密码只能为0-9数字2英文字母密码只能为a-z和A-Z字母3字母和数字密码必须包含字母数字,4字母数字和特殊字符目前支持的特殊字符包括~!@#$%^&*()-=_+');
-- ----------------------------
-- 14、系统访问记录
-- ----------------------------
drop table if exists sys_logininfor;
create table sys_logininfor (
info_id bigint(20) not null auto_increment comment '访问ID',
user_name varchar(50) default '' comment '用户账号',
ipaddr varchar(128) default '' comment '登录IP地址',
login_location varchar(255) default '' comment '登录地点',
browser varchar(50) default '' comment '浏览器类型',
os varchar(50) default '' comment '操作系统',
status char(1) default '0' comment '登录状态0成功 1失败',
msg varchar(255) default '' comment '提示消息',
login_time datetime comment '访问时间',
primary key (info_id),
key idx_sys_logininfor_s (status),
key idx_sys_logininfor_lt (login_time)
) engine=innodb auto_increment=100 comment = '系统访问记录';
-- ----------------------------
-- 15、定时任务调度表
-- ----------------------------
drop table if exists sys_job;
create table sys_job (
job_id bigint(20) not null auto_increment comment '任务ID',
job_name varchar(64) default '' comment '任务名称',
job_group varchar(64) default 'DEFAULT' comment '任务组名',
invoke_target varchar(500) not null comment '调用目标字符串',
cron_expression varchar(255) default '' comment 'cron执行表达式',
misfire_policy varchar(20) default '3' comment '计划执行错误策略1立即执行 2执行一次 3放弃执行',
concurrent char(1) default '1' comment '是否并发执行0允许 1禁止',
status char(1) default '0' comment '状态0正常 1暂停',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default '' comment '备注信息',
primary key (job_id, job_name, job_group)
) engine=innodb auto_increment=100 comment = '定时任务调度表';
insert into sys_job values(1, '系统默认(无参)', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, '');
insert into sys_job values(2, '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, '');
insert into sys_job values(3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, '');
-- ----------------------------
-- 16、定时任务调度日志表
-- ----------------------------
drop table if exists sys_job_log;
create table sys_job_log (
job_log_id bigint(20) not null auto_increment comment '任务日志ID',
job_name varchar(64) not null comment '任务名称',
job_group varchar(64) not null comment '任务组名',
invoke_target varchar(500) not null comment '调用目标字符串',
job_message varchar(500) comment '日志信息',
status char(1) default '0' comment '执行状态0正常 1失败',
exception_info varchar(2000) default '' comment '异常信息',
start_time datetime comment '执行开始时间',
end_time datetime comment '执行结束时间',
create_time datetime comment '创建时间',
primary key (job_log_id)
) engine=innodb comment = '定时任务调度日志表';
-- ----------------------------
-- 17、通知公告表
-- ----------------------------
drop table if exists sys_notice;
create table sys_notice (
notice_id int(4) not null auto_increment comment '公告ID',
notice_title varchar(50) not null comment '公告标题',
notice_type char(1) not null comment '公告类型1通知 2公告',
notice_content longblob default null comment '公告内容',
status char(1) default '0' comment '公告状态0正常 1关闭',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(255) default null comment '备注',
primary key (notice_id)
) engine=innodb auto_increment=10 comment = '通知公告表';
-- ----------------------------
-- 初始化-公告信息表数据
-- ----------------------------
insert into sys_notice values('1', '温馨提醒2018-07-01 若依新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员');
insert into sys_notice values('2', '维护通知2018-07-01 若依系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员');
insert into sys_notice values('3', '若依开源框架介绍', '1', '<p><span style=\"color: rgb(230, 0, 0);\">项目介绍</span></p><p><font color=\"#333333\">RuoYi开源项目是为企业用户定制的后台脚手架框架为企业打造的一站式解决方案降低企业开发成本提升开发效率。主要包括用户管理、角色管理、部门管理、菜单管理、参数管理、字典管理、</font><span style=\"color: rgb(51, 51, 51);\">岗位管理</span><span style=\"color: rgb(51, 51, 51);\">、定时任务</span><span style=\"color: rgb(51, 51, 51);\">、</span><span style=\"color: rgb(51, 51, 51);\">服务监控、登录日志、操作日志、代码生成等功能。其中还支持多数据源、数据权限、国际化、Redis缓存、Docker部署、滑动验证码、第三方认证登录、分布式事务、</span><font color=\"#333333\">分布式文件存储</font><span style=\"color: rgb(51, 51, 51);\">、分库分表处理等技术特点。</span></p><p><img src=\"https://foruda.gitee.com/images/1773931848342439032/a4d22313_1815095.png\" style=\"width: 64px;\"><br></p><p><span style=\"color: rgb(230, 0, 0);\">官网及演示</span></p><p><span style=\"color: rgb(51, 51, 51);\">若依官网地址:&nbsp;</span><a href=\"http://ruoyi.vip\" target=\"_blank\">http://ruoyi.vip</a><a href=\"http://ruoyi.vip\" target=\"_blank\"></a></p><p><span style=\"color: rgb(51, 51, 51);\">若依文档地址:&nbsp;</span><a href=\"http://doc.ruoyi.vip\" target=\"_blank\">http://doc.ruoyi.vip</a><br></p><p><span style=\"color: rgb(51, 51, 51);\">演示地址【不分离版】:&nbsp;</span><a href=\"http://demo.ruoyi.vip\" target=\"_blank\">http://demo.ruoyi.vip</a></p><p><span style=\"color: rgb(51, 51, 51);\">演示地址【分离版本】:&nbsp;</span><a href=\"http://vue.ruoyi.vip\" target=\"_blank\">http://vue.ruoyi.vip</a></p><p><span style=\"color: rgb(51, 51, 51);\">演示地址【微服务版】:&nbsp;</span><a href=\"http://cloud.ruoyi.vip\" target=\"_blank\">http://cloud.ruoyi.vip</a></p><p><span style=\"color: rgb(51, 51, 51);\">演示地址【移动端版】:&nbsp;</span><a href=\"http://h5.ruoyi.vip\" target=\"_blank\">http://h5.ruoyi.vip</a></p><p><br style=\"color: rgb(48, 49, 51); font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: 12px;\"></p>', '0', 'admin', sysdate(), '', null, '管理员');
-- ----------------------------
-- 18、公告已读记录表
-- ----------------------------
drop table if exists sys_notice_read;
create table sys_notice_read (
read_id bigint(20) not null auto_increment comment '已读主键',
notice_id int(4) not null comment '公告id',
user_id bigint(20) not null comment '用户id',
read_time datetime not null comment '阅读时间',
primary key (read_id),
unique key uk_user_notice (user_id, notice_id) comment '同一用户同一公告只记录一次'
) engine=innodb auto_increment=1 comment='公告已读记录表';
-- ----------------------------
-- 19、代码生成业务表
-- ----------------------------
drop table if exists gen_table;
create table gen_table (
table_id bigint(20) not null auto_increment comment '编号',
table_name varchar(200) default '' comment '表名称',
table_comment varchar(500) default '' comment '表描述',
sub_table_name varchar(64) default null comment '关联子表的表名',
sub_table_fk_name varchar(64) default null comment '子表关联的外键名',
class_name varchar(100) default '' comment '实体类名称',
tpl_category varchar(200) default 'crud' comment '使用的模板crud单表操作 tree树表操作',
tpl_web_type varchar(30) default '' comment '前端模板类型element-ui模版 element-plus模版',
package_name varchar(100) comment '生成包路径',
module_name varchar(30) comment '生成模块名',
business_name varchar(30) comment '生成业务名',
function_name varchar(50) comment '生成功能名',
function_author varchar(50) comment '生成功能作者',
form_col_num int(1) default 1 comment '表单布局(单列 双列 三列)',
gen_type char(1) default '0' comment '生成代码方式0zip压缩包 1自定义路径',
gen_path varchar(200) default '/' comment '生成路径(不填默认项目路径)',
options varchar(1000) comment '其它生成选项',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
remark varchar(500) default null comment '备注',
primary key (table_id)
) engine=innodb auto_increment=1 comment = '代码生成业务表';
-- ----------------------------
-- 20、代码生成业务表字段
-- ----------------------------
drop table if exists gen_table_column;
create table gen_table_column (
column_id bigint(20) not null auto_increment comment '编号',
table_id bigint(20) comment '归属表编号',
column_name varchar(200) comment '列名称',
column_comment varchar(500) comment '列描述',
column_type varchar(100) comment '列类型',
java_type varchar(500) comment 'JAVA类型',
java_field varchar(200) comment 'JAVA字段名',
is_pk char(1) comment '是否主键1是',
is_increment char(1) comment '是否自增1是',
is_required char(1) comment '是否必填1是',
is_insert char(1) comment '是否为插入字段1是',
is_edit char(1) comment '是否编辑字段1是',
is_list char(1) comment '是否列表字段1是',
is_query char(1) comment '是否查询字段1是',
query_type varchar(200) default 'EQ' comment '查询方式(等于、不等于、大于、小于、范围)',
html_type varchar(200) comment '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)',
dict_type varchar(200) default '' comment '字典类型',
sort int comment '排序',
create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间',
update_by varchar(64) default '' comment '更新者',
update_time datetime comment '更新时间',
primary key (column_id)
) engine=innodb auto_increment=1 comment = '代码生成业务表字段';

View File

@@ -0,0 +1,279 @@
-- 智慧报价平台业务表
-- 租户表SaaS买方隔离
CREATE TABLE IF NOT EXISTS biz_tenant (
tenant_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_name VARCHAR(100) NOT NULL COMMENT '租户名称',
contact VARCHAR(50) COMMENT '联系人',
phone VARCHAR(20) COMMENT '联系电话',
email VARCHAR(100) COMMENT '邮箱',
status CHAR(1) DEFAULT '0' COMMENT '0正常 1停用',
create_by VARCHAR(64) DEFAULT '',
create_time DATETIME,
update_by VARCHAR(64) DEFAULT '',
update_time DATETIME,
remark VARCHAR(500) DEFAULT NULL,
PRIMARY KEY (tenant_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户表';
INSERT IGNORE INTO biz_tenant(tenant_id,tenant_name,contact,phone,email,status,create_by,create_time)
VALUES(1,'默认租户','管理员','','admin@example.com','0','admin',NOW());
-- 给 sys_user 增加 tenant_id 字段用于SaaS隔离
ALTER TABLE sys_user ADD COLUMN IF NOT EXISTS tenant_id BIGINT DEFAULT 1 COMMENT '所属租户';
-- 物料分类
CREATE TABLE IF NOT EXISTS biz_material_category (
category_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id BIGINT NOT NULL DEFAULT 1,
category_name VARCHAR(100) NOT NULL,
parent_id BIGINT DEFAULT 0,
ancestors VARCHAR(500) DEFAULT '',
sort INT DEFAULT 0,
status CHAR(1) DEFAULT '0',
create_by VARCHAR(64) DEFAULT '',
create_time DATETIME,
PRIMARY KEY (category_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物料分类';
-- 物料
CREATE TABLE IF NOT EXISTS biz_material (
material_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id BIGINT NOT NULL DEFAULT 1,
category_id BIGINT DEFAULT 0,
material_code VARCHAR(50) NOT NULL COMMENT '物料编码',
material_name VARCHAR(200) NOT NULL COMMENT '物料名称',
spec VARCHAR(500) DEFAULT '' COMMENT '规格型号',
unit VARCHAR(50) DEFAULT '' COMMENT '单位',
brand VARCHAR(100) DEFAULT '' COMMENT '品牌',
description TEXT COMMENT '描述',
status CHAR(1) DEFAULT '0',
create_by VARCHAR(64) DEFAULT '',
create_time DATETIME,
update_by VARCHAR(64) DEFAULT '',
update_time DATETIME,
remark VARCHAR(500) DEFAULT NULL,
PRIMARY KEY (material_id),
UNIQUE KEY uk_code_tenant (tenant_id, material_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物料';
-- 供应商
CREATE TABLE IF NOT EXISTS biz_supplier (
supplier_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id BIGINT NOT NULL DEFAULT 1,
supplier_name VARCHAR(200) NOT NULL,
contact VARCHAR(50) DEFAULT '',
phone VARCHAR(20) DEFAULT '',
email VARCHAR(100) DEFAULT '',
address VARCHAR(500) DEFAULT '',
user_id BIGINT DEFAULT NULL COMMENT '关联系统用户',
status CHAR(1) DEFAULT '0',
create_by VARCHAR(64) DEFAULT '',
create_time DATETIME,
update_by VARCHAR(64) DEFAULT '',
update_time DATETIME,
remark VARCHAR(500) DEFAULT NULL,
PRIMARY KEY (supplier_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='供应商';
-- 报价请求RFQ
CREATE TABLE IF NOT EXISTS biz_rfq (
rfq_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id BIGINT NOT NULL DEFAULT 1,
rfq_no VARCHAR(50) NOT NULL COMMENT 'RFQ编号',
rfq_title VARCHAR(200) NOT NULL COMMENT 'RFQ标题',
deadline DATETIME DEFAULT NULL COMMENT '截止日期',
delivery_addr VARCHAR(500) DEFAULT '' COMMENT '交货地址',
status VARCHAR(20) DEFAULT 'draft' COMMENT 'draft/published/closed/completed',
remark TEXT,
create_by VARCHAR(64) DEFAULT '',
create_time DATETIME,
update_by VARCHAR(64) DEFAULT '',
update_time DATETIME,
PRIMARY KEY (rfq_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报价请求';
-- RFQ物料明细
CREATE TABLE IF NOT EXISTS biz_rfq_item (
item_id BIGINT NOT NULL AUTO_INCREMENT,
rfq_id BIGINT NOT NULL,
material_id BIGINT DEFAULT 0,
material_name VARCHAR(200) NOT NULL,
spec VARCHAR(500) DEFAULT '',
unit VARCHAR(50) DEFAULT '',
quantity DECIMAL(15,4) NOT NULL,
expected_price DECIMAL(15,4) DEFAULT NULL COMMENT '预期单价',
remark VARCHAR(500) DEFAULT '',
PRIMARY KEY (item_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='RFQ物料明细';
-- RFQ邀请供应商
CREATE TABLE IF NOT EXISTS biz_rfq_supplier (
id BIGINT NOT NULL AUTO_INCREMENT,
rfq_id BIGINT NOT NULL,
supplier_id BIGINT NOT NULL,
invited_time DATETIME DEFAULT NULL,
quoted_time DATETIME DEFAULT NULL,
status VARCHAR(20) DEFAULT 'pending' COMMENT 'pending/quoted/declined',
PRIMARY KEY (id),
UNIQUE KEY uk_rfq_supplier (rfq_id, supplier_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='RFQ邀请供应商';
-- 供应商报价单
CREATE TABLE IF NOT EXISTS biz_quotation (
quotation_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id BIGINT NOT NULL DEFAULT 1,
rfq_id BIGINT NOT NULL,
supplier_id BIGINT NOT NULL,
quote_no VARCHAR(50) DEFAULT '' COMMENT '报价单编号',
valid_days INT DEFAULT 30 COMMENT '报价有效天数',
delivery_days INT DEFAULT 0 COMMENT '交货天数',
total_amount DECIMAL(15,4) DEFAULT 0 COMMENT '总金额',
currency VARCHAR(10) DEFAULT 'CNY',
status VARCHAR(20) DEFAULT 'draft' COMMENT 'draft/submitted/accepted/rejected',
note TEXT,
submit_time DATETIME DEFAULT NULL,
create_by VARCHAR(64) DEFAULT '',
create_time DATETIME,
update_time DATETIME,
PRIMARY KEY (quotation_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='供应商报价单';
-- 报价明细
CREATE TABLE IF NOT EXISTS biz_quotation_item (
item_id BIGINT NOT NULL AUTO_INCREMENT,
quotation_id BIGINT NOT NULL,
rfq_item_id BIGINT NOT NULL,
material_name VARCHAR(200) DEFAULT '',
spec VARCHAR(500) DEFAULT '',
unit VARCHAR(50) DEFAULT '',
quantity DECIMAL(15,4) DEFAULT 0,
unit_price DECIMAL(15,4) NOT NULL,
total_price DECIMAL(15,4) DEFAULT 0,
delivery_days INT DEFAULT 0,
remark VARCHAR(500) DEFAULT '',
PRIMARY KEY (item_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报价明细';
-- 采购单
CREATE TABLE IF NOT EXISTS biz_purchase_order (
po_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id BIGINT NOT NULL DEFAULT 1,
po_no VARCHAR(50) NOT NULL COMMENT '采购单编号',
rfq_id BIGINT DEFAULT NULL,
supplier_id BIGINT NOT NULL,
total_amount DECIMAL(15,4) DEFAULT 0,
currency VARCHAR(10) DEFAULT 'CNY',
delivery_addr VARCHAR(500) DEFAULT '',
delivery_date DATE DEFAULT NULL,
status VARCHAR(20) DEFAULT 'draft' COMMENT 'draft/confirmed/delivered/closed/disputed',
remark TEXT,
create_by VARCHAR(64) DEFAULT '',
create_time DATETIME,
update_by VARCHAR(64) DEFAULT '',
update_time DATETIME,
PRIMARY KEY (po_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='采购单';
-- 采购单明细
CREATE TABLE IF NOT EXISTS biz_purchase_order_item (
item_id BIGINT NOT NULL AUTO_INCREMENT,
po_id BIGINT NOT NULL,
material_id BIGINT DEFAULT 0,
material_name VARCHAR(200) NOT NULL,
spec VARCHAR(500) DEFAULT '',
unit VARCHAR(50) DEFAULT '',
quantity DECIMAL(15,4) NOT NULL,
unit_price DECIMAL(15,4) NOT NULL,
total_price DECIMAL(15,4) DEFAULT 0,
remark VARCHAR(500) DEFAULT '',
PRIMARY KEY (item_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='采购单明细';
-- 供应商评价
CREATE TABLE IF NOT EXISTS biz_supplier_evaluation (
eval_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id BIGINT NOT NULL DEFAULT 1,
po_id BIGINT NOT NULL,
supplier_id BIGINT NOT NULL,
quality_score INT DEFAULT 5 COMMENT '质量评分1-5',
delivery_score INT DEFAULT 5 COMMENT '交期评分1-5',
service_score INT DEFAULT 5 COMMENT '服务评分1-5',
price_score INT DEFAULT 5 COMMENT '价格评分1-5',
total_score DECIMAL(3,1) DEFAULT 5.0,
comment TEXT,
evaluator VARCHAR(64) DEFAULT '',
eval_time DATETIME,
PRIMARY KEY (eval_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='供应商评价';
-- 订单异议
CREATE TABLE IF NOT EXISTS biz_order_objection (
objection_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id BIGINT NOT NULL DEFAULT 1,
po_id BIGINT NOT NULL,
supplier_id BIGINT NOT NULL,
reason TEXT NOT NULL COMMENT '异议原因',
attachment VARCHAR(500) DEFAULT '' COMMENT '附件',
status VARCHAR(20) DEFAULT 'pending' COMMENT 'pending/processing/resolved/rejected',
resolution TEXT COMMENT '处理结果',
create_by VARCHAR(64) DEFAULT '',
create_time DATETIME,
resolve_time DATETIME DEFAULT NULL,
PRIMARY KEY (objection_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单异议';
-- 交易记录
CREATE TABLE IF NOT EXISTS biz_transaction (
tx_id BIGINT NOT NULL AUTO_INCREMENT,
tenant_id BIGINT NOT NULL DEFAULT 1,
po_id BIGINT DEFAULT NULL,
supplier_id BIGINT DEFAULT NULL,
tx_type VARCHAR(50) DEFAULT '' COMMENT '类型:RFQ/QUOTE/PO/EVAL',
tx_no VARCHAR(50) DEFAULT '',
amount DECIMAL(15,4) DEFAULT NULL,
currency VARCHAR(10) DEFAULT 'CNY',
description TEXT,
operator VARCHAR(64) DEFAULT '',
tx_time DATETIME,
create_time DATETIME,
PRIMARY KEY (tx_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易记录';
-- 系统菜单(智慧报价平台业务菜单)
INSERT IGNORE INTO sys_menu(menu_id,menu_name,parent_id,order_num,path,component,query,is_frame,is_cache,menu_type,visible,status,perms,icon,create_by,create_time,update_by,update_time,remark)
VALUES
(2000,'智慧报价',0,5,'bid',NULL,NULL,'1','0','M','0','0','','#','admin',NOW(),'','',''),
(2001,'物料管理',2000,1,'material','bid/material/index',NULL,'1','0','C','0','0','bid:material:list','component','admin',NOW(),'','',''),
(2002,'供应商管理',2000,2,'supplier','bid/supplier/index',NULL,'1','0','C','0','0','bid:supplier:list','user','admin',NOW(),'','',''),
(2003,'报价请求',2000,3,'rfq','bid/rfq/index',NULL,'1','0','C','0','0','bid:rfq:list','form','admin',NOW(),'','',''),
(2004,'供应商报价',2000,4,'quotation','bid/quotation/index',NULL,'1','0','C','0','0','bid:quotation:list','money','admin',NOW(),'','',''),
(2005,'智慧比价',2000,5,'comparison','bid/comparison/index',NULL,'1','0','C','0','0','bid:comparison:list','chart','admin',NOW(),'','',''),
(2006,'采购单',2000,6,'purchaseorder','bid/purchaseorder/index',NULL,'1','0','C','0','0','bid:purchaseorder:list','shopping','admin',NOW(),'','',''),
(2007,'供应商评价',2000,7,'evaluation','bid/evaluation/index',NULL,'1','0','C','0','0','bid:evaluation:list','star','admin',NOW(),'','',''),
(2008,'订单异议',2000,8,'objection','bid/objection/index',NULL,'1','0','C','0','0','bid:objection:list','warning','admin',NOW(),'','',''),
(2009,'交易记录',2000,9,'transaction','bid/transaction/index',NULL,'1','0','C','0','0','bid:transaction:list','list','admin',NOW(),'','',''),
(2010,'租户管理',2000,10,'tenant','bid/tenant/index',NULL,'1','0','C','0','0','bid:tenant:list','peoples','admin',NOW(),'','','');
-- 菜单按钮权限
INSERT IGNORE INTO sys_menu(menu_id,menu_name,parent_id,order_num,path,component,query,is_frame,is_cache,menu_type,visible,status,perms,icon,create_by,create_time)
VALUES
(2101,'物料查询',2001,1,'','','','1','0','F','0','0','bid:material:query','#','admin',NOW()),
(2102,'物料新增',2001,2,'','','','1','0','F','0','0','bid:material:add','#','admin',NOW()),
(2103,'物料修改',2001,3,'','','','1','0','F','0','0','bid:material:edit','#','admin',NOW()),
(2104,'物料删除',2001,4,'','','','1','0','F','0','0','bid:material:remove','#','admin',NOW()),
(2201,'供应商查询',2002,1,'','','','1','0','F','0','0','bid:supplier:query','#','admin',NOW()),
(2202,'供应商新增',2002,2,'','','','1','0','F','0','0','bid:supplier:add','#','admin',NOW()),
(2203,'供应商修改',2002,3,'','','','1','0','F','0','0','bid:supplier:edit','#','admin',NOW()),
(2204,'供应商删除',2002,4,'','','','1','0','F','0','0','bid:supplier:remove','#','admin',NOW()),
(2301,'RFQ查询',2003,1,'','','','1','0','F','0','0','bid:rfq:query','#','admin',NOW()),
(2302,'RFQ新增',2003,2,'','','','1','0','F','0','0','bid:rfq:add','#','admin',NOW()),
(2303,'RFQ修改',2003,3,'','','','1','0','F','0','0','bid:rfq:edit','#','admin',NOW()),
(2304,'RFQ删除',2003,4,'','','','1','0','F','0','0','bid:rfq:remove','#','admin',NOW()),
(2305,'发布RFQ',2003,5,'','','','1','0','F','0','0','bid:rfq:publish','#','admin',NOW()),
(2401,'报价查询',2004,1,'','','','1','0','F','0','0','bid:quotation:query','#','admin',NOW()),
(2402,'报价新增',2004,2,'','','','1','0','F','0','0','bid:quotation:add','#','admin',NOW()),
(2403,'报价修改',2004,3,'','','','1','0','F','0','0','bid:quotation:edit','#','admin',NOW()),
(2601,'采购单查询',2006,1,'','','','1','0','F','0','0','bid:purchaseorder:query','#','admin',NOW()),
(2602,'采购单新增',2006,2,'','','','1','0','F','0','0','bid:purchaseorder:add','#','admin',NOW()),
(2603,'采购单修改',2006,3,'','','','1','0','F','0','0','bid:purchaseorder:edit','#','admin',NOW()),
(2604,'采购单删除',2006,4,'','','','1','0','F','0','0','bid:purchaseorder:remove','#','admin',NOW());

35
deploy/nginx.conf Normal file
View File

@@ -0,0 +1,35 @@
server {
listen 80;
server_name _;
charset utf-8;
root /usr/share/nginx/html;
index index.html;
# Frontend - Vue history mode
location / {
try_files $uri $uri/ /index.html;
expires 1h;
}
# Backend API proxy
location /prod-api/ {
proxy_pass http://backend:8080/;
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_connect_timeout 30s;
proxy_read_timeout 120s;
}
# Static assets caching
location ~* \.(js|css|png|jpg|gif|ico|woff|woff2|ttf|svg)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# Gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_min_length 1000;
}

View File

@@ -0,0 +1,20 @@
package com.ruoyi.web.controller.bid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.service.bid.IBizComparisonService;
@RestController
@RequestMapping("/bid/comparison")
public class BizComparisonController extends BaseController {
@Autowired private IBizComparisonService service;
@PreAuthorize("@ss.hasPermi('bid:comparison:list')")
@GetMapping("/rfq/{rfqId}")
public AjaxResult compareRfq(@PathVariable Long rfqId) {
return success(service.compareRfq(rfqId, 1L));
}
}

View File

@@ -0,0 +1,57 @@
package com.ruoyi.web.controller.bid;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.bid.BizMaterial;
import com.ruoyi.system.service.bid.IBizMaterialService;
@RestController
@RequestMapping("/bid/material")
public class BizMaterialController extends BaseController {
@Autowired
private IBizMaterialService service;
@PreAuthorize("@ss.hasPermi('bid:material:list')")
@GetMapping("/list")
public TableDataInfo list(BizMaterial query) {
startPage();
List<BizMaterial> list = service.selectBizMaterialList(query);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('bid:material:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable Long id) {
return success(service.selectBizMaterialById(id));
}
@PreAuthorize("@ss.hasPermi('bid:material:add')")
@Log(title = "物料管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizMaterial record) {
record.setCreateBy(getUsername());
return toAjax(service.insertBizMaterial(record));
}
@PreAuthorize("@ss.hasPermi('bid:material:edit')")
@Log(title = "物料管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody BizMaterial record) {
record.setUpdateBy(getUsername());
return toAjax(service.updateBizMaterial(record));
}
@PreAuthorize("@ss.hasPermi('bid:material:remove')")
@Log(title = "物料管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{materialIds}")
public AjaxResult remove(@PathVariable Long[] materialIds) {
return toAjax(service.deleteBizMaterialByIds(materialIds));
}
}

View File

@@ -0,0 +1,52 @@
package com.ruoyi.web.controller.bid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.bid.BizOrderObjection;
import com.ruoyi.system.service.bid.IBizOrderObjectionService;
@RestController
@RequestMapping("/bid/objection")
public class BizOrderObjectionController extends BaseController {
@Autowired private IBizOrderObjectionService service;
@PreAuthorize("@ss.hasPermi('bid:objection:list')")
@GetMapping("/list")
public TableDataInfo list(BizOrderObjection q) {
startPage();
return getDataTable(service.selectBizOrderObjectionList(q));
}
@PreAuthorize("@ss.hasPermi('bid:objection:query')")
@GetMapping("/{objectionId}")
public AjaxResult getInfo(@PathVariable Long objectionId) {
return success(service.selectBizOrderObjectionById(objectionId));
}
@Log(title = "订单异议", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizOrderObjection record) {
record.setCreateBy(getUsername());
return toAjax(service.insertBizOrderObjection(record));
}
@PreAuthorize("@ss.hasPermi('bid:objection:edit')")
@Log(title = "处理异议", businessType = BusinessType.UPDATE)
@PutMapping("/resolve")
public AjaxResult resolve(@RequestBody BizOrderObjection record) {
record.setStatus("resolved");
return toAjax(service.updateBizOrderObjection(record));
}
@Log(title = "订单异议", businessType = BusinessType.DELETE)
@DeleteMapping("/{objectionIds}")
public AjaxResult remove(@PathVariable Long[] objectionIds) {
return toAjax(service.deleteBizOrderObjectionByIds(objectionIds));
}
}

View File

@@ -0,0 +1,61 @@
package com.ruoyi.web.controller.bid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.bid.BizPurchaseOrder;
import com.ruoyi.system.service.bid.IBizPurchaseOrderService;
@RestController
@RequestMapping("/bid/purchaseorder")
public class BizPurchaseOrderController extends BaseController {
@Autowired private IBizPurchaseOrderService service;
@PreAuthorize("@ss.hasPermi('bid:purchaseorder:list')")
@GetMapping("/list")
public TableDataInfo list(BizPurchaseOrder q) {
startPage();
return getDataTable(service.selectBizPurchaseOrderList(q));
}
@PreAuthorize("@ss.hasPermi('bid:purchaseorder:query')")
@GetMapping("/{poId}")
public AjaxResult getInfo(@PathVariable Long poId) {
return success(service.selectBizPurchaseOrderById(poId));
}
@PreAuthorize("@ss.hasPermi('bid:purchaseorder:add')")
@Log(title = "采购单", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizPurchaseOrder po) {
po.setCreateBy(getUsername());
return toAjax(service.insertBizPurchaseOrder(po));
}
@PreAuthorize("@ss.hasPermi('bid:purchaseorder:edit')")
@Log(title = "采购单", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody BizPurchaseOrder po) {
po.setUpdateBy(getUsername());
return toAjax(service.updateBizPurchaseOrder(po));
}
@PreAuthorize("@ss.hasPermi('bid:purchaseorder:edit')")
@Log(title = "确认采购单", businessType = BusinessType.UPDATE)
@PutMapping("/confirm/{poId}")
public AjaxResult confirm(@PathVariable Long poId) {
return toAjax(service.confirmOrder(poId));
}
@PreAuthorize("@ss.hasPermi('bid:purchaseorder:remove')")
@Log(title = "采购单", businessType = BusinessType.DELETE)
@DeleteMapping("/{poIds}")
public AjaxResult remove(@PathVariable Long[] poIds) {
return toAjax(service.deleteBizPurchaseOrderByIds(poIds));
}
}

View File

@@ -0,0 +1,73 @@
package com.ruoyi.web.controller.bid;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.bid.BizQuotation;
import com.ruoyi.system.service.bid.IBizQuotationService;
@RestController
@RequestMapping("/bid/quotation")
public class BizQuotationController extends BaseController {
@Autowired private IBizQuotationService service;
@PreAuthorize("@ss.hasPermi('bid:quotation:list')")
@GetMapping("/list")
public TableDataInfo list(BizQuotation q) {
startPage();
return getDataTable(service.selectBizQuotationList(q));
}
@PreAuthorize("@ss.hasPermi('bid:quotation:query')")
@GetMapping("/{quotationId}")
public AjaxResult getInfo(@PathVariable Long quotationId) {
return success(service.selectBizQuotationById(quotationId));
}
@PreAuthorize("@ss.hasPermi('bid:quotation:add')")
@Log(title = "报价单", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizQuotation q) {
q.setCreateBy(getUsername());
return toAjax(service.insertBizQuotation(q));
}
@PreAuthorize("@ss.hasPermi('bid:quotation:edit')")
@Log(title = "报价单", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody BizQuotation q) {
return toAjax(service.updateBizQuotation(q));
}
@PreAuthorize("@ss.hasPermi('bid:quotation:edit')")
@Log(title = "提交报价", businessType = BusinessType.UPDATE)
@PutMapping("/submit/{quotationId}")
public AjaxResult submit(@PathVariable Long quotationId) {
return toAjax(service.submitQuotation(quotationId));
}
@PreAuthorize("@ss.hasPermi('bid:quotation:edit')")
@PutMapping("/accept/{quotationId}")
public AjaxResult accept(@PathVariable Long quotationId) {
return toAjax(service.acceptQuotation(quotationId));
}
@PreAuthorize("@ss.hasPermi('bid:quotation:edit')")
@PutMapping("/reject/{quotationId}")
public AjaxResult reject(@PathVariable Long quotationId) {
return toAjax(service.rejectQuotation(quotationId));
}
@PreAuthorize("@ss.hasPermi('bid:quotation:remove')")
@Log(title = "报价单", businessType = BusinessType.DELETE)
@DeleteMapping("/{quotationIds}")
public AjaxResult remove(@PathVariable Long[] quotationIds) {
return toAjax(service.deleteBizQuotationByIds(quotationIds));
}
}

View File

@@ -0,0 +1,69 @@
package com.ruoyi.web.controller.bid;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.bid.BizRfq;
import com.ruoyi.system.domain.bid.BizRfqItem;
import com.ruoyi.system.service.bid.IBizRfqService;
@RestController
@RequestMapping("/bid/rfq")
public class BizRfqController extends BaseController {
@Autowired private IBizRfqService service;
@PreAuthorize("@ss.hasPermi('bid:rfq:list')")
@GetMapping("/list")
public TableDataInfo list(BizRfq query) {
startPage();
return getDataTable(service.selectBizRfqList(query));
}
@PreAuthorize("@ss.hasPermi('bid:rfq:query')")
@GetMapping("/{rfqId}")
public AjaxResult getInfo(@PathVariable Long rfqId) {
return success(service.selectBizRfqById(rfqId));
}
@PreAuthorize("@ss.hasPermi('bid:rfq:query')")
@GetMapping("/{rfqId}/items")
public AjaxResult getItems(@PathVariable Long rfqId) {
return success(service.selectItemsByRfqId(rfqId));
}
@PreAuthorize("@ss.hasPermi('bid:rfq:add')")
@Log(title = "报价请求", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizRfq rfq) {
rfq.setCreateBy(getUsername());
return toAjax(service.insertBizRfq(rfq));
}
@PreAuthorize("@ss.hasPermi('bid:rfq:edit')")
@Log(title = "报价请求", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody BizRfq rfq) {
rfq.setUpdateBy(getUsername());
return toAjax(service.updateBizRfq(rfq));
}
@PreAuthorize("@ss.hasPermi('bid:rfq:publish')")
@Log(title = "发布RFQ", businessType = BusinessType.UPDATE)
@PutMapping("/publish/{rfqId}")
public AjaxResult publish(@PathVariable Long rfqId, @RequestBody Long[] supplierIds) {
return toAjax(service.publishRfq(rfqId, supplierIds));
}
@PreAuthorize("@ss.hasPermi('bid:rfq:remove')")
@Log(title = "报价请求", businessType = BusinessType.DELETE)
@DeleteMapping("/{rfqIds}")
public AjaxResult remove(@PathVariable Long[] rfqIds) {
return toAjax(service.deleteBizRfqByIds(rfqIds));
}
}

View File

@@ -0,0 +1,57 @@
package com.ruoyi.web.controller.bid;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.bid.BizSupplier;
import com.ruoyi.system.service.bid.IBizSupplierService;
@RestController
@RequestMapping("/bid/supplier")
public class BizSupplierController extends BaseController {
@Autowired
private IBizSupplierService service;
@PreAuthorize("@ss.hasPermi('bid:supplier:list')")
@GetMapping("/list")
public TableDataInfo list(BizSupplier query) {
startPage();
List<BizSupplier> list = service.selectBizSupplierList(query);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('bid:supplier:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable Long id) {
return success(service.selectBizSupplierById(id));
}
@PreAuthorize("@ss.hasPermi('bid:supplier:add')")
@Log(title = "供应商管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizSupplier record) {
record.setCreateBy(getUsername());
return toAjax(service.insertBizSupplier(record));
}
@PreAuthorize("@ss.hasPermi('bid:supplier:edit')")
@Log(title = "供应商管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody BizSupplier record) {
record.setUpdateBy(getUsername());
return toAjax(service.updateBizSupplier(record));
}
@PreAuthorize("@ss.hasPermi('bid:supplier:remove')")
@Log(title = "供应商管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{supplierIds}")
public AjaxResult remove(@PathVariable Long[] supplierIds) {
return toAjax(service.deleteBizSupplierByIds(supplierIds));
}
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.web.controller.bid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.bid.BizSupplierEvaluation;
import com.ruoyi.system.service.bid.IBizSupplierEvaluationService;
@RestController
@RequestMapping("/bid/evaluation")
public class BizSupplierEvaluationController extends BaseController {
@Autowired private IBizSupplierEvaluationService service;
@PreAuthorize("@ss.hasPermi('bid:evaluation:list')")
@GetMapping("/list")
public TableDataInfo list(BizSupplierEvaluation q) {
startPage();
return getDataTable(service.selectBizSupplierEvaluationList(q));
}
@PreAuthorize("@ss.hasPermi('bid:evaluation:query')")
@GetMapping("/{evalId}")
public AjaxResult getInfo(@PathVariable Long evalId) {
return success(service.selectBizSupplierEvaluationById(evalId));
}
@Log(title = "供应商评价", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizSupplierEvaluation record) {
record.setEvaluator(getUsername());
return toAjax(service.insertBizSupplierEvaluation(record));
}
@Log(title = "供应商评价", businessType = BusinessType.DELETE)
@DeleteMapping("/{evalIds}")
public AjaxResult remove(@PathVariable Long[] evalIds) {
return toAjax(service.deleteBizSupplierEvaluationByIds(evalIds));
}
}

View File

@@ -0,0 +1,57 @@
package com.ruoyi.web.controller.bid;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.bid.BizTenant;
import com.ruoyi.system.service.bid.IBizTenantService;
@RestController
@RequestMapping("/bid/tenant")
public class BizTenantController extends BaseController {
@Autowired
private IBizTenantService service;
@PreAuthorize("@ss.hasPermi('bid:tenant:list')")
@GetMapping("/list")
public TableDataInfo list(BizTenant query) {
startPage();
List<BizTenant> list = service.selectBizTenantList(query);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('bid:tenant:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable Long id) {
return success(service.selectBizTenantById(id));
}
@PreAuthorize("@ss.hasPermi('bid:tenant:add')")
@Log(title = "租户管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BizTenant record) {
record.setCreateBy(getUsername());
return toAjax(service.insertBizTenant(record));
}
@PreAuthorize("@ss.hasPermi('bid:tenant:edit')")
@Log(title = "租户管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody BizTenant record) {
record.setUpdateBy(getUsername());
return toAjax(service.updateBizTenant(record));
}
@PreAuthorize("@ss.hasPermi('bid:tenant:remove')")
@Log(title = "租户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{tenantIds}")
public AjaxResult remove(@PathVariable Long[] tenantIds) {
return toAjax(service.deleteBizTenantByIds(tenantIds));
}
}

View File

@@ -0,0 +1,29 @@
package com.ruoyi.web.controller.bid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.bid.BizTransaction;
import com.ruoyi.system.service.bid.IBizTransactionService;
@RestController
@RequestMapping("/bid/transaction")
public class BizTransactionController extends BaseController {
@Autowired private IBizTransactionService service;
@PreAuthorize("@ss.hasPermi('bid:transaction:list')")
@GetMapping("/list")
public TableDataInfo list(BizTransaction q) {
startPage();
return getDataTable(service.selectBizTransactionList(q));
}
@PreAuthorize("@ss.hasPermi('bid:transaction:query')")
@GetMapping("/{txId}")
public AjaxResult getInfo(@PathVariable Long txId) {
return success(service.selectBizTransactionById(txId));
}
}

View File

@@ -0,0 +1,50 @@
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
master:
url: ${SPRING_DATASOURCE_URL:jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8}
username: ${SPRING_DATASOURCE_USERNAME:root}
password: ${SPRING_DATASOURCE_PASSWORD:password}
slave:
enabled: false
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
connectTimeout: 30000
socketTimeout: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
maxEvictableIdleTimeMillis: 900000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: false
filter:
stat:
enabled: true
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
redis:
host: ${SPRING_REDIS_HOST:localhost}
port: ${SPRING_REDIS_PORT:6379}
password: ${SPRING_REDIS_PASSWORD:}
database: 0
timeout: 10s
lettuce:
pool:
min-idle: 0
max-idle: 8
max-active: 8
max-wait: -1ms

View File

@@ -0,0 +1,54 @@
package com.ruoyi.system.domain.bid;
import java.math.BigDecimal;
import java.util.List;
public class BizComparisonVO {
private Long rfqItemId;
private String materialName;
private String spec;
private String unit;
private BigDecimal quantity;
private List<BizComparisonVO.SupplierPrice> prices;
public static class SupplierPrice {
private Long supplierId;
private String supplierName;
private Long quotationId;
private String quoteNo;
private BigDecimal unitPrice;
private BigDecimal totalPrice;
private Integer deliveryDays;
private boolean lowestPrice;
public Long getSupplierId() { return supplierId; }
public void setSupplierId(Long supplierId) { this.supplierId = supplierId; }
public String getSupplierName() { return supplierName; }
public void setSupplierName(String supplierName) { this.supplierName = supplierName; }
public Long getQuotationId() { return quotationId; }
public void setQuotationId(Long quotationId) { this.quotationId = quotationId; }
public String getQuoteNo() { return quoteNo; }
public void setQuoteNo(String quoteNo) { this.quoteNo = quoteNo; }
public BigDecimal getUnitPrice() { return unitPrice; }
public void setUnitPrice(BigDecimal unitPrice) { this.unitPrice = unitPrice; }
public BigDecimal getTotalPrice() { return totalPrice; }
public void setTotalPrice(BigDecimal totalPrice) { this.totalPrice = totalPrice; }
public Integer getDeliveryDays() { return deliveryDays; }
public void setDeliveryDays(Integer deliveryDays) { this.deliveryDays = deliveryDays; }
public boolean isLowestPrice() { return lowestPrice; }
public void setLowestPrice(boolean lowestPrice) { this.lowestPrice = lowestPrice; }
}
public Long getRfqItemId() { return rfqItemId; }
public void setRfqItemId(Long rfqItemId) { this.rfqItemId = rfqItemId; }
public String getMaterialName() { return materialName; }
public void setMaterialName(String materialName) { this.materialName = materialName; }
public String getSpec() { return spec; }
public void setSpec(String spec) { this.spec = spec; }
public String getUnit() { return unit; }
public void setUnit(String unit) { this.unit = unit; }
public BigDecimal getQuantity() { return quantity; }
public void setQuantity(BigDecimal quantity) { this.quantity = quantity; }
public List<SupplierPrice> getPrices() { return prices; }
public void setPrices(List<SupplierPrice> prices) { this.prices = prices; }
}

View File

@@ -0,0 +1,41 @@
package com.ruoyi.system.domain.bid;
import com.ruoyi.common.core.domain.BaseEntity;
public class BizMaterial extends BaseEntity {
private Long materialId;
private Long tenantId;
private Long categoryId;
private String materialCode;
private String materialName;
private String spec;
private String unit;
private String brand;
private String description;
private String status;
// search helper
private String categoryName;
public Long getMaterialId() { return materialId; }
public void setMaterialId(Long materialId) { this.materialId = materialId; }
public Long getTenantId() { return tenantId; }
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
public Long getCategoryId() { return categoryId; }
public void setCategoryId(Long categoryId) { this.categoryId = categoryId; }
public String getMaterialCode() { return materialCode; }
public void setMaterialCode(String materialCode) { this.materialCode = materialCode; }
public String getMaterialName() { return materialName; }
public void setMaterialName(String materialName) { this.materialName = materialName; }
public String getSpec() { return spec; }
public void setSpec(String spec) { this.spec = spec; }
public String getUnit() { return unit; }
public void setUnit(String unit) { this.unit = unit; }
public String getBrand() { return brand; }
public void setBrand(String brand) { this.brand = brand; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getCategoryName() { return categoryName; }
public void setCategoryName(String categoryName) { this.categoryName = categoryName; }
}

View File

@@ -0,0 +1,49 @@
package com.ruoyi.system.domain.bid;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class BizOrderObjection {
private Long objectionId;
private Long tenantId;
private Long poId;
private Long supplierId;
private String reason;
private String attachment;
private String status;
private String resolution;
private String createBy;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date resolveTime;
private String supplierName;
private String poNo;
public Long getObjectionId() { return objectionId; }
public void setObjectionId(Long objectionId) { this.objectionId = objectionId; }
public Long getTenantId() { return tenantId; }
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
public Long getPoId() { return poId; }
public void setPoId(Long poId) { this.poId = poId; }
public Long getSupplierId() { return supplierId; }
public void setSupplierId(Long supplierId) { this.supplierId = supplierId; }
public String getReason() { return reason; }
public void setReason(String reason) { this.reason = reason; }
public String getAttachment() { return attachment; }
public void setAttachment(String attachment) { this.attachment = attachment; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getResolution() { return resolution; }
public void setResolution(String resolution) { this.resolution = resolution; }
public String getCreateBy() { return createBy; }
public void setCreateBy(String createBy) { this.createBy = createBy; }
public Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; }
public Date getResolveTime() { return resolveTime; }
public void setResolveTime(Date resolveTime) { this.resolveTime = resolveTime; }
public String getSupplierName() { return supplierName; }
public void setSupplierName(String supplierName) { this.supplierName = supplierName; }
public String getPoNo() { return poNo; }
public void setPoNo(String poNo) { this.poNo = poNo; }
}

View File

@@ -0,0 +1,51 @@
package com.ruoyi.system.domain.bid;
import com.ruoyi.common.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
public class BizPurchaseOrder extends BaseEntity {
private Long poId;
private Long tenantId;
private String poNo;
private Long rfqId;
private Long supplierId;
private BigDecimal totalAmount;
private String currency;
private String deliveryAddr;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date deliveryDate;
private String status;
private List<BizPurchaseOrderItem> items;
private String supplierName;
private String rfqTitle;
public Long getPoId() { return poId; }
public void setPoId(Long poId) { this.poId = poId; }
public Long getTenantId() { return tenantId; }
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
public String getPoNo() { return poNo; }
public void setPoNo(String poNo) { this.poNo = poNo; }
public Long getRfqId() { return rfqId; }
public void setRfqId(Long rfqId) { this.rfqId = rfqId; }
public Long getSupplierId() { return supplierId; }
public void setSupplierId(Long supplierId) { this.supplierId = supplierId; }
public BigDecimal getTotalAmount() { return totalAmount; }
public void setTotalAmount(BigDecimal totalAmount) { this.totalAmount = totalAmount; }
public String getCurrency() { return currency; }
public void setCurrency(String currency) { this.currency = currency; }
public String getDeliveryAddr() { return deliveryAddr; }
public void setDeliveryAddr(String deliveryAddr) { this.deliveryAddr = deliveryAddr; }
public Date getDeliveryDate() { return deliveryDate; }
public void setDeliveryDate(Date deliveryDate) { this.deliveryDate = deliveryDate; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public List<BizPurchaseOrderItem> getItems() { return items; }
public void setItems(List<BizPurchaseOrderItem> items) { this.items = items; }
public String getSupplierName() { return supplierName; }
public void setSupplierName(String supplierName) { this.supplierName = supplierName; }
public String getRfqTitle() { return rfqTitle; }
public void setRfqTitle(String rfqTitle) { this.rfqTitle = rfqTitle; }
}

View File

@@ -0,0 +1,37 @@
package com.ruoyi.system.domain.bid;
import java.math.BigDecimal;
public class BizPurchaseOrderItem {
private Long itemId;
private Long poId;
private Long materialId;
private String materialName;
private String spec;
private String unit;
private BigDecimal quantity;
private BigDecimal unitPrice;
private BigDecimal totalPrice;
private String remark;
public Long getItemId() { return itemId; }
public void setItemId(Long itemId) { this.itemId = itemId; }
public Long getPoId() { return poId; }
public void setPoId(Long poId) { this.poId = poId; }
public Long getMaterialId() { return materialId; }
public void setMaterialId(Long materialId) { this.materialId = materialId; }
public String getMaterialName() { return materialName; }
public void setMaterialName(String materialName) { this.materialName = materialName; }
public String getSpec() { return spec; }
public void setSpec(String spec) { this.spec = spec; }
public String getUnit() { return unit; }
public void setUnit(String unit) { this.unit = unit; }
public BigDecimal getQuantity() { return quantity; }
public void setQuantity(BigDecimal quantity) { this.quantity = quantity; }
public BigDecimal getUnitPrice() { return unitPrice; }
public void setUnitPrice(BigDecimal unitPrice) { this.unitPrice = unitPrice; }
public BigDecimal getTotalPrice() { return totalPrice; }
public void setTotalPrice(BigDecimal totalPrice) { this.totalPrice = totalPrice; }
public String getRemark() { return remark; }
public void setRemark(String remark) { this.remark = remark; }
}

View File

@@ -0,0 +1,61 @@
package com.ruoyi.system.domain.bid;
import com.ruoyi.common.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
public class BizQuotation extends BaseEntity {
private Long quotationId;
private Long tenantId;
private Long rfqId;
private Long supplierId;
private String quoteNo;
private Integer validDays;
private Integer deliveryDays;
private BigDecimal totalAmount;
private String currency;
private String status;
private String note;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date submitTime;
private List<BizQuotationItem> items;
// joins
private String supplierName;
private String rfqTitle;
private String rfqNo;
public Long getQuotationId() { return quotationId; }
public void setQuotationId(Long quotationId) { this.quotationId = quotationId; }
public Long getTenantId() { return tenantId; }
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
public Long getRfqId() { return rfqId; }
public void setRfqId(Long rfqId) { this.rfqId = rfqId; }
public Long getSupplierId() { return supplierId; }
public void setSupplierId(Long supplierId) { this.supplierId = supplierId; }
public String getQuoteNo() { return quoteNo; }
public void setQuoteNo(String quoteNo) { this.quoteNo = quoteNo; }
public Integer getValidDays() { return validDays; }
public void setValidDays(Integer validDays) { this.validDays = validDays; }
public Integer getDeliveryDays() { return deliveryDays; }
public void setDeliveryDays(Integer deliveryDays) { this.deliveryDays = deliveryDays; }
public BigDecimal getTotalAmount() { return totalAmount; }
public void setTotalAmount(BigDecimal totalAmount) { this.totalAmount = totalAmount; }
public String getCurrency() { return currency; }
public void setCurrency(String currency) { this.currency = currency; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getNote() { return note; }
public void setNote(String note) { this.note = note; }
public Date getSubmitTime() { return submitTime; }
public void setSubmitTime(Date submitTime) { this.submitTime = submitTime; }
public List<BizQuotationItem> getItems() { return items; }
public void setItems(List<BizQuotationItem> items) { this.items = items; }
public String getSupplierName() { return supplierName; }
public void setSupplierName(String supplierName) { this.supplierName = supplierName; }
public String getRfqTitle() { return rfqTitle; }
public void setRfqTitle(String rfqTitle) { this.rfqTitle = rfqTitle; }
public String getRfqNo() { return rfqNo; }
public void setRfqNo(String rfqNo) { this.rfqNo = rfqNo; }
}

View File

@@ -0,0 +1,40 @@
package com.ruoyi.system.domain.bid;
import java.math.BigDecimal;
public class BizQuotationItem {
private Long itemId;
private Long quotationId;
private Long rfqItemId;
private String materialName;
private String spec;
private String unit;
private BigDecimal quantity;
private BigDecimal unitPrice;
private BigDecimal totalPrice;
private Integer deliveryDays;
private String remark;
public Long getItemId() { return itemId; }
public void setItemId(Long itemId) { this.itemId = itemId; }
public Long getQuotationId() { return quotationId; }
public void setQuotationId(Long quotationId) { this.quotationId = quotationId; }
public Long getRfqItemId() { return rfqItemId; }
public void setRfqItemId(Long rfqItemId) { this.rfqItemId = rfqItemId; }
public String getMaterialName() { return materialName; }
public void setMaterialName(String materialName) { this.materialName = materialName; }
public String getSpec() { return spec; }
public void setSpec(String spec) { this.spec = spec; }
public String getUnit() { return unit; }
public void setUnit(String unit) { this.unit = unit; }
public BigDecimal getQuantity() { return quantity; }
public void setQuantity(BigDecimal quantity) { this.quantity = quantity; }
public BigDecimal getUnitPrice() { return unitPrice; }
public void setUnitPrice(BigDecimal unitPrice) { this.unitPrice = unitPrice; }
public BigDecimal getTotalPrice() { return totalPrice; }
public void setTotalPrice(BigDecimal totalPrice) { this.totalPrice = totalPrice; }
public Integer getDeliveryDays() { return deliveryDays; }
public void setDeliveryDays(Integer deliveryDays) { this.deliveryDays = deliveryDays; }
public String getRemark() { return remark; }
public void setRemark(String remark) { this.remark = remark; }
}

View File

@@ -0,0 +1,38 @@
package com.ruoyi.system.domain.bid;
import com.ruoyi.common.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
import java.util.List;
public class BizRfq extends BaseEntity {
private Long rfqId;
private Long tenantId;
private String rfqNo;
private String rfqTitle;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date deadline;
private String deliveryAddr;
private String status;
private List<BizRfqItem> items;
private List<Long> supplierIds;
public Long getRfqId() { return rfqId; }
public void setRfqId(Long rfqId) { this.rfqId = rfqId; }
public Long getTenantId() { return tenantId; }
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
public String getRfqNo() { return rfqNo; }
public void setRfqNo(String rfqNo) { this.rfqNo = rfqNo; }
public String getRfqTitle() { return rfqTitle; }
public void setRfqTitle(String rfqTitle) { this.rfqTitle = rfqTitle; }
public Date getDeadline() { return deadline; }
public void setDeadline(Date deadline) { this.deadline = deadline; }
public String getDeliveryAddr() { return deliveryAddr; }
public void setDeliveryAddr(String deliveryAddr) { this.deliveryAddr = deliveryAddr; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public List<BizRfqItem> getItems() { return items; }
public void setItems(List<BizRfqItem> items) { this.items = items; }
public List<Long> getSupplierIds() { return supplierIds; }
public void setSupplierIds(List<Long> supplierIds) { this.supplierIds = supplierIds; }
}

View File

@@ -0,0 +1,34 @@
package com.ruoyi.system.domain.bid;
import java.math.BigDecimal;
public class BizRfqItem {
private Long itemId;
private Long rfqId;
private Long materialId;
private String materialName;
private String spec;
private String unit;
private BigDecimal quantity;
private BigDecimal expectedPrice;
private String remark;
public Long getItemId() { return itemId; }
public void setItemId(Long itemId) { this.itemId = itemId; }
public Long getRfqId() { return rfqId; }
public void setRfqId(Long rfqId) { this.rfqId = rfqId; }
public Long getMaterialId() { return materialId; }
public void setMaterialId(Long materialId) { this.materialId = materialId; }
public String getMaterialName() { return materialName; }
public void setMaterialName(String materialName) { this.materialName = materialName; }
public String getSpec() { return spec; }
public void setSpec(String spec) { this.spec = spec; }
public String getUnit() { return unit; }
public void setUnit(String unit) { this.unit = unit; }
public BigDecimal getQuantity() { return quantity; }
public void setQuantity(BigDecimal quantity) { this.quantity = quantity; }
public BigDecimal getExpectedPrice() { return expectedPrice; }
public void setExpectedPrice(BigDecimal expectedPrice) { this.expectedPrice = expectedPrice; }
public String getRemark() { return remark; }
public void setRemark(String remark) { this.remark = remark; }
}

View File

@@ -0,0 +1,34 @@
package com.ruoyi.system.domain.bid;
import com.ruoyi.common.core.domain.BaseEntity;
public class BizSupplier extends BaseEntity {
private Long supplierId;
private Long tenantId;
private String supplierName;
private String contact;
private String phone;
private String email;
private String address;
private Long userId;
private String status;
public Long getSupplierId() { return supplierId; }
public void setSupplierId(Long supplierId) { this.supplierId = supplierId; }
public Long getTenantId() { return tenantId; }
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
public String getSupplierName() { return supplierName; }
public void setSupplierName(String supplierName) { this.supplierName = supplierName; }
public String getContact() { return contact; }
public void setContact(String contact) { this.contact = contact; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
public Long getUserId() { return userId; }
public void setUserId(Long userId) { this.userId = userId; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
}

View File

@@ -0,0 +1,52 @@
package com.ruoyi.system.domain.bid;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.math.BigDecimal;
import java.util.Date;
public class BizSupplierEvaluation {
private Long evalId;
private Long tenantId;
private Long poId;
private Long supplierId;
private Integer qualityScore;
private Integer deliveryScore;
private Integer serviceScore;
private Integer priceScore;
private BigDecimal totalScore;
private String comment;
private String evaluator;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date evalTime;
private String supplierName;
private String poNo;
public Long getEvalId() { return evalId; }
public void setEvalId(Long evalId) { this.evalId = evalId; }
public Long getTenantId() { return tenantId; }
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
public Long getPoId() { return poId; }
public void setPoId(Long poId) { this.poId = poId; }
public Long getSupplierId() { return supplierId; }
public void setSupplierId(Long supplierId) { this.supplierId = supplierId; }
public Integer getQualityScore() { return qualityScore; }
public void setQualityScore(Integer qualityScore) { this.qualityScore = qualityScore; }
public Integer getDeliveryScore() { return deliveryScore; }
public void setDeliveryScore(Integer deliveryScore) { this.deliveryScore = deliveryScore; }
public Integer getServiceScore() { return serviceScore; }
public void setServiceScore(Integer serviceScore) { this.serviceScore = serviceScore; }
public Integer getPriceScore() { return priceScore; }
public void setPriceScore(Integer priceScore) { this.priceScore = priceScore; }
public BigDecimal getTotalScore() { return totalScore; }
public void setTotalScore(BigDecimal totalScore) { this.totalScore = totalScore; }
public String getComment() { return comment; }
public void setComment(String comment) { this.comment = comment; }
public String getEvaluator() { return evaluator; }
public void setEvaluator(String evaluator) { this.evaluator = evaluator; }
public Date getEvalTime() { return evalTime; }
public void setEvalTime(Date evalTime) { this.evalTime = evalTime; }
public String getSupplierName() { return supplierName; }
public void setSupplierName(String supplierName) { this.supplierName = supplierName; }
public String getPoNo() { return poNo; }
public void setPoNo(String poNo) { this.poNo = poNo; }
}

View File

@@ -0,0 +1,35 @@
package com.ruoyi.system.domain.bid;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class BizTenant extends BaseEntity {
private Long tenantId;
private String tenantName;
private String contact;
private String phone;
private String email;
private String status;
public Long getTenantId() { return tenantId; }
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
public String getTenantName() { return tenantName; }
public void setTenantName(String tenantName) { this.tenantName = tenantName; }
public String getContact() { return contact; }
public void setContact(String contact) { this.contact = contact; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("tenantId", getTenantId())
.append("tenantName", getTenantName())
.toString();
}
}

View File

@@ -0,0 +1,60 @@
package com.ruoyi.system.domain.bid;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.math.BigDecimal;
import java.util.Date;
public class BizTransaction {
private Long txId;
private Long tenantId;
private Long poId;
private Long supplierId;
private String txType;
private String txNo;
private BigDecimal amount;
private String currency;
private String description;
private String operator;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date txTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
private String supplierName;
private String poNo;
// search params
private String beginTime;
private String endTime;
public Long getTxId() { return txId; }
public void setTxId(Long txId) { this.txId = txId; }
public Long getTenantId() { return tenantId; }
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
public Long getPoId() { return poId; }
public void setPoId(Long poId) { this.poId = poId; }
public Long getSupplierId() { return supplierId; }
public void setSupplierId(Long supplierId) { this.supplierId = supplierId; }
public String getTxType() { return txType; }
public void setTxType(String txType) { this.txType = txType; }
public String getTxNo() { return txNo; }
public void setTxNo(String txNo) { this.txNo = txNo; }
public BigDecimal getAmount() { return amount; }
public void setAmount(BigDecimal amount) { this.amount = amount; }
public String getCurrency() { return currency; }
public void setCurrency(String currency) { this.currency = currency; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public String getOperator() { return operator; }
public void setOperator(String operator) { this.operator = operator; }
public Date getTxTime() { return txTime; }
public void setTxTime(Date txTime) { this.txTime = txTime; }
public Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; }
public String getSupplierName() { return supplierName; }
public void setSupplierName(String supplierName) { this.supplierName = supplierName; }
public String getPoNo() { return poNo; }
public void setPoNo(String poNo) { this.poNo = poNo; }
public String getBeginTime() { return beginTime; }
public void setBeginTime(String beginTime) { this.beginTime = beginTime; }
public String getEndTime() { return endTime; }
public void setEndTime(String endTime) { this.endTime = endTime; }
}

View File

@@ -0,0 +1,10 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizComparisonVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface BizComparisonMapper {
List<Map<String, Object>> selectComparisonData(@Param("rfqId") Long rfqId, @Param("tenantId") Long tenantId);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizMaterial;
import java.util.List;
public interface BizMaterialMapper {
List<BizMaterial> selectBizMaterialList(BizMaterial query);
BizMaterial selectBizMaterialById(Long id);
int insertBizMaterial(BizMaterial record);
int updateBizMaterial(BizMaterial record);
int deleteBizMaterialById(Long id);
int deleteBizMaterialByIds(Long[] ids);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizOrderObjection;
import java.util.List;
public interface BizOrderObjectionMapper {
List<BizOrderObjection> selectBizOrderObjectionList(BizOrderObjection query);
BizOrderObjection selectBizOrderObjectionById(Long id);
int insertBizOrderObjection(BizOrderObjection record);
int updateBizOrderObjection(BizOrderObjection record);
int deleteBizOrderObjectionById(Long id);
int deleteBizOrderObjectionByIds(Long[] ids);
}

View File

@@ -0,0 +1,10 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizPurchaseOrderItem;
import java.util.List;
public interface BizPurchaseOrderItemMapper {
List<BizPurchaseOrderItem> selectItemsByPoId(Long poId);
int insertBizPurchaseOrderItem(BizPurchaseOrderItem item);
int deleteByPoId(Long poId);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizPurchaseOrder;
import java.util.List;
public interface BizPurchaseOrderMapper {
List<BizPurchaseOrder> selectBizPurchaseOrderList(BizPurchaseOrder query);
BizPurchaseOrder selectBizPurchaseOrderById(Long id);
int insertBizPurchaseOrder(BizPurchaseOrder record);
int updateBizPurchaseOrder(BizPurchaseOrder record);
int deleteBizPurchaseOrderById(Long id);
int deleteBizPurchaseOrderByIds(Long[] ids);
}

View File

@@ -0,0 +1,10 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizQuotationItem;
import java.util.List;
public interface BizQuotationItemMapper {
List<BizQuotationItem> selectItemsByQuotationId(Long quotationId);
int insertBizQuotationItem(BizQuotationItem item);
int deleteByQuotationId(Long quotationId);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizQuotation;
import java.util.List;
public interface BizQuotationMapper {
List<BizQuotation> selectBizQuotationList(BizQuotation query);
BizQuotation selectBizQuotationById(Long id);
int insertBizQuotation(BizQuotation record);
int updateBizQuotation(BizQuotation record);
int deleteBizQuotationById(Long id);
int deleteBizQuotationByIds(Long[] ids);
}

View File

@@ -0,0 +1,10 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizRfqItem;
import java.util.List;
public interface BizRfqItemMapper {
List<BizRfqItem> selectItemsByRfqId(Long rfqId);
int insertBizRfqItem(BizRfqItem item);
int deleteByRfqId(Long rfqId);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizRfq;
import java.util.List;
public interface BizRfqMapper {
List<BizRfq> selectBizRfqList(BizRfq query);
BizRfq selectBizRfqById(Long id);
int insertBizRfq(BizRfq record);
int updateBizRfq(BizRfq record);
int deleteBizRfqById(Long id);
int deleteBizRfqByIds(Long[] ids);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizSupplierEvaluation;
import java.util.List;
public interface BizSupplierEvaluationMapper {
List<BizSupplierEvaluation> selectBizSupplierEvaluationList(BizSupplierEvaluation query);
BizSupplierEvaluation selectBizSupplierEvaluationById(Long id);
int insertBizSupplierEvaluation(BizSupplierEvaluation record);
int updateBizSupplierEvaluation(BizSupplierEvaluation record);
int deleteBizSupplierEvaluationById(Long id);
int deleteBizSupplierEvaluationByIds(Long[] ids);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizSupplier;
import java.util.List;
public interface BizSupplierMapper {
List<BizSupplier> selectBizSupplierList(BizSupplier query);
BizSupplier selectBizSupplierById(Long id);
int insertBizSupplier(BizSupplier record);
int updateBizSupplier(BizSupplier record);
int deleteBizSupplierById(Long id);
int deleteBizSupplierByIds(Long[] ids);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizTenant;
import java.util.List;
public interface BizTenantMapper {
List<BizTenant> selectBizTenantList(BizTenant query);
BizTenant selectBizTenantById(Long id);
int insertBizTenant(BizTenant record);
int updateBizTenant(BizTenant record);
int deleteBizTenantById(Long id);
int deleteBizTenantByIds(Long[] ids);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.mapper.bid;
import com.ruoyi.system.domain.bid.BizTransaction;
import java.util.List;
public interface BizTransactionMapper {
List<BizTransaction> selectBizTransactionList(BizTransaction query);
BizTransaction selectBizTransactionById(Long id);
int insertBizTransaction(BizTransaction record);
int updateBizTransaction(BizTransaction record);
int deleteBizTransactionById(Long id);
int deleteBizTransactionByIds(Long[] ids);
}

View File

@@ -0,0 +1,8 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizComparisonVO;
import java.util.List;
public interface IBizComparisonService {
List<BizComparisonVO> compareRfq(Long rfqId, Long tenantId);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizMaterial;
import java.util.List;
public interface IBizMaterialService {
List<BizMaterial> selectBizMaterialList(BizMaterial query);
BizMaterial selectBizMaterialById(Long id);
int insertBizMaterial(BizMaterial record);
int updateBizMaterial(BizMaterial record);
int deleteBizMaterialById(Long id);
int deleteBizMaterialByIds(Long[] ids);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizOrderObjection;
import java.util.List;
public interface IBizOrderObjectionService {
List<BizOrderObjection> selectBizOrderObjectionList(BizOrderObjection query);
BizOrderObjection selectBizOrderObjectionById(Long id);
int insertBizOrderObjection(BizOrderObjection record);
int updateBizOrderObjection(BizOrderObjection record);
int deleteBizOrderObjectionById(Long id);
int deleteBizOrderObjectionByIds(Long[] ids);
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizPurchaseOrder;
import java.util.List;
public interface IBizPurchaseOrderService {
List<BizPurchaseOrder> selectBizPurchaseOrderList(BizPurchaseOrder query);
BizPurchaseOrder selectBizPurchaseOrderById(Long id);
int insertBizPurchaseOrder(BizPurchaseOrder po);
int updateBizPurchaseOrder(BizPurchaseOrder po);
int confirmOrder(Long poId);
int deleteBizPurchaseOrderById(Long id);
int deleteBizPurchaseOrderByIds(Long[] ids);
}

View File

@@ -0,0 +1,18 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizQuotation;
import com.ruoyi.system.domain.bid.BizQuotationItem;
import java.util.List;
public interface IBizQuotationService {
List<BizQuotation> selectBizQuotationList(BizQuotation query);
BizQuotation selectBizQuotationById(Long id);
int insertBizQuotation(BizQuotation q);
int updateBizQuotation(BizQuotation q);
int submitQuotation(Long quotationId);
int acceptQuotation(Long quotationId);
int rejectQuotation(Long quotationId);
int deleteBizQuotationById(Long id);
int deleteBizQuotationByIds(Long[] ids);
List<BizQuotationItem> selectItemsByQuotationId(Long quotationId);
}

View File

@@ -0,0 +1,16 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizRfq;
import com.ruoyi.system.domain.bid.BizRfqItem;
import java.util.List;
public interface IBizRfqService {
List<BizRfq> selectBizRfqList(BizRfq query);
BizRfq selectBizRfqById(Long id);
int insertBizRfq(BizRfq rfq);
int updateBizRfq(BizRfq rfq);
int deleteBizRfqById(Long id);
int deleteBizRfqByIds(Long[] ids);
int publishRfq(Long rfqId, Long[] supplierIds);
List<BizRfqItem> selectItemsByRfqId(Long rfqId);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizSupplierEvaluation;
import java.util.List;
public interface IBizSupplierEvaluationService {
List<BizSupplierEvaluation> selectBizSupplierEvaluationList(BizSupplierEvaluation query);
BizSupplierEvaluation selectBizSupplierEvaluationById(Long id);
int insertBizSupplierEvaluation(BizSupplierEvaluation record);
int updateBizSupplierEvaluation(BizSupplierEvaluation record);
int deleteBizSupplierEvaluationById(Long id);
int deleteBizSupplierEvaluationByIds(Long[] ids);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizSupplier;
import java.util.List;
public interface IBizSupplierService {
List<BizSupplier> selectBizSupplierList(BizSupplier query);
BizSupplier selectBizSupplierById(Long id);
int insertBizSupplier(BizSupplier record);
int updateBizSupplier(BizSupplier record);
int deleteBizSupplierById(Long id);
int deleteBizSupplierByIds(Long[] ids);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizTenant;
import java.util.List;
public interface IBizTenantService {
List<BizTenant> selectBizTenantList(BizTenant query);
BizTenant selectBizTenantById(Long id);
int insertBizTenant(BizTenant record);
int updateBizTenant(BizTenant record);
int deleteBizTenantById(Long id);
int deleteBizTenantByIds(Long[] ids);
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.system.service.bid;
import com.ruoyi.system.domain.bid.BizTransaction;
import java.util.List;
public interface IBizTransactionService {
List<BizTransaction> selectBizTransactionList(BizTransaction query);
BizTransaction selectBizTransactionById(Long id);
int insertBizTransaction(BizTransaction record);
int updateBizTransaction(BizTransaction record);
int deleteBizTransactionById(Long id);
int deleteBizTransactionByIds(Long[] ids);
}

View File

@@ -0,0 +1,64 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizComparisonVO;
import com.ruoyi.system.mapper.bid.BizComparisonMapper;
import com.ruoyi.system.service.bid.IBizComparisonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
@Service
public class BizComparisonServiceImpl implements IBizComparisonService {
@Autowired private BizComparisonMapper mapper;
@Override
public List<BizComparisonVO> compareRfq(Long rfqId, Long tenantId) {
List<Map<String, Object>> rows = mapper.selectComparisonData(rfqId, tenantId);
Map<Long, BizComparisonVO> itemMap = new LinkedHashMap<>();
for (Map<String, Object> row : rows) {
Long rfqItemId = toLong(row.get("rfqItemId"));
BizComparisonVO vo = itemMap.computeIfAbsent(rfqItemId, k -> {
BizComparisonVO v = new BizComparisonVO();
v.setRfqItemId(rfqItemId);
v.setMaterialName(str(row.get("materialName")));
v.setSpec(str(row.get("spec")));
v.setUnit(str(row.get("unit")));
v.setQuantity(toBD(row.get("quantity")));
v.setPrices(new ArrayList<>());
return v;
});
if (row.get("quotationId") != null) {
BizComparisonVO.SupplierPrice sp = new BizComparisonVO.SupplierPrice();
sp.setSupplierId(toLong(row.get("supplierId")));
sp.setSupplierName(str(row.get("supplierName")));
sp.setQuotationId(toLong(row.get("quotationId")));
sp.setQuoteNo(str(row.get("quoteNo")));
sp.setUnitPrice(toBD(row.get("unitPrice")));
sp.setTotalPrice(toBD(row.get("totalPrice")));
sp.setDeliveryDays(row.get("deliveryDays") == null ? 0 : ((Number) row.get("deliveryDays")).intValue());
vo.getPrices().add(sp);
}
}
// mark lowest price per item
for (BizComparisonVO vo : itemMap.values()) {
BigDecimal min = vo.getPrices().stream()
.filter(p -> p.getUnitPrice() != null)
.map(BizComparisonVO.SupplierPrice::getUnitPrice)
.min(BigDecimal::compareTo).orElse(null);
if (min != null) {
for (BizComparisonVO.SupplierPrice p : vo.getPrices()) {
p.setLowestPrice(min.compareTo(p.getUnitPrice()) == 0);
}
}
}
return new ArrayList<>(itemMap.values());
}
private Long toLong(Object v) { return v == null ? null : ((Number)v).longValue(); }
private BigDecimal toBD(Object v) { return v == null ? null : new BigDecimal(v.toString()); }
private String str(Object v) { return v == null ? "" : v.toString(); }
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizMaterial;
import com.ruoyi.system.mapper.bid.BizMaterialMapper;
import com.ruoyi.system.service.bid.IBizMaterialService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BizMaterialServiceImpl implements IBizMaterialService {
@Autowired
private BizMaterialMapper mapper;
@Override
public List<BizMaterial> selectBizMaterialList(BizMaterial query) {
return mapper.selectBizMaterialList(query);
}
@Override
public BizMaterial selectBizMaterialById(Long id) {
return mapper.selectBizMaterialById(id);
}
@Override
public int insertBizMaterial(BizMaterial record) {
return mapper.insertBizMaterial(record);
}
@Override
public int updateBizMaterial(BizMaterial record) {
return mapper.updateBizMaterial(record);
}
@Override
public int deleteBizMaterialById(Long id) {
return mapper.deleteBizMaterialById(id);
}
@Override
public int deleteBizMaterialByIds(Long[] ids) {
return mapper.deleteBizMaterialByIds(ids);
}
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizOrderObjection;
import com.ruoyi.system.mapper.bid.BizOrderObjectionMapper;
import com.ruoyi.system.service.bid.IBizOrderObjectionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BizOrderObjectionServiceImpl implements IBizOrderObjectionService {
@Autowired
private BizOrderObjectionMapper mapper;
@Override
public List<BizOrderObjection> selectBizOrderObjectionList(BizOrderObjection query) {
return mapper.selectBizOrderObjectionList(query);
}
@Override
public BizOrderObjection selectBizOrderObjectionById(Long id) {
return mapper.selectBizOrderObjectionById(id);
}
@Override
public int insertBizOrderObjection(BizOrderObjection record) {
return mapper.insertBizOrderObjection(record);
}
@Override
public int updateBizOrderObjection(BizOrderObjection record) {
return mapper.updateBizOrderObjection(record);
}
@Override
public int deleteBizOrderObjectionById(Long id) {
return mapper.deleteBizOrderObjectionById(id);
}
@Override
public int deleteBizOrderObjectionByIds(Long[] ids) {
return mapper.deleteBizOrderObjectionByIds(ids);
}
}

View File

@@ -0,0 +1,101 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizPurchaseOrder;
import com.ruoyi.system.domain.bid.BizPurchaseOrderItem;
import com.ruoyi.system.domain.bid.BizTransaction;
import com.ruoyi.system.mapper.bid.BizPurchaseOrderItemMapper;
import com.ruoyi.system.mapper.bid.BizPurchaseOrderMapper;
import com.ruoyi.system.mapper.bid.BizTransactionMapper;
import com.ruoyi.system.service.bid.IBizPurchaseOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Service
public class BizPurchaseOrderServiceImpl implements IBizPurchaseOrderService {
@Autowired private BizPurchaseOrderMapper poMapper;
@Autowired private BizPurchaseOrderItemMapper itemMapper;
@Autowired private BizTransactionMapper txMapper;
@Override
public List<BizPurchaseOrder> selectBizPurchaseOrderList(BizPurchaseOrder q) { return poMapper.selectBizPurchaseOrderList(q); }
@Override
public BizPurchaseOrder selectBizPurchaseOrderById(Long id) {
BizPurchaseOrder po = poMapper.selectBizPurchaseOrderById(id);
if (po != null) po.setItems(itemMapper.selectItemsByPoId(id));
return po;
}
@Override
@Transactional
public int insertBizPurchaseOrder(BizPurchaseOrder po) {
if (po.getPoNo() == null || po.getPoNo().isEmpty()) {
po.setPoNo("PO" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
}
int rows = poMapper.insertBizPurchaseOrder(po);
if (po.getItems() != null) {
BigDecimal total = BigDecimal.ZERO;
for (BizPurchaseOrderItem item : po.getItems()) {
item.setPoId(po.getPoId());
if (item.getUnitPrice() != null && item.getQuantity() != null) {
item.setTotalPrice(item.getUnitPrice().multiply(item.getQuantity()));
total = total.add(item.getTotalPrice());
}
itemMapper.insertBizPurchaseOrderItem(item);
}
po.setTotalAmount(total);
poMapper.updateBizPurchaseOrder(po);
}
// record transaction
BizTransaction tx = new BizTransaction();
tx.setTenantId(po.getTenantId());
tx.setPoId(po.getPoId());
tx.setSupplierId(po.getSupplierId());
tx.setTxType("PO");
tx.setTxNo(po.getPoNo());
tx.setAmount(po.getTotalAmount());
tx.setCurrency(po.getCurrency());
tx.setDescription("创建采购单 " + po.getPoNo());
tx.setOperator(po.getCreateBy());
txMapper.insertBizTransaction(tx);
return rows;
}
@Override
@Transactional
public int updateBizPurchaseOrder(BizPurchaseOrder po) {
itemMapper.deleteByPoId(po.getPoId());
if (po.getItems() != null) {
BigDecimal total = BigDecimal.ZERO;
for (BizPurchaseOrderItem item : po.getItems()) {
item.setPoId(po.getPoId());
if (item.getUnitPrice() != null && item.getQuantity() != null) {
item.setTotalPrice(item.getUnitPrice().multiply(item.getQuantity()));
total = total.add(item.getTotalPrice());
}
itemMapper.insertBizPurchaseOrderItem(item);
}
po.setTotalAmount(total);
}
return poMapper.updateBizPurchaseOrder(po);
}
@Override
public int confirmOrder(Long poId) {
BizPurchaseOrder po = new BizPurchaseOrder();
po.setPoId(poId);
po.setStatus("confirmed");
return poMapper.updateBizPurchaseOrder(po);
}
@Override
public int deleteBizPurchaseOrderById(Long id) { return poMapper.deleteBizPurchaseOrderById(id); }
@Override
public int deleteBizPurchaseOrderByIds(Long[] ids) { return poMapper.deleteBizPurchaseOrderByIds(ids); }
}

View File

@@ -0,0 +1,98 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizQuotation;
import com.ruoyi.system.domain.bid.BizQuotationItem;
import com.ruoyi.system.mapper.bid.BizQuotationItemMapper;
import com.ruoyi.system.mapper.bid.BizQuotationMapper;
import com.ruoyi.system.service.bid.IBizQuotationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Service
public class BizQuotationServiceImpl implements IBizQuotationService {
@Autowired private BizQuotationMapper mapper;
@Autowired private BizQuotationItemMapper itemMapper;
@Override
public List<BizQuotation> selectBizQuotationList(BizQuotation query) { return mapper.selectBizQuotationList(query); }
@Override
public BizQuotation selectBizQuotationById(Long id) {
BizQuotation q = mapper.selectBizQuotationById(id);
if (q != null) q.setItems(itemMapper.selectItemsByQuotationId(id));
return q;
}
@Override
@Transactional
public int insertBizQuotation(BizQuotation q) {
int rows = mapper.insertBizQuotation(q);
saveItems(q);
return rows;
}
@Override
@Transactional
public int updateBizQuotation(BizQuotation q) {
itemMapper.deleteByQuotationId(q.getQuotationId());
saveItems(q);
return mapper.updateBizQuotation(q);
}
private void saveItems(BizQuotation q) {
if (q.getItems() == null) return;
BigDecimal total = BigDecimal.ZERO;
for (BizQuotationItem item : q.getItems()) {
item.setQuotationId(q.getQuotationId());
if (item.getUnitPrice() != null && item.getQuantity() != null) {
item.setTotalPrice(item.getUnitPrice().multiply(item.getQuantity()));
total = total.add(item.getTotalPrice());
}
itemMapper.insertBizQuotationItem(item);
}
BizQuotation upd = new BizQuotation();
upd.setQuotationId(q.getQuotationId());
upd.setTotalAmount(total);
mapper.updateBizQuotation(upd);
}
@Override
public int submitQuotation(Long id) {
BizQuotation q = new BizQuotation();
q.setQuotationId(id);
q.setStatus("submitted");
q.setSubmitTime(new Date());
return mapper.updateBizQuotation(q);
}
@Override
public int acceptQuotation(Long id) {
BizQuotation q = new BizQuotation();
q.setQuotationId(id);
q.setStatus("accepted");
return mapper.updateBizQuotation(q);
}
@Override
public int rejectQuotation(Long id) {
BizQuotation q = new BizQuotation();
q.setQuotationId(id);
q.setStatus("rejected");
return mapper.updateBizQuotation(q);
}
@Override
public int deleteBizQuotationById(Long id) { return mapper.deleteBizQuotationById(id); }
@Override
public int deleteBizQuotationByIds(Long[] ids) { return mapper.deleteBizQuotationByIds(ids); }
@Override
public List<BizQuotationItem> selectItemsByQuotationId(Long quotationId) {
return itemMapper.selectItemsByQuotationId(quotationId);
}
}

View File

@@ -0,0 +1,74 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizRfq;
import com.ruoyi.system.domain.bid.BizRfqItem;
import com.ruoyi.system.mapper.bid.BizRfqItemMapper;
import com.ruoyi.system.mapper.bid.BizRfqMapper;
import com.ruoyi.system.service.bid.IBizRfqService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
@Service
public class BizRfqServiceImpl implements IBizRfqService {
@Autowired private BizRfqMapper rfqMapper;
@Autowired private BizRfqItemMapper itemMapper;
@Override
public List<BizRfq> selectBizRfqList(BizRfq query) { return rfqMapper.selectBizRfqList(query); }
@Override
public BizRfq selectBizRfqById(Long id) {
BizRfq rfq = rfqMapper.selectBizRfqById(id);
if (rfq != null) rfq.setItems(itemMapper.selectItemsByRfqId(id));
return rfq;
}
@Override
@Transactional
public int insertBizRfq(BizRfq rfq) {
rfq.setStatus("draft");
int rows = rfqMapper.insertBizRfq(rfq);
if (rfq.getItems() != null) {
for (BizRfqItem item : rfq.getItems()) {
item.setRfqId(rfq.getRfqId());
itemMapper.insertBizRfqItem(item);
}
}
return rows;
}
@Override
@Transactional
public int updateBizRfq(BizRfq rfq) {
itemMapper.deleteByRfqId(rfq.getRfqId());
if (rfq.getItems() != null) {
for (BizRfqItem item : rfq.getItems()) {
item.setRfqId(rfq.getRfqId());
itemMapper.insertBizRfqItem(item);
}
}
return rfqMapper.updateBizRfq(rfq);
}
@Override
public int deleteBizRfqById(Long id) { return rfqMapper.deleteBizRfqById(id); }
@Override
public int deleteBizRfqByIds(Long[] ids) { return rfqMapper.deleteBizRfqByIds(ids); }
@Override
public int publishRfq(Long rfqId, Long[] supplierIds) {
BizRfq rfq = new BizRfq();
rfq.setRfqId(rfqId);
rfq.setStatus("published");
return rfqMapper.updateBizRfq(rfq);
}
@Override
public List<BizRfqItem> selectItemsByRfqId(Long rfqId) {
return itemMapper.selectItemsByRfqId(rfqId);
}
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizSupplierEvaluation;
import com.ruoyi.system.mapper.bid.BizSupplierEvaluationMapper;
import com.ruoyi.system.service.bid.IBizSupplierEvaluationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BizSupplierEvaluationServiceImpl implements IBizSupplierEvaluationService {
@Autowired
private BizSupplierEvaluationMapper mapper;
@Override
public List<BizSupplierEvaluation> selectBizSupplierEvaluationList(BizSupplierEvaluation query) {
return mapper.selectBizSupplierEvaluationList(query);
}
@Override
public BizSupplierEvaluation selectBizSupplierEvaluationById(Long id) {
return mapper.selectBizSupplierEvaluationById(id);
}
@Override
public int insertBizSupplierEvaluation(BizSupplierEvaluation record) {
return mapper.insertBizSupplierEvaluation(record);
}
@Override
public int updateBizSupplierEvaluation(BizSupplierEvaluation record) {
return mapper.updateBizSupplierEvaluation(record);
}
@Override
public int deleteBizSupplierEvaluationById(Long id) {
return mapper.deleteBizSupplierEvaluationById(id);
}
@Override
public int deleteBizSupplierEvaluationByIds(Long[] ids) {
return mapper.deleteBizSupplierEvaluationByIds(ids);
}
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizSupplier;
import com.ruoyi.system.mapper.bid.BizSupplierMapper;
import com.ruoyi.system.service.bid.IBizSupplierService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BizSupplierServiceImpl implements IBizSupplierService {
@Autowired
private BizSupplierMapper mapper;
@Override
public List<BizSupplier> selectBizSupplierList(BizSupplier query) {
return mapper.selectBizSupplierList(query);
}
@Override
public BizSupplier selectBizSupplierById(Long id) {
return mapper.selectBizSupplierById(id);
}
@Override
public int insertBizSupplier(BizSupplier record) {
return mapper.insertBizSupplier(record);
}
@Override
public int updateBizSupplier(BizSupplier record) {
return mapper.updateBizSupplier(record);
}
@Override
public int deleteBizSupplierById(Long id) {
return mapper.deleteBizSupplierById(id);
}
@Override
public int deleteBizSupplierByIds(Long[] ids) {
return mapper.deleteBizSupplierByIds(ids);
}
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizTenant;
import com.ruoyi.system.mapper.bid.BizTenantMapper;
import com.ruoyi.system.service.bid.IBizTenantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BizTenantServiceImpl implements IBizTenantService {
@Autowired
private BizTenantMapper mapper;
@Override
public List<BizTenant> selectBizTenantList(BizTenant query) {
return mapper.selectBizTenantList(query);
}
@Override
public BizTenant selectBizTenantById(Long id) {
return mapper.selectBizTenantById(id);
}
@Override
public int insertBizTenant(BizTenant record) {
return mapper.insertBizTenant(record);
}
@Override
public int updateBizTenant(BizTenant record) {
return mapper.updateBizTenant(record);
}
@Override
public int deleteBizTenantById(Long id) {
return mapper.deleteBizTenantById(id);
}
@Override
public int deleteBizTenantByIds(Long[] ids) {
return mapper.deleteBizTenantByIds(ids);
}
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.system.service.bid.impl;
import com.ruoyi.system.domain.bid.BizTransaction;
import com.ruoyi.system.mapper.bid.BizTransactionMapper;
import com.ruoyi.system.service.bid.IBizTransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BizTransactionServiceImpl implements IBizTransactionService {
@Autowired
private BizTransactionMapper mapper;
@Override
public List<BizTransaction> selectBizTransactionList(BizTransaction query) {
return mapper.selectBizTransactionList(query);
}
@Override
public BizTransaction selectBizTransactionById(Long id) {
return mapper.selectBizTransactionById(id);
}
@Override
public int insertBizTransaction(BizTransaction record) {
return mapper.insertBizTransaction(record);
}
@Override
public int updateBizTransaction(BizTransaction record) {
return mapper.updateBizTransaction(record);
}
@Override
public int deleteBizTransactionById(Long id) {
return mapper.deleteBizTransactionById(id);
}
@Override
public int deleteBizTransactionByIds(Long[] ids) {
return mapper.deleteBizTransactionByIds(ids);
}
}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizComparisonMapper">
<select id="selectComparisonData" resultType="java.util.HashMap">
SELECT
ri.item_id AS rfqItemId,
ri.material_name AS materialName,
ri.spec AS spec,
ri.unit AS unit,
ri.quantity AS quantity,
qi.unit_price AS unitPrice,
qi.total_price AS totalPrice,
qi.delivery_days AS deliveryDays,
q.quotation_id AS quotationId,
q.quote_no AS quoteNo,
q.supplier_id AS supplierId,
s.supplier_name AS supplierName
FROM biz_rfq_item ri
LEFT JOIN biz_quotation_item qi ON qi.rfq_item_id = ri.item_id
LEFT JOIN biz_quotation q ON q.quotation_id = qi.quotation_id AND q.status = 'submitted'
LEFT JOIN biz_supplier s ON s.supplier_id = q.supplier_id
WHERE ri.rfq_id = #{rfqId}
ORDER BY ri.item_id, qi.unit_price
</select>
</mapper>

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizMaterialMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizMaterial">
<id property="materialId" column="material_id"/>
<result property="tenantId" column="tenant_id"/>
<result property="categoryId" column="category_id"/>
<result property="materialCode" column="material_code"/>
<result property="materialName" column="material_name"/>
<result property="spec" column="spec"/>
<result property="unit" column="unit"/>
<result property="brand" column="brand"/>
<result property="description" column="description"/>
<result property="status" column="status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="selectBizMaterialList" resultMap="BaseRM">
SELECT m.* FROM biz_material m
<where>
<if test="tenantId != null"> AND m.tenant_id = #{tenantId}</if>
<if test="materialCode != null and materialCode != ''"> AND m.material_code LIKE CONCAT('%',#{materialCode},'%')</if>
<if test="materialName != null and materialName != ''"> AND m.material_name LIKE CONCAT('%',#{materialName},'%')</if>
<if test="status != null and status != ''"> AND m.status = #{status}</if>
</where>
ORDER BY m.material_id DESC
</select>
<select id="selectBizMaterialById" resultMap="BaseRM">
SELECT * FROM biz_material WHERE material_id=#{id}
</select>
<insert id="insertBizMaterial" useGeneratedKeys="true" keyProperty="materialId">
INSERT INTO biz_material(tenant_id,category_id,material_code,material_name,spec,unit,brand,description,status,create_by,create_time)
VALUES(#{tenantId},#{categoryId},#{materialCode},#{materialName},#{spec},#{unit},#{brand},#{description},#{status},#{createBy},NOW())
</insert>
<update id="updateBizMaterial">
UPDATE biz_material
<set>
<if test="materialName != null">material_name=#{materialName},</if>
<if test="materialCode != null">material_code=#{materialCode},</if>
<if test="spec != null">spec=#{spec},</if>
<if test="unit != null">unit=#{unit},</if>
<if test="brand != null">brand=#{brand},</if>
<if test="description != null">description=#{description},</if>
<if test="categoryId != null">category_id=#{categoryId},</if>
<if test="status != null">status=#{status},</if>
update_by=#{updateBy}, update_time=NOW()
</set>
WHERE material_id=#{materialId}
</update>
<delete id="deleteBizMaterialById">DELETE FROM biz_material WHERE material_id=#{id}</delete>
<delete id="deleteBizMaterialByIds">
DELETE FROM biz_material WHERE material_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizOrderObjectionMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizOrderObjection">
<id property="objectionId" column="objection_id"/>
<result property="tenantId" column="tenant_id"/>
<result property="poId" column="po_id"/>
<result property="supplierId" column="supplier_id"/>
<result property="reason" column="reason"/>
<result property="attachment" column="attachment"/>
<result property="status" column="status"/>
<result property="resolution" column="resolution"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="resolveTime" column="resolve_time"/>
<result property="supplierName" column="supplier_name"/>
<result property="poNo" column="po_no"/>
</resultMap>
<select id="selectBizOrderObjectionList" resultMap="BaseRM">
SELECT o.*, s.supplier_name, p.po_no
FROM biz_order_objection o
LEFT JOIN biz_supplier s ON o.supplier_id=s.supplier_id
LEFT JOIN biz_purchase_order p ON o.po_id=p.po_id
<where>
<if test="tenantId != null"> AND o.tenant_id=#{tenantId}</if>
<if test="status != null and status != ''"> AND o.status=#{status}</if>
</where>
ORDER BY o.objection_id DESC
</select>
<select id="selectBizOrderObjectionById" resultMap="BaseRM">
SELECT o.*, s.supplier_name, p.po_no FROM biz_order_objection o
LEFT JOIN biz_supplier s ON o.supplier_id=s.supplier_id
LEFT JOIN biz_purchase_order p ON o.po_id=p.po_id
WHERE o.objection_id=#{id}
</select>
<insert id="insertBizOrderObjection" useGeneratedKeys="true" keyProperty="objectionId">
INSERT INTO biz_order_objection(tenant_id,po_id,supplier_id,reason,attachment,status,create_by,create_time)
VALUES(#{tenantId},#{poId},#{supplierId},#{reason},#{attachment},'pending',#{createBy},NOW())
</insert>
<update id="updateBizOrderObjection">
UPDATE biz_order_objection
<set>
<if test="status != null">status=#{status},</if>
<if test="resolution != null">resolution=#{resolution},</if>
<if test="resolveTime != null">resolve_time=#{resolveTime},</if>
</set>
WHERE objection_id=#{objectionId}
</update>
<delete id="deleteBizOrderObjectionById">DELETE FROM biz_order_objection WHERE objection_id=#{id}</delete>
<delete id="deleteBizOrderObjectionByIds">
DELETE FROM biz_order_objection WHERE objection_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizPurchaseOrderItemMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizPurchaseOrderItem">
<id property="itemId" column="item_id"/>
<result property="poId" column="po_id"/>
<result property="materialId" column="material_id"/>
<result property="materialName" column="material_name"/>
<result property="spec" column="spec"/>
<result property="unit" column="unit"/>
<result property="quantity" column="quantity"/>
<result property="unitPrice" column="unit_price"/>
<result property="totalPrice" column="total_price"/>
<result property="remark" column="remark"/>
</resultMap>
<select id="selectItemsByPoId" resultMap="BaseRM">
SELECT * FROM biz_purchase_order_item WHERE po_id=#{poId}
</select>
<insert id="insertBizPurchaseOrderItem" useGeneratedKeys="true" keyProperty="itemId">
INSERT INTO biz_purchase_order_item(po_id,material_id,material_name,spec,unit,quantity,unit_price,total_price,remark)
VALUES(#{poId},#{materialId},#{materialName},#{spec},#{unit},#{quantity},#{unitPrice},#{totalPrice},#{remark})
</insert>
<delete id="deleteByPoId">DELETE FROM biz_purchase_order_item WHERE po_id=#{poId}</delete>
</mapper>

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizPurchaseOrderMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizPurchaseOrder">
<id property="poId" column="po_id"/>
<result property="tenantId" column="tenant_id"/>
<result property="poNo" column="po_no"/>
<result property="rfqId" column="rfq_id"/>
<result property="supplierId" column="supplier_id"/>
<result property="totalAmount" column="total_amount"/>
<result property="currency" column="currency"/>
<result property="deliveryAddr" column="delivery_addr"/>
<result property="deliveryDate" column="delivery_date"/>
<result property="status" column="status"/>
<result property="remark" column="remark"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="supplierName" column="supplier_name"/>
<result property="rfqTitle" column="rfq_title"/>
</resultMap>
<select id="selectBizPurchaseOrderList" resultMap="BaseRM">
SELECT p.*, s.supplier_name, r.rfq_title
FROM biz_purchase_order p
LEFT JOIN biz_supplier s ON p.supplier_id=s.supplier_id
LEFT JOIN biz_rfq r ON p.rfq_id=r.rfq_id
<where>
<if test="tenantId != null"> AND p.tenant_id=#{tenantId}</if>
<if test="poNo != null and poNo != ''"> AND p.po_no LIKE CONCAT('%',#{poNo},'%')</if>
<if test="supplierId != null"> AND p.supplier_id=#{supplierId}</if>
<if test="status != null and status != ''"> AND p.status=#{status}</if>
</where>
ORDER BY p.po_id DESC
</select>
<select id="selectBizPurchaseOrderById" resultMap="BaseRM">
SELECT p.*, s.supplier_name, r.rfq_title
FROM biz_purchase_order p
LEFT JOIN biz_supplier s ON p.supplier_id=s.supplier_id
LEFT JOIN biz_rfq r ON p.rfq_id=r.rfq_id
WHERE p.po_id=#{id}
</select>
<insert id="insertBizPurchaseOrder" useGeneratedKeys="true" keyProperty="poId">
INSERT INTO biz_purchase_order(tenant_id,po_no,rfq_id,supplier_id,total_amount,currency,delivery_addr,delivery_date,status,remark,create_by,create_time)
VALUES(#{tenantId},#{poNo},#{rfqId},#{supplierId},#{totalAmount},#{currency},#{deliveryAddr},#{deliveryDate},#{status},#{remark},#{createBy},NOW())
</insert>
<update id="updateBizPurchaseOrder">
UPDATE biz_purchase_order
<set>
<if test="totalAmount != null">total_amount=#{totalAmount},</if>
<if test="deliveryAddr != null">delivery_addr=#{deliveryAddr},</if>
<if test="deliveryDate != null">delivery_date=#{deliveryDate},</if>
<if test="status != null">status=#{status},</if>
<if test="remark != null">remark=#{remark},</if>
update_by=#{updateBy}, update_time=NOW()
</set>
WHERE po_id=#{poId}
</update>
<delete id="deleteBizPurchaseOrderById">DELETE FROM biz_purchase_order WHERE po_id=#{id}</delete>
<delete id="deleteBizPurchaseOrderByIds">
DELETE FROM biz_purchase_order WHERE po_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizQuotationItemMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizQuotationItem">
<id property="itemId" column="item_id"/>
<result property="quotationId" column="quotation_id"/>
<result property="rfqItemId" column="rfq_item_id"/>
<result property="materialName" column="material_name"/>
<result property="spec" column="spec"/>
<result property="unit" column="unit"/>
<result property="quantity" column="quantity"/>
<result property="unitPrice" column="unit_price"/>
<result property="totalPrice" column="total_price"/>
<result property="deliveryDays" column="delivery_days"/>
<result property="remark" column="remark"/>
</resultMap>
<select id="selectItemsByQuotationId" resultMap="BaseRM">
SELECT * FROM biz_quotation_item WHERE quotation_id=#{quotationId}
</select>
<insert id="insertBizQuotationItem" useGeneratedKeys="true" keyProperty="itemId">
INSERT INTO biz_quotation_item(quotation_id,rfq_item_id,material_name,spec,unit,quantity,unit_price,total_price,delivery_days,remark)
VALUES(#{quotationId},#{rfqItemId},#{materialName},#{spec},#{unit},#{quantity},#{unitPrice},#{totalPrice},#{deliveryDays},#{remark})
</insert>
<delete id="deleteByQuotationId">DELETE FROM biz_quotation_item WHERE quotation_id=#{quotationId}</delete>
</mapper>

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizQuotationMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizQuotation">
<id property="quotationId" column="quotation_id"/>
<result property="tenantId" column="tenant_id"/>
<result property="rfqId" column="rfq_id"/>
<result property="supplierId" column="supplier_id"/>
<result property="quoteNo" column="quote_no"/>
<result property="validDays" column="valid_days"/>
<result property="deliveryDays" column="delivery_days"/>
<result property="totalAmount" column="total_amount"/>
<result property="currency" column="currency"/>
<result property="status" column="status"/>
<result property="note" column="note"/>
<result property="submitTime" column="submit_time"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="supplierName" column="supplier_name"/>
<result property="rfqTitle" column="rfq_title"/>
<result property="rfqNo" column="rfq_no"/>
</resultMap>
<select id="selectBizQuotationList" resultMap="BaseRM">
SELECT q.*, s.supplier_name, r.rfq_title, r.rfq_no
FROM biz_quotation q
LEFT JOIN biz_supplier s ON q.supplier_id=s.supplier_id
LEFT JOIN biz_rfq r ON q.rfq_id=r.rfq_id
<where>
<if test="tenantId != null"> AND q.tenant_id=#{tenantId}</if>
<if test="rfqId != null"> AND q.rfq_id=#{rfqId}</if>
<if test="supplierId != null"> AND q.supplier_id=#{supplierId}</if>
<if test="status != null and status != ''"> AND q.status=#{status}</if>
</where>
ORDER BY q.quotation_id DESC
</select>
<select id="selectBizQuotationById" resultMap="BaseRM">
SELECT q.*, s.supplier_name, r.rfq_title, r.rfq_no
FROM biz_quotation q
LEFT JOIN biz_supplier s ON q.supplier_id=s.supplier_id
LEFT JOIN biz_rfq r ON q.rfq_id=r.rfq_id
WHERE q.quotation_id=#{id}
</select>
<insert id="insertBizQuotation" useGeneratedKeys="true" keyProperty="quotationId">
INSERT INTO biz_quotation(tenant_id,rfq_id,supplier_id,quote_no,valid_days,delivery_days,total_amount,currency,status,note,create_by,create_time)
VALUES(#{tenantId},#{rfqId},#{supplierId},#{quoteNo},#{validDays},#{deliveryDays},#{totalAmount},#{currency},#{status},#{note},#{createBy},NOW())
</insert>
<update id="updateBizQuotation">
UPDATE biz_quotation
<set>
<if test="validDays != null">valid_days=#{validDays},</if>
<if test="deliveryDays != null">delivery_days=#{deliveryDays},</if>
<if test="totalAmount != null">total_amount=#{totalAmount},</if>
<if test="status != null">status=#{status},</if>
<if test="note != null">note=#{note},</if>
<if test="submitTime != null">submit_time=#{submitTime},</if>
update_time=NOW()
</set>
WHERE quotation_id=#{quotationId}
</update>
<delete id="deleteBizQuotationById">DELETE FROM biz_quotation WHERE quotation_id=#{id}</delete>
<delete id="deleteBizQuotationByIds">
DELETE FROM biz_quotation WHERE quotation_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizRfqItemMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizRfqItem">
<id property="itemId" column="item_id"/>
<result property="rfqId" column="rfq_id"/>
<result property="materialId" column="material_id"/>
<result property="materialName" column="material_name"/>
<result property="spec" column="spec"/>
<result property="unit" column="unit"/>
<result property="quantity" column="quantity"/>
<result property="expectedPrice" column="expected_price"/>
<result property="remark" column="remark"/>
</resultMap>
<select id="selectItemsByRfqId" resultMap="BaseRM">
SELECT * FROM biz_rfq_item WHERE rfq_id=#{rfqId}
</select>
<insert id="insertBizRfqItem" useGeneratedKeys="true" keyProperty="itemId">
INSERT INTO biz_rfq_item(rfq_id,material_id,material_name,spec,unit,quantity,expected_price,remark)
VALUES(#{rfqId},#{materialId},#{materialName},#{spec},#{unit},#{quantity},#{expectedPrice},#{remark})
</insert>
<delete id="deleteByRfqId">DELETE FROM biz_rfq_item WHERE rfq_id=#{rfqId}</delete>
</mapper>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizRfqMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizRfq">
<id property="rfqId" column="rfq_id"/>
<result property="tenantId" column="tenant_id"/>
<result property="rfqNo" column="rfq_no"/>
<result property="rfqTitle" column="rfq_title"/>
<result property="deadline" column="deadline"/>
<result property="deliveryAddr" column="delivery_addr"/>
<result property="status" column="status"/>
<result property="remark" column="remark"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="selectBizRfqList" resultMap="BaseRM">
SELECT * FROM biz_rfq
<where>
<if test="tenantId != null"> AND tenant_id=#{tenantId}</if>
<if test="rfqNo != null and rfqNo != ''"> AND rfq_no LIKE CONCAT('%',#{rfqNo},'%')</if>
<if test="rfqTitle != null and rfqTitle != ''"> AND rfq_title LIKE CONCAT('%',#{rfqTitle},'%')</if>
<if test="status != null and status != ''"> AND status=#{status}</if>
</where>
ORDER BY rfq_id DESC
</select>
<select id="selectBizRfqById" resultMap="BaseRM">SELECT * FROM biz_rfq WHERE rfq_id=#{id}</select>
<insert id="insertBizRfq" useGeneratedKeys="true" keyProperty="rfqId">
INSERT INTO biz_rfq(tenant_id,rfq_no,rfq_title,deadline,delivery_addr,status,remark,create_by,create_time)
VALUES(#{tenantId},#{rfqNo},#{rfqTitle},#{deadline},#{deliveryAddr},#{status},#{remark},#{createBy},NOW())
</insert>
<update id="updateBizRfq">
UPDATE biz_rfq
<set>
<if test="rfqTitle != null">rfq_title=#{rfqTitle},</if>
<if test="deadline != null">deadline=#{deadline},</if>
<if test="deliveryAddr != null">delivery_addr=#{deliveryAddr},</if>
<if test="status != null">status=#{status},</if>
<if test="remark != null">remark=#{remark},</if>
update_by=#{updateBy}, update_time=NOW()
</set>
WHERE rfq_id=#{rfqId}
</update>
<delete id="deleteBizRfqById">DELETE FROM biz_rfq WHERE rfq_id=#{id}</delete>
<delete id="deleteBizRfqByIds">
DELETE FROM biz_rfq WHERE rfq_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizSupplierEvaluationMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizSupplierEvaluation">
<id property="evalId" column="eval_id"/>
<result property="tenantId" column="tenant_id"/>
<result property="poId" column="po_id"/>
<result property="supplierId" column="supplier_id"/>
<result property="qualityScore" column="quality_score"/>
<result property="deliveryScore" column="delivery_score"/>
<result property="serviceScore" column="service_score"/>
<result property="priceScore" column="price_score"/>
<result property="totalScore" column="total_score"/>
<result property="comment" column="comment"/>
<result property="evaluator" column="evaluator"/>
<result property="evalTime" column="eval_time"/>
<result property="supplierName" column="supplier_name"/>
<result property="poNo" column="po_no"/>
</resultMap>
<select id="selectBizSupplierEvaluationList" resultMap="BaseRM">
SELECT e.*, s.supplier_name, p.po_no
FROM biz_supplier_evaluation e
LEFT JOIN biz_supplier s ON e.supplier_id=s.supplier_id
LEFT JOIN biz_purchase_order p ON e.po_id=p.po_id
<where>
<if test="tenantId != null"> AND e.tenant_id=#{tenantId}</if>
<if test="supplierId != null"> AND e.supplier_id=#{supplierId}</if>
</where>
ORDER BY e.eval_id DESC
</select>
<select id="selectBizSupplierEvaluationById" resultMap="BaseRM">
SELECT e.*, s.supplier_name, p.po_no FROM biz_supplier_evaluation e
LEFT JOIN biz_supplier s ON e.supplier_id=s.supplier_id
LEFT JOIN biz_purchase_order p ON e.po_id=p.po_id
WHERE e.eval_id=#{id}
</select>
<insert id="insertBizSupplierEvaluation" useGeneratedKeys="true" keyProperty="evalId">
INSERT INTO biz_supplier_evaluation(tenant_id,po_id,supplier_id,quality_score,delivery_score,service_score,price_score,total_score,comment,evaluator,eval_time)
VALUES(#{tenantId},#{poId},#{supplierId},#{qualityScore},#{deliveryScore},#{serviceScore},#{priceScore},#{totalScore},#{comment},#{evaluator},NOW())
</insert>
<update id="updateBizSupplierEvaluation">
UPDATE biz_supplier_evaluation
<set>
<if test="qualityScore != null">quality_score=#{qualityScore},</if>
<if test="deliveryScore != null">delivery_score=#{deliveryScore},</if>
<if test="serviceScore != null">service_score=#{serviceScore},</if>
<if test="priceScore != null">price_score=#{priceScore},</if>
<if test="totalScore != null">total_score=#{totalScore},</if>
<if test="comment != null">comment=#{comment},</if>
</set>
WHERE eval_id=#{evalId}
</update>
<delete id="deleteBizSupplierEvaluationById">DELETE FROM biz_supplier_evaluation WHERE eval_id=#{id}</delete>
<delete id="deleteBizSupplierEvaluationByIds">
DELETE FROM biz_supplier_evaluation WHERE eval_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizSupplierMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizSupplier">
<id property="supplierId" column="supplier_id"/>
<result property="tenantId" column="tenant_id"/>
<result property="supplierName" column="supplier_name"/>
<result property="contact" column="contact"/>
<result property="phone" column="phone"/>
<result property="email" column="email"/>
<result property="address" column="address"/>
<result property="userId" column="user_id"/>
<result property="status" column="status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="selectBizSupplierList" resultMap="BaseRM">
SELECT * FROM biz_supplier
<where>
<if test="tenantId != null"> AND tenant_id=#{tenantId}</if>
<if test="supplierName != null and supplierName != ''"> AND supplier_name LIKE CONCAT('%',#{supplierName},'%')</if>
<if test="status != null and status != ''"> AND status=#{status}</if>
</where>
ORDER BY supplier_id DESC
</select>
<select id="selectBizSupplierById" resultMap="BaseRM">SELECT * FROM biz_supplier WHERE supplier_id=#{id}</select>
<insert id="insertBizSupplier" useGeneratedKeys="true" keyProperty="supplierId">
INSERT INTO biz_supplier(tenant_id,supplier_name,contact,phone,email,address,user_id,status,create_by,create_time)
VALUES(#{tenantId},#{supplierName},#{contact},#{phone},#{email},#{address},#{userId},#{status},#{createBy},NOW())
</insert>
<update id="updateBizSupplier">
UPDATE biz_supplier
<set>
<if test="supplierName != null">supplier_name=#{supplierName},</if>
<if test="contact != null">contact=#{contact},</if>
<if test="phone != null">phone=#{phone},</if>
<if test="email != null">email=#{email},</if>
<if test="address != null">address=#{address},</if>
<if test="status != null">status=#{status},</if>
update_by=#{updateBy}, update_time=NOW()
</set>
WHERE supplier_id=#{supplierId}
</update>
<delete id="deleteBizSupplierById">DELETE FROM biz_supplier WHERE supplier_id=#{id}</delete>
<delete id="deleteBizSupplierByIds">
DELETE FROM biz_supplier WHERE supplier_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizTenantMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizTenant">
<id property="tenantId" column="tenant_id"/>
<result property="tenantName" column="tenant_name"/>
<result property="contact" column="contact"/>
<result property="phone" column="phone"/>
<result property="email" column="email"/>
<result property="status" column="status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<sql id="cols">tenant_id,tenant_name,contact,phone,email,status,create_by,create_time,update_by,update_time,remark</sql>
<select id="selectBizTenantList" resultMap="BaseRM">
SELECT <include refid="cols"/> FROM biz_tenant
<where>
<if test="tenantName != null and tenantName != ''"> AND tenant_name LIKE CONCAT('%',#{tenantName},'%')</if>
<if test="status != null and status != ''"> AND status = #{status}</if>
</where>
ORDER BY tenant_id
</select>
<select id="selectBizTenantById" resultMap="BaseRM">
SELECT <include refid="cols"/> FROM biz_tenant WHERE tenant_id = #{id}
</select>
<insert id="insertBizTenant" useGeneratedKeys="true" keyProperty="tenantId">
INSERT INTO biz_tenant(tenant_name,contact,phone,email,status,create_by,create_time,remark)
VALUES(#{tenantName},#{contact},#{phone},#{email},#{status},#{createBy},NOW(),#{remark})
</insert>
<update id="updateBizTenant">
UPDATE biz_tenant
<set>
<if test="tenantName != null">tenant_name=#{tenantName},</if>
<if test="contact != null">contact=#{contact},</if>
<if test="phone != null">phone=#{phone},</if>
<if test="email != null">email=#{email},</if>
<if test="status != null">status=#{status},</if>
<if test="remark != null">remark=#{remark},</if>
update_by=#{updateBy}, update_time=NOW()
</set>
WHERE tenant_id=#{tenantId}
</update>
<delete id="deleteBizTenantById">DELETE FROM biz_tenant WHERE tenant_id=#{id}</delete>
<delete id="deleteBizTenantByIds">
DELETE FROM biz_tenant WHERE tenant_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizTransactionMapper">
<resultMap id="BaseRM" type="com.ruoyi.system.domain.bid.BizTransaction">
<id property="txId" column="tx_id"/>
<result property="tenantId" column="tenant_id"/>
<result property="poId" column="po_id"/>
<result property="supplierId" column="supplier_id"/>
<result property="txType" column="tx_type"/>
<result property="txNo" column="tx_no"/>
<result property="amount" column="amount"/>
<result property="currency" column="currency"/>
<result property="description" column="description"/>
<result property="operator" column="operator"/>
<result property="txTime" column="tx_time"/>
<result property="createTime" column="create_time"/>
<result property="supplierName" column="supplier_name"/>
<result property="poNo" column="po_no"/>
</resultMap>
<select id="selectBizTransactionList" resultMap="BaseRM">
SELECT t.*, s.supplier_name, p.po_no
FROM biz_transaction t
LEFT JOIN biz_supplier s ON t.supplier_id=s.supplier_id
LEFT JOIN biz_purchase_order p ON t.po_id=p.po_id
<where>
<if test="tenantId != null"> AND t.tenant_id=#{tenantId}</if>
<if test="txType != null and txType != ''"> AND t.tx_type=#{txType}</if>
<if test="supplierId != null"> AND t.supplier_id=#{supplierId}</if>
<if test="beginTime != null and beginTime != ''"> AND t.tx_time >= #{beginTime}</if>
<if test="endTime != null and endTime != ''"> AND t.tx_time &lt;= #{endTime}</if>
</where>
ORDER BY t.tx_id DESC
</select>
<select id="selectBizTransactionById" resultMap="BaseRM">
SELECT t.*, s.supplier_name, p.po_no FROM biz_transaction t
LEFT JOIN biz_supplier s ON t.supplier_id=s.supplier_id
LEFT JOIN biz_purchase_order p ON t.po_id=p.po_id
WHERE t.tx_id=#{id}
</select>
<insert id="insertBizTransaction" useGeneratedKeys="true" keyProperty="txId">
INSERT INTO biz_transaction(tenant_id,po_id,supplier_id,tx_type,tx_no,amount,currency,description,operator,tx_time,create_time)
VALUES(#{tenantId},#{poId},#{supplierId},#{txType},#{txNo},#{amount},#{currency},#{description},#{operator},NOW(),NOW())
</insert>
<update id="updateBizTransaction">UPDATE biz_transaction SET description=#{description} WHERE tx_id=#{txId}</update>
<delete id="deleteBizTransactionById">DELETE FROM biz_transaction WHERE tx_id=#{id}</delete>
<delete id="deleteBizTransactionByIds">
DELETE FROM biz_transaction WHERE tx_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>
</mapper>

View File

@@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
VUE_APP_TITLE = 福安德智慧报价平台
# 开发环境配置
ENV = 'development'

View File

@@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
VUE_APP_TITLE = 福安德智慧报价平台
# 生产环境配置
ENV = 'production'

View File

@@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
VUE_APP_TITLE = 福安德智慧报价平台
BABEL_ENV = production

View File

@@ -0,0 +1,2 @@
import request from '@/utils/request'
export const compareRfq = (rfqId) => request({ url: '/bid/comparison/rfq/' + rfqId, method: 'get' })

View File

@@ -0,0 +1,7 @@
import request from '@/utils/request'
const baseUrl = '/bid/evaluation'
export const listEvaluation = (params) => request({ url: baseUrl + '/list', method: 'get', params })
export const getEvaluation = (id) => request({ url: baseUrl + '/' + id, method: 'get' })
export const addEvaluation = (data) => request({ url: baseUrl, method: 'post', data })
export const updateEvaluation = (data) => request({ url: baseUrl, method: 'put', data })
export const delEvaluation = (ids) => request({ url: baseUrl + '/' + ids, method: 'delete' })

View File

@@ -0,0 +1,7 @@
import request from '@/utils/request'
const baseUrl = '/bid/material'
export const listMaterial = (params) => request({ url: baseUrl + '/list', method: 'get', params })
export const getMaterial = (id) => request({ url: baseUrl + '/' + id, method: 'get' })
export const addMaterial = (data) => request({ url: baseUrl, method: 'post', data })
export const updateMaterial = (data) => request({ url: baseUrl, method: 'put', data })
export const delMaterial = (ids) => request({ url: baseUrl + '/' + ids, method: 'delete' })

View File

@@ -0,0 +1,7 @@
import request from '@/utils/request'
const baseUrl = '/bid/objection'
export const listObjection = (params) => request({ url: baseUrl + '/list', method: 'get', params })
export const getObjection = (id) => request({ url: baseUrl + '/' + id, method: 'get' })
export const addObjection = (data) => request({ url: baseUrl, method: 'post', data })
export const updateObjection = (data) => request({ url: baseUrl, method: 'put', data })
export const delObjection = (ids) => request({ url: baseUrl + '/' + ids, method: 'delete' })

View File

@@ -0,0 +1,8 @@
import request from '@/utils/request'
const baseUrl = '/bid/purchaseorder'
export const listPurchaseorder = (params) => request({ url: baseUrl + '/list', method: 'get', params })
export const getPurchaseorder = (id) => request({ url: baseUrl + '/' + id, method: 'get' })
export const addPurchaseorder = (data) => request({ url: baseUrl, method: 'post', data })
export const updatePurchaseorder = (data) => request({ url: baseUrl, method: 'put', data })
export const confirmPurchaseorder = (id) => request({ url: baseUrl + '/confirm/' + id, method: 'put' })
export const delPurchaseorder = (ids) => request({ url: baseUrl + '/' + ids, method: 'delete' })

View File

@@ -0,0 +1,10 @@
import request from '@/utils/request'
const baseUrl = '/bid/quotation'
export const listQuotation = (params) => request({ url: baseUrl + '/list', method: 'get', params })
export const getQuotation = (id) => request({ url: baseUrl + '/' + id, method: 'get' })
export const addQuotation = (data) => request({ url: baseUrl, method: 'post', data })
export const updateQuotation = (data) => request({ url: baseUrl, method: 'put', data })
export const submitQuotation = (id) => request({ url: baseUrl + '/submit/' + id, method: 'put' })
export const acceptQuotation = (id) => request({ url: baseUrl + '/accept/' + id, method: 'put' })
export const rejectQuotation = (id) => request({ url: baseUrl + '/reject/' + id, method: 'put' })
export const delQuotation = (ids) => request({ url: baseUrl + '/' + ids, method: 'delete' })

View File

@@ -0,0 +1,9 @@
import request from '@/utils/request'
const baseUrl = '/bid/rfq'
export const listRfq = (params) => request({ url: baseUrl + '/list', method: 'get', params })
export const getRfq = (id) => request({ url: baseUrl + '/' + id, method: 'get' })
export const getRfqItems = (id) => request({ url: baseUrl + '/' + id + '/items', method: 'get' })
export const addRfq = (data) => request({ url: baseUrl, method: 'post', data })
export const updateRfq = (data) => request({ url: baseUrl, method: 'put', data })
export const publishRfq = (rfqId, supplierIds) => request({ url: baseUrl + '/publish/' + rfqId, method: 'put', data: supplierIds })
export const delRfq = (ids) => request({ url: baseUrl + '/' + ids, method: 'delete' })

View File

@@ -0,0 +1,7 @@
import request from '@/utils/request'
const baseUrl = '/bid/supplier'
export const listSupplier = (params) => request({ url: baseUrl + '/list', method: 'get', params })
export const getSupplier = (id) => request({ url: baseUrl + '/' + id, method: 'get' })
export const addSupplier = (data) => request({ url: baseUrl, method: 'post', data })
export const updateSupplier = (data) => request({ url: baseUrl, method: 'put', data })
export const delSupplier = (ids) => request({ url: baseUrl + '/' + ids, method: 'delete' })

View File

@@ -0,0 +1,7 @@
import request from '@/utils/request'
const baseUrl = '/bid/tenant'
export const listTenant = (params) => request({ url: baseUrl + '/list', method: 'get', params })
export const getTenant = (id) => request({ url: baseUrl + '/' + id, method: 'get' })
export const addTenant = (data) => request({ url: baseUrl, method: 'post', data })
export const updateTenant = (data) => request({ url: baseUrl, method: 'put', data })
export const delTenant = (ids) => request({ url: baseUrl + '/' + ids, method: 'delete' })

View File

@@ -0,0 +1,7 @@
import request from '@/utils/request'
const baseUrl = '/bid/transaction'
export const listTransaction = (params) => request({ url: baseUrl + '/list', method: 'get', params })
export const getTransaction = (id) => request({ url: baseUrl + '/' + id, method: 'get' })
export const addTransaction = (data) => request({ url: baseUrl, method: 'post', data })
export const updateTransaction = (data) => request({ url: baseUrl, method: 'put', data })
export const delTransaction = (ids) => request({ url: baseUrl + '/' + ids, method: 'delete' })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,39 +1,37 @@
// base color
$blue:#324157;
$light-blue:#3A71A8;
$red:#C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow:#FEC171;
$panGreen: #30B08F;
// 默认菜单主题风格
$base-menu-color: #bfcbd9;
$base-menu-color-active: #ffffff;
$base-menu-background: #1a1f2e;
$base-logo-title-color: #ffffff;
$base-menu-light-color:rgba(0,0,0,.70);
$base-menu-light-background:#ffffff;
$base-logo-light-title-color: #001529;
$base-sub-menu-background: #141824;
$base-sub-menu-hover: rgba(255,255,255,.06);
$base-sidebar-width: 200px;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuColor: $base-menu-color;
menuLightColor: $base-menu-light-color;
menuColorActive: $base-menu-color-active;
menuBackground: $base-menu-background;
menuLightBackground: $base-menu-light-background;
subMenuBackground: $base-sub-menu-background;
subMenuHover: $base-sub-menu-hover;
sideBarWidth: $base-sidebar-width;
logoTitleColor: $base-logo-title-color;
logoLightTitleColor: $base-logo-light-title-color
}
// base color - ERPNext inspired palette
$blue:#1171c4;
$light-blue:#409EFF;
$red:#C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow:#FEC171;
$panGreen: #30B08F;
// 默认菜单主题风格ERPNext风格白色边栏蓝色主色
$base-menu-color: #555c70;
$base-menu-color-active: #1171c4;
$base-menu-background: #1a2332;
$base-logo-title-color: #ffffff;
$base-menu-light-color: rgba(0,0,0,.65);
$base-menu-light-background: #ffffff;
$base-logo-light-title-color: #1171c4;
$base-sub-menu-background: #111a27;
$base-sub-menu-hover: rgba(17,113,196,.08);
$base-sidebar-width: 210px;
:export {
menuColor: $base-menu-color;
menuLightColor: $base-menu-light-color;
menuColorActive: $base-menu-color-active;
menuBackground: $base-menu-background;
menuLightBackground: $base-menu-light-background;
subMenuBackground: $base-sub-menu-background;
subMenuHover: $base-sub-menu-hover;
sideBarWidth: $base-sidebar-width;
logoTitleColor: $base-logo-title-color;
logoLightTitleColor: $base-logo-light-title-color
}

View File

@@ -7,7 +7,7 @@ module.exports = {
/**
* 侧边栏主题 深色主题theme-dark浅色主题theme-light
*/
sideTheme: 'theme-dark',
sideTheme: 'theme-light',
/**
* 系统布局配置
@@ -62,5 +62,5 @@ module.exports = {
/**
* 底部版权文本内容
*/
footerContent: 'Copyright © 2018-2026 RuoYi. All Rights Reserved.'
footerContent: 'Copyright © 2024-2026 福安德. 版权所有'
}

View File

@@ -6,7 +6,7 @@ const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, t
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const state = {
title: '',
theme: storageSetting.theme || '#409EFF',
theme: storageSetting.theme || '#1171c4',
sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings,
navType: storageSetting.navType === undefined ? navType : storageSetting.navType,

View File

@@ -0,0 +1,77 @@
<template>
<div class="app-container">
<div class="filter-bar">
<el-form :inline="true" size="small">
<el-form-item label="选择RFQ">
<el-select v-model="selectedRfqId" placeholder="请选择要比价的RFQ" filterable style="width:320px">
<el-option v-for="r in rfqOptions" :key="r.rfqId" :label="r.rfqNo+' — '+r.rfqTitle" :value="r.rfqId" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-data-analysis" @click="doCompare" :loading="loading">开始比价</el-button>
</el-form-item>
</el-form>
</div>
<div v-if="result.length === 0 && !loading" class="empty-tip">
<i class="el-icon-data-analysis" style="font-size:48px;color:#ddd"></i>
<p>请选择RFQ并点击"开始比价"</p>
</div>
<div v-for="(item, idx) in result" :key="item.rfqItemId" style="margin-bottom:24px">
<div class="compare-header">
<span class="item-no">物料 {{ idx+1 }}</span>
<strong>{{ item.materialName }}</strong>
<span v-if="item.spec" style="color:#909399;margin-left:8px">{{ item.spec }}</span>
<span style="margin-left:16px;color:#606266">数量: {{ item.quantity }} {{ item.unit }}</span>
</div>
<el-table :data="item.prices || []" border size="small">
<el-table-column label="供应商" prop="supplierName" min-width="140">
<template slot-scope="scope">
<i class="el-icon-star-on" style="color:#f7ba2a;margin-right:4px" v-if="scope.row.lowestPrice"></i>
{{ scope.row.supplierName }}
</template>
</el-table-column>
<el-table-column label="报价单号" prop="quoteNo" width="140" />
<el-table-column label="单价" prop="unitPrice" width="120" align="right">
<template slot-scope="scope">
<span :style="scope.row.lowestPrice ? 'color:#67C23A;font-weight:bold' : ''">
¥{{ scope.row.unitPrice }}
</span>
<el-tag v-if="scope.row.lowestPrice" type="success" size="mini" style="margin-left:4px">最低</el-tag>
</template>
</el-table-column>
<el-table-column label="总价" prop="totalPrice" width="130" align="right">
<template slot-scope="scope">¥{{ scope.row.totalPrice }}</template>
</el-table-column>
<el-table-column label="交货期(天)" prop="deliveryDays" width="100" align="center" />
</el-table>
<div v-if="!item.prices || item.prices.length === 0" style="padding:12px;color:#909399;background:#fafafa;border:1px solid #eee">暂无供应商报价</div>
</div>
</div>
</template>
<script>
import { compareRfq } from "@/api/bid/comparison";
import { listRfq } from "@/api/bid/rfq";
export default {
name: "Comparison",
data() {
return { selectedRfqId: null, loading: false, result: [], rfqOptions: [] };
},
created() {
listRfq({ pageSize: 200, status: "published" }).then(r => { this.rfqOptions = r.rows || []; });
},
methods: {
doCompare() {
if (!this.selectedRfqId) { this.$message.warning("请先选择RFQ"); return; }
this.loading = true;
compareRfq(this.selectedRfqId).then(r => { this.result = r.data || []; this.loading = false; }).catch(() => { this.loading = false; });
}
}
};
</script>
<style scoped>
.compare-header { background:#f5f7fa; padding:10px 16px; border-left:4px solid #409EFF; margin-bottom:8px; border-radius:2px; }
.item-no { background:#409EFF; color:#fff; padding:2px 8px; border-radius:10px; font-size:12px; margin-right:8px; }
.empty-tip { text-align:center; padding:80px; color:#909399; }
</style>

View File

@@ -0,0 +1,75 @@
<template>
<div class="app-container">
<el-table v-loading="loading" :data="list">
<el-table-column label="供应商" prop="supplierName" />
<el-table-column label="采购单" prop="poNo" width="140" />
<el-table-column label="质量" width="70" align="center">
<template slot-scope="scope"><el-rate :value="scope.row.qualityScore" disabled show-score /></template>
</el-table-column>
<el-table-column label="交期" width="70" align="center">
<template slot-scope="scope"><el-rate :value="scope.row.deliveryScore" disabled show-score /></template>
</el-table-column>
<el-table-column label="服务" width="70" align="center">
<template slot-scope="scope"><el-rate :value="scope.row.serviceScore" disabled show-score /></template>
</el-table-column>
<el-table-column label="价格" width="70" align="center">
<template slot-scope="scope"><el-rate :value="scope.row.priceScore" disabled show-score /></template>
</el-table-column>
<el-table-column label="综合评分" width="90" align="center">
<template slot-scope="scope"><span style="color:#F7BA2A;font-weight:bold">{{ scope.row.totalScore }}</span></template>
</el-table-column>
<el-table-column label="评价意见" prop="comment" :show-overflow-tooltip="true" />
<el-table-column label="评价人" prop="evaluator" width="100" />
<el-table-column label="评价时间" prop="evalTime" width="160" />
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" style="margin-top:16px">添加评价</el-button>
<el-dialog title="供应商评价" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="供应商">
<el-select v-model="form.supplierId" placeholder="选择供应商" style="width:100%">
<el-option v-for="s in supplierOptions" :key="s.supplierId" :label="s.supplierName" :value="s.supplierId" />
</el-select>
</el-form-item>
<el-form-item label="质量评分"><el-rate v-model="form.qualityScore" /></el-form-item>
<el-form-item label="交期评分"><el-rate v-model="form.deliveryScore" /></el-form-item>
<el-form-item label="服务评分"><el-rate v-model="form.serviceScore" /></el-form-item>
<el-form-item label="价格评分"><el-rate v-model="form.priceScore" /></el-form-item>
<el-form-item label="评价意见"><el-input v-model="form.comment" type="textarea" rows="3" /></el-form-item>
</el-form>
<div slot="footer">
<el-button @click="open=false">取消</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listEvaluation, addEvaluation } from "@/api/bid/evaluation";
import { listSupplier } from "@/api/bid/supplier";
export default {
name: "Evaluation",
data() {
return {
loading: false, total: 0, list: [], open: false,
supplierOptions: [],
queryParams: { pageNum: 1, pageSize: 10 },
form: { qualityScore: 5, deliveryScore: 5, serviceScore: 5, priceScore: 5 }
};
},
created() { this.getList(); listSupplier({ pageSize: 200 }).then(r => { this.supplierOptions = r.rows || []; }); },
methods: {
getList() {
this.loading = true;
listEvaluation(this.queryParams).then(r => { this.list = r.rows; this.total = r.total; this.loading = false; });
},
handleAdd() { this.form = { qualityScore: 5, deliveryScore: 5, serviceScore: 5, priceScore: 5 }; this.open = true; },
submitForm() {
this.form.totalScore = ((this.form.qualityScore + this.form.deliveryScore + this.form.serviceScore + this.form.priceScore) / 4).toFixed(1);
addEvaluation(this.form).then(() => { this.$modal.msgSuccess("评价成功"); this.open = false; this.getList(); });
}
}
};
</script>

View File

@@ -0,0 +1,132 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
<el-form-item label="物料名称" prop="materialName">
<el-input v-model="queryParams.materialName" placeholder="请输入物料名称" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="物料编码" prop="materialCode">
<el-input v-model="queryParams.materialCode" placeholder="请输入物料编码" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete">删除</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="materialList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="物料编码" prop="materialCode" width="130" />
<el-table-column label="物料名称" prop="materialName" :show-overflow-tooltip="true" />
<el-table-column label="规格型号" prop="spec" :show-overflow-tooltip="true" />
<el-table-column label="单位" prop="unit" width="80" />
<el-table-column label="品牌" prop="brand" />
<el-table-column label="状态" align="center" width="80">
<template slot-scope="scope">
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)" />
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
<el-table-column label="操作" align="center" width="160">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="物料编码" prop="materialCode">
<el-input v-model="form.materialCode" placeholder="请输入物料编码" />
</el-form-item>
<el-form-item label="物料名称" prop="materialName">
<el-input v-model="form.materialName" placeholder="请输入物料名称" />
</el-form-item>
<el-form-item label="规格型号" prop="spec">
<el-input v-model="form.spec" placeholder="请输入规格型号" />
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="单位" prop="unit">
<el-input v-model="form.unit" placeholder="如:台/件/米" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="品牌" prop="brand">
<el-input v-model="form.brand" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="描述" prop="description">
<el-input v-model="form.description" type="textarea" rows="3" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listMaterial, getMaterial, addMaterial, updateMaterial, delMaterial } from "@/api/bid/material";
export default {
name: "Material",
data() {
return {
loading: false, multiple: true, total: 0, materialList: [],
open: false, title: "",
queryParams: { pageNum: 1, pageSize: 10, materialName: null, materialCode: null },
form: {},
rules: {
materialCode: [{ required: true, message: "物料编码不能为空", trigger: "blur" }],
materialName: [{ required: true, message: "物料名称不能为空", trigger: "blur" }],
}
};
},
created() { this.getList(); },
methods: {
getList() {
this.loading = true;
listMaterial(this.queryParams).then(res => {
this.materialList = res.rows;
this.total = res.total;
this.loading = false;
});
},
handleQuery() { this.queryParams.pageNum = 1; this.getList(); },
resetQuery() { this.resetForm("queryForm"); this.handleQuery(); },
handleSelectionChange(sel) { this.multiple = !sel.length; },
handleAdd() { this.reset(); this.open = true; this.title = "新增物料"; },
handleUpdate(row) {
this.reset();
getMaterial(row.materialId).then(res => { this.form = res.data; this.open = true; this.title = "修改物料"; });
},
handleDelete(row) {
const ids = row.materialId || this.ids;
this.$modal.confirm("确认删除?").then(() => delMaterial(ids)).then(() => { this.getList(); this.$modal.msgSuccess("删除成功"); });
},
handleStatusChange(row) { updateMaterial(row); },
reset() { this.form = { status: "0" }; this.resetForm("form"); },
cancel() { this.open = false; this.reset(); },
submitForm() {
this.$refs["form"].validate(valid => {
if (!valid) return;
const action = this.form.materialId ? updateMaterial : addMaterial;
action(this.form).then(() => { this.$modal.msgSuccess("操作成功"); this.open = false; this.getList(); });
});
}
}
};
</script>

View File

@@ -0,0 +1,106 @@
<template>
<div class="app-container">
<el-form :model="queryParams" size="small" :inline="true">
<el-form-item label="状态">
<el-select v-model="queryParams.status" clearable placeholder="全部" style="width:110px">
<el-option label="待处理" value="pending"/>
<el-option label="处理中" value="processing"/>
<el-option label="已解决" value="resolved"/>
<el-option label="已拒绝" value="rejected"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="getList">搜索</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">提交异议</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="list">
<el-table-column label="采购单号" prop="poNo" width="150" />
<el-table-column label="供应商" prop="supplierName" width="150" />
<el-table-column label="异议原因" prop="reason" :show-overflow-tooltip="true" />
<el-table-column label="状态" width="100">
<template slot-scope="scope">
<el-tag :type="{ pending:'warning', processing:'primary', resolved:'success', rejected:'danger' }[scope.row.status]">
{{ { pending:'待处理', processing:'处理中', resolved:'已解决', rejected:'已拒绝' }[scope.row.status] || scope.row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="处理结果" prop="resolution" :show-overflow-tooltip="true" />
<el-table-column label="提交时间" prop="createTime" width="160" />
<el-table-column label="操作" align="center" width="150">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="handleResolve(scope.row)" v-if="scope.row.status==='pending'||scope.row.status==='processing'" style="color:#67C23A">处理</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<el-dialog title="提交异议" :visible.sync="addOpen" width="500px" append-to-body>
<el-form ref="addForm" :model="addForm" label-width="100px">
<el-form-item label="采购单号"><el-input v-model="addForm.poId" placeholder="输入采购单ID" /></el-form-item>
<el-form-item label="供应商">
<el-select v-model="addForm.supplierId" placeholder="选择供应商" style="width:100%">
<el-option v-for="s in supplierOptions" :key="s.supplierId" :label="s.supplierName" :value="s.supplierId" />
</el-select>
</el-form-item>
<el-form-item label="异议原因"><el-input v-model="addForm.reason" type="textarea" rows="4" /></el-form-item>
</el-form>
<div slot="footer">
<el-button @click="addOpen=false">取消</el-button>
<el-button type="primary" @click="submitAdd">提交</el-button>
</div>
</el-dialog>
<el-dialog title="处理异议" :visible.sync="resolveOpen" width="460px" append-to-body>
<el-form :model="resolveForm" label-width="90px">
<el-form-item label="处理结果"><el-input v-model="resolveForm.resolution" type="textarea" rows="4" /></el-form-item>
<el-form-item label="处理状态">
<el-radio-group v-model="resolveForm.status">
<el-radio label="resolved">已解决</el-radio>
<el-radio label="rejected">拒绝</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="resolveOpen=false">取消</el-button>
<el-button type="primary" @click="submitResolve">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listObjection, addObjection, updateObjection } from "@/api/bid/objection";
import { listSupplier } from "@/api/bid/supplier";
export default {
name: "Objection",
data() {
return {
loading: false, total: 0, list: [],
addOpen: false, resolveOpen: false,
supplierOptions: [],
queryParams: { pageNum: 1, pageSize: 10, status: null },
addForm: {}, resolveForm: {}
};
},
created() { this.getList(); listSupplier({ pageSize: 200 }).then(r => { this.supplierOptions = r.rows || []; }); },
methods: {
getList() {
this.loading = true;
listObjection(this.queryParams).then(r => { this.list = r.rows; this.total = r.total; this.loading = false; });
},
handleAdd() { this.addForm = {}; this.addOpen = true; },
submitAdd() {
addObjection(this.addForm).then(() => { this.$modal.msgSuccess("提交成功"); this.addOpen = false; this.getList(); });
},
handleResolve(row) { this.resolveForm = { objectionId: row.objectionId, status: "resolved" }; this.resolveOpen = true; },
submitResolve() {
updateObjection(this.resolveForm).then(() => { this.$modal.msgSuccess("处理成功"); this.resolveOpen = false; this.getList(); });
}
}
};
</script>

View File

@@ -0,0 +1,177 @@
<template>
<div class="app-container">
<el-form :model="queryParams" size="small" :inline="true" ref="queryForm">
<el-form-item label="采购单号" prop="poNo">
<el-input v-model="queryParams.poNo" placeholder="采购单号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="全部" clearable style="width:110px">
<el-option label="草稿" value="draft"/>
<el-option label="已确认" value="confirmed"/>
<el-option label="已交付" value="delivered"/>
<el-option label="已关闭" value="closed"/>
<el-option label="异议中" value="disputed"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新建采购单</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="list">
<el-table-column label="采购单号" prop="poNo" width="160" />
<el-table-column label="供应商" prop="supplierName" />
<el-table-column label="RFQ" prop="rfqTitle" :show-overflow-tooltip="true" />
<el-table-column label="总金额" prop="totalAmount" width="130" align="right">
<template slot-scope="scope"><span style="color:#409EFF;font-weight:bold">¥{{ scope.row.totalAmount }}</span></template>
</el-table-column>
<el-table-column label="交货日期" prop="deliveryDate" width="110" />
<el-table-column label="状态" width="100">
<template slot-scope="scope">
<el-tag :type="statusType(scope.row.status)">{{ statusLabel(scope.row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="createTime" width="160" />
<el-table-column label="操作" align="center" width="220">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-if="scope.row.status==='draft'">编辑</el-button>
<el-button size="mini" type="text" style="color:#67C23A" @click="handleConfirm(scope.row)" v-if="scope.row.status==='draft'">确认</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-if="scope.row.status==='draft'">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :visible.sync="open" width="960px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="供应商" prop="supplierId">
<el-select v-model="form.supplierId" placeholder="选择供应商" filterable style="width:100%">
<el-option v-for="s in supplierOptions" :key="s.supplierId" :label="s.supplierName" :value="s.supplierId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="交货日期" prop="deliveryDate">
<el-date-picker v-model="form.deliveryDate" type="date" placeholder="选择日期" value-format="yyyy-MM-dd" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="交货地址"><el-input v-model="form.deliveryAddr" /></el-form-item>
<el-divider content-position="left">采购明细</el-divider>
<el-table :data="form.items || []" border size="small">
<el-table-column label="物料名称" min-width="150">
<template slot-scope="scope"><el-input v-model="scope.row.materialName" size="small" /></template>
</el-table-column>
<el-table-column label="规格" min-width="120">
<template slot-scope="scope"><el-input v-model="scope.row.spec" size="small" /></template>
</el-table-column>
<el-table-column label="单位" width="80">
<template slot-scope="scope"><el-input v-model="scope.row.unit" size="small" /></template>
</el-table-column>
<el-table-column label="数量" width="100">
<template slot-scope="scope">
<el-input-number v-model="scope.row.quantity" :min="0" :precision="2" size="small" style="width:90px" />
</template>
</el-table-column>
<el-table-column label="单价" width="130">
<template slot-scope="scope">
<el-input-number v-model="scope.row.unitPrice" :min="0" :precision="4" size="small" style="width:120px" />
</template>
</el-table-column>
<el-table-column label="金额" width="120" align="right">
<template slot-scope="scope">
<span style="color:#409EFF">{{ ((scope.row.quantity||0)*(scope.row.unitPrice||0)).toFixed(2) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="60" align="center">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-delete" @click="form.items.splice(scope.$index,1)" style="color:#f56c6c" />
</template>
</el-table-column>
</el-table>
<el-button size="small" style="margin-top:8px" @click="form.items.push({materialName:'',unit:'',quantity:1,unitPrice:0})" icon="el-icon-plus">添加行</el-button>
<el-form-item label="备注" style="margin-top:16px"><el-input v-model="form.remark" type="textarea" rows="2" /></el-form-item>
</el-form>
<div slot="footer">
<el-button @click="open=false">取消</el-button>
<el-button type="primary" @click="submitForm">保存</el-button>
</div>
</el-dialog>
<el-drawer title="采购单详情" :visible.sync="detailOpen" size="720px">
<div v-if="detailData" style="padding:20px">
<el-descriptions :column="2" border>
<el-descriptions-item label="采购单号">{{ detailData.poNo }}</el-descriptions-item>
<el-descriptions-item label="供应商">{{ detailData.supplierName }}</el-descriptions-item>
<el-descriptions-item label="总金额"><span style="color:#409EFF;font-size:18px;font-weight:bold">¥{{ detailData.totalAmount }}</span></el-descriptions-item>
<el-descriptions-item label="状态"><el-tag :type="statusType(detailData.status)">{{ statusLabel(detailData.status) }}</el-tag></el-descriptions-item>
<el-descriptions-item label="交货日期">{{ detailData.deliveryDate }}</el-descriptions-item>
<el-descriptions-item label="交货地址">{{ detailData.deliveryAddr }}</el-descriptions-item>
</el-descriptions>
<el-divider>明细</el-divider>
<el-table :data="detailData.items || []" border size="small">
<el-table-column label="物料" prop="materialName" />
<el-table-column label="规格" prop="spec" />
<el-table-column label="数量" prop="quantity" align="right" />
<el-table-column label="单价" prop="unitPrice" align="right" />
<el-table-column label="金额" prop="totalPrice" align="right" />
</el-table>
</div>
</el-drawer>
</div>
</template>
<script>
import { listPurchaseorder, getPurchaseorder, addPurchaseorder, updatePurchaseorder, confirmPurchaseorder, delPurchaseorder } from "@/api/bid/purchaseorder";
import { listSupplier } from "@/api/bid/supplier";
export default {
name: "PurchaseOrder",
data() {
return {
loading: false, total: 0, list: [],
open: false, title: "", detailOpen: false, detailData: null,
supplierOptions: [],
queryParams: { pageNum: 1, pageSize: 10, poNo: null, status: null },
form: { items: [], currency: "CNY" },
rules: { supplierId: [{ required: true, message: "请选择供应商", trigger: "change" }] }
};
},
created() { this.getList(); listSupplier({ pageSize: 200 }).then(r => { this.supplierOptions = r.rows || []; }); },
methods: {
getList() {
this.loading = true;
listPurchaseorder(this.queryParams).then(r => { this.list = r.rows; this.total = r.total; this.loading = false; });
},
handleQuery() { this.queryParams.pageNum = 1; this.getList(); },
resetQuery() { this.resetForm("queryForm"); this.handleQuery(); },
handleAdd() { this.form = { items: [], currency: "CNY", status: "draft" }; this.open = true; this.title = "新建采购单"; },
handleUpdate(row) { getPurchaseorder(row.poId).then(r => { this.form = r.data; this.open = true; this.title = "编辑采购单"; }); },
handleView(row) { getPurchaseorder(row.poId).then(r => { this.detailData = r.data; this.detailOpen = true; }); },
handleConfirm(row) {
this.$modal.confirm("确认提交采购单?").then(() => confirmPurchaseorder(row.poId))
.then(() => { this.$modal.msgSuccess("已确认"); this.getList(); });
},
handleDelete(row) {
this.$modal.confirm("确认删除?").then(() => delPurchaseorder(row.poId)).then(() => { this.getList(); this.$modal.msgSuccess("删除成功"); });
},
submitForm() {
this.$refs["form"].validate(valid => {
if (!valid) return;
const action = this.form.poId ? updatePurchaseorder : addPurchaseorder;
action(this.form).then(() => { this.$modal.msgSuccess("保存成功"); this.open = false; this.getList(); });
});
},
statusType(s) { return { draft:"info", confirmed:"success", delivered:"", closed:"", disputed:"danger" }[s] || ""; },
statusLabel(s) { return { draft:"草稿", confirmed:"已确认", delivered:"已交付", closed:"已关闭", disputed:"异议中" }[s] || s; }
}
};
</script>

Some files were not shown because too many files have changed in this diff Show More