diff --git a/app.js b/app.js index 49e5040..c338468 100644 --- a/app.js +++ b/app.js @@ -6,8 +6,8 @@ var fs = require('fs'); var gm = require('gm'); var db = require('./db'); -var app = express(); +var app = express(); var storage = multer.diskStorage({ destination: function (req, res, cb) { var fileType = req.params["fileType"]; @@ -17,7 +17,6 @@ var storage = multer.diskStorage({ }); var upload = multer({ storage: storage }); //共享页面 -var shareLink = '127.0.0.1/share' app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json({ limit: '50mb' })); @@ -30,33 +29,23 @@ app.use(session({ maxAge: 1000 * 60 * 60 * 24 * 30, // 设置 session 的有效时间,单位毫秒 } })); - //权限判断:拦截器 -app.use(['/create', '/logout', '/home', '/saveScheme', '/getScheme'], function (req, res, next) { +app.use(['/create', '/logout', '/home', '/saveScheme', '/getScheme', '/changeShareConfig'], function (req, res, next) { if (req.session.user) next(); else res.redirect('/'); }); -//临时存储数据 -//var data = { name: '默认方案', components: [], img: null }; +//自定义数据-------------------------------------------------------------------------- +var shareLink = '127.0.0.1/share' -//主页加载:登录页面 +//主页加载:登录页面------------------------------------------------------------------ app.get('/', function (req, res) { res.sendFile(__dirname + "/views/login.html"); }); -//方案创建 -app.get('/create', function (req, res) { - res.sendFile(__dirname + "/views/createScheme.html"); -}); - -app.get('/create/:id', function (req, res) { - res.sendFile(__dirname + "/views/createScheme.html"); -}); - -//登录 +//登录验证 app.post('/', function (req, res) { var account = req.body.account; var password = req.body.password; @@ -71,12 +60,7 @@ app.post('/', function (req, res) { }); }); -//用户注销 -app.get('/logout', function (req, res) { - req.session.user = null; - res.redirect('/'); -}); - +//主页请求---------------------------------------------------------------------------- //用户主页 app.get('/home', function (req, res) { res.sendFile(__dirname + "/views/home.html"); @@ -98,13 +82,80 @@ app.post('/home', function (req, res) { }); }); +//用户注销 +app.get('/logout', function (req, res) { + req.session.user = null; + res.redirect('/'); +}); + +//方案创建 +app.get('/create', function (req, res) { + res.sendFile(__dirname + "/views/createScheme.html"); +}); + +app.get('/create/:id', function (req, res) { + res.sendFile(__dirname + "/views/createScheme.html"); +}); + +// 方案分享配置 +app.post('/changeShareConfig', function (req, res) { + var user = req.session.user; + var data = req.body; + db.changeShareConfig(data.id, user.id, data.share_password, data.share_state, function (row) { + if (row.affectedRows > 0) { + var returnData = { + affectedRows: row.affectedRows + } + res.send(returnData); + } else { + + } + }); +}); + +//方案创建页面-------------------------------------------------------------------------------- +//初始数据获取 +//未创建的方案:获取初始方案 +app.post('/getScheme', function (req, res) { + var data = { name: '默认方案', components: [], img: null, id: null, maxHeight: 10, height: 2, maxDistance: 30, distance: 10 }; + replyData = { + msg: 0, + data: data + } + res.send(replyData); +}); +//已经创建的方案:根据局ID获取初始方案 +app.post('/getScheme/:id', function (req, res) { + var id = req.params['id']; + var user = req.session.user; + if (id) { + db.getSchemeById(user.id, id, function (row) { + if (row.length > 0) { + var data = JSON.parse(row[0].data); + data.id = id; + replyData = { + msg: 0, + data: data + } + res.send(replyData); + } else { + replyData = { + msg: 1 + } + res.send(replyData); + } + }) + } else { + } +}); +//文件上传:分为model文件,texture文件 //接受文件上传,并且返回文件名 app.post('/upload/:fileType', upload.single('file'), function (req, res) { //console.info(req.file) res.send(req.file); }); - -//返回缩略图 +//文件返回 +//贴图文件:返回缩略图 app.get('/files/thumbnail/:filename', function (req, res) { var filename = req.params['filename']; // fs.exists(__dirname + "/uploads/thumbnail/" + filename, function (exist) { @@ -121,14 +172,14 @@ app.get('/files/thumbnail/:filename', function (req, res) { res.sendFile(__dirname + "/uploads/texture/" + filename); }); -//返回文件 +//其他文件(model文件,texture文件):返回文件 app.get('/files/:fileType/:fileName', function (req, res) { //TODO 根据session判断是否有权限获取文件 var fileType = req.params['fileType']; var fileName = req.params['fileName']; res.sendFile(__dirname + "/uploads/" + fileType + "/" + fileName); }); -//------------------------------------------------------------------------------------------------ + //保存方案 app.post('/saveScheme', function (req, res) { var data = req.body; @@ -163,26 +214,49 @@ app.post('/saveScheme', function (req, res) { } // console.info(data); }); -//------------------------------------------------------------------------------------------------ -//获取初始方案 -app.post('/getScheme', function (req, res) { - var data = { name: '默认方案', components: [], img: null, id: null, maxHeight: 10, height: 2, maxDistance: 30, distance: 10 }; - replyData = { - msg: 0, - data: data - } - res.send(replyData); -}); -//根据局ID获取初始方案 -app.post('/getScheme/:id', function (req, res) { + +//分享页面------------------------------------------------------------------------------------------------ +//页面返回 +app.get('/share/:id', function (req, res) { + res.sendFile(__dirname + "/views/share.html"); +}); +//分享状态获取 +app.post('/share/:id', function (req, res) { var id = req.params['id']; - var user = req.session.user; - if (id) { - db.getSchemeById(user.id, id, function (row) { + db.getShareById(id, function (row) { + if (row.length > 0) + res.send(row[0].share_state + ""); + else + //如果没有则返回 + res.send(3 + ""); + }); +}); +//获取分享的data数据 +app.post('/shareData/:id', function (req, res) { + var id = req.params['id']; + var reqData = req.body; + // console.info(reqData); + if (reqData.state == 1) { + db.getShareData(id, function (row) { + if (row.length > 0) { + var data = JSON.parse(row[0].data); + replyData = { + msg: 0, + data: data + } + res.send(replyData); + } else { + replyData = { + msg: 1 + } + res.send(replyData); + } + }) + } else if (reqData.state == 2) { + db.getShareDataByPassword(id, reqData.password, function (row) { if (row.length > 0) { var data = JSON.parse(row[0].data); - data.id = id; replyData = { msg: 0, data: data @@ -195,9 +269,7 @@ app.post('/getScheme/:id', function (req, res) { res.send(replyData); } }) - } else { - } }); - +//------------------------------------------------------------------------------------ app.listen(80); \ No newline at end of file diff --git a/db.js b/db.js index a5cdedf..d6116a9 100644 --- a/db.js +++ b/db.js @@ -106,3 +106,71 @@ module.exports.getSchemeById = function (uid, id, callback) { }); }; +module.exports.changeShareConfig = function (id, uid, share_password, share_state, callback) { + connection.getConnection(function (err, conn) { + if (err) { + console.info(err); + } else { + conn.query('UPDATE scheme SET share_password=?,share_state=? WHERE id =? AND uid =?', [share_password, share_state, id, uid], function (err, rows) { + if (err) { + console.log(err); + return; + } + callback(rows); + conn.release(); + }); + } + }); +}; + + +module.exports.getShareById = function (id, callback) { + connection.getConnection(function (err, conn) { + if (err) { + console.info(err); + } else { + conn.query('SELECT share_state FROM scheme WHERE id =?', [id], function (err, rows) { + if (err) { + console.log(err); + return; + } + callback(rows); + conn.release(); + }); + } + }); +}; + +module.exports.getShareData = function (id, callback) { + connection.getConnection(function (err, conn) { + if (err) { + console.info(err); + } else { + conn.query('SELECT data FROM scheme WHERE id =? AND share_state=?', [id, 1], function (err, rows) { + if (err) { + console.log(err); + return; + } + callback(rows); + conn.release(); + }); + } + }); +}; + +module.exports.getShareDataByPassword = function (id, password, callback) { + connection.getConnection(function (err, conn) { + if (err) { + console.info(err); + } else { + conn.query('SELECT data FROM scheme WHERE id =? AND share_state=? AND share_password=?', [id, 2, password], function (err, rows) { + if (err) { + console.log(err); + return; + } + callback(rows); + conn.release(); + }); + } + }); +}; diff --git a/static/js/createScheme.js b/static/js/createScheme.js index b5cb5ac..439eaac 100644 --- a/static/js/createScheme.js +++ b/static/js/createScheme.js @@ -338,8 +338,8 @@ function initEvent() { var tWidth = sHeigth / 1.2; var tHeigth = sHeigth; //压缩后的像素 - $('#compress')[0].width = 200; - $('#compress')[0].height = 240; + $('#compress')[0].width = 500; + $('#compress')[0].height = 600; //console.info(sWidth + ":" + sHeigth + ":" + tWidth + ":" + tHeigth); //压缩图片 $('#compress')[0].getContext('2d').drawImage(image, (sWidth - tWidth) / 2, (sHeigth - tHeigth) / 2, tWidth, tHeigth, 0, 0, $('#compress')[0].width, $('#compress')[0].height); @@ -578,6 +578,8 @@ function addTexture(url, callBack) { callBack(object); }); } + +//公用方法:模型贴图替换 function replaceTexture(modelObj, textureObj) { modelObj.traverse(function (child) { if (child instanceof THREE.Mesh) { diff --git a/static/js/share.js b/static/js/share.js new file mode 100644 index 0000000..e3fdf6b --- /dev/null +++ b/static/js/share.js @@ -0,0 +1,222 @@ +var data; + +$().ready(function () { + init(); +}); + +//获取数据 初始化data +function init() { + var url = document.location.toString(); + var arrUrl = url.split("share"); + var id = arrUrl[arrUrl.length - 1]; + //ajax请求数据 + $.post("/share" + id, function (reply) { + //拒绝访问 + if (reply == 0) + alert('Sorry, you have no access to this page.'); + //请求数据 + else if (reply == 1) { + var reqData = { + state: 1 + } + $.ajax({ + type: "POST", + url: "/shareData" + id, + data: reqData, + async: false, //同步请求,不然data会出问题 + success: function (remotaData) { + //给全局data赋值 + if (remotaData.msg == 0) { + data = remotaData.data; + initUi(); + initThree(); + loadModel(); + initEvent(); + } + else + alert('Sorry, some problems have arisen.'); + } + }); + } + //密码访问 + else if (reply == 2) { + $('#visitPasswordModal').modal('show'); + $('#visitBtn').click(function () { + var password = $('#visitPassword').val().trim(); + var reqData = { + state: 2, + password: password + } + $.ajax({ + type: "POST", + url: "/shareData" + id, + data: reqData, + async: false, //同步请求,不然data会出问题 + success: function (remotaData) { + //给全局data赋值 + if (remotaData.msg == 0) { + data = remotaData.data; + $('#visitPassword').val(''); + $('#visitPasswordModal').modal('hide'); + initUi(); + initThree(); + loadModel(); + initEvent(); + } + else { + $('#visitPassword').val(''); + alert('Sorry, some problems have arisen.'); + } + } + }); + }); + } else { + alert('Sorry, some problems have arisen.'); + } + }); +} + +//------------------------------------------------------------------------------ +//界面初始化 +function initUi() { + +} +//------------------------------------------------------------------------------ +//threejs配置 +function initThree() { + initScene(); + initCamera(); + initRenderer(); + render(); +} + +function initScene() { + //场景设置 + scene = new THREE.Scene(); + //设置天空盒 + scene.background = new THREE.CubeTextureLoader() + .setPath('/img/skybox/') + .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']); + //场景灯光 + //环境光 + var light = new THREE.HemisphereLight(0xffffff, 0x444444); + light.position.set(0, 2, 0); + scene.add(light); + //直射光 + light = new THREE.DirectionalLight(0xffffff); + light.position.set(0, 2, 1); + light.castShadow = true; + light.shadow.camera.top = 180; + light.shadow.camera.bottom = - 100; + light.shadow.camera.left = - 120; + light.shadow.camera.right = 120; + scene.add(light); + //grid + var grid = new THREE.GridHelper(20, 20, 0x0000ff, 0xff0000); + grid.material.opacity = 0.2; + grid.material.transparent = true; + scene.add(grid); +} + +function initCamera() { + //相机设置 + camera = new THREE.PerspectiveCamera(45, $('#viewField').innerWidth() / $('#viewField').innerHeight()); + camera.position.y = data.height; + controls = new THREE.OrbitControls(camera, $('#viewField')[0]); + controls.target.set(0, data.height, 0); + controls.maxPolarAngle = Math.PI / 2; + controls.minPolarAngle = Math.PI / 2; + controls.minDistance = data.distance; + controls.maxDistance = data.distance; + controls.enablePan = false; + controls.enableKeys = false; + controls.update(); +} + +function initRenderer() { + //初始化渲染器 + renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true }); + //设置像素值 + renderer.setPixelRatio(window.devicePixelRatio); + //设置渲染范围为屏幕的大小 + renderer.setSize($('#viewField').innerWidth(), $('#viewField').innerHeight()); + //将渲染结果放到页面中 + $('#viewField').append(renderer.domElement); +} + +function render() { + requestAnimationFrame(render); + renderer.render(scene, camera); +} +//------------------------------------------------------------------------------ +//初始化模型 +function loadModel() { + var manager = new THREE.LoadingManager(); + manager.onLoad = function () { + initTexture(); + }; + //模型加载 + var loader = new THREE.FBXLoader(manager); + for (var comIndex in data.components) { + for (var molIndex in data.components[comIndex].models) { + //异步加载问题 + (function (comIndex, molIndex) { + var url = '/files/model/' + data.components[comIndex].models[molIndex].fileId; + loader.load(url, function (object) { + object.visible = (data.components[comIndex].modelIndex == molIndex); + data.components[comIndex].models[molIndex].modelObj = object; + scene.add(object); + } + ); + })(comIndex, molIndex); + } + } + //贴图加载 + var loader = new THREE.TextureLoader(manager); + for (var comIndex in data.components) { + for (var textureIndex in data.components[comIndex].textures) { + //异步加载问题 + (function (comIndex, textureIndex) { + var url = '/files/texture/' + data.components[comIndex].textures[textureIndex].fileId; + loader.load(url, function (object) { + data.components[comIndex].textures[textureIndex].textureObj = object; + } + ); + })(comIndex, textureIndex); + } + } +} + +//当模型和贴图都加载结束后,给模型赋予默认贴图 +function initTexture() { + for (var comIndex in data.components) { + var modelIndex = data.components[comIndex].modelIndex; + var textureIndex = data.components[comIndex].textureIndex; + //赋贴图 + if (data.components[comIndex].models.length > 0 && data.components[comIndex].textures.length > 0) + replaceTexture(data.components[comIndex].models[modelIndex].modelObj, data.components[comIndex].textures[textureIndex].textureObj); + } +} +//------------------------------------------------------------------------------ +//事件初始化 +function initEvent() { + //当浏览器大小变化时 + $(window).resize(function () { + camera.aspect = $('#viewField').innerWidth() / $('#viewField').innerHeight(); + camera.updateProjectionMatrix(); + renderer.setSize($('#viewField').innerWidth(), $('#viewField').innerHeight()); + }); +} + +//------------------------------------------------------------------------------ +//公用方法 +function replaceTexture(modelObj, textureObj) { + modelObj.traverse(function (child) { + if (child instanceof THREE.Mesh) { + child.material.map = textureObj; + child.material.castShadow = true; + child.material.receiveShadow = true; + child.material.needsUpdate = true; + } + }); +} \ No newline at end of file diff --git a/views/createScheme.html b/views/createScheme.html index 6d6c7bc..cbe3cde 100644 --- a/views/createScheme.html +++ b/views/createScheme.html @@ -54,10 +54,6 @@ #textureField>img{ margin-top:5px; } - #cameraConfig>*{ - margin-top:5px; - margin-bottom:5px; - } @@ -78,11 +74,12 @@
-
+
xx

-
+
xx
@@ -104,9 +101,7 @@
- +

请先选择部件

@@ -190,7 +185,7 @@
- + diff --git a/views/home.html b/views/home.html index 90bc39a..189ec8c 100644 --- a/views/home.html +++ b/views/home.html @@ -150,6 +150,29 @@ $('#isShared').attr("checked", true); break; } + $('#changeShareConfig').click(function () { + var needPassword = $('#needPassword').is(":checked") + var isShared = $('#isShared').is(":checked") + var share_password = $('#sharePassword').val(); + var share_state = 0; + if (isShared) + share_state = 1; + if (needPassword && share_state) + share_state = 2; + var sendData = { + id: data.schemeList[index].id, + share_password: share_password, + share_state: share_state + } + $.post('/changeShareConfig', sendData, function (reply) { + if (reply.affectedRows) { + data.schemeList[index].share_password = share_password; + data.schemeList[index].share_state = share_state; + $('#shareSchemeModal').modal('hide'); + } + }); + + }); } diff --git a/views/login.html b/views/login.html index b5dd9fa..5807c5e 100644 --- a/views/login.html +++ b/views/login.html @@ -11,7 +11,6 @@ - + +
+ +
+ + + \ No newline at end of file