完成设置页面和退出页面,开卡页面的画图

This commit is contained in:
Jingfan Ke 2024-07-28 22:47:24 +08:00 committed by kejingfan
commit 1a300f4ca7
16 changed files with 1297 additions and 0 deletions

74
.gitignore vendored Normal file
View File

@ -0,0 +1,74 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
CMakeLists.txt.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe

44
CardManageSystem.pro Normal file
View File

@ -0,0 +1,44 @@
QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
HF15693.h \
mainwindow.h \
newCardPage.h \
quitAppPage.h \
readerAPI.h \
settingPage.h
FORMS += \
mainwindow.ui
TRANSLATIONS += \
CardManageSystem_zh_CN.ts
CONFIG += lrelease
CONFIG += embed_translations
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
HF15693.dll \
HF15693.lib
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../release/ -lHF15693
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../debug/ -lHF15693
else:unix: LIBS += -L$$PWD/../ -lHF15693
LIBS += -L. -lHF15693

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN"></TS>

195
HF15693.h Normal file
View File

@ -0,0 +1,195 @@
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 HF15693_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// HF15693_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifndef __HF15693_H__
#define __HF15693_H__
#ifdef HF15693_EXPORTS
#define HF15693_API __declspec(dllexport)
#else
#define HF15693_API __declspec(dllimport)
#endif
#define OP_RESPONSE_FLAG_ERROR 0x01
#define OP_RESPONSE_FLAG_EXTENSION 0x08
#define DATA_LEN 256
#define MAX_UID 32
#define UID_LEN 68
#define DSFID_LEN 4
#define CMD_LEN 2048
// 15693命令代码
#define CC_INVENTORY "01"
#define CC_QUIET "02"
#define CC_READ_SB "20"
#define CC_WRITE_SB "21"
#define CC_LOCK "22"
#define CC_READ_MP "23"
#define CC_WRITE_MP "24"
#define CC_SELECT "25"
#define CC_READY "26"
#define CC_WRITE_API "27"
#define CC_LOCK_API "28"
#define CC_WRITE_DSFID "29"
#define CC_LOCK_DSFID "2A"
#define CC_GET_INFO "2B"
#define CC_GET_SEC_STAT "2C"
//命令字
#define INVENTORY 0
#define READ_SB 1
#define WRITE_SB 2
#define LOCK_B 3
#define READ_MB 4
#define WRITE_MB 5
#define QUIET 6
#define SELECT 7
#define READY 8
#define WRITE_AFI 9
#define LOCK_AFI 10
#define WRITE_DSFID 11
#define LOCK_DSFID 12
#define T15SYSTEM_INFO 13
#define MBS_STATUS 14
#define PROTOCOL 15
#define FLAG 16
#define SET 17
#ifdef __cplusplus
extern "C" {
#endif
extern HF15693_API int t15bDataCoding /*数据编码:0 - 1/4; 1 - 1/256*/, t15bFullPower /*全功率*/, t15bSubCarrier /*副载波*/,
t15bDataRate /*高数据率*/,
t15bInventory /*盘点标志*/, t15bSelect /*选择标志/AFI标志*/, t15bAddress /*地址标志/槽数据标志*/,
t15bOption /*可选标志*/;
extern HF15693_API char t15UID[UID_LEN], t15FirstBN[3], t15NumBl[3], t15Data[DATA_LEN],
t15DSFID[DSFID_LEN], t15AFI[5];
// 与字节序相关的函数,在函数内部不处理,需使用者自行处理
//////////////////////////////
//工具函数
/*********************************************
/* 描述:打开串口
/* 输入:串口号如若打开com1则参数为 1
/* 输出:无
/* 返回:true 打开成功false 打开失败
/* 其他:
/*********************************************/
HF15693_API bool t15portOpen(int comno);
/*********************************************
/* 描述:关闭串口
/* 输入:无
/* 输出:无
/* 返回:true 关闭成功false 关闭失败
/* 其他:
/*********************************************/
HF15693_API bool t15portClose();
/*********************************************
/* 描述:设置协议
/* 输入:无
/* 输出:无
/* 返回: 0 设置成功; ~0 设置失败
/* 其他:
/*********************************************/
HF15693_API int t15setProtocol();
/*********************************************
/* 描述:执行命令
/* 输入:cmdno - 命令字
/* 输出:cmdstr - 向下发出的命令字段reply - 对命令回复的字段
/* 返回:(int) 命令回复字段中的有效字节数
/* 其他:
/*********************************************/
HF15693_API int t15execute(int cmdno, char *cmdstr,char *reply);
/////////////////////////////////////
/*********************************************
/* 描述:从一个字串中提取一个表示十六进制数字的子串,子串间以',' '[' 分隔
/* 输入: str - 原字串
/* 输出: str - 指向原串中提取到的子串的下一下字符, word - 提取到的子串
/* 返回: 0 - 成功 1 - 失败
/* 其他:
/*********************************************/
HF15693_API int getXWord (char **str, char *word);
/*********************************************
/* 描述:从一个字串中提取一个表示十六进制数字的子串,子串间以',' '[' 分隔
/* 输入: str - 原字串
/* 输出: word - 提取到的子串
/* 返回:
/* 其他:
/*********************************************/
HF15693_API int getXWord2 ( char *str, char *word);
/*********************************************
/* 描述:更改字节序
/* 输入:pin - 原字串 lenbytes - 字串数据长度
/* 输出:pout - 更改字节序后的字串
/* 返回:无
/* 其他:此函数会在pout后补0使用者须保证其长度。
/* 如,字串"123456" 更改字节序后变为 "563412"
/*********************************************/
HF15693_API void t15changeByteOrder(char *pout,const char *pin,int lenbytes);
/*********************************************
/* 描述:更改带块安全状态信息(block security status)的字串的字节序
/* 输入:pin - 原字串 lenbytes - 字串数据长度,不包含'块安全状态信息'的长度
/* 输出:sbss - 原字串中的bss值 pout - 更改字节序后的字串
/* 返回:无
/* 其他:字串的存储空间由使用者保证会在pout后补0sbss是用字串表示的一个字节的十六进制数
/*********************************************/
HF15693_API void t15changeByteOrder2(char *sbss,char *pout, char *pin,int lenbytes);
/*********************************************
/* 描述:更改字串的字节序,字串包含多个块的数据
/* 输入:pin - 原字串 numblocks - 原字串中包含的块数目
/* 输出:pout - 更改字节序后的字串
/* 返回:无
/* 其他:每个块数据长度由pin长度和numblocks决定会在pout后补0
/*********************************************/
HF15693_API void t15changeByteOrder_MB(char *pout, char *pin, int numblocks);
/*********************************************
/* 描述:更改带块安全状态信息(block security status)的字串的字节序,字串包含多个块的数据
/* 输入:pin - 原字串;lenbytes - 字串数据长度,不包含'块安全状态信息'的长度; numblocks - 原字串中包含的块数目
/* 输出:mbss - 原字串中的bss值 pout - 更改字节序后的字串
/* 返回:无
/* 其他:各个块的bss依次存放于mbss中多个块的数据依次存放于pout中
/*********************************************/
HF15693_API void t15changeByteOrder_MB2(char *mbss,char *pout, char *pin,int lenbytes, int numblocks);
/*********************************************
/* 描述:解析返回的RSSI值
/* 输入:字串表示的RSSI
/* 输出:无
/* 返回:指向解析过的RSSI信息的内存块
/* 其他:返回的指针指向的内存由函数分配管理
/*********************************************/
HF15693_API char* t15hex2rssi (char *str);
/*********************************************
/* 描述:解析标签信息字串
/* 输入:data - 原标签信息字串flag - 标签信息标志
/* 输出:(其他参数)
/* 返回:0
/* 其他:
/*********************************************/
HF15693_API int t15getTagSysInfo (char *data, const unsigned char flag,char *uid, char *dsfid, char *afi,
char *blSize, char *numBl, char *ic);
#ifdef __cplusplus
}
#endif
#endif

