您的位置:首页 > 其它

Drupal项目实战:公司员工订餐系统

2010-11-30 00:45 330 查看

原文(需 翻->墙):http://doctor-fang.blogspot.com/search/label/Drupal%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-%E5%85%AC%E5%8F%B8%E5%91%98%E5%B7%A5%E8%AE%A2%E9%A4%90%E7%B3%BB%E7%BB%9F



Drupal项目实战:公司员工订餐系统 (一)

简单的需求


我们要做的是一个公司内部的员工订餐网站,它的主要功能是:

员工可以浏览各种菜的信息:为了简单,我们先假设可以浏览的是“套餐”

员工在选择好菜后,就可以下订单:订单中可以选择订菜的数量

饭店可以查看员工所下订单 :并根据订单进行送餐,订单的有效期是当日上午10:00 (假设我们订的是午餐)

菜单的主要属性:标题、说明、照片、价格

OK. 非常简单易懂,基本上三个需求 。这个系统中,主要的角色是:

公司员工

饭店

订餐管理员

我们要做的就是实现这样一个系统。首先快速做出原型,然后逐步迭代,即采用敏捷开发[1]
方法。可以发挥同学的想像力,逐步完善。



图1 员工午饭订餐系统结构图(用户视角)

客户


在了解了需求后,我们可以对系统的功能进行分析,以便进行技术架构的分析,进而估计出,要实现这样一个系统,大概要多少成本。这是一个很现实的问题。在实际的项目中,客户一般只关心花多少钱来完成这样一个项目,至于用哪种技术,用不用Drupal,其实他们并不关心。因此,某些开发者有时过多的向客户介绍Drupal的优势,其实是完全没有必要的。只需要让客户了解我们采用了“先进的”、“高效的”、“便于扩展”的技术架构就可以了。但是,对于开发者来说,技术框架是非常重要的,因为这样我们才能准确的估计出是否能顺利完成项目,以及其开发成本。

UML


我个人是比较主张使用UML的。因为UML的用例图,状态图和时序图等,可以很好很方便的对系统进行建模,而且便于和世界各地的用户交流。这一点很重要,因为如果我们的客户和我们使用的不是同一种语言时,这种图型就成为了很好的交流媒介。

分析

我们力求简化开发过程,不必要的就直接省略。对于这个项目,我认为接下来应该分析如何用Drupal来实现。

首先,要找出系统中的“元数据”。因为Drupal是CMS,且核心就是Node。那么分析系统时,首先就是找出系统中的“Node”,即“元数据”。从面向对像的角度看,就是“类”。我认为这是面向数据和面向对像分析的综合运用。

菜单应该是系统中的“元数据”,因为所有的行为都是围绕这个进行的。菜的主要属性已经在需求中说明了,那么我们可以马上联想到,“菜单”即是Node的子类,是Node的继承,扩展Node的属性(因为Node只有标题和内容两个内容属性),就可以完成“菜单”的管理。我们把“菜单”类称为Food。

除了Food,还有一个类是“订单(Order)”。订单用于记录员工的订餐情况。它也是一个“元数据(meta-data)”。那么它是否也可以继承Node类呢?我们知道,使用Drupal的一个原则,就是尽可能使用Drupal本身的模块功能来完成业务需求。简单的讲,能少使用模块就少使用模块。现在有两个第三方模块可以实现电子商务的功能:
e-Commerce



Ubercart






前者历史比较悠久,在Drupal 5时代非常流行,不过进入Drupal 6时代就暂停开发了。听说最近又重新开始开发了,估计作者前一段时间持观望态度。Ubercart是后起之秀,它也是以“商品”为主的电子商务网站的解决方案。而且Ubercart也于最近推出了Drupal 6的beta版本。我没有对这两个插件作过横向对比,刚好我们借这个实战项目,也可以进行一下实验。不过,在使用这两个模块之前,我想先使用“纯Drupal”来实现我们的功能(尝试),如果能实现,那么效率应该是比较高的,而且更简单。

预计要使用的模块


