index.js 11.4 KB
Newer Older
Scott Sun's avatar
s  
Scott Sun committed
1 2
var fs = require('fs');
var book = require('topsin.excelxs');
Scott Sun's avatar
s  
Scott Sun committed
3
var db = require('topsin.database');
Scott Sun's avatar
s  
Scott Sun committed
4
var crypto = require('topsin.crypto');
Scott Sun's avatar
s  
Scott Sun committed
5
var error = require('topsin.error');
Scott Sun's avatar
s  
Scott Sun committed
6

Scott Sun's avatar
s  
Scott Sun committed
7
// 读取配置文件
Scott Sun's avatar
s  
Scott Sun committed
8 9 10
var config = JSON.parse(fs.readFile('./config.json'));

// 主函数
Scott Sun's avatar
s  
Scott Sun committed
11 12
function Main(props){
    // 执行初始化
Scott Sun's avatar
s  
Scott Sun committed
13
    this.init();
Scott Sun's avatar
s  
Scott Sun committed
14 15 16 17 18 19 20
}
// 初始化方法
Main.prototype.init = function(){
    this.dirlist = this.readDir(config.dirPath, -1)  // 获取文件夹下的文件列表
    if(this.dirlist.length === 0){  // 没有文件就退出
        return
    }
Scott Sun's avatar
s  
Scott Sun committed
21
    this.readXlsx(this.dirlist) // 循环读取文件列表
Scott Sun's avatar
s  
Scott Sun committed
22 23 24 25 26 27 28 29 30
}
// 读取文件夹 获取xlsx
Main.prototype.readDir = function(path){
    return fs.listDir(path).filter(function(v){return v.completeSuffix === "XLSX"})
}
// 循环读取文件列表 
Main.prototype.readXlsx = function(list){
    var that = this
    list.forEach(function(v){
Scott Sun's avatar
s  
Scott Sun committed
31
        // 读取excel文件
Scott Sun's avatar
s  
Scott Sun committed
32 33 34 35 36 37 38 39 40 41 42
        that.excelxs(v.dir + '/' + v.name, v.name)
    })
}
// 读取excelxs
Main.prototype.excelxs = function(path,name){
    if(book.open(path)) {
        var sheet = book.getActiveSheet()  // 获取当前表
        if(sheet.isNull()){return}
        // 获取表字段数量
        var keysCount = sheet.getLastCol()
        // 获取字段数组
Scott Sun's avatar
s  
Scott Sun committed
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
        this.keys = [] // 存放所有字段
        this.newkeys = []  // (如果有)存放新的字段
        this.attrData = config.dataKeys["attr_data"]  // 存放 attr_data
        for(var i=0;i<keysCount;i++){  // 读取第一行的字段
            if(config.dataKeys[crypto.md5(sheet.getCellValue(0, i))]){  // 如果是之前存在的字段 直接放入keys 以md5加密作为中介
                this.keys.push(config.dataKeys[crypto.md5(sheet.getCellValue(0, i))].dbkey)
            } else {  // 读取不到的字段 可能是attr_data下的 也可能是新增的
                if(!this.attrData[crypto.md5(sheet.getCellValue(0, i))]){  // 在attr_data下读取 不存在的是新增的
                    this.newkeys.push(sheet.getCellValue(0, i)) // 给newkeys添加新增的字段
                }
            }
        }
        this.keys.push('attr_data') // keys添加上 attr_data
        var that = this
        if(this.newkeys.length !== 0){ // 如果有新增的字段 
            this.newkeys.forEach(function(v){
                var mdkey = crypto.md5(v)  // md5状态
                var dbkeyArr = []
                var str = ""
                var tempv = v + " "
                for(var i = 0,len=tempv.length;i<len;i++){  // 数据库字段 命名规则
                    if(/[a-zA-Z]/.test(tempv[i])){
                        str += tempv[i].toLowerCase()
                    } else if(tempv[i] === " " || tempv[i] === "\n"){
                        dbkeyArr.push(str)
                        str = ""
                    } else {
Scott Sun's avatar
s  
Scott Sun committed
70
                        i = len
Scott Sun's avatar
s  
Scott Sun committed
71 72 73
                    }
                }
                var dbkey = dbkeyArr.join("_") 
Scott Sun's avatar
s  
Scott Sun committed
74
                dbkey += "_" + mdkey.substr(0,10)
Scott Sun's avatar
s  
Scott Sun committed
75 76 77 78 79 80 81 82 83
                that.attrData[mdkey] = {  // 内存中的attrData添加新字段的map
                    name:v,
                    dbkey: dbkey
                }
                config.dataKeys["attr_data"][mdkey] = { // 配置里也要添加
                    name:v,
                    dbkey: dbkey
                }
            })
Scott Sun's avatar
s  
Scott Sun committed
84 85 86 87
        }
        var datalist = []  // 定义数组 两次循环获取表数据
        for(var j = 1,length = sheet.getLastRow();j<length;j++){
            datalist[j-1] = {}
Scott Sun's avatar
s  
Scott Sun committed
88
            datalist[j-1]["attr_data"] = {}  // 对attr_data的处理
Scott Sun's avatar
s  
Scott Sun committed
89
            for(var i = 0;i<keysCount;i++){
Scott Sun's avatar
s  
Scott Sun committed
90 91 92 93 94 95 96 97
                // dbkey 是 对应到数据库的key
                var dbkey = config.dataKeys[crypto.md5(sheet.getCellValue(0, i))] ? config.dataKeys[crypto.md5(sheet.getCellValue(0, i))].dbkey : null
                if(dbkey === "posting_date"){  // 对日期的特殊处理
                    datalist[j-1][dbkey] = formatDate(sheet.getCellValue(j, i))
                } else if (dbkey === "confirmation_entry_time") { // 对时间的特殊处理
                    datalist[j-1][dbkey] = formatTime(sheet.getCellValue(j, i))
                } else if(!config.dataKeys[crypto.md5(sheet.getCellValue(0, i))]) { // 对attr_data字段的特殊处理
                    datalist[j-1]["attr_data"][this.attrData[crypto.md5(sheet.getCellValue(0, i))].dbkey] = sheet.getCellValue(j, i)
Scott Sun's avatar
s  
Scott Sun committed
98
                } else {
Scott Sun's avatar
s  
Scott Sun committed
99
                    datalist[j-1][dbkey] = sheet.getCellValue(j, i)
Scott Sun's avatar
s  
Scott Sun committed
100 101 102 103 104 105 106 107
                }
            }
        }
        // 数据处理
        this.paytionType({
            datalist:datalist
        })
        book.saveAs(config.rdir + '/' + name)  // 读取完的文件另存为 然后可以删除
Scott Sun's avatar
s  
Scott Sun committed
108 109 110
        // 删除处理过的文件
        fs.unlink(path)
        book.close()
Scott Sun's avatar
s  
Scott Sun committed
111 112 113 114 115 116 117 118
    }
}
Main.prototype.paytionType = function(props){  // 处理数据
    db.addConnection(config.dbconfig, "Scott_PMO_TRAINING");  // 连接数据库
    this.tablename = 'sec_production_order_confirmation_2'  // 设置数据库表名
    this.query = db.query('Scott_PMO_TRAINING');  // 获取操作对象
    var dbDatas = getDbData(this.query,this.tablename)  // 获取数据库的所有数据
    if(!dbDatas){return}
Scott Sun's avatar
s  
Scott Sun committed
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
    console.log("数据库的数据数量:" + dbDatas.length)
    if(this.newkeys.length === 0){ // 不存在新的字段 只要新增就行
        console.log("插入操作");
        var res = this.filterOldData(props.datalist,dbDatas)  // 数据过滤
        var newData = res.newData // 获取要插入的数据
        console.log("新的数据:"+newData.length);
        console.log(newData[0]);
        // console.log(this.query.deleteRow({
        //     table:'sec_production_order_confirmation_2',
        //     where: ["id >= 0"]
        // }))   // 删除所有数据
        if(newData.length === 0) {return}
        this.insertAny(newData)  // 插入数据库操作
    } else {  // 对旧的数据执行更新操作 对新的数据执行添加
        console.log('要对字段扩展:')
Scott Sun's avatar
Scott Sun committed
134
        var res = this.filterOldData(props.datalist,dbDatas,"newkey")  // 数据过滤 顺便更新旧的数据
Scott Sun's avatar
s  
Scott Sun committed
135 136 137 138 139 140 141 142
        var newData = res.newData // 获取要插入的数据
        console.log("新的数据:"+newData.length);
        console.log(newData[0]);
        // 插入新数据
        if(newData.length === 0) {
            return
        }
        this.insertAny(newData)  // 插入数据库操作
Scott Sun's avatar
s  
Scott Sun committed
143 144 145 146 147 148
    }

    db.removeConnection('Scott_PMO_TRAINING');  // 移除数据库操作
}
Main.prototype.insertAny = function(datas){ // 批量插入数据
    this.query.begin()
Scott Sun's avatar
s  
Scott Sun committed
149
    var that = this
Scott Sun's avatar
s  
Scott Sun committed
150 151
    try{
        this.query.batchInsert(
Scott Sun's avatar
s  
Scott Sun committed
152 153
            that.tablename,
            that.keys,
Scott Sun's avatar
s  
Scott Sun committed
154 155
            datas
        );
Scott Sun's avatar
s  
Scott Sun committed
156 157 158
        if (this.query.lastError().isValid()){
            throw this.query.lastError().text();
        }
Scott Sun's avatar
s  
Scott Sun committed
159 160 161 162 163 164 165 166 167
        this.query.commit();
    }
    catch(err) {
        console.log("插入数据错误")
        console.log(err)
        this.query.rollback();
    }
}
function getDbData(query,tablename){   // 获取数据库所有数据
Scott Sun's avatar
s  
Scott Sun committed
168
    query.begin();
Scott Sun's avatar
s  
Scott Sun committed
169 170 171 172 173 174
    var data;
    try {
        data = query.selectArrayMap({
            table: tablename,
            field: '*',
            field_format:{"tags":'array', attr_data:'json'}
Scott Sun's avatar
s  
Scott Sun committed
175
        });
Scott Sun's avatar
s  
Scott Sun committed
176 177 178 179 180
        if (query.lastError().isValid()){
            throw query.lastError().text();
        }
        query.commit();
    } catch (error) {
Scott Sun's avatar
s  
Scott Sun committed
181 182
        console.log("获取数据库数据错误");
        console.log(error);
Scott Sun's avatar
s  
Scott Sun committed
183 184 185 186 187 188
        query.rollback();
        // data = false;
    }
    return data
}
// key过滤  根据唯一的key将数据分为两组 一组是新数据 一组是原来的数据
Scott Sun's avatar
s  
Scott Sun committed
189 190 191
Main.prototype.filterOldData = function (datas,dbdatas, type){
    var type = type || null
    console.log("type:"+ type)  // 类型 是否执行字段更新操作
Scott Sun's avatar
s  
Scott Sun committed
192 193 194
    // 获取dbdata的唯一字段列表
    dbI = dbdatas.map(function(v){
        var tempStr = ""
Scott Sun's avatar
s  
Scott Sun committed
195
        tempStr += v["confirmation"] + v["plant"] + v["material"] + v["posting_date"] + v["confirmation_entry_time"] + v["activity"]
Scott Sun's avatar
s  
Scott Sun committed
196 197 198 199 200 201
        return tempStr
    })
    var oldData = [],
        newData = [];
    for(var i = 0,len=datas.length;i<len;i++){
        var v = datas[i]
Scott Sun's avatar
s  
Scott Sun committed
202
        var dataI = v["confirmation"] + v["plant"] + v["material"] + v["posting_date"] + v["confirmation_entry_time"] + v["activity"]
Scott Sun's avatar
s  
Scott Sun committed
203
        if(dbI.indexOf(dataI) >= 0){
Scott Sun's avatar
s  
Scott Sun committed
204
            // 老数据
Scott Sun's avatar
Scott Sun committed
205 206 207 208
            var updateData = {}
            if(type === "newkey"){
                updateData["attr_data"] = v["attr_data"]
                // this.UpdateKeys({"attr_data":},dbdatas[dbI.indexOf(dataI)]["id"]) // 更新
Scott Sun's avatar
s  
Scott Sun committed
209
            }
Scott Sun's avatar
Scott Sun committed
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
            // 判断老数据是否更新了
            for(var key in v){
                if(key==="attr_data"){
                    if(JSON.stringify(v[key]) !== JSON.stringify(dbdatas[dbI.indexOf(dataI)][key])){
                    updateData["attr_data"] = v["attr_data"]
                }
                } else {
                    if(v[key] != dbdatas[dbI.indexOf(dataI)][key]) {
                        updateData[key] = v[key]
                    }
                }
                
            }
            if(JSON.stringify(updateData) !== "{}"){ // 有要更新的情况
                console.log("更新...")
                this.UpdateKeys(updateData,dbdatas[dbI.indexOf(dataI)]["id"])
            }
            oldData.push(v)
Scott Sun's avatar
s  
Scott Sun committed
228 229 230 231 232
        } else{
            // 新数据
            newData.push(v)
        }
    }
Scott Sun's avatar
s  
Scott Sun committed
233 234
    console.log("旧的数据:"+oldData.length)
    console.log(oldData[oldData.length-1]);
Scott Sun's avatar
s  
Scott Sun committed
235 236 237 238 239
    return {
        oldData:oldData,
        newData:newData
    }
}
Scott Sun's avatar
s  
Scott Sun committed
240 241
// 更新数据
Main.prototype.UpdateKeys = function(data,id){
Scott Sun's avatar
Scott Sun committed
242 243
    console.log(data)
    console.log(id)
Scott Sun's avatar
s  
Scott Sun committed
244 245 246 247 248 249 250 251 252 253
    // 执行更新操作
    this.query.begin()
    var that = this
    try {
        this.query.updateRow({
            table:that.tablename,
            data:data,
            where:{id:id},
            update_policy:{tags:'array_append', attr_data:'json_merge'}
        })
Scott Sun's avatar
s  
Scott Sun committed
254 255 256
        if (this.query.lastError().isValid()){
            throw this.query.lastError().text();
        }
Scott Sun's avatar
s  
Scott Sun committed
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
        this.query.commit();
    } catch (error) {
        console.log("更新错误")
        console.log(error)
        this.query.rollback();
    }
}
function formatDate(numb) {
    var time = new Date((numb - 1) * 24 * 3600000 + 1)
    time.setYear(time.getFullYear() - 70)
    var year = time.getFullYear() + ''
    var month = time.getMonth() + 1 + ''
    var date = time.getDate() + ''
    return year + "-" + (month<10?"0"+month:month) + "-" + (date<10?"0"+date:date)
}
function formatTime(numb) {
    var hourTmp = numb * 24;
    var hour = Math.floor(hourTmp);
    var minuteTmp = hourTmp - hour;
    var minute = Math.floor(minuteTmp * 60);
    var secondTmp = (minuteTmp*60) - minute;
    var second = Math.round(secondTmp*60);
    if(second >= 60){
        second = 0
        minute += 1
    }
    if(minute >= 60) {
        minute = minute - 60
        hour += 1
    }
    if(hour >= 24) {
        hour = 0
    }
    return (hour<10? "0" + hour : hour) + ":" + (minute<10? "0" + minute : minute) + ":" + (second<10? "0" + second : second) 
}
function configReset(bol){
    config.isUseing = bol
Scott Sun's avatar
s  
Scott Sun committed
294 295 296
    fs.writeFile('./config.json',JSON.stringify(config)) // 覆盖写入json
}
if(!config.isUseing){  // 如果没在运行程序就可以实例化
Scott Sun's avatar
s  
Scott Sun committed
297
    configReset(true) // 状态变成运行中
Scott Sun's avatar
s  
Scott Sun committed
298
    var demo = new Main()
Scott Sun's avatar
s  
Scott Sun committed
299
    configReset(false)  // 状态变成未运行
Scott Sun's avatar
s  
Scott Sun committed
300 301 302 303 304 305
}



// ["attr_data","action_data","extra_data","tags","sys_tags","sys_data"]