BIN
HF15693.lib Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="i18n">
<file alias="CardManageSystem_zh_CN.qm">D:/Courseware/Integrated_Practice_of_IoT_System/CardManageSystem/build/Desktop_Qt_6_7_2_MinGW_64_bit-Debug/debug/CardManageSystem_zh_CN.qm</file>
</qresource>
</RCC>

View File

@ -0,0 +1,31 @@
<mxfile host="Electron" modified="2024-07-28T12:00:05.441Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.6.1 Chrome/124.0.6367.207 Electron/30.0.6 Safari/537.36" etag="zDIfvHg48gbbwDQY4H_P" version="24.6.1" type="device">
<diagram name="第 1 页" id="8yjcYh25Fj_Vruqp0e9_">
<mxGraphModel dx="1434" dy="836" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="ikCD32b5rJxaaIhKNZvf-1" value="卡" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="400" y="200" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-2" value="用户" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="80" y="200" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-3" value="记录" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="400" y="440" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-4" value="学号" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="80" y="120" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-5" value="余额" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="200" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-6" value="卡号" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="400" y="120" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-7" value="状态" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="120" width="120" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

148
doc/source/ER.drawio Normal file
View File

@ -0,0 +1,148 @@
<mxfile host="Electron" modified="2024-07-28T12:31:43.332Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.6.1 Chrome/124.0.6367.207 Electron/30.0.6 Safari/537.36" etag="HsDZe_ryQ9wAG3Kks_rW" version="24.6.1" type="device">
<diagram name="第 1 页" id="8yjcYh25Fj_Vruqp0e9_">
<mxGraphModel dx="1834" dy="836" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="ikCD32b5rJxaaIhKNZvf-11" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-1" target="ikCD32b5rJxaaIhKNZvf-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-18" value="1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-1" target="ikCD32b5rJxaaIhKNZvf-16">
<mxGeometry y="10" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-1" value="卡" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="400" y="200" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-8" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-2" target="ikCD32b5rJxaaIhKNZvf-4">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-14" value="1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-2" target="ikCD32b5rJxaaIhKNZvf-13">
<mxGeometry y="10" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-2" value="用户" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="80" y="200" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-25" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;endArrow=none;endFill=0;entryX=1;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-3" target="ikCD32b5rJxaaIhKNZvf-21">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-27" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-3" target="ikCD32b5rJxaaIhKNZvf-22">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-28" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-3" target="ikCD32b5rJxaaIhKNZvf-24">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-30" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-3" target="ikCD32b5rJxaaIhKNZvf-29">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-32" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-3" target="ikCD32b5rJxaaIhKNZvf-31">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-3" value="记录" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="400" y="360" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-4" value="&lt;u&gt;学号&lt;/u&gt;" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="80" y="120" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-5" value="余额" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="200" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-9" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-6" target="ikCD32b5rJxaaIhKNZvf-1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-6" value="&lt;u&gt;卡号&lt;/u&gt;" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="400" y="120" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-10" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-7" target="ikCD32b5rJxaaIhKNZvf-1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-7" value="状态" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="120" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-15" value="1" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-13" target="ikCD32b5rJxaaIhKNZvf-1">
<mxGeometry y="10" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-13" value="绑定" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="240" y="200" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-17" value="n" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-16" target="ikCD32b5rJxaaIhKNZvf-3">
<mxGeometry y="10" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-16" value="存储" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="400" y="280" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-20" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-19" target="ikCD32b5rJxaaIhKNZvf-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-19" value="&lt;u&gt;编号&lt;/u&gt;" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="240" y="280" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-21" value="金额" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="240" y="440" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-22" value="原金额" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="400" y="440" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-24" value="类型" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="360" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-29" value="余额" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="440" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-31" value="时间" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="280" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-46" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-35" target="ikCD32b5rJxaaIhKNZvf-44">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-35" value="设备名" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="80" y="360" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-37" value="n" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-36" target="ikCD32b5rJxaaIhKNZvf-3">
<mxGeometry y="10" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-38" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-36" target="ikCD32b5rJxaaIhKNZvf-35">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-40" value="1" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="ikCD32b5rJxaaIhKNZvf-38">
<mxGeometry x="0.05" y="1" relative="1" as="geometry">
<mxPoint y="-11" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-36" value="产生" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="240" y="360" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-42" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-41" target="ikCD32b5rJxaaIhKNZvf-35">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-41" value="&lt;u&gt;编号&lt;/u&gt;" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="80" y="280" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-45" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-43" target="ikCD32b5rJxaaIhKNZvf-35">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-43" value="充值权限" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="-80" y="360" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-44" value="名称" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="80" y="440" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-48" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=none;endFill=0;" edge="1" parent="1" source="ikCD32b5rJxaaIhKNZvf-47" target="ikCD32b5rJxaaIhKNZvf-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ikCD32b5rJxaaIhKNZvf-47" value="姓名" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="-80" y="200" width="120" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

