30天搭建消防安全培训小步调

打印 上一主题 下一主题

主题 998|帖子 998|积分 2994

一、功能需求

搭建一款消防安全培训答题小步调,大要上实现功能如下:
1.重要消防相关信息发布提示;
2.培训课程库播放,文档的,加视频的;
3.题库、考试单选、多选、判定三类题 ;
4.考试结果查询、输出表单 ;
5.单次培训:限时内完成,签到(手署名),限时内完成考试;
二、项目结构

使用微信开辟者工具创建一个新的小步调项目,项目结构大抵如下:
  1. pages
  2. ├── index           // 首页,显示重要信息提醒
  3. ├── course          // 培训课程库页面
  4. ├── exam            // 考试页面
  5. ├── result          // 考试成绩查询页面
  6. ├── signin          // 单次培训签到页面
复制代码
三、关键代码

实现一个基本的消防安全培训答题小步调,包含重要信息发布、培训课程库、题库考试、结果查询和单次培训签到等功能。以下是一个消防安全培训答题小步调的实现思绪及部门代码:
app.json
  1. {
  2.     "pages": [
  3.         "pages/index/index",
  4.         "pages/course/course",
  5.         "pages/exam/exam",
  6.         "pages/result/result",
  7.         "pages/signin/signin"
  8.     ],
  9.     "window": {
  10.         "backgroundTextStyle": "light",
  11.         "navigationBarBackgroundColor": "#fff",
  12.         "navigationBarTitleText": "消防安全培训答题小程序",
  13.         "navigationBarTextStyle": "black"
  14.     }
  15. }
复制代码
pages/index/index.wxml
  1. <view class="container">
  2.     <view class="notice" wx:for="{{notices}}" wx:key="*this">{{item}}</view>
  3.     <button bindtap="goToCourse">进入培训课程库</button>
  4.     <button bindtap="goToSignin">参加单次培训</button>
  5. </view>
复制代码
pages/index/index.js
  1. Page({
  2.     data: {
  3.         notices: ["近期将开展消防安全培训,请及时参加!"]
  4.     },
  5.     goToCourse() {
  6.         wx.navigateTo({
  7.             url: '/pages/course/course'
  8.         });
  9.     },
  10.     goToSignin() {
  11.         wx.navigateTo({
  12.             url: '/pages/signin/signin'
  13.         });
  14.     }
  15. });
复制代码
pages/course/course.wxml
  1. <view class="container">
  2.     <view class="doc-item" wx:for="{{documents}}" wx:key="*this">
  3.         <text>{{item.title}}</text>
  4.         <button bindtap="openDoc" data-url="{{item.url}}">查看文档</button>
  5.     </view>
  6.     <video src="{{videoUrl}}" controls></video>
  7. </view>
复制代码
pages/course/course.js
  1. Page({
  2.     data: {
  3.         documents: [
  4.             { title: "消防知识手册", url: "https://example.com/fire_manual.pdf" },
  5.             { title: "消防应急预案", url: "https://example.com/fire_plan.pdf" }
  6.         ],
  7.         videoUrl: "https://example.com/fire_video.mp4"
  8.     },
  9.     openDoc(e) {
  10.         const url = e.currentTarget.dataset.url;
  11.         wx.downloadFile({
  12.             url: url,
  13.             success: function (res) {
  14.                 const filePath = res.tempFilePath;
  15.                 wx.openDocument({
  16.                     filePath: filePath,
  17.                     success: function (res) {
  18.                         console.log('打开文档成功');
  19.                     }
  20.                 });
  21.             }
  22.         });
  23.     }
  24. });
复制代码
pages/exam/exam.wxml
  1. <view class="container">
  2.     <view wx:for="{{questions}}" wx:key="index">
  3.         <view>{{item.question}}</view>
  4.         <view wx:if="{{item.type === 'single'}}" wx:for="{{item.options}}" wx:key="*this">
  5.             <radio-group bindchange="onSingleAnswerChange" data-index="{{index}}">
  6.                 <radio value="{{item}}">{{item}}</radio>
  7.             </radio-group>
  8.         </view>
  9.         <view wx:if="{{item.type === 'multiple'}}" wx:for="{{item.options}}" wx:key="*this">
  10.             <checkbox-group bindchange="onMultipleAnswerChange" data-index="{{index}}">
  11.                 <checkbox value="{{item}}">{{item}}</checkbox>
  12.             </checkbox-group>
  13.         </view>
  14.         <view wx:if="{{item.type === 'judge'}}">
  15.             <radio-group bindchange="onJudgeAnswerChange" data-index="{{index}}">
  16.                 <radio value="true">正确</radio>
  17.                 <radio value="false">错误</radio>
  18.             </radio-group>
  19.         </view>
  20.     </view>
  21.     <button bindtap="submitExam">提交考试</button>
  22. </view>
