zhangweicheng 7 年之前
父節點
當前提交
2722b9d0a8

+ 22 - 0
modules/all_models/project_feature_lib.js

@@ -0,0 +1,22 @@
+/**
+ * Created by zhang on 2018/9/3.
+ */
+
+//工程特征库
+const mongoose = require('mongoose');
+const Schema = mongoose.Schema;
+const oprSchema = require('../all_schemas/opr_schema');
+const project_feature_lib = new Schema({
+        ID:{type:String,index:true},
+        creator: String,
+        createDate: Number,
+        recentOpr: [oprSchema],
+        name: String,
+        feature:{
+            type: [Schema.Types.Mixed],
+            default: []
+        }
+    }, {versionKey: false}
+);
+
+mongoose.model("std_project_feature_lib", project_feature_lib,"std_project_feature_lib");

+ 1 - 0
modules/bills_template_lib/controllers/bills_template_controller.js

@@ -47,6 +47,7 @@ class BillsTemplateController extends BaseController {
 
         }catch (err){
             console.log(err);
+            result.message = err.message;
         }
         response.json(result);
     }

+ 0 - 4
modules/material_replace_lib/controllers/material_replace_controller.js

@@ -24,7 +24,6 @@ class ReplaceController extends BaseController{
         };
         response.render("maintain/material_replace_lib/html/main", randerData);
     }
-
     async edit(request,response){
         //先取出替换库信息:
         let libID = request.params.libID;
@@ -54,7 +53,6 @@ class ReplaceController extends BaseController{
             response.redirect(request.headers.referer);
         }
     }
