浏览代码

Merge branch 'kevin' into Dev

oransheep 3 年之前
父节点
当前提交
c8fe1d1c8e

+ 169 - 0
assets/vendor/jquery-hoverIntent/jquery.hoverIntent.js

@@ -0,0 +1,169 @@
+/*!
+ * hoverIntent v1.10.2 // 2020.04.28 // jQuery v1.7.0+
+ * http://briancherne.github.io/jquery-hoverIntent/
+ *
+ * You may use hoverIntent under the terms of the MIT license. Basically that
+ * means you are free to use hoverIntent as long as this header is left intact.
+ * Copyright 2007-2019 Brian Cherne
+ */
+
+/**
+ * hoverIntent is similar to jQuery's built-in "hover" method except that
+ * instead of firing the handlerIn function immediately, hoverIntent checks
+ * to see if the user's mouse has slowed down (beneath the sensitivity
+ * threshold) before firing the event. The handlerOut function is only
+ * called after a matching handlerIn.
+ *
+ * // basic usage ... just like .hover()
+ * .hoverIntent( handlerIn, handlerOut )
+ * .hoverIntent( handlerInOut )
+ *
+ * // basic usage ... with event delegation!
+ * .hoverIntent( handlerIn, handlerOut, selector )
+ * .hoverIntent( handlerInOut, selector )
+ *
+ * // using a basic configuration object
+ * .hoverIntent( config )
+ *
+ * @param  handlerIn   function OR configuration object
+ * @param  handlerOut  function OR selector for delegation OR undefined
+ * @param  selector    selector OR undefined
+ * @author Brian Cherne <brian(at)cherne(dot)net>
+ */
+
+;(function(factory) {
+    'use strict';
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery'], factory);
+    } else if (typeof module === 'object' && module.exports) {
+        module.exports = factory(require('jquery'));
+    } else if (jQuery && !jQuery.fn.hoverIntent) {
+        factory(jQuery);
+    }
+})(function($) {
+    'use strict';
+
+    // default configuration values
+    var _cfg = {
+        interval: 100,
+        sensitivity: 6,
+        timeout: 0
+    };
+
+    // counter used to generate an ID for each instance
+    var INSTANCE_COUNT = 0;
+
+    // current X and Y position of mouse, updated during mousemove tracking (shared across instances)
+    var cX, cY;
+
+    // saves the current pointer position coordinates based on the given mousemove event
+    var track = function(ev) {
+        cX = ev.pageX;
+        cY = ev.pageY;
+    };
+
+    // compares current and previous mouse positions
+    var compare = function(ev,$el,s,cfg) {
+        // compare mouse positions to see if pointer has slowed enough to trigger `over` function
+        if ( Math.sqrt( (s.pX-cX)*(s.pX-cX) + (s.pY-cY)*(s.pY-cY) ) < cfg.sensitivity ) {
+            $el.off(s.event,track);
+            delete s.timeoutId;
+            // set hoverIntent state as active for this element (permits `out` handler to trigger)
+            s.isActive = true;
+            // overwrite old mouseenter event coordinates with most recent pointer position
+            ev.pageX = cX; ev.pageY = cY;
+            // clear coordinate data from state object
+            delete s.pX; delete s.pY;
+            return cfg.over.apply($el[0],[ev]);
+        } else {
+            // set previous coordinates for next comparison
+            s.pX = cX; s.pY = cY;
+            // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
+            s.timeoutId = setTimeout( function(){compare(ev, $el, s, cfg);} , cfg.interval );
+        }
+    };
+
+    // triggers given `out` function at configured `timeout` after a mouseleave and clears state
+    var delay = function(ev,$el,s,out) {
+        var data = $el.data('hoverIntent');
+        if (data) {
+            delete data[s.id];
+        }
+        return out.apply($el[0],[ev]);
+    };
+
+    // checks if `value` is a function
+    var isFunction = function(value) {
+        return typeof value === 'function';
+    };
+
+    $.fn.hoverIntent = function(handlerIn,handlerOut,selector) {
+        // instance ID, used as a key to store and retrieve state information on an element
+        var instanceId = INSTANCE_COUNT++;
+
+        // extend the default configuration and parse parameters
+        var cfg = $.extend({}, _cfg);
+        if ( $.isPlainObject(handlerIn) ) {
+            cfg = $.extend(cfg, handlerIn);
+            if ( !isFunction(cfg.out) ) {
+                cfg.out = cfg.over;
+            }
+        } else if ( isFunction(handlerOut) ) {
+            cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );
+        } else {
+            cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );
+        }
+
+        // A private function for handling mouse 'hovering'
+        var handleHover = function(e) {
+            // cloned event to pass to handlers (copy required for event object to be passed in IE)
+            var ev = $.extend({},e);
+
+            // the current target of the mouse event, wrapped in a jQuery object
+            var $el = $(this);
+
+            // read hoverIntent data from element (or initialize if not present)
+            var hoverIntentData = $el.data('hoverIntent');
+            if (!hoverIntentData) { $el.data('hoverIntent', (hoverIntentData = {})); }
+
+            // read per-instance state from element (or initialize if not present)
+            var state = hoverIntentData[instanceId];
+            if (!state) { hoverIntentData[instanceId] = state = { id: instanceId }; }
+
+            // state properties:
+            // id = instance ID, used to clean up data
+            // timeoutId = timeout ID, reused for tracking mouse position and delaying "out" handler
+            // isActive = plugin state, true after `over` is called just until `out` is called
+            // pX, pY = previously-measured pointer coordinates, updated at each polling interval
+            // event = string representing the namespaced event used for mouse tracking
+
+            // clear any existing timeout
+            if (state.timeoutId) { state.timeoutId = clearTimeout(state.timeoutId); }
+
+            // namespaced event used to register and unregister mousemove tracking
+            var mousemove = state.event = 'mousemove.hoverIntent.hoverIntent'+instanceId;
+
+            // handle the event, based on its type
+            if (e.type === 'mouseenter') {
+                // do nothing if already active
+                if (state.isActive) { return; }
+                // set "previous" X and Y position based on initial entry point
+                state.pX = ev.pageX; state.pY = ev.pageY;
+                // update "current" X and Y position based on mousemove
+                $el.off(mousemove,track).on(mousemove,track);
+                // start polling interval (self-calling timeout) to compare mouse coordinates over time
+                state.timeoutId = setTimeout( function(){compare(ev,$el,state,cfg);} , cfg.interval );
+            } else { // "mouseleave"
+                // do nothing if not already active
+                if (!state.isActive) { return; }
+                // unbind expensive mousemove event
+                $el.off(mousemove,track);
+                // if hoverIntent state is true, then call the mouseOut function after the specified delay
+                state.timeoutId = setTimeout( function(){delay(ev,$el,state,cfg.out);} , cfg.timeout );
+            }
+        };
+
+        // listen for mouseenter and mouseleave
+        return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);
+    };
+});

