sby 10 months ago
parent 568e3dd9a8
commit 43693f9842

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 KiB

@ -0,0 +1,23 @@
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="WarehouseMS" />
</profile>
</annotationProcessing>
</component>
</project>

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="@localhost" uuid="644ebb56-8816-4c1c-b7a6-fa23e4461a33">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.resource.type" value="Deployment" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/design.sql" dialect="MySQL" />
</component>
</project>

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Mr Zhang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" dumb="true">
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
</content>
</component>
</module>

@ -0,0 +1,82 @@
/*
Navicat Premium Data Transfer
Source Server : fuwuqi_mysql
Source Server Type : MySQL
Source Server Version : 50728
Source Host : ip:3306
Source Schema : design
Target Server Type : MySQL
Target Server Version : 50728
File Encoding : 65001
Date: 07/02/2020 13:05:26
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for goods
-- ----------------------------
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods` (
`gid` int(11) NOT NULL AUTO_INCREMENT,
`gName` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`gShelf` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`gCnt` int(11) NULL DEFAULT 0,
`gPrice` decimal(10, 2) NULL DEFAULT NULL,
PRIMARY KEY (`gid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 33 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of goods
-- ----------------------------
INSERT INTO `goods` VALUES (1, '粉笔', '3号', 4, 5.00);
INSERT INTO `goods` VALUES (2, '双面奶', '2号', 3, 0.30);
INSERT INTO `goods` VALUES (3, '水杯', '2号', 13, 5.00);
INSERT INTO `goods` VALUES (4, '大宝', '2号', 12, 10.90);
INSERT INTO `goods` VALUES (5, '曲奇饼干', '4号', 3, 0.90);
INSERT INTO `goods` VALUES (6, '小刚比', '1号', 12, 12.10);
INSERT INTO `goods` VALUES (7, '比比', '5号', 10, 1.10);
INSERT INTO `goods` VALUES (8, '白萝卜', '6号', 12, 1.10);
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`userid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`userpwd` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`userphone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`useraddress` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`userid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('小强', '111', '10010', '北京海定');
INSERT INTO `user` VALUES ('小猪', '222', '99923', '安徽12');
INSERT INTO `user` VALUES ('小白', '111', '123', '桂林');
INSERT INTO `user` VALUES ('小美', '111', '10086', '北京海淀');
INSERT INTO `user` VALUES ('张三', '1234', '12345678', '广东省88');
INSERT INTO `user` VALUES ('李四', '111', '10086', '33333');
SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE IF EXISTS `stock_log`;
create table stock_log
(
id int auto_increment
primary key,
gid int not null comment '商品id',
outTime varchar(20) not null comment '出库时间',
outNum int not null comment '出库数量'
)
comment '出库记录';

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.design</groupId>
<artifactId>WarehouseMS</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,26 @@
#-------------------------------------------------------------------------------#
# Qodana analysis is configured by qodana.yaml file #
# https://www.jetbrains.com/help/qodana/qodana-yaml.html #
#-------------------------------------------------------------------------------#
version: "1.0"
#Specify inspection profile for code analysis
profile:
name: qodana.starter
#Enable inspections
#include:
# - name: <SomeEnabledInspectionId>
#Disable inspections
#exclude:
# - name: <SomeDisabledInspectionId>
# paths:
# - <path/where/not/run/inspection>
projectJDK: 8 #(Applied in CI/CD pipeline)
#Execute shell command before Qodana execution (Applied in CI/CD pipeline)
#bootstrap: sh ./prepare-qodana.sh
#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline)
#plugins:
# - id: <plugin.id> #(plugin id can be found at https://plugins.jetbrains.com)
#Specify Qodana linter for analysis (Applied in CI/CD pipeline)
linter: jetbrains/qodana-jvm:latest
include:
- name: ClassLoaderInstantiation

@ -0,0 +1,20 @@
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("/views/login.fxml"));
primaryStage.setTitle("用户登录");
primaryStage.setScene(new Scene(root, 500, 400));
primaryStage.setResizable(false);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

@ -0,0 +1,75 @@
package controller;
import dao.IUserDao;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import org.apache.ibatis.session.SqlSession;
import patterns.memento.Memento;
import patterns.singleton.SingleRegisterStage;
import utils.DialogUtil;
import utils.MybatisUtil;
import java.io.IOException;
public class LoginController {
@FXML
private AnchorPane rootPane;
@FXML
private TextField userid;
@FXML
private PasswordField userpwd;
// 获取SqlSession对象
private SqlSession sqlSession = MybatisUtil.getSession();
// 创建userDao接口然后通过反射来获取代理对象
private IUserDao userDao = sqlSession.getMapper(IUserDao.class);
@FXML
void loginClick() throws IOException {
String id = userid.getText();
String pwd = userpwd.getText();
if (id == null || pwd == null || id.equals("") || pwd.equals("")) {
DialogUtil.showDialog("ERROR", "输入不能为空!");
} else {
int cnt = userDao.selectHasUser(id);
if (cnt == 0) {
DialogUtil.showDialog("WARNING", "用户不存在,请先注册!");
} else {
Memento user = userDao.findUserById(id);
String mypwd = user.getUserpwd();
if (mypwd.equals(pwd)) {
// 跳转到主界面
FXMLLoader Loader = new FXMLLoader(getClass().getResource("/views/mainPage.fxml"));
Parent parent = Loader.load();
MainPageController mocl = Loader.getController();
mocl.initPersonData(id);
Stage stage = new Stage();
stage.setTitle("小型仓库管理系统");
stage.setScene(new Scene(parent, 900, 700));
stage.setResizable(false);
stage.show();
// 关闭登录窗口,并且关闭会话资源
sqlSession.close();
((Stage) rootPane.getScene().getWindow()).close();
} else {
DialogUtil.showDialog("ERROR", "密码错误!");
}
}
}
}
@FXML
void registerClick() throws IOException {
// 单例模式生成一个注册界面
SingleRegisterStage.getInstance().show();
}
}

@ -0,0 +1,681 @@
package controller;
import dao.IGoodsDao;
import dao.IStockLogDao;
import dao.IUserDao;
import emp.EmpGoods;
import emp.EmpLook;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import org.apache.ibatis.session.SqlSession;
import patterns.bridge.ImpLog;
import patterns.bridge.JImpLog;
import patterns.bridge.Log;
import patterns.bridge.TextFileLog;
import patterns.memento.CareTaker;
import patterns.memento.Memento;
import patterns.memento.UserInfoOriginator;
import patterns.observer.ComputeObserver;
import patterns.observer.ConcreteSubject;
import patterns.observer.Observer;
import patterns.observer.Subject;
import patterns.prototype.Goods;
import patterns.prototype.StockLog;
import utils.DialogUtil;
import utils.MybatisUtil;
import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;
public class MainPageController {
@FXML
private TabPane tabpane;
@FXML
private TextField goodName;
@FXML
private TextField goodShelfid;
@FXML
private TextField goodTotal;
@FXML
private TextField goodPrice;
@FXML
private Label showValue;
@FXML
private TextArea textArea;
@FXML
private TextField userid;
@FXML
private TextField userphone;
@FXML
private TextField useraddress;
@FXML
private TextField oldpwd;
@FXML
private TextField newpwd;
@FXML
private TableView<EmpLook> tableView;
@FXML
private TableColumn<EmpLook, Integer> colid;
@FXML
private TableColumn<EmpLook, String> colname;
@FXML
private TableColumn<EmpLook, String> colshelf;
@FXML
private TableColumn<EmpLook, Integer> colnum;
@FXML
private TableColumn<EmpLook, Double> colprice;
@FXML
private TextField fillid;
@FXML
private TextField fillname;
@FXML
private TextField fillshelf;
@FXML
private TextField fillnum;
@FXML
private TextField fillPrice;
@FXML
private DatePicker outTime;
// 将所有货物作为参数传递给观察者
private ArrayList<Goods> goodsArrayList = new ArrayList<>();
// 创建一个抽象被观察者的实例
private Subject subject = new ConcreteSubject();
// 每次点击添加时去创建一个新的
private Observer observer;
// 第一次初始化以后直接clone
private Goods headGoods = new Goods();
// 获取SqlSession对象
private SqlSession sqlSession = MybatisUtil.getSession();
// 创建userDao接口然后通过反射来获取代理对象
private IUserDao userDao = sqlSession.getMapper(IUserDao.class);
// 创建goodsDao接口然后通过反射来获取代理对象
private IGoodsDao goodsDao = sqlSession.getMapper(IGoodsDao.class);
private IStockLogDao stockLogDao = sqlSession.getMapper(IStockLogDao.class);
private String userIDDD = "";
private ObservableList<EmpLook> data = FXCollections.observableArrayList();
private EmpLook empLook;
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private boolean check(String str) {
return str == null || str.equals("");
}
// 创建一个备忘录管理员
private CareTaker careTaker = new CareTaker();
private UserInfoOriginator uiog = new UserInfoOriginator();
// tab标签的切换
@FXML
void tabClick() {
if (tabpane.getSelectionModel().isSelected(2)) {
System.out.println("点击了个人信息!");
} else if (tabpane.getSelectionModel().isSelected(1)) {
System.out.println("点击了货物出库!");
this.outTime.setConverter(new StringConverter<LocalDate>() {
@Override
public String toString(LocalDate object) {
if (object != null) {
return object.format(DATE_FORMAT);
}
return "";
}
@Override
public LocalDate fromString(String string) {
if (string != null && !string.isEmpty()) {
try {
return LocalDate.parse(string, DATE_FORMAT);
} catch (DateTimeParseException e) {
DialogUtil.showDialog("ERROR", "输入的出库时间必须是yyyy-MM-dd格式的");
return null;
}
}
return null;
}
});
this.outTime.setPromptText("yyyy-MM-dd");
data.clear();
initGoods();
}
}
public void initPersonData(String useriddd) {
userIDDD = useriddd;
Memento user = userDao.findUserById(useriddd);
updateData(user.getUserid(), user.getUserpwd(), user.getUserphone(), user.getUseraddress());
uiog.setUseraddress(user.getUseraddress());
uiog.setUserid(user.getUserid());
uiog.setUserphone(user.getUserphone());
uiog.setUserpwd(user.getUserpwd());
careTaker.add(uiog.saveToMemento());
}
private void updateData(String uid, String upwd, String uph, String uad) {
userid.setText(uid);
oldpwd.setText(upwd);
userphone.setText(uph);
useraddress.setText(uad);
}
@FXML
void addClick() {
String gName = goodName.getText();
String gShelf = goodShelfid.getText();
String gTotal = goodTotal.getText();
String gPrice = goodPrice.getText();
if (check(gName) || check(gShelf) || check(gTotal) || check(gPrice)) {
DialogUtil.showDialog("ERROR", "输入不能为空!");
} else {
// 判断是否为非负整数
String reg1 = "^\\d+$";
if (!gTotal.matches(reg1)) {
DialogUtil.showDialog("ERROR", "输入的货物数量必须为正整数!");
return;
}
// 判断是否为非负浮点数
String reg2 = "^\\d+(\\.\\d+)?$";
if (!gPrice.matches(reg2)) {
DialogUtil.showDialog("ERROR", "输入的货物单价必须为非负浮点数!");
return;
} else {
// 使用原型模式先克隆一个货物信息对象,并且重新赋值
Goods curGoods = (Goods) headGoods.clone();
curGoods.setgName(gName);
curGoods.setgShelf(gShelf);
curGoods.setgCnt(Integer.parseInt(gTotal));
curGoods.setgPrice(Double.parseDouble(gPrice));
goodsArrayList.add(curGoods);
// 使用观察者更新清单和总价格
observer = new ComputeObserver(goodsArrayList);
// 添加观察者
subject.attach(observer);
// 通知观察者更新
EmpGoods ans = subject.transform();
// 将结果显示在列表上
textArea.setText(ans.getMessage());
showValue.setText("¥" + (Math.round(ans.getTolPrice() * 100) / 100.0));
// 注销当前对象
subject.detach(observer);
// 清空表单数据
clearClick();
}
}
}
@FXML
void clearClick() {
goodName.setText("");
goodShelfid.setText("");
goodTotal.setText("");
goodPrice.setText("");
}
// 把所有商品都插入到数据库
@FXML
void addToDBAClick() {
if (check(textArea.getText())) {
return;
}
// 将所有商品信息都插入到数据库中
int cnt = goodsDao.addGoods(goodsArrayList);
// 注意提交事务,不然没有增加数据
if (cnt == goodsArrayList.size()) {
sqlSession.commit();
// 打印日志
/*IPrintLog printLog = new PrintLogSon();
PrintLogProxy proxy = new PrintLogProxy(printLog);
proxy.output(textArea.getText());*/
ImpLog j = new JImpLog(); //建立java平台
Log jl = new TextFileLog(j); //建立基于java 的文本文件日志写入
jl.write(textArea.getText()); //写入日志文件
DialogUtil.showDialog("INFORMATION", "入库成功!日志已成功写入!");
showValue.setText("¥0.00");
textArea.setText("");
} else {
DialogUtil.showDialog("ERROR", "入库失败!");
}
}
@FXML
void resetClick() {
userphone.setText("");
useraddress.setText("");
oldpwd.setText("");
newpwd.setText("");
}
@FXML
void revokeClick() {
// 保留的状态大于1才可进行撤销操作
int n = careTaker.getMementoList().size();
if (n > 1) {
// 撤销返回上一级操作
uiog.restoreFromMemento(careTaker.getMementoList().get(n - 2));
// 并且删除掉最后一个
careTaker.getMementoList().remove(n - 1);
// 更新用户信息
Memento tmp = new Memento(userIDDD, uiog.getUserpwd(), uiog.getUserphone(), uiog.getUseraddress());
int cnt = userDao.updateUserById(tmp);
if (cnt > 0) {
sqlSession.commit();
updateData(userIDDD, uiog.getUserpwd(), uiog.getUserphone(), uiog.getUseraddress());
newpwd.setText("");
DialogUtil.showDialog("INFORMATION", "撤销成功!");
// 修改表单状态值
} else {
DialogUtil.showDialog("ERROR", "撤销失败!");
}
}
}
@FXML
void updateClick() {
// 先确定旧密码是否输入正确,若输入正确且新密码输入不为空,则直接修改
String oldp = oldpwd.getText(), newp = newpwd.getText();
if (check(oldp) || check(newp) || check(useraddress.getText()) || check(userphone.getText())) {
DialogUtil.showDialog("ERROR", "输入不能为空!");
return;
}
Memento nowU = userDao.findUserById(userIDDD);
if (!oldp.equals(nowU.getUserpwd())) {
DialogUtil.showDialog("ERROR", "旧密码输入错误!");
return;
}
Memento tmp = new Memento(userIDDD, newp, userphone.getText(), useraddress.getText());
int cnt = userDao.updateUserById(tmp);
if (cnt > 0) {
sqlSession.commit();
DialogUtil.showDialog("INFORMATION", "修改成功!");
// 备忘录保存状态值
uiog.setUserpwd(newp);
uiog.setUserphone(userphone.getText());
uiog.setUseraddress(useraddress.getText());
careTaker.add(uiog.saveToMemento());
} else {
DialogUtil.showDialog("ERROR", "修改失败!");
}
}
// 初始化货物表单数据
private void initGoods() {
List<Goods> allGoods = goodsDao.findAllGoods();
System.out.println(allGoods);
List<EmpLook> query = new ArrayList<>();
for (Goods allGood : allGoods) {
query.add(new EmpLook(allGood.getGid(), allGood.getgName(), allGood.getgShelf(), allGood.getgCnt(), allGood.getgPrice()));
}
data.addAll(query);
tableView.setItems(data);
colid.setCellValueFactory(new PropertyValueFactory<EmpLook, Integer>("goodid"));
colname.setCellValueFactory(new PropertyValueFactory<EmpLook, String>("goodname"));
colshelf.setCellValueFactory(new PropertyValueFactory<EmpLook, String>("goodShelfid"));
colnum.setCellValueFactory(new PropertyValueFactory<EmpLook, Integer>("goodTotal"));
colprice.setCellValueFactory(new PropertyValueFactory<EmpLook, Double>("goodPrice"));
}
//清空下方的表单
void clearFill() {
fillid.setText("");
fillname.setText("");
fillnum.setText("");
fillPrice.setText("");
fillshelf.setText("");
}
// 直接删除商品
@FXML
void deleteClick() {
if (check(fillid.getText())) {
return;
}
// 直接通过编号删除信息
int cnt = goodsDao.deleteGoodById(Integer.parseInt(fillid.getText()));
if (cnt > 0) {
sqlSession.commit();
clearFill();
data.remove(empLook);
DialogUtil.showDialog("INFORMATION", "删除商品成功!");
// 清空表单
} else {
DialogUtil.showDialog("ERROR", "删除商品失败!");
}
}
// 出库一定数量的书籍
@FXML
void outboundClick() {
if (check(fillid.getText())) {
return;
}
// 查询某个商品的信息
int goodId = Integer.parseInt(fillid.getText());
Goods nowG = goodsDao.findGoodById(goodId);
String inputNum = fillnum.getText();
//输入不能为非负整数
String reg3 = "^\\d+$";
if (!inputNum.matches(reg3)) {
DialogUtil.showDialog("ERROR", "出库数量必须为非负整数!");
return;
}
int num1 = Integer.parseInt(fillnum.getText());
int num2 = nowG.getgCnt();
if (num1 > num2) {
DialogUtil.showDialog("ERROR", "输入数量不能超过原有货物的数量!");
return;
}
LocalDate outTimeValue = this.outTime.getValue();
if (outTimeValue == null) {
DialogUtil.showDialog("ERROR", "请输入出库时间!");
return;
}
// 查询该日期下是否存在出库的记录
StockLog log = this.stockLogDao.getStockLog(goodId, outTimeValue.format(DATE_FORMAT));
int result;
if (log == null) {
// 说明没有出库记录,新增。记录出库记录
result = this.stockLogDao.addOutLog(goodId, num1, outTimeValue.format(DATE_FORMAT));
} else {
result = this.stockLogDao.updateLogById(log.getId(), num1);
}
if (result < 0) {
DialogUtil.showDialog("ERROR", "记录出库的商品失败!");
return;
}
// 出库
try {
if (num1 < num2) {
int cnt = goodsDao.updateGoodsById(goodId, num1);
if (cnt > 0) {
sqlSession.commit();
DialogUtil.showDialog("INFORMATION", "出库成功!");
empLook.setGoodTotal(num2 - num1);
} else {
DialogUtil.showDialog("ERROR", "出库失败!");
}
} else { //直接删除该商品
int cnt = goodsDao.deleteGoodById(goodId);
if (cnt > 0) {
sqlSession.commit();
clearFill();
data.remove(empLook);
DialogUtil.showDialog("INFORMATION", "出库成功!");
} else {
DialogUtil.showDialog("ERROR", "出库失败!");
}
}
} finally {
// 回滚记录的出库记录
sqlSession.rollback();
}
}
// 双击选中
@FXML
void rowClick() {
TableView.TableViewSelectionModel<EmpLook> model = tableView.getSelectionModel();
empLook = model.getSelectedItem();
if (empLook == null) return;
System.out.println("当前选中的是" + empLook);
fillid.setText(String.valueOf(empLook.getGoodid()));
fillname.setText(empLook.getGoodname());
fillnum.setText(String.valueOf(empLook.getGoodTotal()));
fillshelf.setText(empLook.getGoodShelfid());
fillPrice.setText(String.valueOf(empLook.getGoodPrice()));
}
//查看位置
@FXML
void location() {
String shelf = fillshelf.getText();
if (shelf == null || shelf.isEmpty()) {
DialogUtil.showDialog("ERROR", "请先选择商品!");
return;
}
String imageUrl = "/images/" + shelf + ".jpeg";
clearFill();
this.showImagePopup(imageUrl);
}
private void showImagePopup(String imageUrl) {
// 创建弹窗
Stage popupStage = new Stage();
popupStage.initModality(Modality.APPLICATION_MODAL);
popupStage.setTitle("图片弹窗");
// 加载图片
URL resource = this.getClass().getResource(imageUrl);
if (resource == null) {
DialogUtil.showDialog("ERROR", "货架位置图不存在,请先配置!");
return;
}
Image image = new Image(resource.toExternalForm());
ImageView imageView = new ImageView(image);
// 设置图片视图的属性
imageView.setFitWidth(600);
imageView.setPreserveRatio(true);
// 布局
StackPane imageRoot = new StackPane(imageView);
Scene imageScene = new Scene(imageRoot, 800, 600);
popupStage.setScene(imageScene);
// 显示弹窗
popupStage.showAndWait();
}
//图表预测
@FXML
void predict() {
String gid = this.fillid.getText();
if (check(gid)) {
DialogUtil.showDialog("ERROR", "请确定选择好了商品或输入商品id");
return;
}
// 查询某个商品的信息
int goodId = Integer.parseInt(fillid.getText());
Goods nowG = this.goodsDao.findGoodById(goodId);
if (nowG == null) {
DialogUtil.showDialog("ERROR", "商品不存在!");
return;
}
// 查询商品的出库数据
List<StockLog> logs = this.stockLogDao.listOutOfStockLog(goodId);
this.showLineChart(nowG, logs);
}
private void showLineChart(Goods goods, List<StockLog> logs) {
if (logs == null || logs.isEmpty()) {
DialogUtil.showDialog("ERROR", "无出库数据,不展示图表!");
return;
}
// 创建新的窗口(弹窗)
Stage chartStage = new Stage();
chartStage.setTitle(goods.getgName());
// 定义X轴和Y轴
CategoryAxis xAxis = new CategoryAxis();
NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("时间");
yAxis.setLabel("出库数量");
// 创建折线图
LineChart<String, Number> lineChart = new LineChart<>(xAxis, yAxis);
lineChart.setTitle("实际出库数量与预测未来一天的出库数量数据");
// 实际数据系列
XYChart.Series<String, Number> actualSeries = new XYChart.Series<>();
actualSeries.setName("实际出库数量");
List<Integer> nums = new ArrayList<>();
logs.stream()
.peek(log -> nums.add(log.getOutNum()))
.forEach(log -> actualSeries.getData().add(new XYChart.Data<>(log.getOutTime(), log.getOutNum())));
// 预测数据系列
XYChart.Series<String, Number> predictedSeries = new XYChart.Series<>();
predictedSeries.setName("预测未来一天的出库数量");
LocalDate newDate = LocalDate.parse(logs.get(logs.size() - 1).getOutTime(), DATE_FORMAT);
String maxDate = newDate.plusDays(1).format(DATE_FORMAT);
int predictNum = this.predictNext(nums);
predictedSeries.getData().add(new XYChart.Data<>(maxDate, predictNum));
actualSeries.getData().add(new XYChart.Data<>(maxDate, predictNum));
// 将数据系列添加到折线图中
lineChart.getData().add(actualSeries);
lineChart.getData().add(predictedSeries);
// 应用样式
lineChart.lookup(".chart-series-line.series1").setStyle("-fx-stroke-dash-array: 20 15;");
Label label;
if (goods.getgCnt() > predictNum) {
label = new Label("库存充足,无需补货!");
label.setStyle("-fx-text-fill: green;");
} else {
label = new Label("库存不足,请尽快补货!");
label.setStyle("-fx-text-fill: red;");
}
VBox vbox = new VBox(10, lineChart, label);
vbox.setAlignment(Pos.CENTER);
Scene scene = new Scene(vbox, 1500, 500);
chartStage.setScene(scene);
// 设置模态窗口
chartStage.initModality(Modality.APPLICATION_MODAL);
chartStage.showAndWait();
}
/**
* 使线
*
* @param data
* @return
*/
private int predictNext(List<Integer> data) {
int n = data.size();
if (n == 0) {
System.out.println("无出库数据返回0");
return 0;
}
if (n < 2) {
System.out.println("出库数据太少,返回跟前一天一致的出库数量!");
return data.get(data.size() - 1);
}
// 计算 x 和 y 的平均值
double sumX = 0;
double sumY = 0;
for (int i = 0; i < n; i++) {
sumX += i;
sumY += data.get(i);
}
double meanX = sumX / n;
double meanY = sumY / n;
// 计算系数 b1 和 b0
double numerator = 0;
double denominator = 0;
for (int i = 0; i < n; i++) {
numerator += (i - meanX) * (data.get(i) - meanY);
denominator += (i - meanX) * (i - meanX);
}
double b1 = numerator / denominator;
double b0 = meanY - b1 * meanX;
// 预测下一天的数据点
return (int) (b0 + b1 * n);
}
//查询
@FXML
void search() {
this.data.clear();
if (this.fillname == null || this.fillname.getText() == null || this.fillname.getText().isEmpty()) {
// 当不存在查询条件,则默认查询全部商品出来
initGoods();
return;
}
String queryString = this.fillname.getText();
// 清空其余输入框的数据,但保留名称的。
clearFill();
this.fillname.setText(queryString);
List<Goods> goods = goodsDao.findGoodsByName(queryString);
goods.forEach(g -> this.data.add(new EmpLook(g.getGid(), g.getgName(), g.getgShelf(), g.getgCnt(), g.getgPrice())));
}
}