23
main.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "mainwindow.h"
#include <QApplication>
#include <QLocale>
#include <QTranslator>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages) {
const QString baseName = "CardManageSystem_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName)) {
a.installTranslator(&translator);
break;
}
}
MainWindow w;
w.show();
return a.exec();
}

47
mainwindow.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingPage.h"
#include "quitAppPage.h"
#include "newCardPage.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 工具栏设置
addToolBar(Qt::LeftToolBarArea, ui->toolBar);
ui->toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
ui->toolBar->setFloatable(false);
ui->toolBar->setMovable(false);
// 状态栏设置
ui->statusBar->setStyleSheet(QString("QStatusBar::item{border: 0px}"));
readerConnectStatusCheckBox = new QCheckBox();
readerConnectStatusCheckBox->setChecked(false);
ui->statusBar->addWidget(readerConnectStatusCheckBox);
comNumberLabel = new QLabel("当前无连接");
ui->statusBar->addWidget(comNumberLabel);
databaseConnectStatusCheckBox = new QCheckBox();
databaseConnectStatusCheckBox->setChecked(false);
ui->statusBar->addWidget(databaseConnectStatusCheckBox);
databaseLabel = new QLabel("数据库无连接");
ui->statusBar->addWidget(databaseLabel);
deviceLabel = new QLabel(device);
ui->statusBar->addWidget(deviceLabel);
ui->stackedWidget->setCurrentWidget(ui->settingPage);
}
MainWindow::~MainWindow()
{
delete ui;
}