有人说,Drupal开发就是“拼模块”,此话有一定道理。而且大多数人在用Drupal开发时,马上头脑中就无数个模块翻腾。其实这不是一个很好的现象,很容易在还没真正弄清楚需求前就陷入了技术误区。当然,我们还是需要在开始前设想一下需要使用哪些模块,因为这样可以提前下载下来,做下尝试。不过我更倾向于:边做边找的模式。也许这不是最佳实践,不过对于比较小的项目还是很有效率的。

CCK、Views、Panels:这三个模块基本没什么悬念,任何一个网站几乎都会用到。Panels可能会损伤性能,不过它可以让我们避免陷入枯燥的CSS定位调试中。

Image Field:用于添加Image的CCK Field

Date:Date模块主要是一些日期相关的功能,也用于添加Date类型的CCK Field

Vote API: 这个模块是用于评论时投票的,与FiveStar等模块连用,可以实现“小星星评分”,可爱又实用。

Webform:在“下订单”时,我们有可能


会用到,先列于此。

自定义模块:如果自己开发模块能够高效的解决问题,那么自定义模块也必不可少。

主题模板


Drupal中的主题模板(Theme)是表示层的术语,除了样式、色彩等,我们还要对内容的显示布局。默认的节点显示页面只适合简单的内容类型,如果我们使用了CCK扩展节点字段的话,那么就需要自定义模板文件了。本项目对网站风格的要求是简洁,同时为了开发方便考虑,先使用Garland(Drupal默认模板)主题,然后再进行定制。

工具


我喜欢使用EditPlus作为开发PHP的工具,然后配以Firefox+Firebug和IE+Developer Tools(或IE8)进行调试。在工具方面,仁者见仁,智者见智,没有好坏之分,只有熟练与否。Choose whatever you like.

同时,我发现微软的Visual Web Developer Express是一个非常不错的编辑器,尤其是网页开发,可用于页面设计,有兴趣的朋友们也可以试一试。

小结


本文叙述了项目的需求,并进行了分析和设计。采用Drupal的开发与普通的软件开发还是有区别的,因为我们是“站在Drupal的肩膀”上,因此对软件开发过程可以做一定的“剪裁”。至于我的方法是不是“Best Practice“,那还需要大家一起共同探讨了。

详细的开发流程从第二篇开始。

Drupal项目实战:公司员工订餐系统(二)

创建菜单节点

首先创建菜单(Food)的节点类型,增加几个字段后,效果见下图。由于属基本操作,就不再赘述了。



