烟草仓储管理系统开发笔记(一)

本文最后更新于:2024年3月18日 晚上

安卓的毕设为烟草仓储管理系统,本科期间最后一个开发项目了,上学年还有安卓的课程,不过也是经典的用完就忘,当时课设所使用的内容在现在也只留下了一个大概印象了,而每次开发总得学到些东西,因此就又从头开始看起了安卓的教程,不过也没能找到近年的评价好的安卓教程,最后直接看jetpack相关的教程。在看了好几天的教程后,终于开始了毕设的编写,因为教程的后半部分使用的是kotlin代码,虽然我并没有学习过,但感觉使用kotlin构建Room的实体类还是要方便不少,因此在数据库设计部分使用kotlin,其余部分仍然使用Java。

功能逻辑梳理

和以往不同的是,这次不是刚开始项目就直接上手写,写了这么多的课设也多少明白了前期设计的重要性,所以首先对软件的功能进行了梳理,主要功能内容分为用户管理、产品信息管理、原料信息管理、客户信息管理、供应商信息管理、采购订单管理、销售订单管理、库存管理以及报表分析。更加详细的内容如以下的思维导图所呈现。其中黄色的为可选功能,粉色的为注释。

数据库设计

数据库也是前期就应该设计好的,后续对数据库进行的更改非常麻烦,所以这次首先根据功能列表设计好数据库的结构,使用Navicat16生成数据进行了测试,并根据需要用到的数据查询情况设计了对应的视图,确保都能获得想要的效果。具体内容如下。

数据库编写

在Android的数据库编写中,使用Kotlin语言和Room组件进行设计,设计的表全部放于Entities包下,其中报表分析所需要的Report表中不存放数据,而是使用视图从其他表中获取数据进行呈现,对于一些数值有限可选的变量设计为静态变量,增加可读性。新建dao包,在其中为每个实体类都添加对应的Dao接口,在Dao接口中定义各种增删改查操作。新建一个抽象类database,在其中返回各个实体的dao对象,并通过kotlin的伴生对象设计为单例模式。
Entity示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Entity(tableName = "sale_order")  
data class SaleOrder(
//订单号
@PrimaryKey(autoGenerate = true)
val orderId:Int=1,
//售出产品名称
@ColumnInfo(name = "productName")
var productName:String,
//售出产品型号
@ColumnInfo(name = "productModel")
var productModel:String,
//销售数量
@ColumnInfo(name = "count")
var count:Int,
//销售总价格
@ColumnInfo(name = "price")
var price:Float,
//客户名称
@ColumnInfo(name = "customer")
var customer:String,
//销售日期
@ColumnInfo(name = "saleDate")
var saleDate: Date,
//预计送达日期
@ColumnInfo(name = "deliveryDate")
var deliveryDate: Date,
//订单状态
@ColumnInfo(name = "state")
var state:String,
//管理员批注
@ColumnInfo(name = "comment")
var comment:String
){
companion object{
const val STATE_REQUEST:String="申请中"
const val STATE_DELIVERY:String="运输中"
const val STATE_REFUSED:String="已拒绝"
const val STATE_COMPLETE:String="已完成"
}
}

视图示例

1
2
3
4
5
@DatabaseView("SELECT customer, count(customer) FROM sale_order GROUP BY customer ORDER BY count(customer) DESC")  
data class PurchaseCount(
val customer: String,
val times:Int
)

dao示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Dao  
interface SaleOrderDao {
@Insert
fun insertSaleOrder(vararg saleOrder: SaleOrder):Long

@Update
fun updateSaleOrder(vararg saleOrder: SaleOrder):Long

@Delete
fun deleteSaleOrder(vararg saleOrder: SaleOrder):Long

@Query("SELECT * FROM sale_order ORDER BY" +
"( CASE WHEN state = '申请中' THEN 0 WHEN state = '已拒绝' THEN 1 WHEN state = '运输中' THEN 2 ELSE 3 END )")
fun getAllSaleOrder(): LiveData<List<SaleOrder>>
}

database

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Database(  
entities = [User::class, Customer::class, Supplier::class, Product::class, Material::class, Inventory::class, PurchaseOrder::class, SaleOrder::class],
views = [PurchaseAmount::class, PurchaseCount::class],
version = 1,
exportSchema = false
)
abstract class WMSDatabase:RoomDatabase(){
companion object{
private var INSTANCE:WMSDatabase?=null

fun getINSTANCE(context: Context):WMSDatabase ? {
if(INSTANCE == null){
INSTANCE = Room.databaseBuilder(context,WMSDatabase::class.java,"tobacco_database.db").allowMainThreadQueries().build()
}
return INSTANCE
}

fun getINSTANCE():WMSDatabase?= INSTANCE
}

abstract fun userDao():UserDao
abstract fun customerDao():CustomerDao
abstract fun supplierDao():SupplierDao
abstract fun productDao():ProductDao
abstract fun materialDao():MaterialDao
abstract fun inventoryDao():InventoryDao
abstract fun purchaseOrderDao():PurchaseOrderDao
abstract fun saleOrderDao():SaleOrderDao
abstract fun reportDao():ReportDao
}

遇到的问题

在这次的开发中由于使用了kotlin语言,而本身对于kotlin可以说完全没有了解,因此当出现问题时耗费了挺多时间去处理,例如上述的静态常量和静态方法,由于kotlin中没有static关键字,因此无法直接使用static定义静态常量,在查阅资料后知道了kotlin伴生对象的使用方法,实现了静态常量的定义。


烟草仓储管理系统开发笔记(一)
http://starnight.top/2022/04/09/烟草仓储管理系统开发笔记(一)/
作者
Cardy Xie
发布于
2022年4月9日
许可协议