复制代码
pages/exam/exam.js
  1. Page({
  2.     data: {
  3.         questions: [
  4.             {
  5.                 question: "以下哪种灭火器适用于扑灭电器火灾?",
  6.                 type: "single",
  7.                 options: ["泡沫灭火器", "二氧化碳灭火器", "水基型灭火器"],
  8.                 answer: "二氧化碳灭火器"
  9.             },
  10.             {
  11.                 question: "消防设施包括以下哪些?",
  12.                 type: "multiple",
  13.                 options: ["灭火器", "消火栓", "应急照明"],
  14.                 answer: ["灭火器", "消火栓", "应急照明"]
  15.             },
  16.             {
  17.                 question: "火灾发生时,应尽快乘坐电梯逃生。",
  18.                 type: "judge",
  19.                 answer: "false"
  20.             }
  21.         ],
  22.         userAnswers: []
  23.     },
  24.     onSingleAnswerChange(e) {
  25.         const index = e.currentTarget.dataset.index;
  26.         const answer = e.detail.value;
  27.         const userAnswers = this.data.userAnswers;
  28.         userAnswers[index] = answer;
  29.         this.setData({
  30.             userAnswers
  31.         });
  32.     },
  33.     onMultipleAnswerChange(e) {
  34.         const index = e.currentTarget.dataset.index;
  35.         const answer = e.detail.value;
  36.         const userAnswers = this.data.userAnswers;
  37.         userAnswers[index] = answer;
  38.         this.setData({
  39.             userAnswers
  40.         });
  41.     },
  42.     onJudgeAnswerChange(e) {
  43.         const index = e.currentTarget.dataset.index;
  44.         const answer = e.detail.value;
  45.         const userAnswers = this.data.userAnswers;
  46.         userAnswers[index] = answer;
  47.         this.setData({
  48.             userAnswers
  49.         });
  50.     },
  51.     submitExam() {
  52.         const { questions, userAnswers } = this.data;
  53.         let score = 0;
  54.         for (let i = 0; i < questions.length; i++) {
  55.             const question = questions[i];
  56.             const userAnswer = userAnswers[i];
  57.             if (Array.isArray(question.answer)) {
  58.                 if (userAnswer.sort().toString() === question.answer.sort().toString()) {
  59.                     score++;
  60.                 }
  61.             } else {
  62.                 if (userAnswer === question.answer) {
  63.                     score++;
  64.                 }
  65.             }
  66.         }
  67.         wx.setStorageSync('examScore', score);
  68.         wx.navigateTo({
  69.             url: '/pages/result/result'
  70.         });
  71.     }
  72. });
复制代码
pages/result/result.wxml
  1. <view class="container">
  2.     <view>您的考试成绩是:{{score}} 分</view>
  3.     <button bindtap="exportResult">导出成绩表单</button>
  4. </view>
复制代码
pages/result/result.js
  1. Page({
  2.     data: {
  3.         score: 0
  4.     },
  5.     onLoad() {
  6.         const score = wx.getStorageSync('examScore');
  7.         this.setData({
  8.             score
  9.         });
  10.     },
  11.     exportResult() {
  12.         // 这里可以实现导出表单的逻辑,如生成 PDF 等
  13.         wx.showToast({
  14.             title: '导出功能待实现',
  15.             icon: 'none'
  16.         });
  17.     }
  18. });
复制代码
pages/signin/signin.wxml 
  1. <view class="container">
  2.     <canvas id="signCanvas" style="width: 300px; height: 200px;"></canvas>
  3.     <button bindtap="saveSignature">保存签名</button>
  4.     <button bindtap="startExam">开始考试</button>
  5. </view>
复制代码
pages/signin/signin.js
  1. Page({
  2.     data: {
  3.         signature: ''
  4.     },
  5.     onLoad() {
  6.         const ctx = wx.createCanvasContext('signCanvas');
  7.         this.setData({
  8.             ctx
  9.         });
  10.     },
  11.     saveSignature() {
  12.         const ctx = this.data.ctx;
  13.         ctx.draw(false, () => {
  14.             wx.canvasToTempFilePath({
  15.                 canvasId: 'signCanvas',
  16.                 success: (res) => {
  17.                     const signature = res.tempFilePath;
  18.                     this.setData({
  19.                         signature
  20.                     });
  21.                     wx.showToast({
  22.                         title: '签名保存成功',
  23.                         icon: 'success'
  24.                     });
  25.                 }
  26.             });
  27.         });
  28.     },
  29.     startExam() {
  30.         if (this.data.signature) {
  31.             wx.navigateTo({
  32.                 url: '/pages/exam/exam'
  33.             });
  34.         } else {
  35.             wx.showToast({
  36.                 title: '请先完成签名',
  37.                 icon: 'none'
  38.             });
  39.         }
  40.     }
  41. });
复制代码



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用户云卷云舒

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表