瀏覽代碼

主图与详情

kongwenhao 8 月之前
父節點
當前提交
078a145f41
共有 3 個文件被更改,包括 450 次插入58 次删除
  1. 17 0
      electron/api/generate.js
  2. 43 0
      electron/controller/generate.js
  3. 390 58
      frontend/src/views/Photography/detail.vue

+ 17 - 0
electron/api/generate.js

@@ -0,0 +1,17 @@
+const { post,get } = require('./request')
+
+module.exports = {
+  // 生成主图详情页
+  generatePhotoDetail(data){
+    console.log('generatePhotoDetail')
+    console.log(data)
+    return post({
+      url: '/handle_detail',
+      data: data,
+      headers:{
+        'Content-Type':"application/json",
+      }
+    })
+  }
+
+}

+ 43 - 0
electron/controller/generate.js

@@ -0,0 +1,43 @@
+'use strict';
+
+const { Controller } = require('ee-core');
+const Log = require('ee-core/log');
+const Services = require('ee-core/services');
+const path = require('path');
+const fs = require('fs');
+const { generatePhotoDetail } = require('../api/generate');
+
+const errData = {
+  msg :'请求失败,请联系管理员',
+  code:999
+}
+
+/**
+ * 设置控制器
+ * @class
+ */
+class GenerateController extends Controller {
+
+  constructor(ctx) {
+    super(ctx);
+    this.configPath = path.join(__dirname, '..', 'config', 'app.config.json');
+  }
+
+  /**
+   * 获取设备配置列表
+   */
+  async generatePhotoDetail(args) {
+    try {
+      const result = await generatePhotoDetail(args);
+      if(result.data)  return result.data
+      return errData;
+    } catch (error) {
+      Log.error('主图详情生成失败:', error);
+      return errData;
+    }
+  }
+
+}
+
+GenerateController.toString = () => '[class GenerateController]';
+module.exports = GenerateController;

+ 390 - 58
frontend/src/views/Photography/detail.vue

@@ -1,29 +1,70 @@
 <template>
 
-  <headerBar
-      title="拍摄商品"
-      :menu="[
-        {
-          type:'setting'
-        },
-        {
-          name:'详情高级配置',
-          click:openPhotographySeniorDetail
-        }
-    ]"
-  />
+  <headerBar title="拍摄商品" :menu="[
+    {
+      type: 'setting'
+    },
+    {
+      name: '详情高级配置',
+      click: openPhotographySeniorDetail
+    }
+  ]" />
   <div class="detail-container">
-    <div style="padding: 20px;">
+    <div>
       <!-- 主图LOGO部分 -->
       <div class="logo-section flex left top">
         <div class="section-title">
           <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
           主图LOGO:
         </div>
-        <upload :value="form.logoImage" @input="onInput"></upload>
+        <upload :value="form.logo_path" @input="onInput"></upload>
       </div>
 
       <el-divider />
+      <!-- 图片抠图与货号图生成 -->
+      <div class="section">
+        <div class="section-title">
+          <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
+          图片抠图与货号图生成
+        </div>
+        <div class="section-content">
+          <div v-if="showTips" class="instruction-out flex top left">
+            <img style="fill: #000" src="@/assets/images/xinxi.svg" />
+            <ol class="instruction-list">
+              <li>请在下方确认图片拍摄过程中的顺序,确保所有拍摄的图片的顺序一致。</li>
+              <li>使用中英文语号分隔。</li>
+              <li>图片的名称不能随意修改,否则无法正常生成详情页。</li>
+              <li>现有图片名称有:俯视、侧视、后视、鞋底、内里</li>
+            </ol>
+            <el-icon @click="showTips = false" class="close-icon">
+              <Close />
+            </el-icon>
+          </div>
+
+          <!-- 货号文件夹 -->
+          <!--    <div class="form-item">
+            <div class="label">货号文件夹:</div>
+            <div class="folder-warp">
+              <div class="folder-input">
+                <el-input style="width: 60%;" v-model="folderPath" type="textarea" :rows="2" readonly
+                  placeholder="请选择货号文件夹" />
+                <el-button class="check-button" type="primary" @click="selectFolder">
+                  <img src="@/assets/images/Photography/wenjian.png" style="width: 14px; " />
+                  选择目标文件夹</el-button>
+              </div>
+              <div class="hint">
+                <el-icon>
+                  <Warning />
+                </el-icon> <text>选择货号的上级文件夹</text>
+              </div>
+            </div>
+          </div>
+         -->
+
+        </div>
+      </div>
+      <el-divider />
+
       <!-- 选择详情模板部分 -->
       <div class="template-section ">
         <div class="flex between">
@@ -40,24 +81,62 @@
 
         <div class="template-list">
           <div v-for="(template, index) in visibleTemplates" :key="index" class="template-item"
-            @click="form.templateId = template.id">
-            <el-image :src="test_image_url" fit="contain" class="cur-p" style="width: 100%; display: block;" />
-            <div class="select-warp" :class="form.templateId == template.id ? 'active' : ''">
+            @click="form.selectTemplate = template">
+            <el-image :src="template.template_cover_image" fit="contain" class="cur-p"
+              style="width: 100%; display: block;" />
+            <div class="select-warp" :class="form.selectTemplate.id == template.id ? 'active' : ''">
               <el-icon color="#FFFFFF">
                 <Select />
               </el-icon>
             </div>
             <div class="template-info">
-              <span class="mar-left-10 chaochu_1">{{ template.templateId }}</span>
+              <span class="mar-left-10 chaochu_1">{{ template.template_name }}</span>
               <div class="template-view" @click="viewTemplate(template)">查看</div>
             </div>
           </div>
         </div>
       </div>
+      <el-divider />
 
+      <!-- 详情高级配置 -->
+      <div class="section">
+        <div class="section-title">
+          <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
+          详情高级配置
+        </div>
+        <div class="section-content">
+          <!-- 图片顺序 -->
+          <div class="form-item">
+            <div class="label">图片顺序:</div>
+            <el-input v-model="imageOrder" placeholder="请输入图片顺序" class="specific-page-input">
+              <template #append>
+                <el-button class="explain-btn" link type="primary">说明</el-button>
+              </template>
+            </el-input>
+          </div>
+
+          <!-- 同款检验 -->
+          <!--   <div class="form-item">
+            <div class="label">同款检验:</div>
+            <el-checkbox v-model="checkSimilar">同款下货号必须齐全</el-checkbox>
+          </div>
+-->
+          <!-- 可指定页面独修改 -->
+          <!--      <div class="form-item">
+            <div class="label">可指定页面独修改:</div>
+            <el-input v-model="specificPage" placeholder="请输入入需要单独修改的页面,示例:4:1 (需修改模版的编号:第一张)"
+              class="specific-page-input">
+              <template #append>
+                <el-button class="explain-btn" link type="primary">说明</el-button>
+              </template>
+            </el-input>
+          </div>
+          -->
+        </div>
+      </div>
+      <el-divider />
       <!-- 详情资料准备部分 -->
       <div class="data-prep-section">
-
         <div class="flex-item left">
           <div class="section-title">
             <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
@@ -83,45 +162,69 @@
           </div>
         </div>
       </div>
-
-      <!-- 开始生成按钮 -->
-      <button class="generate-button button--primary1" @click="generate">开始生成</button>
     </div>
-    <el-dialog v-model="dialogVisible">
-      <img style="width: 100%;" :src="dialogImageUrl" alt="Preview Image" />
-    </el-dialog>
+    <!-- 底部按钮 -->
+    <div class="footer">
+      <!-- <el-button class="button--primary1 footer-button" type="primary" @click="saveConfig">保存配置</el-button> -->
+      <el-button class="button--primary1 footer-button" type="primary" @click="startProcess">开始处理</el-button>
+      <el-button class="button--primary1 footer-button" type="primary" @click="generate">开始生成</el-button>
+    </div>
   </div>
+
+
+  <loading-dialog v-model="loadingDialogVisible" :progress="progress" :message="message" :show-button="showButton"
+    @button-click="handleComplete" />
+  <el-dialog v-model="dialogVisible">
+    <img style="width: 100%;" :src="dialogImageUrl" alt="Preview Image" />
+  </el-dialog>
+
+
+
 </template>
 
 <script lang="ts" setup>
+
+import { getCompanyTemplatesApi } from '@/apis/other'
+import tokenInfo from '@/stores/modules/token';
+import useUserInfo from "@/stores/modules/user";
+
+import { ElMessage, ElMessageBox } from 'element-plus'
+
 import headerBar from '@/components/header-bar/index.vue'
-import { ref, computed, reactive } from 'vue';
+import { ref, computed, reactive, onMounted } from 'vue';
 import { Select } from '@element-plus/icons-vue'
 import upload from '@/components/upload'
 import client from "@/stores/modules/client";
 import icpList from '@/utils/ipc'
 const clientStore = client();
 import { getRouterUrl } from '@/utils/appfun'
-import {useRouter} from "vue-router";
-const test_image_url = ref('https://ossimg.valimart.net/uploads/vali_ai/20230927/169580582298394.png')
-
-// 模拟数据
-const templates = [
-  { id: 1101, templateId: '某某模版编号1', preview: '...' },
-  { id: 1102, templateId: '某某模版编号2', preview: '...' },
-  { id: 1103, templateId: '某某模版编号3', preview: '...' },
-  { id: 1104, templateId: '某某模版编号4', preview: '...' },
-  { id: 1105, templateId: '某某模版编号5', preview: '...' },
-  { id: 1106, templateId: '某某模版编号6', preview: '...' },
-  { id: 1107, templateId: '某某模版编号7', preview: '...' },
-  { id: 1108, templateId: '某某模版编号8', preview: '...' },
-  { id: 1109, templateId: '某某模版编号9', preview: '...' },
-  { id: 1110, templateId: '某某模版编号10', preview: '...' },
-  { id: 1111, templateId: '某某模版编号11', preview: '...' },
-  { id: 1112, templateId: '某某模版编号12', preview: '...' },
-];
+import { useRouter } from "vue-router";
+
+import { Close, Warning } from '@element-plus/icons-vue'
+import LoadingDialog from '@/views/Photography/components/LoadingDialog.vue'
+
+const showTips = ref(true)
+
+const folderPath = ref('') //货号文件夹
+// const reportMode = ref('normal') // 抠图模式
+const imageOrder = ref('俯视、侧视、后跟、鞋底、内里、组合、组合2、组合3') // 图片顺序
+const checkSimilar = ref(false) // 同款检验
+const specificPage = ref('')  // 可指定页面独修改
+
+
+
+// 完成目录
+const completeDirectory = ref('')
+
+
+const loadingDialogVisible = ref(false)
+const progress = ref(0)
+const message = ref('正在为您处理,请稍后')
+const showButton = ref(true)
+
+let templates = ref([])
 // 状态变量
-const totalPage = ref(3);
+const totalPage = ref(0);
 const itemsPerPage = 4; // 每页显示的模板数量
 const dialogVisible = ref(false);
 const dialogImageUrl = ref('');
@@ -130,40 +233,108 @@ const queryParams = reactive({ // 分页查询参数
   current: 1,
 })
 const form = reactive({
+  selectTemplate: {}, //选中的模板 
   dataType: '1', // 1: 选择excel文件 2: 系统对接
-  logoImage: '', // 主图LOGO
-  templateId: 1101,
+  logo_path: '', // 主图LOGO
   excelFilePath: 'D:\\MyDocuments\\PythonCode\\MyPython\\red_dragonfly\\deal_pics\\auto_capture_V2\\auto_photo', // 商品基础资料EXCEL文件选择
-
 })
+onMounted(() => {
+  getCompanyTemplates()
+})
+
+
 // 计算属性,获取当前页可见的模板
 const visibleTemplates = computed(() => {
   const startIndex = (queryParams.current - 1) * itemsPerPage;
-  const data = templates.slice(startIndex, startIndex + itemsPerPage);
+  const data = templates.value.slice(startIndex, startIndex + itemsPerPage);
   return data
 });
 // 查看模板详情
 const viewTemplate = (template) => {
-  console.log('查看模板详情', template);
   // 展示大图
   dialogVisible.value = true
-  dialogImageUrl.value = 'https://ossimg.valimart.net/uploads/vali_ai/20250218/173984697449910.png'
+  dialogImageUrl.value = template.template_preview_image
 
 };
+// 获取模版列表
+const getCompanyTemplates = async () => {
+  const { data } = await getCompanyTemplatesApi()
+  templates.value = data.list
+  // 默认选中第一个模板
+  if (templates.value.length > 0) {
+    form.selectTemplate = templates.value[0]
+  }
+  // 计算总页数
+  totalPage.value = Math.ceil(templates.value.length / itemsPerPage);
+}
+
+
 const onCurrentChange = (page) => {
   queryParams.current = page;
 };
 const onSizeChange = (data) => {
 };
+
+
+
 // 开始生成操作
-const generate = () => {
-  // 这里添加实际生成主图和详情的逻辑
-  console.log('queryParams', form)
-  
+const generate = async function () {
+  const tokenInfoStore = tokenInfo();
+  const token = tokenInfoStore.getToken; // 使用 getToken() 获取 token
+  let temp_list = []
+  templates.value.map(item => {
+    temp_list.push({
+      template_id: item.template_id,
+      template_local_classes: item.template_local_classes,
+    })
+  })
+  const params = {
+    goods_art_no: 'ARN1411512',
+    logo_path: form.logo_path,
+    temp_name: form.selectTemplate.template_id,
+    excel_path: '',
+    template_image_order: form.selectTemplate.template_image_order,
+    temp_list,
+    token,
+  }
+  loadingDialogVisible.value = true
+  progress.value = 0
+  showButton.value = true
+
+  const interval = setInterval(() => {
+    if (progress.value < 100) {
+      progress.value += 10
+    }
+  }, 1000)
+  clientStore.ipc.removeAllListeners(icpList.generate.generatePhotoDetail);
+  clientStore.ipc.send(icpList.generate.generatePhotoDetail, params);
+  clientStore.ipc.on(icpList.generate.generatePhotoDetail, (event, result) => {
+    clientStore.ipc.removeAllListeners(icpList.generate.generatePhotoDetail);
+    console.log("%c Line:306 🍻 result", "color:#42b983", result);
+    clearInterval(interval)
+    if (result.code === 0) {
+      const href = result.data.out_put_dir
+      completeDirectory.value = href
+      progress.value = 100
+      message.value = '全部处理完毕'
+      showButton.value = false
+    } else {
+      showButton.value = false
+      if (result.msg) {
+        ElMessage.error(result.msg)
+      }
+    }
+  });
+}
+
+
+
+
+
+
 
-};
 const onInput = (value) => {
-  form.logoImage = value
+  form.logo_path = value
 }
 
 function selectExcel() {
@@ -202,13 +373,57 @@ function openPhotographySeniorDetail() {
 }
 
 
+const startProcess = () => {
+  loadingDialogVisible.value = true
+  progress.value = 0
+  showButton.value = true
+  // 模拟进度更新
+  const interval = setInterval(() => {
+    if (progress.value < 100) {
+      progress.value += 10
+    } else {
+      clearInterval(interval)
+      message.value = '全部处理完毕'
+      showButton.value = false
+    }
+  }, 500)
+}
+
+const handleComplete = () => {
+  loadingDialogVisible.value = false
+  // 这里可以添加打开目录的逻辑
+  // 打开目录
+  clientStore.ipc.removeAllListeners(icpList.utils.openDirectory);
+  console.log('打开目录')
+  clientStore.ipc.removeAllListeners(icpList.utils.shellFun);
+  let params = {
+      action: 'openPath',
+      params: completeDirectory.value
+      // params: 'C:\Users\\21333\\Desktop\\HQT\\151405492752642685067862.jpg'
+  }
+  clientStore.ipc.send(icpList.utils.shellFun, params);
+}
+
+const selectFolder = () => {
+  clientStore.ipc.removeAllListeners(icpList.utils.openDirectory);
+  clientStore.ipc.send(icpList.utils.openDirectory);
+  clientStore.ipc.on(icpList.utils.openDirectory, async (event, result) => {
+    folderPath.value = result
+    clientStore.ipc.removeAllListeners(icpList.utils.openDirectory);
+  })
+}
+
+
 </script>
 
 <style lang="scss" scoped>
 .detail-container {
   background-color: #EAECED;
   width: 100%;
-  min-width: 600px
+  min-width: 600px;
+  padding: 20px;
+  overflow: hidden;
+
 }
 
 .logo-section,
@@ -336,4 +551,121 @@ function openPhotographySeniorDetail() {
   margin-bottom: 16px;
   color: #474747;
 }
+
+
+
+.section {
+  margin-bottom: 24px;
+
+  .section-title {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    font-weight: bold;
+    margin-bottom: 16px;
+    color: #474747;
+  }
+
+  .section-content {
+    padding-left: 16px;
+  }
+}
+
+.instruction-out {
+  background: #EAF3FF;
+  border-radius: 4px;
+  border: 1px solid #CBE1FF;
+  padding: 10px 20px;
+  width: 80%;
+  position: relative;
+
+  .instruction-list {
+    margin: 0px 0 0 10px;
+    padding-left: 20px;
+    padding-right: 40px;
+    width: 100%;
+
+    li {
+      margin-bottom: 4px;
+      text-align: left;
+      font-size: 14px;
+    }
+  }
+
+  .close-icon {
+    position: absolute;
+    top: 12px;
+    right: 19px;
+  }
+}
+
+
+
+.form-item {
+  margin: 16px 0;
+  display: flex;
+
+
+  .label {
+    min-width: 120px;
+    margin-right: 12px;
+  }
+
+  .folder-warp {
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+
+    .folder-input {
+      flex: 1;
+      display: flex;
+      align-items: center;
+
+      .check-button {
+        background: #DFE2E3;
+        border-radius: 6px;
+        padding: 6px 12px;
+        color: #2957FF;
+        margin-left: 20px;
+      }
+
+    }
+  }
+
+  .hint {
+    text-align: left;
+    color: #999;
+    margin-top: 6px;
+    font-size: 14px;
+    color: #FF4C00;
+    font-style: normal;
+  }
+
+  .specific-page-input {
+    flex: 1;
+  }
+}
+
+.image-order {
+  flex: 1;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.footer {
+  display: flex;
+  justify-content: center;
+  margin-top: 24px;
+
+  .footer-button {
+    padding: 10px 20px;
+  }
+}
+
+.explain-btn {
+  padding-left: 20px;
+  padding-right: 20px;
+  color: #2957FF !important;
+}
 </style>