2014年团队项目总结
在开始之前,送大家我收藏的几句话,希望对大家有用:
总有一天你将破蛹而出,成长得比人们期待的还要美丽。
但这个过程会很痛,会很辛苦,有时候还会觉得灰心。
面对着汹涌而来的现实,觉得自己渺小无力。
但这,也是生命的一部分。做好现在你能做的,然后,一切都会好的。
我们都将孤独地长大,不要害怕。
时光马上就要临近毕业了,我最想说的一句话就是:“在南方,我深爱过,奋战过,我的青春无悔”。 两年下来,大大小小的项目都做过,一学期的C#图书管理系统,二学期的飞机订票系统,二学年的个人项目餐饮管理系统,以及团队项目服装专卖网站。这些的一切,都来源自身曾今努力的付出,还有我最想对大家说的就是:一个好的项目,离不开一个团结高效的合作团队,希望已经进入公司当程序员的你或者即将毕业的你,都要正确认识团队,发挥自己的光芒。好了,废话就不多说了,接下来进行我们团队项目中的核心讲解。
MVC开发模式基本结构:
SSH 包:
EasyUI引入:
图表插件:
OK,基本结构是这样子的,
首先后台要讲到的就是商品页面。我们的后台是用的EasyUI插件。待会会细细讲到。
正是如图所示,左边是菜单栏,点击后,容器中相当于打开了一个新的选项卡,实际上就是另外一个页面。该布局采取传统项目中的常用布局方式,上下左右。不过,你所看到的商品的布局,我是看了朋友圈后突然来的一个灵感。右侧是服装类型的树,别看结构复杂,其实设计的就是一张表。采用递归方式进行显示。
树递归代码如下所示:
//加载树
public ArrayList<TreeBean> findTree(String pid) {
ArrayList<TreeBean> typeList = new ArrayList();
log.debug("finding all Ptype instances");
try {
String queryString = " select new map(ptid as ptid,typeId as typeId, typeName as typeName,typePid as typePid) from Ptype p where p.typePid=:pid";
Query q = getSession().createQuery(queryString).setParameter("pid", pid);
List<Map> list = q.list();
if ((list != null) || (list.size() != 0)){
for (Map map : list) {
TreeBean tb = new TreeBean();
tb.setPtid(Integer.valueOf(Integer.parseInt(map.get("ptid").toString())));
tb.setId(map.get("typeId").toString());
tb.setPid(map.get("typePid").toString());
tb.setText(map.get("typeName").toString());
tb.setChildren(findTree(map.get("typeId").toString().trim()));//递归调用传入id继续查找该阶段的子节点。
typeList.add(tb);
}
}
} catch (RuntimeException re) {
log.error("find all failed", re);
throw re;
}
return typeList;
}
点击后,弹出以下框:
$('#win_product').window({title:'修改商品信息',
width:800,
height:500,
modal:true ,
iconCls:'icon-save',
href:'upload.jsp?pid='+pid+'&size='+size
});
多文件文件上传:
页面上传的表单标签:
<form method="post" id="manyPics" action="uploadAction_uploadImg" name="manyPics" enctype="multipart/form-data" >
<input type="hidden" name="r.p.pid" value="${param.pid}">
<input type="hidden" name="r.color.cname" id="pcolor">
<input class="text" type="file" onchange="prevImages(this,'pics')" id="goodsDetaidImg" style="display:none" name="goodsImg" multiple="multiple"/>
</form>
//上传图片,预览等--------------
function startUpload(){
$("#pcolor").val($("#colorSelect").val());
$("#manyPics").submit();
}
var uploadImgArr = [];
//防止图片上传完成后,再点击上传按钮的时候重复上传图片
var isUpload = false;
//获取图片的大小、名称予以显示,这里还可以显示图片的文件类型
function showFileInfo(file,divPreviewId) {
var fileName = file.name;
var file_typename = fileName.substring(fileName.lastIndexOf('.'), fileName.length);
if (file) {
var fileSize = 0;
if (file.size > 1024 * 1024){
fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
}else{
fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
}
document.getElementById(divPreviewId+"Name").innerHTML = '文件名: ' + file.name;
document.getElementById(divPreviewId+"Size").innerHTML = '图片大小: ' + fileSize;
document.getElementById(divPreviewId+"Name").style.display="block";
document.getElementById(divPreviewId+"Size").style.display="block";
document.getElementById(divPreviewId+"De").style.display="block";
}
}
//清空队列及html中的内容
function qingkongImg(){
var c=uploadImgArr.length;
for(var j=c-1;j>=0;j--){
uploadImgArr.splice(j,1);
}
$("#pics").html("");
$("#preImgDiv1").html("");
}
//多张上传
var index =0;
function prevImages(fileObj,divPreviewId){
var allowExtention=".jpg,.bmp,.gif,.png";//允许上传文件的后缀名document.getElementById("hfAllowPicSuffix").value;
var extention=fileObj.value.substring(fileObj.value.lastIndexOf(".")+1).toLowerCase();
var browserVersion= window.navigator.userAgent.toUpperCase();
if(true){
if(fileObj.files){//兼容chrome、火狐7+、360浏览器5.5+等,应该也兼容ie10,HTML5实现预览
if(window.FileReader){
var isUpload = false;
for (var i = 0,f; f = fileObj.files[i]; i++) {
//console.log(f);
uploadImgArr.push(f);
var reader = new FileReader();
//类似于原生JS实现tab一样(闭包的方法),参见http://www.css119.com/archives/1418
reader.onload = (function(file) {
//获取图片相关的信息
var fileSize = (file.size / 1024).toFixed(2) + "K",
fileName = file.name,
fileType = file.type;
//console.log(fileName)
return function(e) {
//console.log(e.target)
//获取图片的宽高
var img = new Image();
img.addEventListener("load", imgLoaded, false);
img.src = e.target.result;
function imgLoaded() {
imgWidth = img.width;
imgHeight = img.height;
//图片加载完成后才能获取imgWidth和imgHeight
var h = "<table class='picsContainer' id="+divPreviewId+index+" οnclick='ChangeBorder(\""+divPreviewId+index+"\")' style='width:220px;height:105px;margin-left:10px;border:1px solid #DDDDDD;float:left;margin-bottom: 5px;'>"+
"<tr>"+
"<td rowspan='2'><img width=80 height=80 src='"+e.target.result+"'/></td>"+
"<td>"+
"<p>文件名:"+fileName+"</p>"+
"<p>大小:"+fileSize+"</p>"+
"<p><a href='javaScript:void()' οnclick='deletePic2("+index+",\""+divPreviewId+index+"\")'>删除</a></p>"+
"</td>"+
"</tr>"+
"</table>";
$("#"+divPreviewId).append(h);
$("#"+divPreviewId+index).addClass("start1");
index++;
}
};
})(f);
//读取文件内容
reader.readAsDataURL(f);
}
}else if(browserVersion.indexOf("SAFARI")>-1){
alert("不支持Safari浏览器6.0以下版本的图片预览!");
}
}
}else{
alert("仅支持"+allowExtention+"为后缀名的文件!");
fileObj.value="";//清空选中文件
if(browserVersion.indexOf("MSIE")>-1){
fileObj.select();
document.selection.clear();
}
fileObj.outerHTML=fileObj.outerHTML;
}
}
//删除单个图片
function deletePic2(index,id){
uploadImgArr.splice(index,1);
$("#"+id).remove();
}
//改变边框效果
function ChangeBorder(id){
var s=$("#pics .start1");
for(var i=0;i<s.length;i++){
$(s[i]).removeClass("light1");
$(s[i]).css("border","1px solid #DDDDDD");
} //清空颜色,样式
$("#"+id).addClass("light1");
$("#"+id).css("border","1px solid #3FBFFF");
}
fileUploadAction类:
public class UploadAction {
private Productimage r;
private ProductImageService pis;
private String filePosition;
private File[] goodsImg;
private String[] goodsImgFileName;
private String[] goodsImgContentType;
public String uploadImg() {
String path = ServletActionContext.getServletContext().getRealPath(
"/pages/images/" + this.filePosition);
if (this.goodsImg != null) {
List paths = new ArrayList();
for (int i = 0; i < this.goodsImg.length; i++) {
String goodsNum = Util.getGoodsImgNum();
int point = this.goodsImgFileName[i].lastIndexOf(".");
String hz = this.goodsImgFileName[i].substring(point,this.goodsImgFileName[i].length());
String detialPath = path + "/" + goodsNum + i + hz;
try {
FileUtils.copyFile(this.goodsImg[i], new File(detialPath));
paths.add("images/" + this.filePosition + "/" + goodsNum+ i + hz);
} catch (IOException e) {
e.printStackTrace();
}
}
for (int i = 0; i < paths.size(); i++) {
this.r.setImgpathid((String) paths.get(i));
this.pis.savePimg(this.r);
}
}
return "main";
}
//get,set方法
............................此处省略。。
}
商品类型管理: 先贴图了
左边的是treegrid.对文件夹节点可进行邮件增加节点,对子节点可以进行删除节点。同时可以编辑,保存等。
<table id="clothType" title="" class="easyui-treegrid" style="height:500px"
data-options="
url: 'ptypeAction_loadPtype',
method: 'get',
rownumbers: true,
idField: 'id',
treeField: 'text',
fit:true,
animate: false,
collapsible: true,
onContextMenu: onContextMenu,
toolbar:'#clothType-tools',
onClickRow:typeRow
">
<thead>
<tr>
<th data-options="field:'text',halign:'center',editor:{
type:'text'}" width="300px">名称</th>
<th data-options="field:'ptid',hidden:true" width="30px" align="right">编号</th>
</tr>
</thead>
</table>
<!-- 右键的菜单:-->
<div id="mm" class="easyui-menu" style="width:120px;">
<div onclick="append()" data-options="iconCls:'icon-add'">添加</div>
<div onclick="removeIt()" data-options="iconCls:'icon-remove'">删除</div>
<div class="menu-sep"></div>
<div onclick="collapse()">收起</div>
<div onclick="expand()">展开</div>
</div>
脚本:
//---------左侧-----------
var editNode;
var beforeNode; //点完成取到编辑节点
// 编辑
function edit(){
var SelectNode = $('#clothType').treegrid('getSelected');
if($("#clothType").treegrid('getChildren',SelectNode.id).length==0){
$("#clothType").treegrid('beginEdit',SelectNode.id);
editNode=SelectNode.id;
beforeNode=SelectNode;
}else{
alert("sorry,this node can't be edit!");
}
}
//保存
function save(){
$("#clothType").treegrid('endEdit',editNode); $.post("ptypeAction_update",{"t.typeId":beforeNode.id,"t.typeName":beforeNode.text,"t.ptid":beforeNode.ptid,"t.typePid":beforeNode.pid},function(data){
$("#clothType").treegrid('reload');
});
}
//选中行--------------------------
function typeRow(row){
$("#ptid2,#ptid1").val("");
$("#clothType").treegrid('endEdit',editNode);
if($("#clothType").treegrid('getChildren',row.id).length==0){
$(".vtname").val(row.text);
$("#style_grid1").datagrid('load',{"ptid":row.ptid});
$("#ptid2,#ptid1").val(row.ptid);
}
}
//刷新
function reloadType(){
$("#clothType").treegrid('reload');
}
//类型品牌
function loadBrand(ptid){
var url = 'brandAction_findBrandType?ptid='+ptid;
$('#brandlist5').combobox('reload', url);
}
//----------左侧右键---------------
function onContextMenu(e,row){
e.preventDefault(); //阻止浏览器默认右键事件
$(this).treegrid('select', row.id);
//取得id : row.id
$('#mm').menu('show',{
left: e.pageX,
top: e.pageY
});
}
//添加
function append(){
var node = $('#clothType').treegrid('getSelected');
if($("#clothType").treegrid('getChildren',node.id).length!=0){ //判断是否叶子节点
$.post("ptypeAction_append",{"t.typeName":"新节点1","t.typePid":node.id},function(data){
$("#clothType").treegrid('reload');
});
}
}
//删除
function removeIt(){
var node = $('#clothType').treegrid('getSelected');
if (node){
$.post("ptypeAction_remove",{"ptid":node.ptid},function(){
$("#clothType").treegrid('reload');
});
}
}
//收起
function collapse(){
var node = $('#clothType').treegrid('getSelected');
if (node){
$('#clothType').treegrid('collapse', node.id);
}
}
//展开
function expand(){
var node = $('#clothType').treegrid('getSelected');
if (node){
$('#clothType').treegrid('expand', node.id);
}
}
//----------------------------------------------------------------------------------
右侧的分组的grid 要先下载一个插件:<script type="text/javascript" src="js/datagrid-groupview.js"></script>
<table id="style_grid1" class="easyui-datagrid" style="width:790px;height:480px;"
data-options="
url:'styleAction_loadBrandStyle',
groupField:'brandname',
toolbar:'#stylebar',
view:groupview,
groupFormatter:groupFormat
">
<thead>
<tr>
<th data-options="field:'styleid'" width="150px" align="center">系列编号</th>
<th data-options="field:'brandname'" width="120px" align="center">品牌</th>
<th data-options="field:'typeId',hidden:true" width="30px" align="center">类别编号</th>
<th data-options="field:'untilName',halign:'center'" align="center" width="80px">单位</th>
<th data-options="field:'pricefw'" width="100px" align="center">价格适用范围</th>
<th data-options="field:'seasonId'" width="100px" align="center">适用季节</th>
<th data-options="field:'typeName'" width="100px" align="center">类别名</th>
<th data-options="field:'description'" width="100px" align="center">操作</th>
</tr>
</thead>
</table>
<!-- 工具条 -->
<div id="stylebar" style="padding-top:0px;">
<a href="javascript:void(0)" class="easyui-linkbutton" plain="true" iconCls="icon-add" onclick="showBrandStyleDialog()">添加品牌系列</a>
<a href="javascript:void(0)" class="easyui-linkbutton" plain="true" iconCls="icon-add" onclick="showBrandTypeDialog()">添加服装品牌</a>
</div>
//格式化分组
function groupFormat(value,rows){
return value + ' - ' + rows.length + '项';
}
统计图:说到统计图,心情忒激动,先贴图了。
<center>
<s:action name="tongjiAction_monthSale"/>
<jsp:include page="Includes/FusionChartsHTMLRenderer.jsp" flush="true">
<jsp:param name="chartSWF" value="FusionCharts/Line.swf" />
<jsp:param name="strURL" value=""/>
<jsp:param name="strXML" value="${session.strXML}" />
<jsp:param name="chartId" value="MyFirst" />
<jsp:param name="chartWidth" value="850" />
<jsp:param name="chartHeight" value="400" />
<jsp:param name="debugMode" value="false" />
</jsp:include>
</center>
/*---------------加载月销售统计表-----------------*/
public void monthSale()throws Exception {
List<Object[]> list=ts.monthSale(testYear(year));
Object monthsMoney[]={0,0,0,0,0,0,0,0,0,0,0,0}; //12个月的销售额
String strXML = "<chart caption='"+testYear(year)+"年度服装各个月份销售统计' xAxisName='月份' yAxisName='月份销售额' yAxisMinValue='15000' numberPrefix='$' showValues='0' alternateHGridColor='FCB541' alternateHGridAlpha='20' divLineColor='FCB541' divLineAlpha='50' canvasBorderColor='666666' baseFontColor='666666' lineColor='FCB541'>";
//初始化数据
for (int i = 0; i < list.size(); i++) {
monthsMoney[Integer.parseInt(list.get(i)[0].toString())-1]=list.get(i)[1];
}
//赋值
for (int k = 0; k < monthsMoney.length; k++) {
strXML+="<set label='"+(k+1)+"月' value='"+monthsMoney[k]+"'/>";
}
strXML+="<styles>"+
"<definition>"+
"<style name='Anim1' type='animation' param='_xscale' start='0' duration='1'/>"+
"<style name='Anim2' type='animation' param='_alpha' start='0' duration='0.6'/>"+
"<style name='DataShadow' type='Shadow' alpha='40'/>"+
"</definition>"+
"<application>"+
"<apply toObject='DIVLINES' styles='Anim1'/>"+
"<apply toObject='HGRID' styles='Anim2'/>"+
"<apply toObject='DATALABELS' styles='DataShadow,Anim2'/>"+
"</application>"+
"</styles>"+
"</chart>";
ActionContext context=ActionContext.getContext();
context.getSession().put("strXML",strXML);
}
<center>
<s:action name="tongjiAction_brandSale"/>
<jsp:include page="Includes/FusionChartsHTMLRenderer.jsp" flush="true">
<jsp:param name="chartSWF" value="FusionCharts/MSLine.swf" />
<jsp:param name="strURL" value=""/>
<jsp:param name="strXML" value="${session.strXML2}" />
<jsp:param name="chartId" value="MyFirst2" />
<jsp:param name="chartWidth" value="850" />
<jsp:param name="chartHeight" value="400" />
<jsp:param name="debugMode" value="false" />
</jsp:include>
</center>
/*---------------加载品牌所对应的统计表-----------------*/
public void brandSale() {
List<Object[]> list=ts.brandSale(testYear(year));
String strXML = "<chart caption='"+testYear(year)+"年,各品牌各月的销售统计' lineThickness='1' showValues='0' formatNumberScale='0' anchorRadius='2' divLineAlpha='20' divLineColor='CC3300' divLineIsDashed='1' showAlternateHGridColor='1' alternateHGridAlpha='5' alternateHGridColor='CC3300' shadowAlpha='40' labelStep='2' numvdivlines='5' chartRightMargin='35' bgColor='FFFFFF,CC3300' bgAngle='270' bgAlpha='10,10'>";
strXML+="<categories>";
for (int i = 1; i <= 12; i++) {
strXML+="<category label='"+i+"月'/>";
}
strXML+="</categories>";
String colors[]={"1D8BD1","F1683C","2AD62A","DBDC25","c0c0c0","F1683C","2AD62A","DBDC25"}; //几种品牌就几种颜色
//每一种品牌各个月所对应的销售额
List<String> brandNamelist=bs.findBrandName(); //取得品牌的名字
for (int b= 0; b < brandNamelist.size(); b++) {
//初始化数据
Object brandMonthsMoney[]={0,0,0,0,0,0,0,0,0,0,0,0}; //默认该品牌12个月销售额都是0
for (int i = 0; i < list.size(); i++) {
if(list.get(i)[0].toString().equals(brandNamelist.get(b))){ //同一品牌
brandMonthsMoney[Integer.parseInt(list.get(i)[1].toString())-1]=list.get(i)[2];
}
}
strXML+="<dataset seriesName='"+brandNamelist.get(b)+"' color='"+colors[b]+"' anchorBorderColor='"+colors[b]+"' anchorBgColor='"+colors[b]+"'>";
for (int k = 0; k < 12; k++) {
strXML+="<set value='"+brandMonthsMoney[k]+"'/>";
}
strXML+="</dataset>";
}
//样式
strXML+="<styles>"+
"<definition>"+
"<style name='CaptionFont' type='font' size='12'/>"+
"</definition>"+
"<application>"+
"<apply toObject='CAPTION' styles='CaptionFont'/>"+
"<apply toObject='SUBCAPTION' styles='CaptionFont'/>"+
"</application>"+
"</styles>"+
"</chart>";
ActionContext content = ActionContext.getContext();
content.getSession().put("strXML2", strXML);
}
<center>
<s:action name="tongjiAction_seasonSale"/>
<jsp:include page="Includes/FusionChartsHTMLRenderer.jsp" flush="true">
<jsp:param name="chartSWF" value="FusionCharts/MSColumn3D.swf" />
<jsp:param name="strURL" value=""/>
<jsp:param name="strXML" value="${session.strXML3}" />
<jsp:param name="chartId" value="MyFirst3" />
<jsp:param name="chartWidth" value="850" />
<jsp:param name="chartHeight" value="400" />
<jsp:param name="debugMode" value="false" />
</jsp:include>
</center>
/*---------------加载年份的季度所对应的统计表-----------------*/
public void seasonSale() throws Exception {
String strXML="<chart caption='近3年得季度销售统计' shownames='1' showvalues='0' decimals='2' numberPrefix='$'>"+
"<categories>"+
"<category label='一季度'/>"+
"<category label='二季度'/>"+
"<category label='三季度'/>"+
"<category label='四季度'/>"+
"</categories>";
List<Object[]> list=ts.seasonSale(testYear(year));
int seasonStr[]={testYear(year)-2,testYear(year)-1,testYear(year)}; //年份
String colors[]={"AFD8F8","F6BD0F","8BBA00"};
for (int i = 0; i < seasonStr.length; i++) { //要找的年份
Object seasonsMoney[]={0,0,0,0};
for (int j = 0; j < list.size(); j++) {// list 中找该年的
if(Integer.parseInt(list.get(j)[0].toString())==seasonStr[i]){ //同年
seasonsMoney[Integer.parseInt(list.get(j)[2].toString())-1]=list.get(j)[1];
}
}
strXML+="<dataset seriesName='"+seasonStr[i]+"年' color='"+colors[i]+"' showValues='0'>";
for (int k = 0; k < seasonsMoney.length; k++) {
strXML+="<set value='"+seasonsMoney[k]+"'/>";
}
strXML+="</dataset>";
}
strXML+="</chart>";
ActionContext content = ActionContext.getContext();
content.getSession().put("strXML3", strXML);
}
看完之后,是不是觉得好牛哈,哈哈,不急,在贴代码之前,我先介绍下这个图标插件,FunishChart .这款插件简单,很方便,可以通过javascript 返回数据成图。还可用一个xml来生成一个图表,不过我是结合了两者的特性,从后台返回xml 的字符串json.
先看看页面代码吧:
<center>
<s:action name="tongjiAction_typeSale"/>
<jsp:include page="Includes/FusionChartsHTMLRenderer.jsp" flush="true">
<jsp:param name="chartSWF" value="FusionCharts/Pie3D.swf" />
<jsp:param name="strURL" value=""/>
<jsp:param name="strXML" value="${session.strXML4}" />
<jsp:param name="chartId" value="MyFirst4" />
<jsp:param name="chartWidth" value="850" />
<jsp:param name="chartHeight" value="400" />
<jsp:param name="debugMode" value="false" />
</jsp:include>
</center>
/*---------------某年各个品牌的-----------------*/
public void typeSale() throws Exception {
List list=ts.typeSale(testYear(year));
String strXML="<chart palette='4' caption='"+testYear(year)+"本店服装类型销售情况' decimals='2' enableSmartLabels='1' enableRotation='0' bgColor='99CCFF,FFFFFF' bgAlpha='40,100' bgRatio='0,100' bgAngle='360' showBorder='1' startingAngle='70'>";
for (int i = 0; i < list.size(); i++) {
strXML+="<set label='" + ((java.lang.Object[])list.get(i))[0] + "' value='" + ((java.lang.Object[])list.get(i))[1] + "'/>";
}
//isSliced='1' 分割开来的效果
strXML+="</chart>";
ActionContext content = ActionContext.getContext();
content.getSession().put("strXML4", strXML);
}
//统计查询语句:这可以葵花宝典哦。
--品牌各个月份的统计
Select max(bname),nvl(to_char(saledate,'mm'),0) m,sum(money) from (
select st.saledate as saledate, b.brandname as bname,b.brandid as brandid ,nvl(SALETOTAL,0) money from (
select s.saledate as saledate, d.saletotal as saletotal,t.brandid as brandid from sale s join saledetailed d on s.saleid=d.sal_saleid join product p
on p.pid=d.pid join style t on p.styleid=t.styleid
where extract(year from s.saledate)=2014
) st right join brand b on st.brandid=b.brandid ) q group by q.brandid,to_char(saledate,'mm')
--某年各个月的销售统计
select to_char(saleDate,'mm') 月,sum(saleTotal) 总销售额 from sale
where to_char(saleDate,'yyyy')=2014 group by to_char(saleDate,'mm')
--分类统计
select max(tname) yf,sum(money) sl from (
select pt.type_Name tname,pt.ptid as ptid ,nvl(SALETOTAL,0) money from (
select d.saletotal as saletotal,t.ptid as ptid from sale s join saledetailed d on s.saleid=d.sal_saleid join product p
on p.pid=d.pid join style t on p.styleid=t.styleid
where extract(year from s.saledate)>2011
) st right join ptype pt on st.ptid=pt.ptid ) q where (tname!='服装' and tname!='鞋子' and tname!='上衣' and tname!='裤子' and tname!='裤装'and tname!='裙装' )
group by q.ptid
--季度 统计
select to_char(saleDate,'yyyy') 年,sum(saleTotal) 总销售金额,
case when to_char(saleDate,'mm') in (1,2,3) then 1
when to_char(saleDate,'mm') in (4,5,6) then 2
when to_char(saleDate,'mm') in (7,8,9) then 3
when to_char(saleDate,'mm') in (10,11,12) then 4 end 季度
from sale where
extract(year from saledate) between 2014-3 and 2014
group by case when to_char(saleDate,'mm') in (1,2,3) then 1
when to_char(saleDate,'mm') in (4,5,6) then 2
when to_char(saleDate,'mm') in (7,8,9) then 3
when to_char(saleDate,'mm') in (10,11,12) then 4 end,to_char(saleDate,'yyyy')
order by to_char(saleDate,'yyyy') asc;
后台订单操作:
点击订单,就能展开看到那条订单所包含的商品明细。这里需要下载一个插件,通常的datagrid 是没有展开的。
<script type="text/javascript" src="js/datagrid-detailview.js"></script>
<table id="sale_table" class="easyui-datagrid" title="订单管理" style="width:1000px;height:470px"
data-options="
fit:true,
collapsible:true,
method:'post',
singleSelect:true,
rownumbers:true,
pageSize:10,
pageNumber:1,
toolbar:'#salework',
showFooter: true,
pagination:true,
pageList:[10,13,16],
onRowContextMenu:fahuoContextMenu,
striped:true">
</table>
//下面是脚本代码,所标红色字体为展开的核心代码。
loadSaleDate('saleAction_saleAll?methods=100');
function loadSaleDate(url){
$("#sale_table").datagrid({
url:url,
columns:[[
{field:'saleid',width:110,align:'left',title:'订单号',formatter: function(value,row,index){
if(row.isgive==2)
return '<span style="text-decoration: line-through;" >'+value+'</span>';
else
return value;
}
},
{field:'saleamout',width:50,align:'center',title:"销售数量"},
{field:'saletotal',width:75,align:'center',halign:'center',title:"合计金额"},
{field:'saledate',width:100,align:'center',halign:'center',title:"消费日期",formatter:function timeformat(val,row,index){
var date = new Date(val);
return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() +' '+date.getHours()+':'+date.getMinutes();
}},
{field:'vipid',width:70,align:'center',halign:'center',title:"会员编号"},
//{field:'eid',width:70,align:'center',halign:'center',title:"员工编号"},
{field:'paystatu',width:70,align:'center',halign:'center',title:"付款状态",
formatter: function(value,row,index){
if (row.paystatu==0){
return "未付款";
} else {
return "已付款";
}
}
},
{field:'isback',width:70,align:'center',halign:'center',title:"退货状态",
formatter: function(value,row,index){
if (row.isback==0){
return "无";
} else if(row.isback==1){
return "申请退货";
} else{
return "同意退货";
}
}
},
{field:'isdelete',width:70,align:'center',halign:'center',title:"回收站状态"},
{field:'isgive',width:80,align:'center',halign:'center',title:"发货状态",
formatter: function(value,row,index){
if (row.isgive==0){
return "待发货";
} else if(row.isgive==1){
return "已发货";
} else{
return "确认收获";
}
}
},
{field:'addr',width:212,align:'left',halign:'center',title:"收货地址"},
{field:'people',width:60,align:'center',halign:'center',title:"收货人"},
{field:'phone',width:100,align:'center',halign:'center',title:"手机号码"},
]],
rowStyler: function(index,row){
if (row.isgive==0){
return 'color:red;'; //background-color:#FEEEBD;
}else if(row.isgive==2){
return 'color:green;'; //background-color:#EFEFEF;
}else{
return 'color:black;'; //background-color:#EDFCAD;
}
},
view: detailview,
detailFormatter:function(index,row){
return '<div style="padding:2px"><table class="ddv"></table></div>';
},
onExpandRow: function(index,row){
var ddv = $(this).datagrid('getRowDetail',index).find('table.ddv');
ddv.datagrid({
url:'saleAction_loadDetialSaleByid?saleid='+row.saleid,
fitColumns:true,
singleSelect:true,
rownumbers:true,
loadMsg:'',
height:'auto',
columns:[[
{field:'saledetailid',title:'编号',width:60,hidden:true},
{field:'pic',title:'商品图',align:'center',width:45,formatter://格式化日期,性别,金钱
function(val,row){
return '<img src="../pages/'+val+'" style="height:50px;width:50px;">';
}},
{field:'pname',title:'商品名',width:90,align:'center'},
{field:'discount',title:'折扣',width:30,align:'center'},
{field:'num',title:'数量',width:50,align:'center'},
{field:'price',title:'售价',width:50,align:'center'},
{field:'total',title:'总额',width:50,align:'center'}
]],
onResize:function(){
$('#sale_table').datagrid('fixDetailRowHeight',index);
},
onLoadSuccess:function(){
setTimeout(function(){
$('#sale_table').datagrid('fixDetailRowHeight',index);
},0);
}
});
$('#sale_table').datagrid('fixDetailRowHeight',index);
}
});
}
前台:
这个最新商品是用的加载xml数据。而xml数据是从资源文件中的记录日期来决定是否从数据库中从新读取一遍数据更新xml,而后的三天内的每次加载该页面都是从xml中直接读取数据,这样就节省了服务器资源。如果今天的日期到达资源文件的记录日期则进行再一次的查询到xml 中,同时更新资源文件的下一次的记录日期。
同时也是为了练习下javaWeb 中如何读取资源文件夹,java 如何读取xml 数据。 我这里用到的是dom4j-1.2-1.jar 来对xml 进行读写操作,在操作之前先把包放入lib文件夹下。
废话不多说了,为了大家都会读取xml,先把代码贴上。
以下是Action中的方法:
//写xml
private void writeXmlNewProduct(){
List<Object[]> list=ps.topFiveNewProduct();
String xmlPath = ServletActionContext.getServletContext().getRealPath("/pages/xml");
Document doc = DocumentHelper.createDocument(); //创建一个Document
Element root = doc.addElement("products");//添加根节点
for (int i = 0; i <list.size(); i++) {
Element product = root.addElement("product").addAttribute("pid", list.get(i)[1].toString());
Element pname = product.addElement("pname");
Element price1 = product.addElement("beforePrice");
Element price2 = product.addElement("nowPrice");
Element pic = product.addElement("pic");
pname.setText(list.get(i)[3].toString());
price1.setText(list.get(i)[10].toString());
price2.setText(list.get(i)[9].toString());
pic.setText(list.get(i)[6].toString());
}
try{
OutputFormat format = new OutputFormat("", true); //格式
format.setEncoding("UTF-8");
XMLWriter xmlWriter = new XMLWriter(new PrintWriter(xmlPath+"/newProduct.xml"), format);
xmlWriter.write(doc); //写入xml文件中
xmlWriter.close();
}catch(IOException e){
e.printStackTrace();
}
}
//读取xml
private void readXmlNewProduct() throws Exception{
SAXReader saxReader = new SAXReader(); //准备一个SAXReader读取器
String xmlPath = ServletActionContext.getServletContext().getRealPath("/pages/xml/newProduct.xml");
Document doc = null;
List<Map> listmap=new ArrayList<Map>();
try {
try {
FileInputStream in = new FileInputStream(new File(xmlPath));
Reader read = new InputStreamReader(in,"gbk"); //防止中午读取后乱码,所以转gbk格式
doc = saxReader.read(read); //读取文档
} catch (FileNotFoundException e) {
System.out.println(e);
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} catch (DocumentException e) {
System.out.println(e);
e.printStackTrace();
}
Element books = doc.getRootElement(); //获得文档的根节点
Iterator it = books.elementIterator();//对根节点进行迭代节点元素
while(it.hasNext()){
HashMap<String,Object> map=new HashMap<String,Object>();
Element product = (Element)it.next();
Element name = product.element("pname");
Element price1 = product.element("beforePrice");
Element price2 = product.element("nowPrice");
Element pic = product.element("pic");
map.put("pid", product.attribute("pid").getText());
map.put("pname", name.getText());
map.put("price1", price1.getText());
map.put("price2", price2.getText());
map.put("pic", pic.getText());
listmap.add(map);
}
Util.toJson(listmap);
}
//读取资源文件:此时xx.properties应该与该类放在同一个目录.
public void readProperties() throws Exception{
Properties props=new Properties();
try {
props.load(this.getClass().getResourceAsStream("newProduct.properties"));
} catch (IOException e) {
System.out.println(e);
e.printStackTrace();
}
String date = props.getProperty("lookDate");
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
try {
Date d=sdf.parse(date);
System.out.println("date:"+d.toGMTString());
if(d.after(new Date())){
//直接加载xml信息
readXmlNewProduct();
}else if(new Date().getDate()>=d.getDate()){
//从新查询一次数据放到xml中
writeXmlNewProduct();
//读取资源文件,改变属性值 props.put("lookDate", "看看");
Date newDate=new Date();
newDate.setDate(newDate.getDate()+3);
props.put("lookDate", newDate);
//然后读取xml数据
readXmlNewProduct();
}
} catch (ParseException e) {
e.printStackTrace();
}
}
其他核心的新特性貌似没有了,如果觉得对你有用,那就收藏下吧。QQ:1432224036 有志者可以加我交流。
总有一天你将破涌而出!
——小高。