在完成菜单类型的创建后,发现默认的节点显示页面,实在是比较简陋.这需要我们自己动手来完善一下.在开始之前,必须介绍一个很重要的模块-Devel(
http://drupal.org/project/devel)


.此模块为开发者必备,主要功能有:

查看节点的变量

清空缓存(模块的)

生成测试数据(节点等)

我常用的是这几个,对于D6,它还可以调试主题模板,比较有效.不过,这个模块有时会用其它模块的Javascript脚本有冲突,目前还不太明确与哪些模块有冲突.如果朋友们在调试Drupal时发现莫名其妙的JS问题,可以考虑先关闭Devel模块,然后再试.

开发主题,当然还需要能方便查看和动态更改CSS的浏览器支持.Firefox+Firebug组合当仁不让成为现时的首选.不过目前,IE8和Chrome也正努力赶上.IE8中按F12可以调出和IE Developer Tools相似的HTML,CSS代码调试框,基本上Firebug功能类似.Chrome目前可以定位HTML页面元素,以及查看其CSS样式,不过还不能即时修改.选择哪个就看大家自己的喜好了.一般情况下,我们都要调试Firefox和IE下的兼容性.尤其是Div+CSS的布局,如果没有很高的技巧,确实需要调试很长时间。

创建菜单显示模板


在开始创建之前,当然要进行设计.我们的项目目前没"网页设计",那我们就直接挑一个差不多的作参考吧。如果你的项目组中有美工人员,这部分应该交给他/她去做了。对于Drupal页面的设计,我的意见是:尽量符合Drupal默认的页面布局,这样交给Drupal开发者时,只需要做少量修改即可。否则就需要花很多时间在主题和模板开发上.毕竟CSS技巧高的又懂Drupal的同志,还是不大容易找到的。

我看中了一个国外网站的"菜单"信息的显示页面,分享一下:
http://www.foodnetwork.com/recipes/paula-deen/christmas-ham-recipe/index.html.


截图如下。



对于Drupal项目,我认为首先应该开发针对不同的节点类型的页面的显示模板,即:node-content_type
.tpl.php。它是显示的模板,它包含节点的各个元素的显示方式的设定(如标题、内容、以及用CCK生成的字段等),但不对整个页面的布局进行设定。此处需要提一个需要注意的问题:通过Devel的"Dev load"查看的变量,并不是在node.tpl.php中直接可用的变量。它显示的是通过node_load函数得到的$node节点,与node.tpl.php中的$node节点还是有区别的。同时,大家在使用节点变量时,也可以参考一下$node->content变量中的内容,它是经过Drupal处理后的HTML内容。

关于Drupal主题模板开发的顺序

,下面是我的看法:

开发节点类型的模板:node-content_type.tpl.php

开发评论的模板:comment.tpl.php

开发普通页面的模板:page.tpl.php

开发首页模板:page-front.tpl.php

整理CSS类别和区块

制作全站的CSS,写入style.css,或创建单独的样式表文件,在style.css中import.

为生产站点作CSS优化:如使用Drupal的CSS Aggregation将CSS文件整合为一个文件或重新设置每页加载的CSS文件。

我喜欢的开发顺序是:先把所有的HTML写出,然后创建好每个CSS类和ID等,最后再进行“上色”。流程如下所示:

原始页面


第一次布局修改:

分左中右三栏

左侧为图像,中间为基本信息,右侧为评论。



第二次布局修改

加入样式

采用table作布局


做成像cnbeta.com那样的评论

Drupal默认的评论在最下方,我想把它放在页面的右侧,这样用户打开这个页面,无需浏览到底部,就可以看到最新的评论。cnbeta.com的形式也不错,它将“支持”者多的评论,放置在右侧。下面我们看看在D中怎样实现。



按正常思路,评论就应该在page.tpl.php中设置。但是,在page.tpl.php中只能找到$content变量。因此,将评论更换显示位置就显得有点“棘手”了。我目前的解决方法是:

使用Views创建某个节点的评论列表,然后创建自定义模块,调用views_build_view函数,将列表以区块的形式,放置在右侧区域。那么,这部分应该以区块形式存在,放置在right区域,也无须对node.tpl.php进行修改了。

(未完待续)

相关函数讲解

theme_image($path, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE)


用途:显示图像,生成IMG标签,同时可以设置style属性——通过设置$attributes数组。

参数解析:

$path:图像路径。如本例中,如果为节点创建了Image Field,那么可以将$field_food_pic[0]['filepath']作为参数传入。

$attributes:用于设置HTML标签的style属性。像这样使用即可——array('weight' => '200px', 'height' => '100px')。

$getsize:如果设置为TRUE,那么将会按照图像文件的实际长和宽来显示图像,通过$attributes设置的自定义长和宽就会失效。

int strtotime ( string $time [, int $now ] )


用途:将任何英文文本的日期时间描述解析为 Unix 时间戳。使用Drupal的Date field得到的日期是ISO日期格式的,如2008-10-20T10:20:20。大家可以发现多了一个“T”,因此我们需要先将这个日期转化为UNIX时间戳,然后再转换为适当的日期格式。

array get_defined_vars ( void )


用途:此函数返回当前页面中所有可用的变量。调试佳品。

发贴者
方医生

时间:
下午5:46

3 评论



标签:
Drupal项目实战-公司员工订餐系统

Drupal项目实战-公司订餐系统(三)

上节回顾

上一节的进展为:

创建了Food的Content type

使用CCK创建了Food的相关字段

修改了node-food.tpl.php

目前,简单的菜单管理功能模块可以说基本上完成了,除了权限控制部分。我认为权限控制应该在所有系统功能完成后再统一考虑,目前还是先实现功能为主。那么接下来,就可以进入订餐功能模块的开发了。本文我们就开始订餐功能的设计和开发。

订餐功能模块分析

公司员工在浏览了菜单后,可以选择订购此午餐,同时设定购买数量。由于菜单是一个套餐,因此通常一个员工只会选择一种套餐。但是,此处我认为应该在一定程序上考虑系统的可扩展性,也就是说,应该考虑一个用户订两个或多个“套餐”的情况。因为很显然的是,员工小A想替小B和小C订餐的话,那么使用小A的帐户就需要同时订购三种不同的套餐。

其实此处就存在一个实际的业务模型和系统模型间的映射关系。如果只是从“一个员工中午只吃一种套餐”的常识来想,将每个“帐户”设定为“只允许订购一种套餐”的话,做成的系统就明显不适合使用了。这点也提醒做系统设计的朋友们要注意。

由于目前本系统只限于某公司员工内部使用,因此不存在需要填写送餐地址的信息。同时为了方便起见,暂时不考虑网上支付。这样问题就简化了。另外,用户在订餐时,通常会按照个人口味提出一些建议,因此系统还需要提供一个文本框,用于用户对订餐进行一些“补充说明”。

总结一下,订饭的流程如下:

浏览菜单并选择“订购”某套餐

设置订购数量

输入补充信息

查看购物车并确认生成订单

查看订单状态(已收到订单、已发货、收货确认)

图!图!图!


我认为任何语言的描述都不如页面草图来的直接。UML和简洁的文字都不是和客户交流的最好方式。看得见的页面图才是最有效的办法。









上面几张图演示了在浏览套餐菜单后,可直接订餐的全部过程。

(未完待续)

Drupal项目实战-公司订餐系统(四)

在本系列上一个文章中,我画了一些页面草图,用于展示网站原型。本文中将讲解如何用
Drpual
来实现。

在上面的文章中,我们已经创建了一个
Food
节点类型,用于存储各个菜单,供员工选择。也就是说,基本上实现了菜单的管理功能。那么接下来要实现在线订餐的功能了。

为了简化功能,我们先不实现购物车的功能,只需要实现用户在设置订餐数量后,即可提交一个订单。午餐管理员就可以查看用户订餐列表了。

可以看出,现在需要下列“东西”:

一个表单:订餐表单,显示一个文本框,用于让用户输出订餐数量,以及一个提交按钮。

一个数据库:用于存放用户的订餐数据。

一个页面,午餐管理员可以查看员工的订餐情况。

除此之外,还需要显示一些提示信息等。

在平时做项目时,我喜欢迭代式的开发,简单的讲就是先开发主要功能,再逐步完善。一方面这样可以使客户能够清楚的看到进展,另一方面也能确保系统更为“扎实”。除此之外,还可以使程序员自己有一定的满足感,避免整天忙碌于开发却看不到效果,产和厌倦感。

下面按照上面的列的“东西”,一个一个的找解决方案。

订餐表单

这个表单上需要下列元素:

一个选择框,列表值为:
1, 2, 3, 4, 5
。我们假定一个员工最多只能订
5
份套餐。

一个提交按钮

这应该是最简单的表单了,下面看看怎么实现。

毫无疑问,需要使用传说中的
Form API

Form API
简称
FAPI

Drupal
中一个非常强大的表单生成函数。它包括表单生成、表单处理及结果显示等各个阶段的功能。其中最重要的几个函数为:

有一个钩子函数和
form
有关,不过大家要弄清它的用途:
hook_form
。这个函数是用于通过模块自定义
content type
时使用的,可以捕获
create/edit
节点时提交的表单。但这里要用的是
drupal_get_form(),

用于生成一个表单。

首先创建一个生成表单元素的函数
function buy_food_form()
,然后使用
drupal_get_form('buy_food_form')
就可以输出表单了。除了生成表单外,还要对用户提交的表单进行处理。
Drupal
中,表单处理分为两步:

验证提交的表单数据

对数据进行处理

这两个步骤都转变为两个钩子函数:
hook_form_validate

hook_form_submit
。我们只需要将
hook
换成生成表单函数的前缀即可,如
food_order_form_validate

food_order_form_submit


由于需要自己写函数了,因此不可避免的需要自定义模块了。我们将订餐模块命名为
Food Order Module
。需要创建下面两个文件:

food_order.info

food_order.module

下面分析一些表单提示函数和处理函数。

OK
,表单准备好了,该研究一下将表单放哪里了。由设计图看出,我们需要将表单放置在每个菜单页面上,这样用户在浏览到感兴趣的菜单时,就可以直接订餐了。那么如何将表单放置在菜单页面中呢?有两种方法:

修改
node-food.tpl.php

生成
Block
,放置在
node/*
页面中

我更倾向于第二种方法,虽然第一种方法更为直接。本例中我们还是使用第二种方法,因为这样更遵循
`Drupal

MVC
模式,而且自定义模块的好处是可以根据需要开关模块。

数据表

我们需要使用数据库来存储哪些同事订了什么餐。首先要做的工作是创建一个数据表。等等,由于我们使用的是强大的
Drupal
,是不是不需要创建数据表也可以实现这样的功能呢。答案是:
YES
,但是,本例为了让读者练习使用自定义的数据表,因此不采用
Drupal
模块的解决方案。其实在
Drupal
中有个很有名的电子商务类模块——
Ubercart
。其实订餐这个业务和买商品本质是一样的,因此
Ubercart
也可以实现这样的功能,只不过有点重量级了。感兴趣的朋友们可以试试
Ubercart
是否可以完成同样的需求。

Drupal
之所以说它是
CMF(Content Management Framework)
,是因为一方面,它具有很好的层次结构,比如“数据库抽像层”,同时提供了很多方便的
API——
一系列的数据库操作函数,用起来还是相当方便的。使用
Drupal

DAL
,可以使我们不去关心数据库服务器配置及连接等细节,而且由于
Drupal
除了
mysql
外还支持
pgsql
,因此我们的程序还可以移植到
pgsql
上而无须更改数据库操作代码。而且,有望在不远的将来,
Drupal
可以使用
MSSQL

Oracle
等大型数据库。数据库抽像层的好处也就更为明显了。

数据表中主要字段有:

菜单号
(nid)

用户
ID(uid)

订餐数量(
qty)

应付金额(
money


订餐时间
(created)

订餐查看页面

最后,需要一个页面,让管理员可以查看当天有哪些人订餐了。当然也可以查看历史订餐信息,不过这个没有什么太大意义。因此在这个页面上只查看当天的订餐信息就可以了。

我们通过一个表格显示所有订餐的信息。
Drupal

API
中有一个
theme_table
的函数,可以生成表格,而且还可以自动生成排序字段,不过使用起来稍微有些复杂。但还是推荐大家使用。

由于我们是自己创建的订餐表,因此需要用到
db_query


$sql = “SELECT * FROM {food_order}”;

$result = db_query($sql);

while ($row = db_fetch_array($result)) { }

另外,还可以使用
pager_query
轻松实现分页。

下面总结一下,本文给出了实现“在线订餐”的基本解决方案,主要是自己创建数据表,并使用
FAPI
生成表单,用
db_query
等插入数据及显示数据。下一小节将给出源代码,供大家参考。

drupal_get_form()

发贴者
方医生

时间:
上午10:25

3 评论



标签:
Drupal项目实战-公司员工订餐系统


参考资料


[1] 敏捷开发:
http://www.agilemanifesto.org/


:敏捷开发是RUP的一个扩展或精简,它有几个关键的实践用于指导软件开发过程。不过任何一种过程方法,都不可能适用于所有的项目,都需要经过我们自身的理解,并结合实际的项目情况而运用,要“以人为本”、“从群众中来、到群众中去”。

[2] Best Practice:指最佳实践。

转载: http://doctor-fang.blogspot.com/search/label/Drupal%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98-%E5%85%AC%E5%8F%B8%E5%91%98%E5%B7%A5%E8%AE%A2%E9%A4%90%E7%B3%BB%E7%BB%9F
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: