Bladeren bron

mod:拍摄商品

panqiuyao 8 maanden geleden
bovenliggende
commit
9d37a5018c

+ 22 - 0
electron/api/takephoto.js

@@ -0,0 +1,22 @@
+const { post,get } = require('./request')
+
+module.exports = {
+  getPhotoRecords(data){
+    return get({
+      url: '/get_photo_records',
+      data: data
+    })
+  },
+
+  delectGoodsArts(data){
+    console.log('delectGoodsArts')
+    console.log(data)
+    return post({
+      url: '/delect_goods_arts',
+      data: data
+    })
+  },
+
+
+
+}

+ 3 - 0
electron/controller/socket.js

@@ -44,6 +44,8 @@ class SocketController extends Controller {
       // 监听连接关闭事件
       socket.on('close', () => {
         console.log('socket close');
+        win.webContents.send('controller.socket.disconnect', null);
+        socket = null
 
       });
 
@@ -51,6 +53,7 @@ class SocketController extends Controller {
       socket.on('error', (err) => {
         console.log('socket error');
         console.log(error);
+        win.webContents.send('controller.socket.disconnect', null);
         reject(true);
 
       });

+ 62 - 0
electron/controller/takephoto.js

@@ -0,0 +1,62 @@
+'use strict';
+const { Controller } = require('ee-core');
+const  { getPhotoRecords,delectGoodsArts } =  require('../api/takephoto');
+const errData = {
+  msg :'请求失败,请联系管理员',
+  code:999
+}
+
+
+/**
+ * example
+ * @class
+ */
+class takePhotoController extends Controller {
+
+  constructor(ctx) {
+    super(ctx);
+  }
+
+
+  /**
+   * 所有方法接收两个参数
+   * @param args 前端传的参数
+   * @param event - ipc通信时才有值。详情见:控制器文档
+   */
+
+  /**
+   * getPhotoRecords
+   */
+  async getPhotoRecords (params) {
+    console.log('getPhotoRecords')
+    try {
+      const result = await getPhotoRecords(params);
+      console.log('getPhotoRecords result')
+      if(result.data)  return result.data
+      return errData;
+    } catch (error) {
+      console.log('getPhotoRecords error')
+      return errData;
+    }
+  }
+
+  async delectGoodsArts (params) {
+    console.log('delectGoodsArts')
+    try {
+      const result = await delectGoodsArts(params);
+      console.log('result')
+      console.log(result)
+      if(result.data)  return result.data
+      return errData;
+    } catch (error) {
+      console.log('error')
+      console.log(error)
+      return errData;
+    }
+  }
+
+
+}
+
+takePhotoController.toString = () => '[class takePhotoController]';
+module.exports = takePhotoController;

+ 59 - 0
electron/controller/windows.js

@@ -0,0 +1,59 @@
+'use strict';
+
+const Addon = require('ee-core/addon');
+const { Controller } = require('ee-core');
+
+/**
+ * example
+ * @class
+ */
+  class WindowsController extends Controller {
+
+  constructor(ctx) {
+    super(ctx);
+  }
+
+
+  async openMain (config) {
+
+
+    if( this.app.electron[config.id]) return;
+    const win = new BrowserWindow({
+      ...config,
+
+      webPreferences: {
+        webSecurity: false,
+        contextIsolation: false, // false -> 可在渲染进程中使用electron的api,true->需要bridge.js(contextBridge)
+        nodeIntegration: true,
+        preload: path.join('../preload/preload.js','../preload/bridge.js'),
+
+      },
+    });
+    win.loadURL(config.url); // 设置窗口的 URL
+    // 监听窗口关闭事件
+
+    win.webContents.openDevTools(config.openDevTools);
+    win.on('close', () => {
+      delete this.app.electron[config.id]; // 删除窗口引用
+    });
+
+    this.app.electron[config.id] = win ;
+
+  }
+
+  /**
+   * 打开新窗口
+   */
+  closeWindows (id) {
+
+  }
+  /**
+   * 窗口最小化
+   */
+  miniWindows (id) {
+
+  }
+}
+
+WindowsController.toString = () => '[class WindowsController]';
+module.exports = WindowsController;

+ 6 - 5
frontend/src/stores/modules/socket.ts

@@ -9,6 +9,12 @@ const socket = defineStore('socket', ()=>{
     const socket = ref(null);
     const clientStore = client();
 
+
+    clientStore.ipc.on(icpList.socket.connect, async (event, result) => {
+        socket.value = null
+    })
+
+
     async function connectSocket(){
         if(!clientStore.isClient) return;
         new  Promise((resolve,reject)=>{
@@ -29,7 +35,6 @@ const socket = defineStore('socket', ()=>{
     async function disconnectSocket(){
         if(!clientStore.isClient) return;
         new  Promise((resolve,reject)=>{
-            if(socket) resolve(socket)
             clientStore.ipc.removeAllListeners(icpList.socket.disconnect);
             clientStore.ipc.send(icpList.socket.disconnect);
             clientStore.ipc.on(icpList.socket.connect, async (event, result) => {
@@ -44,12 +49,8 @@ const socket = defineStore('socket', ()=>{
     async function sendMessage(data){
         if(!clientStore.isClient) return;
         new  Promise((resolve,reject)=>{
-            if(socket) resolve(socket)
             clientStore.ipc.removeAllListeners(icpList.socket.sendMessage);
             clientStore.ipc.send(icpList.socket.sendMessage,JSON.stringify(data));
-            clientStore.ipc.on(icpList.socket.sendMessage, async (event, result) => {
-                resolve(result)
-            })
 
         })
     }

+ 3 - 2
frontend/src/styles/lanhu.scss

@@ -7,6 +7,7 @@ body {
   font-family: PingFangSC-Regular, Roboto, Helvetica Neue, Helvetica, Tahoma,
     Arial, PingFang SC-Light, Microsoft YaHei;
 }
+/*
 button {
   margin: 0;
   padding: 0;
@@ -14,6 +15,7 @@ button {
   outline: none;
   background-color: transparent;
 }
+*/
 
 button:active {
   opacity: 0.6;
@@ -34,7 +36,7 @@ button:active {
     display: flex;
     justify-content: center;
 }
-  
+
 .justify-end {
     display: flex;
     justify-content: flex-end;
@@ -63,4 +65,3 @@ button:active {
     display: flex;
     align-items: flex-end;
 }
-   

+ 7 - 6
frontend/src/utils/appfun.ts

@@ -1,6 +1,7 @@
-import { ossResize } from './oss'
-export  {
-  // 格式化图片
-  ossResize,
-  // 获取图片信息
-} 
+
+//获取文件路径
+export  function getFilePath (file_path){
+    if(file_path) return file_path;
+    return null
+}
+

+ 4 - 0
frontend/src/utils/ipc.ts

@@ -26,6 +26,10 @@ const icpList = {
         saveDeviceConfig: 'controller.setting.saveDeviceConfig',
         getDeviceConfigList: 'controller.setting.getDeviceConfigList',
         resetDeviceConfig: 'controller.setting.resetDeviceConfig',
+    },
+    takePhoto:{
+        getPhotoRecords: 'controller.takephoto.getPhotoRecords',
+        delectGoodsArts: 'controller.takephoto.delectGoodsArts'
     }
 }
 

+ 134 - 75
frontend/src/views/Photography/shot.vue

@@ -47,9 +47,10 @@
                 <span class="method-description">手工输入货号</span>
               </div>
               <div class="input-container flex-row">
-                <el-input class="input-item" v-model="goods_art_no" placeholder="请输入货号">
+                <el-input class="input-item" v-model="goods_art_no_tpl" placeholder="请输入货号">
                   <template #append>
-                    <el-button class="input-button" type="primary" @click="runGoods">确认</el-button>
+
+                    <el-button class="input-button" type="primary" @click="saveGoodsArtNo">确认</el-button>
                   </template>
                 </el-input>
 
@@ -84,28 +85,34 @@
 
       </div>
       <div class="history-section flex-col">
-          <span class="history-title">拍摄记录</span>
+          <span class="history-title flex between">
+            <div>拍摄记录</div>
+            <div class="c-666 fs-12" v-if="goodsList.length">
+                    <el-button @click="delAll" class="input-button" type="primary" size="mini">一键删除</el-button>
+            </div>
+          </span>
           <img class="divider-line" referrerpolicy="no-referrer" src="@/assets/images/Photography/divider-line.png" />
           <div class="history-warp">
 
-              <div class="history-item clearfix"  v-for="item in goodsList" style="padding:10px;">
+              <div class="history-item clearfix"  v-for="item,index in goodsList" style="padding:10px;">
                 <div class="flex  between flex-item  c-333">
                   <div class="chaochu flex-item flex left">货号:{{ item.goods_art_no }}</div>
-                  <div class="c-666 fs-12">{{ item.time }}</div>
+                  <div class="c-666 fs-12">{{ getTime(item.action_time) }}</div>
                 </div>
                 <div class="mar-top-10" style="width: 100%" >
                     <component class="history-item_image"
-                         v-loading="!src"
-                         v-for="src in item.images"
-                               :is="src ? 'div' : 'p'"
+                         v-loading="!image.image_path && runAction.goods_art_no == item.goods_art_no"
+                         v-for="image in item.items"
+                               :is="image.image_path ? 'div' : 'p'"
+
                     >
                       <el-popover
                           popper-class="shot-image-popper"
                           placement="left"
-                          v-if="src"
+                          v-if="image.image_path"
                       >
                         <template #reference>
-                          <el-image  :src="src"  fit="contain" >
+                          <el-image  :src="getFilePath(image.image_path)"  fit="contain" >
                             <template #error>
                               <div class="image-slot"></div>
                             </template>
@@ -113,7 +120,7 @@
                         </template>
 
 
-                        <el-image  :src="src"  fit="contain" >
+                        <el-image  :src="getFilePath(image.image_path)"  fit="contain" >
                           <template #error>
                             <div class="image-slot"></div>
                           </template>
@@ -121,7 +128,7 @@
                       </el-popover>
 
 
-                      <el-image  :src="src"  fit="contain" v-else>
+                      <el-image :src="getFilePath(image.image_path)"  fit="contain" v-else>
                         <template #error>
                           <div class="image-slot"></div>
                         </template>
@@ -151,98 +158,150 @@
 <script setup lang="ts">
 import headerBar from '@/components/header-bar/index.vue'
 import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
-import { ossResize } from '@/utils/appfun'
 import icpList from '@/utils/ipc'
 import client from "@/stores/modules/client";
 import socket from "@/stores/modules/socket";
+import { ElMessage ,ElMessageBox } from 'element-plus'
+import { getFilePath } from '@/utils/appfun'
 
-const goods_art_no = ref('')
-const loading = ref(true)
-const test_image_url = ref('https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png')
 
 const clientStore = client();
+
+const  goods_art_no_tpl = ref('')
+const  goods_art_no = ref('')
 const runAction = ref({
   "action": "",
   "goods_art_no": ""
 })
 
+// 初始化 WebSocket 状态管理
+const socketStore = socket()
 
-const goodsList = reactive(
-    [
-      {
-        goods_art_no:"123456789123456789123456789",
-        image_counts:6,
-        images:['file:\\\C:\\Users\\Administrator\\Desktop\\图片\\已扣图\\123.png','','','','','','',''],
-        time:"03/20 14:45"
-      },
-      {
-        goods_art_no:"123456789",
-        image_counts:6,
-        images:['','','','','','','',''],
-        time:"25/03/20 14:45"
-      },
-      {
-        goods_art_no:"123456789",
-        image_counts:6,
-        images:['','','','','','','',''],
-        time:"25/03/20 14:45"
-      },
-      {
-        goods_art_no:"123456789",
-        image_counts:6,
-        images:['','','','','','','',''],
-        time:"25/03/20 14:45"
-      },
-      {
-        goods_art_no:"123456789",
-        image_counts:6,
-        images:['','','','','','','',''],
-        time:"25/03/20 14:45"
-      }
-    ]
-)
 
-onMounted(() => {
-  clientStore.ipc.on(icpList.socket.message + '_blue_tooth_scan', (event, result) => {
-    if (result.code === 0 && result.data?.data) {
-      runGoods(result.data?.data)
+function saveGoodsArtNo(){
+  if(goods_art_no_tpl.value) goods_art_no.value = goods_art_no_tpl.value
+
+}
+
+//获取拍照记录
+async function getPhotoRecords(params?:{}) {
+  clientStore.ipc.removeAllListeners(icpList.takePhoto.getPhotoRecords);
+  clientStore.ipc.send(icpList.takePhoto.getPhotoRecords,{
+    ...params,
+    page:1,
+    size:100,
+  });
+  console.log({
+    ...params,
+    page:1,
+    size:100,
+  })
+  clientStore.ipc.on(icpList.takePhoto.getPhotoRecords, (event, result) => {
+
+    console.log('getPhotoRecords');
+    console.log(result);
+    clientStore.ipc.removeAllListeners(icpList.takePhoto.getPhotoRecords);
+    if(result.code === 0){
+      goodsList.value = result.data.list
+    }else if(result.msg) {
+      ElMessage.error(result.msg)
     }
   });
+}
 
-  clientStore.ipc.on(icpList.socket.message + '_mcu', (event, result) => {
-    console.log('mcu')
-    console.log(result)
+//执行拍照   扫了货号,点击遥控器
+async function runGoods(data) {
+  await socketStore.connectSocket();
+  socketStore.sendMessage({
+    type: 'run_mcu',
+    data,
   })
+  runAction.value = data
+  goods_art_no.value = ''
+  goods_art_no_tpl.value = ''
+}
+
+
+const goodsList = ref([])
+
+const getTime = function(time){
+  if(!time) return null
+  return time.replace('T',' ').substr(5,11)
+}
+async function delAll(){
+    let params = goodsList.value.map(item=>item.goods_art_no)
+    await ElMessageBox.confirm('确定要删除当下的历史记录吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+    })
+    del({goods_art_nos:params})
+}
+const del = async function(params){
+
+  clientStore.ipc.removeAllListeners(icpList.takePhoto.delectGoodsArts);
+  clientStore.ipc.send(icpList.takePhoto.delectGoodsArts,params);
+  clientStore.ipc.on(icpList.takePhoto.delectGoodsArts, (event, result) => {
+    clientStore.ipc.removeAllListeners(icpList.takePhoto.delectGoodsArts);
+    if(result.code === 0){
+      ElMessage.info('货号删除成功')
+      getPhotoRecords()
+    }else if(result.msg) {
+      ElMessage.error(result.msg)
+    }
+  });
+
+}
+
+
+onMounted(async () => {
+  //扫货号
+  clientStore.ipc.on(icpList.socket.message + '_blue_tooth_scan', (event, result) => {
+
+    console.log('_blue_tooth_scan')
+    if (result.code === 0 && result.data?.data) {
+      if(result.data?.data.goods_art_no) runGoods(result.data?.data)
+      if(!result.data?.data.goods_art_no && goods_art_no.value){
+        console.log('手工')
+        console.log({
+          ...result.data?.data,
+          goods_art_no: goods_art_no.value
+        })
+        runGoods({
+          ...result.data?.data,
+          goods_art_no: goods_art_no.value
+        })
+      }
 
-  clientStore.ipc.on(icpList.socket.message + '_image_process', (event, result) => {
-    if(result.msg === 'MCU 命令已发送完成'){
-      result.image_counts   //拍照数量
-      result.goods_art_no   //货号
     }
+  });
+
+  await getPhotoRecords();
+  // 扫码后 货号入库
+  clientStore.ipc.on(icpList.socket.message + '_image_process', (event, result) => {
     console.log('_image_process')
     console.log(result)
+    getPhotoRecords()
+  })
+  clientStore.ipc.on(icpList.socket.message + '_photo_take', (event, result) => {
+    console.log('_photo_take')
+    console.log(result)
+    if(result.status === 2 && result.msg.includes('执行完成')) getPhotoRecords()
+
   })
+
+
+
+
+
 })
 
 //关闭页面  去掉监听
 onBeforeUnmount(() => {
   clientStore.ipc.removeAllListeners(icpList.socket.message + '_blue_tooth_scan');
-  clientStore.ipc.removeAllListeners(icpList.socket.message + '_mcu');
   clientStore.ipc.removeAllListeners(icpList.socket.message + '_image_process');
+  clientStore.ipc.removeAllListeners(icpList.socket.message + '_photo_take');
 })
 
-// 初始化 WebSocket 状态管理
-const socketStore = socket()
-
-async function runGoods(data) {
-  await socketStore.connectSocket();
-  socketStore.sendMessage({
-    type: 'run_mcu',
-    data,
-  })
-
-  runAction.value = data
-}
 </script>
 
 <style  lang="scss">
@@ -665,7 +724,7 @@ async function runGoods(data) {
         padding-top: 30px;
 
         .history-title {
-          width: 64px;
+          width: calc(100% - 20px);
           height: 22px;
           overflow-wrap: break-word;
           color: rgba(51, 51, 51, 1);