62
mainwindow.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QCheckBox>
#include <QLabel>
#include <QStackedWidget>
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <readerAPI.h>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void updateStatusBarComNumber();
bool ready();
private slots:
void on_settingAction_triggered();
void on_quitAppAction_triggered();
void on_NewCardAction_triggered();
void on_connectReaderButton_clicked();
void on_confirmQuitButton_clicked();
void on_connectDatabaseButton_clicked();
void on_inventoryButton_clicked();
private:
Ui::MainWindow *ui;
Reader reader;
QSqlDatabase db;
QString databaseIpAddr = "";
int databasePort = 3306;
QString databasePassword = "";
QString device = QString("未指定设备名");
bool depositAllowed = false;
QStatusBar *statusBar;
QStackedWidget *stackedWidget;
QCheckBox *readerConnectStatusCheckBox;
QLabel *comNumberLabel;
QCheckBox *databaseConnectStatusCheckBox;
QLabel *databaseLabel;
QLabel *deviceLabel;
};
#endif // MAINWINDOW_H

441
mainwindow.ui Normal file
View File

@ -0,0 +1,441 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>708</width>
<height>493</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QStackedWidget" name="stackedWidget">
<property name="geometry">
<rect>
<x>-50</x>
<y>-40</y>
<width>701</width>
<height>481</height>
</rect>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="currentIndex">
<number>2</number>
</property>
<widget class="QWidget" name="quitAppPage">
<widget class="QPushButton" name="confirmQuitButton">
<property name="geometry">
<rect>
<x>310</x>
<y>260</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>确认</string>
</property>
</widget>
<widget class="QLabel" name="confirmQuitLabel">
<property name="geometry">
<rect>
<x>270</x>
<y>180</y>
<width>161</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>确认退出应用吗?</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</widget>
<widget class="QWidget" name="settingPage">
<widget class="QWidget" name="verticalLayoutWidget_2">
<property name="geometry">
<rect>
<x>240</x>
<y>70</y>
<width>229</width>
<height>118</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<family>Microsoft JhengHei UI</family>
<pointsize>11</pointsize>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>连接读卡器</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>选择端口COM</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="comNumberBox">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="directLinkButton">
<property name="text">
<string>直连模式</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QPushButton" name="connectReaderButton">
<property name="geometry">
<rect>
<x>320</x>
<y>200</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>连接</string>
</property>
</widget>
<widget class="QWidget" name="verticalLayoutWidget_3">
<property name="geometry">
<rect>
<x>250</x>
<y>260</y>
<width>231</width>
<height>159</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<family>Microsoft JhengHei UI</family>
<pointsize>11</pointsize>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>连接数据库</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QLabel" name="portLabel">
<property name="text">
<string>端口:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="ipAddrEdit">
<property name="text">
<string>172.29.68.245</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="ipAddrLabel">
<property name="text">
<string>IP地址</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="passwordLabel">
<property name="text">
<string>密码:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="portBox">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="minimum">
<number>1024</number>
</property>
<property name="maximum">
<number>65534</number>
</property>
<property name="value">
<number>3306</number>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="passwordEdit"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="deviceLabel">
<property name="text">
<string>设备名:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="deviceEdit"/>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QPushButton" name="connectDatabaseButton">
<property name="geometry">
<rect>
<x>330</x>
<y>430</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>连接</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="newCardPage">
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>210</x>
<y>130</y>
<width>347</width>
<height>84</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="cardIdBox">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="cardIdLabel">
<property name="text">
<string>卡号:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="userIdLabel">
<property name="text">
<string>学/工号:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="inventoryButton">
<property name="text">
<string>查询</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>300</x>
<y>230</y>
<width>80</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>开卡</string>
</property>
</widget>
</widget>
</widget>
</widget>
<widget class="QStatusBar" name="statusBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar_2</string>
</property>
<attribute name="toolBarArea">
<enum>LeftToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="settingAction"/>
<addaction name="NewCardAction"/>
<addaction name="depositAction"/>
<addaction name="ConsumptionAction"/>
<addaction name="QueryAction"/>
<addaction name="reportLossAction"/>
<addaction name="quitAppAction"/>
</widget>
<action name="settingAction">
<property name="text">
<string>设置</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="quitAppAction">
<property name="text">
<string>退出</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="ConsumptionAction">
<property name="text">
<string>消费</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="NewCardAction">
<property name="text">
<string>开卡</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="QueryAction">
<property name="text">
<string>查询</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="depositAction">
<property name="text">
<string>充值</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="reportLossAction">
<property name="text">
<string>挂失</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

