要仿制织梦投票模块,需先理解其核心逻辑:通过数据表存储投票选项、用户投票记录及结果统计,结合前端表单交互与后端数据处理实现功能,以下是详细步骤,涵盖环境准备、数据库设计、文件修改及功能实现。

环境准备与文件结构分析
仿制前需确保本地已搭建织梦(DedeCMS)运行环境,建议使用PHP 7.x+MySQL 5.6+版本,织梦投票模块的核心文件位于/dede/(后台管理)和/templets/(前端模板)目录,主要涉及:
- 后台:
vote_add.php(添加投票)、vote_edit.php(编辑投票)、vote_main.php(投票管理列表)、vote_list.php(投票结果展示) - 前端:
vote.htm(投票表单模板)、vote_result.htm(投票结果模板) - 数据库:
dede_vote(投票主表)、dede_vote_data(投票选项表)、dede_vote_record(用户投票记录表)
数据库设计与表创建
织梦投票模块依赖三张核心表,需通过SQL语句手动创建(或在后台“系统-SQL命令工具”中执行):
投票主表(dede_vote)
存储投票基本信息,如标题、描述、状态等:
CREATE TABLE `dede_vote` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, varchar(100) NOT NULL DEFAULT '' COMMENT '投票标题', `voteinfo` text COMMENT '投票说明', `starttime` date DEFAULT NULL COMMENT '开始时间', `endtime` date DEFAULT NULL COMMENT '结束时间', `totalcount` int(10) unsigned DEFAULT '0' COMMENT '总投票数', `ismore` tinyint(1) DEFAULT '0' COMMENT '是否多选(0单选1多选)', `ischeck` tinyint(1) DEFAULT '0' COMMENT '是否审核(0直接显示1需审核)', `token` char(32) DEFAULT '' COMMENT '安全令牌', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
投票选项表(dede_vote_data)
存储投票选项内容及对应票数:

