采购申请单明细账/汇总账页面编写

业务需求和功能

1、功能:编写采购申请页面和采购申请管理页面。在申请单界面添加常用的查询条件,如单品、申请单等。在采购申请管理页面以单品维度去展示采购申请单的汇总信息,添加一个默认查询时间为7天,并对查询出来的不同状态申请单的做数量的自动汇总。
2、具体实现:编写两个订单的实体类,并通过@IOC注解将实体类交给系统容器管理,。在service层中编写业务逻辑,html做页面的静态页面,c#做动态界面与后端进行交互,。
3、特殊说明:为了页面美观,做了以下两点优化。使用内置标签函数如@Columns,绑定app页面中的表头,使得打开页面默认展示表头。并对后端查询到的特殊数据做客户端转换,方便客户观看。如申请单的状态,后端查到的是10,前端需要显示状态为编辑中。
在这里插入图片描述

具体代码实现

创建html作为采购申请明细账的静态界面

下面是具体代码:

**<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><link href="../../common/common.css" rel="stylesheet" type="text/css" /><link href="../../common/tabs.css" rel="stylesheet" type="text/css" /><link href="../../common/listview.css" rel="stylesheet" type="text/css" /><style>.with_label > text:first-child {width: 6em;}.more_search > popup .with_label > text:first-child {width: 7em!important;}#purchase_collect_detail [qp="provider_id"] {behavior: transform!important;}td[hf="onway_count"] {assigned!: self.title="采购量-采购到货量-采购已入库量(小于0则为0)";}td[hf="stockin_no_num"] {assigned!: self.title="采购量-采购已入库量(小于0则为0)";}td[hf="stockin_no_amount"] {assigned!: self.title="总金额-入库金额";}</style>
</head>
<body><!-- 注解:这是一个图片元素,用于显示采购统计详情的帮助 --><img help="statistics_purchaseDetail" /><div class="flat_bar"><!-- 注解:这是一个具有类名 "flat_bar" 的 div 元素 --><div persist="purchase_collect_detail"><!-- 注解:这是一个持久化的 div 元素,用于采购信息的收集 --><div class="search_bar"><!-- 注解:这是一个搜索栏,包含了多个搜索条件 --><div class="with_label">申请单状态<widget type="select-dropdown" fixedrows="2" qp="status" defval="-1"><!-- 注解:这是一个下拉框部件,用于选择申请单状态 --><option value="-1" selected>全部</option><option value="30">待审核</option><option value="35">待财审</option><option value="40">已审核</option><option value="90">已完成</option></widget></div><!-- ... 其他搜索条件的注解 ... --><btn id="btn_search">搜索</btn><!-- 注解:这是一个按钮,用于触发搜索操作 --></div></div></div><div class="hori expand"><!-- 注解:这是一个水平扩展的 div 元素 --><table id="goods_sell_list" row_template=".temp > tr"fixedrows="1"fixedlayoutclass="listview expand"next_page_btn="#btn_next_page"prev_page_btn="#btn_prev_page"first_page_btn="#btn_first_page"last_page_btn="#btn_last_page"refresh_btn="#btn_refresh"select_all_btn="#btn_sel_all"rselect_btn="#btn_rev_sel"total_count="#total_count"total_page="#total_page"current_page="#current_page"selected_count="#selected_count"total="sum(num),sum(arrive_num),sum(to_purchase_num),sum(onway_count),sum(amount),sum(stockin_num),sum(stockin_amount),sum(stockin_no_num),sum(stockin_no_amount),sum(invoice_num),sum(invoice_amount),sum(confirm_num),sum(stockin_num_amount),sum(price_amount),sum(arrive_more_num)"></table></div><!-- ... 其他注解 ... -->
</body>
</html>
**

需要注意上面中的两个按钮功能:
1、btn_search

 <btn id="btn_search">搜索</btn>
这是一个按钮,点击可触发搜索操作 ,与c#中的点击事件方法调用交互。
点击搜索按钮触发该标记下方的void OnClickSearch()回调函数。
[Click("#btn search")]
void OnClickSearch()

2、flat_bar
可以后期查询中获取页面输入信息作为搜索条件。下面是c#中使用的代码:

当前实例对象中匹配选择器"flat bar"的元素转为后续查询的参数
var queryParams = this.ToQueryParam(",flat_bar");

C#创建采购申请单明细的交互窗口