文件差异内容过多而无法显示
+ 8 - 0
assets/vendor/jquery-hoverIntent/jquery.hoverIntent.min.js


+ 298 - 19
index.php

@@ -47,7 +47,6 @@ if (!isset($_SESSION['loggedin'])) {
 	<!-- chart.js -->
 	<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
 	<!-- DataTable -->
-
 	<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.css">
 	<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.js"></script>
 	<!-- Icon -->
@@ -59,11 +58,12 @@ if (!isset($_SESSION['loggedin'])) {
 	<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.4/jstree.min.js"></script>
 	<script src="./script/js/jstreeAJAX.js"></script>
 	<script src="https://js.arcgis.com/4.21/"></script>
-	<style>
-		.row {
-			margin-top: -15px;
-		}
 
+	<!-- vue3 -->
+	<script src="https://unpkg.com/vue@next"></script>
+	<script src="./script/js/vue-search-block.js"></script>
+
+	<style>
 		.page-header>ul {
 			list-style: none;
 			padding: 0;
@@ -223,6 +223,60 @@ if (!isset($_SESSION['loggedin'])) {
 		#datatable-ajax_length {
 			width: 100%;
 		}
+
+		.multiselect {
+			width: 200px;
+		}
+
+		.selectBox {
+			position: relative;
+			width: 200px;
+		}
+
+		.selectBox select {
+			width: 100%;
+			font-weight: bold;
+		}
+
+		.overSelect {
+			position: absolute;
+			left: 0;
+			right: 0;
+			top: 0;
+			bottom: 0;
+		}
+
+		.checkboxes {
+			display: none;
+			border: 1px #dadada solid;
+			background-color: white;
+			z-index: 2;
+			position: absolute;
+			width: 200px;
+			display: none;
+		}
+
+		.checkboxes label {
+			display: block;
+			padding-left: 10px;
+			padding-right: 10px;
+			padding-top: 5px;
+			padding-bottom: 5px;
+		}
+
+		.checkboxes label:hover {
+			background-color: #1e90ff;
+			color: #ffffff;
+		}
+
+		.multiselect {
+			display: inline-block;
+		}
+
+		#filter-slide{
+			width: 100%;
+		}
+
 	</style>
 
 	<script>
@@ -547,6 +601,60 @@ if (!isset($_SESSION['loggedin'])) {
 
 
 		});
+
+		$.ajax({
+			url: "./script/php/get_db_table.php",
+			type: "GET",
+			async: false,
+			contentType: "application/json",
+			dataType: "json"
+		}).done(function(data) {
+			db_table = data;
+		}).error(function(error) {
+			console.log(error);
+		});
+
+		db_table["notes"] = merge_object_by_key(db_table["notes"], "project_id", "notes");
+		var notes_button_list = [...new Set([].concat(...Object.values(db_table["notes"])))];
+
+		var search_data = {
+			"category": get_value_list_by_key(db_table["category"], null, -1, "category_id").toString().split(","),
+			"project": get_value_list_by_key(db_table["project"], null, -1, "project_id"),
+			"type": get_value_list_by_key(db_table["type"], null, -1, "type_id").toString().split(","),
+			"notes": notes_button_list
+		};
+
+		var filter_base_data = search_data;
+
+		function get_value_list_by_key(obj_list, key_search, target_value, key_save) {
+			output_list = [];
+			obj_list.forEach(element => {
+				if (target_value != -1) {
+					target_value.forEach(e => {
+						if(e.toString() == element[key_search].toString()) {
+							output_list.push(element[key_save]);
+						}
+					});
+				} else {
+					output_list.push(element[key_save]);
+				}
+			});
+			output_list = [...new Set(output_list)];
+			return output_list;
+		}
+
+		function merge_object_by_key(obj, key, value) {
+			output_object = {};
+			while (obj.length > 0) {
+				pop_out = obj.pop();
+				if (output_object[pop_out[key]] == undefined) {
+					output_object[pop_out[key]] = [pop_out[value]];
+				} else {
+					output_object[pop_out[key]].push(pop_out[value]);
+				}
+			}
+			return output_object
+		}
 	</script>
 </head>
 
@@ -642,12 +750,157 @@ if (!isset($_SESSION['loggedin'])) {
 							<label id="header"></label>
 						</li>
 						<li class="right">
-							<div class="input-group input-search" style="table-layout: auto;"><input type="text" class="form-control" name="search" id="search" placeholder="Search..."><span class="input-group-btn"><button class="btn btn-default" id="btn-search"><i class="fa fa-search"></i></button></span></div>
+							<a class="mb-xs mt-xs mr-xs modal-with-move-anim btn btn-default" href="#advancedSearch"><i class="fa fa-search"></i> 進階搜尋</a>
 						</li>
 					</ul>
 				</header>
 				<div class="row">
+					<div id="advancedSearch" class="zoom-anim-dialog modal-block modal-block-primary mfp-hide">
+						<section class="panel">
+							<header class="panel-heading">
+								<h2 class="panel-title">進階搜尋</h2>
+							</header>
+							<div class="panel-body">
+								<form class="form-horizontal form-bordered" method="get">
+									<div class="form-group" id="category">
+										<label class="col-md-3 control-label">工程類別:</label>
+										<div class="multiselect col-md-6">
+											<div class="selectBox">
+												<select>
+													<option>選擇工程</option>
+												</select>
+												<div class="overSelect"></div>
+											</div>
+											<div class="checkboxes form-inline" style="display: none;">
+												<label for="category-any"><input type="checkbox" id="category-any" value="any" checked/> 全選</label>
+												<!-- append option -->
+											</div>
+										</div>
+									</div>
+
+									<div class="form-group" id="project">
+										<label class="col-md-3 control-label">專案類別:</label>
+										<div class="multiselect col-md-6">
+											<div class="selectBox">
+												<select>
+													<option>選擇專案</option>
+												</select>
+												<div class="overSelect"></div>
+											</div>
+											<div class="checkboxes form-inline" style="display: none;">
+												<label for="project-any"><input type="checkbox" id="project-any" value="any" checked/> 全選</label>
+												<!-- append option -->
+											</div>
+										</div>
+									</div>
+
+									<div class="form-group" id="type">
+										<label class="col-md-3 control-label">文件類別:</label>
+										<div class="multiselect col-md-6">
+											<div class="selectBox">
+												<select>
+													<option>選擇文件</option>
+												</select>
+												<div class="overSelect"></div>
+											</div>
+											<div class="checkboxes form-inline" style="display: none;">
+												<label for="type-any"><input type="checkbox" id="type-any" value="any" checked/> 全選</label>
+												<!-- append option -->
+											</div>
+										</div>
+									</div>
+
+									<div class="form-group" id="notes" style="display: bllock;" hidden>
+										<label class="col-md-3 control-label">設計圖類別:</label>
+										<div class="multiselect col-md-6">
+											<div class="selectBox">
+												<select>
+													<option>選擇設計圖</option>
+												</select>
+												<div class="overSelect"></div>
+											</div>
+											<div class="checkboxes form-inline" style="display: none;">
+												<label for="notes-any"><input type="checkbox" id="notes-any" value="any" checked/> 全選</label>
+												<!-- append option -->
+											</div>
+										</div>
+									</div>
+
+									<div class="form-group">
+										<label class="col-md-3 control-label" for="search-word">文字搜尋:</label>
+										<div class="col-md-6">
+											<input type="text" class="form-control" placeholder="輸入關鍵字" id="search-word">
+										</div>
+									</div>
+								</form>
+								
+							</div>
+							<footer class="panel-footer">
+								<div class="row">
+									<div class="col-md-12 text-right">
+										<div id="treeAjaxJSON" class="jstree jstree-4 jstree-default" role="tree"  style="display: none;">
+											<ul class="jstree-container-ul jstree-children">
+												<li class="jstree-initial-node jstree-loading jstree-leaf jstree-last">
+													<i class="jstree-icon jstree-ocl"></i>
+													<a class="jstree-anchor" href="#"><i class="jstree-icon jstree-themeicon-hidden"></i>Loading ...</a>
+												</li>
+											</ul>
+										</div>
+										<div class="progress progress-striped light active m-md" style="display: none;">
+											<div class="progress-bar progress-bar-primary" id="progress-bars" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>
+										</div>
+										<div class="jstree jstree-4 jstree-default" id="loading" style="display: none;">
+											<ul class="jstree-container-ul">
+												<li class="jstree-loading">
+													<i class="jstree-icon jstree-ocl"></i>讀取中 ...
+												</li>
+											</ul>
+										</div>
+										<div id="advanced-search-button-group" style="display: block;">
+											<button class="btn btn-primary" id="advanced-search-button">搜尋</button>
+											<button class="btn btn-default modal-dismiss">取消</button>
+										</div>
+									</div>
+								</div>
+							</footer>
+						</section>
+					</div>
+
 					<div class="col-md-6">
+						<section class="panel">
+							<div class="panel-body" id="search-filter-panel-body">
+								<form class="form-horizontal form-bordered" id="search-filter" method="get" hidden>
+									<div class="form-group">
+										<label class="col-md-3 control-label">工程類別:</label>
+										<div class="col-md-7" id="f-category">
+											<!-- append option -->
+										</div>
+									</div>
+
+									<div class="form-group">
+										<label class="col-md-3 control-label">專案類別:</label>
+										<div class="col-md-7" id="f-project">
+											<!-- append option -->
+										</div>
+									</div>
+
+									<div class="form-group">
+										<label class="col-md-3 control-label">文件類別:</label>
+										<div class="col-md-7" id="f-type">
+											<!-- append option -->
+										</div>
+									</div>
+
+									<div class="form-group" id="filter_notes" style="display: none;">
+										<label class="col-md-3 control-label">設計圖類別:</label>
+										<div class="col-md-7" id="f-notes">
+											<!-- append option -->
+										</div>
+									</div>
+								</form>
+								<i class="text-center fa fa-sort-desc" id="filter-slide"></i>
+							</div>
+						</section>
 						<section class="panel">
 							<div class="panel-body">
 
@@ -734,26 +987,52 @@ if (!isset($_SESSION['loggedin'])) {
 
 					</div>
 				</div>
-
-
-
-
-
+			</section>
 		</div>
 	</section>
 	</div>
+	<script>
+		db_table["category"].forEach(element => {
+			option_id = "c" + element["category_id"] + "-l" + element["list_id"];
+			$("#category .checkboxes").append("<label class='category-button' for="+option_id+"><input type='checkbox' class='category-option' value="+element["category_name"]+" id="+option_id+" />"+element["category_name"]+"</label>");
+			
+			filter_option_id = "f-c" + element["category_id"]
+			list_id = element["list_id"];
+			$("#f-category").append("<button type='button' class='mb-xs mt-xs mr-xs btn btn-primary' id="+filter_option_id+" list_id="+list_id+" style='display:none;'>"+element["category_name"]+"</button>");
+		});
 
+		db_table["project"].forEach(element => {
+			option_id = "p" + element["project_id"];
+			$("#project .checkboxes").append("<label class='project-button' for="+option_id+"><input type='checkbox' class='project-option' value="+element["project_id"]+" id="+option_id+" />["+element["project_id"]+"] "+element["project_name"]+"</label>");
+		
+			filter_option_id = "f-" + option_id;
+			$("#f-project").append("<button type='button' class='mb-xs mt-xs mr-xs btn btn-primary' id="+filter_option_id+" style='display:none;'>"+element["project_name"]+"</button>");
+		});
 
+		db_table["type"].forEach(element => {
+			option_id = "t" + element["type_id"];
+			$("#type .checkboxes").append("<label class='type-button' for="+option_id+"><input type='checkbox' class='type-option' value="+element["type_name"]+" id="+option_id+" />"+element["type_name"]+"</label>");
+		
+			filter_option_id = "f-" + option_id;
+			$("#f-type").append("<button type='button' class='mb-xs mt-xs mr-xs btn btn-primary' id="+filter_option_id+" style='display:none;'>"+element["type_name"]+"</button>");
+		});
 
-
-
-
-	</section>
-
-	<script>
-
+		for(i=0;i<notes_button_list.length;i++) {
+			option_id = "n" + i;
+			$("#notes .checkboxes").append("<label class='notes-button' for="+option_id+"><input type='checkbox' class='notes-option' value="+notes_button_list[i]+" id="+option_id+" />"+notes_button_list[i]+"</label>");
+		
+			filter_option_id = "f-" + option_id;
+			$("#f-notes").append("<button type='button' class='mb-xs mt-xs mr-xs btn btn-primary' id="+filter_option_id+" style='display:none;'>"+notes_button_list[i]+"</button>");
+		}
 	</script>
-
+	<!-- Vendor -->
+	<script src="assets/vendor/magnific-popup/magnific-popup.js"></script>
+
+	<!-- Examples -->
+	<script src='./script/js/search.js'></script>
+	<script src='./script/js/filter.js'></script>
+	<script src="assets/javascripts/ui-elements/examples.modals.js"></script>
+	
 </body>
 
 </html>

+ 31 - 0
script/js/filter.js

@@ -0,0 +1,31 @@
+$(function() {
+    // $("#f-category button").on("click", function() {
+    //     c_id = $(this).attr("id").replace("f-c", "");
+    //     l_id = $(this).attr("list_id");
+
+    //     sub_project_list = [];
+    //     db_table["project"].forEach(element => {
+    //         if(element["category_id"] == c_id) {
+    //             sub_project_list.push(element["project_id"]);
+    //         }
+    //     });
+    //     sub_project_list.forEach(element => {
+    //         $("#f-p" + element).toggleClass("btn-primary btn-default");
+    //     });
+
+    //     sub_type_list = [];
+    //     db_table["type"].forEach(element => {
+    //         if(element["filetype_id"] == l_id) {
+    //             sub_project_list.push(element["type_id"]);
+    //         }
+    //     });
+    //     sub_type_list.forEach(element => {
+    //         $("#f-t" + element).toggleClass("btn-primary btn-default");
+    //     });
+    // });
+
+    // $("#f-project button").on("click", function() {
+    //     id = $(this).attr("id").replace("f-p", "");
+        
+    // });
+});

+ 250 - 0
script/js/jstreeAJAX.js

@@ -290,6 +290,7 @@ $(document).ready(function () {
             .complete(function () {});
 
     });
+
     $('#search').keyup(function (e) {
         if (e.keyCode == 13) {
             $('#btn-search').click();
@@ -531,5 +532,254 @@ $(document).ready(function () {
         }
     }
 
+    var search_output = {};
+    var search_word = ""
+    $("#advanced-search-button").on("click", function (e) {
+        show_progress_bar(true);
+        update_progress_bar();
+        
+        $.ajax({
+            url: "./script/php/get_search_list.php",
+            data: {
+                project_id: [''].concat(search_data["project"]),
+                type_id: [''].concat(search_data["type"]),
+                notes_name: [''].concat(search_data["notes"].filter(element => {return element !== undefined;})),
+                search: $("#search-word").val(),
+            },
+            type: "GET",
+            dataType: "json",
+            contentType: "application/json",
+            async: false
+        }).success(function (response) {
+            displayDetail(true);
+            search_output = response;
+            search_word = $("#search-word").val();
+            filter_base_data = search_data;
+        }).error(function(error) {
+            console.log(error);
+        });
+        
+        setTimeout(() => {
+            draw_datatable(search_output);
+            e.preventDefault();
+            $.magnificPopup.close();
+
+            if($("#search-filter").css("display") != "none") {
+                $("#search-filter").slideUp(200);
+                $("#filter-slide").toggleClass("fa-sort-desc fa-sort-up");
+            }
+            $("#search-filter-panel-body .btn-default").toggleClass("btn-primary btn-default");
+            show_filter(filter_base_data);
+            show_progress_bar(false);
+        }, 0);
+    });
+
+    function draw_datatable(search_output) {
+        table.clear().draw();
+
+        for (i = 0; i < search_output.length; i++) {
+            table.row.add([
+                search_output[i]["SN"],
+                search_output[i]["original_name"],
+                search_output[i]["keyword"],
+                '1.0.0',
+                '',
+                search_output[i]["project_id"],
+                search_output[i]["project_name"],
+                search_output[i]["type_id"],
+                search_output[i]["category_name"],
+                search_output[i]["notes"],
+                search_output[i]["filename"],
+            ])
+            table.draw();
+
+            // progress_bar_value = (i/search_output.length)*100
+            // update_progress_bar();
+        }
+    }
+
+    function reset_filter_search_output(){
+        output_data = [];
+        click_option = get_filter_click("btn-primary");
+
+        $.ajax({
+            url: "./script/php/get_search_list.php",
+            data: {
+                project_id: [''].concat(click_option["project"]),
+                type_id: [''].concat(click_option["type"]),
+                notes_name: [''].concat(click_option["notes"]),
+                search: search_word
+            },
+            type: "GET",
+            dataType: "json",
+            contentType: "application/json",
+            async: false
+        }).success(function (response) {
+            displayDetail(true);
+            search_output = response;
+        }).error(function(error) {
+            console.log(error);
+        });
+
+        draw_datatable(search_output);
+    }
+
+    function get_filter_click(click_class){
+        click_id_list = {
+            "category": [],
+            "project": [],
+            "type": [],
+            "notes": []
+        };
+        check_notes = false;
+        $("#f-category ."+click_class).each(function() {
+            if($(this).css("display") == "inline-block") {
+                click_id_list["category"].push($(this).attr("id").replace("f-c", ""));
+            }
+        });
+        $("#f-project ."+click_class).each(function() {
+            if($(this).css("display") == "inline-block") {
+                click_id_list["project"].push($(this).attr("id").replace("f-p", ""));
+            }
+        });
+        $("#f-type ."+click_class).each(function() {
+            if($(this).css("display") == "inline-block") {
+                click_id_list["type"].push($(this).attr("id").replace("f-t", ""));
+                if($(this).attr("id").replace("f-t", "") == "3"){
+                    check_notes = true;
+                }
+            }
+        });
+        if(check_notes) {
+            $("#f-notes ."+click_class).each(function() {
+                if($(this).css("display") == "inline-block") {
+                    click_id_list["notes"].push($(this).text());
+                }
+            });
+        }
+        
+        return click_id_list;
+    }
 
+    function show_filter(filter_base_data) {
+        show_notes = false;
+        $("#search-filter button").css("display", "none");
+        filter_base_data["category"].forEach(element => {
+            id = "f-c" + element;
+            $("#" + id).css("display", "inline-block");
+        });
+        filter_base_data["project"].forEach(element => {
+            id = "f-p" + element;
+            $("#" + id).css("display", "inline-block");
+        });
+        filter_base_data["type"].forEach(element => {
+            id = "f-t" + element;
+            $("#" + id).css("display", "inline-block");
+            if(element == "3"){
+                show_notes = true;
+            }
+        });
+        if(show_notes) {
+            $("#filter_notes").css("display", "block");
+            filter_base_data["notes"].forEach(element => {
+                $("#f-notes button").each(function() {
+                    if($(this).text() == element) {
+                        $(this).css("display", "inline-block");
+                    }
+                });
+            });
+        } else {
+            $("#filter_notes").css("display", "none");
+        }
+    }
+
+    var progress_bar_value = 0;
+    function update_progress_bar() {
+        var i=0;
+        if (i == 0) {
+          i = 1;
+          var id = setInterval(frame, 10);
+          function frame() {
+            if (progress_bar_value >= 100) {
+              clearInterval(id);
+              i = 0;
+            } else {
+              $("#progress-bars").css("width", progress_bar_value+"%");
+            }
+          }
+        }
+      }
+
+    function show_progress_bar(show) {
+        if(show) {
+            $("#advanced-search-button-group").css("display", "none");
+            $("#loading").css("display", "block");
+            // $("#progress-bars").parent().css("display", "block");
+        } else {
+            $("#advanced-search-button-group").css("display", "block");
+            $("#loading").css("display", "none");
+            // $("#progress-bars").parent().css("display", "none");
+        }
+    }
+
+    $("#filter-slide").on("click", function (e) {
+        if($("#search-filter").css("display") == "block"){
+            $("#search-filter").slideUp(200);
+        } else {
+            $("#search-filter").slideDown(200);
+        }
+        $("#filter-slide").toggleClass("fa-sort-desc fa-sort-up")
+    });
+
+    $("#search-filter-panel-body button").on("click", function (e) {
+        $(this).toggleClass("btn-primary btn-default");
+
+        click_option = get_filter_click("btn-primary");
+        if(click_option["category"].length>0 && click_option["project"].length>0 && click_option["type"].length>0) {
+            reset_filter_search_output();
+        } else {
+            table.clear().draw();
+        }
+    });
+
+    $("#f-category button").on("click", function() {
+        c_id = $(this).attr("id").replace("f-c", "");
+
+        sub_project_list = [];
+        db_table["project"].forEach(element => {
+            if(element["category_id"] == c_id) {
+                sub_project_list.push(element["project_id"]);
+            }
+        });
+        sub_project_list.forEach(element => {
+            if($(this).hasClass("btn-primary")) {
+                if($("#f-p" + element).hasClass("btn-default")){
+                    $("#f-p" + element).toggleClass("btn-primary btn-default");
+                }
+            } else {
+                if($("#f-p" + element).hasClass("btn-primary")){
+                    $("#f-p" + element).toggleClass("btn-primary btn-default");
+                }
+            }
+
+            click_option = get_filter_click("btn-primary");
+            if(click_option["category"].length == 0) {
+                table.clear().draw();
+            }
+        });
+
+        reset_filter_search_output();
+    });
+
+    $("#f-type button").on("click", function() {
+        t_id = $(this).attr("id").replace("f-t", "");
+        if(t_id == "3") {
+            if($(this).hasClass("btn-default")) {
+                $("#filter_notes").css("display", "none");
+                $("#f-notes .btn-default").toggleClass("btn-primary btn-default");
+            } else {
+                $("#filter_notes").css("display", "block");
+            }
+        }
+    });
 });

+ 280 - 0
script/js/search.js

@@ -0,0 +1,280 @@
+$(function() {
+    $(".selectBox").on("click", function (e) {
+        if($(this).siblings(".checkboxes").find("label").css("display") == "block") {
+            if($(this).siblings(".checkboxes").css("display") == "none") {
+                $(".checkboxes").css("display", "none");
+                $(this).siblings(".checkboxes").css("display", "block");
+            } else {
+                $(".checkboxes").css("display", "none");
+            }
+        }
+    });
+
+    $("body").on("click", function (event) {
+        if (!$(event.target).hasClass("overSelect")) {
+            if (($(event.target).closest(".checkboxes").length == 0)) {
+                $(".checkboxes").css("display", "none");
+            }
+        }
+    });
+
+    $(".multiselect #category-any").on("change", function() {
+        $("#notes").slideUp(200);
+        $(".category-option").prop("checked", false);
+        if(this.checked) {
+            search_data["category"] = get_value_list_by_key(db_table["category"], null, -1, "category_id");
+            search_data["project"] = get_value_list_by_key(db_table["project"], null, -1, "project_id");
+            search_data["type"] = get_value_list_by_key(db_table["type"], null, -1, "type_id");
+        } else {
+            search_data["category"] = [];
+            search_data["project"] = [];
+            search_data["type"] = [];
+        }
+        notes_show = get_notes_list_by_project(notes_button_list);
+
+        set_select_text("category", false);
+        show_select_option("project", search_data["project"], "p", true);
+        show_select_option("type", search_data["type"], "t", true);
+        show_select_option("notes", notes_show, "n", true);
+    });
+    
+    $(".multiselect .category-option").on("change", function() {
+        $("#notes").slideUp(200);
+        category_id_list = [];
+        list_id_list = [];
+
+        //set search_data
+        check_list = get_multi_checkbox_check_list("category-option");
+        check_list.forEach(element => {
+            category_id_list.push(element.split("-")[0].replace("c", ""));
+            list_id_list.push(element.split("-")[1].replace("l", ""));
+        });
+        search_data["category"] = category_id_list;
+        search_data["project"] = get_value_list_by_key(db_table["project"], "category_id", category_id_list, "project_id");
+        target_type_id_list = get_value_list_by_key(db_table["category_type"], "list_id", list_id_list, "category_list");
+        search_data["type"] = merge_string_to_list(target_type_id_list);
+        notes_show = get_notes_list_by_project(notes_button_list);
+
+        //set view
+        if(search_data["category"].length == db_table["category"].length) {
+            $("#category .checkboxes input").prop("checked", false);
+            $("#category-any").prop("checked", true);
+        } else {
+            $("#category-any").prop("checked", false);
+        }
+        set_select_text("category", false);
+        show_select_option("project", search_data["project"], "p", true);
+        show_select_option("type", search_data["type"], "t", true);
+        show_select_option("notes", notes_show, "n", true);
+    });
+
+    $(".multiselect #project-any").on("change", function() {
+        $("#notes").slideUp(200);
+        $(".project-option").prop("checked", false);
+
+        search_data["project"] = [];
+        if(this.checked) {
+            $(".project-button:visible").each(function(){
+                search_data["project"].push($(this).find("input").attr("id").replace("p", ""));
+            });
+        }
+        notes_show = get_notes_list_by_project(notes_button_list);
+
+        set_select_text("project", false);
+        reset_checkbox("type", "t", true);
+        show_select_option("notes", notes_show, "n", true);
+    });
+    
+    $(".multiselect .project-option").on("change", function() {
+        $("#notes").slideUp(200);
+
+        search_data["project"] = get_multi_checkbox_check_list("project-option", "p");
+        notes_show = get_notes_list_by_project(notes_button_list);
+
+        if($(".project-option:checked").length == $(".project-button:visible").length) {
+            $("#project .checkboxes input").prop("checked", false);
+            $("#project-any").prop("checked", true);
+        } else {
+            $("#project-any").prop("checked", false);
+        }
+        set_select_text("project", false);
+        reset_checkbox("type", "t", true);
+        show_select_option("notes", notes_show, "n", true);
+    });
+
+    $(".multiselect #type-any").on("change", function() {
+        $("#notes").slideUp(200);
+        $(".type-option").prop("checked", false);
+
+        search_data["type"] = [];
+        if(this.checked) {
+            $(".type-button:visible").each(function(){
+                search_data["type"].push($(this).find("input").attr("id").replace("t", ""));
+            });
+        }
+        set_select_text("type", false);
+        reset_checkbox("notes", "n", true);
+    });
+
+    $(".multiselect .type-option").on("change", function() {
+        search_data["type"] = get_multi_checkbox_check_list("type-option", "t");
+
+        if($(".type-option:checked").length == $(".type-button:visible").length) {
+            $("#type .checkboxes input").prop("checked", false);
+            $("#type-any").prop("checked", true);
+        } else {
+            $("#type-any").prop("checked", false);
+        }
+        set_select_text("type", false);
+
+        if($("#t3").prop("checked")) {
+            $("#notes").slideDown(200);
+            reset_checkbox("notes", "n", true);
+        } else {
+            $("#notes").slideUp(200);
+        }
+    });
+
+    $(".multiselect #notes-any").on("change", function() {
+        $(".notes-option").prop("checked", false);
+
+        search_data["notes"] = [];
+        if(this.checked) {
+            $(".notes-button:visible").each(function(){
+                search_data["notes"].push(notes_button_list[parseInt($(this).find("input").attr("id").replace("n", ""))]);
+            });
+        }
+        set_select_text("notes", false);
+    });
+
+    $(".multiselect .notes-option").on("change", function() {
+        search_data["notes"] = get_multi_checkbox_check_list("notes-option", "n");
+        
+        if($(".notes-option:checked").length == $(".notes-button:visible").length) {
+            $("#notes .checkboxes input").prop("checked", false);
+            $("#notes-any").prop("checked", true);
+        } else {
+            $("#notes-any").prop("checked", false);
+        }
+        set_select_text("notes", false);
+    });
+});
+
+function merge_string_to_list(string_list) {
+    output = [];
+    string_list.forEach(element => {
+        output = output.concat(element.split(","));
+    });
+    return output;
+}
+
+function string_concat_list(name, target_list) {
+    output_list = [];
+    target_list.forEach(element => {
+        output_list.push(name + element);
+    });
+    return output_list;
+}
+
+function get_multi_checkbox_check_list(checkbox_class, name_replace) {
+    output = [];
+    var $select_option = $("."+checkbox_class+":checked");
+    $select_option.each(function(){
+        if(checkbox_class == "notes-option") {
+            output.push($(this).attr('value'));
+        } else {
+            output.push($(this).attr('id').replace(name_replace, ""));
+        }
+        
+    });
+    return output;
+}
+
+function set_select_text(address, lock) {
+    //unlock select bar
+    $("#"+address+" select").prop("disabled", false);
+
+    //get option name that show on select bar
+    show_list = [];
+    if($("#"+address+"-any").prop("checked")) {
+        $("."+address+"-button").each(function() {
+            if($(this).css("display") == "block") {
+                show_list = show_list.concat($(this).find("input").attr("value"));
+            }
+        });
+    } else {
+        $("."+address+"-option:checked").each(function() {
+            show_list = show_list.concat($(this).attr("value"));
+        });
+    }
+
+    //set select bar text
+    if(show_list.length == 0){
+        if(lock) {
+            $("#"+address+" select option").text("無符合條件選項");
+            $("#"+address+" select").prop("disabled", true);
+        } else {
+            $("#"+address+" select option").text("未選擇任何專案");
+        }
+    } else {
+        if(show_list.length > 2) {
+            $("#"+address+" select option").text("已選擇 "+show_list.length+" 項");
+        } else {
+            $("#"+address+" select option").text(show_list);
+        }
+    }
+}
+
+function show_select_option(address, show_list, id_name, lock) {
+    //init option
+    $("#" + address + " .checkboxes input").prop("checked", false);
+    $("#" + address + " .checkboxes label").css("display", "none");
+
+    //show option
+    show_list.forEach(element => {
+        $("#"+id_name+element).parent().css("display", "block");
+    });
+
+    if(show_list.length) {
+        $("#" + address + " #" + address + "-any").prop("checked", true);
+        $("#" + address + " #" + address + "-any").parent().css("display", "block");
+    }
+
+    set_select_text(address, lock);
+}
+
+function reset_checkbox(checkbox_class, id_name, lock) {
+    search_data[checkbox_class] = [];
+
+    $("#"+checkbox_class+" ." + checkbox_class + "-button").each(function() {
+        if($(this).css("display") == "block") {
+            if(checkbox_class == "notes") {
+                search_data[checkbox_class] = search_data[checkbox_class].concat($(this).find("input").attr("value"));
+            } else {
+                search_data[checkbox_class] = search_data[checkbox_class].concat($(this).find("input").attr("id").replace(id_name, ""));
+            }
+        }
+    });
+
+    $("#"+checkbox_class+" .checkboxes input").prop("checked", false);
+    $("#"+checkbox_class+" #" + checkbox_class + "-any").prop("checked", true);
+    set_select_text(checkbox_class, lock)
+}
+
+function get_notes_list_by_project(notes_order_list) {
+    search_data["notes"] = []
+    search_data["project"].forEach(element => {
+        search_data["notes"] = search_data["notes"].concat(db_table["notes"][element]);
+    });
+    search_data["notes"] = [...new Set(search_data["notes"])];
+
+    output_notes_order = []
+    search_data["notes"].forEach(element => {
+        for(i=0; i<notes_order_list.length; i++) {
+            if(notes_order_list[i] == element) {
+                output_notes_order.push(i);
+            }
+        }
+    });
+    return output_notes_order;
+}

+ 235 - 0
script/js/vue-search-block.js

@@ -0,0 +1,235 @@
+var db_table = {};
+
+function get_value_list_by_key(obj_list, key_search, target_value, key_save) {
+    output_list = [];
+    obj_list.forEach(element => {
+        if (target_value.length) {
+            target_value.forEach(e => {
+                if(e.toString() == element[key_search].toString()) {
+                    output_list.push(element[key_save]);
+                }
+            });
+        } else {
+            output_list.push(element[key_save]);
+        }
+    });
+    output_list = [...new Set(output_list)];
+    return output_list;
+}
+
+function merge_object_by_key(obj, key, value) {
+    output_object = {};
+    while (obj.length > 0) {
+        pop_out = obj.pop();
+        if (output_object[pop_out[key]] == undefined) {
+            output_object[pop_out[key]] = [pop_out[value]];
+        } else {
+            output_object[pop_out[key]].push(pop_out[value]);
+        }
+    }
+    return output_object
+}
+
+$.ajax({
+    url: "./script/php/get_db_table.php",
+    type: "GET",
+    async: false,
+    contentType: "application/json",
+    dataType: "json"
+}).done(function(data) {
+    db_table = data;
+}).error(function(error) {
+    console.log(error);
+});
+
+db_table["notes"] = merge_object_by_key(db_table["notes"], "project_id", "notes");
+var notes_button_list = [...new Set([].concat(...Object.values(db_table["notes"])))];
+
+var search_data = {
+    "category": get_value_list_by_key(db_table["category"], null, [], "category_id"),
+    "project": get_value_list_by_key(db_table["project"], null, [], "project_id"),
+    "type": get_value_list_by_key(db_table["type"], null, [], "type_id"),
+    "notes": notes_button_list
+};
+
+const vm = Vue.createApp({});
+
+vm.component('search-block', {
+    data() {
+        return {
+            category_list: db_table["category"],
+            project_list: db_table["project"],
+            type_list: db_table["type"],
+            notes_button_list: notes_button_list
+        }
+    },
+    template: `<section class="panel">
+            <div class="panel-body">
+                <ul class="button-group nav nav-pills nav-pills-primary">
+                    <li style="padding: 10px 15px;">
+                        <label>工程類別:</label>
+                    </li>
+                    <select id="category_button">
+                        <option value="any">any</option>
+                        <category-button v-for="item in category_list" v-bind:object="item"></category-button>
+                    </select>
+                    <div class="multiselect">
+                        <div class="selectBox">
+                            <select id="c-select">
+                                <option>選擇專案</option>
+                            </select>
+                            <div class="overSelect"></div>
+                        </div>
+                        <div class="checkboxes form-inline" style="display: none;">
+                            <label for="category-any"><input type="checkbox" id="category-any" value="any" checked/> 全選</label>
+                            <category-button v-for="item in category_list" :object="item"></category-button>
+                        </div>
+                    </div>
+                </ul>
+
+                <ul class="button-group nav nav-pills nav-pills-primary">
+                    <li style="padding: 10px 15px;">
+                        <label >專案類別:</label>
+                    </li>
+                    <div class="multiselect">
+                        <div class="selectBox">
+                            <select id="p-select">
+                                <option>選擇專案</option>
+                            </select>
+                            <div class="overSelect"></div>
+                        </div>
+                        <div class="checkboxes form-inline" style="display: none;">
+                            <label for="project-any"><input type="checkbox" id="project-any" value="any" checked/> 全選</label>
+                            <project-button v-for="item in project_list" :object="item"></project-button>
+                        </div>
+                    </div>
+                </ul>
+                
+                <div id="type">
+                    <ul class="button-group nav nav-pills nav-pills-primary">
+                        <li style="padding: 10px 15px;">
+                            <label>文件類別:</label>
+                        </li>
+                        <select id="type-button">
+                            <option value="any">any</option>
+                            <type-button v-for="item in type_list" v-bind:object="item"></type-button>
+                        </select>
+                    </ul>
+                </div>
+
+                <div id="notes" hidden>
+                    <ul class="button-group nav nav-pills nav-pills-primary">
+                        <li style="padding: 10px 15px;">
+                            <label>設計圖類別:</label>
+                        </li>
+                        <select id="notes-button">
+                            <option value="any">any</option>
+                            <option value="none">無符合條件選項</option>
+                            <notes-button v-for="item in notes_button_list" v-bind:object="item"></notes-button>
+                        </select>
+                    </ul>
+                </div>
+                <div class="filter-search-bar">
+                    <hr class="solid short">
+                    <button class="search-by-filter" style="float:right">search</button>
+                </div>
+            </div>
+            
+        </section>`
+});
+
+vm.component("multi-select", {
+    template:
+        `<div class="multiselect">
+            <div class="selectBox">
+                <select id="c-select">
+                    <option>選擇專案</option>
+                </select>
+                <div class="overSelect"></div>
+            </div>
+            <div class="checkboxes form-inline" style="display: none;">
+                <label for="category-any"><input type="checkbox" id="category-any" value="any" checked/> 全選</label>
+                <category-button v-for="item in category_list" :object="item"></category-button>
+            </div>
+        </div>`,
+    props: {
+        object: {
+            category_name: String,
+            category_id: String,
+            list_id: String
+        },
+    },
+    computed: {
+        id_concat(){
+            return "category" + this.object.category_id + "-" + this.object.list_id;
+        }        
+    }
+});
+
+vm.component("checkbox-option", {
+    template: `<label class="category-button" v-bind:for="id_concat"><input type="checkbox" class="category-checkbox" :value=object.category_id :id="id_concat" checked/>{{" " + this.object.category_name}}</label>`,
+    props: {
+        object: {
+            category_name: String,
+            category_id: String,
+            list_id: String
+        },
+    },
+    computed: {
+        id_concat(){
+            return "category" + this.object.category_id + "-" + this.object.list_id;
+        }        
+    }
+});
+
+vm.component('category-button', {
+    template: `<label class="category-button" v-bind:for="id_concat"><input type="checkbox" class="category-checkbox" :value=object.category_id :id="id_concat" checked/>{{" " + this.object.category_name}}</label>`,
+    props: {
+        object: {
+            category_name: String,
+            category_id: String,
+            list_id: String
+        },
+    },
+    computed: {
+        id_concat(){
+            return "category" + this.object.category_id + "-" + this.object.list_id;
+        }        
+    }
+});
+
+vm.component('project-button', {
+    template: `<label class="project-button" v-bind:for="id_concat"><input type="checkbox" class="project-checkbox" :value=object.project_id :id="id_concat" checked/>{{" [" + this.object.project_id + "] " + this.object.project_name}}</label>`,
+    props: {
+        object: {
+            project_id: String,
+            project_name: String,
+            category_id: String
+        },
+    },
+    computed: {
+        id_concat(){
+            return "project" + this.object.project_id;
+        }  
+    }
+
+});
+
+vm.component('type-button', {
+    template: `<option :value=object.type_id>{{object.type_name}}</option>`,
+    props: {
+        object: {
+            type_id: String,
+            type_name: String,
+            filetype_id: String
+        },
+    }
+});
+
+vm.component('notes-button', {
+    template: `<option v-bind:value=object>{{object}}</option>`,
+    props: {
+        object: String
+    }
+});
+

+ 60 - 0
script/php/get_db_table.php

@@ -0,0 +1,60 @@
+<?php
+
+include("sql.php");
+$category = [];
+$project = [];
+$type = [];
+$notes = [];
+$category_type = [];
+
+$connectionInfo = array("Database" => "$dbname", "UID" => "$username", "PWD" => "$password", "CharacterSet" => "UTF-8");
+$conn = sqlsrv_connect($hostname, $connectionInfo);
+if ($conn === false) {
+    die(print_r(sqlsrv_errors(), true));
+}
+
+//get category table
+$sql = "SELECT DISTINCT * FROM [21000X].[dbo].[Construction_Category];";
+$fetchResult = sqlsrv_query($conn, $sql);
+while ($row = sqlsrv_fetch_array($fetchResult, SQLSRV_FETCH_ASSOC)) {
+    array_push($category ,$row);
+}
+
+//get project table
+$sql = "SELECT DISTINCT * FROM [21000X].[dbo].[Project_Table];";
+$fetchResult = sqlsrv_query($conn, $sql);
+while ($row = sqlsrv_fetch_array($fetchResult, SQLSRV_FETCH_ASSOC)) {
+    array_push($project ,$row);
+}
+
+//get type table
+$sql = "SELECT DISTINCT * FROM [21000X].[dbo].[File_Category];";
+$fetchResult = sqlsrv_query($conn, $sql);
+while ($row = sqlsrv_fetch_array($fetchResult, SQLSRV_FETCH_ASSOC)) {
+    array_push($type ,$row);
+}
+
+//get notes table
+$sql = "SELECT DISTINCT [Project_Table].[project_id], [notes] FROM [21000X].[dbo].[Project_Table]
+    RIGHT JOIN [Blueprint] ON [Project_Table].[project_id] = [Blueprint].[project_id];";
+$fetchResult = sqlsrv_query($conn, $sql);
+while ($row = sqlsrv_fetch_array($fetchResult, SQLSRV_FETCH_ASSOC)) {
+    array_push($notes ,$row);
+}
+
+//get category_type table
+$sql = "SELECT DISTINCT * FROM [21000X].[dbo].[Category_List];";
+$fetchResult = sqlsrv_query($conn, $sql);
+while ($row = sqlsrv_fetch_array($fetchResult, SQLSRV_FETCH_ASSOC)) {
+    array_push($category_type ,$row);
+}
+
+$data["category"] = $category;
+$data["project"] = $project;
+$data["type"] = $type;
+$data["notes"] = $notes;
+$data["category_type"] = $category_type;
+
+echo json_encode($data,JSON_UNESCAPED_UNICODE);
+sqlsrv_close($conn);  
+?>

+ 63 - 0
script/php/get_search_list.php

@@ -0,0 +1,63 @@
+<?php
+
+if (isset($_GET['project_id'])) {
+    include("sql.php");
+    $project_id = implode("', '", $_GET['project_id']);
+    $type_id = implode("', '", $_GET['type_id']);
+    $notes_name = implode("', '", $_GET['notes_name']);
+    $search = $_GET['search'];
+    $array = [];
+
+    $connectionInfo = array("Database" => "$dbname", "UID" => "$username", "PWD" => "$password", "CharacterSet" => "UTF-8");
+    $conn = sqlsrv_connect($hostname, $connectionInfo);
+    if ($conn === false) {
+        die(print_r(sqlsrv_errors(), true));
+    }
+
+    if(in_array("3", $_GET['type_id'])) {
+        $sql = "SELECT DISTINCT [Blueprint].[project_id],[SN],[original_name],[filename],[project_name],[type_id],[category_name],[notes],[keyword] FROM [21000X].[dbo].[Blueprint]
+            INNER JOIN [Project_Table] ON [Blueprint].[project_id] = [Project_Table].[project_id] 
+            INNER JOIN [Construction_Category] ON [Project_Table].[category_id] = [Construction_Category].[category_id]
+            WHERE [Blueprint].[project_id] IN ('$project_id') AND [type_id] IN ('$type_id') AND [notes] IN ('$notes_name') 
+            AND CONCAT(
+                [Blueprint].[project_id] ,' '
+                ,[SN] ,' '
+                ,[blueprint_id] ,' '
+                ,[original_name] ,' '
+                ,[keyword] ,' '
+                ,[notes] ,' '
+                ,[filename]) like '%".$search."%'
+            UNION
+            SELECT DISTINCT [File_Table].[project_id],[SN],[original_name],[filename],[project_name],[type_id],[category_name],null,[keyword] FROM [21000X].[dbo].[File_Table]
+            INNER JOIN [Project_Table] ON [File_Table].[project_id] = [Project_Table].[project_id]
+            INNER JOIN [Construction_Category] ON [Project_Table].[category_id] = [Construction_Category].[category_id]
+            WHERE [File_Table].[project_id] IN ('$project_id') AND [type_id] IN ('$type_id')
+            AND CONCAT(
+                [File_Table].[project_id],' '
+                ,[SN],' '
+                ,[type_id],' '
+                ,[original_name],' '
+                ,[filename],' ') like '%".$search."%';";
+    } else {
+        $sql = "SELECT DISTINCT [File_Table].[project_id],[SN],[original_name],[filename],[project_name],[type_id],[category_name],null,[keyword] FROM [21000X].[dbo].[File_Table]
+            INNER JOIN [Project_Table] ON [File_Table].[project_id] = [Project_Table].[project_id]
+            INNER JOIN [Construction_Category] ON [Project_Table].[category_id] = [Construction_Category].[category_id]
+            WHERE [File_Table].[project_id] IN ('$project_id') AND [type_id] IN ('$type_id')
+            AND CONCAT(
+                [File_Table].[project_id],' '
+                ,[SN],' '
+                ,[type_id],' '
+                ,[original_name],' '
+                ,[filename],' ') like '%".$search."%';";
+    }
+    
+    $fetchResult = sqlsrv_query($conn, $sql);
+    while ($row = sqlsrv_fetch_array($fetchResult, SQLSRV_FETCH_ASSOC)) {
+        array_push($array ,$row);
+    }
+    echo json_encode($array,JSON_UNESCAPED_UNICODE);
+} else {
+    die("post error!");
+}
+
+?>

部分文件因为文件数量过多而无法显示