@ -0,0 +1,78 @@
package controller;
import dao.IUserDao;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import org.apache.ibatis.session.SqlSession;
import patterns.memento.Memento;
import utils.DialogUtil;
import utils.MybatisUtil;
public class RegisterController {
@FXML
private AnchorPane rootPane;
@FXML
private TextField userid;
@FXML
private TextField userpwd;
@FXML
private TextField userphone;
@FXML
private TextField useraddress;
// 获取SqlSession对象
private SqlSession sqlSession = MybatisUtil.getSession();
// 创建userDao接口然后通过反射来获取代理对象
private IUserDao userDao = sqlSession.getMapper(IUserDao.class);
@FXML
void clearClick() {
userid.setText("");
userpwd.setText("");
userphone.setText("");
useraddress.setText("");
}
private boolean check(String str) {
return str == null || str.equals("");
}
@FXML
void registerClick() {
String id = userid.getText();
String pwd = userpwd.getText();
String phoneNum = userphone.getText();
String address = useraddress.getText();
if (check(id) || check(pwd) || check(phoneNum) || check(address)) {
DialogUtil.showDialog("ERROR", "输入不能为空!");
} else {
int cnt = userDao.selectHasUser(id);
if (cnt > 0) {
// 提示用户名已注册
DialogUtil.showDialog("WARNING", "用户名已存在,请重新输入另一个用户名!");
} else {
// 注册用户,添加一名用户
Memento user = new Memento(id, pwd, phoneNum, address);
cnt = userDao.addUser(user);
//注意提交事务
sqlSession.commit();
if (cnt > 0) {
DialogUtil.showDialog("INFORMATION", "注册成功!");
// 并且销毁当前stage销毁时要先关闭会话资源
sqlSession.close();
((Stage) rootPane.getScene().getWindow()).close();
} else {
DialogUtil.showDialog("ERROR", "注册失败!");
}
}
}
}
}

