1、crm开发定制先创建数据库,crm开发定制再创建集合,crm开发定制用到了数据库图形界面Robo 3T,crm开发定制数据集合如下所示:
2、crm开发定制安装脚手架
npm i express-generator -g //crm开发定制在终端中输入
- 1
3、创建项目
express stuSystem //crm开发定制执行完成之后根据提示crm开发定制执行以下内容: cd stuSystem //进入stuSystem这个目录 npm install //安装相关的依赖包 npm start //服务器运行开始
- 1
- 2
- 3
- 4
4、在浏览器中输入http://localhost:3000/,结果如下:
5、进行完第4步,就搭建好了项目,项目的目录结构如下:
- app.js:入口文件 - bin:二进制目录 - node_modules:依赖包 - package.json:依赖包的记录文件 - public:静态目录 - routes:路由 - views:页面模板
- 1
- 2
- 3
- 4
- 5
- 6
- 7
6、现在开始创建学生管理系统相关的文件:
- 在public文件夹下创建一个index.html文件 (public是专门用来管理静态资源的,在public下创建index.html,express就会自动访问到它),服务器一启动就运行。
- 在routes路由这个文件夹建stu.js文件,用于接收前端ajax请求,以及返回响应数据
- 修改app.js文件的有关内容(app.js文件是生成项目就有的)
var stuRouter = require('./routes/stu');//在路由这个文件夹下面创建了stu.js文件,在这里通过require()引入这个文件,定义一个stuRouter变量来得到 app.use('/stu', stuRouter); //注册中间件stuRouter
- 1
- 2
- 在目录中创建Service文件夹,创建stuService.js文件
- 在目录中创建Dao文件夹,创建stuDao.js文件、db.js文件以及Model文件夹,再在Model下创建stuModel.js文件
整体文件如下:
7、上面介绍了项目大体的文件,接下来是具体的内容,具体的内容涉及到两个知识点:
- Restful(表现层状态转移)
- Restful就是规范url,url本身就是标志资源的,不应该标志这个资源要做什么,例如下面两条url都是标志删除资源的操作
http://abc.com/?method=comment.del&id=XXX http://abc.com/comment/del/xxx
- 1
- 2
- 所以应该使用 http不同的请求方式来表达要对一个资源做什么事情:
- 新增:【POST】http://abc.com/comment - 查询:【GET】http://abc.com/comment/x - 删除:【DELETE】http://abc.com/comment/x - 修改:【PUT】http://abc.com/comment/x
- 1
- 2
- 3
- 4
- 三层架构
- 表示层: 主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。
- 业务逻辑层: 主要负责对数据层的操作。也就是说把一些数据层的操作进行组合。
- 数据访问层: 主要看数据层里面有没有包含逻辑处理,实际上它的各个函数主要完成各个对数据文件的操作。而不必管其他操作。
- 具体的实现就是目录表中对应的文件夹:
- routes:表现层 - service:业务层 - dao:持久层
- 1
- 2
- 3
8、具体文件内容:
index.html
//这是html部分 <div class="container"> <h1>学生管理系统</h1> <form> <!-- 姓名 --> <div> <label for="name">姓名:</label> <input type="text" name="name" id="name"> </div> <!-- 年龄 --> <div> <label for="age">年龄:</label> <input type="text" name="age" id="age"> </div> <!-- 性别 --> <div> <label for="gender">性别:</label> <input type="radio" name="gender" value="男" id="male" checked>男 <input type="radio" name="gender" value="女" id="female">女 </div> <!-- 分数 --> <div> <label for="score">分数:</label> <input type="text" name="score" id="score"> </div> <!-- 提交、重置 --> <div class="btn"> <input type="button" value="提交" class="submitBtn"> <input type="reset" value="重置" class="reset"> </div> </form> <h2>学生信息表</h2> <table></table> </div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
//javascript部分 <script> let id =0; // 渲染表格的render函数 function render(arr) { $('table').html(''); let tHead = ` <tr> <th>学生姓名</th> <th>学生年龄</th> <th>学生性别</th> <th>学生分数</th> <th>操作</th> </tr> `; let tBody = arr.map(item => { return ` <tr> <td>${item.name}</td> <td>${item.age}</td> <td>${item.gender}</td> <td>${item.score}</td> <td> <button class="editBtn" data-id=${item._id}>修改</button> <button class="delBtn" data-id=${item._id}>删除</button> </td> </tr> ` }).join(''); $("table").html(tHead + tBody); } // 发送请求到后端得到数据库数据 const stuInfo = function () { $.ajax({ url: '/stu', type: 'GET', success: function (data) { render(data); } }) }; stuInfo(); // submit按钮绑定点击事件,(既是提交也是修改) $(".submitBtn").on('click', function () { let data = $("form").serializeArray(); if (data.every(item => { return item.value !== '' })) { // 根据提交按钮的文字来判定用户是做新增还是修改 if ($(".submitBtn").val() === '提交') { // 新增操作 $.ajax({ url: '/stu', type: 'POST', data: $('form').serialize(), success: function (data) { $('form')[0].reset(); stuInfo(); } }) } else { // 修改操作 $.ajax({ url: '/stu', type: 'PUT', data: { id, info: $('form').serialize()}, success: function (data) { $('form')[0].reset(); $('.submitBtn').val('提交'); stuInfo(); } }) } } else { window.alert("不能为空!!!!") } }) // 获取一个学生信息 const oneStuInfo=async function(id){ return new Promise((resolve,reject)=>{ $.ajax({ url:'/stu/findOneStu', type:'GET', data:{id}, success:function(data){ resolve(data); } }) }) } // 删除(事件委托) $('table').on('click','.delBtn',async function(e){ let data=await oneStuInfo(e.target.dataset.id); if(window.confirm(`你确定要删除此学生吗? 学生姓名:${data[0].name} 学生年龄:${data[0].age} 学生性别:${data[0].gender} 学生分数:${data[0].score} `)){ $.ajax({ url:'/stu', type:'DELETE', data:{id:e.target.dataset.id}, success:function(){ stuInfo(); } }); } }); //修改(事件委托) $('table').on("click",".editBtn",async function(e){ let data=await oneStuInfo(e.target.dataset.id); id=e.target.dataset.id; // 将数据进行回填 $('#name').val(data[0].name); $('#age').val(data[0].age); if(data[0].gender==='男'){ $('#male').prop('checked',true); }else{ $('#female').prop('checked',true); } $('#score').val(data[0].score); $('.submitBtn').val("修改"); }) </script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
stu.js
// 表现层//在这里就用到了Restful(表现层状态转移)var express = require('express');var router = express.Router();const {findStuService,addStuService,findOneStuService,delStuService,editStuService} = require('../Service/stuService');router.get('/', async function (req, res, next) { res.send(await findStuService());});// 增加学生router.post('/', async function (req, res, next) { res.send(await addStuService(req.body));});// 获取一个学生信息router.get('/findOneStu', async function (req, res, next) { res.send(await findOneStuService(req.query.id));});// 删除学生信息router.delete('/', async function (req, res, next) { res.send(await delStuService(req.body.id));});// 修改学生信息router.put('/', async function (req, res, next) { console.log(req.body); res.send(await editStuService(req.body));});module.exports = router;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
stuService.js
// 这一层就是业务层const urlencode = require('urlencode');const {findStuDao,addStuDao,findOneStuDao,delStuDao,editStuDao} = require('../Dao/stuDao');// 查找所有进行渲染表格module.exports.findStuService = async function(){ console.log(findStuDao,'func') return await findStuDao()}// 增加学生module.exports.addStuService = async function(newStu){ return await addStuDao(newStu)}// 获取一个学生信息module.exports.findOneStuService = async function(id){ return await findOneStuDao(id);}// 删除学生信息module.exports.delStuService = async function(id){ return await delStuDao(id);}// 修改学生信息module.exports.editStuService = async function(stu){ // 'name=%E5%90%8E%E5%A4%A9&age=44&gender=%E7%94%B7&score=34' let stuInfo=urlencode.decode(stu.info).split('&').map(item=>{ return item.split('='); }); let data={}; for(let i of stuInfo){ data[i[0]]=i[1]; //键=值 } data.id=stu.id; return await editStuDao(data);}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
stuDao.js
//持久层const stuModel = require('./Model/stuModel');// 查找所有进行渲染表格module.exports.findStuDao = async function () { return await stuModel.find();}// 增加学生module.exports.addStuDao = async function (newStu) { console.log(newStu); return await stuModel.create(newStu);}// 获取一个学生信息module.exports.findOneStuDao = async function (id) { return await stuModel.find({_id : id});}// 删除学生信息module.exports.delStuDao = async function (id) { return await stuModel.deleteOne({_id : id}); }// 修改学生信息module.exports.editStuDao = async function(stu){ // {"name":"xiejie"},{"name" : "谢杰"} console.log(stu); return await stuModel.updateOne({_id : stu.id},stu);}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
stuModel.js
// stuModel.js是数据模型文件require('../db.js')const mongoose = require('mongoose');// 1. 创建 Schema,Schema 就是我们数据模型的骨架// 在创建 Schema,就需要和集合(表)进行对应const stuSchema = new mongoose.Schema({ name: String, age: Number, gender: String, score:Number},{versionKey:false});// 2. 根据上面创建的 Schema 来生成数据模型// (1) model 的名字 (2)定义的 Schema (3)和数据库的哪个集合关联mongoose.model('stuModel', stuSchema, 'student');//相对应的集合// 3. 将这个模型导出去,后面所有的操作(增删改查)都是基于这个模型module.exports = mongoose.model('stuModel');
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
db.js
// 这个文件负责书写连接数据库的相关配置const mongoose = require('mongoose');const dbURI = 'mongodb://localhost/students'; // 配置要连接的数据库mongoose.connect(dbURI,{useNewUrlParser : true, useUnifiedTopology : true});mongoose.connection.on('connected',()=>{ console.log('数据库已经连接...');})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9