# VUE + Element UI 作为前端,Node的Express作为后台,模拟打印机的Web即时打印 **Repository Path**: lie2believe/webPrint ## Basic Information - **Project Name**: VUE + Element UI 作为前端,Node的Express作为后台,模拟打印机的Web即时打印 - **Description**: 使用VUE + Element UI 开发Web前端,使用Express来开发后台模拟打印机,实现通过Web前端向打印机设定打印参数,并且可以向打印机发送文件实现打印,以及查看打印历史记录的功能。 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 4 - **Created**: 2022-04-17 - **Last Updated**: 2022-04-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # VUE + Element UI 作为前端,Node的Express作为后台,模拟打印机的Web即时打印 ### 开发背景 公司接到了这样一个用户需求,用户可以通过手机扫描打印机的二维码来打开打印机的WebPage,然后可以通过WebPage来设定部分打印参数,并且可以向打印机发送打印文件,可以查看打印完毕的历史记录。 由于打印机端的固件程序开发还没有完成(二维码生成模块,打印部模块还在重构中),为了保证前后端的开发同其他部门并行顺利进行,在没有打印机硬件的前提下,我决定先行模拟开发出一个演示版,模拟开发可以提前确定一部分API接口,等到打印机硬件开发结束,可以把我们的前端代码,嵌入的到打印机里,直接进入到测试阶段,以缩短我们的开发周期。 ### 模拟方案提出 使用VUE框架 + Element UI 开发Web前端,使用Node的Express框架来模拟打印机后端,前端使用axios通信框架向Express发送请求,Express接收到请求后,模拟打印机把设定的参数保存到文件中,把收到的打印文件数据保存到一个固定的目录中。如果目录中的文件可以完整的打开,就说明数据收到正确。 ### 软件架构 ![输入图片说明](https://images.gitee.com/uploads/images/2021/1213/114007_7a153aa6_9851214.png "Printer的整体结构.png") ### 接口设计 #### 设定打印参数 方法:post URL: /printer/parameter 参数:form: { size: '', type: '', depulx: false, tray: '', direction: '' }, #### 取得打印参数 方法:get URL: /printer/parameter #### 取得打印历史数据 方法:get URL: /printer/history #### 发送打印文件,打印机收到文件开始打印 方法:post URL: /printer/upload 参数:formdata type=file ### 前端设计 #### 组件结构 设计了三个组件: Home组件(父组件),Print组件(子组件),History组件(子组件) Home组件:入口组件,负责加载两个子组件。 Print组件:负责打印参数设定和打印文件的组件,在这个组件中使用Element UI的el-form和el-upload。 History组件:负责显示打印的历史记录,在这个组件中使用Element UI的el-table。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/1213/114049_c36fdbfc_9851214.png "组件图.png") #### 模块关系 ![输入图片说明](%E6%A8%A1%E5%9D%97%E5%85%B3%E7%B3%BB.png) #### 发送打印文件动作时序 ![输入图片说明](print_sq.png) #### 发送打印文件代码参照 以下是局部代码,整体代码请参照上传到git的代码 ```javascript fileUpload () { if (this.fileList.length === 0) { this.$message({ type: 'warning', message: '请先选择文件 !!! ' }) } else { this.$confirm('可以开始打印?', '打印确认', { distinguishCancelAndClose: true, confirmButtonText: '开始打印', cancelButtonText: '取消打印', type: 'info' }).then(async () => { while (this.fileList.length !== 0) { let data = new FormData() data.append('file', this.fileList.shift().raw) try { let response = await startPrint(data) if (response.status === 200) { this.$message({ type: 'success', message: response.data.data }) } } catch (error) { this.$message({ type: 'error', message: '打印失败 : ' + error }) } } }).catch(action => { this.$message({ type: 'info', message: action === 'cancel' ? '已经取消打印' : action }) }) } }, ``` #### 整体画面 ##### 打印设定和发送打印文件画面 ![输入图片说明](print%E7%BB%84%E4%BB%B6%E5%9B%BE.png) ##### 打印历史记录画面 ![输入图片说明](History%E7%BB%84%E4%BB%B6%E5%9B%BE.png) ### 后端设计 #### 模块结构 整体结构,由如下中间件组成。浅绿色部分不是中间件是功能函数。 ![输入图片说明](%E5%90%8E%E7%AB%AF%E6%A8%A1%E5%9D%97%E7%BB%93%E6%9E%84.png) #### 模块关系 ![输入图片说明](%E5%90%8E%E7%AB%AF%E6%A8%A1%E5%9D%97%E5%85%B3%E7%B3%BB%E5%9B%BE.png) #### 模拟打印 模拟打印的实现在printer路由中间件实现,当服务器收到 http://XXXXX:8080/printer/upload 的请求后,读出请求体的文件内容,保存到指定的路径下来完成模拟打印。 ```javascript printer.post('/upload', upload.single('file'), async (req, res, next) => { try { // console.log(req) if (req.file == undefined) { throw new Error('你发送一个空文件'); } else { let parameter = await getParameter() if (parameter == undefined) { res.status(202).send('请先进行打印参数设定') }else{ let name = upload_path + `${req.file.originalname}` await rename(`${req.file.path}`, name) console.log('成功打印' + name) let time = getTime() let db = await getDb() db.upload.push({ "ip": req.ip, "date": time, "file": `${req.file.originalname}`, "parameter": parameter }) await saveDb(db) res.json({ data: `成功收到文件: ${req.file.originalname}` }) } } } catch (error) { next(error) } }) ``` ### 开发环境 #### 前端开发路径 ![输入图片说明](%E5%89%8D%E7%AB%AF%E8%B7%AF%E5%BE%84.png) #### 后端开发路径 ![输入图片说明](%E5%90%8E%E7%AB%AF%E8%B7%AF%E5%BE%84.png)