x1ongzhu 6 år sedan
förälder
incheckning
e86b81f3d3

+ 2 - 0
package.json

@@ -25,12 +25,14 @@
     "file-type": "^12.0.0",
     "light-event-bus": "^1.0.1",
     "node-downloader-helper": "^1.0.10",
+    "nodejs-fs-utils": "^1.1.2",
     "pg-hstore": "^2.3.3",
     "qrcode": "^1.3.3",
     "qrcode.vue": "^1.6.2",
     "read-chunk": "^3.2.0",
     "request": "^2.88.0",
     "sequelize": "^5.8.12",
+    "sequelize-cli": "^5.5.0",
     "sharp": "^0.22.1",
     "sqlite3": "^4.0.9",
     "swiper": "^4.5.0",

+ 1 - 1
src/Constants.js

@@ -14,4 +14,4 @@ exports.DownloadStatus = {
     PAUSE: 3,
     FINISHED: 4,
     ERROR: 5
-}
+}

+ 21 - 11
src/components/OrderUpload.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="upload">
+    <div class="upload" v-loading="loading">
         <div class="tr head">
             <div class="td title">
                 <img src="../assets/icon_wenjianjia_02.png" alt>
@@ -13,7 +13,7 @@
                 <span>上传中</span>
             </div>
             <div class="td edit">
-                <img src="../assets/icon_xiazaikaishi_lvxe.png" alt v-if="paused" @click="resume({orderId:orderInfo.id})">
+                <img src="../assets/icon_xiazaikaishi_lvxe.png" alt v-if="orderInfo.pause" @click="resume({orderId:orderInfo.id})">
                 <img src="../assets/icon_xiazaizanting_lvse.png" alt v-else @click="pause({orderId:orderInfo.id})">
             </div>
         </div>
@@ -25,7 +25,7 @@
             <span class="td amount">{{item.fileNum}}</span>
             <span class="td size">
                 <span>{{getSize(item.totalSize*item.progress)}}/{{getSize(item.totalSize)}}</span>
-                
+
             </span>
             <div class="td status" v-if="item.progress===1">
                 <img src="../assets/icon_shangchuanok.png" style="vertical-align: middle;width:24px;height:24px">
@@ -45,7 +45,7 @@
             </div>
             <div class="td edit">
                 <template v-if="item.progress!==1">
-                    <img src="../assets/icon_xiazaikaishi.png" v-if="item.paused" @click="resume({subOrderId:item.id})">
+                    <img src="../assets/icon_xiazaikaishi.png" v-if="item.pause" @click="resume({subOrderId:item.id})">
                     <img src="../assets/icon_xiazaizanting.png" v-else @click="pause({subOrderId:item.id})">
                 </template>
                 <img src="../assets/icon_chakanweizhi.png" alt @click="open(item)">
@@ -61,6 +61,7 @@ import Constants from '../Constants';
 import eventBus from '../service/EventBus';
 import { UploadStatus } from '../Constants';
 import { shell } from 'electron';
