javascript 3d網頁 簡單的 可視化編輯 圖形界面 搭建幾何體 帶導出物體 示例 ( three.js r114 初探 五)

来源:https://www.cnblogs.com/weihexinCode/archive/2020/03/22/12543925.html
-Advertisement-
Play Games

1 完整代碼下載 https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ 提取碼 3fzt (壓縮包名: 2020-3-20-demo.zip) 2 圖片展示 3 主要代碼 1 /** HandCreate 簡單的 圖形界面 搭建幾何體 2 construct ...


1 完整代碼下載   https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ   提取碼 3fzt (壓縮包名: 2020-3-20-demo.zip)    2 圖片展示   3 主要代碼
  1 /** HandCreate 簡單的 圖形界面 搭建幾何體
  2     constructor:
  3     params:
  4     prototype:
  5     method:
  6 */
  7 class HandCreate{
  8     
  9     constructor(func, view, three){
 10         this.func = func;
 11         this.view = view;
 12         this.three = three;
 13         this.size = 1;
 14         this.color = "#DCDCDC";
 15         this.target = {};
 16         this.isOldAddMesh = false;
 17         this.lockTarget = false;
 18         this.exportGLTFFileType = false;
 19         
 20         this.group = new THREE.Group();
 21         this.three.scene.add(this.group);
 22         this.group.name = "Group_HandCreate";
 23         
 24         this.raycaster = {
 25             raycaster:new THREE.Raycaster(),
 26             vector2:new THREE.Vector2(),
 27             childrens:[],
 28             result:[]
 29         }
 30         this.raycaster.raycaster.far = 100;
 31         
 32         this.materials = this.initMaterials();
 33         this.geometrys = this.initGeometrys();
 34         this.lands();
 35         this.controls();
 36         this.initGui();
 37     }
 38     
 39     initMaterials(){
 40         let color = new THREE.Color(this.color);
 41         return new Map([
 42             [0, new THREE.MeshBasicMaterial({color:color})], 
 43             [1, new THREE.MeshLambertMaterial({color:color})], 
 44             [2, new THREE.MeshStandardMaterial({color:color})] 
 45         ]);
 46     }
 47     
 48     initGeometrys(){
 49         
 50         var geometrys = new Map([
 51             [0, new THREE.BoxGeometry(this.size, this.size, this.size, 1, 1, 1)],
 52             [1, new THREE.SphereGeometry(this.size/2, 8, 6, 0, Math.PI * 2, 0, Math.PI)],
 53         ]);
 54         
 55         for(let k = 0; k < geometrys.size; k++){
 56             this.createShowMesh(k, new THREE.Mesh(geometrys.get(k), this.materials.get(0)));
 57         }
 58         
 59         return geometrys;
 60         
 61     }
 62     
 63     initGui(){
 64         var k, len, upd = ()=>{this.update();}
 65         var exportGltf = {
 66             exAll:()=>{console.log("導出所有物體")},
 67             extar:()=>{this.exporterGLTF(this.target.mesh, this.exportGLTFFileType);},
 68             ft:false
 69         }
 70         
 71         new this.view.Gui({setMode:"translate"}, {setMode:[["平移", "translate"], ["旋轉", "rotate"], ["縮放", "scale"]]}, "控制模式")
 72         .change((v)=>{this.transformControl.setMode(v);}).title("控制器")
 73         
 74         .create(this, ["isOldAddMesh", "lockTarget"])
 75         .name({isOldAddMesh:"是否共用材質", lockTarget:"是否鎖定目標"})
 76         .title("其它").change(upd)
 77         
 78         .create(exportGltf, {ft:[[".gltf", false], [".glb", true]]}, "導出物體")
 79         .name({exAll:"所有物體", extar:"目標物體", ft:"文件類型"})
 80         .change("ft", (v)=>{this.exportGLTFFileType = v;})
 81 
 82     }
 83 
 84     addTarget(mesh){//當前目標物體
 85         if(this.target.mesh === mesh || this.lockTarget === true) return;
 86         this.removeTarget(mesh);
 87         this.transformControl.attach(mesh);
 88         this.target.gui = this.addTargetGui(mesh);
 89         this.target.mesh = mesh;
 90         this.update();
 91     }
 92     
 93     removeTarget(mesh){//移除當前目標物體
 94         this.transformControl.detach(mesh);
 95         if(this.target.gui){this.target.gui.remove(this.target.gui);}
 96         for(let k in this.target){delete(this.target[k]);}
 97     }
 98     
 99     lands(){//地面
100         var geometry = new THREE.PlaneBufferGeometry(this.three.sceneSize, this.three.sceneSize);
101         geometry.rotateX( - Math.PI / 2 );
102         var mesh = new THREE.Mesh(
103             geometry,
104             new THREE.MeshLambertMaterial({color:0x00ff00, visible:false})
105         );
106         mesh.receiveShadow = true;
107         mesh.matrixAutoUpdate = false;
108         this.gridHelper = new THREE.GridHelper(this.three.sceneSize, this.three.sceneSize/this.size);//每1米為一格
109         this.add(this.gridHelper, false);
110         this.add(mesh, false);
111     }
112     
113     controls(){//控制項
114         //平移控制項
115         var tc = new THREE.TransformControls(this.three.camera, this.three.renderer.domElement);
116         tc.addEventListener( 'dragging-changed', (e)=>{this.three.control.enabled = !e.value;});
117         tc.addEventListener('change', ()=>{this.update();});
118         tc.addEventListener('mouseDown', ()=>{});
119         tc.addEventListener('mouseUp', ()=>{});
120         tc.addEventListener('objectChange', ()=>{});
121         this.transformControl = tc;
122         this.three.scene.add(tc);
123         
124         //拖放控制項
125         var dc = new THREE.DragControls(this.raycaster.childrens, this.three.camera, this.three.renderer.domElement);
126         dc.addEventListener('hoveron', (e)=>{this.addTarget(e.object);});
127         dc.addEventListener('hoveroff', ()=>{this.update();});
128         dc.enabled = false;
129         this.dragcontrols = dc;
130         
131         //軌道控制項
132         this.three.control.addEventListener("change", ()=>{this.update()});
133         //this.three.control.addEventListener( 'start', ()=>{});
134         //this.three.control.addEventListener( 'end', ()=>{});
135     }
136     
137     add(mesh, isChildrens){//添加
138         if(!mesh){return;}
139         this.group.add(mesh);
140         if(isChildrens !== false){this.raycaster.childrens.push(mesh);}
141         this.update();
142         return mesh;
143     }
144     
145     remove(mesh, group){//移除物體
146         if(!mesh){return;}
147         let arr = group || this.group, k = this.raycaster.childrens.indexOf(mesh);
148         if(k !== -1){this.raycaster.childrens.splice(k, 1);}
149         mesh.material.dispose();
150         mesh.geometry.dispose();
151         arr.remove(mesh);
152     }
153     
154     addMesh(gkey, mkey, isChildrens){//添加物體
155         let g = gkey || 0, m = mkey || 0, mesh;
156         if(this.isOldAddMesh === true){
157             mesh = new THREE.Mesh(this.geometrys.get(g), this.materials.get(m));
158         }else{
159             mesh = new THREE.Mesh(this.geometrys.get(g), this.materials.get(m).clone());
160         }
161         return this.add(mesh, isChildrens);
162     }
163     
164     addWireframe(geometry){//添加網格輔助線
165         var wireframe = new THREE.WireframeGeometry(geometry);
166         var line = new THREE.LineSegments(wireframe);
167         line.material.depthTest = false;
168         line.material.opacity = 0.25;
169         line.material.transparent = true;
170         return line;
171     }
172     
173     createShowMesh(elemId, mesh){//物體選項
174         if(!mesh){return;}
175         if(!this.minSceneDom){
176             this.minSceneDom = this.view.add(document.body, "div", null, "ShowMesh box-scroll-block");
177             this.view.addEvent(this.minSceneDom, 'mousedown', (e)=>{
178                 let key = parseInt(e.target.id);
179                 if(typeof(key) !== "number" || isNaN(key) === true){return;}
180                 this.addTarget(this.addMesh(key, 0));
181             });
182         }
183         var scene = new THREE.Scene();
184         scene.background = new THREE.Color("black");
185         var camera = new THREE.PerspectiveCamera(45, 100/100, 0.1, 10);
186         camera.position.set(0, 1, 2);
187         camera.lookAt(0, 0, 0);
188         var renderer = new THREE.WebGLRenderer({antialias : true});
189         renderer.setSize(100, 100);
190         renderer.domElement.id = elemId + "_ShowMeshId";
191         this.minSceneDom.appendChild(renderer.domElement);
192         scene.add(camera, mesh);
193         mesh.material.wireframe = true;
194         mesh.matrixAutoUpdate = false;
195         this.update(scene, camera, renderer);
196     }
197     
198     update(scene, camera, renderer){//更新場景
199         this.three.render(scene, camera, renderer);
200     }
201     
202     updateGeometry(mesh, geometry){
203         mesh.geometry.dispose();
204         mesh.geometry = geometry;
205     }
206     
207     //光線投射
208     runRaycaster(x, y, recursive){
209         var c = this.raycaster;
210         c.result.length = 0;
211         c.vector2.set((x / this.view.client.w) * 2 - 1, -(y / this.view.client.h) * 2 + 1);
212         c.raycaster.setFromCamera(c.vector2, this.three.camera);
213         c.raycaster.intersectObjects(c.childrens, recursive, c.result);
214         //console.log(c.result[0]);
215     }
216     
217     //布爾運算 type = intersect    交集、重合的部分 union    並集、組合、相加 subtract    差集、相減
218     getBSP(meshA, meshB, type){
219         if(!meshA || !meshB || !type){return;}
220         var bsp_a = new ThreeBSP(meshA);//生成ThreeBSP對象
221         var bsp_b = new ThreeBSP(meshB);//生成ThreeBSP對象
222         var bsp = bsp_a[type](bsp_b);//進行 type 計算
223         var mesh = bsp.toMesh();//轉換為mesh模型
224         mesh.geometry.computeFaceNormals();//更新模型的面
225         mesh.geometry.computeVertexNormals();//更新模型的頂點
226         mesh.geometry = new THREE.BufferGeometry().fromGeometry(mesh.geometry);//轉換為 buff緩衝幾何體
227         mesh.material = meshA.material;//重賦值紋理
228         return mesh;
229     }
230     
231     //導入物體  .gltf || .glb
232     loadingGLTF(url){
233         if(!this.loadGLTF){this.loadGLTF = new THREE.GLTFLoader();}
234         this.loadGLTF.load(url, (gltf)=>{
235             //let model = gltf.scene;
236             this.add(gltf.scene);
237             //modlAnimate(model, gltf.animations)
238         });
239     }
240     
241     //導出物體(限谷歌瀏覽器)
242     exporterGLTF(mesh, fileType){
243         if(!this.exportGLTF){this.exportGLTF = new THREE.GLTFExporter();}
244         if(!mesh){console.log("mesh 錯誤"); return;}
245         //if(mesh.geometry.isGeometry === true){mesh.geometry = new THREE.BufferGeometry().fromGeometry(mesh.geometry);}
246         var opt = {binary: fileType || false};
247         var download = ( blob, filename )=>{
248             let link = this.view.add(document.body, "a");
249             link.style.display = 'none';
250             link.href = URL.createObjectURL( blob ); console.log(link.href);
251             link.download = filename;
252             link.click();
253             this.view.remove(link); 
254         }
255         
256         this.exportGLTF.parse(mesh, function ( result ){
257             if(result instanceof ArrayBuffer){
258                 download(new Blob([result], {type: 'application/octet-stream'}), 'scene.glb');
259             }else{
260                 download(new Blob([JSON.stringify( result, null, 2 )], {type: 'text/plain'}), 'scene.gltf');
261             }
262         }, opt);
263     }
264     
265     //添加目標gui視圖
266     addTargetGui(mesh){
267         
268         var g_rc, pi2 = Math.PI * 2, g_s = mesh.geometry.parameters, upd = ()=>{this.update();};
269         
270         var gui = new this.view.Gui(mesh.material, ["wireframe", "visible"], "修改材質-"+mesh.material.type)
271         .name({wireframe:"顯示網格", visible:"顯示物體"}).change(upd)
272         .add({color:"#"+mesh.material.color.getHexString()})
273         .change((e)=>{mesh.material.color.set(e.target.value); upd();})
274         
275         switch(mesh.geometry.type){
276             
277             case "BoxGeometry" :
278                 g_rc = {
279                     width:[0.1, 10, 0.1], 
280                     height:[0.1, 10, 0.1], 
281                     depth:[0.1, 10, 0.1], 
282                     widthSegments:[1, 30, 1], 
283                     heightSegments:[1, 30, 1], 
284                     depthSegments:[1, 30, 1]
285                 }
286                 gui.create(g_s, g_rc, "修改幾何體-"+mesh.geometry.type)
287                 .change(()=>{
288                     this.updateGeometry(
289                         mesh, 
290                         new THREE.BoxGeometry(g_s.width, g_s.height, g_s.depth, g_s.widthSegments, g_s.heightSegments, g_s.depthSegments)
291                     );
292                     upd();
293                 })
294                 
295             break;
296             
297             case "SphereGeometry" :
298                 g_rc = {
299                     radius:[0.5, 10, 0.1], 
300                     widthSegments:[1, 30, 1], 
301                     heightSegments:[1, 30, 1], 
302                     phiStart:[0, pi2, 0.1], 
303                     phiLength:[0, pi2, 0.1], 
304                     thetaStart:[0, pi2, 0.1], 
305                     thetaLength:[0, pi2, 0.1]
306                 }
307                 gui.create(g_s, g_rc, "修改幾何體-"+mesh.geometry.type)
308                 .change(()=>{
309                     this.updateGeometry(
310                         mesh, 
311                         new THREE.SphereGeometry(g_s.radius, g_s.widthSegments, g_s.heightSegments, g_s.phiStart, g_s.phiLength, g_s.thetaStart, g_s.thetaLength)
312                     );
313                     upd();
314                 })
315                 
316             break;
317             
318             default : break;
319         }
320         
321         return gui;
322         
323     }
324     
325 }

 

  1 /** HandCreate 簡單的 圖形界面 搭建幾何體
  2     constructor:
  3     params:
  4     prototype:
  5     method:
  6 */
  7 class HandCreate{
  8     
  9     constructor(func, view, three){
 10         this.func = func;
 11         this.view = view;
 12         this.three = three;
 13         this.size = 1;
 14         this.color = 0xDCDCDC;
 15         this.target = {};
 16         this.isOldAddMesh = true;
 17         
 18         this.group = new THREE.Group();
 19         this.three.scene.add(this.group);
 20         this.group.name = "Group_HandCreate";
 21         
 22         this.raycaster = {
 23             raycaster:new THREE.Raycaster(),
 24             vector2:new THREE.Vector2(),
 25             childrens:[],
 26             result:[]
 27         }
 28         this.raycaster.raycaster.far = 100;
 29         
 30         this.materials = this.initMaterials();
 31         this.geometrys = this.initGeometrys();
 32         this.lands();
 33         this.controls();
 34         this.initGui();
 35     }
 36     
 37     initMaterials(){
 38         return new Map([
 39             [0, new THREE.MeshBasicMaterial({color:this.color})], 
 40             [1, new THREE.MeshLambertMaterial({color:this.color})], 
 41             [2, new THREE.MeshStandardMaterial({color:this.color})] 
 42         ]);
 43     }
 44     
 45     initGeometrys(){
 46         
 47         var geometrys = new Map([
 48             [0, new THREE.BoxGeometry(this.size, this.size, this.size, 1, 1, 1)],
 49             [1, new THREE.SphereGeometry(this.size/2, 8, 6, 0, Math.PI * 2, 0, Math.PI)],
 50         ]);
 51         
 52         for(let k = 0; k < geometrys.size; k++){
 53             this.createShowMesh(k, new THREE.Mesh(geometrys.get(k), this.materials.get(0)));
 54         }
 55         
 56         return geometrys;
 57         
 58     }
 59     
 60     initGui(){
 61         var g_c = ()=>{this.update();}
 62         new this.view.Gui(
 63             {
 64                 translate:()=>{this.transformControl.setMode("translate")}, 
 65                 rotate:()=>{this.transformControl.setMode("rotate")}, 
 66                 scale:()=>{this.transformControl.setMode("scale")}
 67             }, 
 68             "控制類型(平移,旋轉,縮放)"
 69         )
 70         .create(this, "isOldAddMesh", "是否添加共用物體").change(g_c)
 71     }
 72     
 73     addTarget(mesh){//當前物體
 74         if(this.target.mesh === mesh) return;
 75         
 76         this.removeTarget(mesh);
 77         this.transformControl.attach(mesh);
 78         
 79         var upd = ()=>{this.update();}
 80         
 81         this.target.gui = new this.view.Gui(mesh.material, "wireframe", "修改材質-"+mesh.material.type).change(upd);
 82 
 83         let g_rc, g_s = mesh.geometry.parameters; //克隆的物體沒有 parameters 屬性
 84         switch(mesh.geometry.type){
 85             case "BoxGeometry" :
 86                 //g_s = {g_s.width, g_s.height, g_s.depth, g_s.widthSegments, g_s.heightSegments, g_s.depthSegments}
 87                 g_rc = {width:[0.1, 10, 0.1], height:[0.1, 10, 0.1], depth:[0.1, 10, 0.1], widthSegments:[1, 30, 1], heightSegments:[1, 30, 1], depthSegments:[1, 30, 1]}
 88                 this.target.gui.create(g_s, g_rc, "修改幾何體-"+mesh.geometry.type)
 89                 .change(()=>{
 90                     this.updateGeometry(mesh, new THREE.BoxGeometry(g_s.width, g_s.height, g_s.depth, g_s.widthSegments, g_s.heightSegments, g_s.depthSegments));
 91                     upd();
 92                 })
 93                 
 94             break;
 95             
 96             case "SphereGeometry" :
 97                 let pi2 = Math.PI * 2;
 98                 g_rc = {radius:[0.5, 10, 0.1], widthSegments:[1, 30, 1], heightSegments:[1, 30, 1], phiStart:[0, pi2, 0.1], phiLength:[0, pi2, 0.1], thetaStart:[0, pi2, 0.1], thetaLength:[0, pi2, 0.1]}
 99                 this.target.gui.create(g_s, g_rc, "修改幾何體-"+mesh.geometry.type)
100                 .change(()=>{
101                     this.updateGeometry(mesh, new THREE.SphereGeometry(g_s.radius, g_s.widthSegments, g_s.heightSegments, g_s.phiStart, g_s.phiLength, g_s.thetaStart, g_s.thetaLength));
102                     upd();
103                 })
104             break;
105             
106             default : break;
107         }
108         
109         this.target.mesh = mesh;
110     }
111     
112     removeTarget(mesh){//移除當前物體
113         this.transformControl.detach(mesh);
114         if(this.target.gui){this.target.gui.remove(this.target.gui);}
115         for(let k in this.target){delete(this.target[k]);}
116     }
117     
118     lands(){//地面
119         var geometry = new THREE.PlaneBufferGeometry(this.three.sceneSize, this.three.sceneSize);
120         geometry.rotateX( - Math.PI / 2 );
121         var mesh = new THREE.Mesh(
122             geometry,
123             new THREE.MeshLambertMaterial({color:0x00ff00, visible:false})
124         );
125         mesh.receiveShadow = true;
126         mesh.matrixAutoUpdate = false;
127         this.gridHelper = new THREE.GridHelper(this.three.sceneSize, this.three.sceneSize/this.size);//每1米為一格
128         this.add(this.gridHelper, false);
129         this.add(mesh, false);
130     }
131     
132     controls(){//控制項
133

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作者:Filip Rakowski 翻譯:啟道學院 我們已經知道,在Vue的新版本中編寫的應用程式將表現得非常好,但性能並不是最重要的部分。 對我們開發人員來說最重要的是新版本將如何影響我們編寫代碼的方式。 正如你所預料的,Vue3帶來了許多新的振奮人心的功能。 幸運的是,Vue團隊主要對當前的Co ...
  • "最新博客鏈接" "Github鏈接" 查看此文檔前應先瞭解, "vuepress基本操作" 參考官方文檔進行配置: "vuepress theme reco" "VuePress" "SamKirkland / FTP Deploy Action" 最終效果 "最終效果鏈接" 思路 下載vuepr ...
  • 訂單頁效果圖: 目錄結構 order.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>order</title> <meta name="viewport" content="width=devic ...
  • [TOC] "最新博客鏈接" "VuePress 線上文檔鏈接_Github Pages" "VuePress 線上文檔鏈接_博客伺服器" (如果上面進不去,可以進這個,伺服器在阿裡雲) "Github鏈接" 最終效果 "最終效果鏈接" 思路 總體 VuePress 在本地完成項目的源文件,推送至 ...
  • 1、環境搭建 基於node.js的http-server伺服器搭建 https://www.npmjs.com/package/http-server cnpm install http-server -g 2、首頁實現 創建一個目錄,叫webapp,在裡面創建一個index.html 打開cmd, ...
  • 利用EasyUI的TreeGrid組件格式化顯示Json數據,首先讀入Json文件,轉成Map對象,迴圈遞歸每一個Map,判斷它的值是基本類型還是Map。如果基本類型,則是屬性節點。如果Map,則是對象,需要再遍歷。 1.Map解析Tree對象 Tree對象 public class Display ...
  • JS 排序演算法之計數和基數排序 [Toc] 計數排序 利用數組的index是天然有序的特征來排序. 例如: 已知一個亂序數組的範圍是0~10,長度未知, 我們只需要遍歷一遍數組,點出每個值出現的次數,並用一個新數組來存儲這個次數,就能做到排序. 假如數字1出現3次, 那麼新數組newAry[1]=3 ...
  • JavaScript 如何複製一個對象?淺拷貝可以複製出原始值屬性,但是對於引用值屬性僅僅複製了一份引用。利用遞歸對每個引用值屬性的屬性進行複製,這種方式稱之為深拷貝 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...