CREATE TABLE `dede_vote_data` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `vid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '关联投票ID', `itemname` varchar(100) NOT NULL DEFAULT '' COMMENT '选项名称', `count` int(10) unsigned DEFAULT '0' COMMENT '得票数', PRIMARY KEY (`id`), KEY `vid` (`vid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
用户投票记录表(dede_vote_record)
存储用户IP及投票时间,防止重复投票:
CREATE TABLE `dede_vote_record` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `vid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '投票ID', `ip` char(15) NOT NULL DEFAULT '' COMMENT '用户IP', `dtime` int(10) unsigned DEFAULT '0' COMMENT '投票时间戳', PRIMARY KEY (`id`), KEY `vid` (`vid`), KEY `ip` (`ip`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
后台管理功能仿制
投票添加页面(vote_add.php)
参考织梦后台文件,创建/dede/vote_add.php,核心功能包括:
- 表单提交:接收投票标题、说明、开始/结束时间、是否多选等参数
- 数据入库:将表单数据写入
dede_vote表,并生成唯一token
关键代码片段:
if (empty($title)) {
ShowMsg('投票标题不能为空!', '-1');
exit();
}
$token = md5(uniqid(mt_rand(), true));
$query = "INSERT INTO `dede_vote` (title, voteinfo, starttime, endtime, ismore, ischeck, token) VALUES ('$title', '$voteinfo', '$starttime', '$endtime', '$ismore', '$ischeck', '$token')";
$dsql->ExecuteNoneQuery($query);
ShowMsg('添加成功!', 'vote_main.php');
投票选项管理
在添加投票时,需同步添加选项,可通过动态表单实现,提交时将选项数组循环写入dede_vote_data表:
$items = $_POST['itemname']; // 前端选项数组
foreach ($items as $item) {
if (!empty($item)) {
$dsql->ExecuteNoneQuery("INSERT INTO `dede_vote_data` (vid, itemname, count) VALUES ('$lastid', '$item', '0')");
}
}
投票列表与编辑
仿制vote_main.php,实现投票列表展示、编辑、删除功能,列表需显示投票标题、状态(进行中/已结束)、操作按钮(编辑/删除/查看结果),编辑页面(vote_edit.php)逻辑与添加类似,需先查询现有选项并允许修改。
前端投票功能仿制
投票表单模板(vote.htm)
在/templets/default/下创建vote.htm,使用织梦标签调用投票数据:
<form name="vote" method="post" action="/plus/vote.php">
<h3>{dede:field.title/}</h3>
<p>{dede:field.voteinfo/}</p>
{dede:vote}
{dede:global.itemlist/}
{/dede:vote}
<input type="hidden" name="dopost" value="send">
<input type="hidden" name="aid" value="{dede:global.aid/}">
<button type="submit">提交投票</button>
</form>
投票处理逻辑(vote.php)
仿制织梦/plus/vote.php,核心功能包括:
- 权限验证:检查投票是否在有效期内、是否需审核
- 重复投票检测:通过
dede_vote_record表查询用户IP是否已投票 - 票数统计:根据单选/多选,更新
dede_vote_data表对应选项的count字段,并累加dede_vote表的totalcount
关键代码:
// 检查重复投票
$ip = GetIP();
$dtime = time();
$record = $dsql->GetOne("SELECT id FROM `dede_vote_record` WHERE vid='$vid' AND ip='$ip'");
if ($record) {
ShowMsg('您已经投过票了!', '-1');
exit();
}
// 更新票数
if ($ismore == 0) { // 单选
$itemid = $_POST['itemid'];
$dsql->ExecuteNoneQuery("UPDATE `dede_vote_data` SET count=count+1 WHERE id='$itemid'");
} else { // 多选
$itemids = $_POST['itemid'];
foreach ($itemids as $itemid) {
$dsql->ExecuteNoneQuery("UPDATE `dede_vote_data` SET count=count+1 WHERE id='$itemid'");
}
}
// 记录投票
$dsql->ExecuteNoneQuery("INSERT INTO `dede_vote_record` (vid, ip, dtime) VALUES ('$vid', '$ip', '$dtime')");
ShowMsg('投票成功!', 'vote_result.php?aid='.$aid);
投票结果展示(vote_result.htm)
创建vote_result.htm模板,调用投票结果并计算百分比:
{dede:vote}
<h3>{dede:field.title/}</h3>
{dede:field.voteitemlist}
<div>
<p>{dede:itemname/}</p>
<div style="width: {dede:per/}%; background: #ccc;">{dede:per/}% ({dede:count/}票)</div>
</div>
{/dede:field.voteitemlist}
<p>总投票数:{dede:field.totalcount/}</p>
{/dede:vote}
功能优化与注意事项
- 防刷票机制:可增加验证码功能,或在
vote.php中限制每个IP每日投票次数。 - 样式美化:通过CSS调整投票表单及结果展示样式,例如进度条效果。
- 标签调用:织梦标签
{dede:vote}需在include/taglib/vote.lib.php中编写逻辑,实现数据动态调用。 - 数据安全:对表单提交数据进行过滤,防止SQL注入,例如使用
dsql->GetString()代替直接拼接SQL。
相关问答FAQs
问题1:仿制投票模块后,前端页面无法显示投票内容,如何排查?
解答:首先检查vote.htm模板中的织梦标签是否正确,例如{dede:field.title/}需对应dede_vote表的title字段;其次确认/plus/vote.php文件路径是否正确,且后台已添加投票数据;最后查看数据库dede_vote表中ischeck字段是否为0(若为1则需审核后才显示)。
问题2:如何实现投票结果实时更新并显示百分比?
解答:在vote_result.htm模板中,通过织梦标签循环调用dede_vote_data表的选项数据,计算每个选项的票数占比。
{dede:sql sql="SELECT * FROM `dede_vote_data` WHERE vid=$aid"}
<p>
[field:itemname/]:([field:count/]票)
<progress value="[field:count/]" max="{dede:sql sql='SELECT SUM(count) as total FROM `dede_vote_data` WHERE vid=$aid'}[field:total/]" />
([field:count/]/{dede:sql sql='SELECT SUM(count) as total FROM `dede_vote_data` WHERE vid=$aid'}[field:total/] * 100)%
</p>
{/dede:sql}
通过{dede:sql}标签动态查询数据,结合<progress>标签实现进度条效果,实时展示投票结果。
