@ -0,0 +1,5 @@ |
|||||||
|
[*.{js,jsx,ts,tsx,vue}] |
||||||
|
indent_style = space |
||||||
|
indent_size = 2 |
||||||
|
trim_trailing_whitespace = true |
||||||
|
insert_final_newline = true |
@ -0,0 +1,21 @@ |
|||||||
|
.DS_Store |
||||||
|
node_modules |
||||||
|
/dist |
||||||
|
|
||||||
|
# local env files |
||||||
|
.env.local |
||||||
|
.env.*.local |
||||||
|
|
||||||
|
# Log files |
||||||
|
npm-debug.log* |
||||||
|
yarn-debug.log* |
||||||
|
yarn-error.log* |
||||||
|
|
||||||
|
# Editor directories and files |
||||||
|
.idea |
||||||
|
.vscode |
||||||
|
*.suo |
||||||
|
*.ntvs* |
||||||
|
*.njsproj |
||||||
|
*.sln |
||||||
|
*.sw? |
@ -0,0 +1,29 @@ |
|||||||
|
# v3dmodel |
||||||
|
|
||||||
|
## Project setup |
||||||
|
``` |
||||||
|
npm install |
||||||
|
``` |
||||||
|
|
||||||
|
### Compiles and hot-reloads for development |
||||||
|
``` |
||||||
|
npm run serve |
||||||
|
``` |
||||||
|
|
||||||
|
### Compiles and minifies for production |
||||||
|
``` |
||||||
|
npm run build |
||||||
|
``` |
||||||
|
|
||||||
|
### Run your tests |
||||||
|
``` |
||||||
|
npm run test |
||||||
|
``` |
||||||
|
|
||||||
|
### Lints and fixes files |
||||||
|
``` |
||||||
|
npm run lint |
||||||
|
``` |
||||||
|
|
||||||
|
### Customize configuration |
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/). |
@ -0,0 +1,5 @@ |
|||||||
|
module.exports = { |
||||||
|
presets: [ |
||||||
|
'@vue/app' |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
{ |
||||||
|
"name": "v3dmodel", |
||||||
|
"version": "0.1.0", |
||||||
|
"private": true, |
||||||
|
"scripts": { |
||||||
|
"serve": "vue-cli-service serve", |
||||||
|
"build": "vue-cli-service build", |
||||||
|
"lint": "vue-cli-service lint" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"core-js": "^2.6.5", |
||||||
|
"qrious": "^4.0.2", |
||||||
|
"three": "^0.103.0", |
||||||
|
"vue": "^2.6.10", |
||||||
|
"vue-resource": "^1.5.1", |
||||||
|
"vue-router": "^3.0.3", |
||||||
|
"vuetify": "^1.5.5", |
||||||
|
"vuex": "^3.0.1" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@vue/cli-plugin-babel": "^3.6.0", |
||||||
|
"@vue/cli-plugin-eslint": "^3.6.0", |
||||||
|
"@vue/cli-service": "^3.6.0", |
||||||
|
"@vue/eslint-config-standard": "^4.0.0", |
||||||
|
"babel-eslint": "^10.0.1", |
||||||
|
"eslint": "^5.16.0", |
||||||
|
"eslint-plugin-vue": "^5.0.0", |
||||||
|
"stylus": "^0.54.5", |
||||||
|
"stylus-loader": "^3.0.1", |
||||||
|
"vue-cli-plugin-vuetify": "^0.5.0", |
||||||
|
"vue-template-compiler": "^2.5.21", |
||||||
|
"vuetify-loader": "^1.0.5" |
||||||
|
}, |
||||||
|
"eslintConfig": { |
||||||
|
"root": true, |
||||||
|
"env": { |
||||||
|
"node": true |
||||||
|
}, |
||||||
|
"extends": [ |
||||||
|
"plugin:vue/essential", |
||||||
|
"@vue/standard" |
||||||
|
], |
||||||
|
"parserOptions": { |
||||||
|
"parser": "babel-eslint" |
||||||
|
} |
||||||
|
}, |
||||||
|
"postcss": { |
||||||
|
"plugins": { |
||||||
|
"autoprefixer": {} |
||||||
|
} |
||||||
|
}, |
||||||
|
"browserslist": [ |
||||||
|
"> 1%", |
||||||
|
"last 2 versions", |
||||||
|
"not ie <= 8" |
||||||
|
] |
||||||
|
} |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 225 KiB |
After Width: | Height: | Size: 449 KiB |
After Width: | Height: | Size: 306 KiB |
After Width: | Height: | Size: 268 KiB |
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 370 KiB |
After Width: | Height: | Size: 3.0 MiB |
After Width: | Height: | Size: 3.0 MiB |
After Width: | Height: | Size: 3.0 MiB |
After Width: | Height: | Size: 3.0 MiB |
After Width: | Height: | Size: 3.0 MiB |
After Width: | Height: | Size: 3.0 MiB |
@ -0,0 +1,20 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0"> |
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
||||||
|
<title>V3D</title> |
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"> |
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons"> |
||||||
|
<script src="./js/inflate.min.js"></script> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<noscript> |
||||||
|
<strong>We're sorry but v3dmodel doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
||||||
|
</noscript> |
||||||
|
<div id="app"></div> |
||||||
|
<!-- built files will be auto injected --> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,15 @@ |
|||||||
|
/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';var l=void 0,aa=this;function r(c,d){var a=c.split("."),b=aa;!(a[0]in b)&&b.execScript&&b.execScript("var "+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&d!==l?b[e]=d:b=b[e]?b[e]:b[e]={}};var t="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function v(c){var d=c.length,a=0,b=Number.POSITIVE_INFINITY,e,f,g,h,k,m,n,p,s,x;for(p=0;p<d;++p)c[p]>a&&(a=c[p]),c[p]<b&&(b=c[p]);e=1<<a;f=new (t?Uint32Array:Array)(e);g=1;h=0;for(k=2;g<=a;){for(p=0;p<d;++p)if(c[p]===g){m=0;n=h;for(s=0;s<g;++s)m=m<<1|n&1,n>>=1;x=g<<16|p;for(s=m;s<e;s+=k)f[s]=x;++h}++g;h<<=1;k<<=1}return[f,a,b]};function w(c,d){this.g=[];this.h=32768;this.d=this.f=this.a=this.l=0;this.input=t?new Uint8Array(c):c;this.m=!1;this.i=y;this.r=!1;if(d||!(d={}))d.index&&(this.a=d.index),d.bufferSize&&(this.h=d.bufferSize),d.bufferType&&(this.i=d.bufferType),d.resize&&(this.r=d.resize);switch(this.i){case A:this.b=32768;this.c=new (t?Uint8Array:Array)(32768+this.h+258);break;case y:this.b=0;this.c=new (t?Uint8Array:Array)(this.h);this.e=this.z;this.n=this.v;this.j=this.w;break;default:throw Error("invalid inflate mode"); |
||||||
|
}}var A=0,y=1,B={t:A,s:y}; |
||||||
|
w.prototype.k=function(){for(;!this.m;){var c=C(this,3);c&1&&(this.m=!0);c>>>=1;switch(c){case 0:var d=this.input,a=this.a,b=this.c,e=this.b,f=d.length,g=l,h=l,k=b.length,m=l;this.d=this.f=0;if(a+1>=f)throw Error("invalid uncompressed block header: LEN");g=d[a++]|d[a++]<<8;if(a+1>=f)throw Error("invalid uncompressed block header: NLEN");h=d[a++]|d[a++]<<8;if(g===~h)throw Error("invalid uncompressed block header: length verify");if(a+g>d.length)throw Error("input buffer is broken");switch(this.i){case A:for(;e+ |
||||||
|
g>b.length;){m=k-e;g-=m;if(t)b.set(d.subarray(a,a+m),e),e+=m,a+=m;else for(;m--;)b[e++]=d[a++];this.b=e;b=this.e();e=this.b}break;case y:for(;e+g>b.length;)b=this.e({p:2});break;default:throw Error("invalid inflate mode");}if(t)b.set(d.subarray(a,a+g),e),e+=g,a+=g;else for(;g--;)b[e++]=d[a++];this.a=a;this.b=e;this.c=b;break;case 1:this.j(ba,ca);break;case 2:for(var n=C(this,5)+257,p=C(this,5)+1,s=C(this,4)+4,x=new (t?Uint8Array:Array)(D.length),S=l,T=l,U=l,u=l,M=l,F=l,z=l,q=l,V=l,q=0;q<s;++q)x[D[q]]= |
||||||
|
C(this,3);if(!t){q=s;for(s=x.length;q<s;++q)x[D[q]]=0}S=v(x);u=new (t?Uint8Array:Array)(n+p);q=0;for(V=n+p;q<V;)switch(M=E(this,S),M){case 16:for(z=3+C(this,2);z--;)u[q++]=F;break;case 17:for(z=3+C(this,3);z--;)u[q++]=0;F=0;break;case 18:for(z=11+C(this,7);z--;)u[q++]=0;F=0;break;default:F=u[q++]=M}T=t?v(u.subarray(0,n)):v(u.slice(0,n));U=t?v(u.subarray(n)):v(u.slice(n));this.j(T,U);break;default:throw Error("unknown BTYPE: "+c);}}return this.n()}; |
||||||
|
var G=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],D=t?new Uint16Array(G):G,H=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],I=t?new Uint16Array(H):H,J=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],K=t?new Uint8Array(J):J,L=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],da=t?new Uint16Array(L):L,ea=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12, |
||||||
|
13,13],N=t?new Uint8Array(ea):ea,O=new (t?Uint8Array:Array)(288),P,fa;P=0;for(fa=O.length;P<fa;++P)O[P]=143>=P?8:255>=P?9:279>=P?7:8;var ba=v(O),Q=new (t?Uint8Array:Array)(30),R,ga;R=0;for(ga=Q.length;R<ga;++R)Q[R]=5;var ca=v(Q);function C(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h;b<d;){if(f>=g)throw Error("input buffer is broken");a|=e[f++]<<b;b+=8}h=a&(1<<d)-1;c.f=a>>>d;c.d=b-d;c.a=f;return h} |
||||||
|
function E(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h=d[0],k=d[1],m,n;b<k&&!(f>=g);)a|=e[f++]<<b,b+=8;m=h[a&(1<<k)-1];n=m>>>16;if(n>b)throw Error("invalid code length: "+n);c.f=a>>n;c.d=b-n;c.a=f;return m&65535} |
||||||
|
w.prototype.j=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length-258,f,g,h,k;256!==(f=E(this,c));)if(256>f)b>=e&&(this.b=b,a=this.e(),b=this.b),a[b++]=f;else{g=f-257;k=I[g];0<K[g]&&(k+=C(this,K[g]));f=E(this,d);h=da[f];0<N[f]&&(h+=C(this,N[f]));b>=e&&(this.b=b,a=this.e(),b=this.b);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b}; |
||||||
|
w.prototype.w=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length,f,g,h,k;256!==(f=E(this,c));)if(256>f)b>=e&&(a=this.e(),e=a.length),a[b++]=f;else{g=f-257;k=I[g];0<K[g]&&(k+=C(this,K[g]));f=E(this,d);h=da[f];0<N[f]&&(h+=C(this,N[f]));b+k>e&&(a=this.e(),e=a.length);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b}; |
||||||
|
w.prototype.e=function(){var c=new (t?Uint8Array:Array)(this.b-32768),d=this.b-32768,a,b,e=this.c;if(t)c.set(e.subarray(32768,c.length));else{a=0;for(b=c.length;a<b;++a)c[a]=e[a+32768]}this.g.push(c);this.l+=c.length;if(t)e.set(e.subarray(d,d+32768));else for(a=0;32768>a;++a)e[a]=e[d+a];this.b=32768;return e}; |
||||||
|
w.prototype.z=function(c){var d,a=this.input.length/this.a+1|0,b,e,f,g=this.input,h=this.c;c&&("number"===typeof c.p&&(a=c.p),"number"===typeof c.u&&(a+=c.u));2>a?(b=(g.length-this.a)/this.o[2],f=258*(b/2)|0,e=f<h.length?h.length+f:h.length<<1):e=h.length*a;t?(d=new Uint8Array(e),d.set(h)):d=h;return this.c=d}; |
||||||
|
w.prototype.n=function(){var c=0,d=this.c,a=this.g,b,e=new (t?Uint8Array:Array)(this.l+(this.b-32768)),f,g,h,k;if(0===a.length)return t?this.c.subarray(32768,this.b):this.c.slice(32768,this.b);f=0;for(g=a.length;f<g;++f){b=a[f];h=0;for(k=b.length;h<k;++h)e[c++]=b[h]}f=32768;for(g=this.b;f<g;++f)e[c++]=d[f];this.g=[];return this.buffer=e}; |
||||||
|
w.prototype.v=function(){var c,d=this.b;t?this.r?(c=new Uint8Array(d),c.set(this.c.subarray(0,d))):c=this.c.subarray(0,d):(this.c.length>d&&(this.c.length=d),c=this.c);return this.buffer=c};function W(c,d){var a,b;this.input=c;this.a=0;if(d||!(d={}))d.index&&(this.a=d.index),d.verify&&(this.A=d.verify);a=c[this.a++];b=c[this.a++];switch(a&15){case ha:this.method=ha;break;default:throw Error("unsupported compression method");}if(0!==((a<<8)+b)%31)throw Error("invalid fcheck flag:"+((a<<8)+b)%31);if(b&32)throw Error("fdict flag is not supported");this.q=new w(c,{index:this.a,bufferSize:d.bufferSize,bufferType:d.bufferType,resize:d.resize})} |
||||||
|
W.prototype.k=function(){var c=this.input,d,a;d=this.q.k();this.a=this.q.a;if(this.A){a=(c[this.a++]<<24|c[this.a++]<<16|c[this.a++]<<8|c[this.a++])>>>0;var b=d;if("string"===typeof b){var e=b.split(""),f,g;f=0;for(g=e.length;f<g;f++)e[f]=(e[f].charCodeAt(0)&255)>>>0;b=e}for(var h=1,k=0,m=b.length,n,p=0;0<m;){n=1024<m?1024:m;m-=n;do h+=b[p++],k+=h;while(--n);h%=65521;k%=65521}if(a!==(k<<16|h)>>>0)throw Error("invalid adler-32 checksum");}return d};var ha=8;r("Zlib.Inflate",W);r("Zlib.Inflate.prototype.decompress",W.prototype.k);var X={ADAPTIVE:B.s,BLOCK:B.t},Y,Z,$,ia;if(Object.keys)Y=Object.keys(X);else for(Z in Y=[],$=0,X)Y[$++]=Z;$=0;for(ia=Y.length;$<ia;++$)Z=Y[$],r("Zlib.Inflate.BufferType."+Z,X[Z]);}).call(this); |
@ -0,0 +1,22 @@ |
|||||||
|
<template> |
||||||
|
<transition mode="out-in"> |
||||||
|
<router-view></router-view> |
||||||
|
</transition> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style> |
||||||
|
.v-enter { |
||||||
|
opacity: 0; |
||||||
|
transform: translateX(300px); |
||||||
|
} |
||||||
|
|
||||||
|
.v-leave-to { |
||||||
|
opacity: 0; |
||||||
|
transform: translateX(-300px); |
||||||
|
} |
||||||
|
|
||||||
|
.v-enter-active, |
||||||
|
.v-leave-active { |
||||||
|
transition: all 0.3s ease; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,202 @@ |
|||||||
|
<template> |
||||||
|
<!-- 挂载点 --> |
||||||
|
<div style="width: 100%; height: 100%; margin: 0; border: 0; padding: 0;"> |
||||||
|
<canvas v-if="suportWebGL" ref="stage" style="width: 100%; height: 100%;"></canvas> |
||||||
|
<div v-else> |
||||||
|
<slot>浏览器不支持WebGL</slot> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import "./plugins/OrbitControls"; |
||||||
|
import "./plugins/OBJLoader"; |
||||||
|
import "./plugins/FBXLoader"; |
||||||
|
|
||||||
|
import { |
||||||
|
CubeTextureLoader, |
||||||
|
Scene, |
||||||
|
WebGLRenderer, |
||||||
|
PerspectiveCamera, |
||||||
|
AmbientLight, |
||||||
|
DirectionalLight, |
||||||
|
OrbitControls |
||||||
|
} from "three"; |
||||||
|
|
||||||
|
//判断浏览器是否支持WebGL |
||||||
|
const suportWebGL = (() => { |
||||||
|
try { |
||||||
|
var canvas = document.createElement("canvas"); |
||||||
|
return !!( |
||||||
|
window.WebGLRenderingContext && |
||||||
|
(canvas.getContext("webgl") || canvas.getContext("experimental-webgl")) |
||||||
|
); |
||||||
|
} catch (e) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
})(); |
||||||
|
|
||||||
|
export default { |
||||||
|
props: ["componentsInfo", "cameraControll"], |
||||||
|
data() { |
||||||
|
return { |
||||||
|
//requestAnimationFrame ID |
||||||
|
reqId: null, |
||||||
|
//浏览器是否支持WebGL |
||||||
|
suportWebGL, |
||||||
|
//相机 |
||||||
|
camera: null, |
||||||
|
//场景 |
||||||
|
scene: new Scene(), |
||||||
|
//相机控制器 |
||||||
|
control: null |
||||||
|
}; |
||||||
|
}, |
||||||
|
//在DOM上树后进行初始化 |
||||||
|
mounted() { |
||||||
|
//相机设置 |
||||||
|
this.camera = new PerspectiveCamera( |
||||||
|
45, |
||||||
|
this.$el.offsetWidth / this.$el.offsetHeight, |
||||||
|
0.01, |
||||||
|
100000 |
||||||
|
); |
||||||
|
//灯光 |
||||||
|
this.scene.add(new AmbientLight(0xffffff)); |
||||||
|
//天空盒 |
||||||
|
this.scene.background = new CubeTextureLoader() |
||||||
|
.setPath("/img/skybox/") |
||||||
|
.load(["px.jpg", "nx.jpg", "py.jpg", "ny.jpg", "pz.jpg", "nz.jpg"]); |
||||||
|
//相机控制器 |
||||||
|
this.control = new OrbitControls(this.camera, this.$refs.stage); |
||||||
|
//固定视角 |
||||||
|
this.camera.position.y = this.cameraControll.height; |
||||||
|
this.control.target.set(0, this.cameraControll.height, 0); |
||||||
|
this.control.minDistance = this.cameraControll.distance; |
||||||
|
this.control.maxDistance = this.cameraControll.distance; |
||||||
|
// this.control.maxPolarAngle = Math.PI / 2; |
||||||
|
// this.control.minPolarAngle = Math.PI / 2; |
||||||
|
this.control.enablePan = false; |
||||||
|
this.control.enableKeys = false; |
||||||
|
this.control.update(); |
||||||
|
//初始化渲染器 |
||||||
|
this.renderer = new WebGLRenderer({ |
||||||
|
antialias: true, |
||||||
|
preserveDrawingBuffer: true, |
||||||
|
alpha: true, |
||||||
|
canvas: this.$refs.stage |
||||||
|
}); |
||||||
|
this.onResize(); |
||||||
|
//浏览器自动重绘 |
||||||
|
this.animate(); |
||||||
|
//窗口进行拉伸需要更新 |
||||||
|
window.addEventListener("resize", this.onResize, false); |
||||||
|
|
||||||
|
// var grid = new GridHelper(20, 20, 0x0000ff, 0xff0000); |
||||||
|
// grid.material.opacity = 0.2; |
||||||
|
// grid.material.transparent = true; |
||||||
|
// this.scene.add(grid); |
||||||
|
}, |
||||||
|
//在组件销毁前要取消各种监听 |
||||||
|
beforeDestroy() { |
||||||
|
//取消窗口拉伸监听 |
||||||
|
window.removeEventListener("resize", this.onResize, false); |
||||||
|
//取消浏览器自动重绘 |
||||||
|
cancelAnimationFrame(this.reqId); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
//窗口拉伸触发事件 |
||||||
|
onResize() { |
||||||
|
let width = this.$el.offsetWidth, |
||||||
|
height = this.$el.offsetHeight; |
||||||
|
//相机更新 |
||||||
|
this.camera.aspect = width / height; |
||||||
|
this.camera.updateProjectionMatrix(); |
||||||
|
//渲染器更新 |
||||||
|
this.renderer.setSize(width, height); |
||||||
|
this.renderer.setPixelRatio(window.devicePixelRatio || 1); |
||||||
|
}, |
||||||
|
//页面刷新重绘方法 |
||||||
|
animate() { |
||||||
|
this.reqId = requestAnimationFrame(this.animate); |
||||||
|
this.renderer.render(this.scene, this.camera); |
||||||
|
}, |
||||||
|
updateScene() { |
||||||
|
if (this.componentsInfo != null) { |
||||||
|
this.componentsInfo.map(item => { |
||||||
|
let modelIndex = item.modelSelected; |
||||||
|
let textureIndex = item.textureSelected; |
||||||
|
let modelObj = null; |
||||||
|
if (item.models[modelIndex] != null) { |
||||||
|
modelObj = item.models[modelIndex].obj; |
||||||
|
} |
||||||
|
let textureObj = null; |
||||||
|
if (item.textures[textureIndex] != null) { |
||||||
|
textureObj = item.textures[textureIndex].obj; |
||||||
|
} |
||||||
|
if (modelObj != null) { |
||||||
|
if (textureObj != null) { |
||||||
|
modelObj.traverse(child => { |
||||||
|
if (child.isMesh) { |
||||||
|
//贴图放大 |
||||||
|
textureObj.repeat.set( |
||||||
|
this.cameraControll.textureSize, |
||||||
|
this.cameraControll.textureSize |
||||||
|
); |
||||||
|
child.material.map = textureObj; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
item.models.map((subItem, index) => { |
||||||
|
if (subItem.obj != null) { |
||||||
|
// if (subItem.obj.parent == null) { |
||||||
|
// this.scene.add(subItem.obj); |
||||||
|
// } |
||||||
|
this.scene.add(subItem.obj); |
||||||
|
if (index == modelIndex) { |
||||||
|
subItem.obj.visible = true; |
||||||
|
} else { |
||||||
|
subItem.obj.visible = false; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
//获取当前的缩略图,并且返回为File |
||||||
|
getCover() { |
||||||
|
var dataurl = this.$refs.stage.toDataURL("image/jpeg", 0.2); |
||||||
|
var arr = dataurl.split(","), |
||||||
|
mime = arr[0].match(/:(.*?);/)[1], |
||||||
|
bstr = atob(arr[1]), |
||||||
|
n = bstr.length, |
||||||
|
u8arr = new Uint8Array(n); |
||||||
|
while (n--) { |
||||||
|
u8arr[n] = bstr.charCodeAt(n); |
||||||
|
} |
||||||
|
return new File([u8arr], "cover.jpg", { type: mime }); |
||||||
|
} |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
cameraControll: { |
||||||
|
handler() { |
||||||
|
if (!isNaN(this.cameraControll.height)) { |
||||||
|
this.camera.position.y = this.cameraControll.height; |
||||||
|
this.control.target.set(0, this.cameraControll.height, 0); |
||||||
|
this.control.update(); |
||||||
|
} |
||||||
|
if (!isNaN(this.cameraControll.distance)) { |
||||||
|
this.control.minDistance = this.cameraControll.distance; |
||||||
|
this.control.maxDistance = this.cameraControll.distance; |
||||||
|
this.control.update(); |
||||||
|
} |
||||||
|
if (!isNaN(this.cameraControll.textureSize)) { |
||||||
|
this.updateScene(); |
||||||
|
} |
||||||
|
}, |
||||||
|
deep: true |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
@ -0,0 +1,799 @@ |
|||||||
|
|
||||||
|
import * as THREE from "three"; |
||||||
|
/** |
||||||
|
* @author mrdoob / http://mrdoob.com/
|
||||||
|
*/ |
||||||
|
|
||||||
|
THREE.OBJLoader = ( function () { |
||||||
|
|
||||||
|
// o object_name | g group_name
|
||||||
|
var object_pattern = /^[og]\s*(.+)?/; |
||||||
|
// mtllib file_reference
|
||||||
|
var material_library_pattern = /^mtllib /; |
||||||
|
// usemtl material_name
|
||||||
|
var material_use_pattern = /^usemtl /; |
||||||
|
|
||||||
|
function ParserState() { |
||||||
|
|
||||||
|
var state = { |
||||||
|
objects: [], |
||||||
|
object: {}, |
||||||
|
|
||||||
|
vertices: [], |
||||||
|
normals: [], |
||||||
|
colors: [], |
||||||
|
uvs: [], |
||||||
|
|
||||||
|
materialLibraries: [], |
||||||
|
|
||||||
|
startObject: function ( name, fromDeclaration ) { |
||||||
|
|
||||||
|
// If the current object (initial from reset) is not from a g/o declaration in the parsed
|
||||||
|
// file. We need to use it for the first parsed g/o to keep things in sync.
|
||||||
|
if ( this.object && this.object.fromDeclaration === false ) { |
||||||
|
|
||||||
|
this.object.name = name; |
||||||
|
this.object.fromDeclaration = ( fromDeclaration !== false ); |
||||||
|
return; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined ); |
||||||
|
|
||||||
|
if ( this.object && typeof this.object._finalize === 'function' ) { |
||||||
|
|
||||||
|
this.object._finalize( true ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
this.object = { |
||||||
|
name: name || '', |
||||||
|
fromDeclaration: ( fromDeclaration !== false ), |
||||||
|
|
||||||
|
geometry: { |
||||||
|
vertices: [], |
||||||
|
normals: [], |
||||||
|
colors: [], |
||||||
|
uvs: [] |
||||||
|
}, |
||||||
|
materials: [], |
||||||
|
smooth: true, |
||||||
|
|
||||||
|
startMaterial: function ( name, libraries ) { |
||||||
|
|
||||||
|
var previous = this._finalize( false ); |
||||||
|
|
||||||
|
// New usemtl declaration overwrites an inherited material, except if faces were declared
|
||||||
|
// after the material, then it must be preserved for proper MultiMaterial continuation.
|
||||||
|
if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) { |
||||||
|
|
||||||
|
this.materials.splice( previous.index, 1 ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
var material = { |
||||||
|
index: this.materials.length, |
||||||
|
name: name || '', |
||||||
|
mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ), |
||||||
|
smooth: ( previous !== undefined ? previous.smooth : this.smooth ), |
||||||
|
groupStart: ( previous !== undefined ? previous.groupEnd : 0 ), |
||||||
|
groupEnd: - 1, |
||||||
|
groupCount: - 1, |
||||||
|
inherited: false, |
||||||
|
|
||||||
|
clone: function ( index ) { |
||||||
|
|
||||||
|
var cloned = { |
||||||
|
index: ( typeof index === 'number' ? index : this.index ), |
||||||
|
name: this.name, |
||||||
|
mtllib: this.mtllib, |
||||||
|
smooth: this.smooth, |
||||||
|
groupStart: 0, |
||||||
|
groupEnd: - 1, |
||||||
|
groupCount: - 1, |
||||||
|
inherited: false |
||||||
|
}; |
||||||
|
cloned.clone = this.clone.bind( cloned ); |
||||||
|
return cloned; |
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
this.materials.push( material ); |
||||||
|
|
||||||
|
return material; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
currentMaterial: function () { |
||||||
|
|
||||||
|
if ( this.materials.length > 0 ) { |
||||||
|
|
||||||
|
return this.materials[ this.materials.length - 1 ]; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return undefined; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
_finalize: function ( end ) { |
||||||
|
|
||||||
|
var lastMultiMaterial = this.currentMaterial(); |
||||||
|
if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) { |
||||||
|
|
||||||
|
lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3; |
||||||
|
lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart; |
||||||
|
lastMultiMaterial.inherited = false; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Ignore objects tail materials if no face declarations followed them before a new o/g started.
|
||||||
|
if ( end && this.materials.length > 1 ) { |
||||||
|
|
||||||
|
for ( var mi = this.materials.length - 1; mi >= 0; mi -- ) { |
||||||
|
|
||||||
|
if ( this.materials[ mi ].groupCount <= 0 ) { |
||||||
|
|
||||||
|
this.materials.splice( mi, 1 ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Guarantee at least one empty material, this makes the creation later more straight forward.
|
||||||
|
if ( end && this.materials.length === 0 ) { |
||||||
|
|
||||||
|
this.materials.push( { |
||||||
|
name: '', |
||||||
|
smooth: this.smooth |
||||||
|
} ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return lastMultiMaterial; |
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// Inherit previous objects material.
|
||||||
|
// Spec tells us that a declared material must be set to all objects until a new material is declared.
|
||||||
|
// If a usemtl declaration is encountered while this new object is being parsed, it will
|
||||||
|
// overwrite the inherited material. Exception being that there was already face declarations
|
||||||
|
// to the inherited material, then it will be preserved for proper MultiMaterial continuation.
|
||||||
|
|
||||||
|
if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) { |
||||||
|
|
||||||
|
var declared = previousMaterial.clone( 0 ); |
||||||
|
declared.inherited = true; |
||||||
|
this.object.materials.push( declared ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
this.objects.push( this.object ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
finalize: function () { |
||||||
|
|
||||||
|
if ( this.object && typeof this.object._finalize === 'function' ) { |
||||||
|
|
||||||
|
this.object._finalize( true ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
parseVertexIndex: function ( value, len ) { |
||||||
|
|
||||||
|
var index = parseInt( value, 10 ); |
||||||
|
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
parseNormalIndex: function ( value, len ) { |
||||||
|
|
||||||
|
var index = parseInt( value, 10 ); |
||||||
|
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
parseUVIndex: function ( value, len ) { |
||||||
|
|
||||||
|
var index = parseInt( value, 10 ); |
||||||
|
return ( index >= 0 ? index - 1 : index + len / 2 ) * 2; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addVertex: function ( a, b, c ) { |
||||||
|
|
||||||
|
var src = this.vertices; |
||||||
|
var dst = this.object.geometry.vertices; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); |
||||||
|
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addVertexPoint: function ( a ) { |
||||||
|
|
||||||
|
var src = this.vertices; |
||||||
|
var dst = this.object.geometry.vertices; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addVertexLine: function ( a ) { |
||||||
|
|
||||||
|
var src = this.vertices; |
||||||
|
var dst = this.object.geometry.vertices; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addNormal: function ( a, b, c ) { |
||||||
|
|
||||||
|
var src = this.normals; |
||||||
|
var dst = this.object.geometry.normals; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); |
||||||
|
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addColor: function ( a, b, c ) { |
||||||
|
|
||||||
|
var src = this.colors; |
||||||
|
var dst = this.object.geometry.colors; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); |
||||||
|
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addUV: function ( a, b, c ) { |
||||||
|
|
||||||
|
var src = this.uvs; |
||||||
|
var dst = this.object.geometry.uvs; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ] ); |
||||||
|
dst.push( src[ b + 0 ], src[ b + 1 ] ); |
||||||
|
dst.push( src[ c + 0 ], src[ c + 1 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addUVLine: function ( a ) { |
||||||
|
|
||||||
|
var src = this.uvs; |
||||||
|
var dst = this.object.geometry.uvs; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) { |
||||||
|
|
||||||
|
var vLen = this.vertices.length; |
||||||
|
|
||||||
|
var ia = this.parseVertexIndex( a, vLen ); |
||||||
|
var ib = this.parseVertexIndex( b, vLen ); |
||||||
|
var ic = this.parseVertexIndex( c, vLen ); |
||||||
|
|
||||||
|
this.addVertex( ia, ib, ic ); |
||||||
|
|
||||||
|
if ( ua !== undefined && ua !== '' ) { |
||||||
|
|
||||||
|
var uvLen = this.uvs.length; |
||||||
|
ia = this.parseUVIndex( ua, uvLen ); |
||||||
|
ib = this.parseUVIndex( ub, uvLen ); |
||||||
|
ic = this.parseUVIndex( uc, uvLen ); |
||||||
|
this.addUV( ia, ib, ic ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( na !== undefined && na !== '' ) { |
||||||
|
|
||||||
|
// Normals are many times the same. If so, skip function call and parseInt.
|
||||||
|
var nLen = this.normals.length; |
||||||
|
ia = this.parseNormalIndex( na, nLen ); |
||||||
|
|
||||||
|
ib = na === nb ? ia : this.parseNormalIndex( nb, nLen ); |
||||||
|
ic = na === nc ? ia : this.parseNormalIndex( nc, nLen ); |
||||||
|
|
||||||
|
this.addNormal( ia, ib, ic ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( this.colors.length > 0 ) { |
||||||
|
|
||||||
|
this.addColor( ia, ib, ic ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addPointGeometry: function ( vertices ) { |
||||||
|
|
||||||
|
this.object.geometry.type = 'Points'; |
||||||
|
|
||||||
|
var vLen = this.vertices.length; |
||||||
|
|
||||||
|
for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) { |
||||||
|
|
||||||
|
this.addVertexPoint( this.parseVertexIndex( vertices[ vi ], vLen ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addLineGeometry: function ( vertices, uvs ) { |
||||||
|
|
||||||
|
this.object.geometry.type = 'Line'; |
||||||
|
|
||||||
|
var vLen = this.vertices.length; |
||||||
|
var uvLen = this.uvs.length; |
||||||
|
|
||||||
|
for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) { |
||||||
|
|
||||||
|
this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) { |
||||||
|
|
||||||
|
this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
state.startObject( '', false ); |
||||||
|
|
||||||
|
return state; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
function OBJLoader( manager ) { |
||||||
|
|
||||||
|
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; |
||||||
|
|
||||||
|
this.materials = null; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
OBJLoader.prototype = { |
||||||
|
|
||||||
|
constructor: OBJLoader, |
||||||
|
|
||||||
|
load: function ( url, onLoad, onProgress, onError ) { |
||||||
|
|
||||||
|
var scope = this; |
||||||
|
|
||||||
|
var loader = new THREE.FileLoader( scope.manager ); |
||||||
|
loader.setPath( this.path ); |
||||||
|
loader.load( url, function ( text ) { |
||||||
|
|
||||||
|
onLoad( scope.parse( text ) ); |
||||||
|
|
||||||
|
}, onProgress, onError ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
setPath: function ( value ) { |
||||||
|
|
||||||
|
this.path = value; |
||||||
|
|
||||||
|
return this; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
setMaterials: function ( materials ) { |
||||||
|
|
||||||
|
this.materials = materials; |
||||||
|
|
||||||
|
return this; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
parse: function ( text ) { |
||||||
|
|
||||||
|
console.time( 'OBJLoader' ); |
||||||
|
|
||||||
|
var state = new ParserState(); |
||||||
|
|
||||||
|
if ( text.indexOf( '\r\n' ) !== - 1 ) { |
||||||
|
|
||||||
|
// This is faster than String.split with regex that splits on both
|
||||||
|
text = text.replace( /\r\n/g, '\n' ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( text.indexOf( '\\\n' ) !== - 1 ) { |
||||||
|
|
||||||
|
// join lines separated by a line continuation character (\)
|
||||||
|
text = text.replace( /\\\n/g, '' ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
var lines = text.split( '\n' ); |
||||||
|
var line = '', lineFirstChar = ''; |
||||||
|
var lineLength = 0; |
||||||
|
var result = []; |
||||||
|
|
||||||
|
// Faster to just trim left side of the line. Use if available.
|
||||||
|
var trimLeft = ( typeof ''.trimLeft === 'function' ); |
||||||
|
|
||||||
|
for ( var i = 0, l = lines.length; i < l; i ++ ) { |
||||||
|
|
||||||
|
line = lines[ i ]; |
||||||
|
|
||||||
|
line = trimLeft ? line.trimLeft() : line.trim(); |
||||||
|
|
||||||
|
lineLength = line.length; |
||||||
|
|
||||||
|
if ( lineLength === 0 ) continue; |
||||||
|
|
||||||
|
lineFirstChar = line.charAt( 0 ); |
||||||
|
|
||||||
|
// @todo invoke passed in handler if any
|
||||||
|
if ( lineFirstChar === '#' ) continue; |
||||||
|
|
||||||
|
if ( lineFirstChar === 'v' ) { |
||||||
|
|
||||||
|
var data = line.split( /\s+/ ); |
||||||
|
|
||||||
|
switch ( data[ 0 ] ) { |
||||||
|
|
||||||
|
case 'v': |
||||||
|
state.vertices.push( |
||||||
|
parseFloat( data[ 1 ] ), |
||||||
|
parseFloat( data[ 2 ] ), |
||||||
|
parseFloat( data[ 3 ] ) |
||||||
|
); |
||||||
|
if ( data.length === 8 ) { |
||||||
|
|
||||||
|
state.colors.push( |
||||||
|
parseFloat( data[ 4 ] ), |
||||||
|
parseFloat( data[ 5 ] ), |
||||||
|
parseFloat( data[ 6 ] ) |
||||||
|
|
||||||
|
); |
||||||
|
|
||||||
|
} |
||||||
|
break; |
||||||
|
case 'vn': |
||||||
|
state.normals.push( |
||||||
|
parseFloat( data[ 1 ] ), |
||||||
|
parseFloat( data[ 2 ] ), |
||||||
|
parseFloat( data[ 3 ] ) |
||||||
|
); |
||||||
|
break; |
||||||
|
case 'vt': |
||||||
|
state.uvs.push( |
||||||
|
parseFloat( data[ 1 ] ), |
||||||
|
parseFloat( data[ 2 ] ) |
||||||
|
); |
||||||
|
break; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} else if ( lineFirstChar === 'f' ) { |
||||||
|
|
||||||
|
var lineData = line.substr( 1 ).trim(); |
||||||
|
var vertexData = lineData.split( /\s+/ ); |
||||||
|
var faceVertices = []; |
||||||
|
|
||||||
|
// Parse the face vertex data into an easy to work with format
|
||||||
|
|
||||||
|
for ( var j = 0, jl = vertexData.length; j < jl; j ++ ) { |
||||||
|
|
||||||
|
var vertex = vertexData[ j ]; |
||||||
|
|
||||||
|
if ( vertex.length > 0 ) { |
||||||
|
|
||||||
|
var vertexParts = vertex.split( '/' ); |
||||||
|
faceVertices.push( vertexParts ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Draw an edge between the first vertex and all subsequent vertices to form an n-gon
|
||||||
|
|
||||||
|
var v1 = faceVertices[ 0 ]; |
||||||
|
|
||||||
|
for ( var j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) { |
||||||
|
|
||||||
|
var v2 = faceVertices[ j ]; |
||||||
|
var v3 = faceVertices[ j + 1 ]; |
||||||
|
|
||||||
|
state.addFace( |
||||||
|
v1[ 0 ], v2[ 0 ], v3[ 0 ], |
||||||
|
v1[ 1 ], v2[ 1 ], v3[ 1 ], |
||||||
|
v1[ 2 ], v2[ 2 ], v3[ 2 ] |
||||||
|
); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} else if ( lineFirstChar === 'l' ) { |
||||||
|
|
||||||
|
var lineParts = line.substring( 1 ).trim().split( " " ); |
||||||
|
var lineVertices = [], lineUVs = []; |
||||||
|
|
||||||
|
if ( line.indexOf( "/" ) === - 1 ) { |
||||||
|
|
||||||
|
lineVertices = lineParts; |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) { |
||||||
|
|
||||||
|
var parts = lineParts[ li ].split( "/" ); |
||||||
|
|
||||||
|
if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] ); |
||||||
|
if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
state.addLineGeometry( lineVertices, lineUVs ); |
||||||
|
|
||||||
|
} else if ( lineFirstChar === 'p' ) { |
||||||
|
|
||||||
|
var lineData = line.substr( 1 ).trim(); |
||||||
|
var pointData = lineData.split( " " ); |
||||||
|
|
||||||
|
state.addPointGeometry( pointData ); |
||||||
|
|
||||||
|
} else if ( ( result = object_pattern.exec( line ) ) !== null ) { |
||||||
|
|
||||||
|
// o object_name
|
||||||
|
// or
|
||||||
|
// g group_name
|
||||||
|
|
||||||
|
// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
|
||||||
|
// var name = result[ 0 ].substr( 1 ).trim();
|
||||||
|
var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 ); |
||||||
|
|
||||||
|
state.startObject( name ); |
||||||
|
|
||||||
|
} else if ( material_use_pattern.test( line ) ) { |
||||||
|
|
||||||
|
// material
|
||||||
|
|
||||||
|
state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries ); |
||||||
|
|
||||||
|
} else if ( material_library_pattern.test( line ) ) { |
||||||
|
|
||||||
|
// mtl file
|
||||||
|
|
||||||
|
state.materialLibraries.push( line.substring( 7 ).trim() ); |
||||||
|
|
||||||
|
} else if ( lineFirstChar === 's' ) { |
||||||
|
|
||||||
|
result = line.split( ' ' ); |
||||||
|
|
||||||
|
// smooth shading
|
||||||
|
|
||||||
|
// @todo Handle files that have varying smooth values for a set of faces inside one geometry,
|
||||||
|
// but does not define a usemtl for each face set.
|
||||||
|
// This should be detected and a dummy material created (later MultiMaterial and geometry groups).
|
||||||
|
// This requires some care to not create extra material on each smooth value for "normal" obj files.
|
||||||
|
// where explicit usemtl defines geometry groups.
|
||||||
|
// Example asset: examples/models/obj/cerberus/Cerberus.obj
|
||||||
|
|
||||||
|
/* |
||||||
|
* http://paulbourke.net/dataformats/obj/
|
||||||
|
* or |
||||||
|
* http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf
|
||||||
|
* |
||||||
|
* From chapter "Grouping" Syntax explanation "s group_number": |
||||||
|
* "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off. |
||||||
|
* Polygonal elements use group numbers to put elements in different smoothing groups. For free-form |
||||||
|
* surfaces, smoothing groups are either turned on or off; there is no difference between values greater |
||||||
|
* than 0." |
||||||
|
*/ |
||||||
|
if ( result.length > 1 ) { |
||||||
|
|
||||||
|
var value = result[ 1 ].trim().toLowerCase(); |
||||||
|
state.object.smooth = ( value !== '0' && value !== 'off' ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// ZBrush can produce "s" lines #11707
|
||||||
|
state.object.smooth = true; |
||||||
|
|
||||||
|
} |
||||||
|
var material = state.object.currentMaterial(); |
||||||
|
if ( material ) material.smooth = state.object.smooth; |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// Handle null terminated files without exception
|
||||||
|
if ( line === '\0' ) continue; |
||||||
|
|
||||||
|
throw new Error( 'THREE.OBJLoader: Unexpected line: "' + line + '"' ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
state.finalize(); |
||||||
|
|
||||||
|
var container = new THREE.Group(); |
||||||
|
container.materialLibraries = [].concat( state.materialLibraries ); |
||||||
|
|
||||||
|
for ( var i = 0, l = state.objects.length; i < l; i ++ ) { |
||||||
|
|
||||||
|
var object = state.objects[ i ]; |
||||||
|
var geometry = object.geometry; |
||||||
|
var materials = object.materials; |
||||||
|
var isLine = ( geometry.type === 'Line' ); |
||||||
|
var isPoints = ( geometry.type === 'Points' ); |
||||||
|
var hasVertexColors = false; |
||||||
|
|
||||||
|
// Skip o/g line declarations that did not follow with any faces
|
||||||
|
if ( geometry.vertices.length === 0 ) continue; |
||||||
|
|
||||||
|
var buffergeometry = new THREE.BufferGeometry(); |
||||||
|
|
||||||
|
buffergeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) ); |
||||||
|
|
||||||
|
if ( geometry.normals.length > 0 ) { |
||||||
|
|
||||||
|
buffergeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
buffergeometry.computeVertexNormals(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( geometry.colors.length > 0 ) { |
||||||
|
|
||||||
|
hasVertexColors = true; |
||||||
|
buffergeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( geometry.uvs.length > 0 ) { |
||||||
|
|
||||||
|
buffergeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Create materials
|
||||||
|
|
||||||
|
var createdMaterials = []; |
||||||
|
|
||||||
|
for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { |
||||||
|
|
||||||
|
var sourceMaterial = materials[ mi ]; |
||||||
|
var material = undefined; |
||||||
|
|
||||||
|
if ( this.materials !== null ) { |
||||||
|
|
||||||
|
material = this.materials.create( sourceMaterial.name ); |
||||||
|
|
||||||
|
// mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
|
||||||
|
if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) { |
||||||
|
|
||||||
|
var materialLine = new THREE.LineBasicMaterial(); |
||||||
|
THREE.Material.prototype.copy.call( materialLine, material ); |
||||||
|
materialLine.color.copy( material.color ); |
||||||
|
materialLine.lights = false; |
||||||
|
material = materialLine; |
||||||
|
|
||||||
|
} else if ( isPoints && material && ! ( material instanceof THREE.PointsMaterial ) ) { |
||||||
|
|
||||||
|
var materialPoints = new THREE.PointsMaterial( { size: 10, sizeAttenuation: false } ); |
||||||
|
THREE.Material.prototype.copy.call( materialPoints, material ); |
||||||
|
materialPoints.color.copy( material.color ); |
||||||
|
materialPoints.map = material.map; |
||||||
|
materialPoints.lights = false; |
||||||
|
material = materialPoints; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( ! material ) { |
||||||
|
|
||||||
|
if ( isLine ) { |
||||||
|
|
||||||
|
material = new THREE.LineBasicMaterial(); |
||||||
|
|
||||||
|
} else if ( isPoints ) { |
||||||
|
|
||||||
|
material = new THREE.PointsMaterial( { size: 1, sizeAttenuation: false } ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
material = new THREE.MeshPhongMaterial(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
material.name = sourceMaterial.name; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
material.flatShading = sourceMaterial.smooth ? false : true; |
||||||
|
material.vertexColors = hasVertexColors ? THREE.VertexColors : THREE.NoColors; |
||||||
|
|
||||||
|
createdMaterials.push( material ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Create mesh
|
||||||
|
|
||||||
|
var mesh; |
||||||
|
|
||||||
|
if ( createdMaterials.length > 1 ) { |
||||||
|
|
||||||
|
for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { |
||||||
|
|
||||||
|
var sourceMaterial = materials[ mi ]; |
||||||
|
buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( isLine ) { |
||||||
|
|
||||||
|
mesh = new THREE.LineSegments( buffergeometry, createdMaterials ); |
||||||
|
|
||||||
|
} else if ( isPoints ) { |
||||||
|
|
||||||
|
mesh = new THREE.Points( buffergeometry, createdMaterials ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
mesh = new THREE.Mesh( buffergeometry, createdMaterials ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
if ( isLine ) { |
||||||
|
|
||||||
|
mesh = new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] ); |
||||||
|
|
||||||
|
} else if ( isPoints ) { |
||||||
|
|
||||||
|
mesh = new THREE.Points( buffergeometry, createdMaterials[ 0 ] ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
mesh = new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
mesh.name = object.name; |
||||||
|
|
||||||
|
container.add( mesh ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
console.timeEnd( 'OBJLoader' ); |
||||||
|
|
||||||
|
return container; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
return OBJLoader; |
||||||
|
|
||||||
|
} )(); |
@ -0,0 +1,17 @@ |
|||||||
|
import Vue from 'vue' |
||||||
|
import './plugins/vuetify' |
||||||
|
import App from './App.vue' |
||||||
|
import router from './router' |
||||||
|
import store from './store' |
||||||
|
import VueResource from 'vue-resource' |
||||||
|
|
||||||
|
Vue.config.productionTip = false |
||||||
|
Vue.use(VueResource) |
||||||
|
Vue.http.options.emulateJSON = true; |
||||||
|
Vue.http.options.emulateHTTP = true; |
||||||
|
|
||||||
|
new Vue({ |
||||||
|
router, |
||||||
|
store, |
||||||
|
render: h => h(App) |
||||||
|
}).$mount('#app') |
@ -0,0 +1,799 @@ |
|||||||
|
|
||||||
|
import * as THREE from "three"; |
||||||
|
/** |
||||||
|
* @author mrdoob / http://mrdoob.com/
|
||||||
|
*/ |
||||||
|
|
||||||
|
THREE.OBJLoader = ( function () { |
||||||
|
|
||||||
|
// o object_name | g group_name
|
||||||
|
var object_pattern = /^[og]\s*(.+)?/; |
||||||
|
// mtllib file_reference
|
||||||
|
var material_library_pattern = /^mtllib /; |
||||||
|
// usemtl material_name
|
||||||
|
var material_use_pattern = /^usemtl /; |
||||||
|
|
||||||
|
function ParserState() { |
||||||
|
|
||||||
|
var state = { |
||||||
|
objects: [], |
||||||
|
object: {}, |
||||||
|
|
||||||
|
vertices: [], |
||||||
|
normals: [], |
||||||
|
colors: [], |
||||||
|
uvs: [], |
||||||
|
|
||||||
|
materialLibraries: [], |
||||||
|
|
||||||
|
startObject: function ( name, fromDeclaration ) { |
||||||
|
|
||||||
|
// If the current object (initial from reset) is not from a g/o declaration in the parsed
|
||||||
|
// file. We need to use it for the first parsed g/o to keep things in sync.
|
||||||
|
if ( this.object && this.object.fromDeclaration === false ) { |
||||||
|
|
||||||
|
this.object.name = name; |
||||||
|
this.object.fromDeclaration = ( fromDeclaration !== false ); |
||||||
|
return; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined ); |
||||||
|
|
||||||
|
if ( this.object && typeof this.object._finalize === 'function' ) { |
||||||
|
|
||||||
|
this.object._finalize( true ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
this.object = { |
||||||
|
name: name || '', |
||||||
|
fromDeclaration: ( fromDeclaration !== false ), |
||||||
|
|
||||||
|
geometry: { |
||||||
|
vertices: [], |
||||||
|
normals: [], |
||||||
|
colors: [], |
||||||
|
uvs: [] |
||||||
|
}, |
||||||
|
materials: [], |
||||||
|
smooth: true, |
||||||
|
|
||||||
|
startMaterial: function ( name, libraries ) { |
||||||
|
|
||||||
|
var previous = this._finalize( false ); |
||||||
|
|
||||||
|
// New usemtl declaration overwrites an inherited material, except if faces were declared
|
||||||
|
// after the material, then it must be preserved for proper MultiMaterial continuation.
|
||||||
|
if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) { |
||||||
|
|
||||||
|
this.materials.splice( previous.index, 1 ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
var material = { |
||||||
|
index: this.materials.length, |
||||||
|
name: name || '', |
||||||
|
mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ), |
||||||
|
smooth: ( previous !== undefined ? previous.smooth : this.smooth ), |
||||||
|
groupStart: ( previous !== undefined ? previous.groupEnd : 0 ), |
||||||
|
groupEnd: - 1, |
||||||
|
groupCount: - 1, |
||||||
|
inherited: false, |
||||||
|
|
||||||
|
clone: function ( index ) { |
||||||
|
|
||||||
|
var cloned = { |
||||||
|
index: ( typeof index === 'number' ? index : this.index ), |
||||||
|
name: this.name, |
||||||
|
mtllib: this.mtllib, |
||||||
|
smooth: this.smooth, |
||||||
|
groupStart: 0, |
||||||
|
groupEnd: - 1, |
||||||
|
groupCount: - 1, |
||||||
|
inherited: false |
||||||
|
}; |
||||||
|
cloned.clone = this.clone.bind( cloned ); |
||||||
|
return cloned; |
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
this.materials.push( material ); |
||||||
|
|
||||||
|
return material; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
currentMaterial: function () { |
||||||
|
|
||||||
|
if ( this.materials.length > 0 ) { |
||||||
|
|
||||||
|
return this.materials[ this.materials.length - 1 ]; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return undefined; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
_finalize: function ( end ) { |
||||||
|
|
||||||
|
var lastMultiMaterial = this.currentMaterial(); |
||||||
|
if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) { |
||||||
|
|
||||||
|
lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3; |
||||||
|
lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart; |
||||||
|
lastMultiMaterial.inherited = false; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Ignore objects tail materials if no face declarations followed them before a new o/g started.
|
||||||
|
if ( end && this.materials.length > 1 ) { |
||||||
|
|
||||||
|
for ( var mi = this.materials.length - 1; mi >= 0; mi -- ) { |
||||||
|
|
||||||
|
if ( this.materials[ mi ].groupCount <= 0 ) { |
||||||
|
|
||||||
|
this.materials.splice( mi, 1 ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Guarantee at least one empty material, this makes the creation later more straight forward.
|
||||||
|
if ( end && this.materials.length === 0 ) { |
||||||
|
|
||||||
|
this.materials.push( { |
||||||
|
name: '', |
||||||
|
smooth: this.smooth |
||||||
|
} ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return lastMultiMaterial; |
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// Inherit previous objects material.
|
||||||
|
// Spec tells us that a declared material must be set to all objects until a new material is declared.
|
||||||
|
// If a usemtl declaration is encountered while this new object is being parsed, it will
|
||||||
|
// overwrite the inherited material. Exception being that there was already face declarations
|
||||||
|
// to the inherited material, then it will be preserved for proper MultiMaterial continuation.
|
||||||
|
|
||||||
|
if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) { |
||||||
|
|
||||||
|
var declared = previousMaterial.clone( 0 ); |
||||||
|
declared.inherited = true; |
||||||
|
this.object.materials.push( declared ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
this.objects.push( this.object ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
finalize: function () { |
||||||
|
|
||||||
|
if ( this.object && typeof this.object._finalize === 'function' ) { |
||||||
|
|
||||||
|
this.object._finalize( true ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
parseVertexIndex: function ( value, len ) { |
||||||
|
|
||||||
|
var index = parseInt( value, 10 ); |
||||||
|
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
parseNormalIndex: function ( value, len ) { |
||||||
|
|
||||||
|
var index = parseInt( value, 10 ); |
||||||
|
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
parseUVIndex: function ( value, len ) { |
||||||
|
|
||||||
|
var index = parseInt( value, 10 ); |
||||||
|
return ( index >= 0 ? index - 1 : index + len / 2 ) * 2; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addVertex: function ( a, b, c ) { |
||||||
|
|
||||||
|
var src = this.vertices; |
||||||
|
var dst = this.object.geometry.vertices; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); |
||||||
|
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addVertexPoint: function ( a ) { |
||||||
|
|
||||||
|
var src = this.vertices; |
||||||
|
var dst = this.object.geometry.vertices; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addVertexLine: function ( a ) { |
||||||
|
|
||||||
|
var src = this.vertices; |
||||||
|
var dst = this.object.geometry.vertices; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addNormal: function ( a, b, c ) { |
||||||
|
|
||||||
|
var src = this.normals; |
||||||
|
var dst = this.object.geometry.normals; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); |
||||||
|
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addColor: function ( a, b, c ) { |
||||||
|
|
||||||
|
var src = this.colors; |
||||||
|
var dst = this.object.geometry.colors; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] ); |
||||||
|
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] ); |
||||||
|
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addUV: function ( a, b, c ) { |
||||||
|
|
||||||
|
var src = this.uvs; |
||||||
|
var dst = this.object.geometry.uvs; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ] ); |
||||||
|
dst.push( src[ b + 0 ], src[ b + 1 ] ); |
||||||
|
dst.push( src[ c + 0 ], src[ c + 1 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addUVLine: function ( a ) { |
||||||
|
|
||||||
|
var src = this.uvs; |
||||||
|
var dst = this.object.geometry.uvs; |
||||||
|
|
||||||
|
dst.push( src[ a + 0 ], src[ a + 1 ] ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) { |
||||||
|
|
||||||
|
var vLen = this.vertices.length; |
||||||
|
|
||||||
|
var ia = this.parseVertexIndex( a, vLen ); |
||||||
|
var ib = this.parseVertexIndex( b, vLen ); |
||||||
|
var ic = this.parseVertexIndex( c, vLen ); |
||||||
|
|
||||||
|
this.addVertex( ia, ib, ic ); |
||||||
|
|
||||||
|
if ( ua !== undefined && ua !== '' ) { |
||||||
|
|
||||||
|
var uvLen = this.uvs.length; |
||||||
|
ia = this.parseUVIndex( ua, uvLen ); |
||||||
|
ib = this.parseUVIndex( ub, uvLen ); |
||||||
|
ic = this.parseUVIndex( uc, uvLen ); |
||||||
|
this.addUV( ia, ib, ic ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( na !== undefined && na !== '' ) { |
||||||
|
|
||||||
|
// Normals are many times the same. If so, skip function call and parseInt.
|
||||||
|
var nLen = this.normals.length; |
||||||
|
ia = this.parseNormalIndex( na, nLen ); |
||||||
|
|
||||||
|
ib = na === nb ? ia : this.parseNormalIndex( nb, nLen ); |
||||||
|
ic = na === nc ? ia : this.parseNormalIndex( nc, nLen ); |
||||||
|
|
||||||
|
this.addNormal( ia, ib, ic ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( this.colors.length > 0 ) { |
||||||
|
|
||||||
|
this.addColor( ia, ib, ic ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addPointGeometry: function ( vertices ) { |
||||||
|
|
||||||
|
this.object.geometry.type = 'Points'; |
||||||
|
|
||||||
|
var vLen = this.vertices.length; |
||||||
|
|
||||||
|
for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) { |
||||||
|
|
||||||
|
this.addVertexPoint( this.parseVertexIndex( vertices[ vi ], vLen ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
addLineGeometry: function ( vertices, uvs ) { |
||||||
|
|
||||||
|
this.object.geometry.type = 'Line'; |
||||||
|
|
||||||
|
var vLen = this.vertices.length; |
||||||
|
var uvLen = this.uvs.length; |
||||||
|
|
||||||
|
for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) { |
||||||
|
|
||||||
|
this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) { |
||||||
|
|
||||||
|
this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
state.startObject( '', false ); |
||||||
|
|
||||||
|
return state; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
function OBJLoader( manager ) { |
||||||
|
|
||||||
|
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; |
||||||
|
|
||||||
|
this.materials = null; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
OBJLoader.prototype = { |
||||||
|
|
||||||
|
constructor: OBJLoader, |
||||||
|
|
||||||
|
load: function ( url, onLoad, onProgress, onError ) { |
||||||
|
|
||||||
|
var scope = this; |
||||||
|
|
||||||
|
var loader = new THREE.FileLoader( scope.manager ); |
||||||
|
loader.setPath( this.path ); |
||||||
|
loader.load( url, function ( text ) { |
||||||
|
|
||||||
|
onLoad( scope.parse( text ) ); |
||||||
|
|
||||||
|
}, onProgress, onError ); |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
setPath: function ( value ) { |
||||||
|
|
||||||
|
this.path = value; |
||||||
|
|
||||||
|
return this; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
setMaterials: function ( materials ) { |
||||||
|
|
||||||
|
this.materials = materials; |
||||||
|
|
||||||
|
return this; |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
parse: function ( text ) { |
||||||
|
|
||||||
|
console.time( 'OBJLoader' ); |
||||||
|
|
||||||
|
var state = new ParserState(); |
||||||
|
|
||||||
|
if ( text.indexOf( '\r\n' ) !== - 1 ) { |
||||||
|
|
||||||
|
// This is faster than String.split with regex that splits on both
|
||||||
|
text = text.replace( /\r\n/g, '\n' ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( text.indexOf( '\\\n' ) !== - 1 ) { |
||||||
|
|
||||||
|
// join lines separated by a line continuation character (\)
|
||||||
|
text = text.replace( /\\\n/g, '' ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
var lines = text.split( '\n' ); |
||||||
|
var line = '', lineFirstChar = ''; |
||||||
|
var lineLength = 0; |
||||||
|
var result = []; |
||||||
|
|
||||||
|
// Faster to just trim left side of the line. Use if available.
|
||||||
|
var trimLeft = ( typeof ''.trimLeft === 'function' ); |
||||||
|
|
||||||
|
for ( var i = 0, l = lines.length; i < l; i ++ ) { |
||||||
|
|
||||||
|
line = lines[ i ]; |
||||||
|
|
||||||
|
line = trimLeft ? line.trimLeft() : line.trim(); |
||||||
|
|
||||||
|
lineLength = line.length; |
||||||
|
|
||||||
|
if ( lineLength === 0 ) continue; |
||||||
|
|
||||||
|
lineFirstChar = line.charAt( 0 ); |
||||||
|
|
||||||
|
// @todo invoke passed in handler if any
|
||||||
|
if ( lineFirstChar === '#' ) continue; |
||||||
|
|
||||||
|
if ( lineFirstChar === 'v' ) { |
||||||
|
|
||||||
|
var data = line.split( /\s+/ ); |
||||||
|
|
||||||
|
switch ( data[ 0 ] ) { |
||||||
|
|
||||||
|
case 'v': |
||||||
|
state.vertices.push( |
||||||
|
parseFloat( data[ 1 ] ), |
||||||
|
parseFloat( data[ 2 ] ), |
||||||
|
parseFloat( data[ 3 ] ) |
||||||
|
); |
||||||
|
if ( data.length === 8 ) { |
||||||
|
|
||||||
|
state.colors.push( |
||||||
|
parseFloat( data[ 4 ] ), |
||||||
|
parseFloat( data[ 5 ] ), |
||||||
|
parseFloat( data[ 6 ] ) |
||||||
|
|
||||||
|
); |
||||||
|
|
||||||
|
} |
||||||
|
break; |
||||||
|
case 'vn': |
||||||
|
state.normals.push( |
||||||
|
parseFloat( data[ 1 ] ), |
||||||
|
parseFloat( data[ 2 ] ), |
||||||
|
parseFloat( data[ 3 ] ) |
||||||
|
); |
||||||
|
break; |
||||||
|
case 'vt': |
||||||
|
state.uvs.push( |
||||||
|
parseFloat( data[ 1 ] ), |
||||||
|
parseFloat( data[ 2 ] ) |
||||||
|
); |
||||||
|
break; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} else if ( lineFirstChar === 'f' ) { |
||||||
|
|
||||||
|
var lineData = line.substr( 1 ).trim(); |
||||||
|
var vertexData = lineData.split( /\s+/ ); |
||||||
|
var faceVertices = []; |
||||||
|
|
||||||
|
// Parse the face vertex data into an easy to work with format
|
||||||
|
|
||||||
|
for ( var j = 0, jl = vertexData.length; j < jl; j ++ ) { |
||||||
|
|
||||||
|
var vertex = vertexData[ j ]; |
||||||
|
|
||||||
|
if ( vertex.length > 0 ) { |
||||||
|
|
||||||
|
var vertexParts = vertex.split( '/' ); |
||||||
|
faceVertices.push( vertexParts ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Draw an edge between the first vertex and all subsequent vertices to form an n-gon
|
||||||
|
|
||||||
|
var v1 = faceVertices[ 0 ]; |
||||||
|
|
||||||
|
for ( var j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) { |
||||||
|
|
||||||
|
var v2 = faceVertices[ j ]; |
||||||
|
var v3 = faceVertices[ j + 1 ]; |
||||||
|
|
||||||
|
state.addFace( |
||||||
|
v1[ 0 ], v2[ 0 ], v3[ 0 ], |
||||||
|
v1[ 1 ], v2[ 1 ], v3[ 1 ], |
||||||
|
v1[ 2 ], v2[ 2 ], v3[ 2 ] |
||||||
|
); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} else if ( lineFirstChar === 'l' ) { |
||||||
|
|
||||||
|
var lineParts = line.substring( 1 ).trim().split( " " ); |
||||||
|
var lineVertices = [], lineUVs = []; |
||||||
|
|
||||||
|
if ( line.indexOf( "/" ) === - 1 ) { |
||||||
|
|
||||||
|
lineVertices = lineParts; |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) { |
||||||
|
|
||||||
|
var parts = lineParts[ li ].split( "/" ); |
||||||
|
|
||||||
|
if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] ); |
||||||
|
if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
state.addLineGeometry( lineVertices, lineUVs ); |
||||||
|
|
||||||
|
} else if ( lineFirstChar === 'p' ) { |
||||||
|
|
||||||
|
var lineData = line.substr( 1 ).trim(); |
||||||
|
var pointData = lineData.split( " " ); |
||||||
|
|
||||||
|
state.addPointGeometry( pointData ); |
||||||
|
|
||||||
|
} else if ( ( result = object_pattern.exec( line ) ) !== null ) { |
||||||
|
|
||||||
|
// o object_name
|
||||||
|
// or
|
||||||
|
// g group_name
|
||||||
|
|
||||||
|
// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
|
||||||
|
// var name = result[ 0 ].substr( 1 ).trim();
|
||||||
|
var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 ); |
||||||
|
|
||||||
|
state.startObject( name ); |
||||||
|
|
||||||
|
} else if ( material_use_pattern.test( line ) ) { |
||||||
|
|
||||||
|
// material
|
||||||
|
|
||||||
|
state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries ); |
||||||
|
|
||||||
|
} else if ( material_library_pattern.test( line ) ) { |
||||||
|
|
||||||
|
// mtl file
|
||||||
|
|
||||||
|
state.materialLibraries.push( line.substring( 7 ).trim() ); |
||||||
|
|
||||||
|
} else if ( lineFirstChar === 's' ) { |
||||||
|
|
||||||
|
result = line.split( ' ' ); |
||||||
|
|
||||||
|
// smooth shading
|
||||||
|
|
||||||
|
// @todo Handle files that have varying smooth values for a set of faces inside one geometry,
|
||||||
|
// but does not define a usemtl for each face set.
|
||||||
|
// This should be detected and a dummy material created (later MultiMaterial and geometry groups).
|
||||||
|
// This requires some care to not create extra material on each smooth value for "normal" obj files.
|
||||||
|
// where explicit usemtl defines geometry groups.
|
||||||
|
// Example asset: examples/models/obj/cerberus/Cerberus.obj
|
||||||
|
|
||||||
|
/* |
||||||
|
* http://paulbourke.net/dataformats/obj/
|
||||||
|
* or |
||||||
|
* http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf
|
||||||
|
* |
||||||
|
* From chapter "Grouping" Syntax explanation "s group_number": |
||||||
|
* "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off. |
||||||
|
* Polygonal elements use group numbers to put elements in different smoothing groups. For free-form |
||||||
|
* surfaces, smoothing groups are either turned on or off; there is no difference between values greater |
||||||
|
* than 0." |
||||||
|
*/ |
||||||
|
if ( result.length > 1 ) { |
||||||
|
|
||||||
|
var value = result[ 1 ].trim().toLowerCase(); |
||||||
|
state.object.smooth = ( value !== '0' && value !== 'off' ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// ZBrush can produce "s" lines #11707
|
||||||
|
state.object.smooth = true; |
||||||
|
|
||||||
|
} |
||||||
|
var material = state.object.currentMaterial(); |
||||||
|
if ( material ) material.smooth = state.object.smooth; |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
// Handle null terminated files without exception
|
||||||
|
if ( line === '\0' ) continue; |
||||||
|
|
||||||
|
throw new Error( 'THREE.OBJLoader: Unexpected line: "' + line + '"' ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
state.finalize(); |
||||||
|
|
||||||
|
var container = new THREE.Group(); |
||||||
|
container.materialLibraries = [].concat( state.materialLibraries ); |
||||||
|
|
||||||
|
for ( var i = 0, l = state.objects.length; i < l; i ++ ) { |
||||||
|
|
||||||
|
var object = state.objects[ i ]; |
||||||
|
var geometry = object.geometry; |
||||||
|
var materials = object.materials; |
||||||
|
var isLine = ( geometry.type === 'Line' ); |
||||||
|
var isPoints = ( geometry.type === 'Points' ); |
||||||
|
var hasVertexColors = false; |
||||||
|
|
||||||
|
// Skip o/g line declarations that did not follow with any faces
|
||||||
|
if ( geometry.vertices.length === 0 ) continue; |
||||||
|
|
||||||
|
var buffergeometry = new THREE.BufferGeometry(); |
||||||
|
|
||||||
|
buffergeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) ); |
||||||
|
|
||||||
|
if ( geometry.normals.length > 0 ) { |
||||||
|
|
||||||
|
buffergeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
buffergeometry.computeVertexNormals(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( geometry.colors.length > 0 ) { |
||||||
|
|
||||||
|
hasVertexColors = true; |
||||||
|
buffergeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( geometry.uvs.length > 0 ) { |
||||||
|
|
||||||
|
buffergeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Create materials
|
||||||
|
|
||||||
|
var createdMaterials = []; |
||||||
|
|
||||||
|
for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { |
||||||
|
|
||||||
|
var sourceMaterial = materials[ mi ]; |
||||||
|
var material = undefined; |
||||||
|
|
||||||
|
if ( this.materials !== null ) { |
||||||
|
|
||||||
|
material = this.materials.create( sourceMaterial.name ); |
||||||
|
|
||||||
|
// mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
|
||||||
|
if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) { |
||||||
|
|
||||||
|
var materialLine = new THREE.LineBasicMaterial(); |
||||||
|
THREE.Material.prototype.copy.call( materialLine, material ); |
||||||
|
materialLine.color.copy( material.color ); |
||||||
|
materialLine.lights = false; |
||||||
|
material = materialLine; |
||||||
|
|
||||||
|
} else if ( isPoints && material && ! ( material instanceof THREE.PointsMaterial ) ) { |
||||||
|
|
||||||
|
var materialPoints = new THREE.PointsMaterial( { size: 10, sizeAttenuation: false } ); |
||||||
|
THREE.Material.prototype.copy.call( materialPoints, material ); |
||||||
|
materialPoints.color.copy( material.color ); |
||||||
|
materialPoints.map = material.map; |
||||||
|
materialPoints.lights = false; |
||||||
|
material = materialPoints; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( ! material ) { |
||||||
|
|
||||||
|
if ( isLine ) { |
||||||
|
|
||||||
|
material = new THREE.LineBasicMaterial(); |
||||||
|
|
||||||
|
} else if ( isPoints ) { |
||||||
|
|
||||||
|
material = new THREE.PointsMaterial( { size: 1, sizeAttenuation: false } ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
material = new THREE.MeshPhongMaterial(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
material.name = sourceMaterial.name; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
material.flatShading = sourceMaterial.smooth ? false : true; |
||||||
|
material.vertexColors = hasVertexColors ? THREE.VertexColors : THREE.NoColors; |
||||||
|
|
||||||
|
createdMaterials.push( material ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Create mesh
|
||||||
|
|
||||||
|
var mesh; |
||||||
|
|
||||||
|
if ( createdMaterials.length > 1 ) { |
||||||
|
|
||||||
|
for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { |
||||||
|
|
||||||
|
var sourceMaterial = materials[ mi ]; |
||||||
|
buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if ( isLine ) { |
||||||
|
|
||||||
|
mesh = new THREE.LineSegments( buffergeometry, createdMaterials ); |
||||||
|
|
||||||
|
} else if ( isPoints ) { |
||||||
|
|
||||||
|
mesh = new THREE.Points( buffergeometry, createdMaterials ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
mesh = new THREE.Mesh( buffergeometry, createdMaterials ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
if ( isLine ) { |
||||||
|
|
||||||
|
mesh = new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] ); |
||||||
|
|
||||||
|
} else if ( isPoints ) { |
||||||
|
|
||||||
|
mesh = new THREE.Points( buffergeometry, createdMaterials[ 0 ] ); |
||||||
|
|
||||||
|
} else { |
||||||
|
|
||||||
|
mesh = new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
mesh.name = object.name; |
||||||
|
|
||||||
|
container.add( mesh ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
console.timeEnd( 'OBJLoader' ); |
||||||
|
|
||||||
|
return container; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
return OBJLoader; |
||||||
|
|
||||||
|
} )(); |
@ -0,0 +1,7 @@ |
|||||||
|
import Vue from 'vue' |
||||||
|
import Vuetify from 'vuetify/lib' |
||||||
|
import 'vuetify/src/stylus/app.styl' |
||||||
|
|
||||||
|
Vue.use(Vuetify, { |
||||||
|
iconfont: 'md', |
||||||
|
}) |
@ -0,0 +1,36 @@ |
|||||||
|
import Vue from 'vue' |
||||||
|
import Router from 'vue-router' |
||||||
|
import Home from './views/Home.vue' |
||||||
|
import Login from './views/Login' |
||||||
|
import Create from './views/Create' |
||||||
|
import Show from './views/Show' |
||||||
|
import Refuse from './views/Refuse' |
||||||
|
|
||||||
|
Vue.use(Router) |
||||||
|
|
||||||
|
export default new Router({ |
||||||
|
routes: [ |
||||||
|
{ |
||||||
|
path: '/', |
||||||
|
component: Login |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: '/home', |
||||||
|
component: Home |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: '/create/:sid', |
||||||
|
component: Create, |
||||||
|
props: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: '/show/:sid', |
||||||
|
component: Show, |
||||||
|
props: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: '/refuse', |
||||||
|
component: Refuse |
||||||
|
}, |
||||||
|
] |
||||||
|
}) |
@ -0,0 +1,16 @@ |
|||||||
|
import Vue from 'vue' |
||||||
|
import Vuex from 'vuex' |
||||||
|
|
||||||
|
Vue.use(Vuex) |
||||||
|
|
||||||
|
export default new Vuex.Store({ |
||||||
|
state: { |
||||||
|
|
||||||
|
}, |
||||||
|
mutations: { |
||||||
|
|
||||||
|
}, |
||||||
|
actions: { |
||||||
|
|
||||||
|
} |
||||||
|
}) |
@ -0,0 +1,841 @@ |
|||||||
|
<template> |
||||||
|
<v-app dark id="keep"> |
||||||
|
<!-- 侧边栏开始 --> |
||||||
|
<v-navigation-drawer v-model="mainDrawer" absolute fixed clipped app> |
||||||
|
<v-list dense> |
||||||
|
<v-layout row align-center> |
||||||
|
<v-flex xs6> |
||||||
|
<v-subheader>所有部件</v-subheader> |
||||||
|
</v-flex> |
||||||
|
<v-flex xs6 class="text-xs-right"> |
||||||
|
<v-btn small flat @click="componentDialog=true">编辑</v-btn> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
<!-- 部件列表开始 --> |
||||||
|
<v-list-group v-for="(item,index) in componentsInfo" :key="index"> |
||||||
|
<template v-slot:activator> |
||||||
|
<v-list-tile> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>{{ item.componentName }}</v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
</template> |
||||||
|
<v-list-tile |
||||||
|
color="amber lighten-1" |
||||||
|
v-for="(subItem,subIndex) in item.models" |
||||||
|
:key="subItem.fid" |
||||||
|
@click="modelChange(index,subIndex)" |
||||||
|
> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title> |
||||||
|
{{ subItem.name }} |
||||||
|
<v-icon small v-if="subIndex==item.modelSelected">arrow_left</v-icon> |
||||||
|
</v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-divider/> |
||||||
|
<v-container grid-list-sm fluid v-if="item.textures.length>0"> |
||||||
|
<v-layout row wrap> |
||||||
|
<v-flex v-for="(subItem,subIndex) in item.textures" :key="subItem.fid" xs2 d-flex> |
||||||
|
<v-card flat tile class="d-flex" @click="textureChange(index,subIndex)"> |
||||||
|
<v-img :src="subItem.path+'?size=60'" aspect-ratio="1" class="grey lighten-2"> |
||||||
|
<template v-slot:placeholder> |
||||||
|
<v-layout fill-height align-center justify-center ma-0> |
||||||
|
<v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular> |
||||||
|
</v-layout> |
||||||
|
</template> |
||||||
|
</v-img> |
||||||
|
</v-card> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-container> |
||||||
|
<v-list-tile @click="componentIndex=index;waitUploadList=[];uploadDrawer = true"> |
||||||
|
<v-list-tile-action> |
||||||
|
<v-icon>cloud_upload</v-icon> |
||||||
|
</v-list-tile-action> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>上传模型文件</v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-list-tile @click="componentIndex=index;textureDialog=true"> |
||||||
|
<v-list-tile-action> |
||||||
|
<v-icon>picture_in_picture</v-icon> |
||||||
|
</v-list-tile-action> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>贴图文件管理</v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
</v-list-group> |
||||||
|
<!-- 部件列表结束 --> |
||||||
|
<v-list-tile @click="addComponentDialog=true"> |
||||||
|
<v-list-tile-action> |
||||||
|
<v-icon>add</v-icon> |
||||||
|
</v-list-tile-action> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>添加新部件</v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
</v-list> |
||||||
|
<!-- 相机参数 --> |
||||||
|
<v-list two-line> |
||||||
|
<v-list-tile> |
||||||
|
<v-layout row> |
||||||
|
<v-flex class="pr-3"> |
||||||
|
<v-slider |
||||||
|
label="相机高度" |
||||||
|
v-model="cameraControll.height" |
||||||
|
:max="cameraControll.heightMax" |
||||||
|
min="0" |
||||||
|
></v-slider> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-list-tile> |
||||||
|
<v-list-tile> |
||||||
|
<v-layout row> |
||||||
|
<v-flex class="pr-3"> |
||||||
|
<v-slider |
||||||
|
label="相机距离" |
||||||
|
v-model="cameraControll.distance" |
||||||
|
:max="cameraControll.distanceMax" |
||||||
|
min="0" |
||||||
|
></v-slider> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-list-tile> |
||||||
|
<v-list-tile> |
||||||
|
<v-layout row> |
||||||
|
<v-flex class="pr-3"> |
||||||
|
<v-slider |
||||||
|
label="贴图缩放" |
||||||
|
v-model="cameraControll.textureSize" |
||||||
|
max="100" |
||||||
|
min="1" |
||||||
|
></v-slider> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-list-tile> |
||||||
|
</v-list> |
||||||
|
</v-navigation-drawer> |
||||||
|
<!-- 侧边栏结束 --> |
||||||
|
<!-- 工具栏开始 --> |
||||||
|
<v-toolbar dark color="red" app clipped-left> |
||||||
|
<v-toolbar-side-icon @click="mainDrawer = !mainDrawer"></v-toolbar-side-icon> |
||||||
|
<span class="title ml-3 mr-5"> |
||||||
|
V3D |
||||||
|
<span class="font-weight-light">创建方案</span> |
||||||
|
</span> |
||||||
|
<v-spacer/> |
||||||
|
<v-text-field v-model="name" solo-inverted flat hide-details class="hidden-sm-and-down"></v-text-field> |
||||||
|
<v-spacer/> |
||||||
|
<v-toolbar-items> |
||||||
|
<v-btn icon> |
||||||
|
<v-icon @click="settingDialog=true">settings</v-icon> |
||||||
|
</v-btn> |
||||||
|
<v-btn icon> |
||||||
|
<v-icon @click="refresh">refresh</v-icon> |
||||||
|
</v-btn> |
||||||
|
<v-tooltip bottom> |
||||||
|
<template v-slot:activator="{ on }"> |
||||||
|
<v-btn icon v-on="on" @click="saveScheme"> |
||||||
|
<v-icon>save</v-icon> |
||||||
|
</v-btn> |
||||||
|
</template> |
||||||
|
<span>保存方案</span> |
||||||
|
</v-tooltip> |
||||||
|
<v-btn icon @click="exitDialog = true"> |
||||||
|
<v-icon>exit_to_app</v-icon> |
||||||
|
</v-btn> |
||||||
|
</v-toolbar-items> |
||||||
|
</v-toolbar> |
||||||
|
<!-- 工具栏结束 --> |
||||||
|
<!-- 诡异的样式问题 --> |
||||||
|
<v-content style="height:0px;background-color:#ddd"> |
||||||
|
<ThreeStage |
||||||
|
:components-info="componentsInfo" |
||||||
|
:camera-controll="cameraControll" |
||||||
|
ref="threeStage" |
||||||
|
/> |
||||||
|
</v-content> |
||||||
|
<!-- 右侧drawer开始 --> |
||||||
|
<v-navigation-drawer v-model="uploadDrawer" right temporary fixed> |
||||||
|
<input |
||||||
|
type="file" |
||||||
|
multiple="multiple" |
||||||
|
ref="file" |
||||||
|
style="display:none" |
||||||
|
accept=".fbx, .obj" |
||||||
|
@change="fileChange" |
||||||
|
> |
||||||
|
<v-list> |
||||||
|
<v-subheader |
||||||
|
v-if="componentsInfo[componentIndex]" |
||||||
|
>{{componentsInfo[componentIndex].componentName}} - 待上传文件</v-subheader> |
||||||
|
<div v-for="(item,index) in waitUploadList" :key="index"> |
||||||
|
<v-list-tile> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title v-text="item.name"></v-list-tile-title> |
||||||
|
<v-list-tile-sub-title>{{item.size|fileSize}}</v-list-tile-sub-title> |
||||||
|
</v-list-tile-content> |
||||||
|
<v-list-tile-action> |
||||||
|
<v-btn icon ripple @click="waitUploadList.splice(index, 1)"> |
||||||
|
<v-icon color="grey lighten-1">cancel</v-icon> |
||||||
|
</v-btn> |
||||||
|
</v-list-tile-action> |
||||||
|
</v-list-tile> |
||||||
|
<v-divider></v-divider> |
||||||
|
</div> |
||||||
|
<v-list-tile> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-btn block dark color="blue" @click="$refs.file.click()"> |
||||||
|
选择文件 |
||||||
|
<v-icon right dark>folder_open</v-icon> |
||||||
|
</v-btn> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-list-tile> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-btn block dark color="red" @click="uploadModel"> |
||||||
|
开始上传 |
||||||
|
<v-icon right dark>cloud_upload</v-icon> |
||||||
|
</v-btn> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
</v-list> |
||||||
|
</v-navigation-drawer> |
||||||
|
<!-- 右侧drawer结束 --> |
||||||
|
<!-- 贴图管理 开始 --> |
||||||
|
<v-dialog v-model="textureDialog" persistent max-width="600px"> |
||||||
|
<input |
||||||
|
type="file" |
||||||
|
multiple="multiple" |
||||||
|
ref="textureFile" |
||||||
|
style="display:none" |
||||||
|
accept=".jpg, .png" |
||||||
|
@change="textureFileChange" |
||||||
|
> |
||||||
|
<v-card light> |
||||||
|
<v-card-title> |
||||||
|
<span |
||||||
|
class="headline" |
||||||
|
v-if="componentsInfo[componentIndex]" |
||||||
|
>{{componentsInfo[componentIndex].componentName}} - 贴图管理</span> |
||||||
|
</v-card-title> |
||||||
|
<v-card-text> |
||||||
|
<v-container grid-list-sm fluid v-if="componentsInfo[componentIndex]"> |
||||||
|
<v-layout row wrap> |
||||||
|
<v-flex |
||||||
|
v-for="(item,index) in componentsInfo[componentIndex].textures" |
||||||
|
:key="item.name" |
||||||
|
xs1 |
||||||
|
d-flex |
||||||
|
@click="delTexture(componentIndex,index)" |
||||||
|
> |
||||||
|
<v-card flat tile class="d-flex elevation-1"> |
||||||
|
<v-img :src="item.path+'?size=40'" aspect-ratio="1" class="grey lighten-2"> |
||||||
|
<template v-slot:placeholder> |
||||||
|
<v-layout fill-height align-center justify-center ma-0> |
||||||
|
<v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular> |
||||||
|
</v-layout> |
||||||
|
</template> |
||||||
|
</v-img> |
||||||
|
</v-card> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-container> |
||||||
|
<small style="display:block;text-align:right;color:#aaa" class="pr-4">*单击可删除贴图</small> |
||||||
|
</v-card-text> |
||||||
|
<v-card-actions> |
||||||
|
<v-btn color="blue" flat @click="$refs.textureFile.click()">添加贴图</v-btn> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn color="red" flat @click="textureDialog = false">确定</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 贴图管理 结束 --> |
||||||
|
<!-- 部件管理 开始 --> |
||||||
|
<v-dialog v-model="componentDialog" max-width="600px"> |
||||||
|
<v-card light> |
||||||
|
<v-card-text> |
||||||
|
<v-tabs v-model="tabActive" color="red" dark slider-color="yellow"> |
||||||
|
<v-tab v-for="(item,index) in componentsInfo" :key="index" ripple>{{item.componentName}}</v-tab> |
||||||
|
<v-tab-item v-for="(item,index) in componentsInfo" :key="index"> |
||||||
|
<v-card flat> |
||||||
|
<v-card-text> |
||||||
|
<v-list> |
||||||
|
<div v-for="(subItem,subIndex) in item.models" :key="subItem.fid"> |
||||||
|
<v-list-tile> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-text-field |
||||||
|
v-model="componentsInfo[index].models[subIndex].name" |
||||||
|
single-line |
||||||
|
full-width |
||||||
|
hide-details |
||||||
|
></v-text-field> |
||||||
|
</v-list-tile-content> |
||||||
|
<v-list-tile-content class="align-end"> |
||||||
|
<v-btn icon ripple @click="delModel(index, subIndex)"> |
||||||
|
<v-icon color="grey lighten-1">cancel</v-icon> |
||||||
|
</v-btn> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-divider/> |
||||||
|
</div> |
||||||
|
</v-list> |
||||||
|
</v-card-text> |
||||||
|
</v-card> |
||||||
|
<div class="text-xs-center"> |
||||||
|
<v-btn round color="primary" outline @click="delComponent(index)">删除该部件</v-btn> |
||||||
|
</div> |
||||||
|
</v-tab-item> |
||||||
|
</v-tabs> |
||||||
|
</v-card-text> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn |
||||||
|
color="red" |
||||||
|
flat |
||||||
|
@click="componentDialog = false" |
||||||
|
item-text="componentName" |
||||||
|
item-children="models" |
||||||
|
>确定</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 部件管理 结束 --> |
||||||
|
<!-- 添加部件模态框 开始--> |
||||||
|
<v-dialog v-model="addComponentDialog" width="500"> |
||||||
|
<v-card> |
||||||
|
<v-toolbar dark color="red"> |
||||||
|
<v-toolbar-title>添加新部件</v-toolbar-title> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn icon dark @click="addComponentDialog = false"> |
||||||
|
<v-icon>close</v-icon> |
||||||
|
</v-btn> |
||||||
|
</v-toolbar> |
||||||
|
<v-card-text> |
||||||
|
<v-text-field label="部件名称" color="red" v-model="componentName"></v-text-field> |
||||||
|
</v-card-text> |
||||||
|
<v-divider></v-divider> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn dark flat @click="addComponent">添加</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 添加部件模态框 结束 --> |
||||||
|
<!-- 文件上传进度模态框 开始 --> |
||||||
|
<v-dialog v-model="uploadingDialog" persistent width="300"> |
||||||
|
<v-card color="red" dark> |
||||||
|
<v-card-text> |
||||||
|
文件上传中 |
||||||
|
<v-progress-linear indeterminate color="white" class="mb-0"></v-progress-linear> |
||||||
|
</v-card-text> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 文件上传进度模态框 结束--> |
||||||
|
<!-- 文件加载进度模态框 开始 --> |
||||||
|
<v-dialog v-model="downloadingDialog" persistent width="300"> |
||||||
|
<v-card color="red" dark> |
||||||
|
<v-card-text> |
||||||
|
文件加载中 |
||||||
|
<v-progress-linear indeterminate color="white" class="mb-0"></v-progress-linear> |
||||||
|
</v-card-text> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 文件加载进度模态框 结束--> |
||||||
|
<!-- 退出保存模态框 开始 --> |
||||||
|
<v-dialog v-model="exitDialog" width="300"> |
||||||
|
<v-card> |
||||||
|
<v-card-text>是否保存当前修改?</v-card-text> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn flat @click="$router.push('/home')">直接退出</v-btn> |
||||||
|
<v-btn flat @click="saveScheme();$router.push('/home')">保存退出</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 退出保存模态框 结束 --> |
||||||
|
<!-- 设置开始 --> |
||||||
|
<v-dialog v-model="settingDialog" fullscreen hide-overlay transition="dialog-bottom-transition"> |
||||||
|
<v-card light> |
||||||
|
<v-toolbar dark color="primary"> |
||||||
|
<v-btn icon dark @click="settingDialog = false"> |
||||||
|
<v-icon>close</v-icon> |
||||||
|
</v-btn> |
||||||
|
<v-toolbar-title>设置</v-toolbar-title> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-toolbar-items> |
||||||
|
<v-btn dark flat @click="saveSetting">确定</v-btn> |
||||||
|
</v-toolbar-items> |
||||||
|
</v-toolbar> |
||||||
|
<v-list three-line subheader> |
||||||
|
<v-subheader>相机参数</v-subheader> |
||||||
|
<v-list-tile avatar> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>相机最大高度</v-list-tile-title> |
||||||
|
<v-list-tile-sub-title> |
||||||
|
<v-flex shrink style="width: 60px"> |
||||||
|
<v-text-field |
||||||
|
v-model="cameraControll.heightMax" |
||||||
|
class="mt-0" |
||||||
|
hide-details |
||||||
|
single-line |
||||||
|
type="number" |
||||||
|
></v-text-field> |
||||||
|
</v-flex> |
||||||
|
</v-list-tile-sub-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-list-tile avatar> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>相机最远距离</v-list-tile-title> |
||||||
|
<v-list-tile-sub-title> |
||||||
|
<v-flex shrink style="width: 60px"> |
||||||
|
<v-text-field |
||||||
|
v-model="cameraControll.distanceMax" |
||||||
|
class="mt-0" |
||||||
|
hide-details |
||||||
|
single-line |
||||||
|
type="number" |
||||||
|
></v-text-field> |
||||||
|
</v-flex> |
||||||
|
</v-list-tile-sub-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-divider></v-divider> |
||||||
|
<v-subheader>方案分享</v-subheader> |
||||||
|
<v-layout wrap class="ma-3"> |
||||||
|
<v-flex xs12 sm8 class="pr-5"> |
||||||
|
<v-switch label="开启分享" color="red" v-model="isShared"></v-switch> |
||||||
|
<v-text-field label="访问地址" outline readonly :value="shareLink"></v-text-field> |
||||||
|
<input :value="shareLink" ref="shareLink" style="display:none"> |
||||||
|
<input |
||||||
|
:value="`<iframe src='${shareLink}' scrolling='no' frameborder='0' width='100%' height='100%'></iframe>`" |
||||||
|
ref="iframLink" |
||||||
|
style="display:none" |
||||||
|
> |
||||||
|
<v-switch label="使用密码" color="red" v-model="hasPassword"></v-switch> |
||||||
|
<v-text-field |
||||||
|
v-model="sharePassword" |
||||||
|
label="访问密码" |
||||||
|
:type="hasPassword&&showPassword ? 'text' : 'password'" |
||||||
|
:disabled="!hasPassword" |
||||||
|
:append-icon="hasPassword&&showPassword? 'visibility' : 'visibility_off'" |
||||||
|
@click:append="showPassword = !showPassword" |
||||||
|
></v-text-field> |
||||||
|
</v-flex> |
||||||
|
<v-flex xs12 sm4> |
||||||
|
<v-layout justify-end fill-height> |
||||||
|
<v-flex align-self-end> |
||||||
|
<canvas ref="qr"></canvas> |
||||||
|
</v-flex> |
||||||
|
<v-spacer/> |
||||||
|
<v-layout column justify-end class="mb-3"> |
||||||
|
<a style="text-align:right" class="ma-2"> |
||||||
|
关于IFrames地址的使用 |
||||||
|
<v-icon small>help</v-icon> |
||||||
|
</a> |
||||||
|
<v-btn color="blue" dark @click="copyIframe">iframe地址</v-btn> |
||||||
|
<v-btn color="blue" dark @click="copyLink">复制访问地址</v-btn> |
||||||
|
<v-btn color="green" dark @click="saveQR">保存二维码</v-btn> |
||||||
|
</v-layout> |
||||||
|
</v-layout> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-list> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 设置结束 --> |
||||||
|
</v-app> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import "../plugins/OBJLoader"; |
||||||
|
import "../plugins/FBXLoader"; |
||||||
|
import { |
||||||
|
LoadingManager, |
||||||
|
TextureLoader, |
||||||
|
OBJLoader, |
||||||
|
FBXLoader, |
||||||
|
DoubleSide |
||||||
|
} from "three"; |
||||||
|
import ThreeStage from "../components/ThreeStage"; |
||||||
|
import QRious from "qrious"; |
||||||
|
|
||||||
|
export default { |
||||||
|
components: { |
||||||
|
ThreeStage |
||||||
|
}, |
||||||
|
props: ["sid"], |
||||||
|
data: () => ({ |
||||||
|
//tab |
||||||
|
tabActive: null, |
||||||
|
//drawer |
||||||
|
mainDrawer: false, |
||||||
|
uploadDrawer: false, |
||||||
|
//dialog |
||||||
|
addComponentDialog: null, |
||||||
|
uploadingDialog: null, |
||||||
|
downloadingDialog: null, |
||||||
|
exitDialog: null, |
||||||
|
textureDialog: null, |
||||||
|
settingDialog: null, |
||||||
|
componentDialog: null, |
||||||
|
//方案临时数据 |
||||||
|
componentIndex: null, |
||||||
|
componentName: "", |
||||||
|
waitUploadList: [], |
||||||
|
//方案保存数据 |
||||||
|
name: "", |
||||||
|
cameraControll: { |
||||||
|
height: 10, |
||||||
|
distance: 40, |
||||||
|
textureSize:1, |
||||||
|
heightMax: 200, |
||||||
|
distanceMax: 200 |
||||||
|
}, |
||||||
|
componentsInfo: [], |
||||||
|
//share |
||||||
|
shareLink: "", |
||||||
|
isShared: false, |
||||||
|
hasPassword: false, |
||||||
|
showPassword: false, |
||||||
|
sharePassword: "" |
||||||
|
}), |
||||||
|
watch: { |
||||||
|
//当创建dialog退出时候清空文本栏 |
||||||
|
addComponentDialog() { |
||||||
|
this.componentName = ""; |
||||||
|
} |
||||||
|
}, |
||||||
|
filters: { |
||||||
|
fileSize: function(value) { |
||||||
|
return (value / 1024 / 1024).toFixed(2) + " MB"; |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
saveSetting() { |
||||||
|
let share = 0; |
||||||
|
if (this.isShared) { |
||||||
|
if (this.hasPassword) { |
||||||
|
share = 2; |
||||||
|
} else { |
||||||
|
share = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
this.$http |
||||||
|
.post( |
||||||
|
"/scheme/share", |
||||||
|
{ |
||||||
|
sid: this.sid, |
||||||
|
share: share, |
||||||
|
password: this.sharePassword |
||||||
|
}, |
||||||
|
{} |
||||||
|
) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
this.settingDialog = false; |
||||||
|
}, |
||||||
|
copyLink() { |
||||||
|
this.$refs.shareLink.style.display = "inline"; |
||||||
|
this.$refs.shareLink.select(); |
||||||
|
document.execCommand("Copy"); |
||||||
|
this.$refs.shareLink.style.display = "none"; |
||||||
|
}, |
||||||
|
copyIframe() { |
||||||
|
this.$refs.iframLink.style.display = "inline"; |
||||||
|
this.$refs.iframLink.select(); |
||||||
|
document.execCommand("Copy"); |
||||||
|
this.$refs.iframLink.style.display = "none"; |
||||||
|
}, |
||||||
|
saveQR() { |
||||||
|
let a = document.createElement("a"); |
||||||
|
a.href = this.$refs.qr.toDataURL("image/png"); |
||||||
|
a.download = "qr.png"; |
||||||
|
let event = document.createEvent("MouseEvents"); |
||||||
|
event.initEvent("click", true, false); |
||||||
|
a.dispatchEvent(event); |
||||||
|
}, |
||||||
|
addComponent() { |
||||||
|
let componentName = this.componentName.replace(/\s+/g, ""); |
||||||
|
if (componentName.length > 0) |
||||||
|
this.componentsInfo.push({ |
||||||
|
componentName, |
||||||
|
modelSelected: -1, |
||||||
|
textureSelected: -1, |
||||||
|
models: [], |
||||||
|
textures: [] |
||||||
|
}); |
||||||
|
this.addComponentDialog = false; |
||||||
|
}, |
||||||
|
fileChange() { |
||||||
|
for (var i = 0, j = this.$refs.file.files.length; i < j; i++) { |
||||||
|
this.waitUploadList.push(this.$refs.file.files[i]); |
||||||
|
} |
||||||
|
//重置file input |
||||||
|
this.$refs.file.value = ""; |
||||||
|
}, |
||||||
|
textureFileChange() { |
||||||
|
if (this.$refs.textureFile.files.length > 0) { |
||||||
|
this.uploadingDialog = true; |
||||||
|
var formData = new FormData(); |
||||||
|
formData.append("sid", this.sid); |
||||||
|
for (var i = 0, j = this.$refs.textureFile.files.length; i < j; i++) { |
||||||
|
formData.append("files", this.$refs.textureFile.files[i]); |
||||||
|
} |
||||||
|
this.$http |
||||||
|
.post("/file/uploadTexture", formData, { |
||||||
|
headers: { "Content-Type": "multipart/form-data" } |
||||||
|
}) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
data.body.data.uploadReply.map(item => { |
||||||
|
this.componentsInfo[this.componentIndex].textures.push(item); |
||||||
|
}); |
||||||
|
} |
||||||
|
this.uploadingDialog = false; |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
//重置file input |
||||||
|
this.$refs.textureFile.value = ""; |
||||||
|
} |
||||||
|
}, |
||||||
|
uploadModel() { |
||||||
|
if (this.waitUploadList.length > 0) { |
||||||
|
this.uploadDrawer = false; |
||||||
|
this.uploadingDialog = true; |
||||||
|
var formData = new FormData(); |
||||||
|
formData.append("sid", this.sid); |
||||||
|
this.waitUploadList.map(item => { |
||||||
|
formData.append("files", item); |
||||||
|
}); |
||||||
|
this.$http |
||||||
|
.post("/file/uploadModel", formData, { |
||||||
|
headers: { "Content-Type": "multipart/form-data" } |
||||||
|
}) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
data.body.data.uploadReply.map(item => { |
||||||
|
this.componentsInfo[this.componentIndex].models.push(item); |
||||||
|
}); |
||||||
|
} |
||||||
|
this.uploadingDialog = false; |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
}, |
||||||
|
refresh() { |
||||||
|
this.$http.get("/scheme/" + this.sid, {}, {}).then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.name = data.body.data.name; |
||||||
|
this.shareLink = data.body.data.shareLink; |
||||||
|
this.sharePassword = data.body.data.password; |
||||||
|
var qr = new QRious({ |
||||||
|
element: this.$refs.qr, |
||||||
|
size: 250, |
||||||
|
level: "L", |
||||||
|
foreground: "#424242", |
||||||
|
background: "#fff", |
||||||
|
value: this.shareLink |
||||||
|
}); |
||||||
|
switch (data.body.data.share) { |
||||||
|
case 0: |
||||||
|
this.isShared = false; |
||||||
|
this.hasPassword = false; |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
this.isShared = true; |
||||||
|
this.hasPassword = false; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
this.isShared = true; |
||||||
|
this.hasPassword = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
let componentsInfo = JSON.parse(data.body.data.data); |
||||||
|
let cameraControll = JSON.parse(data.body.data.camera); |
||||||
|
if (componentsInfo) this.componentsInfo = componentsInfo; |
||||||
|
if (cameraControll) this.cameraControll = cameraControll; |
||||||
|
let manager = new LoadingManager(() => { |
||||||
|
this.downloadingDialog = false; |
||||||
|
}); |
||||||
|
this.componentsInfo.map((item, index) => { |
||||||
|
let modelIndex = item.modelSelected; |
||||||
|
let textureIndex = item.textureSelected; |
||||||
|
|
||||||
|
if (item.models[modelIndex] != null) { |
||||||
|
this.downloadingDialog = true; |
||||||
|
this.modelChange(index, modelIndex, manager); |
||||||
|
} |
||||||
|
if (item.textures[textureIndex] != null) { |
||||||
|
this.downloadingDialog = true; |
||||||
|
this.textureChange(index, textureIndex, manager); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else if (data.body.code == 2) { |
||||||
|
this.$router.push("/"); |
||||||
|
} else { |
||||||
|
this.$router.push("/home"); |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
}, |
||||||
|
saveScheme() { |
||||||
|
var formData = new FormData(); |
||||||
|
formData.append("sid", this.sid); |
||||||
|
formData.append("name", this.name); |
||||||
|
formData.append("file", this.$refs.threeStage.getCover()); |
||||||
|
//清空缓存的obj |
||||||
|
formData.append( |
||||||
|
"data", |
||||||
|
JSON.stringify(this.componentsInfo, (key, value) => { |
||||||
|
if (key == "obj") { |
||||||
|
return null; |
||||||
|
} else { |
||||||
|
return value; |
||||||
|
} |
||||||
|
}) |
||||||
|
); |
||||||
|
formData.append("camera", JSON.stringify(this.cameraControll)); |
||||||
|
this.$http |
||||||
|
.post("/scheme/save", formData, { |
||||||
|
headers: { "Content-Type": "multipart/form-data" } |
||||||
|
}) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
}, |
||||||
|
modelChange(componentIndex, modelIndex, manager) { |
||||||
|
if (manager == null) { |
||||||
|
this.downloadingDialog = true; |
||||||
|
manager = new LoadingManager(() => { |
||||||
|
this.downloadingDialog = false; |
||||||
|
}); |
||||||
|
} |
||||||
|
let model = this.componentsInfo[componentIndex].models[modelIndex]; |
||||||
|
if (model.obj == null) { |
||||||
|
//obj |
||||||
|
if ( |
||||||
|
model.path |
||||||
|
.split(".") |
||||||
|
.pop() |
||||||
|
.toLowerCase() === "obj" |
||||||
|
) { |
||||||
|
new OBJLoader(manager).load( |
||||||
|
model.path, |
||||||
|
//success回调 |
||||||
|
obj => { |
||||||
|
obj.traverse(child => { |
||||||
|
if (child.isMesh) { |
||||||
|
child.material.side = DoubleSide; |
||||||
|
} |
||||||
|
}); |
||||||
|
model.obj = obj; |
||||||
|
this.componentsInfo[componentIndex].modelSelected = modelIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
} |
||||||
|
); |
||||||
|
//fbx |
||||||
|
} else if ( |
||||||
|
model.path |
||||||
|
.split(".") |
||||||
|
.pop() |
||||||
|
.toLowerCase() === "fbx" |
||||||
|
) { |
||||||
|
new FBXLoader(manager).load( |
||||||
|
model.path, |
||||||
|
obj => { |
||||||
|
obj.traverse(child => { |
||||||
|
if (child.isMesh) { |
||||||
|
child.material.side = DoubleSide; |
||||||
|
} |
||||||
|
}); |
||||||
|
model.obj = obj; |
||||||
|
this.componentsInfo[componentIndex].modelSelected = modelIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
}, |
||||||
|
xhr => { |
||||||
|
if (xhr.lengthComputable) { |
||||||
|
// console.info((xhr.loaded / xhr.total) * 100); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
} else { |
||||||
|
this.componentsInfo[componentIndex].modelSelected = modelIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
this.downloadingDialog = false; |
||||||
|
} |
||||||
|
}, |
||||||
|
textureChange(componentIndex, textureIndex, manager) { |
||||||
|
if (manager == null) { |
||||||
|
this.downloadingDialog = true; |
||||||
|
manager = new LoadingManager(() => { |
||||||
|
this.downloadingDialog = false; |
||||||
|
}); |
||||||
|
} |
||||||
|
let texture = this.componentsInfo[componentIndex].textures[textureIndex]; |
||||||
|
if (texture.obj == null) { |
||||||
|
new TextureLoader(manager).load(texture.path, obj => { |
||||||
|
texture.obj = obj; |
||||||
|
this.componentsInfo[componentIndex].textureSelected = textureIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.componentsInfo[componentIndex].textureSelected = textureIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
this.downloadingDialog = false; |
||||||
|
} |
||||||
|
}, |
||||||
|
delTexture(componentIndex, textureIndex) { |
||||||
|
this.componentsInfo[componentIndex].textures.splice(textureIndex, 1); |
||||||
|
}, |
||||||
|
delModel(componentIndex, modelIndex) { |
||||||
|
let model = this.componentsInfo[componentIndex].models[modelIndex].obj; |
||||||
|
if (model != null) { |
||||||
|
model.parent.remove(model); |
||||||
|
} |
||||||
|
this.componentsInfo[componentIndex].models.splice(modelIndex, 1); |
||||||
|
}, |
||||||
|
delComponent(componentIndex) { |
||||||
|
for (let component of this.componentsInfo[componentIndex].models) { |
||||||
|
if (component.obj != null) { |
||||||
|
component.obj.parent.remove(component.obj); |
||||||
|
} |
||||||
|
} |
||||||
|
this.componentsInfo.splice(componentIndex, 1); |
||||||
|
} |
||||||
|
}, |
||||||
|
created() { |
||||||
|
this.refresh(); |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style > |
||||||
|
</style> |
@ -0,0 +1,514 @@ |
|||||||
|
<template> |
||||||
|
<v-app dark id="inspire"> |
||||||
|
<!-- drawer开始 --> |
||||||
|
<v-navigation-drawer v-model="drawer" fixed app> |
||||||
|
<v-list class="pa-1"> |
||||||
|
<v-list-tile avatar> |
||||||
|
<v-list-tile-avatar @click="avatarUpload=true"> |
||||||
|
<img :src="avatar"> |
||||||
|
</v-list-tile-avatar> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title v-text="userName"></v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
</v-list> |
||||||
|
<v-list class="pt-0" dense> |
||||||
|
<v-divider></v-divider> |
||||||
|
<v-list-tile @click="userDialog=true"> |
||||||
|
<v-list-tile-action> |
||||||
|
<v-icon>account_box</v-icon> |
||||||
|
</v-list-tile-action> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>修改用户信息</v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-list-tile @click> |
||||||
|
<v-list-tile-action> |
||||||
|
<v-icon>info</v-icon> |
||||||
|
</v-list-tile-action> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>关于V3D</v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-list-tile @click="logout"> |
||||||
|
<v-list-tile-action> |
||||||
|
<v-icon>exit_to_app</v-icon> |
||||||
|
</v-list-tile-action> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>退出系统</v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
</v-list> |
||||||
|
</v-navigation-drawer> |
||||||
|
<!-- drawer结束 --> |
||||||
|
|
||||||
|
<!-- 工具栏开始 --> |
||||||
|
<v-toolbar color="red" dark fixed app> |
||||||
|
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon> |
||||||
|
<v-toolbar-title>V3D</v-toolbar-title> |
||||||
|
<v-spacer/> |
||||||
|
<v-text-field |
||||||
|
clearable |
||||||
|
v-model="keyword" |
||||||
|
solo-inverted |
||||||
|
flat |
||||||
|
hide-details |
||||||
|
label="搜索" |
||||||
|
prepend-inner-icon="search" |
||||||
|
class="hidden-sm-and-down" |
||||||
|
></v-text-field> |
||||||
|
<v-spacer/> |
||||||
|
<v-toolbar-items class="hidden-sm-and-down"> |
||||||
|
<v-btn flat @click="createDialog=true"> |
||||||
|
<v-icon>add</v-icon>创建方案 |
||||||
|
</v-btn> |
||||||
|
</v-toolbar-items> |
||||||
|
</v-toolbar> |
||||||
|
<!-- 工具栏结束 --> |
||||||
|
|
||||||
|
<!-- 内容开始 --> |
||||||
|
<v-content> |
||||||
|
<v-container fluid fill-height v-if="schemeList.length==0"> |
||||||
|
<v-layout justify-center align-center> |
||||||
|
<v-flex text-xs-center class="headline font-weight-light">还没有方案,请先创建方案</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-container> |
||||||
|
<v-container fluid grid-list-md v-else> |
||||||
|
<v-layout row wrap> |
||||||
|
<v-flex |
||||||
|
v-for="(item,index) in schemeList" |
||||||
|
:key="item.sid" |
||||||
|
xs12 |
||||||
|
sm6 |
||||||
|
md3 |
||||||
|
v-if="keyword==null||item.name.indexOf(keyword)!=-1" |
||||||
|
> |
||||||
|
<v-card> |
||||||
|
<v-img :src="item.cover" height="200px"> |
||||||
|
<v-container fill-height fluid pa-2> |
||||||
|
<v-layout fill-height> |
||||||
|
<v-flex xs12 align-end flexbox> |
||||||
|
<span class="headline white--text" v-text="item.name"></span> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-container> |
||||||
|
</v-img> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn icon @click="edit(item.sid)"> |
||||||
|
<v-icon>edit</v-icon> |
||||||
|
</v-btn> |
||||||
|
<v-btn icon @click="share(index)"> |
||||||
|
<v-icon>share</v-icon> |
||||||
|
</v-btn> |
||||||
|
<v-btn icon @click="del(index)"> |
||||||
|
<v-icon>delete</v-icon> |
||||||
|
</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-container> |
||||||
|
</v-content> |
||||||
|
<!-- 内容结束 --> |
||||||
|
|
||||||
|
<!-- 底部开始 --> |
||||||
|
<v-footer color="red" app> |
||||||
|
<v-flex py-3 text-xs-center white--text xs12> |
||||||
|
<span class="white--text">© 2019 TONKIA V3D</span> |
||||||
|
</v-flex> |
||||||
|
</v-footer> |
||||||
|
<!-- 底部结束 --> |
||||||
|
|
||||||
|
<!-- 创建方案模态框 开始--> |
||||||
|
<v-dialog v-model="createDialog" width="500"> |
||||||
|
<v-card> |
||||||
|
<v-toolbar dark color="red"> |
||||||
|
<v-toolbar-title>创建新方案</v-toolbar-title> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn icon dark @click="createDialog = false"> |
||||||
|
<v-icon>close</v-icon> |
||||||
|
</v-btn> |
||||||
|
</v-toolbar> |
||||||
|
<v-card-text> |
||||||
|
<v-text-field label="方案名称" color="red" v-model="schemeName"></v-text-field> |
||||||
|
</v-card-text> |
||||||
|
<v-divider></v-divider> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn dark flat @click="createScheme">确定</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 创建方案模态框 结束 --> |
||||||
|
|
||||||
|
<!-- 方案分享 开始 --> |
||||||
|
<v-dialog v-model="shareDialog" persistent max-width="600px"> |
||||||
|
<v-card light> |
||||||
|
<v-card-title> |
||||||
|
<span class="headline">方案分享</span> |
||||||
|
</v-card-title> |
||||||
|
<v-divider/> |
||||||
|
<v-card-text> |
||||||
|
<v-container grid-list-md> |
||||||
|
<v-layout wrap> |
||||||
|
<v-flex xs12> |
||||||
|
<v-switch label="开启分享" color="red" v-model="isShared"></v-switch> |
||||||
|
<v-text-field label="访问地址" outline readonly :value="shareLink"></v-text-field> |
||||||
|
<input :value="shareLink" ref="shareLink" style="display:none"> |
||||||
|
<input |
||||||
|
:value="`<iframe src='${shareLink}' scrolling='no' frameborder='0' width='100%' height='100%'></iframe>`" |
||||||
|
ref="iframLink" |
||||||
|
style="display:none" |
||||||
|
> |
||||||
|
</v-flex> |
||||||
|
<v-layout class="ma-3"> |
||||||
|
<canvas ref="qr"></canvas> |
||||||
|
<v-spacer/> |
||||||
|
<v-layout column justify-end> |
||||||
|
<a style="text-align:right" class="ma-2"> |
||||||
|
关于IFrames地址的使用 |
||||||
|
<v-icon small>help</v-icon> |
||||||
|
</a> |
||||||
|
<v-btn color="blue" dark @click="copyIframe">iframe地址</v-btn> |
||||||
|
<v-btn color="blue" dark @click="copyLink">复制访问地址</v-btn> |
||||||
|
<v-btn color="green" dark @click="saveQR">保存二维码</v-btn> |
||||||
|
</v-layout> |
||||||
|
</v-layout> |
||||||
|
<v-flex xs12> |
||||||
|
<v-divider/> |
||||||
|
</v-flex> |
||||||
|
<v-flex xs12> |
||||||
|
<v-switch label="使用密码" color="red" v-model="hasPassword"></v-switch> |
||||||
|
<v-text-field |
||||||
|
v-model="sharePassword" |
||||||
|
label="访问密码" |
||||||
|
:type="hasPassword&&showPassword ? 'text' : 'password'" |
||||||
|
:disabled="!hasPassword" |
||||||
|
:append-icon="hasPassword&&showPassword? 'visibility' : 'visibility_off'" |
||||||
|
@click:append="showPassword = !showPassword" |
||||||
|
></v-text-field> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-container> |
||||||
|
</v-card-text> |
||||||
|
<v-divider/> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn color="blue darken-1" flat @click="shareDialog = false">取消</v-btn> |
||||||
|
<v-btn color="blue darken-1" flat @click="saveShare">保存</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 方案分享 结束 --> |
||||||
|
|
||||||
|
<!-- 用户信息修改 开始 --> |
||||||
|
<v-dialog v-model="userDialog" persistent max-width="600px"> |
||||||
|
<v-card light> |
||||||
|
<v-card-title> |
||||||
|
<span class="headline">用户信息修改</span> |
||||||
|
</v-card-title> |
||||||
|
<v-divider/> |
||||||
|
<v-card-text> |
||||||
|
<v-container> |
||||||
|
<v-layout row wrap> |
||||||
|
<v-flex xs9> |
||||||
|
<v-text-field box label="用户名" v-model="newName"></v-text-field> |
||||||
|
</v-flex> |
||||||
|
<v-flex xs3> |
||||||
|
<v-btn large flat color="blue" @click="changeName">修改用户名</v-btn> |
||||||
|
</v-flex> |
||||||
|
<v-flex xs12> |
||||||
|
<v-text-field box label="修改密码" v-model="pwd" type="password"></v-text-field> |
||||||
|
</v-flex> |
||||||
|
<v-flex xs12> |
||||||
|
<v-text-field box label="确认密码" v-model="repwd" type="password"></v-text-field> |
||||||
|
</v-flex> |
||||||
|
<v-flex xs12> |
||||||
|
<v-btn block color="blue" dark @click="changePwd">修改密码</v-btn> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-container> |
||||||
|
</v-card-text> |
||||||
|
<v-divider/> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn color="blue darken-1" flat @click="userDialog = false">确认</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 用户信息修改 结束 --> |
||||||
|
|
||||||
|
<!-- 图片上传组件 --> |
||||||
|
<avatar-upload |
||||||
|
@crop-upload-success="cropUploadSuccess" |
||||||
|
field="file" |
||||||
|
v-model="avatarUpload" |
||||||
|
:width="300" |
||||||
|
:height="300" |
||||||
|
url="/user/avatar" |
||||||
|
img-format="png" |
||||||
|
></avatar-upload> |
||||||
|
<!-- 图片上传组件 --> |
||||||
|
</v-app> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import QRious from "qrious"; |
||||||
|
import avatarUpload from "vue-image-crop-upload"; |
||||||
|
|
||||||
|
export default { |
||||||
|
components: { |
||||||
|
"avatar-upload": avatarUpload |
||||||
|
}, |
||||||
|
data: () => ({ |
||||||
|
//方案数据 |
||||||
|
schemeList: [], |
||||||
|
//临时数据 |
||||||
|
schemeName: "", |
||||||
|
keyword: "", |
||||||
|
shareLink: "", |
||||||
|
isShared: false, |
||||||
|
hasPassword: false, |
||||||
|
showPassword: false, |
||||||
|
sharePassword: "", |
||||||
|
shareIndex: 0, |
||||||
|
//用户 |
||||||
|
avatar: null, |
||||||
|
userName: null, |
||||||
|
//ui |
||||||
|
drawer: null, |
||||||
|
createDialog: null, |
||||||
|
shareDialog: null, |
||||||
|
userDialog: null, |
||||||
|
//crop image |
||||||
|
avatarUpload: false, |
||||||
|
//update userinfo |
||||||
|
newName: "", |
||||||
|
pwd: "", |
||||||
|
repwd: "" |
||||||
|
}), |
||||||
|
methods: { |
||||||
|
changeName() { |
||||||
|
this.$http |
||||||
|
.post( |
||||||
|
"/user/changeInfo", |
||||||
|
{ |
||||||
|
userName: this.newName |
||||||
|
}, |
||||||
|
{} |
||||||
|
) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.userName = this.newName; |
||||||
|
this.newName = ""; |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
}, |
||||||
|
changePwd() { |
||||||
|
if (this.pwd == this.repwd) { |
||||||
|
this.$http |
||||||
|
.post( |
||||||
|
"/user/changeInfo", |
||||||
|
{ |
||||||
|
password: this.pwd |
||||||
|
}, |
||||||
|
{} |
||||||
|
) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.pwd = ""; |
||||||
|
this.repwd = ""; |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
}, |
||||||
|
cropUploadSuccess(data, field) { |
||||||
|
if (data.code == 0) { |
||||||
|
this.avatar = data.data.avatar; |
||||||
|
} |
||||||
|
}, |
||||||
|
del(index) { |
||||||
|
this.$http |
||||||
|
.post( |
||||||
|
"/scheme/delete", |
||||||
|
{ |
||||||
|
sid: this.schemeList[index].sid |
||||||
|
}, |
||||||
|
{} |
||||||
|
) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.schemeList.splice(index, 1); |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
}, |
||||||
|
edit(sid) { |
||||||
|
this.$router.push("create/" + sid); |
||||||
|
}, |
||||||
|
share(index) { |
||||||
|
this.shareIndex = index; |
||||||
|
let scheme = this.schemeList[index]; |
||||||
|
var qr = new QRious({ |
||||||
|
element: this.$refs.qr, |
||||||
|
size: 250, |
||||||
|
level: "L", |
||||||
|
foreground: "#424242", |
||||||
|
background: "#fff", |
||||||
|
value: scheme.shareLink |
||||||
|
}); |
||||||
|
this.shareLink = scheme.shareLink; |
||||||
|
this.sharePassword = scheme.password; |
||||||
|
switch (scheme.share) { |
||||||
|
case 0: |
||||||
|
this.isShared = false; |
||||||
|
this.hasPassword = false; |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
this.isShared = true; |
||||||
|
this.hasPassword = false; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
this.isShared = true; |
||||||
|
this.hasPassword = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
this.shareDialog = true; |
||||||
|
}, |
||||||
|
copyLink() { |
||||||
|
this.$refs.shareLink.style.display = "inline"; |
||||||
|
this.$refs.shareLink.select(); |
||||||
|
document.execCommand("Copy"); |
||||||
|
this.$refs.shareLink.style.display = "none"; |
||||||
|
}, |
||||||
|
copyIframe() { |
||||||
|
this.$refs.iframLink.style.display = "inline"; |
||||||
|
this.$refs.iframLink.select(); |
||||||
|
document.execCommand("Copy"); |
||||||
|
this.$refs.iframLink.style.display = "none"; |
||||||
|
}, |
||||||
|
saveQR() { |
||||||
|
let a = document.createElement("a"); |
||||||
|
a.href = this.$refs.qr.toDataURL("image/png"); |
||||||
|
a.download = "qr.png"; |
||||||
|
let event = document.createEvent("MouseEvents"); |
||||||
|
event.initEvent("click", true, false); |
||||||
|
a.dispatchEvent(event); |
||||||
|
}, |
||||||
|
saveShare() { |
||||||
|
let index = this.shareIndex; |
||||||
|
let share = 0; |
||||||
|
if (this.isShared) { |
||||||
|
if (this.hasPassword) { |
||||||
|
share = 2; |
||||||
|
} else { |
||||||
|
share = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
this.schemeList[index].share = share; |
||||||
|
this.schemeList[index].password = this.sharePassword; |
||||||
|
this.$http |
||||||
|
.post( |
||||||
|
"/scheme/share", |
||||||
|
{ |
||||||
|
sid: this.schemeList[index].sid, |
||||||
|
share: this.schemeList[index].share, |
||||||
|
password: this.schemeList[index].password |
||||||
|
}, |
||||||
|
{} |
||||||
|
) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
this.shareDialog = false; |
||||||
|
}, |
||||||
|
createScheme() { |
||||||
|
this.$http |
||||||
|
.post( |
||||||
|
"/scheme/create", |
||||||
|
{ |
||||||
|
name: this.schemeName |
||||||
|
}, |
||||||
|
{} |
||||||
|
) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.$router.push("create/" + data.body.data.sid); |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
}, |
||||||
|
logout() { |
||||||
|
this.$http.get("/user/logout").then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.$router.push("/"); |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
//当创建dialog推出时候清空文本栏 |
||||||
|
createDialog() { |
||||||
|
this.schemeName = ""; |
||||||
|
}, |
||||||
|
userDialog() { |
||||||
|
this.newName = ""; |
||||||
|
this.pwd = ""; |
||||||
|
this.repwd = ""; |
||||||
|
} |
||||||
|
}, |
||||||
|
created() { |
||||||
|
this.$http.get("/home/getHomeInfo").then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
//初始化主页数据 |
||||||
|
this.avatar = data.body.data.userInfo.avatar; |
||||||
|
this.userName = data.body.data.userInfo.userName; |
||||||
|
this.schemeList = data.body.data.schemeList; |
||||||
|
} else { |
||||||
|
//初始化数据失败 |
||||||
|
this.$router.push("/"); |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
@ -0,0 +1,116 @@ |
|||||||
|
<template> |
||||||
|
<v-app dark> |
||||||
|
<v-content> |
||||||
|
<v-alert |
||||||
|
dismissible |
||||||
|
v-model="alert" |
||||||
|
type="error" |
||||||
|
transition="scale-transition" |
||||||
|
style="position:absolute;width:100%;margin:0px" |
||||||
|
>{{msg}}</v-alert> |
||||||
|
<v-container fluid fill-height> |
||||||
|
<v-layout align-center justify-center> |
||||||
|
<v-flex sm12 md4> |
||||||
|
<v-card light class="elevation-12"> |
||||||
|
<v-toolbar dark color="red"> |
||||||
|
<v-toolbar-title>用户登录</v-toolbar-title> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<!-- 提示的方向 --> |
||||||
|
<v-tooltip bottom> |
||||||
|
<!-- 这是需要提示的部件,任意 --> |
||||||
|
<!-- on 是 v-tooltip 传递过来的事件处理方法 --> |
||||||
|
<template v-slot:activator="{on}"> |
||||||
|
<v-btn icon large v-on="on"> |
||||||
|
<v-icon large>info</v-icon> |
||||||
|
</v-btn> |
||||||
|
</template> |
||||||
|
<!-- 这是默认插槽,即提示的内容 --> |
||||||
|
<span>关于V3D</span> |
||||||
|
</v-tooltip> |
||||||
|
</v-toolbar> |
||||||
|
<v-card-text> |
||||||
|
<v-form> |
||||||
|
<v-text-field |
||||||
|
prepend-icon="phone" |
||||||
|
name="phoneNumber" |
||||||
|
label="手机号" |
||||||
|
type="tel" |
||||||
|
color="red" |
||||||
|
v-model="phoneNumber" |
||||||
|
mask="###########" |
||||||
|
/> |
||||||
|
<v-text-field |
||||||
|
prepend-icon="lock" |
||||||
|
name="password" |
||||||
|
label="密码" |
||||||
|
type="password" |
||||||
|
color="red" |
||||||
|
v-model="password" |
||||||
|
/> |
||||||
|
</v-form> |
||||||
|
</v-card-text> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn dark color="red" @click="login">登 录</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-container> |
||||||
|
</v-content> |
||||||
|
</v-app> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
data: () => ({ |
||||||
|
alert: false, |
||||||
|
msg: "", |
||||||
|
phoneNumber: "", |
||||||
|
password: "" |
||||||
|
}), |
||||||
|
methods: { |
||||||
|
login() { |
||||||
|
this.$http |
||||||
|
.post( |
||||||
|
"/user/login", |
||||||
|
{ |
||||||
|
phoneNumber: this.phoneNumber, |
||||||
|
password: this.password |
||||||
|
}, |
||||||
|
{} |
||||||
|
) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.$router.push("home"); |
||||||
|
} else { |
||||||
|
this.alert = true; |
||||||
|
this.msg = data.body.msg; |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
}, |
||||||
|
beforeCreate() { |
||||||
|
this.$http.get("/user/hasLogin").then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.$router.push("home"); |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
</style> |
@ -0,0 +1,12 @@ |
|||||||
|
<template> |
||||||
|
<v-app dark> |
||||||
|
<v-content class="body-2 text-xs-center">无法获取数据!</v-content> |
||||||
|
</v-app> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default {}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
</style> |
@ -0,0 +1,415 @@ |
|||||||
|
<template> |
||||||
|
<v-app> |
||||||
|
<v-toolbar color="red" dark app clipped-left> |
||||||
|
<v-toolbar-side-icon @click="mainDrawer = !mainDrawer"></v-toolbar-side-icon> |
||||||
|
<v-toolbar-title>{{name}}</v-toolbar-title> |
||||||
|
</v-toolbar> |
||||||
|
<v-content style="height:0px;background-color:#ddd"> |
||||||
|
<ThreeStage |
||||||
|
:components-info="componentsInfo" |
||||||
|
:camera-controll="cameraControll" |
||||||
|
ref="threeStage" |
||||||
|
/> |
||||||
|
<v-speed-dial |
||||||
|
v-model="fab" |
||||||
|
bottom |
||||||
|
right |
||||||
|
direction="top" |
||||||
|
transition="slide-y-reverse-transition" |
||||||
|
> |
||||||
|
<template v-slot:activator> |
||||||
|
<v-btn v-model="fab" color="red" dark fab> |
||||||
|
<v-icon>add</v-icon> |
||||||
|
<v-icon>close</v-icon> |
||||||
|
</v-btn> |
||||||
|
</template> |
||||||
|
<v-btn fab dark small color="blue" @click="pulishDialog=true"> |
||||||
|
<v-icon>edit</v-icon> |
||||||
|
</v-btn> |
||||||
|
<v-btn fab dark small color="green" @click="getComment();commentDialog=true"> |
||||||
|
<v-icon>comment</v-icon> |
||||||
|
</v-btn> |
||||||
|
</v-speed-dial> |
||||||
|
</v-content> |
||||||
|
<!-- 文件加载进度模态框 开始 --> |
||||||
|
<v-dialog v-model="downloadingDialog" persistent width="300"> |
||||||
|
<v-card color="red" dark> |
||||||
|
<v-card-text> |
||||||
|
文件加载中 |
||||||
|
<v-progress-linear indeterminate color="white" class="mb-0"></v-progress-linear> |
||||||
|
</v-card-text> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 文件加载进度模态框 结束--> |
||||||
|
<!-- 密码 开始--> |
||||||
|
<v-dialog v-model="passwordDialog" persistent max-width="290"> |
||||||
|
<v-card> |
||||||
|
<v-card-title class="headline">该项目需要密码访问</v-card-title> |
||||||
|
<v-card-text> |
||||||
|
<v-text-field label="密码" outline v-model="password" type="password"></v-text-field> |
||||||
|
</v-card-text> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn color="green darken-1" flat @click="customer">确定</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 密码 结束--> |
||||||
|
<!-- 发表评论 开始 --> |
||||||
|
<v-dialog v-model="pulishDialog" max-width="500px"> |
||||||
|
<v-card> |
||||||
|
<v-card-title>发表评论</v-card-title> |
||||||
|
<v-divider/> |
||||||
|
<v-card-text> |
||||||
|
<v-text-field single-line outline v-model="text"></v-text-field> |
||||||
|
</v-card-text> |
||||||
|
<v-divider/> |
||||||
|
<v-card-actions> |
||||||
|
<v-spacer></v-spacer> |
||||||
|
<v-btn color="green darken-1" flat @click="pulish">发表</v-btn> |
||||||
|
</v-card-actions> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 发表评论 结束 --> |
||||||
|
<!-- 评论区 开始 --> |
||||||
|
<v-dialog v-model="commentDialog" scrollable max-width="800px"> |
||||||
|
<v-card> |
||||||
|
<v-card-title class="font-weight-bold headline">评论区</v-card-title> |
||||||
|
<v-divider></v-divider> |
||||||
|
<v-card-text style="height: 300px;"> |
||||||
|
<v-list two-line> |
||||||
|
<div v-for="item in commentList" :key="item.time"> |
||||||
|
<v-list-tile> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title>{{ item.text }}</v-list-tile-title> |
||||||
|
<v-list-tile-sub-title |
||||||
|
class="text--primary text-xs-right" |
||||||
|
>{{ item.time|timeFilter }}</v-list-tile-sub-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-divider/> |
||||||
|
</div> |
||||||
|
</v-list> |
||||||
|
</v-card-text> |
||||||
|
</v-card> |
||||||
|
</v-dialog> |
||||||
|
<!-- 评论区 结束 --> |
||||||
|
<v-navigation-drawer v-model="mainDrawer" absolute fixed clipped app> |
||||||
|
<v-tabs v-model="tab" color="red" dark align-with-title show-arrows> |
||||||
|
<v-tabs-slider color="yellow"></v-tabs-slider> |
||||||
|
<v-tab v-for="(item,index) in componentsInfo" :key="index" ripple>{{item.componentName}}</v-tab> |
||||||
|
</v-tabs> |
||||||
|
<v-tabs-items v-model="tab" style="position:absolute;buttom:0px;width:100%"> |
||||||
|
<v-tab-item v-for="(item,index) in componentsInfo" :key="index"> |
||||||
|
<v-card flat> |
||||||
|
<v-card-text> |
||||||
|
<v-list-tile |
||||||
|
color="amber lighten-1" |
||||||
|
v-for="(subItem,subIndex) in item.models" |
||||||
|
:key="subItem.fid" |
||||||
|
@click="modelChange(index,subIndex)" |
||||||
|
> |
||||||
|
<v-list-tile-content> |
||||||
|
<v-list-tile-title> |
||||||
|
{{ subItem.name }} |
||||||
|
<v-icon small v-if="subIndex==item.modelSelected">arrow_left</v-icon> |
||||||
|
</v-list-tile-title> |
||||||
|
</v-list-tile-content> |
||||||
|
</v-list-tile> |
||||||
|
<v-divider/> |
||||||
|
<v-container grid-list-sm fluid v-if="item.textures.length>0"> |
||||||
|
<v-layout row wrap> |
||||||
|
<v-flex v-for="(subItem,subIndex) in item.textures" :key="subItem.fid" xs2 d-flex> |
||||||
|
<v-card flat tile class="d-flex" @click="textureChange(index,subIndex)"> |
||||||
|
<v-img :src="subItem.path+'?size=60'" aspect-ratio="1" class="grey lighten-2"> |
||||||
|
<template v-slot:placeholder> |
||||||
|
<v-layout fill-height align-center justify-center ma-0> |
||||||
|
<v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular> |
||||||
|
</v-layout> |
||||||
|
</template> |
||||||
|
</v-img> |
||||||
|
</v-card> |
||||||
|
</v-flex> |
||||||
|
</v-layout> |
||||||
|
</v-container> |
||||||
|
</v-card-text> |
||||||
|
</v-card> |
||||||
|
</v-tab-item> |
||||||
|
</v-tabs-items> |
||||||
|
</v-navigation-drawer> |
||||||
|
</v-app> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import "../plugins/OBJLoader"; |
||||||
|
import "../plugins/FBXLoader"; |
||||||
|
import { |
||||||
|
LoadingManager, |
||||||
|
TextureLoader, |
||||||
|
OBJLoader, |
||||||
|
FBXLoader, |
||||||
|
DoubleSide |
||||||
|
} from "three"; |
||||||
|
import ThreeStage from "../components/ThreeStage"; |
||||||
|
export default { |
||||||
|
components: { |
||||||
|
ThreeStage |
||||||
|
}, |
||||||
|
props: ["sid"], |
||||||
|
data() { |
||||||
|
return { |
||||||
|
commentList: null, |
||||||
|
text: "", |
||||||
|
mainDrawer: false, |
||||||
|
tab: null, |
||||||
|
fab: false, |
||||||
|
pulishDialog: null, |
||||||
|
commentDialog: null, |
||||||
|
downloadingDialog: null, |
||||||
|
passwordDialog: null, |
||||||
|
password: "", |
||||||
|
name: "", |
||||||
|
cameraControll: { |
||||||
|
height: 10, |
||||||
|
distance: 40, |
||||||
|
heightMax: 200, |
||||||
|
distanceMax: 200 |
||||||
|
}, |
||||||
|
componentsInfo: [] |
||||||
|
}; |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getComment() { |
||||||
|
this.$http.post("/show/getComment", { sid: this.sid }, {}).then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.commentList = data.body.data; |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
}, |
||||||
|
pulish() { |
||||||
|
this.$http |
||||||
|
.post("/show/comment", { sid: this.sid, text: this.text }, {}) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.pulishDialog = false; |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
}, |
||||||
|
getSchemeInfo() { |
||||||
|
this.$http.get("/scheme/" + this.sid, {}, {}).then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.name = data.body.data.name; |
||||||
|
let componentsInfo = JSON.parse(data.body.data.data); |
||||||
|
let cameraControll = JSON.parse(data.body.data.camera); |
||||||
|
if (componentsInfo) this.componentsInfo = componentsInfo; |
||||||
|
if (cameraControll) this.cameraControll = cameraControll; |
||||||
|
let manager = new LoadingManager(() => { |
||||||
|
this.downloadingDialog = false; |
||||||
|
}); |
||||||
|
this.componentsInfo.map((item, index) => { |
||||||
|
let modelIndex = item.modelSelected; |
||||||
|
let textureIndex = item.textureSelected; |
||||||
|
if (item.models[modelIndex] != null) { |
||||||
|
this.downloadingDialog = true; |
||||||
|
this.modelChange(index, modelIndex, manager); |
||||||
|
} |
||||||
|
if (item.textures[textureIndex] != null) { |
||||||
|
this.downloadingDialog = true; |
||||||
|
this.textureChange(index, textureIndex, manager); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else if (data.body.code == 2) { |
||||||
|
this.$router.push("/"); |
||||||
|
} else { |
||||||
|
this.$router.push("/home"); |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
}, |
||||||
|
modelChange(componentIndex, modelIndex, manager) { |
||||||
|
if (manager == null) { |
||||||
|
this.downloadingDialog = true; |
||||||
|
manager = new LoadingManager(() => { |
||||||
|
this.downloadingDialog = false; |
||||||
|
}); |
||||||
|
} |
||||||
|
let model = this.componentsInfo[componentIndex].models[modelIndex]; |
||||||
|
if (model.obj == null) { |
||||||
|
//obj |
||||||
|
if ( |
||||||
|
model.path |
||||||
|
.split(".") |
||||||
|
.pop() |
||||||
|
.toLowerCase() === "obj" |
||||||
|
) { |
||||||
|
new OBJLoader(manager).load( |
||||||
|
model.path, |
||||||
|
//success回调 |
||||||
|
obj => { |
||||||
|
obj.traverse(child => { |
||||||
|
if (child.isMesh) { |
||||||
|
child.material.side = DoubleSide; |
||||||
|
} |
||||||
|
}); |
||||||
|
model.obj = obj; |
||||||
|
this.componentsInfo[componentIndex].modelSelected = modelIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
} |
||||||
|
); |
||||||
|
//fbx |
||||||
|
} else if ( |
||||||
|
model.path |
||||||
|
.split(".") |
||||||
|
.pop() |
||||||
|
.toLowerCase() === "fbx" |
||||||
|
) { |
||||||
|
new FBXLoader(manager).load( |
||||||
|
model.path, |
||||||
|
obj => { |
||||||
|
obj.traverse(child => { |
||||||
|
if (child.isMesh) { |
||||||
|
child.material.side = DoubleSide; |
||||||
|
} |
||||||
|
}); |
||||||
|
model.obj = obj; |
||||||
|
this.componentsInfo[componentIndex].modelSelected = modelIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
}, |
||||||
|
xhr => { |
||||||
|
if (xhr.lengthComputable) { |
||||||
|
// console.info((xhr.loaded / xhr.total) * 100); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
} else { |
||||||
|
this.componentsInfo[componentIndex].modelSelected = modelIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
this.downloadingDialog = false; |
||||||
|
} |
||||||
|
}, |
||||||
|
textureChange(componentIndex, textureIndex, manager) { |
||||||
|
if (manager == null) { |
||||||
|
this.downloadingDialog = true; |
||||||
|
manager = new LoadingManager(() => { |
||||||
|
this.downloadingDialog = false; |
||||||
|
}); |
||||||
|
} |
||||||
|
let texture = this.componentsInfo[componentIndex].textures[textureIndex]; |
||||||
|
if (texture.obj == null) { |
||||||
|
new TextureLoader(manager).load(texture.path, obj => { |
||||||
|
texture.obj = obj; |
||||||
|
this.componentsInfo[componentIndex].textureSelected = textureIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.componentsInfo[componentIndex].textureSelected = textureIndex; |
||||||
|
this.$refs.threeStage.updateScene(); |
||||||
|
this.downloadingDialog = false; |
||||||
|
} |
||||||
|
}, |
||||||
|
customer() { |
||||||
|
this.$http |
||||||
|
.post( |
||||||
|
"/show/customer", |
||||||
|
{ |
||||||
|
sid: this.sid, |
||||||
|
password: this.password |
||||||
|
}, |
||||||
|
{} |
||||||
|
) |
||||||
|
.then( |
||||||
|
data => { |
||||||
|
console.info(data); |
||||||
|
if (data.body.code == 0) { |
||||||
|
this.passwordDialog = false; |
||||||
|
this.password = ""; |
||||||
|
this.getSchemeInfo(); |
||||||
|
} else { |
||||||
|
this.password = ""; |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
pulishDialog() { |
||||||
|
this.text = ""; |
||||||
|
} |
||||||
|
}, |
||||||
|
filters: { |
||||||
|
timeFilter: function(value) { |
||||||
|
var date = new Date(); |
||||||
|
date.setTime(value); |
||||||
|
var month = |
||||||
|
date.getMonth().toString().length > 1 |
||||||
|
? date.getMonth() |
||||||
|
: "0" + date.getMonth(); |
||||||
|
var day = |
||||||
|
date.getDate().toString().length > 1 |
||||||
|
? date.getDate() |
||||||
|
: "0" + date.getDate(); |
||||||
|
var hour = |
||||||
|
date.getHours().toString().length > 1 |
||||||
|
? date.getHours() |
||||||
|
: "0" + date.getHours(); |
||||||
|
var min = |
||||||
|
date.getMinutes().toString().length > 1 |
||||||
|
? date.getMinutes() |
||||||
|
: "0" + date.getMinutes(); |
||||||
|
return ( |
||||||
|
date.getFullYear() + "-" + month + "-" + day + " " + hour + ":" + min |
||||||
|
); |
||||||
|
} |
||||||
|
}, |
||||||
|
created() { |
||||||
|
this.$http.get("/show/" + this.sid, {}, {}).then( |
||||||
|
data => { |
||||||
|
if (data.body.code == 0) { |
||||||
|
console.info(data); |
||||||
|
let share = data.body.data.share; |
||||||
|
if (share == 1) { |
||||||
|
this.getSchemeInfo(); |
||||||
|
} else if (share == 2) { |
||||||
|
this.passwordDialog = true; |
||||||
|
}else{ |
||||||
|
this.$router.push("/refuse") |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
error => { |
||||||
|
console.info(error); |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style> |
||||||
|
.v-speed-dial { |
||||||
|
position: absolute; |
||||||
|
} |
||||||
|
|
||||||
|
.v-btn--floating { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,10 @@ |
|||||||
|
module.exports = { |
||||||
|
devServer: { |
||||||
|
host: "localhost", |
||||||
|
port: 8080, // 端口号
|
||||||
|
https: false, // https:{type:Boolean}
|
||||||
|
open: true, //配置自动启动浏览器
|
||||||
|
proxy: 'http://localhost' |
||||||
|
}, |
||||||
|
lintOnSave: false |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="CompilerConfiguration"> |
||||||
|
<annotationProcessing> |
||||||
|
<profile name="Maven default annotation processors profile" enabled="true"> |
||||||
|
<sourceOutputDir name="target/generated-sources/annotations" /> |
||||||
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> |
||||||
|
<outputRelativeToContentRoot value="true" /> |
||||||
|
<module name="v3dmodel" /> |
||||||
|
</profile> |
||||||
|
</annotationProcessing> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,7 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="Encoding" native2AsciiForPropertiesFiles="true" addBOMForNewFiles="with NO BOM"> |
||||||
|
<file url="file://$PROJECT_DIR$" charset="UTF-8" /> |
||||||
|
<file url="PROJECT" charset="UTF-8" /> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,46 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" /> |
||||||
|
<component name="FrameworkDetectionExcludesConfiguration"> |
||||||
|
<file type="web" url="file://$PROJECT_DIR$" /> |
||||||
|
</component> |
||||||
|
<component name="MavenProjectsManager"> |
||||||
|
<option name="originalFiles"> |
||||||
|
<list> |
||||||
|
<option value="$PROJECT_DIR$/pom.xml" /> |
||||||
|
</list> |
||||||
|
</option> |
||||||
|
</component> |
||||||
|
<component name="ProjectInspectionProfilesVisibleTreeState"> |
||||||
|
<entry key="Project Default"> |
||||||
|
<profile-state> |
||||||
|
<expanded-state> |
||||||
|
<State /> |
||||||
|
<State> |
||||||
|
<id>Java</id> |
||||||
|
</State> |
||||||
|
<State> |
||||||
|
<id>Probable bugsJava</id> |
||||||
|
</State> |
||||||
|
<State> |
||||||
|
<id>RELAX NG</id> |
||||||
|
</State> |
||||||
|
<State> |
||||||
|
<id>XPath</id> |
||||||
|
</State> |
||||||
|
<State> |
||||||
|
<id>XSLT</id> |
||||||
|
</State> |
||||||
|
</expanded-state> |
||||||
|
<selected-state> |
||||||
|
<State> |
||||||
|
<id>CSS</id> |
||||||
|
</State> |
||||||
|
</selected-state> |
||||||
|
</profile-state> |
||||||
|
</entry> |
||||||
|
</component> |
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK"> |
||||||
|
<output url="file://$PROJECT_DIR$/out" /> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,124 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="Palette2"> |
||||||
|
<group name="Swing"> |
||||||
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> |
||||||
|
</item> |
||||||
|
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true"> |
||||||
|
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> |
||||||
|
<initial-values> |
||||||
|
<property name="text" value="Button" /> |
||||||
|
</initial-values> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> |
||||||
|
<initial-values> |
||||||
|
<property name="text" value="RadioButton" /> |
||||||
|
</initial-values> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> |
||||||
|
<initial-values> |
||||||
|
<property name="text" value="CheckBox" /> |
||||||
|
</initial-values> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> |
||||||
|
<initial-values> |
||||||
|
<property name="text" value="Label" /> |
||||||
|
</initial-values> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> |
||||||
|
<preferred-size width="150" height="-1" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> |
||||||
|
<preferred-size width="150" height="-1" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> |
||||||
|
<preferred-size width="150" height="-1" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||||
|
<preferred-size width="150" height="50" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||||
|
<preferred-size width="150" height="50" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||||
|
<preferred-size width="150" height="50" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||||
|
<preferred-size width="150" height="50" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> |
||||||
|
<preferred-size width="150" height="50" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||||
|
<preferred-size width="150" height="50" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> |
||||||
|
<preferred-size width="200" height="200" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> |
||||||
|
<preferred-size width="200" height="200" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> |
||||||
|
<preferred-size width="-1" height="20" /> |
||||||
|
</default-constraints> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> |
||||||
|
</item> |
||||||
|
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||||
|
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> |
||||||
|
</item> |
||||||
|
</group> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="VcsDirectoryMappings"> |
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" /> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,219 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
|
||||||
|
<groupId>com.tonkia</groupId> |
||||||
|
<artifactId>v3dmodel</artifactId> |
||||||
|
<version>1.0-SNAPSHOT</version> |
||||||
|
<packaging>war</packaging> |
||||||
|
|
||||||
|
<name>v3dmodel Maven Webapp</name> |
||||||
|
|
||||||
|
<properties> |
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||||
|
<maven.compiler.source>1.7</maven.compiler.source> |
||||||
|
<maven.compiler.target>1.7</maven.compiler.target> |
||||||
|
<!--<spring-version>4.3.20.RELEASE</spring-version>--> |
||||||
|
<spring-version>5.1.3.RELEASE</spring-version> |
||||||
|
</properties> |
||||||
|
|
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>junit</groupId> |
||||||
|
<artifactId>junit</artifactId> |
||||||
|
<version>4.11</version> |
||||||
|
<scope>test</scope> |
||||||
|
</dependency> |
||||||
|
<!--servlet-api--> |
||||||
|
<dependency> |
||||||
|
<groupId>javax.servlet</groupId> |
||||||
|
<artifactId>javax.servlet-api</artifactId> |
||||||
|
<version>4.0.1</version> |
||||||
|
<scope>provided</scope> |
||||||
|
</dependency> |
||||||
|
<!--jsp-api --> |
||||||
|
<dependency> |
||||||
|
<groupId>javax.servlet</groupId> |
||||||
|
<artifactId>jsp-api</artifactId> |
||||||
|
<version>2.0</version> |
||||||
|
<scope>provided</scope> |
||||||
|
</dependency> |
||||||
|
<!--jstl--> |
||||||
|
<dependency> |
||||||
|
<groupId>jstl</groupId> |
||||||
|
<artifactId>jstl</artifactId> |
||||||
|
<version>1.2</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>taglibs</groupId> |
||||||
|
<artifactId>standard</artifactId> |
||||||
|
<version>1.1.2</version> |
||||||
|
</dependency> |
||||||
|
<!--spring framework--> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework</groupId> |
||||||
|
<artifactId>spring-webmvc</artifactId> |
||||||
|
<version>${spring-version}</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework</groupId> |
||||||
|
<artifactId>spring-jdbc</artifactId> |
||||||
|
<version>${spring-version}</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.aspectj</groupId> |
||||||
|
<artifactId>aspectjweaver</artifactId> |
||||||
|
<version>1.9.2</version> |
||||||
|
</dependency> |
||||||
|
<!--mybatis--> |
||||||
|
<dependency> |
||||||
|
<groupId>org.mybatis</groupId> |
||||||
|
<artifactId>mybatis</artifactId> |
||||||
|
<version>3.4.6</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.mybatis</groupId> |
||||||
|
<artifactId>mybatis-spring</artifactId> |
||||||
|
<version>1.3.2</version> |
||||||
|
</dependency> |
||||||
|
<!--mysql--> |
||||||
|
<dependency> |
||||||
|
<groupId>mysql</groupId> |
||||||
|
<artifactId>mysql-connector-java</artifactId> |
||||||
|
<version>6.0.6</version> |
||||||
|
</dependency> |
||||||
|
<!--druid--> |
||||||
|
<dependency> |
||||||
|
<groupId>com.alibaba</groupId> |
||||||
|
<artifactId>druid</artifactId> |
||||||
|
<version>1.1.10</version> |
||||||
|
</dependency> |
||||||
|
<!--log4j--> |
||||||
|
<dependency> |
||||||
|
<groupId>log4j</groupId> |
||||||
|
<artifactId>log4j</artifactId> |
||||||
|
<version>1.2.17</version> |
||||||
|
</dependency> |
||||||
|
<!--jsckson--> |
||||||
|
<dependency> |
||||||
|
<groupId>com.fasterxml.jackson.core</groupId> |
||||||
|
<artifactId>jackson-databind</artifactId> |
||||||
|
<version>2.9.8</version> |
||||||
|
</dependency> |
||||||
|
<!--apache commons fileupload--> |
||||||
|
<dependency> |
||||||
|
<groupId>commons-fileupload</groupId> |
||||||
|
<artifactId>commons-fileupload</artifactId> |
||||||
|
<version>1.3.3</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.junit.jupiter</groupId> |
||||||
|
<artifactId>junit-jupiter-api</artifactId> |
||||||
|
<version>RELEASE</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<!--短信--> |
||||||
|
<dependency> |
||||||
|
<groupId>com.github.qcloudsms</groupId> |
||||||
|
<artifactId>qcloudsms</artifactId> |
||||||
|
<version>1.0.6</version> |
||||||
|
<scope>system</scope> |
||||||
|
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/qcloudsms-1.0.6.jar</systemPath> |
||||||
|
</dependency> |
||||||
|
<!--ueditor--> |
||||||
|
<dependency> |
||||||
|
<groupId>com.baidu</groupId> |
||||||
|
<artifactId>ueditor</artifactId> |
||||||
|
<version>1.1.2</version> |
||||||
|
<scope>system</scope> |
||||||
|
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/ueditor-1.1.2.jar</systemPath> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.json</groupId> |
||||||
|
<artifactId>json</artifactId> |
||||||
|
<version>1.1.2</version> |
||||||
|
<scope>system</scope> |
||||||
|
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/json.jar</systemPath> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.commons</groupId> |
||||||
|
<artifactId>codec</artifactId> |
||||||
|
<version>1.9</version> |
||||||
|
<scope>system</scope> |
||||||
|
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/commons-codec-1.9.jar</systemPath> |
||||||
|
</dependency> |
||||||
|
<!--ftpclient--> |
||||||
|
<dependency> |
||||||
|
<groupId>commons-net</groupId> |
||||||
|
<artifactId>commons-net</artifactId> |
||||||
|
<version>3.3</version> |
||||||
|
</dependency> |
||||||
|
<!--shiro--> |
||||||
|
<dependency> |
||||||
|
<groupId>org.apache.shiro</groupId> |
||||||
|
<artifactId>shiro-spring</artifactId> |
||||||
|
<version>1.4.0</version> |
||||||
|
</dependency> |
||||||
|
<!--图片压缩缩略图--> |
||||||
|
<dependency> |
||||||
|
<groupId>net.coobird</groupId> |
||||||
|
<artifactId>thumbnailator</artifactId> |
||||||
|
<version>0.4.8</version> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
|
||||||
|
<build> |
||||||
|
<finalName>v3dmodel</finalName> |
||||||
|
<pluginManagement> |
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<artifactId>maven-clean-plugin</artifactId> |
||||||
|
<version>3.1.0</version> |
||||||
|
</plugin> |
||||||
|
<plugin> |
||||||
|
<artifactId>maven-resources-plugin</artifactId> |
||||||
|
<version>3.0.2</version> |
||||||
|
</plugin> |
||||||
|
<plugin> |
||||||
|
<artifactId>maven-compiler-plugin</artifactId> |
||||||
|
<version>3.8.0</version> |
||||||
|
</plugin> |
||||||
|
<plugin> |
||||||
|
<artifactId>maven-surefire-plugin</artifactId> |
||||||
|
<version>2.22.1</version> |
||||||
|
</plugin> |
||||||
|
<plugin> |
||||||
|
<artifactId>maven-war-plugin</artifactId> |
||||||
|
<version>3.2.2</version> |
||||||
|
</plugin> |
||||||
|
<plugin> |
||||||
|
<artifactId>maven-install-plugin</artifactId> |
||||||
|
<version>2.5.2</version> |
||||||
|
</plugin> |
||||||
|
<plugin> |
||||||
|
<artifactId>maven-deploy-plugin</artifactId> |
||||||
|
<version>2.8.2</version> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</pluginManagement> |
||||||
|
|
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<groupId>org.apache.tomcat.maven</groupId> |
||||||
|
<artifactId>tomcat7-maven-plugin</artifactId> |
||||||
|
<version>2.2</version> |
||||||
|
<configuration> |
||||||
|
<uriEncoding>UTF-8</uriEncoding> |
||||||
|
<port>80</port> |
||||||
|
<path>/</path> |
||||||
|
<url>http://v3d.tonkia.xyz/manager/text</url> |
||||||
|
<update>true</update> |
||||||
|
<username>tonkia</username> |
||||||
|
<password>tonkia</password> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
</project> |
@ -0,0 +1,101 @@ |
|||||||
|
package com.tonkia.v3dmodel.controller; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.*; |
||||||
|
import com.tonkia.v3dmodel.service.FileService; |
||||||
|
import com.tonkia.v3dmodel.service.SchemeService; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping("file") |
||||||
|
public class FileController { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
FileService fileService; |
||||||
|
@Autowired |
||||||
|
SchemeService schemeService; |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传模型 |
||||||
|
* |
||||||
|
* @param request |
||||||
|
* @param files |
||||||
|
* @param sid |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@RequestMapping("uploadModel") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData uploadModel(HttpServletRequest request, MultipartFile[] files, String sid) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
if (schemeService.hasPermission(sid, userInfo)) { |
||||||
|
List<FileRely> fileInfoList = fileService.insertModelFile(userInfo, sid, files); |
||||||
|
Map data = new HashMap<>(); |
||||||
|
data.put("uploadReply", fileInfoList); |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "文件上传成功", data); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "该用户没有当前方案权限", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传贴图 |
||||||
|
* |
||||||
|
* @param request |
||||||
|
* @param files |
||||||
|
* @param sid |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@RequestMapping("uploadTexture") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData uploadTexture(HttpServletRequest request, MultipartFile[] files, String sid) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
if (schemeService.hasPermission(sid, userInfo)) { |
||||||
|
List<FileRely> fileInfoList = fileService.insertTextureFile(userInfo, sid, files); |
||||||
|
Map data = new HashMap<>(); |
||||||
|
data.put("uploadReply", fileInfoList); |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "文件上传成功", data); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "该用户没有当前方案权限", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 资源请求 |
||||||
|
* |
||||||
|
* @param request |
||||||
|
* @param response |
||||||
|
* @param type 资源类型 |
||||||
|
* @param sid 所属方案 |
||||||
|
* @param fileName 文件名 |
||||||
|
* @param size 图片压缩的大小 |
||||||
|
*/ |
||||||
|
//后缀名的匹配规则
|
||||||
|
@RequestMapping("download/{type}/{sid}/{fileName:.+}") |
||||||
|
public void download(HttpServletRequest request, HttpServletResponse response, @PathVariable("type") String type, @PathVariable("sid") String sid, @PathVariable("fileName") String fileName, Integer size) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
CustomerInfo customerInfo = (CustomerInfo) request.getSession().getAttribute("customerInfo"); |
||||||
|
fileService.download(userInfo, customerInfo, type, sid, fileName, response, size); |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping("avatar/{fileName:.+}") |
||||||
|
public void avatar(HttpServletRequest request, HttpServletResponse response, @PathVariable("fileName") String fileName) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
fileService.avatar(userInfo.getUid(), fileName, response); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
package com.tonkia.v3dmodel.controller; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.ResponseData; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.SchemeInfo; |
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
import com.tonkia.v3dmodel.service.SchemeService; |
||||||
|
import com.tonkia.v3dmodel.service.UserService; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping("home") |
||||||
|
public class HomeController { |
||||||
|
@Autowired |
||||||
|
UserService userService; |
||||||
|
@Autowired |
||||||
|
SchemeService schemeService; |
||||||
|
|
||||||
|
/** |
||||||
|
* 主页信息请求 |
||||||
|
* @param request |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@RequestMapping("getHomeInfo") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData getHomeInfo(HttpServletRequest request) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
UserInfo ui = userService.getHomeUserInfo(userInfo.getUid()); |
||||||
|
List<SchemeInfo> schemeList = schemeService.getHomeSchemeList(userInfo.getUid()); |
||||||
|
Map data = new HashMap<>(); |
||||||
|
data.put("userInfo", ui); |
||||||
|
data.put("schemeList", schemeList); |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "主页信息获取成功", data); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,148 @@ |
|||||||
|
package com.tonkia.v3dmodel.controller; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.CustomerInfo; |
||||||
|
import com.tonkia.v3dmodel.pojo.ResponseData; |
||||||
|
import com.tonkia.v3dmodel.pojo.SchemeInfo; |
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
import com.tonkia.v3dmodel.service.FileService; |
||||||
|
import com.tonkia.v3dmodel.service.SchemeService; |
||||||
|
import org.apache.http.util.TextUtils; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping("scheme") |
||||||
|
public class SchemeController { |
||||||
|
@Autowired |
||||||
|
SchemeService schemeService; |
||||||
|
@Autowired |
||||||
|
FileService fileService; |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建一个新的方案 |
||||||
|
* |
||||||
|
* @param request |
||||||
|
* @param name |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@RequestMapping("create") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData create(HttpServletRequest request, String name) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
//对于插入操作为了安全,不能把对象暴露给前端啊,是不是?自己再封装一层,只插入name字段
|
||||||
|
SchemeInfo schemeInfo = new SchemeInfo(); |
||||||
|
schemeInfo.setName(name); |
||||||
|
if (userInfo != null) { |
||||||
|
if (!TextUtils.isEmpty(schemeInfo.getName())) { |
||||||
|
String sid = schemeService.insertScheme(schemeInfo, userInfo); |
||||||
|
if (sid != null) { |
||||||
|
Map data = new HashMap<>(); |
||||||
|
data.put("sid", sid); |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "创建方案成功", data); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "新建方案失败", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "方案名称不能为空", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 保存方案 |
||||||
|
* |
||||||
|
* @param request |
||||||
|
* @param schemeInfo |
||||||
|
* @param file |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@RequestMapping("save") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData save(HttpServletRequest request, SchemeInfo schemeInfo, MultipartFile file) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
if (!TextUtils.isEmpty(schemeInfo.getName())) { |
||||||
|
String cover = fileService.insertCoverFile(schemeInfo.getSid(), file); |
||||||
|
if (cover != null) { |
||||||
|
schemeInfo.setCover(cover); |
||||||
|
schemeInfo.setUid(userInfo.getUid()); |
||||||
|
if (schemeService.updateScheme(schemeInfo)) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "保存方案成功", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "保存方案失败", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "缩略图上传失败", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "方案名称不能为空", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取方案 |
||||||
|
* |
||||||
|
* @param request |
||||||
|
* @param sid |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@RequestMapping("/{sid}") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData getSchemeInfo(HttpServletRequest request, @PathVariable("sid") String sid) { |
||||||
|
int share = schemeService.getShareBySid(sid); |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
CustomerInfo customerInfo = (CustomerInfo) request.getSession().getAttribute("customerInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
SchemeInfo schemeInfo = schemeService.getSchemeInfo(userInfo.getUid(), sid); |
||||||
|
if (schemeInfo != null) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "方案数据获取成功", schemeInfo); |
||||||
|
} |
||||||
|
} |
||||||
|
if (share == 1) { |
||||||
|
SchemeInfo schemeInfo = schemeService.getSchemeInfo(sid); |
||||||
|
if (schemeInfo != null) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "方案数据获取成功", schemeInfo); |
||||||
|
} |
||||||
|
} else if (share == 2 && customerInfo != null && customerInfo.getSid().equals(sid)) { |
||||||
|
SchemeInfo schemeInfo = schemeService.getSchemeInfo(sid); |
||||||
|
if (schemeInfo != null) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "方案数据获取成功", schemeInfo); |
||||||
|
} |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "方案数据获取失败", null); |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping("/share") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData share(HttpServletRequest request, SchemeInfo schemeInfo) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
schemeInfo.setUid(userInfo.getUid()); |
||||||
|
if (schemeService.updateShareInfo(schemeInfo)) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "更新分享数据成功", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "更新分享数据失败", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping("/delete") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData delete(HttpServletRequest request, String sid) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
if (schemeService.deleteScheme(userInfo.getUid(), sid)) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "删除方案成功", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "删除方案失败", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,97 @@ |
|||||||
|
package com.tonkia.v3dmodel.controller; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.*; |
||||||
|
import com.tonkia.v3dmodel.service.CommentService; |
||||||
|
import com.tonkia.v3dmodel.service.SchemeService; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping("show") |
||||||
|
public class ShowController { |
||||||
|
@Autowired |
||||||
|
SchemeService schemeService; |
||||||
|
@Autowired |
||||||
|
CommentService commentService; |
||||||
|
|
||||||
|
@RequestMapping("/{sid}") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData getShareType(@PathVariable("sid") String sid) { |
||||||
|
Integer code = schemeService.getShareBySid(sid); |
||||||
|
if (code != null) { |
||||||
|
Map data = new HashMap<>(); |
||||||
|
data.put("share", code); |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "获取方案分享类型成功", data); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "获取方案分享类型失败", null); |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping("customer") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData customer(HttpServletRequest request, String sid, String password) { |
||||||
|
if (schemeService.getCustomer(sid, password)) { |
||||||
|
CustomerInfo customerInfo = new CustomerInfo(); |
||||||
|
customerInfo.setSid(sid); |
||||||
|
request.getSession().setAttribute("customerInfo", customerInfo); |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "密码有效", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "验证无效", null); |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping("getComment") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData getComment(HttpServletRequest request, String sid) { |
||||||
|
int share = schemeService.getShareBySid(sid); |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
CustomerInfo customerInfo = (CustomerInfo) request.getSession().getAttribute("customerInfo"); |
||||||
|
if (userInfo != null && schemeService.hasPermission(sid, userInfo)) { |
||||||
|
List<CommentInfo> list = commentService.getAllComment(sid); |
||||||
|
if (list != null) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "方案评论获取成功", list); |
||||||
|
} |
||||||
|
} |
||||||
|
if (share == 1) { |
||||||
|
List<CommentInfo> list = commentService.getAllComment(sid); |
||||||
|
if (list != null) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "方案评论获取成功", list); |
||||||
|
} |
||||||
|
} else if (share == 2 && customerInfo != null && customerInfo.getSid().equals(sid)) { |
||||||
|
List<CommentInfo> list = commentService.getAllComment(sid); |
||||||
|
if (list != null) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "方案评论获取成功", list); |
||||||
|
} |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "方案评论获取失败", null); |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping("comment") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData comment(HttpServletRequest request, String sid,String text) { |
||||||
|
int share = schemeService.getShareBySid(sid); |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
CustomerInfo customerInfo = (CustomerInfo) request.getSession().getAttribute("customerInfo"); |
||||||
|
if (userInfo != null && schemeService.hasPermission(sid, userInfo)) { |
||||||
|
if (commentService.insertComment(sid,text)) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "方案评论成功", null); |
||||||
|
} |
||||||
|
} |
||||||
|
if (share == 1) { |
||||||
|
if (commentService.insertComment(sid,text)) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "方案评论成功", null); |
||||||
|
} |
||||||
|
} else if (share == 2 && customerInfo != null && customerInfo.getSid().equals(sid)) { |
||||||
|
if (commentService.insertComment(sid,text)) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "方案评论成功", null); |
||||||
|
} |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "方案评论失败", null); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,93 @@ |
|||||||
|
package com.tonkia.v3dmodel.controller; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.ResponseData; |
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
import com.tonkia.v3dmodel.service.FileService; |
||||||
|
import com.tonkia.v3dmodel.service.UserService; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.io.File; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping("user") |
||||||
|
public class UserController { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
UserService userService; |
||||||
|
@Autowired |
||||||
|
FileService fileService; |
||||||
|
|
||||||
|
//验证登录
|
||||||
|
@RequestMapping("hasLogin") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData hasLogin(HttpServletRequest request) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "登录成功", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
|
||||||
|
//登录请求
|
||||||
|
@RequestMapping("login") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData login(HttpServletRequest request, UserInfo userInfo) { |
||||||
|
UserInfo ui = userService.getUserInfo(userInfo); |
||||||
|
if (ui == null) { |
||||||
|
//用户不存在
|
||||||
|
return new ResponseData(ResponseData.FAILURE, "用户不存在", null); |
||||||
|
} |
||||||
|
if (!ui.getPassword().equals(userInfo.getPassword())) { |
||||||
|
//密码错误
|
||||||
|
return new ResponseData(ResponseData.FAILURE, "密码错误", null); |
||||||
|
} |
||||||
|
request.getSession().setAttribute("userInfo", ui); |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "登录成功", null); |
||||||
|
} |
||||||
|
|
||||||
|
//用户注销
|
||||||
|
@RequestMapping("logout") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData logout(HttpServletRequest request) { |
||||||
|
request.getSession().setAttribute("userInfo", null); |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "注销成功", null); |
||||||
|
} |
||||||
|
|
||||||
|
//修改头像
|
||||||
|
@RequestMapping("avatar") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData avatar(HttpServletRequest request, MultipartFile file) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
String path = fileService.uploadAvatar(userInfo.getUid(), file); |
||||||
|
if (userService.updateAvatar(userInfo.getUid(), path)) { |
||||||
|
Map data = new HashMap(); |
||||||
|
data.put("avatar", path); |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "头像修改成功", data); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "头像修改失败", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
|
||||||
|
//修改头像
|
||||||
|
@RequestMapping("changeInfo") |
||||||
|
@ResponseBody |
||||||
|
public ResponseData changeInfo(HttpServletRequest request, String userName, String password) { |
||||||
|
UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo"); |
||||||
|
if (userInfo != null) { |
||||||
|
if (userService.updateInfo(userInfo.getUid(),userName,password)) { |
||||||
|
return new ResponseData(ResponseData.SUCCEED, "用户信息修改成功", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE, "用户信息修改失败", null); |
||||||
|
} |
||||||
|
return new ResponseData(ResponseData.FAILURE_UNLOGIN, "用户未登录", null); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
package com.tonkia.v3dmodel.mapper; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.CommentInfo; |
||||||
|
import org.apache.ibatis.annotations.Insert; |
||||||
|
import org.apache.ibatis.annotations.Select; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public interface CommentMapper { |
||||||
|
@Select("select text,time from tb_comment where sid = #{sid} order by time desc") |
||||||
|
List<CommentInfo> getAllComment(String sid); |
||||||
|
|
||||||
|
@Insert("insert into tb_comment(text,sid) values (#{text},#{sid})") |
||||||
|
boolean insertComment(Map para); |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
package com.tonkia.v3dmodel.mapper; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.FileInfo; |
||||||
|
import org.apache.ibatis.annotations.Insert; |
||||||
|
|
||||||
|
public interface FileMapper { |
||||||
|
@Insert("insert into tb_file(fid,uid,sid,type,path,name) values(#{fid},#{uid},#{sid},#{type},#{path},#{name})") |
||||||
|
boolean insertFile(FileInfo fi); |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
package com.tonkia.v3dmodel.mapper; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.SchemeInfo; |
||||||
|
import org.apache.ibatis.annotations.Delete; |
||||||
|
import org.apache.ibatis.annotations.Insert; |
||||||
|
import org.apache.ibatis.annotations.Select; |
||||||
|
import org.apache.ibatis.annotations.Update; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public interface SchemeMapper { |
||||||
|
@Insert("insert into tb_scheme(sid,uid,name,createTime) values(#{sid},#{uid},#{name},#{createTime})") |
||||||
|
boolean insertScheme(SchemeInfo schemeInfo); |
||||||
|
|
||||||
|
@Select("select sid,name,cover,share,password from tb_scheme where uid = #{0} and state = 0 order by createTime desc") |
||||||
|
List<SchemeInfo> getHomeSchemeList(Integer uid); |
||||||
|
|
||||||
|
@Select("select count(*) from tb_scheme where uid = #{uid} and sid = #{sid}") |
||||||
|
int hasPermission(Map para); |
||||||
|
|
||||||
|
@Update("update tb_scheme set name=#{name},cover=#{cover},data=#{data},camera=#{camera} where uid = #{uid} and sid = #{sid}") |
||||||
|
boolean updateScheme(SchemeInfo schemeInfo); |
||||||
|
|
||||||
|
@Select("select name,data,camera,share,password from tb_scheme where uid = #{uid} and sid = #{sid}") |
||||||
|
SchemeInfo getSchemeInfo(Map para); |
||||||
|
|
||||||
|
@Update("update tb_scheme set share = #{share} ,password = #{password} where uid = #{uid} and sid = #{sid}") |
||||||
|
boolean updateShareInfo(SchemeInfo schemeInfo); |
||||||
|
|
||||||
|
@Select("select share from tb_scheme where sid = #{sid}") |
||||||
|
Integer getShareBySid(String sid); |
||||||
|
|
||||||
|
@Select("select name,data,camera from tb_scheme where sid = #{sid}") |
||||||
|
SchemeInfo getSchemeInfoBySid(String sid); |
||||||
|
|
||||||
|
@Select("select count(*) from tb_scheme where sid = #{sid} and password = #{password} and share = 2") |
||||||
|
int getCustomer(Map para); |
||||||
|
|
||||||
|
@Delete("delete from tb_scheme where sid = #{sid} and uid = #{uid}") |
||||||
|
boolean deleteScheme(Map para); |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.tonkia.v3dmodel.mapper; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
import org.apache.ibatis.annotations.Select; |
||||||
|
import org.apache.ibatis.annotations.Update; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public interface UserMapper { |
||||||
|
@Select("select * from tb_user where phoneNumber = #{phoneNumber}") |
||||||
|
UserInfo getUserInfo(UserInfo userInfo); |
||||||
|
|
||||||
|
@Select("select userName, avatar from tb_user where uid = #{uid}") |
||||||
|
UserInfo getHomeUserInfo(Integer uid); |
||||||
|
|
||||||
|
@Update("update tb_user set avatar =#{avatar} where uid = #{uid} ") |
||||||
|
boolean updateAvatar(Map para); |
||||||
|
|
||||||
|
@Update("update tb_user set userName =#{userName} where uid = #{uid} ") |
||||||
|
boolean updateUserName(Map para); |
||||||
|
|
||||||
|
@Update("update tb_user set password =#{password} where uid = #{uid} ") |
||||||
|
boolean updatePassword(Map para); |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.tonkia.v3dmodel.pojo; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
public class CommentInfo { |
||||||
|
private String text; |
||||||
|
private Date time; |
||||||
|
|
||||||
|
public String getText() { |
||||||
|
return text; |
||||||
|
} |
||||||
|
|
||||||
|
public void setText(String text) { |
||||||
|
this.text = text; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getTime() { |
||||||
|
return time; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTime(Date time) { |
||||||
|
this.time = time; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package com.tonkia.v3dmodel.pojo; |
||||||
|
|
||||||
|
public class CustomerInfo { |
||||||
|
private String sid; |
||||||
|
|
||||||
|
public String getSid() { |
||||||
|
return sid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSid(String sid) { |
||||||
|
this.sid = sid; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
package com.tonkia.v3dmodel.pojo; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
public class FileInfo { |
||||||
|
private String fid; |
||||||
|
private String sid; |
||||||
|
private Integer uid; |
||||||
|
private String name; |
||||||
|
private String path; |
||||||
|
private Date uploadTime; |
||||||
|
private Integer state; |
||||||
|
private String type; |
||||||
|
|
||||||
|
public String getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
public void setType(String type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
|
||||||
|
public String getFid() { |
||||||
|
return fid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setFid(String fid) { |
||||||
|
this.fid = fid; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSid() { |
||||||
|
return sid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSid(String sid) { |
||||||
|
this.sid = sid; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getUid() { |
||||||
|
return uid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUid(Integer uid) { |
||||||
|
this.uid = uid; |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public void setName(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPath() { |
||||||
|
return path; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPath(String path) { |
||||||
|
this.path = path; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getUploadTime() { |
||||||
|
return uploadTime; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUploadTime(Date uploadTime) { |
||||||
|
this.uploadTime = uploadTime; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getState() { |
||||||
|
return state; |
||||||
|
} |
||||||
|
|
||||||
|
public void setState(Integer state) { |
||||||
|
this.state = state; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
package com.tonkia.v3dmodel.pojo; |
||||||
|
|
||||||
|
public class FileRely { |
||||||
|
private String fid; |
||||||
|
private String name; |
||||||
|
private String path; |
||||||
|
|
||||||
|
public String getFid() { |
||||||
|
return fid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setFid(String fid) { |
||||||
|
this.fid = fid; |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public void setName(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPath() { |
||||||
|
return path; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPath(String path) { |
||||||
|
this.path = path; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
package com.tonkia.v3dmodel.pojo; |
||||||
|
|
||||||
|
public class ResponseData { |
||||||
|
//code编码
|
||||||
|
public static int SUCCEED=0; |
||||||
|
public static int FAILURE=1; |
||||||
|
public static int FAILURE_UNLOGIN=2; |
||||||
|
|
||||||
|
//返回格式
|
||||||
|
private int code; |
||||||
|
private String msg; |
||||||
|
private Object data; |
||||||
|
|
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCode(int code) { |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMsg() { |
||||||
|
return msg; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMsg(String msg) { |
||||||
|
this.msg = msg; |
||||||
|
} |
||||||
|
|
||||||
|
public Object getData() { |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
public void setData(Object data) { |
||||||
|
this.data = data; |
||||||
|
} |
||||||
|
|
||||||
|
public ResponseData(int code, String msg, Object data) { |
||||||
|
this.code = code; |
||||||
|
this.msg = msg; |
||||||
|
this.data = data; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,105 @@ |
|||||||
|
package com.tonkia.v3dmodel.pojo; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
public class SchemeInfo { |
||||||
|
private String sid; |
||||||
|
private Integer uid; |
||||||
|
private String name; |
||||||
|
private String cover; |
||||||
|
private Integer state; |
||||||
|
private Date createTime; |
||||||
|
private Object data; |
||||||
|
private Object camera; |
||||||
|
private Integer share; |
||||||
|
private String password; |
||||||
|
private String shareLink; |
||||||
|
|
||||||
|
public String getSid() { |
||||||
|
return sid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSid(String sid) { |
||||||
|
this.sid = sid; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getUid() { |
||||||
|
return uid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUid(Integer uid) { |
||||||
|
this.uid = uid; |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public void setName(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCover() { |
||||||
|
return cover; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCover(String cover) { |
||||||
|
this.cover = cover; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getState() { |
||||||
|
return state; |
||||||
|
} |
||||||
|
|
||||||
|
public void setState(Integer state) { |
||||||
|
this.state = state; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getCreateTime() { |
||||||
|
return createTime; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCreateTime(Date createTime) { |
||||||
|
this.createTime = createTime; |
||||||
|
} |
||||||
|
|
||||||
|
public Object getData() { |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
public void setData(Object data) { |
||||||
|
this.data = data; |
||||||
|
} |
||||||
|
|
||||||
|
public Object getCamera() { |
||||||
|
return camera; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCamera(Object camera) { |
||||||
|
this.camera = camera; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getShare() { |
||||||
|
return share; |
||||||
|
} |
||||||
|
|
||||||
|
public void setShare(Integer share) { |
||||||
|
this.share = share; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPassword() { |
||||||
|
return password; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPassword(String password) { |
||||||
|
this.password = password; |
||||||
|
} |
||||||
|
|
||||||
|
public String getShareLink() { |
||||||
|
return shareLink; |
||||||
|
} |
||||||
|
|
||||||
|
public void setShareLink(String shareLink) { |
||||||
|
this.shareLink = shareLink; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
package com.tonkia.v3dmodel.pojo; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
public class UserInfo { |
||||||
|
private Integer uid; |
||||||
|
private String phoneNumber; |
||||||
|
private String userName; |
||||||
|
private String password; |
||||||
|
private Integer state; |
||||||
|
private Date regTime; |
||||||
|
private String avatar; |
||||||
|
|
||||||
|
public Integer getUid() { |
||||||
|
return uid; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUid(Integer uid) { |
||||||
|
this.uid = uid; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPhoneNumber() { |
||||||
|
return phoneNumber; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPhoneNumber(String phoneNumber) { |
||||||
|
this.phoneNumber = phoneNumber; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUserName() { |
||||||
|
return userName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUserName(String userName) { |
||||||
|
this.userName = userName; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPassword() { |
||||||
|
return password; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPassword(String password) { |
||||||
|
this.password = password; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getState() { |
||||||
|
return state; |
||||||
|
} |
||||||
|
|
||||||
|
public void setState(Integer state) { |
||||||
|
this.state = state; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getRegTime() { |
||||||
|
return regTime; |
||||||
|
} |
||||||
|
|
||||||
|
public void setRegTime(Date regTime) { |
||||||
|
this.regTime = regTime; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAvatar() { |
||||||
|
return avatar; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAvatar(String avatar) { |
||||||
|
this.avatar = avatar; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
package com.tonkia.v3dmodel.service; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.CommentInfo; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public interface CommentService { |
||||||
|
List<CommentInfo> getAllComment(String sid); |
||||||
|
|
||||||
|
boolean insertComment(String sid, String text); |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package com.tonkia.v3dmodel.service; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.CustomerInfo; |
||||||
|
import com.tonkia.v3dmodel.pojo.FileInfo; |
||||||
|
import com.tonkia.v3dmodel.pojo.FileRely; |
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.OutputStream; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public interface FileService { |
||||||
|
void download(UserInfo userInfo, CustomerInfo customerInfo, String type, String sid, String fileName, HttpServletResponse response, Integer size); |
||||||
|
|
||||||
|
List<FileRely> insertModelFile(UserInfo userInfo, String sid, MultipartFile[] files); |
||||||
|
|
||||||
|
List<FileRely> insertTextureFile(UserInfo userInfo, String sid, MultipartFile[] files); |
||||||
|
|
||||||
|
String insertCoverFile(String sid,MultipartFile file); |
||||||
|
|
||||||
|
String uploadAvatar(int uid ,MultipartFile file); |
||||||
|
|
||||||
|
void avatar(Integer uid, String fileName, HttpServletResponse response); |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package com.tonkia.v3dmodel.service; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.SchemeInfo; |
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public interface SchemeService { |
||||||
|
String insertScheme(SchemeInfo schemeInfo, UserInfo userInfo); |
||||||
|
|
||||||
|
List<SchemeInfo> getHomeSchemeList(Integer uid); |
||||||
|
|
||||||
|
boolean hasPermission(String sid, UserInfo userInfo); |
||||||
|
|
||||||
|
boolean updateScheme(SchemeInfo schemeInfo); |
||||||
|
|
||||||
|
SchemeInfo getSchemeInfo(Integer uid, String sid); |
||||||
|
|
||||||
|
boolean updateShareInfo(SchemeInfo schemeInfo); |
||||||
|
|
||||||
|
Integer getShareBySid(String sid); |
||||||
|
|
||||||
|
SchemeInfo getSchemeInfo(String sid); |
||||||
|
|
||||||
|
boolean getCustomer(String sid, String password); |
||||||
|
|
||||||
|
boolean deleteScheme(Integer uid, String sid); |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package com.tonkia.v3dmodel.service; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
|
||||||
|
public interface UserService { |
||||||
|
UserInfo getUserInfo(UserInfo userInfo); |
||||||
|
|
||||||
|
UserInfo getHomeUserInfo(Integer uid); |
||||||
|
|
||||||
|
boolean updateAvatar(Integer uid, String path); |
||||||
|
|
||||||
|
boolean updateInfo(Integer uid, String userName, String password); |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
package com.tonkia.v3dmodel.service.impl; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.mapper.CommentMapper; |
||||||
|
import com.tonkia.v3dmodel.pojo.CommentInfo; |
||||||
|
import com.tonkia.v3dmodel.service.CommentService; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import javax.xml.stream.events.Comment; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Service |
||||||
|
public class CommentServiceImpl implements CommentService { |
||||||
|
@Autowired |
||||||
|
CommentMapper commentMapper; |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<CommentInfo> getAllComment(String sid) { |
||||||
|
return commentMapper.getAllComment(sid); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean insertComment(String sid, String text) { |
||||||
|
Map para = new HashMap<>(); |
||||||
|
para.put("sid", sid); |
||||||
|
para.put("text", text); |
||||||
|
return commentMapper.insertComment(para); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,196 @@ |
|||||||
|
package com.tonkia.v3dmodel.service.impl; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.mapper.FileMapper; |
||||||
|
import com.tonkia.v3dmodel.mapper.SchemeMapper; |
||||||
|
import com.tonkia.v3dmodel.pojo.CustomerInfo; |
||||||
|
import com.tonkia.v3dmodel.pojo.FileInfo; |
||||||
|
import com.tonkia.v3dmodel.pojo.FileRely; |
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
import com.tonkia.v3dmodel.service.FileService; |
||||||
|
import com.tonkia.v3dmodel.utils.FtpUtil; |
||||||
|
import com.tonkia.v3dmodel.utils.ThumbUtil; |
||||||
|
import com.tonkia.v3dmodel.utils.UUIDUtil; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.annotation.Value; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.*; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Service |
||||||
|
public class FileServiceImpl implements FileService { |
||||||
|
@Autowired |
||||||
|
FileMapper fileMapper; |
||||||
|
@Autowired |
||||||
|
SchemeMapper schemeMapper; |
||||||
|
|
||||||
|
@Value("${ftpclient.host}") |
||||||
|
private String host; |
||||||
|
@Value("${ftpclient.port}") |
||||||
|
private int port; |
||||||
|
@Value("${ftpclient.username}") |
||||||
|
private String username; |
||||||
|
@Value("${ftpclient.password}") |
||||||
|
private String password; |
||||||
|
@Value("${ftpclient.basePath}") |
||||||
|
private String basePath; |
||||||
|
@Value("${ftpclient.filePath}") |
||||||
|
private String filePath; |
||||||
|
@Value("${ftpclient.downloadPathPrefix}") |
||||||
|
private String downloadPathPrefix; |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<FileRely> insertModelFile(UserInfo userInfo, String sid, MultipartFile[] files) { |
||||||
|
int uid = userInfo.getUid(); |
||||||
|
List<FileRely> list = new ArrayList<>(); |
||||||
|
for (MultipartFile file : files) { |
||||||
|
//判断是否是 .obj 或者 .fbx
|
||||||
|
String subfix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')); |
||||||
|
if (subfix.toLowerCase().equals(".obj") || subfix.toLowerCase().equals(".fbx")) { |
||||||
|
String fileName = UUIDUtil.generate() + subfix; |
||||||
|
boolean isSucceed = false; |
||||||
|
try { |
||||||
|
isSucceed = FtpUtil.uploadFile(host, port, username, password, basePath, filePath + "/models/" + sid, fileName, file.getInputStream()); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
if (isSucceed) { |
||||||
|
FileRely fr = new FileRely(); |
||||||
|
FileInfo fi = new FileInfo(); |
||||||
|
String name = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf('.')); |
||||||
|
String fid = UUIDUtil.generate(); |
||||||
|
String path = downloadPathPrefix + "/models/" + sid + "/" + fileName; |
||||||
|
fi.setFid(fid); |
||||||
|
fi.setUid(uid); |
||||||
|
fi.setSid(sid); |
||||||
|
fi.setName(name); |
||||||
|
fi.setPath(path); |
||||||
|
fi.setType(file.getContentType()); |
||||||
|
if (fileMapper.insertFile(fi)) { |
||||||
|
fr.setFid(fid); |
||||||
|
fr.setName(name); |
||||||
|
fr.setPath(path); |
||||||
|
list.add(fr); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<FileRely> insertTextureFile(UserInfo userInfo, String sid, MultipartFile[] files) { |
||||||
|
int uid = userInfo.getUid(); |
||||||
|
List<FileRely> list = new ArrayList<>(); |
||||||
|
for (MultipartFile file : files) { |
||||||
|
//判断是否是 .jpg 或者 .png
|
||||||
|
String subfix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')); |
||||||
|
if (subfix.toLowerCase().equals(".jpg") || subfix.toLowerCase().equals(".png")) { |
||||||
|
String fileName = UUIDUtil.generate() + subfix; |
||||||
|
boolean isSucceed = false; |
||||||
|
try { |
||||||
|
isSucceed = FtpUtil.uploadFile(host, port, username, password, basePath, filePath + "/textures/" + sid, fileName, file.getInputStream()); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
if (isSucceed) { |
||||||
|
FileRely fr = new FileRely(); |
||||||
|
FileInfo fi = new FileInfo(); |
||||||
|
String name = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf('.')); |
||||||
|
String fid = UUIDUtil.generate(); |
||||||
|
String path = downloadPathPrefix + "/textures/" + sid + "/" + fileName; |
||||||
|
fi.setFid(fid); |
||||||
|
fi.setUid(uid); |
||||||
|
fi.setSid(sid); |
||||||
|
fi.setName(name); |
||||||
|
fi.setPath(path); |
||||||
|
fi.setType(file.getContentType()); |
||||||
|
if (fileMapper.insertFile(fi)) { |
||||||
|
fr.setFid(fid); |
||||||
|
fr.setName(name); |
||||||
|
fr.setPath(path); |
||||||
|
list.add(fr); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String insertCoverFile(String sid, MultipartFile file) { |
||||||
|
|
||||||
|
String subfix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')); |
||||||
|
String fileName = UUIDUtil.generate() + subfix; |
||||||
|
boolean isSucceed = false; |
||||||
|
try { |
||||||
|
isSucceed = FtpUtil.uploadFile(host, port, username, password, basePath, filePath + "/cover/" + sid, fileName, file.getInputStream()); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
if (isSucceed) { |
||||||
|
String path = downloadPathPrefix + "/cover/" + sid + "/" + fileName; |
||||||
|
return path; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String uploadAvatar(int uid, MultipartFile file) { |
||||||
|
String fileName = UUIDUtil.generate(); |
||||||
|
boolean isSucceed = false; |
||||||
|
try { |
||||||
|
isSucceed = FtpUtil.uploadFile(host, port, username, password, basePath, filePath + "/avatar/" + uid, fileName, file.getInputStream()); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
if (isSucceed) { |
||||||
|
String path = "/file/avatar/" + fileName; |
||||||
|
return path; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void avatar(Integer uid, String fileName, HttpServletResponse response) { |
||||||
|
FtpUtil.downloadFileWithProgress(host, port, username, password, basePath + filePath + "/avatar/" + uid, fileName, response); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void download(UserInfo userInfo, CustomerInfo customerInfo, String type, String sid, String fileName, HttpServletResponse response, Integer size) { |
||||||
|
boolean hasRight = false; |
||||||
|
int share = schemeMapper.getShareBySid(sid); |
||||||
|
if (share == 1) { |
||||||
|
hasRight = true; |
||||||
|
} else if (userInfo != null) { |
||||||
|
Map para = new HashMap<>(); |
||||||
|
para.put("uid", userInfo.getUid()); |
||||||
|
para.put("sid", sid); |
||||||
|
hasRight = schemeMapper.hasPermission(para) > 0; |
||||||
|
} else if (share == 2 && customerInfo != null && customerInfo.getSid().equals(sid)) { |
||||||
|
hasRight = customerInfo.getSid().equals(sid); |
||||||
|
} |
||||||
|
if (hasRight) { |
||||||
|
try { |
||||||
|
if (size == null) |
||||||
|
FtpUtil.downloadFileWithProgress(host, port, username, password, basePath + filePath + "/" + type + "/" + sid, fileName, response); |
||||||
|
else { |
||||||
|
//如果指定了size返回压缩缩略图
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
||||||
|
FtpUtil.downloadFile(host, port, username, password, basePath + filePath + "/" + type + "/" + sid, fileName, baos); |
||||||
|
ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray()); |
||||||
|
ThumbUtil.thumb(swapStream, response.getOutputStream(), size); |
||||||
|
} |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,101 @@ |
|||||||
|
package com.tonkia.v3dmodel.service.impl; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.mapper.SchemeMapper; |
||||||
|
import com.tonkia.v3dmodel.pojo.SchemeInfo; |
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
import com.tonkia.v3dmodel.service.SchemeService; |
||||||
|
import com.tonkia.v3dmodel.utils.UUIDUtil; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.annotation.Value; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
|
||||||
|
@Service |
||||||
|
public class SchemeServiceImpl implements SchemeService { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
SchemeMapper schemeMapper; |
||||||
|
@Value("${shareLink.prefix}") |
||||||
|
String shareLinkPrefix; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String insertScheme(SchemeInfo schemeInfo, UserInfo userInfo) { |
||||||
|
String sid = UUIDUtil.generate(); |
||||||
|
schemeInfo.setSid(sid); |
||||||
|
schemeInfo.setCreateTime(new Date()); |
||||||
|
schemeInfo.setUid(userInfo.getUid()); |
||||||
|
return schemeMapper.insertScheme(schemeInfo) ? sid : null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<SchemeInfo> getHomeSchemeList(Integer uid) { |
||||||
|
List<SchemeInfo> list = schemeMapper.getHomeSchemeList(uid); |
||||||
|
for (SchemeInfo schemeInfo : list) { |
||||||
|
schemeInfo.setShareLink(shareLinkPrefix + schemeInfo.getSid()); |
||||||
|
} |
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean hasPermission(String sid, UserInfo userInfo) { |
||||||
|
Map para = new HashMap<>(); |
||||||
|
para.put("uid", userInfo.getUid()); |
||||||
|
para.put("sid", sid); |
||||||
|
return schemeMapper.hasPermission(para) > 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean updateScheme(SchemeInfo schemeInfo) { |
||||||
|
return schemeMapper.updateScheme(schemeInfo); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public SchemeInfo getSchemeInfo(Integer uid, String sid) { |
||||||
|
Map para = new HashMap<>(); |
||||||
|
para.put("uid", uid); |
||||||
|
para.put("sid", sid); |
||||||
|
SchemeInfo schemeInfo = schemeMapper.getSchemeInfo(para); |
||||||
|
if (schemeInfo != null) |
||||||
|
schemeInfo.setShareLink(shareLinkPrefix + sid); |
||||||
|
return schemeInfo; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean updateShareInfo(SchemeInfo schemeInfo) { |
||||||
|
return schemeMapper.updateShareInfo(schemeInfo); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Integer getShareBySid(String sid) { |
||||||
|
return schemeMapper.getShareBySid(sid); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public SchemeInfo getSchemeInfo(String sid) { |
||||||
|
return schemeMapper.getSchemeInfoBySid(sid); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean getCustomer(String sid, String password) { |
||||||
|
Map para = new HashMap<>(); |
||||||
|
para.put("password", password); |
||||||
|
para.put("sid", sid); |
||||||
|
return schemeMapper.getCustomer(para)>0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean deleteScheme(Integer uid, String sid) { |
||||||
|
Map para = new HashMap<>(); |
||||||
|
para.put("uid", uid); |
||||||
|
para.put("sid", sid); |
||||||
|
return schemeMapper.deleteScheme(para); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
package com.tonkia.v3dmodel.service.impl; |
||||||
|
|
||||||
|
import com.tonkia.v3dmodel.mapper.UserMapper; |
||||||
|
import com.tonkia.v3dmodel.pojo.UserInfo; |
||||||
|
import com.tonkia.v3dmodel.service.UserService; |
||||||
|
import org.apache.http.util.TextUtils; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Service |
||||||
|
public class UserServiceImpl implements UserService { |
||||||
|
@Autowired |
||||||
|
UserMapper userMapper; |
||||||
|
|
||||||
|
@Override |
||||||
|
public UserInfo getUserInfo(UserInfo userInfo) { |
||||||
|
return userMapper.getUserInfo(userInfo); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 获取主页的用户信息,关键信息需要保留 |
||||||
|
* |
||||||
|
* @param uid |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public UserInfo getHomeUserInfo(Integer uid) { |
||||||
|
return userMapper.getHomeUserInfo(uid); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean updateAvatar(Integer uid, String path) { |
||||||
|
Map para = new HashMap(); |
||||||
|
para.put("uid", uid); |
||||||
|
para.put("avatar", path); |
||||||
|
return userMapper.updateAvatar(para); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean updateInfo(Integer uid, String userName, String password) { |
||||||
|
boolean res = false; |
||||||
|
if (!TextUtils.isEmpty(userName)) { |
||||||
|
Map para = new HashMap(); |
||||||
|
para.put("uid", uid); |
||||||
|
para.put("userName", userName); |
||||||
|
res = res || userMapper.updateUserName(para); |
||||||
|
} |
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(password)) { |
||||||
|
Map para = new HashMap(); |
||||||
|
para.put("uid", uid); |
||||||
|
para.put("password", password); |
||||||
|
res = res || userMapper.updatePassword(para); |
||||||
|
} |
||||||
|
return res; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package com.tonkia.v3dmodel.utils; |
||||||
|
|
||||||
|
import java.io.FileInputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
public class Test { |
||||||
|
public static void main(String[] args) throws IOException { |
||||||
|
InputStream is = new FileInputStream("d:/web.png"); |
||||||
|
boolean res = FtpUtil.uploadFile("192.168.226.128", 21, "ftpuser", "123456", "/home/ftpuser", "/v3d", "target", is); |
||||||
|
System.out.println(res); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.tonkia.v3dmodel.utils; |
||||||
|
|
||||||
|
import net.coobird.thumbnailator.Thumbnails; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.io.OutputStream; |
||||||
|
|
||||||
|
public class ThumbUtil { |
||||||
|
public static void thumb(InputStream is, OutputStream os, int size) { |
||||||
|
try { |
||||||
|
Thumbnails.of(is).size(size, size).outputQuality(0.5).toOutputStream(os); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package com.tonkia.v3dmodel.utils; |
||||||
|
|
||||||
|
import java.util.UUID; |
||||||
|
|
||||||
|
public class UUIDUtil { |
||||||
|
public static String generate() { |
||||||
|
return UUID.randomUUID().toString().replaceAll("-", ""); |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
System.out.println(generate()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
#ftpclient.host=134.175.111.158 |
||||||
|
ftpclient.host=192.168.226.129 |
||||||
|
ftpclient.port=21 |
||||||
|
ftpclient.username=ftpuser |
||||||
|
#ftpclient.password=41509060104 |
||||||
|
ftpclient.password=123456 |
||||||
|
ftpclient.basePath=/home/ftpuser |
||||||
|
ftpclient.filePath=/v3d |
||||||
|
ftpclient.downloadPathPrefix=/file/download |
||||||
|
|
||||||
|
shareLink.prefix=http://192.168.43.208/#/show/ |
||||||
|
#shareLink.prefix=http://v3d.tonkia.xyz/#/show/ |
@ -0,0 +1,4 @@ |
|||||||
|
jdbc.driverClassName=com.mysql.cj.jdbc.Driver |
||||||
|
jdbc.url=jdbc:mysql://localhost:3306/v3dmodel?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false |
||||||
|
jdbc.username=root |
||||||
|
jdbc.password=123456 |
@ -0,0 +1,5 @@ |
|||||||
|
log4j.rootLogger=DEBUG,Console |
||||||
|
#Console |
||||||
|
log4j.appender.Console=org.apache.log4j.ConsoleAppender |
||||||
|
log4j.appender.Console.layout=org.apache.log4j.PatternLayout |
||||||
|
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n |
@ -0,0 +1,131 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xmlns:context="http://www.springframework.org/schema/context" |
||||||
|
xmlns:mvc="http://www.springframework.org/schema/mvc" |
||||||
|
xmlns:aop="http://www.springframework.org/schema/aop" |
||||||
|
xmlns:tx="http://www.springframework.org/schema/tx" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans |
||||||
|
http://www.springframework.org/schema/beans/spring-beans.xsd |
||||||
|
http://www.springframework.org/schema/context |
||||||
|
http://www.springframework.org/schema/context/spring-context.xsd |
||||||
|
http://www.springframework.org/schema/mvc |
||||||
|
http://www.springframework.org/schema/mvc/spring-mvc.xsd |
||||||
|
http://www.springframework.org/schema/aop |
||||||
|
http://www.springframework.org/schema/aop/spring-aop.xsd |
||||||
|
http://www.springframework.org/schema/tx |
||||||
|
http://www.springframework.org/schema/tx/spring-tx.xsd"> |
||||||
|
|
||||||
|
<!--引入配置文件,多个用逗号隔开--> |
||||||
|
<context:property-placeholder location="classpath:db.properties,classpath:cfg.properties"/> |
||||||
|
|
||||||
|
<!-- 启用springmvc注解--> |
||||||
|
<mvc:annotation-driven/> |
||||||
|
|
||||||
|
<!-- 设置使用注解的类路径 --> |
||||||
|
<context:component-scan base-package="com.tonkia.v3dmodel.controller,com.tonkia.v3dmodel.service.impl"/> |
||||||
|
<!--<context:annotation-config/>--> |
||||||
|
|
||||||
|
<!-- 静态文件处理 --> |
||||||
|
<mvc:resources location="/css/" mapping="/css/**/"/> |
||||||
|
<mvc:resources location="/js/" mapping="/js/**/"/> |
||||||
|
<mvc:resources location="/img/" mapping="/img/**/"/> |
||||||
|
<mvc:resources location="/ueditor/" mapping="/ueditor/**/"/> |
||||||
|
|
||||||
|
<!-- 文件上传--> |
||||||
|
<bean id="multipartResolver" |
||||||
|
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> |
||||||
|
<property name="defaultEncoding" value="utf-8"/> |
||||||
|
<property name="maxUploadSize" value="10240000"/> |
||||||
|
<property name="maxInMemorySize" value="10240000"/> |
||||||
|
<property name="resolveLazily" value="true"/> |
||||||
|
</bean> |
||||||
|
|
||||||
|
<!-- druid数据源 --> |
||||||
|
<bean id="ds" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> |
||||||
|
<property name="driverClassName" value="${jdbc.driverClassName}"/> |
||||||
|
<property name="url" value="${jdbc.url}"/> |
||||||
|
<property name="username" value="${jdbc.username}"/> |
||||||
|
<property name="password" value="${jdbc.password}"/> |
||||||
|
<property name="initialSize" value="2"/> |
||||||
|
<property name="minIdle" value="1"/> |
||||||
|
<property name="maxActive" value="20"/> |
||||||
|
<property name="maxWait" value="60000"/> |
||||||
|
<property name="timeBetweenEvictionRunsMillis" value="60000"/> |
||||||
|
<property name="minEvictableIdleTimeMillis" value="300000"/> |
||||||
|
<property name="validationQuery" value="SELECT 'x' from dual "/> |
||||||
|
<property name="testWhileIdle" value="true"/> |
||||||
|
<property name="testOnBorrow" value="false"/> |
||||||
|
<property name="testOnReturn" value="false"/> |
||||||
|
<property name="poolPreparedStatements" value="true"/> |
||||||
|
<property name="maxPoolPreparedStatementPerConnectionSize" value="20"/> |
||||||
|
</bean> |
||||||
|
|
||||||
|
<!-- 配置mybatis --> |
||||||
|
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> |
||||||
|
<property name="dataSource" ref="ds"/> |
||||||
|
</bean> |
||||||
|
|
||||||
|
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> |
||||||
|
<property name="sqlSessionFactoryBeanName" value="sessionFactory"/> |
||||||
|
<property name="basePackage" value="com.tonkia.v3dmodel.mapper"/> |
||||||
|
</bean> |
||||||
|
|
||||||
|
<!-- 事务管理器 --> |
||||||
|
<bean id="tm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> |
||||||
|
<property name="dataSource" ref="ds"/> |
||||||
|
</bean> |
||||||
|
<tx:advice id="txAdvice" transaction-manager="tm"> |
||||||
|
<tx:attributes> |
||||||
|
<tx:method name="insert*"/> |
||||||
|
<tx:method name="delete*"/> |
||||||
|
<tx:method name="update*"/> |
||||||
|
<tx:method name="*" read-only="true"/> |
||||||
|
</tx:attributes> |
||||||
|
</tx:advice> |
||||||
|
<aop:config> |
||||||
|
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.tonkia.v3dmodel.service.impl.*.*(..))"/> |
||||||
|
</aop:config> |
||||||
|
|
||||||
|
<!--shiro--> |
||||||
|
<!--<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">--> |
||||||
|
<!--<property name="securityManager" ref="securityManager"/>--> |
||||||
|
<!--<property name="loginUrl" value="/login"/>--> |
||||||
|
<!--<property name="unauthorizedUrl" value="/refuse"/>--> |
||||||
|
<!--<property name="filterChainDefinitions">--> |
||||||
|
<!--<value>--> |
||||||
|
<!--/test/**=anon--> |
||||||
|
<!--/=user--> |
||||||
|
<!--/logout=logout--> |
||||||
|
<!--/**=authc--> |
||||||
|
<!--</value>--> |
||||||
|
<!--</property>--> |
||||||
|
<!--</bean>--> |
||||||
|
<!--<!–securityManager–>--> |
||||||
|
<!--<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">--> |
||||||
|
<!--<property name="realm" ref="userRealm"/>--> |
||||||
|
<!--<property name="sessionManager" ref="sessionManager"/>--> |
||||||
|
<!--<!–<property name="cacheManager" ref="cacheManager"/>–>--> |
||||||
|
<!--</bean>--> |
||||||
|
<!--<bean id="userRealm" class="com.tonkia.v3dmodel.realm.UserRealm"/>--> |
||||||
|
<!--<!–sessionManager–>--> |
||||||
|
<!--<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">--> |
||||||
|
<!--<property name="sessionIdUrlRewritingEnabled" value="false"/>--> |
||||||
|
<!--<property name="deleteInvalidSessions" value="true"/>--> |
||||||
|
<!--<property name="globalSessionTimeout" value="600000"/>--> |
||||||
|
<!--</bean>--> |
||||||
|
<!--<!– Ehcache缓存–>--> |
||||||
|
<!--<!–<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"/>–>--> |
||||||
|
<!--<!–启用注解–>--> |
||||||
|
<!--<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>--> |
||||||
|
<!--<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"--> |
||||||
|
<!--depends-on="lifecycleBeanPostProcessor">--> |
||||||
|
<!--<property name="proxyTargetClass" value="true"/>--> |
||||||
|
<!--</bean>--> |
||||||
|
<!--<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">--> |
||||||
|
<!--<property name="securityManager" ref="securityManager"/>--> |
||||||
|
<!--</bean>--> |
||||||
|
|
||||||
|
</beans> |
||||||
|
|
||||||
|
|
@ -0,0 +1,55 @@ |
|||||||
|
<!DOCTYPE web-app PUBLIC |
||||||
|
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" |
||||||
|
"http://java.sun.com/dtd/web-app_2_3.dtd" > |
||||||
|
|
||||||
|
<web-app> |
||||||
|
<welcome-file-list> |
||||||
|
<welcome-file>index.jsp</welcome-file> |
||||||
|
</welcome-file-list> |
||||||
|
<!--字符编码过滤器--> |
||||||
|
<filter> |
||||||
|
<filter-name>encodingFilter</filter-name> |
||||||
|
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> |
||||||
|
<init-param> |
||||||
|
<param-name>encoding</param-name> |
||||||
|
<param-value>UTF-8</param-value> |
||||||
|
</init-param> |
||||||
|
</filter> |
||||||
|
<!--shiro--> |
||||||
|
<!--<filter>--> |
||||||
|
<!--<filter-name>shiroFilter</filter-name>--> |
||||||
|
<!--<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>--> |
||||||
|
<!--<init-param>--> |
||||||
|
<!--<param-name>targetFilterLifecycle</param-name>--> |
||||||
|
<!--<param-value>true</param-value>--> |
||||||
|
<!--</init-param>--> |
||||||
|
<!--</filter>--> |
||||||
|
<filter-mapping> |
||||||
|
<filter-name>encodingFilter</filter-name> |
||||||
|
<url-pattern>/*</url-pattern> |
||||||
|
</filter-mapping> |
||||||
|
<!--<filter-mapping>--> |
||||||
|
<!--<filter-name>shiroFilter</filter-name>--> |
||||||
|
<!--<url-pattern>/*</url-pattern>--> |
||||||
|
<!--</filter-mapping>--> |
||||||
|
<!--springmvc--> |
||||||
|
|
||||||
|
<servlet> |
||||||
|
<servlet-name>springmvc</servlet-name> |
||||||
|
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> |
||||||
|
<init-param> |
||||||
|
<param-name>contextConfigLocation</param-name> |
||||||
|
<param-value>classpath:/springmvc.xml</param-value> |
||||||
|
</init-param> |
||||||
|
<load-on-startup>1</load-on-startup> |
||||||
|
</servlet> |
||||||
|
<servlet-mapping> |
||||||
|
<servlet-name>default</servlet-name> |
||||||
|
<url-pattern>*.ico</url-pattern> |
||||||
|
</servlet-mapping> |
||||||
|
<servlet-mapping> |
||||||
|
<servlet-name>springmvc</servlet-name> |
||||||
|
<url-pattern>/</url-pattern> |
||||||
|
</servlet-mapping> |
||||||
|
|
||||||
|
</web-app> |
@ -0,0 +1 @@ |
|||||||
|
.v-enter{opacity:0;-webkit-transform:translateX(300px);transform:translateX(300px)}.v-leave-to{opacity:0;-webkit-transform:translateX(-300px);transform:translateX(-300px)}.v-enter-active,.v-leave-active{-webkit-transition:all .3s ease;transition:all .3s ease}.v-speed-dial{position:absolute}.v-btn--floating{position:relative} |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 225 KiB |
After Width: | Height: | Size: 449 KiB |
After Width: | Height: | Size: 306 KiB |
After Width: | Height: | Size: 268 KiB |
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 370 KiB |
@ -0,0 +1,27 @@ |
|||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %> |
||||||
|
<!DOCTYPE html> |
||||||
|
<html lang=en> |
||||||
|
<head> |
||||||
|
<meta charset=utf-8> |
||||||
|
<meta http-equiv=X-UA-Compatible content="IE=edge"> |
||||||
|
<meta name=viewport content="width=device-width,initial-scale=1"> |
||||||
|
<link rel=icon href=/favicon.ico> |
||||||
|
<title>V3D</title> |
||||||
|
<link rel=stylesheet href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"> |
||||||
|
<link rel=stylesheet href="https://fonts.googleapis.com/css?family=Material+Icons"> |
||||||
|
<script src=./js/inflate.min.js></script> |
||||||
|
<link href=/css/app.a0a149c8.css rel=preload as=style> |
||||||
|
<link href=/css/chunk-vendors.504cc259.css rel=preload as=style> |
||||||
|
<link href=/js/app.f155bb4f.js rel=preload as=script> |
||||||
|
<link href=/js/chunk-vendors.af4edcc5.js rel=preload as=script> |
||||||
|
<link href=/css/chunk-vendors.504cc259.css rel=stylesheet> |
||||||
|
<link href=/css/app.a0a149c8.css rel=stylesheet> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<noscript><strong>We're sorry but v3dmodel doesn't work properly without JavaScript enabled. Please enable it to |
||||||
|
continue.</strong></noscript> |
||||||
|
<div id=app></div> |
||||||
|
<script src=/js/chunk-vendors.af4edcc5.js></script> |
||||||
|
<script src=/js/app.f155bb4f.js></script> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,15 @@ |
|||||||
|
/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';var l=void 0,aa=this;function r(c,d){var a=c.split("."),b=aa;!(a[0]in b)&&b.execScript&&b.execScript("var "+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&d!==l?b[e]=d:b=b[e]?b[e]:b[e]={}};var t="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function v(c){var d=c.length,a=0,b=Number.POSITIVE_INFINITY,e,f,g,h,k,m,n,p,s,x;for(p=0;p<d;++p)c[p]>a&&(a=c[p]),c[p]<b&&(b=c[p]);e=1<<a;f=new (t?Uint32Array:Array)(e);g=1;h=0;for(k=2;g<=a;){for(p=0;p<d;++p)if(c[p]===g){m=0;n=h;for(s=0;s<g;++s)m=m<<1|n&1,n>>=1;x=g<<16|p;for(s=m;s<e;s+=k)f[s]=x;++h}++g;h<<=1;k<<=1}return[f,a,b]};function w(c,d){this.g=[];this.h=32768;this.d=this.f=this.a=this.l=0;this.input=t?new Uint8Array(c):c;this.m=!1;this.i=y;this.r=!1;if(d||!(d={}))d.index&&(this.a=d.index),d.bufferSize&&(this.h=d.bufferSize),d.bufferType&&(this.i=d.bufferType),d.resize&&(this.r=d.resize);switch(this.i){case A:this.b=32768;this.c=new (t?Uint8Array:Array)(32768+this.h+258);break;case y:this.b=0;this.c=new (t?Uint8Array:Array)(this.h);this.e=this.z;this.n=this.v;this.j=this.w;break;default:throw Error("invalid inflate mode"); |
||||||
|
}}var A=0,y=1,B={t:A,s:y}; |
||||||
|
w.prototype.k=function(){for(;!this.m;){var c=C(this,3);c&1&&(this.m=!0);c>>>=1;switch(c){case 0:var d=this.input,a=this.a,b=this.c,e=this.b,f=d.length,g=l,h=l,k=b.length,m=l;this.d=this.f=0;if(a+1>=f)throw Error("invalid uncompressed block header: LEN");g=d[a++]|d[a++]<<8;if(a+1>=f)throw Error("invalid uncompressed block header: NLEN");h=d[a++]|d[a++]<<8;if(g===~h)throw Error("invalid uncompressed block header: length verify");if(a+g>d.length)throw Error("input buffer is broken");switch(this.i){case A:for(;e+ |
||||||
|
g>b.length;){m=k-e;g-=m;if(t)b.set(d.subarray(a,a+m),e),e+=m,a+=m;else for(;m--;)b[e++]=d[a++];this.b=e;b=this.e();e=this.b}break;case y:for(;e+g>b.length;)b=this.e({p:2});break;default:throw Error("invalid inflate mode");}if(t)b.set(d.subarray(a,a+g),e),e+=g,a+=g;else for(;g--;)b[e++]=d[a++];this.a=a;this.b=e;this.c=b;break;case 1:this.j(ba,ca);break;case 2:for(var n=C(this,5)+257,p=C(this,5)+1,s=C(this,4)+4,x=new (t?Uint8Array:Array)(D.length),S=l,T=l,U=l,u=l,M=l,F=l,z=l,q=l,V=l,q=0;q<s;++q)x[D[q]]= |
||||||
|
C(this,3);if(!t){q=s;for(s=x.length;q<s;++q)x[D[q]]=0}S=v(x);u=new (t?Uint8Array:Array)(n+p);q=0;for(V=n+p;q<V;)switch(M=E(this,S),M){case 16:for(z=3+C(this,2);z--;)u[q++]=F;break;case 17:for(z=3+C(this,3);z--;)u[q++]=0;F=0;break;case 18:for(z=11+C(this,7);z--;)u[q++]=0;F=0;break;default:F=u[q++]=M}T=t?v(u.subarray(0,n)):v(u.slice(0,n));U=t?v(u.subarray(n)):v(u.slice(n));this.j(T,U);break;default:throw Error("unknown BTYPE: "+c);}}return this.n()}; |
||||||
|
var G=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],D=t?new Uint16Array(G):G,H=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],I=t?new Uint16Array(H):H,J=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],K=t?new Uint8Array(J):J,L=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],da=t?new Uint16Array(L):L,ea=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12, |
||||||
|
13,13],N=t?new Uint8Array(ea):ea,O=new (t?Uint8Array:Array)(288),P,fa;P=0;for(fa=O.length;P<fa;++P)O[P]=143>=P?8:255>=P?9:279>=P?7:8;var ba=v(O),Q=new (t?Uint8Array:Array)(30),R,ga;R=0;for(ga=Q.length;R<ga;++R)Q[R]=5;var ca=v(Q);function C(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h;b<d;){if(f>=g)throw Error("input buffer is broken");a|=e[f++]<<b;b+=8}h=a&(1<<d)-1;c.f=a>>>d;c.d=b-d;c.a=f;return h} |
||||||
|
function E(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h=d[0],k=d[1],m,n;b<k&&!(f>=g);)a|=e[f++]<<b,b+=8;m=h[a&(1<<k)-1];n=m>>>16;if(n>b)throw Error("invalid code length: "+n);c.f=a>>n;c.d=b-n;c.a=f;return m&65535} |
||||||
|
w.prototype.j=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length-258,f,g,h,k;256!==(f=E(this,c));)if(256>f)b>=e&&(this.b=b,a=this.e(),b=this.b),a[b++]=f;else{g=f-257;k=I[g];0<K[g]&&(k+=C(this,K[g]));f=E(this,d);h=da[f];0<N[f]&&(h+=C(this,N[f]));b>=e&&(this.b=b,a=this.e(),b=this.b);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b}; |
||||||
|
w.prototype.w=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length,f,g,h,k;256!==(f=E(this,c));)if(256>f)b>=e&&(a=this.e(),e=a.length),a[b++]=f;else{g=f-257;k=I[g];0<K[g]&&(k+=C(this,K[g]));f=E(this,d);h=da[f];0<N[f]&&(h+=C(this,N[f]));b+k>e&&(a=this.e(),e=a.length);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b}; |
||||||
|
w.prototype.e=function(){var c=new (t?Uint8Array:Array)(this.b-32768),d=this.b-32768,a,b,e=this.c;if(t)c.set(e.subarray(32768,c.length));else{a=0;for(b=c.length;a<b;++a)c[a]=e[a+32768]}this.g.push(c);this.l+=c.length;if(t)e.set(e.subarray(d,d+32768));else for(a=0;32768>a;++a)e[a]=e[d+a];this.b=32768;return e}; |
||||||
|
w.prototype.z=function(c){var d,a=this.input.length/this.a+1|0,b,e,f,g=this.input,h=this.c;c&&("number"===typeof c.p&&(a=c.p),"number"===typeof c.u&&(a+=c.u));2>a?(b=(g.length-this.a)/this.o[2],f=258*(b/2)|0,e=f<h.length?h.length+f:h.length<<1):e=h.length*a;t?(d=new Uint8Array(e),d.set(h)):d=h;return this.c=d}; |
||||||
|
w.prototype.n=function(){var c=0,d=this.c,a=this.g,b,e=new (t?Uint8Array:Array)(this.l+(this.b-32768)),f,g,h,k;if(0===a.length)return t?this.c.subarray(32768,this.b):this.c.slice(32768,this.b);f=0;for(g=a.length;f<g;++f){b=a[f];h=0;for(k=b.length;h<k;++h)e[c++]=b[h]}f=32768;for(g=this.b;f<g;++f)e[c++]=d[f];this.g=[];return this.buffer=e}; |
||||||
|
w.prototype.v=function(){var c,d=this.b;t?this.r?(c=new Uint8Array(d),c.set(this.c.subarray(0,d))):c=this.c.subarray(0,d):(this.c.length>d&&(this.c.length=d),c=this.c);return this.buffer=c};function W(c,d){var a,b;this.input=c;this.a=0;if(d||!(d={}))d.index&&(this.a=d.index),d.verify&&(this.A=d.verify);a=c[this.a++];b=c[this.a++];switch(a&15){case ha:this.method=ha;break;default:throw Error("unsupported compression method");}if(0!==((a<<8)+b)%31)throw Error("invalid fcheck flag:"+((a<<8)+b)%31);if(b&32)throw Error("fdict flag is not supported");this.q=new w(c,{index:this.a,bufferSize:d.bufferSize,bufferType:d.bufferType,resize:d.resize})} |
||||||
|
W.prototype.k=function(){var c=this.input,d,a;d=this.q.k();this.a=this.q.a;if(this.A){a=(c[this.a++]<<24|c[this.a++]<<16|c[this.a++]<<8|c[this.a++])>>>0;var b=d;if("string"===typeof b){var e=b.split(""),f,g;f=0;for(g=e.length;f<g;f++)e[f]=(e[f].charCodeAt(0)&255)>>>0;b=e}for(var h=1,k=0,m=b.length,n,p=0;0<m;){n=1024<m?1024:m;m-=n;do h+=b[p++],k+=h;while(--n);h%=65521;k%=65521}if(a!==(k<<16|h)>>>0)throw Error("invalid adler-32 checksum");}return d};var ha=8;r("Zlib.Inflate",W);r("Zlib.Inflate.prototype.decompress",W.prototype.k);var X={ADAPTIVE:B.s,BLOCK:B.t},Y,Z,$,ia;if(Object.keys)Y=Object.keys(X);else for(Z in Y=[],$=0,X)Y[$++]=Z;$=0;for(ia=Y.length;$<ia;++$)Z=Y[$],r("Zlib.Inflate.BufferType."+Z,X[Z]);}).call(this); |
@ -0,0 +1,12 @@ |
|||||||
|
#ftpclient.host=134.175.111.158 |
||||||
|
ftpclient.host=192.168.226.129 |
||||||
|
ftpclient.port=21 |
||||||
|
ftpclient.username=ftpuser |
||||||
|
#ftpclient.password=41509060104 |
||||||
|
ftpclient.password=123456 |
||||||
|
ftpclient.basePath=/home/ftpuser |
||||||
|
ftpclient.filePath=/v3d |
||||||
|
ftpclient.downloadPathPrefix=/file/download |
||||||
|
|
||||||
|
shareLink.prefix=http://192.168.43.208/#/show/ |
||||||
|
#shareLink.prefix=http://v3d.tonkia.xyz/#/show/ |