一次团购活动项目开发
一次团购活动项目开发
项目需求
1、 单点登录:任何一名公司员工采用portal帐号密码登录系统,系统需自动获得该员工的以下基本信息:员工编号、portal帐号、姓名、性别、手机号、归属组织架构(精确到底层)。
2、 衣服属性:被投票的每件衣服需具备以下基本信息:衣服类别(男装、女装)、衣服种类(上衣、裤子等)、衣服款号(Abcde等)、颜色(SHP(西瓜红)等)、尺码(S、M、L等)、库存(该尺码目前剩下的库存量,库存为0,该尺码将不能进行选择)
3、 界面要求:一名员工登陆该站点后,系统将具备以下要求:
(1) 界面顶部应该包含本次投票的一些说明细则还有衣服的热点排行(男员工显示男服装的排行,女员工显示女装的排行)。
(2) 自动识别该员工的性别而显示衣服的类别,如男员工应该显示男衣服,女员工显示女衣服
(3) 衣服的种类应用在同一页面内分开显示,如男员工有上衣和裤子,应该在不同栏目里显示。
(4) 同一种类而不同款号的衣服应该在同一栏目里以不同的项来显示,如男员工上衣有:QB-716301和QB-716302两款,那么这两款要的同一栏目中分开显示。
(5) 同一款衣服中的不同颜色的款式应该在同一项下的子项显示。
(6) 员工投票时,对不同类别,不同的项的选择数目是有限制的,比如:男员工有5款上衣和6款裤子,但有规定:一名员工只能选择其中两件上衣和两条裤子,选多选少都不给于提交。(男员工的配置为:一件T恤,一件衬衣,两条裤子。。。女员工的配置为:一件T恤,一件衬衣,一条牛仔裤子)
在员工选择好衣服后提交投票时,应该弹出提示说明框,内容如下:投票成功,请注意以下您要的颜色如果没有,公司到时会单独通知您进行调换。
4、 导出数据的要求:为了方便综合部统计,在投票结束后,导出的表格信息应该包括以下信息内容:员工编号、portal帐号、姓名、性别、归属组织架构(精确到底层)、手机号、所选衣服1名称、所选衣服1颜色、所选衣服1尺码;所选衣服2称、所选衣服2颜色、所选衣服2尺码。。。。以此类推。
需求分析/开发计划
1.功能点。(1)单点登录。(2)服饰数据的录入模块。(3)热点排行的显示。(4)根据性别显示不同内容。(5)对服饰的选择有库存限制。(6)数据的统计导出。(7)展示和选择页面
2.时间。大概一个星期。
3.与需求人确认。经过商讨,服饰的数据会由需求部门提供给我们,一般情况下需要由我们录入;同时活动结束后,数据由我们生成以excel的格式提供给他们。同时考虑到时间比较少,同时该项目为一次性项目,活动结束即项目生命周期完毕。所以决定服饰的录入模块和数据导出两个功能点可以去掉,使用直接的数据库操作录入原始数据和查询统计结果替代。同时又觉得热点排行用途不大,在时间有余的情况下才做,其实这么说了,也就属于不做部分。这么下来,开发计划基本定下来,主要需要完成的就是展示的页面的设计和投票逻辑的提交。
数据库设计
数据库比较简单,从以上需求不难想象,至少需要包括服饰信息、员工信息、员工对应服饰这3张表,其中员工信息可以通过单点登录模块获取,所以该表可以省略,需要时直接通过单点登录功能获取即可。于是整个项目只有2张表。
Product 服饰信息表
字段名 |
类型 |
说明 |
fnumber |
文本 |
服饰款式 |
fcolor |
文本 |
颜色 |
fsize |
文本 |
尺寸 |
fsex |
文本 |
性别 |
fcatalogue |
文本 |
分类(上衣、T恤、裤子) |
fpic |
文本 |
图片路径 |
fstock |
数字 |
库存 |
Fid |
自增 |
Vote投票表
字段名 |
类型 |
说明 |
Fid |
自增 |
|
floginid |
文本 |
员工信息 |
fproduct |
数字 |
对应Product表服饰的id |
fcreateTime |
日期 |
|
fname |
文本 |
员工信息 |
fsex |
文本 |
员工信息 |
fdpfullName |
文本 |
员工信息 |
fdpfullcode |
文本 |
员工信息 |
fdpid |
文本 |
员工信息 |
fmobile |
文本 |
员工信息 |
对vote表的设计存在较多的冗余的员工信息,但是这样能方便统计结果的导出。
页面设计
首先问需求人的意见,征求他要什么样子的界面,并通过笔纸画出草稿。定型如下:
下面是完成后的样子
其中的尺寸选择和颜色选择是仿淘宝页面的,基本制作思路如下:
html结果
<ul><li><a>红色</a></li><li><a>白色</a></li></ul>
样式
ul
{
list-style-type: none;
}
ul li
{
float: left;
margin-right: 5px;
width: auto;
overflow: hidden;
}
ul li a
{
display: block;
border: 1px solid #CCCCCC;
padding: 3px 5px 3px 5px;
margin: 1px;
}
ul li a:hover
{
border: 2px solid #FF6701;
margin: 0px;
}
如果该内容被选中,则赋予该li一个样式attrSel
.attrSel a
{
border: 2px solid #FF6701;
margin: 0px;
background: url(../images/select.gif) no-repeat no-repeat right bottom;
/*背景图片就是右下角那个小图片*/
}
通过jquery的事件绑定可以容易的完成。
$("ul li a").bind("click",function(e){
Var myself=$(e.currentTarget); //获取点击的元素
var myli = $(e.currentTarget).parent(); //获取点击的li元素
myli.addClass("attrSel"); //为该元素增加被选择的样式
myli.siblings().removeClass("attrSel"); //其他的去除该样式
})
通过以上代码就可以实现仿淘宝的颜色选择和尺寸选择。
在选择颜色选项的时候,要求根据选择的不同颜色,切换不同的图片显示。这个的实现我通过先给每个颜色选项的li增加一个pic属性来存放其相应图片的路径。如
<ul><li pic='a.jpg'><a>红色</a></li><li pic="b.jpg"><a>白色</a></li></ul>
然后每次选择的时候读取该值,并加载图片显示。
if (myli.attr('pic') != undefined) {
var myImg =$("#img");
var imgSrc = '<a alt="点击看大图" href="images/product/' + myli.attr('pic') + '" target=_blank >' + '<img alt="点击看大图" src="images/product/' + myli.attr('pic') + '" > </a>';
myImg.html(imgSrc);
某个款式+某个颜色+某个尺寸对应某件具体的衣服,要求每当选择一件衣服时,需要显示该衣服的库存。这个我通过每次选择事件,将衣服的这个3个属性发回服务器查询衣服库存,并动态更新显示。如果库存为0了,还要把下面的选择按钮隐藏起来,不让用户选择。
///是否还有库存
function FreeStock(el) {
var myProperty = el.parents(".property");
var mySelSize = myProperty.find(".ulSize .attrSel:first");
var mySizeValue = mySelSize.attr("fsize");
var mySelColor = myProperty.find(".ulColor .attrSel:first");
var myColorValue = mySelColor.attr("fcolor");
var myNumber = myProperty.find("input[type=hidden]:first");
var myNumberValue = myNumber.val();
var myCatalogue = myProperty.find("input[type=hidden]:last");
var myCatalogueValue = myCatalogue.val();
$.get('../AjaxServer.svc/FreeStock', { 'fnumber': myNumberValue, 'fcolor': myColorValue, 'fsize': mySizeValue, 'fcatalogue': myCatalogueValue }
, function(content) {
var stock = myProperty.find(".fstock");
stock.text("还剩 " + content.d + "件");
var btn = myProperty.find(".btn");
if (content.d < 1) {
var btn = myProperty.find(".btn");
btn.hide();
}
else {
btn.show();
}
});
}
页面一开始显示的时候,是全部选项没有被选择的,一般要默认选择第一个内容。所以需要初始化执行给第一个li增加attrSel属性。通过jquery的遍历方法来实现。
//默认选中第一个
$(".ulSize").each(function(index, e) {
$(this).children("li:first").addClass("attrSel");
});
//默认选中第一个
$(".ulColor").each(function(index, e) {
$(this).find("a:first").click();
});
当用户选择好要购买的衣服后,提交到服务器,由于提交的数据比较多,如果以post的参数来传递的话比较麻烦。我是定义了个结构体数组,结构体的结构和Product表中的商品信息一样。
public class SubmitData
{
public string fnumber { get; set; }
public string fcatalogue { get; set; }
public string fcolor { get; set; }
public string fsize { get; set; }
}
Js代码如下:
Var shopCar=[];
var myItem = { 'fnumber': myNumberValue, 'fcolor': myColorValue, 'fsize': mySizeValue, 'fcatalogue': myCatalogueValue };
shopCar.push(myItem);
这样,就只需要将这个shopCar对象序列化为文本后单做一个参数值传输到服务器端,再由服务器端转换为SubmitData对象。
$.ajax({
type: "POST",
url: "../submit.aspx",
data: "data=" + JSON.stringify(shopCar),
success: function(msg) { alert("投票成功,请注意以下两点:(一)您要的颜色如果没有,公司到时会单独通知您进行调换。(二)所有衣服的样板现已经放在市公司8楼外接待室,欢迎大家前来试穿。"); window.location = window.location; },
error: function(msg) { alert("啊啊!出了一点错误了,请通知一下管理员处理一下问题吧!不过一般是您选择的衣服已经没有库存了,刷新一下看看是不是没有库存了!"); }
});
上面的这段js看起来没啥问题,可惜ie6不支持 JSON.stringify()这个方法,而客户端公司是规定使用ie6作为标准的,所以需要加入一个第3方的json操作类,这需要在文档头加入一段判断。
<script type="text/javascript">
if (typeof (JSON) == 'undefined') { //沒有 JSON 時才讓 browser 下載 json2.js
var jspath='<%=ResolveUrl("js/json/json2.js") %>';
$('head').append($("<script src='<%=ResolveUrl("js/json/json2.js") %>' type='text/javascript'>"));
}
</script>
上面的代码是判断浏览器支持json不,如果不,则引入牛人开发的json2.有了该js的引入,ie6下也能使用json函数。代码中的ResolveUrl 不是js代码,是asp.net的一个函数,该函数实现将相对路径转换为绝对路径,这个尤其在使用了asp.net 的模板时特别有用。
在服务端,会接收到客户端传来的参数data,该参数经过反序列后能得到一个submitData数组。这里我使用的序列化不是json4net,而是asp.net自带的函数。
string data=Request.Form ["data"];
System.Web.Script.Serialization.JavaScriptSerializer json = new System.Web.Script.Serialization.JavaScriptSerializer();
SubmitData[] ls = json.Deserialize<SubmitData[]>(data);
得到提交的数据后就是插入数据库咯。但是这个过程中需要再次判断一下库存的问题。因为多用户操作问题,也许甲选择某衣服时候还剩下一件库存,但经过一段时间后才按下提交按钮,此间隔中衣服也许已经被其他人选择提交了。所以需要在服务端再次验证一下库存的问题。
用户提交完毕后,刷新该页面,去除掉提交按钮,同时在右下角有一个固定的图层,显示用户已经选择了你的衣服。效果是该div的位置总在右下角,不随网页滚动而移动。难度在于ie6不支持几个css属性。导致有点麻烦。
#wrap{display:block;bottom:0px;right:1px!important;right:18px;width:300px;line-height:20px;position:fixed;border:1px solid #999;background:#f0f0f0;padding:10px;
_position:absolute;
_bottom:auto;
_top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)));
}
*html{
background-image:url(about:blank);
background-attachment:fixed;
}
<div id="wrap">你选择了xxx</div>
下划线的属性和*html专为ie6设计的。
最后提供一下整个项目的代码给大家参考一下,代码中去除了单点登录相关的代码,这个毕竟是内部的东西,所以要工程打开后直接运行肯定出错,请自行替换修补。https://files.cnblogs.com/topdog/DressVote.zip