### 0.欢迎参加23年软件杯a6/b4,申请环境时,推荐码填7068,凭截图可后台私戳我一对一答疑+送资料~ (宣传一波嘿嘿)
1.前言
项目来自2022年的中国软件杯A6赛题—智慧图书馆基于“金蝶云·苍穹”平台完成图书馆功能的设计项目基本是独立完成,最终有幸获得国家三等奖
2.项目展示
图书馆0802演示视频
3.项目描述
基于金蝶云·苍穹平台,通过社区自主学习并独立完成智慧图书馆项目的设计与实现 -> 功能:书籍检索,图书借还及预约委托,图书采购申请,借书单打印,个人中心,新增书籍,基础信息维护等 -> 涉及平台技术:页面开发,单据流转换,插件开发(Java)打印功能,到期预警,轻分析等 -> 项目设计:从基础资料(书籍-ISBN、书本-索书号、图书馆、中图法)到单据流转换(图书的采购申请单映射为图书采购订单);从书籍检索、借阅、申购到自动审批、书籍到期预警、轻分析卡片;
4.下一步(2022.10计划)
打算作为毕设~ 预计新添功能:图书智能推荐 √参考:我的协同过滤实现参考:参考itemcf代码
.
5.ItemCF实现(2023.3实现… 摆烂哈哈哈)
5.1 页面建模
其实就是单据啦 ![在这里插入图片描述](https://img-blog.csdnimg.cn/24da4498303d4369bfd965cb6a9727c5.png)
5.2 自动填充单据的相关代码(java插件,需要在页面注册)
package kd.lpqj.sa.plugins;
import akka.dispatch.Foreach;
import kd.bos.bill.AbstractBillPlugIn;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.lpqj.sa.plugins.utils.Recommend;
import org.apache.commons.collections.map.HashedMap;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.HashMap;
import java.util.List;
public class BookRecommendPlugin extends AbstractBillPlugIn {
@Override
public void afterCreateNewData(EventObject e) {
super.afterCreateNewData(e);
//用户设置为:当前用户
// DynamicObject dataEntity = this.getModel().getDataEntity();
long currentUserId = UserServiceHelper.getCurrentUserId();//获取当前用户id
QFilter qFilter = new QFilter("lpqj_borrowinfo.lpqj_borrow_person", QCP.equals, currentUserId);
QFilter qFilter2 = new QFilter("lpqj_borrowinfo.enable", QCP.equals, 1);
QFilter[] qFilters = {qFilter,qFilter2};
DynamicObject[] query_record = BusinessDataServiceHelper.load("lpqj_borrowinfo", "id,number,lpqj_borror_book",qFilters);
// lpqj_book_isbn lpqj_borror_book
QFilter[] qFilter3 = {new QFilter("lpqj_borrowinfo.lpqj_borrow_person", QCP.equals, currentUserId)};
//查出 书籍isbn表的数据,填充到单据体
int all = query_record.length;
HashMap recommendMap = new HashMap();
if(all > 0){
for (int i = 0; i 0) {
// 待新增分录的行数
IDataModel dataModel = this.getModel();
dataModel.batchCreateNewEntryRow("entryentity", size);
for (DynamicObject book : recommend) {
// 第 1 个参数(propName): 单据体列字段的字段标识
// 第 2 个参数(value):对应列字段待填充的值
// 第 3 个参数(rowIndex):行号, 从0开始计
dataModel.setValue("lpqj_isbn", book.get("id"), index++);
}
}
}
}
5.3 推荐算法代码(推荐算法函数)
package kd.lpqj.sa.plugins.utils;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import java.util.*;
import java.util.stream.Collectors;
public class Recommend {
/*
在电影推荐系统的基础上修改 (可能存在用户数少于书籍数的情况)
int len = arr1.length>arr2.length?arr2.length:arr1.length; //原来是arr1.length
*/
public List builderRecommend(long UserId) {
// 查询所有订单记录
QFilter[] qFilter1 = {new QFilter("lpqj_borrowinfo.enable", QCP.equals, 1)};
DynamicObject[] borrowList = BusinessDataServiceHelper.load("lpqj_borrowinfo", "id,number,lpqj_borror_book,lpqj_borrow_person", qFilter1);
QFilter[] qFilter2 = {new QFilter("lpqj_book_isbn.enable", QCP.equals, 1)};
DynamicObject[] bookList = BusinessDataServiceHelper.load("lpqj_book_isbn", "id,number", qFilter2);
QFilter[] qFilter3 = {new QFilter("lpqj_bos_user_ext.enable", QCP.equals, 1)};
DynamicObject[] userList = BusinessDataServiceHelper.load("bos_user", "id,number", qFilter3);
//java.lang.RuntimeException: CAUSE: java.lang.NullPointerException
// 定义一个分数集合用户去存储用户行为,根据购买记录赋分,购买则算1分
List scoreList = new ArrayList();
for (DynamicObject borrow : borrowList) {
String isbn = (String) borrow.get("lpqj_borror_book.lpqj_textfield4");
Long user = (Long) borrow.get("lpqj_borrow_person.id");
ScoreDto scoreDto = new ScoreDto(user, isbn, 1d);
scoreList.add(scoreDto);
System.out.println("************借书记录:"+scoreDto.toString());
}
// 构建评分矩阵,行数是书籍数,列数是用户数
double[][] scoreArr = new double[bookList.length][userList.length];
for (ScoreDto scoreDto : scoreList) {
Long currentUserId = scoreDto.getUserId();
String currentBookIsbn = scoreDto.getbookId();
for (int i = 0; i |