35
newCardPage.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef NEWCARDPAGE_H
#define NEWCARDPAGE_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
/*
*
*
*/
void MainWindow::on_NewCardAction_triggered()
{
if (!ready())
{
QMessageBox::warning(this, QString("提示"), QString("读卡器或数据库未连接,请设置。"));
ui->stackedWidget->setCurrentWidget(ui->settingPage);
return;
}
ui->stackedWidget->setCurrentWidget(ui->newCardPage);
}
/*
*
*
*/
void MainWindow::on_inventoryButton_clicked()
{
}
#endif // NEWCARDPAGE_H

28
quitAppPage.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef QUITAPPPAGE_H
#define QUITAPPPAGE_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
/*
* 退
* 退
*/
void MainWindow::on_quitAppAction_triggered()
{
ui->stackedWidget->setCurrentWidget(ui->quitAppPage);
}
/*
* 退
* 退
*/
void MainWindow::on_confirmQuitButton_clicked()
{
this->close();
}
#endif // QUITAPPPAGE_H

43
readerAPI.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef READERAPI_H
#define READERAPI_H
#include <HF15693.h>
class Reader
{
private:
int comNumber = -1; // com口号若未连接为-1
public:
bool is_connected()
{
return comNumber > 0;
}
bool connectReader()
{
if (t15portOpen(comNumber))
{
return true;
}
else
{
comNumber = -1;
return false;
}
}
void setComNumber(int comNumber)
{
this->comNumber = comNumber;
}
int getComNumber()
{
return comNumber;
}
};
#endif // READERAPI_H

