基于springboot和sqlite实现的便利店管理系统
1.项目简介
Bridie CRM即小店CRM,核心支持积分兑换,前置提供商品管理、用户管理、员工管理、套餐管理。报表统计、会员新增、现金购买-零售转积分等功能。
扩展功能:数据备份,数据报表。
基于JavaFX8的一款单机的小型店铺管理系统,数据库使用sqlite3,无需用户安装数据库软件,也无需软件方提供远程数据库。
2.数据库设计
2.1 商品表
2.2 商品类型表
2.3 登录信息表
2.4 订单详情表
2.5 订单信息表
2.6 订单触发器
2.7 项目内容信息表
2.8 套餐项目表
2.9 员工管理界面表
2.10 用户购物车表
2.11 用户订单表
2.12 用户信息表
2.13 VIP信息表
3.项目实现
3.1 导出excel表工具类
```java public class JXLUtil {
/**
* @param title 表格标题
* @param listContent 列表内容
* @param os 输出流
* @return 成功则返回true,失败返回false
*/
public static boolean exportExcel(String[] title, String[] fieldNames, List<Object> listContent, OutputStream os) {
// 以下开始输出到EXCEL
try {
/* **********创建工作簿************ */
WritableWorkbook workbook = Workbook.createWorkbook(os);
/* * **********创建工作表************ */
WritableSheet sheet = workbook.createSheet("Sheet1", 0);
/* * **********设置纵横打印(默认为纵打)、打印纸***************** */
jxl.SheetSettings sheetSet = sheet.getSettings();
sheetSet.setProtected(false);
/* * ************设置单元格字体************** */
WritableFont NormalFont = new WritableFont(WritableFont.ARIAL, 10);
WritableFont BoldFont = new WritableFont(WritableFont.ARIAL, 10, WritableFont.BOLD);
// 用于标题居中
WritableCellFormat wcf_title = new WritableCellFormat(BoldFont);
wcf_title.setBorder(Border.ALL, BorderLineStyle.THIN); // 线条
wcf_title.setVerticalAlignment(VerticalAlignment.CENTRE); // 文字垂直对齐
wcf_title.setAlignment(Alignment.CENTRE); // 文字水平对齐
wcf_title.setWrap(false); // 文字是否换行
// 用于正文居左
WritableCellFormat wcf_text = new WritableCellFormat(NormalFont);
wcf_text.setBorder(Border.NONE, BorderLineStyle.THIN); // 线条
wcf_text.setVerticalAlignment(VerticalAlignment.CENTRE); // 文字垂直对齐
wcf_text.setAlignment(Alignment.CENTRE); // 文字水平对齐
wcf_text.setWrap(false); // 文字是否换行
/* * ***************EXCEL第一行列标题********************* */
for (int i = 0; i < title.length; i++) {
sheet.addCell(new Label(i, 0, title[i], wcf_title));
}
/* * ***************EXCEL正文数据********************* */
int rIndex = 1;
for (Object obj : listContent) {
int cIndex = 0;
for (String fieldName : fieldNames) {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object val = field.get(obj);
if (val == null)
val = "";
sheet.addCell(new Label(cIndex, rIndex, val.toString(), wcf_text));
cIndex++;
}
rIndex++;
}
/* * **********将以上缓存中的内容写到EXCEL文件中******** */
workbook.write();
/* * *********关闭文件************* */
workbook.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
} ```
3.2 加密工具类
java
/**
* 密码加盐工具
*/
public class SaltUtil {
private final Object salt;
private final String algorithm;
private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
public SaltUtil(Object salt, String algorithm) {
this.salt = salt;
this.algorithm = algorithm;
}
public String encode(String rawPass) {
String result = null;
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
//加密后的字符串
result = byteArrayToHexString(md.digest(mergePasswordAndSalt(rawPass).getBytes(StandardCharsets.UTF_8)));
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
private String mergePasswordAndSalt(String password) {
if (password == null) {
password = "";
}
if ((salt == null) || salt.equals("")) {
return password;
} else {
return password + "{" + salt.toString() + "}";
}
}
/**
* 转换字节数组为16进制字串
*
* @param b 字节数组
* @return 16进制字串
*/
private static String byteArrayToHexString(byte[] b) {
StringBuilder resultSb = new StringBuilder();
for (byte value : b) {
resultSb.append(byteToHexString(value));
}
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n = 256 + n;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
}
3.3 登录类
java
@Override
public void initialize(URL location, ResourceBundle resources) {
tf_username.setValue("admin");
pf_password.setText("admin");
}
@FXML // 登录按钮事件
private void login() {
String username = tf_username.getValue();
String password = pf_password.getText();
// 判断用户名是否为空
if (username.equals("")) {
new MyAlert(AlertType.WARNING, "用户名不能为空!").show();
return;
}
// 判断密码是否为空
if (password.equals("")) {
new MyAlert(AlertType.WARNING, "密码不能为空!").show();
return;
}
btn_Login.setDisable(true);
btn_Login.setText("验证密码中···");
VerifyTask vTask = new VerifyTask(username, password); // 新建线程,用于验证密码并更新UI
new Thread(vTask).start();
vTask.valueProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.getId() != null) {
ClientSession.addAttribute("user", newValue);
ApplicationStarter.toMainStageView();
} else {
btn_Login.setText("登录");
btn_Login.setDisable(false);
new MyAlert(AlertType.INFORMATION, "用户名或密码错误!").showAndWait();
}
});
}
/**
* 子线程任务,用于验证用户名密码
*/
private static class VerifyTask extends javafx.concurrent.Task<LoginBean> {
String username;
String password;
VerifyTask(String u, String p) {
this.username = u;
this.password = new SaltUtil(u, "MD5").encode(p);
}
@Override
protected LoginBean call() {
LoginService service = (LoginService) SpringUtil.getBean("LoginServiceImpl");
LoginBean loginBean = service.verify(username, password);
// 如果查询结果为不为空,则返回该LoginBean对象
if (loginBean != null)
return loginBean;
// 否则返回一个空的LoginBean()对象
// 如果直接返回null,则ChangeListener不会回调,因为old值为null
else
return new LoginBean();
}
3.4 主要功能实现
```java
@Override
public void initialize(URL location, ResourceBundle resources) {
initView();
//设置回车查询
tf_find.setOnKeyPressed(keyEvent -> {
if (keyEvent.getCode().equals(KeyCode.ENTER))
inquireVIP();
});
}
@FXML // 查找信息
private void inquireVIP() {
String keyWord = tf_find.getText().trim();
if (keyWord.equals(""))
return;
vipBean = userService.getInfoByIdOrName(keyWord, keyWord);
if (vipBean != null) {
showFindResult(vipBean);
} else {
new MyAlert(AlertType.INFORMATION, "没有找到您查询的会员!").show();
}
}
/*
* 显示搜索结果
*
* @param bean 搜索的用户信息
/
private void showFindResult(UserBean bean) {
if (bean == null)
return;
lb_cardState.setText("可用");
lb_id.setText(bean.getId());
lb_integral.setText(String.valueOf(bean.getIntegral()));
lb_cardLevel.setText(bean.getCardLevel());
lb_name.setText(bean.getName());
lb_balance.setText(String.format("¥%.2f", bean.getBalance()));
if (bean == SANKE)
lb_name.setStyle("-fx-text-fill: #cf4813");
else
lb_name.setStyle("-fx-text-fill: black");
}
@FXML
private void inquireVIPInfo() {
String str = tf_findInfo.getText().trim();
String disType = cb_disType.getValue().equals("全部类型") ? "" : cb_disType.getValue();
if (str.equals(""))
return;
ArrayList
initGoodsTab(); //初始化商品消费面板
initPackageTab(); //初始化套餐消费面板
initCountTab(); //初始化计次消费面板
}
m /* * 初始化界面 / private void initView() { table = new VipInfoTable(); scrollPane.setContent(table);
cbb_level.getItems().addAll("所有等级", "普通会员", "超级会员");
cbb_level.setValue("所有等级");
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String str_from = "1900-01-01";
LocalDate from = LocalDate.parse(str_from, df);
LocalDate to = LocalDate.now();
dpk_from.setValue(from); //入会时间上限
dpk_to.setValue(to); //入会时间下限
}
private void initData() {
}
@FXML
private void findVIP() {
String idOrName = "%" + tf_findInfo.getText().trim() + "%"; //卡号或姓名
String str0 = cbb_level.getValue().equals("所有等级") ? "" : cbb_level.getValue();
String level = str0 + "%"; //会员等级
String dateFrom = dpk_from.getValue().toString(); //时间上限
String dateTo = dpk_to.getValue().toString(); //时间下限
ArrayList<UserBean> listVipBeans = vipInfoDao.selectByFiltrate(idOrName, idOrName, level, dateFrom, dateTo);
if (listVipBeans != null) {
table.clearData();
for (UserBean bean : listVipBeans)
table.addBean(bean);
} else {
new MyAlert(AlertType.INFORMATION, "没有找到您查询的会员!").show();
}
}
@FXML // 添加会员信息
private void addVip() {
ObservableList<Tab> obList = tp_rootPane.getTabs();
final String DATA = "添加会员";
for (Tab tab : obList) { // 遍历判断该tab是否已经添加
String userDate = (String) tab.getUserData();
if (userDate != null && userDate.equals(DATA)) {
tp_rootPane.getSelectionModel().select(tab); // 如果已经添加则显示该tab并返回
return;
}
}
Tab tab = new VipAddTab();
tab.setUserData(DATA);
obList.add(tab);
tp_rootPane.getSelectionModel().select(tab);
}
/**
* 删除会员信息
*/
@FXML
private void deleteVip() {
UserBean bean = table.getSelectedData();
if (bean == null) {
new MyAlert(AlertType.INFORMATION, "请先选择一条数据!").show();
return;
}
String id = "卡号:" + bean.getId();
String name = "姓名:" + bean.getName();
MyAlert alert = new MyAlert(AlertType.CONFIRMATION, "是否确定删除该用户的信息?\n[ " + id + "," + name + " ]");
Optional<ButtonType> result = alert.showAndWait();
if (result.isPresent() && result.get() == ButtonType.OK) {
table.removeData(bean);
vipInfoDao.deleteByID(bean);
}
}
/**
* 修改会员信息
*/
@FXML
private void modifyVip() {
UserBean bean = table.getSelectedData();
if (bean == null) {
new MyAlert(AlertType.INFORMATION, "请先选择一条数据!").show();
return;
}
ObservableList<Tab> obList = tp_rootPane.getTabs();
final String DATA = "修改会员信息";
for (Tab tab : obList) { // 遍历判断该tab是否已经添加
String userDate = (String) tab.getUserData();
if (userDate != null && userDate.equals(DATA)) {
tp_rootPane.getSelectionModel().select(tab); // 如果已经添加则显示该tab并返回
return;
}
}
VipModifyTab tab = new VipModifyTab(bean);
tab.setUserData(DATA);
tab.setPreTab(tab_manage);
obList.add(tab);
tp_rootPane.getSelectionModel().select(tab);
}
@FXML
private void printInfo() {
File file = new File("D:/会员信息.xls");
OutputStream os = null;
try {
os = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
ObservableList<TableColumn<UserBean, ?>> columns = table.getColumns();
ObservableList<UserBean> items = table.getItems();
List<Object> contentList = new ArrayList<>(items);
String[] titles = new String[columns.size()];
String[] fieldNames = {"id", "admissionDate", "name", "sex", "cardLevel", "balance", "frequency", "cumulative", "address", "integral", "telephone", "idcard", "birthday", "career", "email", "other"};
for (int i = 0; i < titles.length; i++) {
titles[i] = columns.get(i).getText();
}
boolean hasPrint = JXLUtil.exportExcel(titles, fieldNames, contentList, os);
if (hasPrint) {
new MyAlert(AlertType.INFORMATION, "打印成功!\n文件保存位置为:" + file.getAbsolutePath()).show();
} else {
new MyAlert(AlertType.INFORMATION, "打印失败!").show();
}
}
```
4.项目展示
登录页
首页
会员查询
添加会员
会员列表
会员管理
商品管理
添加商品
套餐项目
数据统计
会员消费
库存不足
订单结算
5.项目安装
软件需使用maven打包,打包插件如下 :
xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.1.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
打包后软件根目录需包含以下文件 :
根目录
|
│ CRM-v200324.jar (主程序)
│
├─config (配置文件)
│ │ userConfig.properties
│ │
│ └─splash (启动界面图片)
│ Splash.png
│
├─data (数据库)
│ mycrm.db
│
└─photo (照片)
├─goods
└─user
参考文献
- 基于Spring框架的B2C电子商务系统的设计与实现(山东大学·葛继武)
- 基于J2EE平台的代理商订单管理系统的开发(东北石油大学·尹亮群)
- 便利店数据管理系统的设计与实现(东北农业大学·刘安旺)
- 便利店数据管理系统的设计与实现(东北农业大学·刘安旺)
- 基于J2EE平台的代理商订单管理系统的开发(东北石油大学·尹亮群)
- 基于SSH资源管理系统的设计及实现(西安电子科技大学·杨静涛)
- 仓库管理系统的设计与实现(电子科技大学·张天一)
- 基于JavaEE的工厂文档管理系统(武汉科技大学·朱永强)
- 面向中小企业的信息管理系统的设计与实现(北京邮电大学·贾士强)
- 基于SSH框架的人力资源管理系统的设计与开发(电子科技大学·唐伟)
- 便利店数据管理系统的设计与实现(东北农业大学·刘安旺)
- 邮政仓储管理信息系统的设计与实现(大连理工大学·于思佳)
- 基于J2EE平台的代理商订单管理系统的开发(东北石油大学·尹亮群)
- 面向石油行业的客户关系管理系统设计与实现(中国海洋大学·郭战齐)
- 外贸订单管理系统的设计与实现(山东大学·曹美玉)
本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:毕设港湾 ,原文地址:https://m.bishedaima.com/yuanma/35473.html