@ -0,0 +1,27 @@
package dao;
import org.apache.ibatis.annotations.Param;
import patterns.prototype.Goods;
import java.util.List;
public interface IGoodsDao {
// 增加一个或多个商品
int addGoods(List<Goods> goosList);
//查询所有商品信息
List<Goods> findAllGoods();
// 查询某个商品
Goods findGoodById(Integer gid);
//根据商品id出库商品det为减少的数量
int updateGoodsById(@Param("gid") Integer gid, @Param("det") Integer det);
//根据商品id删除某个商品包括减少的数量
int deleteGoodById(Integer gid);
//查询所有商品信息
List<Goods> findGoodsByName(@Param("gName") String name);
}

@ -0,0 +1,45 @@
package dao;
import org.apache.ibatis.annotations.Param;
import patterns.prototype.StockLog;
import java.util.List;
public interface IStockLogDao {
/**
* 线
*
* @param goodId id
* @param outNum
* @param outTime
* @return
*/
int addOutLog(@Param("gid") int goodId, @Param("outNum") int outNum, @Param("outTime") String outTime);
/**
* id
*
* @param gid id
* @return
*/
List<StockLog> listOutOfStockLog(@Param("gid") Integer gid);
/**
* id
*
* @param goodId id
* @param outTime
* @return
*/
StockLog getStockLog(@Param("gid") int goodId, @Param("outTime") String outTime);
/**
*
*
* @param id id
* @param outNum
* @return
*/
int updateLogById(@Param("id") int id, @Param("outNum") int outNum);
}

