Selaa lähdekoodia

crx插件demo

gaoshuaixing 4 vuotta sitten
vanhempi
commit
5d39549e69

+ 22 - 13
app/controller/v1/example.js

@@ -61,20 +61,7 @@ class ExampleController extends BaseController {
     const self = this;
     const { ctx, service } = this;
     let tmpDir = service.storage.getStorageDir();
-    // for (const file of ctx.request.files) {
-    //   this.app.logger.info('file:', file);
-
-    //   try {
-    //     let tmpFile = fs.readFileSync(file.filepath)
-    //     fs.writeFileSync(path.join(tmpDir, file.filename), tmpFile)
-    //   } finally {
-    //     await fs.unlink(file.filepath, function(){});
-    //   }
-    //   const fileStream = fs.createReadStream(path.join(tmpDir, file.filename))
-    //   const uploadRes = await service.example.uploadFileToSMMS(fileStream);
-    // }
     const file = ctx.request.files[0];
-    //this.app.logger.info('file:', file);
 
     try {
       let tmpFile = fs.readFileSync(file.filepath)
@@ -88,6 +75,28 @@ class ExampleController extends BaseController {
     self.sendData(uploadRes);
   }
 
+  async uploadExtension() {
+    const self = this;
+    const { ctx, service } = this;
+    const data = {};
+    let tmpDir = service.storage.getStorageDir();
+
+    const file = ctx.request.files[0];
+    this.app.logger.info('file:', file);
+
+    try {
+      let tmpFile = fs.readFileSync(file.filepath)
+      fs.writeFileSync(path.join(tmpDir, file.filename), tmpFile)
+    } finally {
+      await fs.unlink(file.filepath, function(){});
+    }
+    
+    const filePath = path.join(tmpDir, file.filename);
+    await service.example.loadExtension(filePath);
+
+    self.sendData(data);
+  }
+
   async setShortcut() {
     const self = this;
     const { ctx, service } = this;

+ 2 - 1
app/router/example.js

@@ -39,5 +39,6 @@ module.exports = app => {
   router.post('/api/v1/example/messageShow', controller.v1.example.messageShow);
   // message show confirm
   router.post('/api/v1/example/messageShowConfirm', controller.v1.example.messageShowConfirm);
-
+  // upload chrome extension
+  router.post('/api/v1/example/uploadExtension', controller.v1.example.uploadExtension);
 };

+ 6 - 0
app/service/example.js

@@ -111,7 +111,13 @@ class ExampleService extends BaseService {
     return true;
   }   
 
+  async loadExtension(filePath) {
+    const self = this;
+
+    await self.ipcCall('example.loadExtension', filePath);
 
+    return true;
+  }
 }
 
 module.exports = ExampleService;

+ 4 - 4
app/service/storage.js

@@ -59,7 +59,7 @@ class StorageService extends BaseService {
   }
 
   /*
-   * add Test data
+   *  Test data
    */
   async addTestData(user) {
     const key = storageKey.TEST_DATA;
@@ -76,7 +76,7 @@ class StorageService extends BaseService {
   }
 
   /*
-   * del Test data
+   *  Test data
    */
   async delTestData(name = '') {
     const key = storageKey.TEST_DATA;
@@ -89,7 +89,7 @@ class StorageService extends BaseService {
   }
 
   /*
-   * update Test data
+   *  Test data
    */
   async updateTestData(name= '', age = 0) {
     const key = storageKey.TEST_DATA;
@@ -103,7 +103,7 @@ class StorageService extends BaseService {
   }
 
   /*
-   * get Test data
+   *  Test data
    */
   async getTestData(name = '') {
     const key = storageKey.TEST_DATA;

+ 1 - 1
config/config.default.js

@@ -94,7 +94,7 @@ module.exports = appInfo => {
 
   config.multipart = {
     mode: 'file',
-    fileExtensions: [ '.xlsx' ] // 增加你需要的文件扩展名
+    fileExtensions: [ '.xlsx', '.crx' ] // 增加你需要的文件扩展名
   };
 
   return {

+ 23 - 0
electron/apis/example.js

@@ -11,6 +11,8 @@ const {exec} = require('child_process');
 const {app, webContents, shell, dialog} = require('electron');
 const AutoLaunchManager = require('../lib/autoLaunch');
 const shortcut = require('../lib/shortcut');
+const chromeExtension = require('../lib/chromeExtension');
+const unzip = require("unzip-crx-3");
 
 /**
  * app根目录
@@ -166,6 +168,27 @@ exports.messageShowConfirm = function () {
   return true;
 }
 
+/**
+ * 加载扩展程序
+ */
+exports.loadExtension = async function (crxFile) {
+  if (_.isEmpty(crxFile)) {
+    return false;
+  }
+
+  const extensionId = path.basename(crxFile, '.crx');
+  const chromeExtensionDir = chromeExtension.getDirectory();
+  const extensionDir = path.join(chromeExtensionDir, extensionId);
+
+  console.log("[api] [example] [loadExtension] extension id:", extensionId);
+  unzip(crxFile, extensionDir).then(() => {    
+    console.log("[api] [example] [loadExtension] unzip success!");
+    chromeExtension.load(extensionId);
+  });
+
+  return true;
+}
+
 function getElectronPath(filepath) {
   //filepath = path.resolve(filepath);
   filepath = filepath.replace("resources", "");

+ 5 - 5
frontend/src/config/router.config.js

@@ -29,11 +29,6 @@ export const constantRouterMap = [
             component: () => import('@/views/demo/socket/Index')
           },
           {
-            path: '/demo/extend/index',
-            name: 'DemoExtendIndex',
-            component: () => import('@/views/demo/extend/Index')
-          },
-          {
             path: '/demo/windowview/index',
             name: 'DemoWindowViewIndex',
             component: () => import('@/views/demo/windowview/Index')
@@ -44,6 +39,11 @@ export const constantRouterMap = [
             component: () => import('@/views/demo/window/Index')
           },
           {
+            path: '/demo/extension/index',
+            name: 'DemoExtensionIndex',
+            component: () => import('@/views/demo/extension/Index')
+          },
+          {
             path: '/demo/notification/index',
             name: 'DemoNotificationIndex',
             component: () => import('@/views/demo/notification/Index')

+ 10 - 10
frontend/src/layouts/DemoMenu.vue

@@ -36,12 +36,6 @@ export default {
           pageName: 'DemoSocketIndex',
           params: {}
         },
-        'menu_301' : {
-          icon: 'profile',
-          title: '扩展程序',
-          pageName: 'DemoExtendIndex',
-          params: {}
-        },
         'menu_400' : {
           icon: 'profile',
           title: '视图',
@@ -54,25 +48,31 @@ export default {
           pageName: 'DemoWindowIndex',
           params: {}
         },
-        'menu_402' : {
+        'menu_403' : {
+          icon: 'profile',
+          title: '扩展程序',
+          pageName: 'DemoExtensionIndex',
+          params: {}
+        },
+        'menu_405' : {
           icon: 'profile',
           title: '桌面通知',
           pageName: 'DemoNotificationIndex',
           params: {}
         },
-        'menu_403' : {
+        'menu_407' : {
           icon: 'profile',
           title: '电源监控',
           pageName: 'DemoPowerMonitorIndex',
           params: {}
         },
-        'menu_404' : {
+        'menu_409' : {
           icon: 'profile',
           title: '屏幕信息',
           pageName: 'DemoScreenIndex',
           params: {}
         },
-        'menu_405' : {
+        'menu_411' : {
           icon: 'profile',
           title: '系统主题',
           pageName: 'DemoThemeIndex',

+ 0 - 77
frontend/src/views/demo/extend/Index.vue

@@ -1,77 +0,0 @@
-<template>
-  <div id="app-demo-screen">
-    <div class="one-block-1">
-      <span>
-        1. 
-      </span>
-    </div>
-    <div class="one-block-2">
-      <a-space>
-        <a-button @click="getTheme()">获取模式</a-button>
-      </a-space>
-      <span>
-        结果:{{ currentThemeMode }}
-      </span>
-    </div>
-    <div class="one-block-1">
-      2. 设置主题模式(请自行实现前端UI效果)
-    </div>  
-    <div class="one-block-2">
-
-    </div>
-  </div>
-</template>
-<script>
-
-export default {
-  data() {
-    return {
-      currentThemeMode: '',
-      themeList: [
-        'system',
-        'light',
-        'dark'
-      ]
-    };
-  },
-  mounted () {
-    this.init();
-  },
-  methods: {
-    init () {
-      const self = this;
-      this.$ipc.on('example.setTheme', (event, result) => {
-        console.log('result:', result)
-        self.currentThemeMode = result;
-      })
-
-      this.$ipc.on('example.getTheme', (event, result) => {
-        console.log('result:', result)
-        self.currentThemeMode = result;
-      })
-    },
-    setTheme (e) {
-      this.currentThemeMode = e.target.value;
-      console.log('setTheme currentThemeMode:', this.currentThemeMode)
-      this.$ipc.send('example.setTheme', this.currentThemeMode);
-    },
-    getTheme () {
-      this.$ipc.send('example.getTheme', '');
-    },
-  }
-};
-</script>
-<style lang="less" scoped>
-#app-demo-screen {
-  padding: 0px 10px;
-  text-align: left;
-  width: 100%;
-  .one-block-1 {
-    font-size: 16px;
-    padding-top: 10px;
-  }
-  .one-block-2 {
-    padding-top: 10px;
-  }
-}
-</style>

+ 82 - 0
frontend/src/views/demo/extension/Index.vue

@@ -0,0 +1,82 @@
+<template>
+  <div id="app-demo-extension">
+    <div class="one-block-1">
+      <span>
+        1. 上传扩展程序(crx文件格式)
+      </span>
+    </div>
+    <div class="one-block-2">
+      <a-upload-dragger
+        name="file"
+        :multiple="true"
+        :action="action_url"
+        @change="handleChange"
+      >
+        <p class="ant-upload-drag-icon">
+          <a-icon type="inbox" />
+        </p>
+        <p class="ant-upload-text">
+          Click or drag file to this area to upload
+        </p>
+        <p class="ant-upload-hint">
+        </p>
+      </a-upload-dragger>
+    </div>
+    <div class="one-block-1">
+      2. chrome扩展商店(crx下载)
+    </div>  
+    <div class="one-block-2">
+      <a-space>
+        极简插件:https://chrome.zzzmh.cn/
+      </a-space>
+    </div>
+  </div>
+</template>
+<script>
+
+export default {
+  data() {
+    return {
+      action_url: process.env.VUE_APP_API_BASE_URL + '/api/v1/example/uploadExtension',
+    };
+  },
+  mounted () {
+    this.init();
+  },
+  methods: {
+    init () {
+    },
+		handleChange(info) {
+      const status = info.file.status;
+      if (status !== 'uploading') {
+        console.log(info.file);
+      }
+      if (status === 'done') {
+        const uploadRes = info.file.response;
+        console.log('uploadRes:', uploadRes)
+        // if (uploadRes.code !== 'success') {
+        //   this.$message.error(`file upload failed ${uploadRes.code} .`);
+        //   return false;
+        // }
+        // this.$message.success(`${info.file.name} file uploaded successfully.`);
+      } else if (status === 'error') {
+        this.$message.error(`${info.file.name} file upload failed.`);
+      }
+    },
+  }
+};
+</script>
+<style lang="less" scoped>
+#app-demo-extension {
+  padding: 0px 10px;
+  text-align: left;
+  width: 100%;
+  .one-block-1 {
+    font-size: 16px;
+    padding-top: 10px;
+  }
+  .one-block-2 {
+    padding-top: 10px;
+  }
+}
+</style>

+ 3 - 2
package.json

@@ -1,6 +1,6 @@
 {
   "name": "electron-egg",
-  "version": "1.14.0",
+  "version": "1.15.0",
   "description": "A fast, desktop software development framework",
   "main": "main.js",
   "scripts": {
@@ -117,6 +117,7 @@
     "lowdb": "^1.0.0",
     "semver": "^5.4.1",
     "socket.io": "^3.0.5",
-    "socket.io-client": "^3.0.5"
+    "socket.io-client": "^3.0.5",
+    "unzip-crx-3": "^0.2.0"
   }
 }