+import { setTimeout } from 'timers';
 export default {
     name: 'OrderUpload',
     data() {
@@ -68,6 +69,7 @@ export default {
             colors: ['#29C7EC', '#FFD651', '#80CD82'],
             interval: null,
             subOrders: [],
+            loading: false,
         };
     },
     props: ['orderInfo'],
@@ -83,18 +85,18 @@ export default {
     },
     computed: {
         paused() {
-            let paused = true;
+            let subOrderAllPause = true;
             this.subOrders.forEach(i => {
-                if (i.paused === 0) {
-                    paused = false;
+                if (i.pause === 0) {
+                    subOrderAllPause = false;
                 }
             });
-            return paused;
+            return this.orderInfo.pause || subOrderAllPause;
         },
     },
     methods: {
-        getTips(info){
-            console.log(info)
+        getTips(info) {
+            console.log(info);
             // if(info.dst.indexOf('/original/min/')!=-1){
             //     return '正在上传'+info.name+'的缩略图'
             // }
@@ -124,10 +126,18 @@ export default {
             }
         },
         pause(arg) {
-            eventBus.publish('pause', arg);
+            this.loading = true;
+            FileUploadDownloadService.pause(arg);
+            setTimeout(() => {
+                this.loading = false;
+            }, 1000);
         },
         resume(arg) {
+            this.loading = true;
             FileUploadDownloadService.resume(arg);
+            setTimeout(() => {
+                this.loading = false;
+            }, 1000);
         },
         open(item) {
             shell.openItem(item.path);

+ 150 - 125
src/main.js

@@ -1,25 +1,25 @@
-import Vue from 'vue'
-import axios from 'axios'
-import App from './App'
-import router from './router'
-import store from './store'
+import Vue from 'vue';
+import axios from 'axios';
+import App from './App';
+import router from './router';
+import store from './store';
 import ElementUI from 'element-ui';
 import './theme/index.css';
 import './main.less';
-import Order from './components/Order'
-import PageTitle from './components/PageTitle'
-import OrderImg from './components/Img'
-import OrderTransfer from './components/OrderTransfer'
-import ProgressBar from './components/ProgressBar'
-import Floder from './components/Folder'
-import FileUploadDownloadService from './service/FileUploadDownloadService'
-import darg from './mixin/darg'
-import main from './mixin/main'
+import Order from './components/Order';
+import PageTitle from './components/PageTitle';
+import OrderImg from './components/Img';
+import OrderTransfer from './components/OrderTransfer';
+import ProgressBar from './components/ProgressBar';
+import Floder from './components/Folder';
+import FileUploadDownloadService from './service/FileUploadDownloadService';
+import darg from './mixin/darg';
+import main from './mixin/main';
 
-Vue.http = Vue.prototype.$http = axios
-Vue.config.productionTip = false
+Vue.http = Vue.prototype.$http = axios;
+Vue.config.productionTip = false;
 
-Vue.use(require('vue-electron'))
+Vue.use(require('vue-electron'));
 Vue.use(ElementUI);
 Vue.use(Order);
 Vue.use(PageTitle);
@@ -31,9 +31,7 @@ Vue.component('Floder', Floder);
 Vue.mixin(darg);
 Vue.mixin(main);
 
-
-
-Vue.prototype.$ImgType = ['']
+Vue.prototype.$ImgType = [''];
 
 const baseUrl = `http://49.4.67.181:8206`;
 // const baseUrl = `http://localhost:8080`;
@@ -62,29 +60,34 @@ Vue.prototype.$http = {
             // if (!/^(http:\/\/)|(https:\/\/)/.test(params.url)) {
             //     params.url = baseUrl + params.url;
             // }
-            axios.get(params.url, {
-                params: params.data
-            }, { withCredentials: true }).then(res => {
-                if (res.status === 200) {
-                    resolve(res.data);
-                } else {
-                    reject(res);
-                }
-                try {
-                    if (res.data.code === 10001) {
-                        axios({
-                            method: 'post',
-                            url: '/auth/logout'
-                        });
-                        store.commit('updateUserInfo', null);
-                        router.replace('/login');
+            axios
+                .get(
+                    params.url,
+                    {
+                        params: params.data,
+                    },
+                    { withCredentials: true },
+                )
+                .then(res => {
+                    if (res.status === 200) {
+                        resolve(res.data);
+                    } else {
+                        reject(res);
                     }
-                } catch (e) {
-
-                }
-            }).catch(e => {
-                reject(e);
-            });
+                    try {
+                        if (res.data.code === 10001) {
+                            axios({
+                                method: 'post',
+                                url: '/auth/logout',
+                            });
+                            store.commit('updateUserInfo', null);
+                            router.replace('/login');
+                        }
+                    } catch (e) {}
+                })
+                .catch(e => {
+                    reject(e);
+                });
         });
     },
     post(params) {
@@ -128,27 +131,28 @@ Vue.prototype.$http = {
             }
         }
         return new Promise((resolve, reject) => {
-            axios.post(params.url, data, { withCredentials: true }).then(res => {
-                if (res.status === 200) {
-                    resolve(res.data);
-                } else {
-                    reject(res);
-                }
-                try {
-                    if (res.data.code === 10001) {
-                        axios({
-                            method: 'post',
-                            url: '/auth/logout'
-                        });
-                        store.commit('updateUserInfo', null);
-                        router.replace('/login');
+            axios
+                .post(params.url, data, { withCredentials: true })
+                .then(res => {
+                    if (res.status === 200) {
+                        resolve(res.data);
+                    } else {
+                        reject(res);
                     }
-                } catch (e) {
-
-                }
-            }).catch(e => {
-                reject(e);
-            });
+                    try {
+                        if (res.data.code === 10001) {
+                            axios({
+                                method: 'post',
+                                url: '/auth/logout',
+                            });
+                            store.commit('updateUserInfo', null);
+                            router.replace('/login');
+                        }
+                    } catch (e) {}
+                })
+                .catch(e => {
+                    reject(e);
+                });
         });
     },
     postJ(params) {
@@ -192,29 +196,30 @@ Vue.prototype.$http = {
         //     }
         // }
         return new Promise((resolve, reject) => {
-            axios.post(params.url, params.data, { withCredentials: true }).then(res => {
-                if (res.status === 200) {
-                    resolve(res.data);
-                } else {
-                    reject(res);
-                }
-                try {
-                    if (res.data.code === 10001) {
-                        axios({
-                            method: 'post',
-                            url: '/auth/logout'
-                        });
-                        store.commit('updateUserInfo', null);
-                        router.replace('/login');
+            axios
+                .post(params.url, params.data, { withCredentials: true })
+                .then(res => {
+                    if (res.status === 200) {
+                        resolve(res.data);
+                    } else {
+                        reject(res);
                     }
-                } catch (e) {
-
-                }
-            }).catch(e => {
-                reject(e);
-            });
+                    try {
+                        if (res.data.code === 10001) {
+                            axios({
+                                method: 'post',
+                                url: '/auth/logout',
+                            });
+                            store.commit('updateUserInfo', null);
+                            router.replace('/login');
+                        }
+                    } catch (e) {}
+                })
+                .catch(e => {
+                    reject(e);
+                });
         });
-    }
+    },
 };
 
 //浮点数加减乘除
@@ -227,22 +232,21 @@ Vue.prototype.$calc = {
     返回值:两数相加的结果
     */
     Add: function(arg1, arg2) {
-        console.log(arg1, arg2)
+        console.log(arg1, arg2);
         if (arg1 && arg2) {
-            arg1 = arg1.toString(), arg2 = arg2.toString();
-            var arg1Arr = arg1.split("."),
-                arg2Arr = arg2.split("."),
-                d1 = arg1Arr.length == 2 ? arg1Arr[1] : "",
-                d2 = arg2Arr.length == 2 ? arg2Arr[1] : "";
+            (arg1 = arg1.toString()), (arg2 = arg2.toString());
+            var arg1Arr = arg1.split('.'),
+                arg2Arr = arg2.split('.'),
+                d1 = arg1Arr.length == 2 ? arg1Arr[1] : '',
+                d2 = arg2Arr.length == 2 ? arg2Arr[1] : '';
             var maxLen = Math.max(d1.length, d2.length);
             var m = Math.pow(10, maxLen);
             var result = Number(((arg1 * m + arg2 * m) / m).toFixed(maxLen));
             var d = arguments[2];
-            console.log(d)
-            console.log(result)
-            return typeof d === "number" ? Number((result).toFixed(d)) : result;
+            console.log(d);
+            console.log(result);
+            return typeof d === 'number' ? Number(result.toFixed(d)) : result;
         }
-
     },
     /*
     函数:减法函数,用来得到精确的减法结果  
@@ -267,10 +271,17 @@ Vue.prototype.$calc = {
         if (arg1 && arg2) {
             var r1 = arg1.toString(),
                 r2 = arg2.toString(),
-                m, resultVal, d = arguments[2];
-            m = (r1.split(".")[1] ? r1.split(".")[1].length : 0) + (r2.split(".")[1] ? r2.split(".")[1].length : 0);
-            resultVal = Number(r1.replace(".", "")) * Number(r2.replace(".", "")) / Math.pow(10, m);
-            return typeof d !== "number" ? Number(resultVal) : Number(resultVal.toFixed(parseInt(d)));
+                m,
+                resultVal,
+                d = arguments[2];
+            m =
+                (r1.split('.')[1] ? r1.split('.')[1].length : 0) +
+                (r2.split('.')[1] ? r2.split('.')[1].length : 0);
+            resultVal =
+                (Number(r1.replace('.', '')) * Number(r2.replace('.', ''))) / Math.pow(10, m);
+            return typeof d !== 'number'
+                ? Number(resultVal)
+                : Number(resultVal.toFixed(parseInt(d)));
         }
     },
     /*
@@ -284,20 +295,31 @@ Vue.prototype.$calc = {
         if (arg1 && arg2) {
             var r1 = arg1.toString(),
                 r2 = arg2.toString(),
-                m, resultVal, d = arguments[2];
-            m = (r2.split(".")[1] ? r2.split(".")[1].length : 0) - (r1.split(".")[1] ? r1.split(".")[1].length : 0);
-            resultVal = Number(r1.replace(".", "")) / Number(r2.replace(".", "")) * Math.pow(10, m);
-            return typeof d !== "number" ? Number(resultVal) : Number(resultVal.toFixed(parseInt(d)));
+                m,
+                resultVal,
+                d = arguments[2];
+            m =
+                (r2.split('.')[1] ? r2.split('.')[1].length : 0) -
+                (r1.split('.')[1] ? r1.split('.')[1].length : 0);
+            resultVal =
+                (Number(r1.replace('.', '')) / Number(r2.replace('.', ''))) * Math.pow(10, m);
+            return typeof d !== 'number'
+                ? Number(resultVal)
+                : Number(resultVal.toFixed(parseInt(d)));
         }
-    }
+    },
 };
 
 const updateTableHeight = () => {
     try {
         const total = document.getElementsByTagName('main')[0].clientHeight;
         const width = document.getElementsByTagName('main')[0].clientWidth;
-        store.commit('updatemainHeight', { height: total, width: width, allWidth: window.innerWidth, allHeight: window.innerHeight });
-
+        store.commit('updatemainHeight', {
+            height: total,
+            width: width,
+            allWidth: window.innerWidth,
+            allHeight: window.innerHeight,
+        });
     } catch (e) {
         // console.error(e)
     }
@@ -306,41 +328,44 @@ const updateTableHeight = () => {
 window.onresize = updateTableHeight;
 window.onload = updateTableHeight;
 
-
 new Vue({
     components: { App },
     router,
     store,
     template: '<App/>',
-    mixins: [{
-        methods: {}
-    }]
-}).$mount('#app')
-
+    mixins: [
+        {
+            methods: {},
+        },
+    ],
+}).$mount('#app');
 
 setInterval(() => {
     if (store.state.userInfo && store.state.userInfo.id) {
         FileUploadDownloadService.queryUnfinishedOrder(store.state.userInfo.id).then(orders => {
-            store.commit('updateUploadingOrders', orders)
-        })
+            store.commit('updateUploadingOrders', orders);
+        });
 
-        FileUploadDownloadService.queryUnfinishedDownloadOrder(store.state.userInfo.id).then(list => {
-            store.commit('updateDownloadList', list)
-        })
+        FileUploadDownloadService.queryUnfinishedDownloadOrder(store.state.userInfo.id).then(
+            list => {
+                store.commit('updateDownloadList', list);
+            },
+        );
     }
-
 }, 500);
 
+setTimeout(() => {
+    FileUploadDownloadService.deleteUploadedFile();
+}, 0 * 1000);
 
 setInterval(() => {
     if (store.state.userInfo && store.state.userInfo.id) {
-
-
-        axios.get('/clientNotice/unread?userId=' + store.state.userInfo.id + '&statusFlag=0').then(res => {
-            if (res.data.success) {
-                store.commit('updateTipsNum', res.data.data)
-            }
-        })
+        axios
+            .get('/clientNotice/unread?userId=' + store.state.userInfo.id + '&statusFlag=0')
+            .then(res => {
+                if (res.data.success) {
+                    store.commit('updateTipsNum', res.data.data);
+                }
+            });
     }
-
-}, 2000);
+}, 2000);

+ 63 - 34
src/pages/OrderTransfer/Uploading.vue

@@ -17,14 +17,15 @@
             <span class="status" @click="archive">状态</span>
             <span class="edit">操作</span>
         </div>
-        <!-- <div>
+        <div>
             <button @click="upload">upload</button>
+            <button @click="upload1">upload1</button>
             <button @click="queryOrder">queryOrder</button>
             <button @click="clearDB">clearDB</button>
             <button @click="archive">archive</button>
             <button @click="init">init</button>
             <button @click="pause">pause</button>
-        </div> -->
+        </div>
         <div v-if="orders.length>0">
             <OrderUpload v-for="item in orders" :key="item.id" :orderInfo="item"></OrderUpload>
         </div>
@@ -37,43 +38,42 @@
 </template>
 
 <script>
-import { mapState } from 'vuex'
-import OrderUpload from '../../components/OrderUpload'
-import FileUploadDownloadService from '../../service/FileUploadDownloadService'
-import ImageUtils from '../../service/ImageUtils'
-import eventBus from '../../service/EventBus'
+import { mapState } from 'vuex';
+import OrderUpload from '../../components/OrderUpload';
+import FileUploadDownloadService from '../../service/FileUploadDownloadService';
+import ImageUtils from '../../service/ImageUtils';
+import eventBus from '../../service/EventBus';
 
 export default {
     name: 'Uploading',
     data() {
         return {
-            interval: null
-        }
+            interval: null,
+        };
     },
     computed: {
         ...mapState({
             userInfo: state => state.userInfo,
-            orders: state => state.uploadingOrders
+            orders: state => state.uploadingOrders,
         }),
         progress() {
             try {
                 let totalSize = 0;
                 let uploadedSize = 0;
                 this.orders.forEach(i => {
-                    totalSize += i.totalSize
-                    uploadedSize += i.uploadedSize
-                })
+                    totalSize += i.totalSize;
+                    uploadedSize += i.uploadedSize;
+                });
                 if (totalSize > 0) {
-                    return parseInt(uploadedSize / totalSize * 100)
+                    return parseInt((uploadedSize / totalSize) * 100);
                 }
-            } catch (e) {
-            }
-            return 0
-        }
+            } catch (e) {}
+            return 0;
+        },
     },
     methods: {
         clearDB() {
-            FileUploadDownloadService.clearDB()
+            FileUploadDownloadService.clearDB();
         },
         upload() {
             // for await (const n of [1, 2, 3, 4, 5]) {
@@ -84,31 +84,60 @@ export default {
             // }
             // console.log('done')
             // await FileUploadDownloadService.uploadOrder('/Users/drew/Downloads/桌面客户端上传测试的副本', 111, 'test111')
-            FileUploadDownloadService.uploadOrder('/Users/drew/Downloads/桌面客户端上传测试小', {
-                '456789096543': 'tutuxiangTest/13/216',
-                '鲁明朋李慧琳': 'tutuxiangTest/13/217',
-                '试片郝摄影513回': 'tutuxiangTest/13/218',
-            })
+            FileUploadDownloadService.uploadOrder(
+                '/Users/drew/Downloads/桌面客户端上传测试小',
+                {
+                    鲁明朋李慧琳: 'tutuxiangTest/13/559',
+                    试片郝摄影513回: 'tutuxiangTest/13/558',
+                    '456789096543': 'tutuxiangTest/13/557',
+                },
+                84664,
+                325,
+            );
+        },
+        upload1() {
+            // for await (const n of [1, 2, 3, 4, 5]) {
+            //     console.log(n)
+            //     let res = await ImageUtils.makeThumbnail('/Users/drew/Downloads/桌面客户端上传测试的副本/鲁明朋李慧琳/000_3273.NEF')
+            //     console.log(res)
+            //     console.log('----------------')
+            // }
+            // console.log('done')
+            // await FileUploadDownloadService.uploadOrder('/Users/drew/Downloads/桌面客户端上传测试的副本', 111, 'test111')
+            FileUploadDownloadService.uploadOrder(
+                '/Users/drew/Downloads/桌面客户端上传测试大',
+                {
+                    鲁明朋李慧琳: 'tutuxiangTest/13/562',
+                    试片郝摄影513回: 'tutuxiangTest/13/561',
+                    '456789096543': 'tutuxiangTest/13/560',
+                },
+                84664,
+                326,
+            );
         },
         queryOrder() {
-            FileUploadDownloadService.queryUnfinishedOrder(this.$store.state.userInfo.id)
+            FileUploadDownloadService.queryUnfinishedOrder(
+                this.$store.state.userInfo.id,
+            );
         },
         archive() {
-            FileUploadDownloadService.archive('/Users/drew/Downloads/桌面客户端上传测试的副本').then(out => {
-                console.log(out)
-            })
+            FileUploadDownloadService.archive(
+                '/Users/drew/Downloads/桌面客户端上传测试的副本',
+            ).then(out => {
+                console.log(out);
+            });
         },
         init() {
-            FileUploadDownloadService.init()
+            FileUploadDownloadService.init();
         },
-        pause() {
-            eventBus.publish('pause')
+        pause(arg) {
+            FileUploadDownloadService.pause(arg);
         },
     },
     components: {
-        OrderUpload
-    }
-}
+        OrderUpload,
+    },
+};
 </script>
 
 <style lang="less" scoped>

+ 1 - 1
src/service/DownloadJob.js

@@ -27,7 +27,7 @@ export class DownloadJob {
     async pause() {
         console.log('暂停');
         if (this.downloadInfo.status != DownloadStatus.FINISHED) {
-            await this.db.File.update({ status: DownloadStatus.PAUSE }, {
+            await this.db.Download.update({ status: DownloadStatus.PAUSE }, {
                 where: {
                     id: this.downloadInfo.id,
                 },

+ 204 - 91
src/service/FileUploadDownloadService.js

@@ -17,6 +17,7 @@ const { UploadJob } = require('./UploadJob');
 const { DownloadJob } = require('./DownloadJob');
 const { Order, SubOrder, File, Download } = require('./model');
 const rimraf = require('rimraf');
+const fsUtils = require('nodejs-fs-utils');
 
 if (!fs.existsSync(path.resolve(app.getPath('userData'), 'db'))) {
     fs.mkdirSync(path.resolve(app.getPath('userData'), 'db'));
@@ -71,13 +72,16 @@ async function checkFalse() {
         where: { status: DownloadStatus.DOWNLOADING, status: DownloadStatus.WAITING },
     })).map(i => i.get());
     downloadList.forEach(async i => {
-        await db.Download.update({
-            status: DownloadStatus.PAUSE,
-        }, {
-            where: {
-                id: i.id,
+        await db.Download.update(
+            {
+                status: DownloadStatus.PAUSE,
+            },
+            {
+                where: {
+                    id: i.id,
+                },
             },
-        }, );
+        );
     });
 
     //上传
@@ -85,13 +89,16 @@ async function checkFalse() {
         i.get(),
     );
     fileList.forEach(async i => {
-        await db.File.update({
-            status: UploadStatus.PAUSE,
-        }, {
-            where: {
-                id: i.id,
+        await db.File.update(
+            {
+                status: UploadStatus.PAUSE,
             },
-        }, );
+            {
+                where: {
+                    id: i.id,
+                },
+            },
+        );
     });
 }
 
@@ -102,32 +109,11 @@ function sleep(ms) {
 }
 
 let initiated = false;
-const init = async() => {
+const init = async () => {
     if (initiated) {
         return;
     }
-    let records = (await db.File.findAll({
-        where: {
-            status: {
-                [Op.not]: UploadStatus.FINISHED,
-            },
-        },
-    })).map(i => i.get());
-    console.log(records);
-    records.forEach(i => {
-        let job = new UploadJob(i, db);
-        uploadQueue.push(job);
-    });
-
-    // let record = (await db.File.findOne({
-    //     where: {
-    //         status: {
-    //             [Op.not]: UploadStatus.FINISHED
-    //         }
-    //     }
-    // })).get()
-    // let job = new UploadJob(record, db)
-    // uploadQueue.push(job)
+    resume();
 
     initiated = true;
 };
@@ -143,12 +129,42 @@ const PromiseQueue = arr => {
 };
 
 const pause = async arg => {
+    if (arg && arg.orderId) {
+        await db.Order.update(
+            {
+                pause: 1,
+            },
+            {
+                where: {
+                    id: arg.orderId,
+                },
+            },
+        );
+        await db.SubOrder.update(
+            { pause: 1 },
+            {
+                where: {
+                    orderId: arg.orderId,
+                },
+            },
+        );
+    }
+    if (arg && arg.subOrderId) {
+        await db.SubOrder.update(
+            { pause: 1 },
+            {
+                where: {
+                    id: arg.subOrderId,
+                },
+            },
+        );
+    }
     eventBus.publish('pause', arg);
 };
 
 const resume = async arg => {
     let records = [];
-    if (arg.orderId) {
+    if (arg && arg.orderId) {
         records = (await db.File.findAll({
             where: {
                 orderId: arg.orderId,
@@ -157,7 +173,7 @@ const resume = async arg => {
                 },
             },
         })).map(i => i.get());
-    } else if (arg.subOrderId) {
+    } else if (arg && arg.subOrderId) {
         records = (await db.File.findAll({
             where: {
                 subOrderId: arg.subOrderId,
@@ -166,7 +182,7 @@ const resume = async arg => {
                 },
             },
         })).map(i => i.get());
-    } else if (arg.fileId) {
+    } else if (arg && arg.fileId) {
         records = (await db.File.findAll({
             where: {
                 id: arg.fileId,
@@ -176,9 +192,42 @@ const resume = async arg => {
             },
         })).map(i => i.get());
     } else {
-        records = (await db.File.findAll()).map(i => i.get());
+        records = (await db.File.findAll({
+            where: {
+                status: {
+                    [Op.not]: UploadStatus.FINISHED,
+                },
+            },
+        })).map(i => i.get());
     }
-    console.log(records);
+    let orderIds = [];
+    let subOrderIds = [];
+    records.forEach(i => {
+        if (orderIds.indexOf(i.orderId) === -1) {
+            orderIds.push(i.orderId);
+        }
+        if (subOrderIds.indexOf(i.subOrderId) === -1) {
+            subOrderIds.push(i.subOrderId);
+        }
+    });
+    await db.Order.update(
+        {
+            pause: 0,
+        },
+        {
+            where: {
+                id: orderIds,
+            },
+        },
+    );
+    await db.SubOrder.update(
+        { pause: 0 },
+        {
+            where: {
+                id: subOrderIds,
+            },
+        },
+    );
     records.forEach(i => {
         let job = new UploadJob(i, db);
         uploadQueue.push(job);
@@ -186,27 +235,42 @@ const resume = async arg => {
 };
 
 const queryUnfinishedOrder = async userId => {
-    let res = await sequelize.query(
-        `SELECT
-            o.*,
-            fileNum,
-            totalSize, 
-            uploadedSize
+    // let sql = `
+    //     SELECT
+    //         o.*,
+    //         fileNum,
+    //         totalSize,
+    //         uploadedSize
+    //     FROM
+    //         Orders o
+    //         JOIN ( SELECT SUM( size ) AS totalSize, SUM( progress * size ) AS uploadedSize, COUNT( * ) AS fileNum, orderId  FROM Files GROUP BY orderId ) t ON o.id = t.orderId
+    //     WHERE
+    //         o.id IN (
+    //         SELECT
+    //             orderId
+    //         FROM
+    //             Files
+    //         WHERE
+    //             status != ${UploadStatus.FINISHED}
+    //     GROUP BY
+    //         orderId)
+    //         and o.userId = ${userId}`;
+    let sql = `
+        SELECT
+            Orders.* ,
+            ( SELECT SUM( size ) FROM SubOrders WHERE SubOrders.orderId = Orders.id ) AS totalSize,
+            ( SELECT SUM( f0.progress * f0.size ) FROM Files f0 WHERE f0.orderId = Orders.id ) AS uploadedSize,
+            ( SELECT COUNT( f1.id ) FROM Files f1 WHERE f1.orderId = Orders.id ) AS fileNum 
         FROM
-            Orders o
-            JOIN ( SELECT SUM( size ) AS totalSize, SUM( progress * size ) AS uploadedSize, COUNT( * ) AS fileNum, orderId  FROM Files GROUP BY orderId ) t ON o.id = t.orderId 
+            Orders
+            JOIN Files ON Files.orderId = Orders.id 
         WHERE
-            o.id IN (
-            SELECT
-                orderId
-            FROM
-                Files 
-            WHERE
-                status != ${UploadStatus.FINISHED} 
+            Files.status != ${UploadStatus.FINISHED}
+            AND Orders.userId = ${userId}
         GROUP BY
-            orderId)
-            and o.userId = ${userId}`, { type: sequelize.QueryTypes.SELECT },
-    );
+            Orders.id
+    `;
+    let res = await sequelize.query(sql, { type: sequelize.QueryTypes.SELECT });
     return res;
 };
 
@@ -223,7 +287,8 @@ const queryFinishedOrder = async userId => {
         Orders 
     WHERE
     totalNum = finishedNum AND userId= ${userId}
-    order by updatedAt DESC`, { type: sequelize.QueryTypes.SELECT },
+    order by updatedAt DESC`,
+        { type: sequelize.QueryTypes.SELECT },
     );
     return res;
 };
@@ -231,13 +296,19 @@ const queryFinishedOrder = async userId => {
 const queryDetail = async orderId => {
     let res = await sequelize.query(
         `SELECT
-            s.*,
+            s.id,
+            s.orderId,
+            s.parentId,
+            s.path,
+            s.name,
+            s.size AS totalSize,
+            s.pause,
+            s.createdAt,
+            s.updatedAt,
             COUNT( * ) AS fileNum,
-            SUM( size ) AS totalSize,
             ( SELECT COUNT( * ) FROM Files WHERE src LIKE '%.zip' AND subOrderId = s.id ) > 0 AS hasZip,
             ( SELECT COUNT( * ) FROM Files WHERE status = - 1 AND subOrderId = s.id ) > 0 AS packing,
-            (
-            SUM( progress * size ) / SUM( size )) AS progress,
+            ( SUM( progress * f.size ) / s.size) AS progress,
             (
             SELECT
                 a = b 
@@ -255,7 +326,8 @@ const queryDetail = async orderId => {
         WHERE
             f.orderId = ${orderId} 
         GROUP BY
-            f.subOrderId`, { type: sequelize.QueryTypes.SELECT },
+            f.subOrderId`,
+        { type: sequelize.QueryTypes.SELECT },
     );
     return res;
 };
@@ -271,12 +343,14 @@ const checkClientOrder = async clientOrderId => {
         FROM 
             Orders 
         WHERE 
-        clientOrderId = ${clientOrderId} `, { type: sequelize.QueryTypes.SELECT },
+        clientOrderId = ${clientOrderId} `,
+        { type: sequelize.QueryTypes.SELECT },
     );
     return res;
 };
 
-const uploadOrder = async(topDir, prefixes, userId, clientOrderId) => {
+const uploadOrder = async (topDir, prefixes, userId, clientOrderId) => {
+    console.log(topDir, JSON.stringify(prefixes), userId, clientOrderId);
     if (!prefixes instanceof Object) {
         throw 'prefixes not found';
     }
@@ -286,6 +360,7 @@ const uploadOrder = async(topDir, prefixes, userId, clientOrderId) => {
         name: name,
         userId: userId,
         clientOrderId: clientOrderId,
+        pause: 0,
     })).get();
     let orderId = mainOrder.id;
 
@@ -317,6 +392,8 @@ const uploadOrder = async(topDir, prefixes, userId, clientOrderId) => {
             parentId: mainOrder.id,
             path: topDir,
             name,
+            size: fsUtils.fsizeSync(topDir),
+            pause: 0,
         })).get();
 
         let outPath = path.resolve(archiveDir, uuidv1() + '.zip');
@@ -334,13 +411,19 @@ const uploadOrder = async(topDir, prefixes, userId, clientOrderId) => {
         await readDir(topDir, orderId, subOrder.id, null, prefix);
         let archiveFile = await archive(topDir, outPath);
         let info = fs.statSync(archiveFile);
-        await db.File.update({
-            status: UploadStatus.WAITING,
-            size: info.size,
-        }, { where: { id: fileinfo.id } }, );
+        await sequelize.query(`UPDATE SubOrders 
+            SET size = ( SELECT SUM( size ) FROM Files WHERE subOrderId = ${subOrder.id} ) 
+            WHERE id = ${subOrder.id}`);
+        await db.File.update(
+            {
+                status: UploadStatus.WAITING,
+                size: info.size,
+            },
+            { where: { id: fileinfo.id } },
+        );
         uploadQueue.push(new UploadJob(fileinfo, db));
     } else {
-        for await (const child of fs.readdirSync(topDir)) {
+        fs.readdirSync(topDir).forEach(async child => {
             if (!child.startsWith('.')) {
                 let prefix = prefixes[child];
                 let info = fs.statSync(path.resolve(topDir, child));
@@ -350,6 +433,8 @@ const uploadOrder = async(topDir, prefixes, userId, clientOrderId) => {
                         parentId: mainOrder.id,
                         path: path.resolve(topDir, child),
                         name: child,
+                        size: fsUtils.fsizeSync(path.resolve(topDir, child)),
+                        pause: 0,
                     })).get();
 
                     let outPath = path.resolve(archiveDir, uuidv1() + '.zip');
@@ -367,14 +452,21 @@ const uploadOrder = async(topDir, prefixes, userId, clientOrderId) => {
                     await readDir(path.resolve(topDir, child), orderId, subOrder.id, child, prefix);
                     let archiveFile = await archive(path.resolve(topDir, child), outPath);
                     let info = fs.statSync(archiveFile);
-                    await db.File.update({
-                        status: UploadStatus.WAITING,
-                        size: info.size,
-                    }, { where: { id: fileinfo.id } }, );
+                    await db.File.update(
+                        {
+                            status: UploadStatus.WAITING,
+                            size: info.size,
+                        },
+                        { where: { id: fileinfo.id } },
+                    );
+                    await sequelize.query(`
+                    UPDATE SubOrders SET size = ( SELECT SUM( size ) FROM Files WHERE subOrderId = ${
+                        subOrder.id
+                    } ) WHERE id = ${subOrder.id}`);
                     uploadQueue.push(new UploadJob(fileinfo, db));
                 }
             }
-        }
+        });
     }
     async function readDir(dir, orderId, subOrderId, relative, prefix) {
         for await (const child of fs.readdirSync(dir)) {
@@ -423,7 +515,7 @@ const uploadOrder = async(topDir, prefixes, userId, clientOrderId) => {
     }
 };
 
-const archive = async(dir, outPath) => {
+const archive = async (dir, outPath) => {
     return new Promise((resolve, reject) => {
         // create a file to stream archive data to.
         let output = fs.createWriteStream(outPath);
@@ -469,7 +561,7 @@ const archive = async(dir, outPath) => {
     });
 };
 
-const clearDB = async() => {
+const clearDB = async () => {
     await db.Order.destroy({ where: {} });
     await db.SubOrder.destroy({ where: {} });
     await db.File.destroy({ where: {} });
@@ -490,11 +582,14 @@ const downloadPause = async arg => {
 
 const downloadResume = async arg => {
     if (arg.id) {
-        await db.Download.update({ status: DownloadStatus.WAITING }, {
-            where: {
-                id: arg.id,
+        await db.Download.update(
+            { status: DownloadStatus.WAITING },
+            {
+                where: {
+                    id: arg.id,
+                },
             },
-        }, );
+        );
         var record = await db.Download.findOne({ where: { id: arg.id } });
 
         console.log(record);
@@ -509,7 +604,8 @@ const queryUnfinishedDownloadOrder = async userId => {
         FROM 
             Downloads 
         WHERE 
-            userId = ${userId} AND status != ${DownloadStatus.FINISHED}`, { type: sequelize.QueryTypes.SELECT },
+            userId = ${userId} AND status != ${DownloadStatus.FINISHED}`,
+        { type: sequelize.QueryTypes.SELECT },
     );
     return res;
 };
@@ -522,7 +618,8 @@ const queryfinishedDownloadOrder = async userId => {
             Downloads 
         WHERE 
             userId = ${userId} AND status = ${DownloadStatus.FINISHED}
-        order by updatedAt DESC`, { type: sequelize.QueryTypes.SELECT },
+        order by updatedAt DESC`,
+        { type: sequelize.QueryTypes.SELECT },
     );
     return res;
 };
@@ -534,10 +631,10 @@ async function getFilePath(pathName, i) {
         _path = path.resolve(
             window.localStorage['downLoadingPath2'],
             path.basename(pathName, path.extname(pathName)) +
-            '(' +
-            i +
-            ')' +
-            path.extname(pathName),
+                '(' +
+                i +
+                ')' +
+                path.extname(pathName),
         );
     }
     var exist = await fs.existsSync(_path);
@@ -548,7 +645,7 @@ async function getFilePath(pathName, i) {
     return _path;
 }
 
-const downloadFile = async(objectName, orderName, userId, quantity, userOrderId) => {
+const downloadFile = async (objectName, orderName, userId, quantity, userOrderId) => {
     let pathName = await getFilePath(userOrderId + '_' + orderName, 0);
     let download = (await db.Download.create({
         dst: objectName,
@@ -564,7 +661,7 @@ const downloadFile = async(objectName, orderName, userId, quantity, userOrderId)
     })).get();
     downloadQueue.push(new DownloadJob(download, db));
 };
-const clearCache = async() => {
+const clearCache = async () => {
     rmDir = function(dirPath) {
         try {
             var files = fs.readdirSync(dirPath);
@@ -583,6 +680,21 @@ const clearCache = async() => {
 };
 window.clearCache = clearCache;
 
+const deleteUploadedFile = async () => {
+    let files = await db.File.findAll({
+        where: {
+            status: UploadStatus.FINISHED,
+        },
+    }).map(i => i.get());
+    files.forEach(i => {
+        fs.unlink(i.src, err => {
+            if (!err) {
+                console.log(`${i.src} deleted`);
+            }
+        });
+    });
+};
+
 export default {
     init,
     pause,
@@ -599,4 +711,5 @@ export default {
     queryUnfinishedDownloadOrder,
     queryfinishedDownloadOrder,
     checkClientOrder,
-};
+    deleteUploadedFile,
+};

+ 20 - 13
src/service/UploadJob.js

@@ -82,10 +82,18 @@ export class UploadJob {
             console.log('retry ' + (this.retry - 1));
         }
 
+        let subOrder = await this.db.SubOrder.findOne({ where: { id: this.fileInfo.subOrderId } });
+        if (subOrder) {
+            subOrder = subOrder.get();
+            if (subOrder.pause === 1) {
+                this.pause();
+                return;
+            }
+        }
+
         let res = await this.db.File.findOne({ where: { id: this.fileInfo.id } });
         if (res) {
             let doc = res.get();
-            console.log('resume upload job', this.fileInfo);
             await this.db.File.update(
                 { status: UploadStatus.UPLOADING },
                 {
@@ -96,12 +104,13 @@ export class UploadJob {
             );
             let stat = fs.statSync(this.fileInfo.src);
             try {
-                if (stat.size > 50 * 1024 * 1024) {
+                if (this.fileInfo.src.endsWith('.zip')) {
                     let self = this;
                     let result = await this.oss.multipartUpload(
                         this.fileInfo.dst,
                         this.fileInfo.src,
                         {
+                            partSize: 1024 * 1024 * 5,
                             checkpoint: doc.checkPoint ? JSON.parse(doc.checkPoint) : null,
                             async progress(p, cpt, res) {
                                 await self.db.File.update(
@@ -116,16 +125,15 @@ export class UploadJob {
                         },
                     );
                     if (200 === result.res.status) {
-                        console.log('upload success', result);
                         this.fileInfo.status = UploadStatus.FINISHED;
                         await this.db.File.update(
                             { status: UploadStatus.FINISHED, progress: 1 },
                             { where: { id: this.fileInfo.id } },
                         );
-                        fs.unlink(this.fileInfo.src, err => {
-                            if (err) throw err;
-                            console.log(`${this.fileInfo.src} deleted`);
-                        });
+                        // fs.unlink(this.fileInfo.src, err => {
+                        //     if (err) throw err;
+                        //     console.log(`${this.fileInfo.src} deleted`);
+                        // });
                         if (this.done) {
                             this.done();
                             this.done = null;
@@ -138,16 +146,15 @@ export class UploadJob {
                 } else {
                     let result = await this.oss.put(this.fileInfo.dst, this.fileInfo.src);
                     if (200 === result.res.status) {
-                        console.log('upload success', result);
                         this.fileInfo.status = UploadStatus.FINISHED;
                         await this.db.File.update(
                             { status: UploadStatus.FINISHED, progress: 1 },
                             { where: { id: this.fileInfo.id } },
                         );
-                        fs.unlink(this.fileInfo.src, err => {
-                            if (err) throw err;
-                            console.log(`${this.fileInfo.src} deleted`);
-                        });
+                        // fs.unlink(this.fileInfo.src, err => {
+                        //     if (err) throw err;
+                        //     console.log(`${this.fileInfo.src} deleted`);
+                        // });
                         if (this.done) {
                             this.done();
                             this.done = null;
@@ -162,7 +169,7 @@ export class UploadJob {
                 if (!(e && 'cancel' == e.name)) {
                     console.log('upload error', e);
                     this.error = e;
-                    await sleep(1000);
+                    await sleep(3000);
                     this.resume();
                 }
             }

+ 27 - 20
src/service/model/Order.js

@@ -1,25 +1,32 @@
-import Sequelize from 'sequelize'
-const Model = Sequelize.Model
+import Sequelize from 'sequelize';
+const Model = Sequelize.Model;
 class Order extends Model {
     static init(sequelize) {
-        super.init({
-            path: {
-                type: Sequelize.STRING,
-                allowNull: false
+        super.init(
+            {
+                path: {
+                    type: Sequelize.STRING,
+                    allowNull: false,
+                },
+                name: {
+                    type: Sequelize.STRING,
+                    allowNull: false,
+                },
+                userId: {
+                    type: Sequelize.INTEGER,
+                    allowNull: false,
+                },
+                clientOrderId: {
+                    type: Sequelize.INTEGER,
+                    allowNull: false,
+                },
+                pause: {
+                    type: Sequelize.INTEGER,
+                    allowNull: false,
+                },
             },
-            name: {
-                type: Sequelize.STRING,
-                allowNull: false
-            },
-            userId:{
-                type: Sequelize.INTEGER,
-                allowNull: false
-            },
-            clientOrderId:{
-                type:Sequelize.INTEGER,
-                allowNull:false
-            }
-        }, { sequelize, modelName: 'Order' })
+            { sequelize, modelName: 'Order' },
+        );
     }
 }
-export default Order
+export default Order;

+ 31 - 20
src/service/model/SubOrder.js

@@ -1,26 +1,37 @@
-import Sequelize from 'sequelize'
-const Model = Sequelize.Model
+import Sequelize from 'sequelize';
+const Model = Sequelize.Model;
 class SubOrder extends Model {
     static init(sequelize) {
-        super.init({
-            orderId: {
-                type: Sequelize.INTEGER,
-                allowNull: false
+        super.init(
+            {
+                orderId: {
+                    type: Sequelize.INTEGER,
+                    allowNull: false,
+                },
+                parentId: {
+                    type: Sequelize.INTEGER,
+                    allowNull: false,
+                },
+                path: {
+                    type: Sequelize.STRING,
+                    allowNull: false,
+                },
+                name: {
+                    type: Sequelize.STRING,
+                    allowNull: false,
+                },
+                size: {
+                    type: Sequelize.INTEGER,
+                    allowNull: false,
+                },
+                pause: {
+                    type: Sequelize.INTEGER,
+                    allowNull: false,
+                },
             },
-            parentId: {
-                type: Sequelize.INTEGER,
-                allowNull: false
-            },
-            path: {
-                type: Sequelize.STRING,
-                allowNull: false
-            },
-            name: {
-                type: Sequelize.STRING,
-                allowNull: false
-            }
-        }, { sequelize, modelName: 'SubOrder' })
+            { sequelize, modelName: 'SubOrder' },
+        );
     }
 }
 
-export default SubOrder
+export default SubOrder;

+ 4 - 0
test.js

@@ -0,0 +1,4 @@
+const fsUtils = require('nodejs-fs-utils');
+console.log(
+    fsUtils.fsizeSync('/Users/drew/Downloads/桌面客户端上传测试大/456789096543') / 1024 / 1024,
+);

+ 18 - 8
vue.config.js

@@ -1,12 +1,22 @@
 module.exports = {
     runtimeCompiler: true,
     devServer: {
-        stats: "verbose"
+        stats: 'verbose',
     },
     pluginOptions: {
         electronBuilder: {
             // List native deps here if they don't work
-            externals: ['sqlite3', 'sharp', 'sequelize', 'ali-oss', 'urllib', 'utility', 'archiver', 'dcraw'],
+            externals: [
+                'sqlite3',
+                'sharp',
+                'sequelize',
+                'ali-oss',
+                'urllib',
+                'utility',
+                'archiver',
+                'dcraw',
+                'nodejs-fs-utils',
+            ],
             // If you are using Yarn Workspaces, you may have multiple node_modules folders
             // List them all here so that VCP Electron Builder can find them
             nodeModulesPath: ['./node_modules'],
@@ -15,9 +25,9 @@ module.exports = {
                 win: {
                     certificateFile: 'sign.pfx',
                     certificatePassword: '123123',
-                    publisherName: '安徽图忆途网络科技服务有限公司'
-                }
-            }
-        }
-    }
-}
+                    publisherName: '安徽图忆途网络科技服务有限公司',
+                },
+            },
+        },
+    },
+};