@ -0,0 +1,20 @@
package dao;
import patterns.memento.Memento;
// 用户接口
public interface IUserDao {
//用户注册,添加用户
int addUser(Memento user);
//查询是否有此用户信息,避免注册相同的用户账号
int selectHasUser(String uid);
//查询用户信息,返回一个用户的实体类
Memento findUserById(String id);
//根据id修改用户信息将其封装成一个用户对象
int updateUserById(Memento user);
}

@ -0,0 +1,36 @@
package emp;
public class EmpGoods {
private String message;
private double tolPrice;
public EmpGoods(String message, double tolPrice) {
this.message = message;
this.tolPrice = tolPrice;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public double getTolPrice() {
return tolPrice;
}
public void setTolPrice(double tolPrice) {
this.tolPrice = tolPrice;
}
@Override
public String toString() {
return "EmpGoods{" +
"message='" + message + '\'' +
", tolPrice=" + tolPrice +
'}';
}
}

@ -0,0 +1,97 @@
package emp;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
public class EmpLook {
private SimpleIntegerProperty goodid = new SimpleIntegerProperty();
private SimpleStringProperty goodname = new SimpleStringProperty();
private SimpleStringProperty goodShelfid = new SimpleStringProperty();
private SimpleIntegerProperty goodTotal = new SimpleIntegerProperty();
private SimpleDoubleProperty goodPrice = new SimpleDoubleProperty();
public EmpLook() {
}
public EmpLook(Integer goodid, String goodname, String goodShelfid, Integer goodTotal, Double goodPrice) {
this.goodid.set(goodid);
this.goodname.set(goodname);
this.goodShelfid.set(goodShelfid);
this.goodTotal.set(goodTotal);
this.goodPrice.set(goodPrice);
}
public int getGoodid() {
return goodid.get();
}
public SimpleIntegerProperty goodidProperty() {
return goodid;
}
public void setGoodid(int goodid) {
this.goodid.set(goodid);
}
public String getGoodname() {
return goodname.get();
}
public SimpleStringProperty goodnameProperty() {
return goodname;
}
public void setGoodname(String goodname) {
this.goodname.set(goodname);
}
public String getGoodShelfid() {
return goodShelfid.get();
}
public SimpleStringProperty goodShelfidProperty() {
return goodShelfid;
}
public void setGoodShelfid(String goodShelfid) {
this.goodShelfid.set(goodShelfid);
}
public int getGoodTotal() {
return goodTotal.get();
}
public SimpleIntegerProperty goodTotalProperty() {
return goodTotal;
}
public void setGoodTotal(int goodTotal) {
this.goodTotal.set(goodTotal);
}
public double getGoodPrice() {
return goodPrice.get();
}
public SimpleDoubleProperty goodPriceProperty() {
return goodPrice;
}
public void setGoodPrice(double goodPrice) {
this.goodPrice.set(goodPrice);
}
@Override
public String toString() {
return "EmpLook{" +
"goodid=" + goodid +
", goodname=" + goodname +
", goodShelfid=" + goodShelfid +
", goodTotal=" + goodTotal +
", goodPrice=" + goodPrice +
'}';
}
}

@ -0,0 +1,14 @@
package patterns.bridge;
// 数据库日志
public class DataBaseLog extends Log{
public DataBaseLog(ImpLog impLog) {
super(impLog);
}
@Override
public void write(String log) {
getImpLog().execute("数据库日志:" + log);
}
}

@ -0,0 +1,6 @@
package patterns.bridge;
// 抽象平台
public abstract class ImpLog {
abstract public void execute(String msg);
}

@ -0,0 +1,9 @@
package patterns.bridge;
// java平台
public class JImpLog extends ImpLog {
@Override
public void execute(String msg) {
System.err.println("在java平台上" + msg);
}
}

@ -0,0 +1,21 @@
package patterns.bridge;
// 抽象日志
public abstract class Log {
private ImpLog impLog;
public Log(ImpLog impLog) {
super();
this.impLog = impLog;
}
abstract public void write(String log);
public ImpLog getImpLog() {
return impLog;
}
public void setImpLog(ImpLog impLog) {
this.impLog = impLog;
}
}

@ -0,0 +1,9 @@
package patterns.bridge;
// net平台
public class NImpLog extends ImpLog{
@Override
public void execute(String msg) {
System.out.println("在Net平台上"+msg);
}
}

@ -0,0 +1,13 @@
package patterns.bridge;
// 文本文件日志
public class TextFileLog extends Log{
public TextFileLog(ImpLog impLog) {
super(impLog);
}
@Override
public void write(String log) {
getImpLog().execute(log);
}
}

@ -0,0 +1,22 @@
package patterns.memento;
import java.util.ArrayList;
import java.util.List;
// 备忘录管理员
public class CareTaker {
private List<Memento> mementoList = new ArrayList<Memento>();
public void add(Memento state) {
mementoList.add(state);
}
public Memento get(int index){
return mementoList.get(index);
}
public List<Memento> getMementoList() {
return mementoList;
}
}

@ -0,0 +1,58 @@
package patterns.memento;
// 备忘录,记录状态变化者的某一个时间点的状态
public class Memento {
private String userid;
private String userpwd;
private String userphone;
private String useraddress;
public Memento(String userid, String userpwd, String userphone, String useraddress) {
this.userid = userid;
this.userpwd = userpwd;
this.userphone = userphone;
this.useraddress = useraddress;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getUserpwd() {
return userpwd;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
public String getUserphone() {
return userphone;
}
public void setUserphone(String userphone) {
this.userphone = userphone;
}
public String getUseraddress() {
return useraddress;
}
public void setUseraddress(String useraddress) {
this.useraddress = useraddress;
}
@Override
public String toString() {
return "Memento{" +
"userid='" + userid + '\'' +
", userpwd='" + userpwd + '\'' +
", userphone='" + userphone + '\'' +
", useraddress='" + useraddress + '\'' +
'}';
}
}

@ -0,0 +1,65 @@
package patterns.memento;
// 发起人,状态变化者
public class UserInfoOriginator {
// 当前状态
private String userid;
private String userpwd;
private String userphone;
private String useraddress;
// 保存到备忘录
public Memento saveToMemento(){
return new Memento(userid, userpwd,userphone,useraddress);
}
// 返回备忘录状态
public void restoreFromMemento(Memento memento){
this.userid = memento.getUserid();
this.userpwd = memento.getUserpwd();
this.userphone = memento.getUserphone();
this.useraddress = memento.getUseraddress();
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getUserpwd() {
return userpwd;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
public String getUserphone() {
return userphone;
}
public void setUserphone(String userphone) {
this.userphone = userphone;
}
public String getUseraddress() {
return useraddress;
}
public void setUseraddress(String useraddress) {
this.useraddress = useraddress;
}
@Override
public String toString() {
return "UserInfoOriginator{" +
"userid='" + userid + '\'' +
", userpwd='" + userpwd + '\'' +
", userphone='" + userphone + '\'' +
", useraddress='" + useraddress + '\'' +
'}';
}
}

@ -0,0 +1,34 @@
package patterns.observer;
import patterns.prototype.Goods;
import java.util.ArrayList;
// 观察者具体实现类
public class ComputeObserver implements Observer {
private ArrayList<Goods> list;
public ComputeObserver(ArrayList<Goods> list) {
this.list = list;
}
@Override
public String response() {
StringBuilder builder = new StringBuilder();
for (int i = 0, len = list.size(); i < len; ++i) {
builder.append((i + 1) + ". " + list.get(i).getgName() + "; 放在" + list.get(i).getgShelf() + "货架; 进货" + list.get(i).getgCnt() + "件; 单价" + list.get(i).getgPrice() + "元; 成本为" + ((Math.round(list.get(i).getgPrice() * list.get(i).getgCnt() * 100)) / 100.0) + "元。\n");
}
return builder.toString();
}
@Override
public double cal() {
double res = 0.0;
for (Goods goods : list) {
res += goods.getgPrice() * goods.getgCnt();
}
return res;
}
}

@ -0,0 +1,31 @@
package patterns.observer;
import emp.EmpGoods;
public class ConcreteSubject extends Subject{
// 注册方法
@Override
public void attach(Observer observer) {
observers.add(observer);
}
// 注销方法
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
// 处理数据并返回单个字符串
@Override
public EmpGoods transform() {
String res = "";
double ans = 0.0;
for (Observer observer : observers) {
res = observer.response();
ans = observer.cal();
}
return new EmpGoods(res, ans);
}
}

@ -0,0 +1,7 @@
package patterns.observer;
// 观察者接口
public interface Observer {
public String response();
public double cal();
}

@ -0,0 +1,19 @@
package patterns.observer;
import emp.EmpGoods;
import java.util.ArrayList;
public abstract class Subject {
protected ArrayList<Observer> observers = new ArrayList<>();
// 添加观察者
public abstract void attach(Observer observer);
// 删除观察者
public abstract void detach(Observer observer);
// 通知处理数据返回一个字符串
public abstract EmpGoods transform();
}

@ -0,0 +1,82 @@
package patterns.prototype;
public class Goods implements Cloneable {
private Integer gid;
private String gName;
private String gShelf;
private int gCnt;
private double gPrice;
public Goods() {
}
public Goods(String gName, String gShelf, int gCnt, double gPrice) {
this.gName = gName;
this.gShelf = gShelf;
this.gCnt = gCnt;
this.gPrice = gPrice;
}
public Integer getGid() {
return gid;
}
public void setGid(Integer gid) {
this.gid = gid;
}
public String getgName() {
return gName;
}
public void setgName(String gName) {
this.gName = gName;
}
public String getgShelf() {
return gShelf;
}
public void setgShelf(String gShelf) {
this.gShelf = gShelf;
}
public int getgCnt() {
return gCnt;
}
public void setgCnt(int gCnt) {
this.gCnt = gCnt;
}
public double getgPrice() {
return gPrice;
}
public void setgPrice(double gPrice) {
this.gPrice = gPrice;
}
// 每次点击添加按钮之后就克隆一个货物类
@Override
public Object clone() {
Goods goods = null;
try {
goods = (Goods) super.clone();
} catch (Exception e) {
e.printStackTrace();
}
return goods;
}
@Override
public String toString() {
return "Goods{" +
"gid=" + gid +
", gName='" + gName + '\'' +
", gShelf='" + gShelf + '\'' +
", gCnt=" + gCnt +
", gPrice=" + gPrice +
'}';
}
}

@ -0,0 +1,46 @@
package patterns.prototype;
import java.time.LocalDateTime;
public class StockLog {
private Integer id;
private Integer gid;
private String outTime;
private Integer outNum;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getGid() {
return gid;
}
public void setGid(Integer gid) {
this.gid = gid;
}
public String getOutTime() {
return outTime;
}
public void setOutTime(String outTime) {
this.outTime = outTime;
}
public Integer getOutNum() {
return outNum;
}
public void setOutNum(Integer outNum) {
this.outNum = outNum;
}
}

@ -0,0 +1,5 @@
package patterns.proxy;
public interface IPrintLog {
public void output(String str);
}

@ -0,0 +1,19 @@
package patterns.proxy;
public class PrintLogProxy implements IPrintLog {
private IPrintLog iPrintLog;
public PrintLogProxy(IPrintLog iPrintLog) {
this.iPrintLog = iPrintLog;
}
public void setiPrintLog(IPrintLog iPrintLog) {
this.iPrintLog = iPrintLog;
}
@Override
public void output(String str) {
iPrintLog.output(str);
}
}

@ -0,0 +1,13 @@
package patterns.proxy;
import java.text.SimpleDateFormat;
import java.util.Date;
public class PrintLogSon implements IPrintLog{
@Override
public void output(String str) {
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:MM:SS");
System.err.println("日志打印时间:" + s.format(new Date()));
System.err.println(str);
}
}

@ -0,0 +1,33 @@
package patterns.singleton;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class SingleRegisterStage {
// 懒汉单例模式
private static Stage registerInstance;
private SingleRegisterStage() {}
public static Stage getInstance() {
if(registerInstance == null) {
FXMLLoader Loader = new FXMLLoader(SingleRegisterStage.class.getResource("/views/register.fxml"));
Parent parent = null;
try {
parent = Loader.load();
} catch (IOException e) {
e.printStackTrace();
}
Stage stage = new Stage();
stage.setTitle("注册界面");
stage.setScene(new Scene(parent, 500, 400));
stage.setResizable(false);
registerInstance = stage;
}
return registerInstance;
}
}

@ -0,0 +1,22 @@
package utils;
import javafx.scene.control.Alert;
public class DialogUtil {
public static void showDialog(String type, String tip) {
Alert alert = null;
if(type.equals("INFORMATION")) {
alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("INFORMATION");
} else if(type.equals("ERROR")){
alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("ERROR");
} else {
alert = new Alert(Alert.AlertType.WARNING);
alert.setHeaderText("WARNING");
}
alert.setContentText(tip);
alert.show();
}
}

@ -0,0 +1,26 @@
package utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.Reader;
public class MybatisUtil {
private static SqlSessionFactory sqlSessionFactory = null;
static {
try {
Reader reader = Resources.getResourceAsReader("config/SqlMapConfig.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSession getSession() {
return sqlSessionFactory.openSession();
}
}

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- mybatis主配置文件-->
<configuration>
<!--加载数据库配置文件-->
<properties resource="config/jdbcConfig.properties">
</properties>
<!--定义类的别名-->
<typeAliases>
<typeAlias type="patterns.prototype.Goods" alias="goods"></typeAlias>
<typeAlias type="patterns.memento.Memento" alias="user"></typeAlias>
</typeAliases>
<!-- 配置环境-->
<environments default="mysql">
<environment id="mysql">
<!-- 配置事务的类型-->
<transactionManager type="jdbc"></transactionManager>
<!-- 配置数据源(连接池)-->
<dataSource type="POOLED">
<!-- 配置链接数据库的四个基本信息-->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
<package name="dao"/>
</mappers>
</configuration>

@ -0,0 +1,4 @@
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/warehouse?useSSL=false&characterEncoding=utf-8&autoReconnect=true&serverTimezone=UTC
jdbc.username=root
jdbc.password=sby6221242

@ -0,0 +1,59 @@
.tab {
-fx-pref-width : 180;
-fx-pref-height : 50;
-fx-font-size: 18px;
}
.table-view {
-fx-border-width: 1px;
-fx-border-color: #CACACA;
-fx-background-color: transparent;
}
.table-view .table-cell {
-fx-font-size: 12px;
}
.table-view .filler {
-fx-background-color: #BDE8FF;
}
.table-view .text {
-fx-text-fill: white;
}
.table-view .column-header {
-fx-background-color: #2A2E37;
-fx-text-fill: white;
-fx-pref-height: 40px;
-fx-border-width: 1px;
-fx-border-color: #D9D9D9;
-fx-border-insets: -2px -2px 0px -2px;
}
.table-view .column-header-background .label {
-fx-text-fill: white;
-fx-font-weight: bold;
-fx-font-size: 16px;
}
.table-row-cell {
-fx-cell-size: 40px;
}
.table-row-cell .cell {
-fx-alignment: center;
}
.table-view .table-cell:selected {
-fx-text-fill: white;
}
.table-view .table-column .column-header {
-fx-background-color: #363739;
}
.table-view .scroll-bar {
-fx-background-color: transparent;
}

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.IGoodsDao">
<!--添加商品-->
<insert id="addGoods" parameterType="List">
insert into goods(gName, gShelf, gCnt, gPrice) VALUES
<foreach collection="list" item="goods" index="index" separator=",">
(#{goods.gName}, #{goods.gShelf}, #{goods.gCnt}, #{goods.gPrice})
</foreach>
</insert>
<!--查询所有商品信息-->
<select id="findAllGoods" resultType="goods" >
select * from goods
</select>
<!--删除某个商品-->
<delete id="deleteGoodById" parameterType="int">
delete from goods where gid = #{gid}
</delete>
<!--查询某个商品信息-->
<select id="findGoodById" resultType="goods">
select * from goods where gid = #{gid}
</select>
<!--商品出库,减少数量-->
<update id="updateGoodsById" >
update goods set gCnt = gCnt - #{det} WHERE gid = #{gid}
</update>
<select id="findGoodsByName" resultType="goods">
<bind name="likeGName" value="'%'+gName+'%'"/>
select *
from goods
where gName like #{likeGName}
</select>
</mapper>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.IStockLogDao">
<insert id="addOutLog">
insert into stock_log(`gid`, `outNum`, `outTime`)
values (#{gid}, #{outNum}, #{outTime})
</insert>
<select id="listOutOfStockLog" resultType="patterns.prototype.StockLog">
select *
from stock_log
where gid = #{gid}
order by outTime
</select>
<select id="getStockLog" resultType="patterns.prototype.StockLog">
select *
from stock_log
where gid = #{gid}
and outTime = #{outTime}
</select>
<update id="updateLogById">
update stock_log
set outNum = outNum + #{outNum}
WHERE id = #{id}
</update>
</mapper>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.IUserDao">
<!--查询用户,避免注册相同的用户账号-->
<select id="selectHasUser" resultType="Integer">
select count(*) from user where userid = #{uid}
</select>
<!--增加用户-->
<insert id="addUser" parameterType="user">
insert into user values (#{userid}, #{userpwd}, #{userphone}, #{useraddress})
</insert>
<!--查询用户信息-->
<select id="findUserById" resultType="user" >
select * from user WHERE userid = #{id}
</select>
<!--根据用户id更新用户信息-->
<update id="updateUserById" parameterType="user" >
UPDATE user SET userpwd = #{userpwd}, userphone = #{userphone}, useraddress = #{useraddress} where userid = #{userid}
</update>
</mapper>

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.*?>
<AnchorPane fx:id="rootPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.LoginController">
<children>
<Label layoutX="152.0" layoutY="56.0" prefHeight="44.0" prefWidth="197.0" text="小型仓库管理系统">
<font>
<Font name="System Bold" size="24.0" />
</font>
</Label>
<Label layoutX="85.0" layoutY="140.0" text="用户名:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="103.0" layoutY="198.0" text="密码:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="userid" layoutX="157.0" layoutY="138.0" prefHeight="36.0" prefWidth="197.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<PasswordField fx:id="userpwd" layoutX="157.0" layoutY="193.0" prefHeight="36.0" prefWidth="197.0">
<font>
<Font size="18.0" />
</font>
</PasswordField>
<Button layoutX="157.0" layoutY="259.0" mnemonicParsing="false" onAction="#registerClick" text="注册">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="287.0" layoutY="259.0" mnemonicParsing="false" onAction="#loginClick" text="登录">
<font>
<Font size="18.0" />
</font>
</Button>
</children>
</AnchorPane>

@ -0,0 +1,292 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Line?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="900.0" stylesheets="@../css/style.css" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainPageController">
<children>
<TabPane fx:id="tabpane" onMouseClicked="#tabClick" prefHeight="700.0" prefWidth="900.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab text="货物入库">
<content>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Label layoutX="167.0" layoutY="29.0" text="货物信息">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
<Label layoutX="636.0" layoutY="29.0" text="进货清单">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
<Line endX="-100.0" endY="644.0" layoutX="542.0" layoutY="1.0" startX="-100.0" />
<Label layoutX="48.0" layoutY="105.0" text="货物名称:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="57.0" layoutY="172.0" text="货架号:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="39.0" layoutY="238.0" text="货物数量:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="goodName" layoutX="146.0" layoutY="99.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="goodShelfid" layoutX="146.0" layoutY="166.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="goodTotal" layoutX="146.0" layoutY="232.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Button layoutX="109.0" layoutY="401.0" mnemonicParsing="false" onAction="#addClick" text="添加">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="284.0" layoutY="401.0" mnemonicParsing="false" onAction="#clearClick" text="重置">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="594.0" layoutY="548.0" mnemonicParsing="false" onAction="#addToDBAClick" prefHeight="23.0" prefWidth="157.0" text="入库">
<font>
<Font size="18.0" />
</font>
</Button>
<Label layoutX="38.0" layoutY="302.0" text="货物单价:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="goodPrice" layoutX="146.0" layoutY="297.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<AnchorPane layoutX="447.0" layoutY="84.0" prefHeight="435.0" prefWidth="450.0">
<children>
<TextArea fx:id="textArea" editable="false" prefHeight="435.0" prefWidth="450.0">
<font>
<Font size="18.0" />
</font>
</TextArea>
</children>
</AnchorPane>
<Label layoutX="731.0" layoutY="54.0" text="总计:">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Label fx:id="showValue" layoutX="773.0" layoutY="55.0" text="¥0.00" textFill="RED">
<font>
<Font size="14.0" />
</font>
</Label>
</children>
</AnchorPane>
</content></Tab>
<Tab text="货物出库">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TableView fx:id="tableView" layoutX="65.0" layoutY="20.0" onMouseClicked="#rowClick" prefHeight="322.0" prefWidth="771.0">
<columns>
<TableColumn fx:id="colid" editable="false" prefWidth="78.0" sortable="false" text="货物编号" />
<TableColumn fx:id="colname" editable="false" prefWidth="235.0" sortable="false" text="货物名称" />
<TableColumn fx:id="colshelf" editable="false" prefWidth="178.0" sortable="false" text="货架号" />
<TableColumn fx:id="colnum" editable="false" prefWidth="160.0" sortable="false" text="货物数量" />
<TableColumn fx:id="colprice" editable="false" prefWidth="118.0" sortable="false" text="货物单价" />
</columns>
</TableView>
<Label layoutX="38.0" layoutY="381.0" text="货物编号:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="fillid" alignment="CENTER" layoutX="134.0" layoutY="375.0" prefHeight="37.0" prefWidth="146.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Label layoutX="316.0" layoutY="381.0" text="货物名称:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="fillname" alignment="CENTER" layoutX="405.0" layoutY="375.0" prefHeight="38.0" prefWidth="162.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Label layoutX="38.0" layoutY="448.0" text="货架号:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="316.0" layoutY="448.0" text="出库数量:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="fillshelf" alignment="CENTER" layoutX="114.0" layoutY="442.0" prefHeight="36.0" prefWidth="169.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="fillnum" alignment="CENTER" layoutX="405.0" layoutY="442.0" prefHeight="36.0" prefWidth="161.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Button layoutX="286.0" layoutY="512.0" mnemonicParsing="false" onAction="#outboundClick" text="出库">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="439.0" layoutY="512.0" mnemonicParsing="false" onAction="#deleteClick" text="删除">
<font>
<Font size="18.0" />
</font>
</Button>
<Label layoutX="597.0" layoutY="448.0" text="货物单价:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="fillPrice" alignment="CENTER" layoutX="688.0" layoutY="442.0" prefHeight="36.0" prefWidth="148.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Label layoutX="597.0" layoutY="381.0" text="出库时间:">
<font>
<Font size="18.0" />
</font>
</Label>
<DatePicker fx:id="outTime" layoutX="688.0" layoutY="375.0" prefHeight="38.0" prefWidth="162.0">
</DatePicker>
<Button layoutX="594.0" layoutY="512.0" mnemonicParsing="false" onAction="#location" text="查看位置">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="733.0" layoutY="512.0" mnemonicParsing="false" onAction="#predict" text="图表预测">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="114.0" layoutY="512.0" mnemonicParsing="false" onAction="#search" text="查询">
<font>
<Font size="18.0" />
</font>
</Button>
</children></AnchorPane>
</content>
</Tab>
<Tab text="个人信息">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Label layoutX="414.0" layoutY="36.0" text="个人信息">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
<Label layoutX="245.0" layoutY="104.0" text="用户账号:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="227.0" layoutY="304.0" text="用户手机号:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="239.0" layoutY="372.0" text="用户地址:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="userid" editable="false" layoutX="347.0" layoutY="98.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="userphone" layoutX="347.0" layoutY="298.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="useraddress" layoutX="347.0" layoutY="366.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Button layoutX="347.0" layoutY="458.0" mnemonicParsing="false" onAction="#updateClick" text="修改">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="438.0" layoutY="458.0" mnemonicParsing="false" onAction="#revokeClick" text="撤销">
<font>
<Font size="18.0" />
</font>
</Button>
<Label layoutX="263.0" layoutY="169.0" text="旧密码:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="263.0" layoutY="235.0" text="新密码:">
<font>
<Font size="18.0" />
</font>
</Label>
<Button layoutX="529.0" layoutY="458.0" mnemonicParsing="false" onAction="#resetClick" text="重置">
<font>
<Font size="18.0" />
</font>
</Button>
<PasswordField fx:id="oldpwd" layoutX="347.0" layoutY="163.0">
<font>
<Font size="18.0" />
</font>
</PasswordField>
<PasswordField fx:id="newpwd" layoutX="347.0" layoutY="229.0">
<font>
<Font size="18.0" />
</font>
</PasswordField>
</children></AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.*?>
<AnchorPane fx:id="rootPane" prefHeight="400.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.RegisterController">
<children>
<Label layoutX="223.0" layoutY="41.0" prefHeight="44.0" prefWidth="54.0" text="注册">
<font>
<Font name="System Bold" size="24.0" />
</font>
</Label>
<Button layoutX="153.0" layoutY="306.0" mnemonicParsing="false" onAction="#registerClick" text="注册">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="300.0" layoutY="306.0" mnemonicParsing="false" onAction="#clearClick" text="重置">
<font>
<Font size="18.0" />
</font>
</Button>
<Label layoutX="48.0" layoutY="115.0" text="用户名:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="65.0" layoutY="161.0" text="密码:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="userid" layoutX="131.0" layoutY="109.0" prefHeight="36.0" prefWidth="338.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Label layoutX="30.0" layoutY="208.0" text="手机号码:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="28.0" layoutY="253.0" text="家庭住址:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="userphone" layoutX="131.0" layoutY="201.0" prefHeight="36.0" prefWidth="338.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="useraddress" layoutX="131.0" layoutY="247.0" prefHeight="36.0" prefWidth="338.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<PasswordField fx:id="userpwd" layoutX="130.0" layoutY="155.0" prefHeight="36.0" prefWidth="338.0">
<font>
<Font size="18.0" />
</font>
</PasswordField>
</children>
</AnchorPane>

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- mybatis主配置文件-->
<configuration>
<!--加载数据库配置文件-->
<properties resource="config/jdbcConfig.properties">
</properties>
<!--定义类的别名-->
<typeAliases>
<typeAlias type="patterns.prototype.Goods" alias="goods"></typeAlias>
<typeAlias type="patterns.memento.Memento" alias="user"></typeAlias>
</typeAliases>
<!-- 配置环境-->
<environments default="mysql">
<environment id="mysql">
<!-- 配置事务的类型-->
<transactionManager type="jdbc"></transactionManager>
<!-- 配置数据源(连接池)-->
<dataSource type="POOLED">
<!-- 配置链接数据库的四个基本信息-->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
<package name="dao"/>
</mappers>
</configuration>

@ -0,0 +1,4 @@
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/warehouse?useSSL=false&characterEncoding=utf-8&autoReconnect=true&serverTimezone=UTC
jdbc.username=root
jdbc.password=sby6221242

@ -0,0 +1,59 @@
.tab {
-fx-pref-width : 180;
-fx-pref-height : 50;
-fx-font-size: 18px;
}
.table-view {
-fx-border-width: 1px;
-fx-border-color: #CACACA;
-fx-background-color: transparent;
}
.table-view .table-cell {
-fx-font-size: 12px;
}
.table-view .filler {
-fx-background-color: #BDE8FF;
}
.table-view .text {
-fx-text-fill: white;
}
.table-view .column-header {
-fx-background-color: #2A2E37;
-fx-text-fill: white;
-fx-pref-height: 40px;
-fx-border-width: 1px;
-fx-border-color: #D9D9D9;
-fx-border-insets: -2px -2px 0px -2px;
}
.table-view .column-header-background .label {
-fx-text-fill: white;
-fx-font-weight: bold;
-fx-font-size: 16px;
}
.table-row-cell {
-fx-cell-size: 40px;
}
.table-row-cell .cell {
-fx-alignment: center;
}
.table-view .table-cell:selected {
-fx-text-fill: white;
}
.table-view .table-column .column-header {
-fx-background-color: #363739;
}
.table-view .scroll-bar {
-fx-background-color: transparent;
}

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.IGoodsDao">
<!--添加商品-->
<insert id="addGoods" parameterType="List">
insert into goods(gName, gShelf, gCnt, gPrice) VALUES
<foreach collection="list" item="goods" index="index" separator=",">
(#{goods.gName}, #{goods.gShelf}, #{goods.gCnt}, #{goods.gPrice})
</foreach>
</insert>
<!--查询所有商品信息-->
<select id="findAllGoods" resultType="goods" >
select * from goods
</select>
<!--删除某个商品-->
<delete id="deleteGoodById" parameterType="int">
delete from goods where gid = #{gid}
</delete>
<!--查询某个商品信息-->
<select id="findGoodById" resultType="goods">
select * from goods where gid = #{gid}
</select>
<!--商品出库,减少数量-->
<update id="updateGoodsById" >
update goods set gCnt = gCnt - #{det} WHERE gid = #{gid}
</update>
<select id="findGoodsByName" resultType="goods">
<bind name="likeGName" value="'%'+gName+'%'"/>
select *
from goods
where gName like #{likeGName}
</select>
</mapper>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.IStockLogDao">
<insert id="addOutLog">
insert into stock_log(`gid`, `outNum`, `outTime`)
values (#{gid}, #{outNum}, #{outTime})
</insert>
<select id="listOutOfStockLog" resultType="patterns.prototype.StockLog">
select *
from stock_log
where gid = #{gid}
order by outTime
</select>
<select id="getStockLog" resultType="patterns.prototype.StockLog">
select *
from stock_log
where gid = #{gid}
and outTime = #{outTime}
</select>
<update id="updateLogById">
update stock_log
set outNum = outNum + #{outNum}
WHERE id = #{id}
</update>
</mapper>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.IUserDao">
<!--查询用户,避免注册相同的用户账号-->
<select id="selectHasUser" resultType="Integer">
select count(*) from user where userid = #{uid}
</select>
<!--增加用户-->
<insert id="addUser" parameterType="user">
insert into user values (#{userid}, #{userpwd}, #{userphone}, #{useraddress})
</insert>
<!--查询用户信息-->
<select id="findUserById" resultType="user" >
select * from user WHERE userid = #{id}
</select>
<!--根据用户id更新用户信息-->
<update id="updateUserById" parameterType="user" >
UPDATE user SET userpwd = #{userpwd}, userphone = #{userphone}, useraddress = #{useraddress} where userid = #{userid}
</update>
</mapper>

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.*?>
<AnchorPane fx:id="rootPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.LoginController">
<children>
<Label layoutX="152.0" layoutY="56.0" prefHeight="44.0" prefWidth="197.0" text="小型仓库管理系统">
<font>
<Font name="System Bold" size="24.0" />
</font>
</Label>
<Label layoutX="85.0" layoutY="140.0" text="用户名:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="103.0" layoutY="198.0" text="密码:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="userid" layoutX="157.0" layoutY="138.0" prefHeight="36.0" prefWidth="197.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<PasswordField fx:id="userpwd" layoutX="157.0" layoutY="193.0" prefHeight="36.0" prefWidth="197.0">
<font>
<Font size="18.0" />
</font>
</PasswordField>
<Button layoutX="157.0" layoutY="259.0" mnemonicParsing="false" onAction="#registerClick" text="注册">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="287.0" layoutY="259.0" mnemonicParsing="false" onAction="#loginClick" text="登录">
<font>
<Font size="18.0" />
</font>
</Button>
</children>
</AnchorPane>

@ -0,0 +1,292 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Line?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="900.0" stylesheets="@../css/style.css" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainPageController">
<children>
<TabPane fx:id="tabpane" onMouseClicked="#tabClick" prefHeight="700.0" prefWidth="900.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab text="货物入库">
<content>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Label layoutX="167.0" layoutY="29.0" text="货物信息">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
<Label layoutX="636.0" layoutY="29.0" text="进货清单">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
<Line endX="-100.0" endY="644.0" layoutX="542.0" layoutY="1.0" startX="-100.0" />
<Label layoutX="48.0" layoutY="105.0" text="货物名称:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="57.0" layoutY="172.0" text="货架号:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="39.0" layoutY="238.0" text="货物数量:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="goodName" layoutX="146.0" layoutY="99.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="goodShelfid" layoutX="146.0" layoutY="166.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="goodTotal" layoutX="146.0" layoutY="232.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Button layoutX="109.0" layoutY="401.0" mnemonicParsing="false" onAction="#addClick" text="添加">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="284.0" layoutY="401.0" mnemonicParsing="false" onAction="#clearClick" text="重置">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="594.0" layoutY="548.0" mnemonicParsing="false" onAction="#addToDBAClick" prefHeight="23.0" prefWidth="157.0" text="入库">
<font>
<Font size="18.0" />
</font>
</Button>
<Label layoutX="38.0" layoutY="302.0" text="货物单价:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="goodPrice" layoutX="146.0" layoutY="297.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<AnchorPane layoutX="447.0" layoutY="84.0" prefHeight="435.0" prefWidth="450.0">
<children>
<TextArea fx:id="textArea" editable="false" prefHeight="435.0" prefWidth="450.0">
<font>
<Font size="18.0" />
</font>
</TextArea>
</children>
</AnchorPane>
<Label layoutX="731.0" layoutY="54.0" text="总计:">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Label fx:id="showValue" layoutX="773.0" layoutY="55.0" text="¥0.00" textFill="RED">
<font>
<Font size="14.0" />
</font>
</Label>
</children>
</AnchorPane>
</content></Tab>
<Tab text="货物出库">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TableView fx:id="tableView" layoutX="65.0" layoutY="20.0" onMouseClicked="#rowClick" prefHeight="322.0" prefWidth="771.0">
<columns>
<TableColumn fx:id="colid" editable="false" prefWidth="78.0" sortable="false" text="货物编号" />
<TableColumn fx:id="colname" editable="false" prefWidth="235.0" sortable="false" text="货物名称" />
<TableColumn fx:id="colshelf" editable="false" prefWidth="178.0" sortable="false" text="货架号" />
<TableColumn fx:id="colnum" editable="false" prefWidth="160.0" sortable="false" text="货物数量" />
<TableColumn fx:id="colprice" editable="false" prefWidth="118.0" sortable="false" text="货物单价" />
</columns>
</TableView>
<Label layoutX="38.0" layoutY="381.0" text="货物编号:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="fillid" alignment="CENTER" layoutX="134.0" layoutY="375.0" prefHeight="37.0" prefWidth="146.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Label layoutX="316.0" layoutY="381.0" text="货物名称:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="fillname" alignment="CENTER" layoutX="405.0" layoutY="375.0" prefHeight="38.0" prefWidth="162.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Label layoutX="38.0" layoutY="448.0" text="货架号:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="316.0" layoutY="448.0" text="出库数量:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="fillshelf" alignment="CENTER" layoutX="114.0" layoutY="442.0" prefHeight="36.0" prefWidth="169.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="fillnum" alignment="CENTER" layoutX="405.0" layoutY="442.0" prefHeight="36.0" prefWidth="161.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Button layoutX="286.0" layoutY="512.0" mnemonicParsing="false" onAction="#outboundClick" text="出库">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="439.0" layoutY="512.0" mnemonicParsing="false" onAction="#deleteClick" text="删除">
<font>
<Font size="18.0" />
</font>
</Button>
<Label layoutX="597.0" layoutY="448.0" text="货物单价:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="fillPrice" alignment="CENTER" layoutX="688.0" layoutY="442.0" prefHeight="36.0" prefWidth="148.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Label layoutX="597.0" layoutY="381.0" text="出库时间:">
<font>
<Font size="18.0" />
</font>
</Label>
<DatePicker fx:id="outTime" layoutX="688.0" layoutY="375.0" prefHeight="38.0" prefWidth="162.0">
</DatePicker>
<Button layoutX="594.0" layoutY="512.0" mnemonicParsing="false" onAction="#location" text="查看位置">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="733.0" layoutY="512.0" mnemonicParsing="false" onAction="#predict" text="图表预测">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="114.0" layoutY="512.0" mnemonicParsing="false" onAction="#search" text="查询">
<font>
<Font size="18.0" />
</font>
</Button>
</children></AnchorPane>
</content>
</Tab>
<Tab text="个人信息">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Label layoutX="414.0" layoutY="36.0" text="个人信息">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
<Label layoutX="245.0" layoutY="104.0" text="用户账号:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="227.0" layoutY="304.0" text="用户手机号:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="239.0" layoutY="372.0" text="用户地址:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="userid" editable="false" layoutX="347.0" layoutY="98.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="userphone" layoutX="347.0" layoutY="298.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="useraddress" layoutX="347.0" layoutY="366.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Button layoutX="347.0" layoutY="458.0" mnemonicParsing="false" onAction="#updateClick" text="修改">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="438.0" layoutY="458.0" mnemonicParsing="false" onAction="#revokeClick" text="撤销">
<font>
<Font size="18.0" />
</font>
</Button>
<Label layoutX="263.0" layoutY="169.0" text="旧密码:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="263.0" layoutY="235.0" text="新密码:">
<font>
<Font size="18.0" />
</font>
</Label>
<Button layoutX="529.0" layoutY="458.0" mnemonicParsing="false" onAction="#resetClick" text="重置">
<font>
<Font size="18.0" />
</font>
</Button>
<PasswordField fx:id="oldpwd" layoutX="347.0" layoutY="163.0">
<font>
<Font size="18.0" />
</font>
</PasswordField>
<PasswordField fx:id="newpwd" layoutX="347.0" layoutY="229.0">
<font>
<Font size="18.0" />
</font>
</PasswordField>
</children></AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.*?>
<AnchorPane fx:id="rootPane" prefHeight="400.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.RegisterController">
<children>
<Label layoutX="223.0" layoutY="41.0" prefHeight="44.0" prefWidth="54.0" text="注册">
<font>
<Font name="System Bold" size="24.0" />
</font>
</Label>
<Button layoutX="153.0" layoutY="306.0" mnemonicParsing="false" onAction="#registerClick" text="注册">
<font>
<Font size="18.0" />
</font>
</Button>
<Button layoutX="300.0" layoutY="306.0" mnemonicParsing="false" onAction="#clearClick" text="重置">
<font>
<Font size="18.0" />
</font>
</Button>
<Label layoutX="48.0" layoutY="115.0" text="用户名:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="65.0" layoutY="161.0" text="密码:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="userid" layoutX="131.0" layoutY="109.0" prefHeight="36.0" prefWidth="338.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<Label layoutX="30.0" layoutY="208.0" text="手机号码:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="28.0" layoutY="253.0" text="家庭住址:">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="userphone" layoutX="131.0" layoutY="201.0" prefHeight="36.0" prefWidth="338.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<TextField fx:id="useraddress" layoutX="131.0" layoutY="247.0" prefHeight="36.0" prefWidth="338.0">
<font>
<Font size="18.0" />
</font>
</TextField>
<PasswordField fx:id="userpwd" layoutX="130.0" layoutY="155.0" prefHeight="36.0" prefWidth="338.0">
<font>
<Font size="18.0" />
</font>
</PasswordField>
</children>
</AnchorPane>
Loading…
Cancel
Save