# hospital **Repository Path**: jxmlearner/hospital ## Basic Information - **Project Name**: hospital - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-09-16 - **Last Updated**: 2021-11-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 初始化项目 ```bash npm init -y npm i koa @koa/router koa-json koa-logger -S npm i koa-static koa-body koa-views ejs -S npm i glob -S npm i nodemon -D ``` ## 生成应用 ```js // src/app.js const Koa = require('koa') const json = require('koa-json') const logger = require('koa-logger') const serve = require('koa-static') const views = require('koa-views') const koaBody = require('koa-body') const path = require('path') // 导入path包 用于拼接路径 const router = require('./router') const app = new Koa() app.use(json()) app.use(logger()) app.use(koaBody()) app.use(serve(path.join(__dirname, 'static'))) app.use(views(path.join(__dirname, 'views'), { map: { html: 'ejs' } })) app.use(router.routes(), router.allowedMethods()) app.listen(8000, () => { console.log('server is running at http://localhost:8000') }) ``` ```js // src/router/index.js const Router = require('@koa/router') const glob = require('glob') const { resolve } = require('path') const router = new Router() router.get('/', async (ctx) => { await ctx.render('index') }) // 遍历router目录下所有js文件,自动注册成路由 glob .sync(resolve(__dirname, './', '**/*.js')) .filter((value) => value.indexOf('index.js') === -1) // 跳过index.js .map((modulePath) => { const moduleRouter = require(modulePath) router.use(moduleRouter.routes(), moduleRouter.allowedMethods()) }) module.exports = router ``` ## vxe-table 安装 这里使用支持 vue3 的 vxe-table4.x 版本:https://xuliangzhan_admin.gitee.io/vxe-table/v4/table/start/install 为了方便前端提取 js,临时安装 `npm install xe-utils@3 vxe-table@next -D` 到 `devDependencies` 里, 当前也可以安装完成之后将其删除。 ```html ``` 使用 ```js function useTable(app) { app.use(VXETable) // 给 vue 实例挂载内部对象,例如: // app.config.globalProperties.$XModal = VXETable.modal // app.config.globalProperties.$XPrint = VXETable.print // app.config.globalProperties.$XSaveFile = VXETable.saveFile // app.config.globalProperties.$XReadFile = VXETable.readFile } createApp(App).use(useTable).mount('#app') ``` ## 父元素 flex:1 子元素 height:100%失效的解决办法 1. 通过设置父元素 height:0; 同理 width 。这个方法还能解决 flex:1 超出省略号 css 失效。 这个方法 safari 浏览器目前还不兼容,但是 chrome 有效 ```css .layout-main { background-color: var(--layout-main-bg-color); padding: 0 20px 20px; height: 0; } .layout-main-inner { width: 100%; height: 100%; background-color: var(--system-primary-text-color); } ``` 2. 父元素 与 子元素 通过定位解决。 ```css /* 父元素 */ .parent { position: relative; } .child { position: absolute; top: 0; right: 0; bottom: 0; left: 0; } ``` ## koa 文件上传 ```js // app.js const koa = require('koa') const app = new koa() const koaBody = require('koa-body') app.use( koaBody({ multipart: true, formidable: { maxFileSize: 200 * 1024 * 1024 // 设置上传文件大小最大限制,默认2M } }) ) app.listen(3001, () => { console.log('koa is listening in 3001') }) ``` 使用中间件后,就可以在 ctx.request.body.files 中获取上传的文件内容。需要注意的就是设置 maxFileSize,不然上传文件一超过默认限制就会报错。 接收到文件之后,我们需要把文件保存到目录中,返回一个 url 给前端。在 node 中的流程为 - 创建可读流 const reader = fs.createReadStream(file.path) - 创建可写流 const writer = fs.createWriteStream('upload/newpath.txt') - 可读流通过管道写入可写流 reader.pipe(writer) ```js const router = require('koa-router')(); const fs = require('fs'); router.post('/upload', async (ctx){ const file = ctx.request.body.files.file; // 获取上传文件 const reader = fs.createReadStream(file.path); // 创建可读流 const ext = file.name.split('.').pop(); // 获取上传文件扩展名 const upStream = fs.createWriteStream(`upload/${Math.random().toString()}.${ext}`); // 创建可写流 reader.pipe(upStream); // 可读流通过管道写入可写流 return ctx.body = '上传成功'; }) ``` ## dayjs ```bash npm install dayjs --save ``` ## 处理 excel ```bash npm install xlsx --save ``` ```js module.exports = { uploadExcel: async (ctx) => { const file = ctx.request.files.file // 获取上传文件 const reader = fs.createReadStream(file.path) // 创建可读流 const ext = file.name.split('.').pop() // 获取上传文件扩展名 const fileName = dayjs().format('YYYYMMDDHHmmss') + '.' + ext const savePath = path.resolve(__dirname, `../uploadExcels/${fileName}`) const upStream = fs.createWriteStream(savePath) // 创建可写流 await getFile(reader, upStream) // 等待数据存储完成 const workbook = xlsx.readFile(savePath) let json = xlsx.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]) if (json && json.length) { json = json.map((item) => { const newItem = {} for (const [itemKey, itemValue] of Object.entries(item)) { const newKey = excelColumnMap[itemKey] newItem[newKey] = itemValue } console.log(newItem) return newItem }) } ctx.body = { code: 200, data: json, msg: '上传成功' } } } ``` ## vue3 中路由结合 keep-alive ```html ``` ## 计算属性的使用 ```js setup() { const { ref, reactive, computed, nextTick } = Vue const tableData = ref([]) const uploadSuccess = (response, file, fileList) => { if (response.code === 200) { console.log(response.data) tableData.value = response.data ElMessage.success(response.msg) } } const filteredTableData = computed(() => { // 对表格数据进行搜索过滤 return searchForm.code ? tableData.value.filter((x) => ('' + x.code).indexOf(searchForm.code) > -1) : tableData.value }) return { tableData, filteredTableData } } ``` ## `Sequelize` 文档地址: https://sequelize.org/master/ ```bash npm install --save sequelize pg # 使用postgres数据库 ``` ## `vue3` 中对 `dialog` 封装 1. 子组件 ```js // 点评页 const CommentDialog = { template: ` `, props: { dialogVisible: { type: Boolean, default: false } }, emits: ['update:dialogVisible', 'on-confirm'], setup(props, { emit }) { const { reactive, toRefs, watch } = Vue const { dialogVisible } = toRefs(props) const state = reactive({ visible: dialogVisible.value }) watch( dialogVisible, (newValue) => { state.visible = newValue }, { immediate: true } ) const onClose = () => { emit('update:dialogVisible', false) } const onConfirm = () => { emit('on-confirm', '子组件的值') } return { ...toRefs(state), onClose, onConfirm } } } ``` 2. 父组件 ```js const HistoryComponent = { template: `
...其它内容
`, setup() { const { ref } = Vue // const { pageData, pageChange } = usePagerEffect(loadHistoryData) const dialogVisible = ref(false) const onShowComment = (row) => { const { code } = row dialogVisible.value = true } const onCommentConfirm = () => { dialogVisible.value = false } return { dialogVisible, onShowComment, onCommentConfirm } } } ``` ## excel 文件的下载 1. 前端 ```js // 导出 const exportExcel = () => { axios .post( '/comment/export', {}, { responseType: 'blob' } ) .then((res) => { const stream = res.data // 后端用stream返回Excel文件 const blob = new Blob([stream]) // 前端获取业务码,成功执行正常业务 const downloadElement = document.createElement('a') const href = window.URL.createObjectURL(blob) // 创建下载的链接 downloadElement.href = href downloadElement.download = '测试下载.xlsx' // 下载后文件名 document.body.appendChild(downloadElement) downloadElement.click() // 点击下载 document.body.removeChild(downloadElement) // 下载完成移除元素 window.URL.revokeObjectURL(href) // 释放掉blob对象 }) } ``` 2. 后端导出 excel ```js const xlsx = require('xlsx') exportExcel: async (ctx) => { const jsonData = [ { username: 'jiang', age: 40 }, { username: 'jancy', age: 30 }, { username: 'test', age: 20 } ] const ws = xlsx.utils.json_to_sheet(jsonData) const wb = xlsx.utils.book_new() // 创建一个空的workbook xlsx.utils.book_append_sheet(wb, ws, 'Sheet1') xlsx.writeFileSync(wb, '导出测试.xlsx') //类型 ctx.type = '.xlsx' //请求返回,生成的xlsx文件 ctx.body = fs.readFileSync('导出测试.xlsx') //请求返回后,删除生成的xlsx文件,不删除也行,下次请求回覆盖 fs.unlink('导出测试.xlsx', (err) => { if (err) { console.log(err) throw err } }) } ``` ## 记录 koa 的日志 参考:https://www.cnblogs.com/HoChine/p/10717831.html