-
     async findLib(request, response){
         let result={
             error:0
@@ -131,7 +129,6 @@ class ReplaceController extends BaseController{
         }
         response.json(result);
     }
-
     async saveMaterial(request,response){
         let result={
             error:0
@@ -148,7 +145,6 @@ class ReplaceController extends BaseController{
         }
         response.json(result);
     }
-
     async findMaterial (request,response){
         let result={
             error:0

+ 0 - 10
modules/material_replace_lib/facade/material_replace_facade.js

@@ -78,10 +78,6 @@ let materialReplaceLib = {
        return  await replaceMaterialModel.find({billsItemID:billsID});
     }
 };
-
-
-
-
 function prepareDatas(data) {//整理数据
     let addList = [],updateList =[],deleteList=[];
     for(let d of data){
@@ -91,7 +87,6 @@ function prepareDatas(data) {//整理数据
     }
     return [addList,updateList,deleteList]
 }
-
 async function addMaterial(datas) {
     let newMaterial = [],missCodes=[];
     for(let d of datas){
@@ -117,7 +112,6 @@ async function addMaterial(datas) {
     }
     return {type:'add',list:newMaterial,missCodes:missCodes};
 }
-
 async function replaceMaterial(datas) {
     let tasks = [],list=[],missCodes = [];
     for(let d of datas){
@@ -136,7 +130,6 @@ async function replaceMaterial(datas) {
     if(tasks.length > 0) await replaceMaterialModel.bulkWrite(tasks);
     return {type:'update',list:list,missCodes:missCodes};
 }
-
 async function deleteMaterial(datas) {
     let IDList = [];
     for(let d of datas){
@@ -145,7 +138,6 @@ async function deleteMaterial(datas) {
     await replaceMaterialModel.deleteMany({ID:{"$in": IDList}});
     return {type:'delete',list:IDList};
 }
-
 async function addBills(datas) {
     let newBills = [],missCodes=[];
     for(let d of datas){
@@ -168,7 +160,6 @@ async function addBills(datas) {
     }
     return {type:'add',list:newBills,missCodes:missCodes};
 }
-
 async function updateBills(datas) {
     let tasks = [],list=[],missCodes = [];
     for(let d of datas){
@@ -195,7 +186,6 @@ async function updateBills(datas) {
     if(tasks.length > 0) await replaceBillModel.bulkWrite(tasks);
     return {type:'update',list:list,missCodes:missCodes};
 }
-
 async function deleteBills(datas) {
     let IDList = [];
     for(let d of datas){

+ 99 - 0
modules/project_feature_lib/controllers/project_feature_controller.js

@@ -0,0 +1,99 @@
+/**
+ * Created by zhang on 2018/9/3.
+ */
+import BaseController from "../../common/base/base_controller";
+import featureFacade from "../facade/project_feature_facade";
+let config = require("../../../config/config.js");
+
+class FeatureController extends BaseController{
+    async main(request, response) {
+        let featureLibs = await featureFacade.findByCondition({},{feature:0},false);
+        let randerData = {
+            title:'工程特征库',
+            userAccount: request.session.managerData.username,
+            userID: request.session.managerData.userID,
+            featureLibs:featureLibs,
+            layout: 'maintain/common/html/layout'
+        };
+        response.render("maintain/project_feature_lib/html/main", randerData);
+    }
+    async addLib(request, response){
+        try {
+            await featureFacade.addLib(request.body);
+        }catch (error) {
+            console.log(error);
+        }
+        response.redirect(request.headers.referer);
+    }
+    async findLib(request, response){
+        let result={
+            error:0
+        };
+        try {
+            let data = request.body.data;
+            data = JSON.parse(data);
+            let conditions={'ID' : data.ID};
+            let resultData = await featureFacade.findByCondition(conditions);
+            result.data=resultData;
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        response.json(result);
+    }
+    async saveLib(request, response){
+        let result={
+            error:0
+        };
+        try {
+            let data = request.body.data;
+            data = JSON.parse(data);
+            let resultData= await featureFacade.saveLib(data);
+            result.data=resultData;
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        response.json(result);
+    }
+    async deleteLibByID(request,response){
+        let result={
+            error:0
+        };
+        try {
+            let data = request.body.data;
+            data = JSON.parse(data);
+            let resultData= await featureFacade.deleteLibByID(data.ID);
+            result.data=resultData;
+        }catch (err){
+            console.log(err);
+            result.error=1;
+            result.message = err.message;
+        }
+        response.json(result);
+    }
+    async edit(request,response){
+        //先取出替换库信息:
+        let libID = request.params.libID;
+        let featureLib = await featureFacade.findByCondition({'ID':libID});
+        if(featureLib){
+            let randerData = {
+                title:'工程特征库',
+                mainURL:'/projectFeature/main',
+                libName:featureLib.name,
+                userAccount: request.session.managerData.username,
+                userID: request.session.managerData.userID,
+                featureList:JSON.stringify(featureLib.feature),
+                libID:libID,
+                LicenseKey:config.getLicenseKey(process.env.NODE_ENV),
+                layout: 'maintain/common/html/edit_layout'
+            };
+            response.render("maintain/project_feature_lib/html/edit", randerData);
+        }else {
+            response.redirect(request.headers.referer);
+        }
+    }
+}
+export default FeatureController;

+ 38 - 0
modules/project_feature_lib/facade/project_feature_facade.js

@@ -0,0 +1,38 @@
+/**
+ * Created by zhang on 2018/9/3.
+ */
+import mongoose from "mongoose";
+const uuidV1 = require('uuid/v1');
+let moment = require("moment");
+let projectFeatureModel = mongoose.model('std_project_feature_lib');
+
+
+let projectFeatureLib = {
+    findByCondition:async function(conditions,options,single=true){
+        if(single == true){
+            return await projectFeatureModel.findOne(conditions,options);
+        }else {
+            return await  projectFeatureModel.find(conditions,options);
+        }
+    },
+    addLib : async function (data){
+        let now = new Date().getTime();
+        let dateStr = moment(now).format('YYYY-MM-DD HH:mm:ss');
+        let newLib = {
+            creator: data.userAccount,
+            createDate: now,
+            recentOpr: [{operator: data.userAccount, operateDate: dateStr}],
+            name: data.name,
+        };
+        newLib.ID = uuidV1();
+        return await projectFeatureModel.create(newLib);
+    },
+    saveLib:async function(param) {
+        return await projectFeatureModel.findOneAndUpdate(param.query,param.data,{new:true});
+    },
+    deleteLibByID:async function(ID){
+        return await projectFeatureModel.deleteOne({ID:ID});
+    },
+};
+
+export default projectFeatureLib

+ 29 - 0
modules/project_feature_lib/routes/project_feature_router.js

@@ -0,0 +1,29 @@
+/**
+ * Created by zhang on 2018/9/3.
+ */
+
+let express = require("express");
+let featureRouter =express.Router();
+import FeatureController from "../controllers/project_feature_controller";
+let featureController = new FeatureController();
+
+module.exports =function (app){
+
+    featureRouter.get("/main", featureController.auth, featureController.init, featureController.main);
+    featureRouter.post("/addLib", featureController.auth, featureController.init, featureController.addLib);
+    featureRouter.post("/findLib", featureController.auth, featureController.init, featureController.findLib);
+    featureRouter.post("/saveLib", featureController.auth, featureController.init, featureController.saveLib);
+    featureRouter.post("/deleteLibByID", featureController.auth, featureController.init, featureController.deleteLibByID);
+    featureRouter.get("/edit/:libID", featureController.auth, featureController.init, featureController.edit);
+/*    repRouter.get("/edit/:libID", replaceController.auth, replaceController.init, replaceController.edit);
+    repRouter.post("/findLib", replaceController.auth, replaceController.init, replaceController.findLib);
+    repRouter.post("/addLib", replaceController.auth, replaceController.init, replaceController.addLib);
+    repRouter.post("/saveLib", replaceController.auth, replaceController.init, replaceController.saveLib);
+    repRouter.post("/deleteLibByID", replaceController.auth, replaceController.init, replaceController.deleteLibByID);
+    repRouter.post("/saveBills", replaceController.auth, replaceController.init, replaceController.saveBills);
+    repRouter.post("/saveMaterial", replaceController.auth, replaceController.init, replaceController.saveMaterial);
+    repRouter.post("/findMaterial", replaceController.auth, replaceController.init, replaceController.findMaterial);*/
+    app.use("/projectFeature", featureRouter);
+};
+
+

+ 53 - 0
public/web/id_tree.js

@@ -519,6 +519,32 @@ var idTree = {
             }
             return node;
         };
+        Tree.prototype.m_insert = function (datas,parentID, nextSiblingID) {
+           // var newID = this.newNodeID(), node = null, data = {};
+            var parent = parentID == -1 ? null : this.nodes[this.prefix + parentID];
+            var nextSibling = nextSiblingID == -1 ? null: this.nodes[this.prefix + nextSiblingID];
+            let preInsertNode = null,nodes = [];
+            for(let d of datas){
+                let node = new Node(this,d);
+                if(preInsertNode == null){
+                    if (nextSibling) {
+                        tools.addNodes(this, parent, [node], nextSibling.siblingIndex());
+                    } else {
+                        tools.addNodes(this, parent, [node]);
+                    }
+                }else {
+                    tools.addNodes(this, parent, [node], preInsertNode.siblingIndex());
+                }
+                this.nodes[this.prefix + d.ID] = node;
+                preInsertNode = node;
+                nodes.push(node);
+            }
+            tools.sortTreeItems(this);
+            return nodes;
+        };
+
+
+
         Tree.prototype.insertByID = function (newID, parentID, nextSiblingID) {
             var node = null, data = {};
             var parent = parentID == -1 ? null : this.nodes[this.prefix + parentID];
@@ -557,6 +583,33 @@ var idTree = {
             }
             return data;
         };
+        //插入多行
+        Tree.prototype.getInsertDatas = function (rowCount,parentID, nextSiblingID) {
+            let data = [],preInsertID = null,lastID;
+            let parent = parentID == -1 ? null : this.nodes[this.prefix + parentID];
+            let nextSibling = nextSiblingID == -1 ? null: this.nodes[this.prefix + nextSiblingID];
+            for(let i=0;i<rowCount ;i++){//先插入的在最后,后插的在最前
+                let newID = this.newNodeID();
+                if(newID !== -1){
+                    if(preInsertID == null){//说明是第一个插入的
+                        data.push({type: 'new', data: this.getDataTemplate(newID, parent ? parent.getID() : this.setting.rootId, nextSibling ? nextSibling.getID() : this.setting.rootId)});
+                    }else {//其它的下一节点ID取上一个插入的节点
+                        data.push({type: 'new', data: this.getDataTemplate(newID, parent ? parent.getID() : this.setting.rootId, preInsertID)});
+                    }
+                    this.maxNodeID(newID);
+                    preInsertID = newID;
+                }
+            }
+            if (nextSibling && nextSibling.preSibling) {
+                tools.addUpdateDataForNextSibling(data, nextSibling.preSibling, preInsertID);
+            } else if (parent && parent.children.length !== 0) {
+                tools.addUpdateDataForNextSibling(data, parent.lastChild(), preInsertID);
+            } else if (!parent && this.roots.length !== 0) {
+                tools.addUpdateDataForNextSibling(data, this.roots[this.roots.length - 1], preInsertID);
+            }
+            return data;
+
+        };
         Tree.prototype.insertByData = function (data, parentID, nextSiblingID) {
             var parent = parentID == -1 ? null : this.nodes[this.prefix + parentID];
             var nextSibling = nextSiblingID == -1 ? null : this.nodes[this.prefix + nextSiblingID];

+ 25 - 0
public/web/tree_sheet/tree_sheet_controller.js

@@ -42,6 +42,31 @@ var TREE_SHEET_CONTROLLER = {
                 }
             }
         };
+        controller.prototype.m_insert = function (datas) {
+            let nodes = [], that = this,  sels = this.sheet.getSelections();
+            if(this.tree){
+                if (this.tree.selected) {
+                    nodes = this.tree.m_insert(datas,this.tree.selected.getParentID(), this.tree.selected.getNextSiblingID());
+                } else {
+                    nodes = this.tree.m_insert(datas);
+                }
+            }
+            let length = nodes.length;
+            if (nodes.length > 0) {
+                TREE_SHEET_HELPER.massOperationSheet(this.sheet, function () {
+                    that.sheet.addRows(nodes[length - 1].serialNo(), length);
+                    TREE_SHEET_HELPER.refreshTreeNodeData(that.setting, that.sheet, nodes, false);
+                    that.setTreeSelected(nodes[length - 1]);
+                    that.sheet.setSelection(nodes[length - 1].serialNo(), sels[0].col, 1, 1);
+                    //that.sheet.showRow(newNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
+                });
+            }
+
+
+
+        };
+
+
         controller.prototype.insertByID = function (ID) {
             var newNode = null, that = this,  sels = this.sheet.getSelections();
             if (this.tree) {

+ 30 - 0
web/maintain/bill_template_lib/html/edit.html

@@ -16,6 +16,7 @@
                         <a href="" class="btn btn-sm"><i class="fa fa-scissors" aria-hidden="true"></i> 剪切</a>
                         <a href="" class="btn btn-sm"><i class="fa fa-clipboard" aria-hidden="true"></i> 粘贴</a>
                         <a href="javascript:void(0)" class="btn btn-sm" id="insert"><i class="fa fa-sign-in" aria-hidden="true"></i> 插入</a>
+                        <a href="javascript:void(0)" class="btn btn-sm" id="m_insert" data-toggle="modal" data-target="#insertInputDiv"><i class="fa fa-sign-in" aria-hidden="true"></i> 插入多行</a>
                         <a href="javascript:void(0)" class="btn btn-sm" id="delete"><i class="fa fa-remove" aria-hidden="true"></i> 删除</a>
                         <a href="javascript:void(0)" class="btn btn-sm" id="upLevel"><i class="fa fa-arrow-left" aria-hidden="true"></i> 升级</a>
                         <a href="javascript:void(0)" class="btn btn-sm" id="downLevel"><i class="fa fa-arrow-right" aria-hidden="true"></i> 降级</a>
@@ -30,6 +31,35 @@
     </div>
 </div>
 
+<!--弹出插入多行对话框-->
+<div class="modal fade" id="insertInputDiv" data-backdrop="static" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">插入多行</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form>
+                    <div class="form-group">
+                        <label>插入行数</label>
+                        <input id="insertCount" class="form-control" placeholder="行数" type="number" min="1" value="1" step="1">
+                        <small class="form-text text-danger" id="insertError" style="display: none">请输入正确的行数。</small>
+                        <input id="libID" type="hidden">
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <a id="m_insert_confirm" href="javascript: void(0);" class="btn btn-primary" >确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+
 <script>
     let billsTemplateData = '<%- billsTemplateData %>';
     let billsFixedFlagList = '<%- billsFixedFlagList %>';

+ 61 - 2
web/maintain/bill_template_lib/js/bills_template_edit.js

@@ -229,6 +229,7 @@ $(document).ready(function () {
         datas.forEach(function (data) {
             let node = tree.findNode(data.data.ID);
             if (node) {
+                setFlagsIndex(data.data,node.data.flagsIndex);
                 $.extend(true, node.data, data.data);
             }
         });
@@ -301,16 +302,26 @@ $(document).ready(function () {
             setFee(data.data, fieldName, value);
         }
     };
+    let setFlagsIndex = function (data,flagsIndex) {
+        if (data.flags) {
+            flagsIndex?data.flagsIndex = flagsIndex:data.flagsIndex={};
+            for (let flag of data.flags) {
+                data.flagsIndex[flag.fieldName] = flag;
+            }
+        }
+    };
+
 
     billsTemplateData = billsTemplateData.replace(/\n/g, '\\n');
     let templateData = JSON.parse(billsTemplateData);
     for (let data of templateData) {
-        if (data.flags) {
+        setFlagsIndex(data);
+       /* if (data.flags) {
             data.flagsIndex = {};
             for (let flag of data.flags) {
                 data.flagsIndex[flag.fieldName] = flag;
             }
-        }
+        }*/
     }
 
     for (col of TEMPLATE_BILLS_SETTING.cols) {
@@ -429,6 +440,54 @@ $(document).ready(function () {
             $(me).removeClass('disabled');
         }
     });
+
+    $('#m_insert_confirm').click(function () {
+        let me = this;
+        let insertCount = $("#insertCount").val();
+        if(isNaN(insertCount)||insertCount<1){
+            $("#insertError").show();
+            return;
+        }
+        $(me).addClass('disabled');
+        let selected = controller.tree.selected, updateData;
+        if (selected) {
+            updateData = controller.tree.getInsertDatas(insertCount,selected.getParentID(), selected.getNextSiblingID());
+        } else {
+            updateData = controller.tree.getInsertDatas(insertCount);
+        }
+        if (updateData.length > 0) {
+            CommonAjax.post(updateUrl, updateData, function (data) {
+                data = _.filter(data,{'type':'new'});
+                console.log(data);
+                //controller.insert();
+                //controller.showTreeData();
+                $(me).removeClass('disabled');
+            });
+        } else {
+            alert('新增节点失败, 请重试.');
+            $(me).removeClass('disabled');
+        }
+
+      /*  var selected = controller.tree.selected, updateData;
+        if (selected) {
+            updateData = controller.tree.getInsertData(selected.getParentID(), selected.getNextSiblingID());
+        } else {
+            updateData = controller.tree.getInsertData();
+        }
+        if (updateData.length > 0) {
+            CommonAjax.post(updateUrl, updateData, function (data) {
+                controller.insert();
+                controller.showTreeData();
+                $(me).removeClass('disabled');
+            });
+        } else {
+            alert('新增节点失败, 请重试.');
+            $(me).removeClass('disabled');
+        }*/
+    });
+
+
+
     $('#delete').click(function () {
         let me = this;
         $(me).addClass('disabled');

+ 40 - 0
web/maintain/project_feature_lib/html/edit.html

@@ -0,0 +1,40 @@
+<nav class="navbar navbar-toggleable-lg justify-content-between navbar-light p-0 second_header">
+    <ul class="nav nav-tabs" role="tablist">
+        <li class="nav-item">
+            <a class="nav-link active px-3" href="javascript: void(0);">工程特征</a>
+        </li>
+    </ul>
+</nav>
+
+<div class="main">
+    <div class="content" >
+        <div class="container-fluid" >
+        <div class=" col-lg-12 p-0">
+            <!--<nav class="navbar sticky-top navbar-toggleable-md navbar-light bg-faded tools-bar">
+                <div class="collapse navbar-collapse" id="navbarNav">
+                    <div class="tools-btn btn-group align-top">
+                        <a href="javascript:void(0)" class="btn btn-sm" id="insert"><i class="fa fa-sign-in" aria-hidden="true"></i> 插入</a>
+                        <a href="javascript:void(0)" class="btn btn-sm" id="delete"><i class="fa fa-remove" aria-hidden="true"></i> 删除</a>
+                    </div>
+                </div>
+            </nav>-->
+            <div class="main-data" id="featureSpread"></div>
+        </div>
+        </div>
+        <input type="hidden" id="libID" value="<%= libID %>">
+    </div>
+</div>
+
+
+
+<script type="text/javascript">
+    //自适应高度
+    $(".main-data").height($(window).height()-$(".header").height()-$(".navbar").height());//-$(".tools-bar").height()
+    let billsList = '<%- featureList %>';
+
+</script>
+<script type="text/javascript" src="/lib/jquery-contextmenu/jquery.contextMenu.js"></script>
+<script type="text/javascript" src="/public/web/sheet/sheet_common.js"></script>
+<script type="text/javascript" src="/public/web/sheet/sheet_data_helper.js"></script>
+
+<script type="text/javascript" src="/web/maintain/project_feature_lib/js/project_feature_edit.js"></script>

+ 108 - 0
web/maintain/project_feature_lib/html/main.html

@@ -0,0 +1,108 @@
+<div class="main">
+    <div class="content">
+        <div class="container-fluid">
+            <div class="row">
+                <div class="col-md-5">
+                    <div class="warp-p2 mt-3">
+                        <table class="table table-hover table-bordered">
+                            <thead><tr><th >库名称</th><th width="160">添加时间</th><th width="120">操作</th></tr></thead>
+                            <tbody id="showArea">
+                            <% for(let lib of featureLibs){ %>
+                            <tr class="libTr">
+                                <td id="<%= lib.ID%>"><a href="/projectFeature/edit/<%= lib.ID%>"><%= lib.name%></a></td>
+                                <td><%= moment(lib.createDate).format('YYYY-MM-DD')%></td>
+                                <td>
+                                    <a style="color: #0275d8" onclick='getFeatureLib("<%= lib.ID%>")' title="编辑"><i class="fa fa-pencil-square-o"></i></a>
+                                    <a style="color: #0275d8" onclick='showDeleteModal("<%= lib.ID%>")' class="text-danger" title="删除"><i class="fa fa-remove"></i></a>
+                                </td>
+                            </tr>
+                            <% } %>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!--弹出添加-->
+<div class="modal fade" id="add" data-backdrop="static" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">添加工程特征换库</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form id="addLibForm" method="post" action="/projectFeature/addLib" enctype="application/x-www-form-urlencoded21">
+                    <div class="form-group">
+                        <label>库名称</label>
+                        <input id="name" name="name" class="form-control" placeholder="请输入特征库名称" type="text">
+                        <small class="form-text text-danger" id="nameError" style="display: none">请输入特征库名称。</small>
+                    </div>
+                    <input type="hidden" name = "userAccount" value="<%= userAccount%>">
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button id="addLibs"  class="btn btn-primary">新建</button>
+                <button type="button" id="cancelBtn" class="btn btn-secondary" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!--弹出编辑-->
+<div class="modal fade" id="edit" data-backdrop="static" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">工程特征库库</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form>
+                    <div class="form-group">
+                        <label>工程特征库名称</label>
+                        <input id="renameText" class="form-control" placeholder="输入名称" type="text" value="">
+                        <small class="form-text text-danger" id="renameError" style="display: none">请输入名称。</small>
+                        <input id="libID" type="hidden">
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <a id="rename" href="javascript: void(0);" class="btn btn-primary" >确定</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!--弹出删除-->
+<div class="modal fade" id="del" data-backdrop="static" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">删除确认</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <h5 class="text-danger">删除后无法恢复,确认是否删除?</h5>
+                <input type="hidden" id="libID_del">
+                <input type="hidden" id="delCount">
+            </div>
+            <div class="modal-footer">
+                <a id="delete" href="javascript:void(0);" class="btn btn-danger" >确认</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script type="text/javascript" src="/web/maintain/project_feature_lib/js/project_feature.js"></script>

+ 76 - 0
web/maintain/project_feature_lib/js/project_feature.js

@@ -0,0 +1,76 @@
+/**
+ * Created by zhang on 2018/9/3.
+ */
+$(document).ready(function() {
+    // 保存按钮
+    $("#addLibs").click(async function() {
+        let name = $('#name').val();
+        if(name==''){
+            $("#nameError").show();
+            return;
+        }else {
+            $("#addLibs").attr("disabled",true);//防止重复提交
+            $("#addLibForm").submit();
+        }
+    });
+
+    $("#rename").click(async function() {
+        let libID = $("#libID").val();
+        let name = $('#renameText').val();
+        if(libID!=''){
+            if(name ==''){
+                $("#renameError").show();
+                return;
+            }else {
+                try {
+                    let newFeature = await ajaxPost("/projectFeature/saveLib",{query:{ID:libID},data:{name:name}});
+                    $("#"+libID).children("a").text(newFeature.name);
+                    $("#edit").modal('hide');
+                }catch(err) {
+                    console.log(err);
+                }
+            }
+        }
+    });
+
+    $("#delete").click(async function() {
+        let libID = $("#libID_del").val();
+        let delCount = parseInt($("#delCount").val());
+        delCount = delCount+1;
+        $("#delCount").val(delCount);
+        if(delCount == 3){
+            if(libID!=""){
+                try {
+                    let result = await ajaxPost("/projectFeature/deleteLibByID",{ID:libID});
+                    if(result.ok){
+                        $("#"+libID).parent(".libTr").remove();
+                    }
+                    $("#del").modal('hide');
+                }catch (err){
+                    console.log(err);
+                }
+            }
+        }
+    });
+});
+
+async function getFeatureLib (ID) {
+    try {
+        let lib = await ajaxPost("/projectFeature/findLib",{ID:ID});
+        if(lib){
+            $("#renameText").val(lib.name);
+            $("#libID").val(ID);
+            $("#edit").modal({show:true});
+        }else {
+            alert("没有找到材料库");
+        }
+    }catch (err){
+        console.log(err);
+    }
+}
+
+function showDeleteModal(ID){
+    $("#libID_del").val(ID);
+    $("#delCount").val(0);
+    $("#del").modal({show:true});
+}

+ 37 - 0
web/maintain/project_feature_lib/js/project_feature_edit.js

@@ -0,0 +1,37 @@
+/**
+ * Created by zhang on 2018/9/3.
+ */
+featureObj = {
+    featureSpread:null,
+    featureSheet:null,
+    setting:{
+        header: [
+            {headerName: "显示名称", headerWidth: 180, dataCode: "dispName", dataType: "String",formatter: "@"},
+            {headerName: "取值属性", headerWidth: 240, dataCode: "key", dataType: "String"},
+            {headerName: "单元格类型", headerWidth: 240, dataCode: "type", dataType: "String"}
+            //{headerName: "规则", headerWidth: 150, dataCode: "rule", hAlign: "left", dataType: "String",cellType:'comboBox',editorValueType:true,options:[{text:"规则1",value:1},{text:"规则2",value:2}]}
+        ],
+        view: {
+            lockColumns: []
+        },
+        headerHeight:45
+    },
+    initSpread:function () {
+        if(!this.featureSpread){
+            this.featureSpread = SheetDataHelper.createNewSpread($("#featureSpread")[0]);
+        }
+        this.featureSheet = this.featureSpread .getSheet(0);
+        sheetCommonObj.initSheet(this.featureSheet,this.setting, 30);
+        this.billsSheet.name('billsSheet');
+        this.billsSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onBillsValueChange);
+        this.billsSheet.bind(GC.Spread.Sheets.Events.SelectionChanged,this.onBillsSelectionChange);
+        this.billsSheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onBillsRangeChange);
+
+        //this.initRightClick("billsSpread",this.billsSpread);
+
+
+
+    }
+};
+
+featureObj.initSpread();

+ 10 - 0
web/users/css/custom.css

@@ -6,6 +6,16 @@
 .engineeringInput {
   -moz-appearance: textfield;
 }
+
+.none_number_step::-webkit-outer-spin-button,
+.none_number_step::-webkit-inner-spin-button {
+  -webkit-appearance: none;
+}
+.none_number_step {
+  -moz-appearance: textfield;
+}
+
+
 .btn-link:focus, .btn-link:hover{
   text-decoration: none
 }

+ 7 - 0
web/users/views/tool/index.html

@@ -69,6 +69,13 @@
                     </h2>
                 </div>
             </div>
+            <div class="col-xs-6 mb-30 ">
+                <div class="c-body">
+                    <h2>工程特征库
+                        <a id="projectFeature" href="/projectFeature/main" target="_blank" class="btn btn-primary pull-right">进入</a>
+                    </h2>
+                </div>
+            </div>
         </div>
     </div>
 </div>