现在开始尝试写接口了哦
先从一个简单的get请求开始吧。从company模块开始,写一个简单的获取企业信息的接口
company.js中
const router = require('koa-router')()
const msql=require('../mysql/processData')
const myCode=require('../utils/code')
router.prefix('/company')
//获取公司信息
router.get('/getCompanyList', async function (ctx, next) {
await msql.query(ctx,`SELECT * FROM company`)
})
是不是特别简单
但是现实中往往不会这么简单,我们需要携带参数,条件查询。
假设我们需要按状态筛选查询,那么我们的sql语句就要做一下更改,并且要获取参数
router.get('/getCompanyList', async function (ctx, next) {
let {state}=ctx.request.query
await msql.query(ctx,`SELECT * FROM company WHERE state=${state}`)
})
加上模糊查询,比如按企业名称模糊匹配,更改如下
router.get('/getCompanyList', async function (ctx, next) {
let {state,companyName}=ctx.request.query
await msql.query(ctx,`SELECT * FROM company WHERE state=${state},companyName like %${companyName}%`)
})
如果有其他更多的条件,我们也可以按这方式拼。当然了,实际开发中肯定有比这更复杂的条件,比如要加分页,分组查询等。这里暂且 不做讨论
对于相等或模糊查询的条件查询,我们不妨封装一下吧,免得条件变了,就需要改代码。现在就封装一个用来将参数进行拼串的方法,假设前端POST请求时均以json形式传过来,get请求时以query参数传递时用
在utils中新建sqlQs.js,这个名字,是参照前端的qs库来的。总之就这么叫吧,里面封装两个函数,一个用来生成精准匹配和模糊查询匹配的sql条件字符串,一个用来反解析。对于使用模糊查询的条件,我们吧它装在一个数组里面,方便判断。
sqlQs.js
// 将对象转换成mysql更新字符串函数
function stringify(obj,config={}) {
let {likeArr=[]}=config
if(!(obj instanceof Object)){
console.error(`${obj}数据格式错误`)
return
}
let qsStr=''
for (let i in obj){
let connectStr='='
let valueGuard=""
if(likeArr.includes(i)){
//模糊查询
connectStr=' like '
valueGuard=`%`
}
let value=typeof obj[i]==='number' ? obj[i] : `'${valueGuard}${obj[i]}${valueGuard}'`
if(!value && value!==0){
//没有值的不做拼接
continue
}
qsStr+=`,${i}${connectStr}${value}`
}
qsStr=qsStr.replace(',','')
console.log(qsStr)
return qsStr
}
// 将mysql更新字符串函数解析成对象
function parse(str,config={}) {
if(typeof str !=='string'){
console.error(`${str}数据格式错误`)
return
}
let {likeArr=[]}=config
let strArr=str.split(',')
return strArr.reduce((result,current)=>{
let likeIndex=likeArr.findIndex(item=>new RegExp(`^${item}`).test(current))
let connectStr=likeIndex>-1 ? ' like ' : '='
let itemArr=current.split(connectStr)
if(likeIndex>-1){
result[itemArr[1]]=result[itemArr[1]].replaceAll('%','')
}
result[itemArr[0]]=result[itemArr[1]]
return result
},{})
}
module.exports={
stringify,
parse
}
o了,现在我们的get请求接口改成
//获取公司信息,记得要增加sqlQs引入
router.get('/getCompanyList', async function (ctx, next) {
let queryObj= {...ctx.request.query}
query=sqlQs.stringify(queryObj,{likeArr:['companyName']})
await msql.query(ctx,`SELECT * FROM company WHERE ${query}`)
})
然后我们再看看返回给前端的数据,会发现返回的时间字符串格式不是前端想要的,直接从数据库查到的时间,带有T,我们得改下返回的时间格式。那么用mysql的DATE_FORMAT语法即可,DATE_FORMAT(inTime,’%Y-%m-%d %H:%i:%S’) as inTime。更改过后,获取企业信息的接口如下
//获取公司信息
router.get('/getCompanyList', async function (ctx, next) {
let queryObj= {...ctx.request.query}
query=sqlQs.stringify(queryObj,{likeArr:['companyName']})
await msql.query(ctx,`SELECT *,DATE_FORMAT(inTime,'%Y-%m-%d %H:%i:%S') as inTime,DATE_FORMAT(outTime,'%Y-%m-%d %H:%i:%S') as outTime,DATE_FORMAT(createTime,'%Y-%m-%d %H:%i:%S') as createTime,DATE_FORMAT(updateTime,'%Y-%m-%d %H:%i:%S') as updateTime FROM company WHERE ${query}`)
})
我们接着来一个查询详情的接口,由于查询详情只需要通过企业id查询即可,所以我们用不着sqlQs的函数。调用mysql.query函数的时候,传递的isObj:true表示这里需要向浏览器返回对象数据,而不是数组数据。
//获取公司信息详情
router.get('/getCompanyDetail', async function (ctx, next) {
let {companyId}=ctx.request.query
if(!companyId){
ctx.body={
msg:'参数companyId 缺少',
code:myCode.err
}
return
}
await msql.query(ctx,`SELECT *,DATE_FORMAT(inTime,'%Y-%m-%d %H:%i:%S') as inTime,DATE_FORMAT(outTime,'%Y-%m-%d %H:%i:%S') as outTime,DATE_FORMAT(createTime,'%Y-%m-%d %H:%i:%S') as createTime,DATE_FORMAT(updateTime,'%Y-%m-%d %H:%i:%S') as updateTime FROM company WHERE companyId='${companyId}'`,{isObj:true})
})
接下来,我们来写一个新增企业信息的接口。使用post,参数放于body中,前端以json格式传递。新增企业信息是需要吧前端传递的数据插入数据库,并且需要生成唯一键值companyId.
我们先来封装一个简单的生成companyId的函数,使用随机字符串。当然,也可以不用生成companyId这步,可以直接使用数据库自增的id
在utils文件夹中新建snowflake.js文件,代码如下
module.exports=function getId(pre='',randomLength=10,) {
let id= Number(Math.random().toString().substr(3,randomLength)).toString(36)
id=`${pre}${id}`
return id
}
然后写接口,并把数据插入数据库
router.post('/addEditCompanyInfo', async function (ctx, next) {
let checkData={...ctx.request.body}
delete checkData.remark
delete checkData.companyId
if(!Object.keys(checkData).length){
ctx.body={
msg:`没有传入任何值`,
code:myCode.err
}
return
}
for(let i in checkData){
if(!checkData[i]){
ctx.body={
msg:`${i}不可为空`,
code:myCode.err
}
return
}
}
await msql.add(ctx,'INSERT INTO company SET ?',{params:{...ctx.request.body,id:0}})
})
然后写更新企业信息,更新和新增区别仅在于sql语句的不同,更新是根据companyId来更新数据库数据,调用我们封装好的msql.update函数
msql.update(ctx,`UPDATE company SET ${params} WHERE companyId='${companyId}'`)
为了简化代码,这里决定将新增和更新写成一个,依据companyId来判断,若有companyId,做更新处理,没有就做新增处理。最终代码是
//添加编辑公司信息
router.post('/addEditCompanyInfo', async function (ctx, next) {
let checkData={...ctx.request.body}
delete checkData.remark
delete checkData.companyId
if(!Object.keys(checkData).length){
ctx.body={
msg:`没有传入任何值`,
code:myCode.err
}
return
}
for(let i in checkData){
if(!checkData[i]){
ctx.body={
msg:`${i}不可为空`,
code:myCode.err
}
return
}
}
let oldCompanyId=ctx.request.body.companyId
const companyId=oldCompanyId ? oldCompanyId : getId('company-id',18)
if(oldCompanyId){
let params={...ctx.request.body}
delete params.companyId
params=sqlQs.stringify(params)
console.log(params)
await msql.update(ctx,`UPDATE company SET ${params} WHERE companyId='${companyId}'`)
}else{
await msql.add(ctx,'INSERT INTO company SET ?',{params:{...ctx.request.body,companyId,id:0}})
}
})
然后我们再加一个更新公司状态的接口,这个比较简单,就不单独展示了。后面看下完整的接口代码
const router = require('koa-router')()
const msql=require('../mysql/processData')
const getId=require('../utils/snowflake')
const myCode=require('../utils/code')
const sqlQs = require('../utils/sqlQs')
const {formatDateTime}=require('../utils/global-methods')
router.prefix('/company')
//获取公司信息
router.get('/getCompanyList', async function (ctx, next) {
let queryObj= {...ctx.request.query}
query=sqlQs.stringify(queryObj,{likeArr:['companyName']})
await msql.query(ctx,`SELECT *,DATE_FORMAT(inTime,'%Y-%m-%d %H:%i:%S') as inTime,DATE_FORMAT(outTime,'%Y-%m-%d %H:%i:%S') as outTime,DATE_FORMAT(createTime,'%Y-%m-%d %H:%i:%S') as createTime,DATE_FORMAT(updateTime,'%Y-%m-%d %H:%i:%S') as updateTime FROM company WHERE ${query}`)
})
//获取公司信息详情
router.get('/getCompanyDetail', async function (ctx, next) {
let {companyId}=ctx.request.query
if(!companyId){
ctx.body={
msg:'参数companyId 缺少',
code:myCode.err
}
return
}
await msql.query(ctx,`SELECT *,DATE_FORMAT(inTime,'%Y-%m-%d %H:%i:%S') as inTime,DATE_FORMAT(outTime,'%Y-%m-%d %H:%i:%S') as outTime,DATE_FORMAT(createTime,'%Y-%m-%d %H:%i:%S') as createTime,DATE_FORMAT(updateTime,'%Y-%m-%d %H:%i:%S') as updateTime FROM company WHERE companyId='${companyId}'`,{isObj:true})
})
//添加编辑公司信息
router.post('/addEditCompanyInfo', async function (ctx, next) {
let checkData={...ctx.request.body}
delete checkData.remark
delete checkData.companyId
if(!Object.keys(checkData).length){
ctx.body={
msg:`没有传入任何值`,
code:myCode.err
}
return
}
for(let i in checkData){
if(!checkData[i]){
ctx.body={
msg:`${i}不可为空`,
code:myCode.err
}
return
}
}
let oldCompanyId=ctx.request.body.companyId
const companyId=oldCompanyId ? oldCompanyId : getId('company-id',18)
if(oldCompanyId){
let params={...ctx.request.body}
delete params.companyId
params=sqlQs.stringify(params)
console.log(params)
await msql.update(ctx,`UPDATE company SET ${params} WHERE companyId='${companyId}'`)
}else{
await msql.add(ctx,'INSERT INTO company SET ?',{params:{...ctx.request.body,companyId,id:0}})
}
})
//公司进场离场
router.get('/companyInOrLeave', async function (ctx, next) {
let {leaveStatus,companyId}=ctx.request.query
console.log(leaveStatus,companyId)
leaveStatus=parseInt(leaveStatus)
if((leaveStatus!==0 && leaveStatus !==1) || !companyId){
ctx.body={
msg:!companyId ? '参数companyId 缺少' : 'leaveStatus 参数值错误',
code:myCode.err
}
return
}
let outTime=leaveStatus===0 ? `'${formatDateTime(new Date())}'` : null
console.log(outTime)
await msql.update(ctx,`UPDATE company SET leaveStatus=${leaveStatus},outTime=${outTime} WHERE companyId='${companyId}'`,{msg:leaveStatus ? '进场成功' : '退场成功'})
})
module.exports = router