该窗口中包括页面的初始化,时间的回调函数调用、还有加载数据库的缓存配置信息,在此处没有用到。下面定义了一个简单的交互窗口,通过点击事件调用后端的statistic,Purchasestatistic,purchaseApplyDetail方法,将查询结果绑定到页面的表格元素 #goods sell list 中,并可能进行分页显示。需要注意的是#goods sell list相当于一个标签,需要提前在html文件中定义好表格元素。

[Window(Title="采购申请单明细账", View="statistic/sta_purchase/purchase_apply_detail.html", Style=Style.WS_VISIBLE|Style.WS_CHILD|Style.WS_CLIPCHILDREN, Width=960, Height=640)]public class PurchaseApplyDetailWindow : BaseWindow<Object>{Dictionary<string, string> custHeaders=null;public PurchaseApplyDetailWindow(){}// OnLoad() 方法在窗口加载完成后被调用,可以用来执行一些初始化操作或加载数据。protected override void OnLoad(){// 在窗口加载完成后,加载表头custHeaders = ControlUtils.LoadCustomPropName(this, CustomAttrType.PURCHASE_GOODS_PROP, "prop", "");Q("#goods_sell_list").Xcall("attach2", "statistic.PurchaseStatistic.purchaseApplyDetail", custHeaders);}// 搜索按钮被点击时的回调函数[Click("#btn_search")]void OnClickSearch(){// 当前实例对象中匹配选择器".flat_bar"的元素转换为查询参数形式。var queryParams = this.ToQueryParam(".flat_bar");Q("#goods_sell_list").DbPageBind2("statistic.PurchaseStatistic.purchaseApplyDetail", custHeaders, queryParams);}}

需要注意,每次在加载新页面的时候,都需要先运行onload方法加载一些初始的配置。如这里通过 .Xcall 函数获取函数中定义的表头元素,并将其绑定在页面元素#goods_sell_list中。

java创建Java实体类,并交给系统容器中管理

@IoC
public class PurchaseApplyEntry
{@InjectPurchaseApplyService purchaseApplyService;/*** 查询采购申请单明细*/@Export@Columns("(purchase_apply_no,申请单号)(status,状态)(creator_id,申请人)(warehouse_id,仓库)(main_remark,主单备注)(expected_time,期望到货时间)(modified,修改时间)(created,创建时间)(goods_name,货品名称)(goods_no,货品编号)(short_name,货品简称)(spec_name,规格名称)(spec_no,商家编码)(provider_id,供应商)(num,申请采购数量)(ref_num,已引用数量)(detail_remark,明细备注)")@BindAttributes("rec_id,brand_id,class_id,apply_id")@Transforms("(status,purchaseapply_status)(num,goods_count)(ref_num,goods_count)")@ServerTransforms("warehouse_name(warehouse_id<),employee_name(creator_id<),provider_name(provider_id<),goods_brand(brand_id<),goods_class(class_id<)")public Response queryApplyDetail(Session session, Map<String, Object> params, Pager pager) throws SQLException{return purchaseApplyService.queryApplyDetail(session, params, pager);}

这是一个 Java 类。它使用了一些注解,如 @IoC 和 @Inject,这表明它可能与一个依赖注入框架(如Spring)相关联,用于管理对象之间的依赖关系和实例化。以下是这个类的一些关键部分和功能的解释:

1、@IoC注解: 这个注解通常用于表示该类是一个由依赖注入容器管理的组件,容器会负责实例化和维护该类的对象。
2、@Inject’注解: 这是一种依赖注入的注解,用于注入PurchaseApplyService’类的实例到purchaseApplyService'字段中。
3、queryApplyDetai方法: 这个方法用于查询采购申请单明细。它接受一个会话(Session) 对象、参数(params) 和一个分页器 (Pager) 作为输入,并返回一个Response’对象。具体的功能包括:3.1、使用@Export注解定义了查询返回的列,以及这些列在查询结果中的显示名使用~@BindAttributes*注解定义了一些属性,如 rec_id’、brand_idclass_idapply_id'3.2、使用@Transforms注解定义了一些列的转换,将查询结果中的列进行重命名或转换成其他列。3.3、使用ServerTransforms注解定义了一些服务端转换,可能用于获取与仓库、创建者、供应商、品牌等相关的信息。3.4、调用purchaseApplyService.queryApplyDetail’方法,将输入的参数传递给该方法然后返回方法的结果。

设计采购申请单明细表service层的页面逻辑

public Response queryApplyDetail(Session session, Map<String, Object> params, Pager pager) throws SQLException{DbSession db = session.db(false);Where where = new Where(params, session){{equal("warehouse_id", "pa.warehouse_id");equal("purchase_apply_no", "pa.purchase_apply_no");equal("spec_no", "gs.spec_no");equal("goods_no", "gg.goods_no");equal("creator_id", "pa.creator_id");like("remark", "pad.remark");equal("provider_id", "pad.provider_id");in("status", "pa.status");condition("pad.real_num > pad.ref_num");}}.orderBy("pad.apply_id");Table table = new Table("purchase_apply_detail pad", "pad.rec_id", where){{innerJoin("purchase_apply pa", "pa.rec_id = pad.apply_id", "pa.,pad.");innerJoin("goods_spec gs", "gs.spec_id = pad.spec_id", "gs.,gg.");innerJoin("goods_goods gg", "gg.goods_id = gs.goods_id", "gg.");}}.extraJoin("purchase_apply pa", "pa.rec_id = pad.apply_id").extraJoin("goods_spec gs", "gs.spec_id = pad.spec_id").extraJoin("goods_goods gg", "gg.goods_id = gs.goods_id");String fields = "pad.rec_id, pa.rec_id AS apply_id, pa.purchase_apply_no, pa.status, pa.creator_id, pa.warehouse_id, pa.remark AS main_remark, pa.expected_time, pa.modified, pa.created, "+ " gg.goods_name, gg.goods_no, gg.short_name, gg.class_id, gg.brand_id, gs.spec_name, gs.spec_no, pad.num, pad.ref_num, pad.remark AS detail_remark, pad.provider_id";table.setOutputFields(fields);return SqlUtils.pageQuery(db, pager, table, where);}

此处需要注意,我们使用了inner join来根据页面填写的信息过滤所需要的采购申请单明细。使用了extra Join作为外连接,来补充展示除了采购申请表明细中的别的信息,如商品id。下图是整个表的关系图
在这里插入图片描述
下图为分别输入单品id和货品id的结果。可以看到,如果添加了单品信息,因为该信息在pad表中能找到,所以在innerjoin中就不会进行对gg和gs的连表。如果添加了商品查询条件,就会触发gg和gs的连表。
在这里插入图片描述在这里插入图片描述
以上采购申请单明细账任务结束。

第二个功能:采购申请单汇总账编写

功能说明:编写采购申请单汇总页面,用于展示以单品为维度的汇总信息
要求:
编写采购申请单汇总账页面
具备针对申请单、货品、单品的常用查询条件,可参考采购申请单管理页面
具备创建时间搜索条件,默认值设置为最近7天
具备申请数量汇总,已引用量汇总,编辑中数量汇总,待确认数量汇总,单据数量汇总列

汇总账c#代码

[Window(Title="采购申请单汇总账", View="statistic/sta_purchase/purchase_apply_collect.html", Style=Style.WS_VISIBLE|Style.WS_CHILD|Style.WS_CLIPCHILDREN, Width=960, Height=640)]public class PurchaseApplyCollectWindow : BaseWindow<Object>{Dictionary<string, string> custHeaders=null;public PurchaseApplyCollectWindow(){}// OnLoad() 方法在窗口加载完成后被调用,可以用来执行一些初始化操作或加载数据。protected override void OnLoad(){// 将建单日期初始化为当日DateTime currDate = DateTime.Now;DateTime preDate = currDate.Subtract(TimeSpan.FromDays(7));var fromDate = preDate.ToString("yyyy-MM-dd hh:mm:ss");var endDate = currDate.ToString("yyyy-MM-dd hh:mm:ss");Q("#start_date").SetValue(fromDate);Q("#end_date").SetValue(endDate);// 在窗口加载完成后,加载表头custHeaders = ControlUtils.LoadCustomPropName(this, CustomAttrType.PURCHASE_GOODS_PROP, "prop", "");Q("#goods_sell_list").Xcall("attach2", "statistic.PurchaseStatistic.purchaseApplyCollectBySpec", custHeaders);}// 搜索按钮被单击时的回调函数[Click("#btn_search")]void OnClickSearch(){// 当前实例对象中匹配选择器".flat_bar"的元素转换为查询参数形式。var queryParams = this.ToQueryParam(".flat_bar");Q("#goods_sell_list").DbPageBind2("statistic.PurchaseStatistic.purchaseApplyCollectBySpec", custHeaders, queryParams);}}

解释:
1、OnLoad() 方法在窗口加载完成后被调用,可以用来执行一些初始化操作或加载数据(这里设置页面属性的开始时间为距今天7天以前,结束时间为当前时间)
2、在窗口加载完成后,加载表头。通过Xcall绑定后端statistic.PurchaseStatistic.purchaseApplyCollectBySpec方法定义的表头
3、设计搜索按钮被单击时的回调函数。当前实例对象中匹配选择器".flat_bar"的元素转换为查询参数形式,通过DbPageBind2将其传入到purchaseApplyCollectBySpec方法中,并将结果保存在页面元素#goods_sell_list中

汇总账java代码

@Export@Columns("(spec_name, 单品名称)(spec_code, 规格码)(spec_no, 商家编码)(goods_no, 货品编号)(goods_name, 货品名称)(sum_num, 申请数量)(ref_sum_num, 引用数量)(editing_num, 编辑中数量)(noConfirm_num, 待确认数量)(apply_num, 单据数量)(class_name, 分类)(brand_name, 品牌)")@Transforms("(sum_num,goods_count)(ref_sum_num,goods_count)(noConfirm_num,goods_count)(editing_num,goods_count)")@ServerTransforms("goods_class(class_id+class_name),goods_brand(brand_id+brand_name)")public Response purchaseApplyCollectBySpec(Session session, Map<String, Object> params, Pager pager)throws SQLException, AppException{return purchaseStatisticService.purchaseApplyCollect(session, params, pager);}
public Response purchaseApplyCollect(Session session, Map<String, Object> params, Pager pager) throws SQLException{DbSession db = session.db(false);Where where = new Where(params, session){{// 根据申请单号搜索equal("purchase_apply_no", "pa.purchase_apply_no");// 根据申请单状态搜索equal("status", "pa.status");// 根据货品编号搜索equal("goods_no", "gg.goods_no");// 根据单品编号搜索equal("spec_id", "pad.spec_id");// 根据申请人ID搜索equal("creator_id", "pa.creator_id");// 根据商家编码搜索equal("spec_no", "gs.spec_no");// 根据货品简称搜索(考虑需求。考虑是否需要模糊查询)equal("short_name", "gg.short_name");// 根据单品名称搜索equal("spec_name", "gs.spec_name");// 根据期望到货日期搜索dateBetween("excepted_begin", "excepted_end", "pa.expected_time");// 根据申请日期搜索dateBetween("create_begin", "create_end", "pad.created");// 根据仓库搜索equal("warehouse_id", "pa.warehouse_id");}}.groupBy("pad.spec_id").orderBy("pad.spec_id");String innerFields = "pad.spec_id,IFNULL(SUM( pad.num ),0) AS sum_num, IFNULL(SUM( pad.ref_num ),0) AS ref_sum_num, sum(if(pa.status='10', pad.num, 0)) as editing_num, sum(if(pa.status='20',pad.num, 0)) as noConfirm_num, count(*) as apply_num";// 没有用的表不要连接Table table = new Table("purchase_apply_detail pad", innerFields, where){{innerJoin("purchase_apply pa", "pad.apply_id = pa.rec_id", true);innerJoin("goods_spec gs", "pad.spec_id = gs.spec_id", "gs.,gg.");innerJoin("goods_goods gg", "gs.goods_id = gg.goods_id", "gg.");}}.extraJoin("goods_spec gs", "tmp.spec_id = gs.spec_id").extraJoin("goods_goods gg", "gs.goods_id = gg.goods_id");// 返回的列中,第一个要是能唯一标识一条记录的列String fields = "gs.spec_id, gs.goods_id, gs.spec_no , gs.spec_code , gs.provider_id , gs.barcode , gs.spec_name , gs.wms_process_mask , gs.is_not_need_examine , gs.goods_label, gs.prop1,  gs.prop2," + "gg.goods_type , gg.goods_no , gg.goods_name , gg.short_name , gg.alias , gg.spec_count , gg.class_id , gg.brand_id,";fields += "sum_num, ref_sum_num, editing_num, noConfirm_num, apply_num";table.setOutputFields(fields);return SqlUtils.pageQuery(db, pager, table, where);}

总的来说,这个就是根据输入条件信息,对数据库做一个查询操作,并通过pageQuery函数分页展示结果

至此,两个界面的创建任务完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/156686.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2021年09月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 使用map函数可以实现列表数据元素类型的转换&#xff0c;而无需通过循环。则将列表L[‘1’,‘3’,‘5’,‘7’,‘9’]转…

如何创建 SpringBoot 多模块项目

1. 创建父模块 【添加依赖】 【删除父模块资源】 父模块只需要保留 pom.xml&#xff0c;其他文件的全部删除&#xff08;包括 src&#xff09; 2. 创建子模块 3. 修改父模块 3.1 删除不必要的依赖 3.2 添加打包类型 3.3 添加所有子模块 声明子模块有两个好处&#xff1a; …

企业链表(未完成)

文章目录 1. 插入2. 类型转换说明2. 代码实现 1. 插入 // 插入 void insert(LinkList* list, int pos, LinkNode* data) {if (!list || !data)return;if (pos < 0 || pos > list->size)return;LinkNode* curNode &(list->head);for (int i 0; i < pos; i)…

Mac 配置环境变量

Mac 配置环境变量 修改配置文件 vim ~/.bash_profile i进入编辑模式. Esc&#xff1a;wq 保存文件 esc:q 退出 如&#xff1a;jdk环境变量配置 JAVA_HOME/Library/Java/JavaVirtualMachines/jdk1.8.0_361.jdk/Contents/HomeCLASSPATH$JAVA_HOME/lib/tools.jar:$JAVA_HOME/…

目标检测 图像处理 计算机视觉 工业视觉

目标检测 图像处理 计算机视觉 工业视觉 工业表盘自动识别&#xff08;指针型和数值型&#xff09;智能水尺识别电梯中电动车识别&#xff0c;人数统计缺陷检测&#xff08;半导体&#xff0c;电子元器件等&#xff09;没带头盔检测基于dlib的人脸识别抽烟检测和睡岗检测/驾驶疲…

GAMP源码阅读:卫星位置钟差计算

原始 Markdown文档、Visio流程图、XMind思维导图见&#xff1a;https://github.com/LiZhengXiao99/Navigation-Learning 文章目录 1、satposs_rtklib()2、ephclk()1. eph2clk()&#xff1a;时钟校正参数&#xff08; a f 0 、 a f 1 、 a f 2 a_{f0}、a_{f1}、a_{f2} af0​、af…

vim

简介 vim是一款多模式的文本编辑器&#xff0c;vim里面还有很多子命令&#xff0c;来进行代码的编写操作 常用模式图 命令模式 光标移动 shif $ 光标定义到当前行的最右侧结尾 shift ^ 光标定义到当前行的最左侧开头 shift g 光标定位到文本最末尾…

怎样解决“缺失msvcp110.dll”错误,msvcp110.dll的修复教程

在计算机使用过程中&#xff0c;我们可能会遇到一些系统错误提示&#xff0c;比如“msvcp110.dll文件丢失”。这是因为msvcp110.dll是Microsoft Visual C 2012的一个动态链接库文件&#xff0c;如果这个文件丢失或者损坏&#xff0c;就可能导致某些程序无法正常运行。那么&…

stm32整理(三)ADC

1 ADC简介 1.1 ADC 简介 12 位 ADC 是逐次趋近型模数转换器。它具有多达 19 个复用通道&#xff0c;可测量来自 16 个外部 源、两个内部源和 VBAT 通道的信号。这些通道的 A/D 转换可在单次、连续、扫描或不连续 采样模式下进行。ADC 的结果存储在一个左对齐或右对齐的 16 位…

IT老鸟给开发者升职加薪的小技巧

前言&#xff1a; 升职加薪对大多数人来说都是工作重要动力所在&#xff0c;但总存在“青出于蓝而胜于蓝”&#xff0c;后来人居上的情况。很多人不清楚&#xff0c;自己兢兢业业&#xff0c;任劳任怨&#xff0c;到头来还是得不到领导的重视&#xff0c;身边一起过来的同事都成…

算法笔记【6】-简单选择排序算法

文章目录 一、基本原理二、实现步骤三、优缺点分析 一、基本原理 在排序算法中&#xff0c;简单选择排序是一种基本且直观的排序方法。尽管它的性能较冒泡排序稍好&#xff0c;但仍然属于较慢的排序算法。本文将详细介绍简单选择排序算法的原理、步骤&#xff0c;并讨论其优缺…

C++之string

C之string #include <iostream>using namespace std;/*string();//创建一个空的字符串string(const char* s);//使用字符串s初始化string(const string& str);//使用一个string对象初始化另外一个string对象string(int n,char c);//使用n个字符c初始化*/void test1()…