118
settingPage.h Normal file
View File

@ -0,0 +1,118 @@
#ifndef SETTINGPAGE_H
#define SETTINGPAGE_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
/*
*
*
*/
void MainWindow::on_settingAction_triggered()
{
ui->stackedWidget->setCurrentWidget(ui->settingPage);
}
/*
* COM口号并更新状态栏的相应内容
* COM口号
*
*/
void MainWindow::updateStatusBarComNumber()
{
if (reader.is_connected())
{
readerConnectStatusCheckBox->setChecked(true);
QString s = "已连接读卡器COM" + QString::number(reader.getComNumber());
comNumberLabel->setText(s);
}
else
{
readerConnectStatusCheckBox->setChecked(false);
QString s = "当前无连接";
comNumberLabel->setText(s);
}
}
/*
*
*
*/
void MainWindow::on_connectReaderButton_clicked()
{
int comNumber = ui->comNumberBox->value();
reader.setComNumber(comNumber);
bool connectSuccess = reader.connectReader();
if (!connectSuccess) {
QString warningMessage = QString("COM") + QString::number(comNumber);
warningMessage += QString("上未识别到读卡器。\n请输入正确的COM口号。");
QMessageBox::warning(this, "读卡器状态提示", warningMessage);
}
updateStatusBarComNumber();
}
/*
*
*
*/
void MainWindow::on_connectDatabaseButton_clicked()
{
databaseIpAddr = ui->ipAddrEdit->text();
databasePort = ui->portBox->value();
databasePassword = ui->passwordEdit->text();
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName(databaseIpAddr);
db.setPort(databasePort);
db.setPassword(databasePassword);
db.setDatabaseName("cardManageSystem");
db.setUserName("cardManageSystem");
if (!db.open())
{
QMessageBox::warning(this, QString("数据库状态提示"), QString("数据库连接失败,请重试。"));
databaseConnectStatusCheckBox->setChecked(false);
databaseLabel->setText(QString("数据库未连接"));
databaseIpAddr = "";
return;
}
databaseConnectStatusCheckBox->setChecked(true);
databaseLabel->setText(QString("数据库已连接:") + databaseIpAddr + QString(":") + QString::number(databasePort));
device = ui->deviceEdit->text();
QSqlQuery query;
QString sql = QString("select * from device where id = '%1';").arg(device);
query.exec(sql);
if (query.next())
{
if (query.value(2).toBool()) depositAllowed = true;
else depositAllowed = false;
}
else
{
device = QString("未指定设备名");
QMessageBox::warning(this, QString("设备名提示"), QString("该设备名无效,请重试。"));
}
deviceLabel->setText(device);
}
/*
*
*
* true - | false -
*/
bool MainWindow::ready()
{
if (!reader.is_connected() || databaseIpAddr.isEmpty()) return false;
return true;
}
#endif // SETTINGPAGE_H