Parcourir la source

local:shopify promotion

chenjiaxin il y a 4 mois
Parent
commit
459443dffa

+ 1 - 0
package.json

@@ -6,6 +6,7 @@
   "license": "MIT",
   "scripts": {
     "dev": "vue-cli-service serve --inline --host swings.pim.com",
+    "dev:local": "vue-cli-service serve",
     "build:prod": "vue-cli-service build",
     "build:stage": "vue-cli-service build --mode staging",
     "preview": "node build/index.js --preview",

+ 8 - 0
src/lang/en.js

@@ -483,5 +483,13 @@ export default {
     tagsView: "Open Tags-View",
     fixedHeader: "Fixed Header",
     sidebarLogo: "Sidebar Logo"
+  },
+  shopifyPromotion: {
+    promotionMessage: "Promotional Information",
+    targetType: "Promotional Application Type",
+    useType: "Usage Type",
+    priceSet: 'Sales Price',//销售价格明细
+    paySet: 'Pay Price',//支付价格
+    amountSet: 'Discount Price',//折扣金额明细
   }
 };

+ 163 - 142
src/lang/es.js

@@ -1,175 +1,196 @@
 export default {
   route: {
-    dashboard: 'Panel de control',
-    documentation: 'Documentación',
-    guide: 'Guía',
-    permission: 'Permisos',
-    rolePermission: 'Permisos de rol',
-    pagePermission: 'Permisos de la página',
-    directivePermission: 'Permisos de la directiva',
-    icons: 'Iconos',
-    components: 'Componentes',
-    tinymce: 'Tinymce',
-    markdown: 'Markdown',
-    jsonEditor: 'Editor JSON',
-    dndList: 'Lista Dnd',
-    splitPane: 'Panel dividido',
-    avatarUpload: 'Subir avatar',
-    dropzone: 'Subir ficheros',
-    sticky: 'Sticky',
-    countTo: 'CountTo',
-    componentMixin: 'Mixin',
-    backToTop: 'Ir arriba',
-    dragDialog: 'Drag Dialog',
-    dragSelect: 'Drag Select',
-    dragKanban: 'Drag Kanban',
-    charts: 'Gráficos',
-    keyboardChart: 'Keyboard Chart',
-    lineChart: 'Gráfico de líneas',
-    mixChart: 'Mix Chart',
-    example: 'Ejemplo',
-    nested: 'Rutas anidadass',
-    menu1: 'Menu 1',
-    'menu1-1': 'Menu 1-1',
-    'menu1-2': 'Menu 1-2',
-    'menu1-2-1': 'Menu 1-2-1',
-    'menu1-2-2': 'Menu 1-2-2',
-    'menu1-3': 'Menu 1-3',
-    menu2: 'Menu 2',
-    Table: 'Tabla',
-    dynamicTable: 'Tabla dinámica',
-    dragTable: 'Arrastrar tabla',
-    inlineEditTable: 'Editor',
-    complexTable: 'Complex Table',
-    tab: 'Pestaña',
-    form: 'Formulario',
-    createArticle: 'Crear artículo',
-    editArticle: 'Editar artículo',
-    articleList: 'Listado de artículos',
-    errorPages: 'Páginas de error',
-    page401: '401',
-    page404: '404',
-    errorLog: 'Registro de errores',
-    excel: 'Excel',
-    exportExcel: 'Exportar a Excel',
-    selectExcel: 'Export seleccionado',
-    mergeHeader: 'Merge Header',
-    uploadExcel: 'Subir Excel',
-    zip: 'Zip',
-    pdf: 'PDF',
-    exportZip: 'Exportar a Zip',
-    theme: 'Tema',
-    clipboardDemo: 'Clipboard',
-    i18n: 'I18n',
-    externalLink: 'Enlace externo',
-    profile: 'Profile'
+    dashboard: "Panel de control",
+    documentation: "Documentación",
+    guide: "Guía",
+    permission: "Permisos",
+    rolePermission: "Permisos de rol",
+    pagePermission: "Permisos de la página",
+    directivePermission: "Permisos de la directiva",
+    icons: "Iconos",
+    components: "Componentes",
+    tinymce: "Tinymce",
+    markdown: "Markdown",
+    jsonEditor: "Editor JSON",
+    dndList: "Lista Dnd",
+    splitPane: "Panel dividido",
+    avatarUpload: "Subir avatar",
+    dropzone: "Subir ficheros",
+    sticky: "Sticky",
+    countTo: "CountTo",
+    componentMixin: "Mixin",
+    backToTop: "Ir arriba",
+    dragDialog: "Drag Dialog",
+    dragSelect: "Drag Select",
+    dragKanban: "Drag Kanban",
+    charts: "Gráficos",
+    keyboardChart: "Keyboard Chart",
+    lineChart: "Gráfico de líneas",
+    mixChart: "Mix Chart",
+    example: "Ejemplo",
+    nested: "Rutas anidadass",
+    menu1: "Menu 1",
+    "menu1-1": "Menu 1-1",
+    "menu1-2": "Menu 1-2",
+    "menu1-2-1": "Menu 1-2-1",
+    "menu1-2-2": "Menu 1-2-2",
+    "menu1-3": "Menu 1-3",
+    menu2: "Menu 2",
+    Table: "Tabla",
+    dynamicTable: "Tabla dinámica",
+    dragTable: "Arrastrar tabla",
+    inlineEditTable: "Editor",
+    complexTable: "Complex Table",
+    tab: "Pestaña",
+    form: "Formulario",
+    createArticle: "Crear artículo",
+    editArticle: "Editar artículo",
+    articleList: "Listado de artículos",
+    errorPages: "Páginas de error",
+    page401: "401",
+    page404: "404",
+    errorLog: "Registro de errores",
+    excel: "Excel",
+    exportExcel: "Exportar a Excel",
+    selectExcel: "Export seleccionado",
+    mergeHeader: "Merge Header",
+    uploadExcel: "Subir Excel",
+    zip: "Zip",
+    pdf: "PDF",
+    exportZip: "Exportar a Zip",
+    theme: "Tema",
+    clipboardDemo: "Clipboard",
+    i18n: "I18n",
+    externalLink: "Enlace externo",
+    profile: "Profile"
   },
   navbar: {
-    logOut: 'Salir',
-    dashboard: 'Panel de control',
-    github: 'Github',
-    theme: 'Tema',
-    size: 'Tamaño global',
-    profile: 'Profile'
+    logOut: "Salir",
+    dashboard: "Panel de control",
+    github: "Github",
+    theme: "Tema",
+    size: "Tamaño global",
+    profile: "Profile"
   },
   login: {
-    title: 'Formulario de acceso',
-    logIn: 'Acceso',
-    username: 'Usuario',
-    password: 'Contraseña',
-    any: 'nada',
-    thirdparty: 'Conectar con',
-    thirdpartyTips: 'No se puede simular en local, así que combine su propia simulación de negocios. ! !'
+    title: "Formulario de acceso",
+    logIn: "Acceso",
+    username: "Usuario",
+    password: "Contraseña",
+    any: "nada",
+    thirdparty: "Conectar con",
+    thirdpartyTips:
+      "No se puede simular en local, así que combine su propia simulación de negocios. ! !"
   },
   documentation: {
-    documentation: 'Documentación',
-    github: 'Repositorio Github'
+    documentation: "Documentación",
+    github: "Repositorio Github"
   },
   permission: {
-    addRole: 'Nuevo rol',
-    editPermission: 'Permiso de edición',
-    roles: 'Tus permisos',
-    switchRoles: 'Cambiar permisos',
-    tips: 'In some cases it is not suitable to use v-permission, such as element Tab component or el-table-column and other asynchronous rendering dom cases which can only be achieved by manually setting the v-if.',
-    delete: 'Borrar',
-    confirm: 'Confirmar',
-    cancel: 'Cancelar'
+    addRole: "Nuevo rol",
+    editPermission: "Permiso de edición",
+    roles: "Tus permisos",
+    switchRoles: "Cambiar permisos",
+    tips:
+      "In some cases it is not suitable to use v-permission, such as element Tab component or el-table-column and other asynchronous rendering dom cases which can only be achieved by manually setting the v-if.",
+    delete: "Borrar",
+    confirm: "Confirmar",
+    cancel: "Cancelar"
   },
   guide: {
-    description: 'The guide page is useful for some people who entered the project for the first time. You can briefly introduce the features of the project. Demo is based on ',
-    button: 'Ver guía'
+    description:
+      "The guide page is useful for some people who entered the project for the first time. You can briefly introduce the features of the project. Demo is based on ",
+    button: "Ver guía"
   },
   components: {
-    documentation: 'Documentación',
-    tinymceTips: 'Rich text editor is a core part of management system, but at the same time is a place with lots of problems. In the process of selecting rich texts, I also walked a lot of detours. The common rich text editors in the market are basically used, and the finally chose Tinymce. See documentation for more detailed rich text editor comparisons and introductions.',
-    dropzoneTips: 'Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.',
-    stickyTips: 'when the page is scrolled to the preset position will be sticky on the top.',
-    backToTopTips1: 'When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner',
-    backToTopTips2: 'You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally',
-    imageUploadTips: 'Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version.'
+    documentation: "Documentación",
+    tinymceTips:
+      "Rich text editor is a core part of management system, but at the same time is a place with lots of problems. In the process of selecting rich texts, I also walked a lot of detours. The common rich text editors in the market are basically used, and the finally chose Tinymce. See documentation for more detailed rich text editor comparisons and introductions.",
+    dropzoneTips:
+      "Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.",
+    stickyTips:
+      "when the page is scrolled to the preset position will be sticky on the top.",
+    backToTopTips1:
+      "When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner",
+    backToTopTips2:
+      "You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally",
+    imageUploadTips:
+      "Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version."
   },
   table: {
-    dynamicTips1: 'Fixed header, sorted by header order',
-    dynamicTips2: 'Not fixed header, sorted by click order',
-    dragTips1: 'Orden por defecto',
-    dragTips2: 'The after dragging order',
-    title: 'Título',
-    importance: 'Importancia',
-    type: 'Tipo',
-    remark: 'Remark',
-    search: 'Buscar',
-    add: 'Añadir',
-    export: 'Exportar',
-    reviewer: 'reviewer',
-    id: 'ID',
-    date: 'Fecha',
-    author: 'Autor',
-    readings: 'Lector',
-    status: 'Estado',
-    actions: 'Acciones',
-    edit: 'Editar',
-    publish: 'Publicar',
-    draft: 'Draft',
-    delete: 'Eliminar',
-    cancel: 'Cancelar',
-    confirm: 'Confirmar'
+    dynamicTips1: "Fixed header, sorted by header order",
+    dynamicTips2: "Not fixed header, sorted by click order",
+    dragTips1: "Orden por defecto",
+    dragTips2: "The after dragging order",
+    title: "Título",
+    importance: "Importancia",
+    type: "Tipo",
+    remark: "Remark",
+    search: "Buscar",
+    add: "Añadir",
+    export: "Exportar",
+    reviewer: "reviewer",
+    id: "ID",
+    date: "Fecha",
+    author: "Autor",
+    readings: "Lector",
+    status: "Estado",
+    actions: "Acciones",
+    edit: "Editar",
+    publish: "Publicar",
+    draft: "Draft",
+    delete: "Eliminar",
+    cancel: "Cancelar",
+    confirm: "Confirmar"
   },
   example: {
-    warning: 'Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all pages directly. See details'
+    warning:
+      "Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all pages directly. See details"
   },
   errorLog: {
-    tips: 'Please click the bug icon in the upper right corner',
-    description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.',
-    documentation: 'Documento de introducción'
+    tips: "Please click the bug icon in the upper right corner",
+    description:
+      "Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.",
+    documentation: "Documento de introducción"
   },
   excel: {
-    export: 'Exportar',
-    selectedExport: 'Exportar seleccionados',
-    placeholder: 'Por favor escribe un nombre de fichero'
+    export: "Exportar",
+    selectedExport: "Exportar seleccionados",
+    placeholder: "Por favor escribe un nombre de fichero"
   },
   zip: {
-    export: 'Exportar',
-    placeholder: 'Por favor escribe un nombre de fichero'
+    export: "Exportar",
+    placeholder: "Por favor escribe un nombre de fichero"
   },
   pdf: {
-    tips: 'Here we use window.print() to implement the feature of downloading pdf.'
+    tips:
+      "Here we use window.print() to implement the feature of downloading pdf."
   },
   theme: {
-    change: 'Cambiar tema',
-    documentation: 'Documentación del tema',
-    tips: 'Tips: It is different from the theme-pick on the navbar is two different skinning methods, each with different application scenarios. Refer to the documentation for details.'
+    change: "Cambiar tema",
+    documentation: "Documentación del tema",
+    tips:
+      "Tips: It is different from the theme-pick on the navbar is two different skinning methods, each with different application scenarios. Refer to the documentation for details."
   },
   tagsView: {
-    refresh: 'Actualizar',
-    close: 'Cerrar',
-    closeOthers: 'Cerrar otros',
-    closeAll: 'Cerrar todos'
+    refresh: "Actualizar",
+    close: "Cerrar",
+    closeOthers: "Cerrar otros",
+    closeAll: "Cerrar todos"
   },
   settings: {
-    title: 'Page style setting',
-    theme: 'Theme Color',
-    tagsView: 'Open Tags-View',
-    fixedHeader: 'Fixed Header',
-    sidebarLogo: 'Sidebar Logo'
+    title: "Page style setting",
+    theme: "Theme Color",
+    tagsView: "Open Tags-View",
+    fixedHeader: "Fixed Header",
+    sidebarLogo: "Sidebar Logo"
+  },
+  shopify: {
+    promotionMessage: "Información promocional",
+    targetType: "Tipo de aplicación promocional",
+    useType: "Tipo de uso",
+    priceSet: 'Precio de venta',//销售价格明细
+    paySet: 'Pagar precio',//支付价格
+    amountSet: 'Precio de descuento',//折扣金额明细
   }
-}
+};

+ 8 - 0
src/lang/ja.js

@@ -399,5 +399,13 @@ export default {
     tagsView: "Tags-View 開く",
     fixedHeader: "Fixed Header",
     sidebarLogo: "Sidebar Logo"
+  },
+  shopify: {
+    promotionMessage: "プロモーション情報",
+    targetType: "プロモーションアプリケーションの種類",
+    useType: "使用タイプ",
+    priceSet: '販売価格',//销售价格明细
+    paySet: '支払い価格',//支付价格
+    amountSet: '割引価格',//折扣金额明细
   }
 };

+ 8 - 5
src/lang/zh.js

@@ -7,8 +7,8 @@ export default {
   label: label,
   view: view,
   place: place,
-  enterTags:"请输入订单标签",
-  tags:"订单标签",
+  enterTags: "请输入订单标签",
+  tags: "订单标签",
   sellerDiscount: "商家折扣",
   platformDiscount: "平台折扣",
   loanAmount: "贷款金额",
@@ -73,7 +73,6 @@ export default {
   mail: "收件人电子邮箱",
   phone: "收件人手机号",
   companyName: "收件公司名",
-
   baseMessage: "基本信息",
   orderStatus: "订单状态",
   orderType: "订单类型",
@@ -195,7 +194,7 @@ export default {
   enterContNo: "请输入固定电话",
   enterMobileNo: "请输入移动电话",
   chooseCountry: "请选择国家/地区",
-  email:"请输入邮箱",
+  email: "请输入邮箱",
   parkOrder: "是否挂起",
   payFrom: "付款开始时间",
   payEnd: "付款结束时间",
@@ -214,7 +213,7 @@ export default {
   returnShoppNo: "退件物流单",
   details: "详情",
   logDetails: "推送日志",
-  operationLog:"操作日志",
+  operationLog: "操作日志",
   shopifyNo: "订单名称",
   postalCode: "邮政编码",
   receiveType: {
@@ -502,5 +501,9 @@ export default {
     tagsView: "开启 Tags-View",
     fixedHeader: "固定 Header",
     sidebarLogo: "侧边栏 Logo"
+  },
+  shopify: {
+    promotionMessage: "促销信息",
+    targetType: "促销应用类型"
   }
 };

+ 9 - 2
src/router/modules/promotion.js

@@ -27,11 +27,18 @@ const promotionRouter = {
       name: "bagProduct",
       meta: { title: "福袋商品" }
     },
+    // {
+    //   path: "promotion",
+    //   component: () => import("@/views/oms/promotion/promotion/index"),
+    //   name: "promotion",
+    //   meta: { title: "promotionConfig" }
+    // },
     {
       path: "promotion",
-      component: () => import("@/views/oms/promotion/promotion/index"),
+      component: () =>
+        import("@/views/oms/promotion/shopifyPromotion/index.vue"),
       name: "promotion",
-      meta: { title: "promotionConfig" }
+      meta: { title: "shopifyPromotion" }
     }
   ]
 };

+ 9 - 8
src/views/oms/order/components/orderGiftCardsTab.vue

@@ -77,16 +77,12 @@
       >
       </el-table-column>
 
-      <el-table-column width="200" :label="$t('containRise')" align="center" >
-        <template slot-scope="scope" >
-          <el-checkbox v-model="scope.row.containRiseCheck" ></el-checkbox>
+      <el-table-column width="200" :label="$t('containRise')" align="center">
+        <template slot-scope="scope">
+          <el-checkbox v-model="scope.row.containRiseCheck"></el-checkbox>
         </template>
       </el-table-column>
-
-
-
     </el-table>
-
   </div>
 </template>
 
@@ -97,6 +93,11 @@ import swPage from "@/views/common/swPage.vue";
 export default {
   name: "orderGiftCardsTab",
   components: { swPage },
+  data() {
+    return {
+      listLoading: false
+    };
+  },
   computed: {
     row() {
       return row;
@@ -109,7 +110,7 @@ export default {
     },
     setCurrent(row) {
       this.$refs.tableDemand.setCurrentRow(row);
-    },
+    }
   }
 };
 </script>

+ 29 - 7
src/views/oms/order/components/orderInfoDialog.vue

@@ -15,6 +15,15 @@
         </div>
       </div>
 
+      <div class="box" style="margin-top: 15px;">
+        <div class="item_title">
+          <span>{{ $t("shopifyPromotion.promotionMessage") }}</span>
+        </div>
+        <div class="ptitle">
+          <promotionInfoTab :orderInfo="orderInfo"></promotionInfoTab>
+        </div>
+      </div>
+
       <div class="box" style="margin-top: 15px;">
         <div class="item_title">
           <span>{{ $t("receInfor") }}</span>
@@ -26,14 +35,16 @@
           ></receivingInfoTab>
         </div>
       </div>
-      <div class="box" style="margin-top: 15px;" v-if="this.pickUpInfo != null && this.pickUpInfo.orderType == 'pickUp' ">
+      <div
+        class="box"
+        style="margin-top: 15px;"
+        v-if="this.pickUpInfo != null && this.pickUpInfo.orderType == 'pickUp'"
+      >
         <div class="item_title">
           <span>{{ $t("pickUpInfor") }}</span>
         </div>
         <div class="ptitle">
-          <pickUpInfoDiaTab
-            :pickUpInfo="pickUpInfo"
-          ></pickUpInfoDiaTab>
+          <pickUpInfoDiaTab :pickUpInfo="pickUpInfo"></pickUpInfoDiaTab>
         </div>
       </div>
 
@@ -60,7 +71,11 @@
         </el-collapse>
       </div>
 
-      <div class="box" style="margin-top: 15px;" v-if="this.orderGiftCards != null ">
+      <div
+        class="box"
+        style="margin-top: 15px;"
+        v-if="this.orderGiftCards != null"
+      >
         <div class="item_title">
           <span>{{ $t("orderPayType") }}</span>
         </div>
@@ -98,11 +113,17 @@
 </template>
 
 <script>
-import {getById, getLogData, queryOrderGiftCard, queryOrderDetails} from "@/api/oms/order/order";
+import {
+  getById,
+  getLogData,
+  queryOrderGiftCard,
+  queryOrderDetails
+} from "@/api/oms/order/order";
 import { queryByOrdersId as getAddress } from "@/api/oms/order/address";
 import { getById as getInvoice } from "@/api/oms/order/invoice";
 
 import baseInfoTab from "./baseInfoTab";
+import promotionInfoTab from "./promotionInfoTab";
 import invoiceInfoTab from "./invoiceInfoTab";
 import optLogTab from "./optLogTab";
 import orderItemListTab from "./orderItemListTab";
@@ -122,7 +143,8 @@ export default {
     optLogTab,
     orderItemListTab,
     orderGiftCardsTab,
-    receivingInfoTab
+    receivingInfoTab,
+    promotionInfoTab
   },
   data() {
     return {

+ 72 - 0
src/views/oms/order/components/promotionInfoTab.vue

@@ -0,0 +1,72 @@
+<template>
+  <div>
+    <el-descriptions
+      class="margin-top"
+      title=""
+      :column="4"
+      direction="horizontal"
+    >
+      <el-descriptions-item :label="$t('label.promotionName')">{{
+        orderInfo.ordersId
+      }}</el-descriptions-item>
+      <el-descriptions-item :label="$t('label.participateType')">{{
+        orderInfo.status | statusFilter
+      }}</el-descriptions-item>
+      <el-descriptions-item :label="$t('shopifyPromotion.targetType')">{{
+        orderInfo.ormorder
+      }}</el-descriptions-item>
+      <el-descriptions-item :label="$t('shopifyPromotion.useType')">{{
+        orderInfo.orderType | orderTypeFilter
+      }}</el-descriptions-item>
+    </el-descriptions>
+    <el-descriptions
+      class="margin-top"
+      title=""
+      :column="4"
+      direction="horizontal"
+    >
+      <el-descriptions-item :label="$t('shopifyPromotion.priceSet')">{{
+        orderInfo.timeplaced
+      }}</el-descriptions-item>
+      <el-descriptions-item :label="$t('shopifyPromotion.paySet')">{{
+        orderInfo.payTime
+      }}</el-descriptions-item>
+      <el-descriptions-item :label="$t('shopifyPromotion.amountSet')">{{
+        orderInfo.currency
+      }}</el-descriptions-item>
+    </el-descriptions>
+  </div>
+</template>
+
+<script>
+import { orderTypeKeyValue, statusKeyValue } from "@/api/oms/order/order";
+import i18n from "@/lang"; // 国际化
+
+export default {
+  name: "baseInfoTab",
+  props: ["orderInfo"],
+  filters: {
+    orderTypeFilter(key) {
+      return i18n.t(orderTypeKeyValue[key]);
+    },
+    statusFilter(key) {
+      return i18n.t(statusKeyValue[key]);
+    }
+  },
+  data() {
+    return {};
+  },
+  methods: {}
+};
+</script>
+
+<style lang="scss" scoped>
+.ptitle {
+  display: flex;
+  justify-content: space-between;
+  margin: 0px 20px 0px 20px;
+  color: #1f2d3d;
+  text-align: left;
+  font-weight: bold;
+}
+</style>

+ 700 - 0
src/views/oms/promotion/shopifyPromotion/index.vue

@@ -0,0 +1,700 @@
+<template>
+  <div class="app-container">
+    <el-container>
+      <el-main>
+        <div class="filter-container">
+          <el-input
+            :placeholder="$t('label.promotionName')"
+            style="width: 200px;"
+            clearable
+            class="filter-item"
+            v-model="listQuery.promotionName"
+            @keyup.enter.native="retPage"
+          />
+          <el-input
+            :placeholder="$t('label.promotionInfo')"
+            style="width: 200px;"
+            clearable
+            class="filter-item"
+            v-model="listQuery.promotionInfo"
+            @keyup.enter.native="retPage"
+          />
+          <el-select
+            v-model="listQuery.promotionStore"
+            clearable
+            class="filter-item"
+            style="width: 200px;"
+            :placeholder="$t('label.promotionStoreName')"
+            @keyup.enter.native="retPage"
+          >
+            <el-option
+              :key="index"
+              v-for="(item, index) in storeList"
+              :label="item.storeName"
+              :value="item.storeId"
+            />
+          </el-select>
+          <el-date-picker
+            v-model="listQuery.promotionStartTime"
+            type="datetime"
+            clearable
+            format="yyyy-MM-dd HH:mm:ss"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            class="filter-item"
+            :placeholder="$t('label.promotionStartTime')"
+          ></el-date-picker>
+          <el-date-picker
+            v-model="listQuery.promotionEndTime"
+            type="datetime"
+            clearable
+            format="yyyy-MM-dd HH:mm:ss"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            class="filter-item"
+            :placeholder="$t('label.promotionEndTime')"
+            default-time="23:59:59"
+          ></el-date-picker>
+          <el-select
+            v-model="listQuery.mutual"
+            clearable
+            class="filter-item"
+            style="width: 200px;"
+            :placeholder="$t('label.mutual')"
+            @keyup.enter.native="retPage"
+          >
+            <el-option :label="$t('yes')" :value="1"></el-option>
+            <el-option :label="$t('no')" :value="0"></el-option>
+          </el-select>
+          <el-select
+            v-model="listQuery.promotionStatus"
+            clearable
+            class="filter-item"
+            style="width: 200px;"
+            :placeholder="$t('label.promotionStatus')"
+            @keyup.enter.native="retPage"
+          >
+            <el-option
+              :key="index"
+              v-for="(item, index) in $t('label.promotionStatusArr')"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+          <el-select
+            v-model="listQuery.conditionType"
+            clearable
+            class="filter-item"
+            style="width: 200px;"
+            :placeholder="$t('label.conditionType')"
+            @keyup.enter.native="retPage"
+          >
+            <el-option
+              :key="index"
+              v-for="(item, index) in $t('label.conditionTypeArr')"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+          <el-select
+            v-model="listQuery.participateType"
+            clearable
+            class="filter-item"
+            style="width: 200px;"
+            :placeholder="$t('label.participateType')"
+            @keyup.enter.native="retPage"
+          >
+            <el-option
+              :key="index"
+              v-for="(item, index) in $t('label.participateTypeArr')"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+          <el-select
+            v-model="listQuery.status"
+            clearable
+            class="filter-item"
+            style="width: 200px;"
+            :placeholder="$t('status')"
+            @keyup.enter.native="retPage"
+          >
+            <el-option :label="$t('view.enable')" :value="1"></el-option>
+            <el-option :label="$t('view.disable')" :value="0"></el-option>
+          </el-select>
+
+          <el-button
+            v-waves
+            v-has="'promotion:list'"
+            class="filter-item"
+            type="primary"
+            icon="el-icon-search"
+            @click="retPage"
+            >{{ $t("view.search") }}
+          </el-button>
+
+          <el-button
+            v-waves
+            v-has="'promotion:update'"
+            class="filter-item"
+            type="primary"
+            icon="el-icon-circle-plus-outline"
+            @click="showDialog('',true)"
+            >{{ $t("view.create") }}
+          </el-button>
+
+        </div>
+        <el-table
+          v-loading="listLoading"
+          :key="tableKey"
+          :data="list"
+          stripe
+          border
+          fit
+          highlight-current-row
+          style="width: 100%;"
+        >
+          <el-table-column type="index" width="40"></el-table-column>
+
+          <el-table-column
+            :label="$t('label.promotionName')"
+            width="220"
+            show-overflow-tooltip
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.promotionName }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.promotionInfo')"
+            align="center"
+            width="220"
+            show-overflow-tooltip
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.promotionInfo }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.promotionStoreName')"
+            align="center"
+            width="220"
+            show-overflow-tooltip
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.storeName }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.promotionStartTime')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.promotionStartTime }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.promotionEndTime')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.promotionEndTime }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.participateNum')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.participateNum }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.mutual')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span v-if="row.mutual">{{ $t("yes") }}</span>
+              <span v-else>{{ $t("no") }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.participateWeight')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.participateWeight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.participateType')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{
+                $t("label.participateTypeArr").find(
+                  item => item.value === row.participateType
+                )
+                  ? $t("label.participateTypeArr").find(
+                      item => item.value === row.participateType
+                    ).label
+                  : ""
+              }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.conditionType')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{
+                $t("label.conditionTypeArr").find(
+                  item => item.value === row.conditionType
+                )
+                  ? $t("label.conditionTypeArr").find(
+                      item => item.value === row.conditionType
+                    ).label
+                  : ""
+              }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.conditionValue')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span v-if="row.participateType === 'gift_consumer'">{{
+                $t("label.conditionValueUserTypeArr").find(
+                  item => item.value === row.conditionValue
+                )
+                  ? $t("label.conditionValueUserTypeArr").find(
+                      item => item.value === row.conditionValue
+                    ).label
+                  : ""
+              }}</span>
+              <span v-else>{{ row.conditionValue }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.goodsRelation')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{
+                $t("label.goodsRelationArr").find(
+                  item => item.value === row.goodsRelation
+                )
+                  ? $t("label.goodsRelationArr").find(
+                      item => item.value === row.goodsRelation
+                    ).label
+                  : ""
+              }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.goodsScope')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{
+                $t("label.goodsScopeArr").find(
+                  item => item.value === row.goodsScope
+                )
+                  ? $t("label.goodsScopeArr").find(
+                      item => item.value === row.goodsScope
+                    ).label
+                  : ""
+              }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.giftRelation')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{
+                $t("label.giftRelationArr").find(
+                  item => item.value === row.giftRelation
+                )
+                  ? $t("label.giftRelationArr").find(
+                      item => item.value === row.giftRelation
+                    ).label
+                  : ""
+              }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.promotionStatus')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <!--不支持{{ $t('label.promotionStatusArr').find(item => item.value === row.promotionStatus)?.lable || ''}} 写法-->
+              <span>{{
+                $t("label.promotionStatusArr").find(
+                  item => item.value === row.promotionStatus
+                )
+                  ? $t("label.promotionStatusArr").find(
+                      item => item.value === row.promotionStatus
+                    ).label
+                  : ""
+              }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.checkBy')"
+            align="center"
+            width="220"
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.checkBy }}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column :label="$t('status')" align="center" width="150">
+            <template v-slot="{ row }">
+              <el-tag :type="row.status ? 'primary' : 'danger'">{{
+                row.status ? $t("view.enable") : $t("view.disable")
+              }}</el-tag>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            :label="$t('label.operation')"
+            min-width="300"
+            align="center"
+            fixed="right"
+          >
+            <template v-slot="{ row }">
+              <el-tooltip
+                class="item"
+                effect="dark"
+                :content="$t('view.edit')"
+                placement="top-start"
+              >
+                <el-button
+                  v-has="'promotion:update'"
+                  type="primary"
+                  size="mini"
+                  icon="el-icon-edit"
+                  circle
+                  @click="showDialog(row.id,true)"
+                >
+                </el-button>
+              </el-tooltip>
+
+              <el-tooltip
+                class="item"
+                effect="dark"
+                :content="$t('view.details')"
+                placement="top-start"
+              >
+                <el-button
+                  v-has="'promotion:list'"
+                  type="primary"
+                  size="mini"
+                  icon="el-icon-more"
+                  circle
+                  @click="showDialog(row.id,false)"
+                >
+                </el-button>
+              </el-tooltip>
+
+              <el-tooltip
+                class="item"
+                effect="dark"
+                :content="$t('view.audit')"
+                placement="top-start"
+              >
+                <el-button
+                  v-if="row.promotionStatus === 0"
+                  v-has="'promotion:check'"
+                  type="primary"
+                  size="mini"
+                  icon="el-icon-check"
+                  circle
+                  @click="handleCheck(row.id)"
+                >
+                </el-button>
+              </el-tooltip>
+              <el-tooltip
+                class="item"
+                effect="dark"
+                :content="$t('label.product')"
+                placement="top-start"
+              >
+                <el-button
+                  v-if="row.goodsScope === 'part'"
+                  v-has="'promotionOrderGoods:list'"
+                  type="primary"
+                  circle
+                  size="mini"
+                  icon="el-icon-shopping-bag-1"
+                  @click="handleGoodsList(row.id, row.promotionStatus)"
+                >
+                </el-button>
+              </el-tooltip>
+              <el-tooltip
+                class="item"
+                effect="dark"
+                :content="$t('label.gift')"
+                placement="top-start"
+              >
+                <el-button
+                  v-has="'promotionGift:list'"
+                  type="primary"
+                  circle
+                  size="mini"
+                  icon="el-icon-shopping-bag-2"
+                  @click="handleGiftList(row.id, row.promotionStatus)"
+                >
+                </el-button>
+              </el-tooltip>
+              <el-tooltip
+                class="item"
+                effect="dark"
+                :content="$t('view.delete')"
+                placement="top-start"
+              >
+                <el-button
+                  v-has="'promotion:delete'"
+                  type="danger"
+                  circle
+                  size="mini"
+                  icon="el-icon-delete"
+                  @click="handleDelete(row.id)"
+                >
+                </el-button>
+              </el-tooltip>
+              <el-tooltip
+                class="item"
+                effect="dark"
+                :content="row.status ? $t('view.disable') : $t('view.enable')"
+                placement="top-start"
+              >
+                <el-button
+                  v-has="'promotion:status'"
+                  :type="row.status ? 'danger' : 'primary'"
+                  circle
+                  size="mini"
+                  :icon="row.status ? 'el-icon-turn-off' : 'el-icon-open'"
+                  @click="changePromotionStatus(row.id, row.status)"
+                >
+                </el-button>
+              </el-tooltip>
+              <el-tooltip
+                class="item"
+                effect="dark"
+                :content="$t('title.operationLog')"
+                placement="top-start"
+              >
+                <el-button
+                  v-has="'promotionLog:list'"
+                  type="primary"
+                  circle
+                  size="mini"
+                  icon="el-icon-notebook-1"
+                  @click="handleLog(row.id)"
+                >
+                </el-button>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+        <!-- 分页 -->
+        <swPage
+          v-if="total > 0"
+          key="2"
+          :listQuery="listQuery"
+          :total="total"
+          pos="btmRight"
+          @retPage="getList"
+        />
+      </el-main>
+    </el-container>
+
+    <promotion-form
+      ref="promotionFormRef"
+      @refresh-table="getList"
+    ></promotion-form>
+    <promotion-gift-list ref="giftListRef"></promotion-gift-list>
+    <promotion-goods-list ref="goodsListRef"></promotion-goods-list>
+    <promotion-log-list ref="logListRef"></promotion-log-list>
+  </div>
+</template>
+
+<script>
+import waves from "@/directive/waves"; // 水波纹指令
+import SwPage from "@/views/common/swPage.vue";
+import ElContainer from "element-ui/packages/container/src/main";
+import PromotionForm from "@/views/oms/promotion/shopifyPromotion/promotionForm.vue";
+import {
+  fetchList,
+  deleteById,
+  storeList,
+  checkPromotion,
+  changeStatus
+} from "@/api/oms/order/promotion";
+import { getToken } from "@/utils/auth";
+import Vue from "vue";
+
+export default {
+  inject: ["reload"], //刷新
+  components: {
+    SwPage,
+    ElContainer,
+    PromotionForm,
+    PromotionGiftList: Vue.component("PromotionGiftList", () =>
+      import("@/views/oms/promotion/promotion/promotionGiftList.vue")
+    ),
+    PromotionGoodsList: Vue.component("PromotionGoodsList", () =>
+      import("@/views/oms/promotion/promotion/promotionGoodsList.vue")
+    ),
+    PromotionLogList: Vue.component("PromotionLogList", () =>
+      import("@/views/oms/promotion/promotion/promotionLogList.vue")
+    )
+  },
+  name: "shopifyPromotion",
+  directives: {
+    waves
+  },
+  data() {
+    return {
+      activeName: "productIndex",
+      iconSize: "mini",
+      //右侧列表
+      tableKey: 0,
+      list: null,
+      total: null,
+      listLoading: false,
+      listQuery: {
+        upAndDown: null,
+        keywords: null,
+        promotionName: null,
+        promotionInfo: null,
+        promotionStore: null,
+        promotionStatus: null,
+        mutual: null,
+        status: null,
+        page: 1,
+        limit: 10
+      },
+      storeList: []
+    };
+  },
+  created() {
+    this.getList();
+    this.getStoreList();
+  },
+  computed: {
+    headers: function() {
+      return { "X-Token": getToken() };
+    }
+  },
+  methods: {
+    getStoreList() {
+      storeList().then(res => {
+        if (res.code === 200) {
+          this.storeList = res.data;
+        }
+      });
+    },
+    getList() {
+      this.listLoading = true;
+      fetchList(this.listQuery)
+        .then(response => {
+          if (response.code === 200) {
+            this.list = response.data.list;
+            this.total = response.data.total;
+            setTimeout(() => {
+              this.listLoading = false;
+            }, 0.5 * 1000);
+          }
+        })
+        .catch(() => {
+          setTimeout(() => {
+            this.listLoading = false;
+          }, 0.5 * 1000);
+        });
+    },
+    retPage() {
+      this.listQuery.page = 1;
+      this.getList();
+    },
+    handleDelete(id) {
+      this.$confirm("是否删除该记录?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        deleteById(id).then(res => {
+          if (res.code === 200) {
+            this.$message({
+              message: "操作成功",
+              type: "success"
+            });
+            this.getList();
+          }
+        });
+      });
+    },
+    showDialog(id,edit) {
+      this.$refs.promotionFormRef.showDialog(id,edit);
+    },
+    handleCheck(id) {
+      this.$confirm("是否审核通过?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        checkPromotion({ id: id }).then(res => {
+          if (res.code === 200) {
+            this.$message({
+              message: "审核成功",
+              type: "success"
+            });
+            this.getList();
+          }
+        });
+      });
+    },
+    handleGiftList(id, status) {
+      this.$refs.giftListRef.handleOpen(id, status);
+    },
+    handleGoodsList(id, status) {
+      this.$refs.goodsListRef.handleOpen(id, status);
+    },
+    changePromotionStatus(id, status) {
+      this.$confirm(status ? "是否确认禁用?" : "是否确认启用?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        changeStatus(id).then(res => {
+          if (res.code === 200) {
+            this.$message({
+              message: "操作成功",
+              type: "success"
+            });
+            this.getList();
+          }
+        });
+      });
+    },
+    handleLog(id) {
+      this.$refs.logListRef.handleOpen(id);
+    }
+  }
+};
+</script>
+
+<style scoped></style>

+ 462 - 0
src/views/oms/promotion/shopifyPromotion/promotionForm.vue

@@ -0,0 +1,462 @@
+<template>
+  <div>
+    <el-dialog
+      v-loading="pageLoad"
+      element-loading-text="loading..."
+      :title="title"
+      top="10vh"
+      :close-on-click-modal="false"
+      :visible.sync="promotionFormVisible"
+      @open="handleOpenDialog"
+      @close="resetData"
+    >
+      <div class="dialog-body">
+        <el-form
+          ref="promotionFormRef"
+          :rules="baseRule"
+          :model="promotion"
+          label-width="auto"
+        >
+          <!--促销名称-->
+          <el-form-item
+            :label="$t('label.promotionName')"
+            prop="promotionName"
+            style="width:320px"
+            required
+          >
+            <el-input v-model.trim="promotion.promotionName" :disabled='edit'></el-input>
+          </el-form-item>
+
+          <!--促销描述-->
+          <el-form-item
+            :label="$t('label.promotionInfo')"
+            prop="promotionInfo"
+            style="width:320px"
+            required
+          >
+            <el-input v-model.trim="promotion.promotionInfo" :disabled='edit'></el-input>
+          </el-form-item>
+
+          <!--促销店铺-->
+          <el-form-item
+            :label="$t('label.promotionStoreName')"
+            prop="promotionStore"
+            required
+          >
+            <el-select v-model="promotion.promotionStore" :disabled='edit'>
+              <el-option
+                :key="index"
+                v-for="(item, index) in storeList"
+                :label="item.storeName"
+                :value="item.storeId"
+              />
+            </el-select>
+          </el-form-item>
+
+          <!--促销开始时间-->
+          <el-form-item
+            :label="$t('label.promotionStartTime')"
+            prop="promotionStartTime"
+            required
+          >
+            <el-date-picker
+              :disabled='edit'
+              type="datetime"
+              placeholder="选择日期"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              v-model="promotion.promotionStartTime"
+            ></el-date-picker>
+          </el-form-item>
+
+          <!--促销失效时间-->
+          <el-form-item
+            :label="$t('label.promotionEndTime')"
+            prop="promotionEndTime"
+            required
+          >
+            <el-date-picker
+             :disabled='edit'
+              type="datetime"
+              placeholder="选择日期"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              v-model="promotion.promotionEndTime"
+            ></el-date-picker>
+          </el-form-item>
+
+          <!--每个用户限定参与次数-->
+          <el-form-item
+            :label="$t('label.participateNum')"
+            prop="participateNum"
+            required
+          >
+            <el-input-number
+            :disabled='edit'
+              v-model="promotion.participateNum"
+              :min="1"
+              controls-position="right"
+            ></el-input-number>
+          </el-form-item>
+
+          <!--是否互斥-->
+          <el-form-item :label="$t('label.mutual')" prop="mutual" required>
+            <el-radio-group v-model="promotion.mutual" :disabled='edit'>
+              <el-radio :label="true">{{ $t("yes") }}</el-radio>
+              <el-radio :label="false">{{ $t("no") }}</el-radio>
+            </el-radio-group>
+          </el-form-item>
+
+          <!--是否可叠加,只有当互斥的时候才能选择-->
+          <el-form-item v-if="this.promotion.mutual == true" :label="$t('label.isSuperposition')"
+                        prop="isSuperposition" required>
+            <el-radio-group v-model="promotion.isSuperposition">
+              <el-radio :label="true">{{ $t("yes") }}</el-radio>
+              <el-radio :label="false">{{ $t("no") }}</el-radio>
+            </el-radio-group>
+          </el-form-item>
+
+          <!--促销优先级-->
+          <el-form-item
+            :label="$t('label.participateWeight')"
+            prop="participateWeight"
+            required
+          >
+            <el-input-number
+             :disabled='edit'
+              v-model="promotion.participateWeight"
+              controls-position="right"
+            ></el-input-number>
+          </el-form-item>
+
+          <!--促销类型-->
+          <el-form-item
+            :label="$t('label.participateType')"
+            prop="participateType"
+            required
+          >
+            <el-select
+              v-model="promotion.participateType"
+              @change="handleChangeParticipateType"
+              :disabled='edit'
+            >
+              <el-option
+                :key="index"
+                v-for="(item, index) in $t('label.participateTypeArr')"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+
+          <!--条件类型-->
+          <el-form-item
+            :label="$t('label.conditionType')"
+            prop="conditionType"
+            v-if="promotion.participateType !== 'gift_all'"
+            required
+          >
+            <el-select v-model="promotion.conditionType" :disabled='edit'>
+              <el-option
+                :key="index"
+                v-for="(item, index) in conditionTypeArr"
+                :label="item.label"
+                :value="item.value"
+                :disabled="item.disabled"
+              />
+            </el-select>
+          </el-form-item>
+
+          <!--条件值-->
+          <el-form-item
+            :label="$t('label.conditionValue')"
+            prop="conditionValue"
+            v-if="
+              promotion.participateType !== '' &&
+                promotion.participateType !== 'gift_all'
+            "
+            required
+            :disabled='edit'
+          >
+            <el-input-number
+              v-if="promotion.participateType === 'gift_money'"
+              v-model="promotion.conditionValue"
+              :min="0"
+              :precision="4"
+              :step="1"
+              controls-position="right"
+              :disabled='edit'
+            />
+            <el-input-number
+              v-if="promotion.participateType === 'gift_qty'"
+              v-model="promotion.conditionValue"
+              controls-position="right"
+              :disabled='edit'
+            />
+            <el-select
+              v-if="promotion.participateType === 'gift_consumer'"
+              v-model="promotion.conditionValue"
+              :disabled='edit'
+            >
+              <el-option
+                :key="index"
+                v-for="(item, index) in $t('label.conditionValueUserTypeArr')"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+
+          <!--参加活动的商品关系-->
+          <el-form-item
+            :label="$t('label.goodsRelation')"
+            prop="goodsRelation"
+            required
+          >
+            <el-select v-model="promotion.goodsRelation" :disabled='edit'>
+              <el-option
+                :key="index"
+                v-for="(item, index) in $t('label.goodsRelationArr')"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+
+          <!--参加活动的商品范围-->
+          <el-form-item
+            :label="$t('label.goodsScope')"
+            prop="goodsScope"
+            required
+          >
+            <el-select v-model="promotion.goodsScope" :disabled='edit'>
+              <el-option
+                :key="index"
+                v-for="(item, index) in $t('label.goodsScopeArr')"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+
+          <!--赠品关系-->
+          <el-form-item
+            :label="$t('label.giftRelation')"
+            prop="giftRelation"
+            required
+          >
+            <el-select v-model="promotion.giftRelation" :disabled='edit'>
+              <el-option
+                :key="index"
+                v-for="(item, index) in $t('label.giftRelationArr')"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+
+      <template slot="footer">
+        <el-button
+          @click="
+            resetData();
+            promotionFormVisible = false;
+          "
+          >{{ $t("view.cancel") }}
+        </el-button>
+        <!-- 未审核时/审核驳回 状态可进行提交 -->
+        <el-button
+          type="primary"
+          @click="handleSaveOrUpdate"
+          v-if="promotion.promotionStatus !== 1"
+          :disabled='edit'
+          >{{ $t("view.confirm") }}
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import waves from "@/directive/waves"; // 水波纹指令
+import { getById, save, storeList, update } from "@/api/oms/order/promotion";
+import i18n from "@/lang";
+import promotion from "@/views/oms/promotion/shopifyPromotion/index.vue";
+
+export default {
+  inject: ["reload"],
+  directives: {
+    waves
+  },
+  components: {},
+  computed: {},
+  name: "shopifyPromotionForm",
+  filters: {},
+  data() {
+    return {
+      promotionFormVisible: false,
+      title: "",
+      promotion: {
+        // 配置基本信息
+        id: "",
+        promotionName: "",
+        promotionInfo: "",
+        promotionStore: "",
+        promotionStartTime: "",
+        promotionEndTime: "",
+        promotionStatus: "",
+        rejectCause: "",
+        participateNum: 1,
+        mutual: "",
+        isSuperposition: "",
+        participateWeight: 0,
+        participateType: "",
+        conditionType: "",
+        conditionValue: "",
+        goodsRelation: "",
+        goodsScope: "",
+        giftRelation: "",
+      },
+      edit:true,
+      storeList: [],
+      noDataText: "加载中",
+      baseRule: {
+        // 促销配置
+        promotionName: [
+          {
+            required: true,
+            message: "请输入促销名称",
+            trigger: ["change", "blur"]
+          },
+          {
+            min: 2,
+            max: 50,
+            message: "长度在 2 到 50 个字符",
+            trigger: ["change", "blur"]
+          }
+        ]
+      },
+      pageLoad: false,
+      conditionTypeArr: i18n.t("label.conditionTypeArr").map(item => {
+        return {
+          ...item,
+          disabled: false
+        };
+      })
+    };
+  },
+  mounted() {},
+  methods: {
+    getStoreList() {
+      storeList().then(res => {
+        if (res.code === 200) {
+          this.storeList = res.data;
+        }
+      });
+    },
+    async showDialog(id,edit) {
+      this.edit = !edit;
+      await this.getStoreList();
+      if (id) {
+        // 修改配置
+        this.promotion.id = id;
+        await this.getPromotionInfo();
+      }
+      this.title = id
+        ? i18n.t("title.updateTitle")
+        : i18n.t("title.createTitle");
+      this.promotionFormVisible = true;
+    },
+    resetData() {
+      this.promotion = {
+        id: "",
+        promotionName: "",
+        promotionInfo: "",
+        promotionStartTime: "",
+        promotionEndTime: "",
+        promotionStatus: "",
+        rejectCause: "",
+        participateNum: "",
+        mutual: "",
+        participateWeight: "",
+        participateType: "",
+        conditionType: "",
+        conditionValue: "",
+        goodsRelation: "",
+        goodsScope: "",
+        giftRelation: ""
+      };
+    },
+    handleOpenDialog() {
+      this.resetData();
+      if (this.$refs.promotionFormRef) {
+        this.$refs.promotionFormRef.clearValidate();
+      }
+    },
+    getPromotionInfo() {
+      this.pageLoad = true;
+      getById(this.promotion.id).then(res => {
+        // 促销配置信息
+        this.promotion = res.data;
+        this.pageLoad = false;
+      });
+    },
+    handleSaveOrUpdate() {
+      //创建商品
+      this.$refs["promotionFormRef"].validate(valid => {
+        //通用属性验证成功
+        if (valid) {
+          // 如果需要在促销类型买就送的情况下将条件类型和条件值改为 "0" 则可在此修改 暂时默认为空字符
+          const data = {
+            ...this.promotion
+          };
+          if (!data.id) {
+            save(data).then(res => {
+              if (res.code === 200) {
+                this.$message({
+                  message: "操作成功",
+                  type: "success"
+                });
+                this.$emit("refresh-table");
+                this.promotionFormVisible = false;
+              }
+            });
+          } else {
+            update(data).then(res => {
+              if (res.code === 200) {
+                this.$message({
+                  message: "操作成功",
+                  type: "success"
+                });
+                this.$emit("refresh-table");
+                this.promotionFormVisible = false;
+              }
+            });
+          }
+        }
+      });
+    },
+    handleChangeParticipateType(e) {
+      this.conditionTypeArr.forEach(item => {
+        item.disabled = false;
+      });
+      this.promotion.conditionType = "";
+      this.promotion.conditionValue = "";
+      if (e === "gift_money" || e === "gift_qty") {
+        this.conditionTypeArr[2].disabled = true;
+      } else if (e === "gift_consumer") {
+        // gift_consumer
+        this.conditionTypeArr[0].disabled = true;
+        this.conditionTypeArr[1].disabled = true;
+        this.promotion.conditionType = this.conditionTypeArr[2].value;
+      }
+    }
+  }
+};
+</script>
+
+<style scoped rel="stylesheet/scss" lang="scss">
+.dialog-body {
+  height: 60vh;
+  overflow: auto;
+}
+</style>

+ 246 - 0
src/views/oms/promotion/shopifyPromotion/promotionGiftForm.vue

@@ -0,0 +1,246 @@
+<template>
+  <div>
+    <el-dialog
+      v-loading="pageLoad"
+      element-loading-text="loading..."
+      :title="title"
+      top="10vh"
+      width="40%"
+      append-to-body
+      :close-on-click-modal="false"
+      v-if="promotionGiftFormVisible"
+      :visible.sync="promotionGiftFormVisible"
+      @open="handleOpenDialog"
+    >
+      <div class="dialog-body">
+        <el-form
+          ref="promotionGiftFormRef"
+          :rules="baseRule"
+          :model="promotionGift"
+          label-width="auto"
+        >
+          <!--Sku Code-->
+          <el-form-item :label="$t('label.giftSku')" prop="giftSku" required>
+            <el-input v-model.trim="promotionGift.giftSku"></el-input>
+          </el-form-item>
+
+          <!--单次赠送数量-->
+          <el-form-item :label="$t('label.giftNum')" prop="giftNum" required>
+            <el-input-number
+              controls-position="right"
+              :min="0"
+              v-model.trim="promotionGift.giftNum"
+            ></el-input-number>
+          </el-form-item>
+
+          <!--计划赠送的总数量-->
+          <el-form-item
+            :label="$t('label.giftAllNum')"
+            prop="giftAllNum"
+            required
+          >
+            <el-input-number
+              controls-position="right"
+              :min="0"
+              v-model.trim="promotionGift.giftAllNum"
+            ></el-input-number>
+          </el-form-item>
+
+          <!--赠品库存校验类型-->
+          <el-form-item
+            :label="$t('label.giftInventoryType')"
+            prop="giftInventoryType"
+            required
+          >
+            <el-select
+              v-model="promotionGift.giftInventoryType"
+              @change="handleChangeGiftInventoryType"
+            >
+              <el-option
+                :key="index"
+                v-for="(item, index) in $t('label.giftInventoryTypeArr')"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+
+          <!--赠品库存校验仓库编码-->
+          <el-form-item
+            :label="$t('label.giftInventoryWarehouseName')"
+            prop="giftInventoryWarehouseCode"
+            v-if="promotionGift.giftInventoryType === 0"
+            required
+          >
+            <el-select
+              v-model="promotionGift.giftInventoryWarehouseCode"
+              @change="handleChangeWarehouse"
+            >
+              <el-option
+                :key="index"
+                v-for="(item, index) in warehouseArr"
+                :label="item.warehouseName"
+                :value="item.warehouseCode"
+              />
+            </el-select>
+          </el-form-item>
+
+          <!--赠品优先级-->
+          <el-form-item
+            :label="$t('label.giftPriority')"
+            prop="giftPriority"
+            required
+          >
+            <el-input-number
+              controls-position="right"
+              v-model.trim="promotionGift.giftPriority"
+            ></el-input-number>
+          </el-form-item>
+        </el-form>
+      </div>
+
+      <template slot="footer">
+        <el-button @click="promotionGiftFormVisible = false"
+          >{{ $t("view.cancel") }}
+        </el-button>
+        <el-button type="primary" @click="handleSaveOrUpdate"
+          >{{ $t("view.confirm") }}
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import waves from "@/directive/waves"; // 水波纹指令
+import {
+  getById,
+  save,
+  update,
+  warehouseList
+} from "@/api/oms/order/promotionGift";
+import i18n from "@/lang";
+
+export default {
+  inject: ["reload"],
+  directives: {
+    waves
+  },
+  components: {},
+  computed: {},
+  name: "shopifyPromotionGiftForm",
+  filters: {},
+  data() {
+    return {
+      promotionGiftFormVisible: false,
+      title: "",
+      promotionGift: {
+        id: "",
+        promotionId: "",
+        giftSku: "",
+        giftNum: "",
+        giftAllNum: "",
+        giftInventoryType: "",
+        giftInventoryWarehouseCode: "",
+        giftInventoryWarehouseName: "",
+        giftPriority: ""
+      },
+      noDataText: "加载中",
+      baseRule: {},
+      pageLoad: false,
+      warehouseArr: []
+    };
+  },
+  mounted() {},
+  methods: {
+    initWarehouse() {
+      warehouseList().then(res => {
+        if (res.code === 200) {
+          this.warehouseArr = res.data;
+        }
+      });
+    },
+    showDialog(promotionId, id) {
+      this.initWarehouse();
+      if (id) {
+        this.promotionGift.id = id;
+        this.getPromotionGiftInfo();
+      } else {
+        this.promotionGift = {
+          id: "",
+          promotionId: promotionId,
+          giftSku: "",
+          giftNum: "",
+          giftAllNum: "",
+          giftInventoryType: "",
+          giftInventoryWarehouseCode: "",
+          giftInventoryWarehouseName: "",
+          giftPriority: ""
+        };
+      }
+      this.title = id
+        ? i18n.t("title.promotionGiftTitle")
+        : i18n.t("title.promotionGiftTitle");
+      this.promotionGiftFormVisible = true;
+    },
+    handleOpenDialog() {},
+    getPromotionGiftInfo() {
+      this.pageLoad = true;
+      getById(this.promotionGift.id).then(res => {
+        // 促销配置信息
+        this.promotionGift = res.data;
+        this.pageLoad = false;
+      });
+    },
+    handleChangeGiftInventoryType(e) {
+      if (e === 1) {
+        this.promotionGift.giftInventoryWarehouseCode = "";
+        this.promotionGift.giftInventoryWarehouseName = "";
+      }
+    },
+    handleChangeWarehouse(e) {
+      this.promotionGift.giftInventoryWarehouseName = this.warehouseArr.find(
+        item => item.warehouseCode === e
+      ).warehouseName;
+    },
+    handleSaveOrUpdate() {
+      //创建商品
+      this.$refs["promotionGiftFormRef"].validate(valid => {
+        //通用属性验证成功
+        if (valid) {
+          if (this.promotionGift.id) {
+            update(this.promotionGift).then(res => {
+              if (res.code === 200) {
+                this.$message({
+                  message: "操作成功",
+                  type: "success"
+                });
+                this.$emit("refresh-table");
+                this.promotionGiftFormVisible = false;
+              }
+            });
+          } else {
+            save(this.promotionGift).then(res => {
+              if (res.code === 200) {
+                this.$message({
+                  message: "操作成功",
+                  type: "success"
+                });
+                this.$emit("refresh-table");
+                this.promotionGiftFormVisible = false;
+              }
+            });
+          }
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style scoped rel="stylesheet/scss" lang="scss">
+.dialog-body {
+  height: 60vh;
+  overflow: auto;
+}
+</style>

+ 423 - 0
src/views/oms/promotion/shopifyPromotion/promotionGiftList.vue

@@ -0,0 +1,423 @@
+<template>
+  <div>
+    <el-dialog
+      :title="$t('title.promotionGiftTitle')"
+      fullscreen
+      :visible.sync="dialogFormVisible"
+    >
+      <el-container>
+        <el-main>
+          <div class="filter-container">
+            <el-input
+              v-model.trim="listQuery.giftSku"
+              clearable
+              class="filter-item"
+              style="width: 200px"
+              :placeholder="$t('label.giftSku')"
+              @keyup.enter.native="retPage"
+            ></el-input>
+            <el-select
+              v-model="listQuery.giftInventoryType"
+              clearable
+              class="filter-item"
+              style="width: 200px;"
+              :placeholder="$t('label.giftInventoryType')"
+              @keyup.enter.native="retPage"
+            >
+              <el-option
+                :key="index"
+                v-for="(item, index) in $t('label.giftInventoryTypeArr')"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+
+            <el-button
+              v-waves
+              class="filter-item"
+              type="primary"
+              icon="el-icon-search"
+              @click="retPage"
+              >{{ $t("view.search") }}
+            </el-button>
+
+            <el-button
+              v-if="status !== 1"
+              v-waves
+              class="filter-item"
+              type="primary"
+              icon="el-icon-circle-plus-outline"
+              @click="showDialog('')"
+              >{{ $t("view.create") }}
+            </el-button>
+
+            <el-button
+              v-if="status !== 1"
+              v-waves
+              class="filter-item"
+              type="primary"
+              icon="el-icon-upload"
+              @click="handleUpload"
+            >
+              {{ $t("view.import") }}
+            </el-button>
+          </div>
+          <el-table
+            v-loading="listLoading"
+            :key="tableKey"
+            :data="list"
+            stripe
+            border
+            fit
+            highlight-current-row
+            style="width: 100%;"
+          >
+            <el-table-column type="index" width="40"></el-table-column>
+
+            <el-table-column :label="$t('label.giftSku')" align="center">
+              <template v-slot="{ row }">
+                <span>{{ row.giftSku }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column
+              :label="$t('label.giftNum')"
+              align="center"
+              width="220"
+            >
+              <template v-slot="{ row }">
+                <span>{{ row.giftNum }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column
+              :label="$t('label.giftAllNum')"
+              align="center"
+              width="220"
+            >
+              <template v-slot="{ row }">
+                <span>{{ row.giftAllNum }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column
+              :label="$t('label.giftInventoryType')"
+              align="center"
+              width="220"
+            >
+              <template v-slot="{ row }">
+                <span>{{
+                  $t("label.giftInventoryTypeArr").find(
+                    item => item.value === row.giftInventoryType
+                  )
+                    ? $t("label.giftInventoryTypeArr").find(
+                        item => item.value === row.giftInventoryType
+                      ).label
+                    : ""
+                }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column
+              :label="$t('label.giftInventoryWarehouseCode')"
+              align="center"
+              width="220"
+            >
+              <template v-slot="{ row }">
+                <span>{{ row.giftInventoryWarehouseCode }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column
+              :label="$t('label.giftInventoryWarehouseName')"
+              align="center"
+              width="220"
+            >
+              <template v-slot="{ row }">
+                <span>{{ row.giftInventoryWarehouseName }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column
+              :label="$t('label.giftPriority')"
+              align="center"
+              width="220"
+            >
+              <template v-slot="{ row }">
+                <span>{{ row.giftPriority }}</span>
+              </template>
+            </el-table-column>
+
+            <el-table-column
+              :label="$t('label.giftCount')"
+              align="center"
+              width="220"
+            >
+              <template v-slot="{ row }">
+                <span>{{ row.giftCount }}</span>
+              </template>
+            </el-table-column>
+
+            <el-table-column
+              v-if="status !== 1"
+              :label="$t('label.operation')"
+              min-width="150"
+              align="center"
+            >
+              <template v-slot="{ row }">
+                <el-tooltip
+                  class="item"
+                  effect="dark"
+                  :content="$t('view.edit')"
+                  placement="top-start"
+                >
+                  <el-button
+                    v-has="'promotionGift:update'"
+                    type="primary"
+                    size="mini"
+                    icon="el-icon-edit"
+                    circle
+                    @click="showDialog(row.id)"
+                  >
+                  </el-button>
+                </el-tooltip>
+                <el-tooltip
+                  class="item"
+                  effect="dark"
+                  :content="$t('view.delete')"
+                  placement="top-start"
+                >
+                  <el-button
+                    v-has="'promotionGift:delete'"
+                    type="danger"
+                    circle
+                    size="mini"
+                    icon="el-icon-delete"
+                    @click="handleDelete(row.id)"
+                  >
+                  </el-button>
+                </el-tooltip>
+              </template>
+            </el-table-column>
+          </el-table>
+          <!-- 分页 -->
+          <swPage
+            v-if="total > 0"
+            key="2"
+            :listQuery="listQuery"
+            :total="total"
+            pos="btmRight"
+            @retPage="getList"
+          />
+        </el-main>
+      </el-container>
+
+      <template slot="footer">
+        <div class="footer-class">
+          <el-button @click="dialogFormVisible = false"
+            >{{ $t("tagsView.close") }}
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      v-loading="pageLoad"
+      :title="$t('title.promotionGiftImport')"
+      :visible.sync="uploadVisible"
+      width="38%"
+      :destroy-on-close="true"
+      :close-on-click-modal="false"
+    >
+      <el-form label-position="right" label-width="140px">
+        <el-form-item :label="$t('label.importTemplate')">
+          <el-button class="filter-item" @click="excelTemplate" type="primary">
+            {{ $t("view.downloadImportTemplate") }}
+          </el-button>
+        </el-form-item>
+
+        <el-form-item :label="$t('label.importData')">
+          <el-upload
+            ref="uploadRef"
+            :limit="1"
+            accept=".xlsx"
+            :headers="headers"
+            :action="uploadUrl"
+            :on-success="handleFileSuccess"
+            :auto-upload="false"
+            :data="uploadData"
+            drag
+          >
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">
+              {{ $t("view.uploadFile") }}<em>{{ $t("view.clickUp") }}</em>
+            </div>
+            <div class="el-upload__tip" slot="tip">
+              {{ $t("view.xlsxFormatOnly") }}
+            </div>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="uploadVisible = false"
+          >{{ $t("view.cancel") }}
+        </el-button>
+        <el-button type="primary" @click="submitUpload"
+          >{{ $t("view.confirm") }}
+        </el-button>
+      </div>
+    </el-dialog>
+
+    <promotion-gift-form
+      ref="promotionGiftFormRef"
+      @refresh-table="getList"
+    ></promotion-gift-form>
+  </div>
+</template>
+
+<script>
+import waves from "@/directive/waves"; // 水波纹指令
+import SwPage from "@/views/common/swPage.vue";
+import ElContainer from "element-ui/packages/container/src/main";
+import promotionGiftForm from "@/views/oms/promotion/promotion/promotionGiftForm.vue";
+import { fetchList, deleteById } from "@/api/oms/order/promotionGift";
+import { getToken } from "@/utils/auth";
+
+export default {
+  inject: ["reload"], //刷新
+  components: {
+    SwPage,
+    ElContainer,
+    promotionGiftForm
+  },
+  name: "shopifyPromotionGiftList",
+  directives: {
+    waves
+  },
+  data() {
+    return {
+      dialogFormVisible: false,
+      tableKey: 0,
+      list: [],
+      total: 0,
+      listLoading: false,
+      listQuery: {
+        upAndDown: null,
+        keywords: null,
+        promotionId: null,
+        giftInventoryType: null,
+        giftSku: null,
+        page: 1,
+        limit: 10
+      },
+      pageLoad: false,
+      uploadVisible: false,
+      uploadUrl: process.env.VUE_APP_OMS_API + "/promotionGift/uploadExcel",
+      uploadData: {
+        promotionId: null
+      },
+      status: "" // 1 已审核通过
+    };
+  },
+  created() {},
+  computed: {
+    headers: function() {
+      return {
+        "X-Token": getToken()
+      };
+    }
+  },
+  methods: {
+    handleOpen(id, status) {
+      this.status = status;
+      this.listQuery.promotionId = id;
+      this.uploadData.promotionId = id;
+      this.dialogFormVisible = true;
+      this.retPage();
+    },
+    getList() {
+      this.listLoading = true;
+      fetchList(this.listQuery)
+        .then(response => {
+          if (response.code === 200) {
+            this.list = response.data.list;
+            this.total = response.data.total;
+            setTimeout(() => {
+              this.listLoading = false;
+            }, 0.5 * 1000);
+          }
+        })
+        .catch(() => {
+          setTimeout(() => {
+            this.listLoading = false;
+          }, 0.5 * 1000);
+        });
+    },
+    retPage() {
+      this.listQuery.page = 1;
+      this.getList();
+    },
+    handleDelete(id) {
+      this.$confirm("是否删除该记录?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        deleteById(id).then(res => {
+          if (res.code === 200) {
+            this.$message({
+              message: "操作成功",
+              type: "success"
+            });
+            this.getList();
+          }
+        });
+      });
+    },
+    showDialog(id) {
+      this.$refs.promotionGiftFormRef.showDialog(
+        this.listQuery.promotionId,
+        id
+      );
+    },
+    excelTemplate() {
+      window.location.href =
+        process.env.VUE_APP_OMS_API + "/promotionGift/excelTemplate";
+    },
+    handleUpload() {
+      this.uploadVisible = true;
+    },
+    submitUpload() {
+      this.$refs.uploadRef.submit();
+      this.pageLoad = true;
+    },
+    //文件上传成功返回
+    handleFileSuccess(response, file, fileList) {
+      this.pageLoad = false;
+      if (file.response.code === 200) {
+        this.$message({
+          message: "导入成功",
+          type: "success"
+        });
+        this.uploadVisible = false;
+        this.getList();
+      } else {
+        this.$message.error(file.response.msg);
+        //删除上传列表中,失败的文件
+        let index = 0;
+        for (const i in fileList) {
+          if (fileList[i] == file) {
+            index = i;
+            break;
+          }
+        }
+        //移出当前文件对象
+        fileList.splice(index, 1);
+      }
+    }
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.footer-class {
+  position: fixed;
+  bottom: 20px;
+  right: 20px;
+}
+</style>

+ 105 - 0
src/views/oms/promotion/shopifyPromotion/promotionGoodsForm.vue

@@ -0,0 +1,105 @@
+<template>
+  <div>
+    <el-dialog
+      v-loading="pageLoad"
+      element-loading-text="loading..."
+      :title="title"
+      width="40%"
+      append-to-body
+      :close-on-click-modal="false"
+      v-if="promotionGoodsFormVisible"
+      :visible.sync="promotionGoodsFormVisible"
+    >
+      <div>
+        <el-form
+          ref="promotionGoodsFormRef"
+          :rules="baseRule"
+          :model="promotionGoods"
+          label-width="auto"
+        >
+          <el-form-item :label="$t('label.goodsSku')" prop="skuCode">
+            <el-input v-model.trim="promotionGoods.skuCode"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+
+      <template slot="footer">
+        <el-button @click="promotionGoodsFormVisible = false"
+          >{{ $t("view.cancel") }}
+        </el-button>
+        <el-button type="primary" @click="handleSaveOrUpdate"
+          >{{ $t("view.confirm") }}
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import waves from "@/directive/waves"; // 水波纹指令
+import { save } from "@/api/oms/order/promotionGoods";
+import i18n from "@/lang";
+
+export default {
+  inject: ["reload"],
+  directives: {
+    waves
+  },
+  components: {},
+  computed: {},
+  name: "shopifyPromotionGoodsForm",
+  filters: {},
+  data() {
+    return {
+      promotionGoodsFormVisible: false,
+      title: "",
+      promotionGoods: {
+        id: "",
+        promotionId: "",
+        skuCode: ""
+      },
+      noDataText: "加载中",
+      baseRule: {},
+      pageLoad: false
+    };
+  },
+  mounted() {},
+  methods: {
+    showDialog(promotionId, id) {
+      this.promotionGoods = {
+        id: "",
+        promotionId: promotionId,
+        skuCode: ""
+      };
+      this.title = id
+        ? i18n.t("title.promotionGoodsTitle")
+        : i18n.t("title.promotionGoodsTitle");
+      this.promotionGoodsFormVisible = true;
+    },
+    handleSaveOrUpdate() {
+      //创建商品
+      this.$refs["promotionGoodsFormRef"].validate(valid => {
+        if (valid) {
+          save(this.promotionGoods).then(res => {
+            if (res.code === 200) {
+              this.$message({
+                message: "操作成功",
+                type: "success"
+              });
+              this.$emit("refresh-table");
+              this.promotionGoodsFormVisible = false;
+            }
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style scoped rel="stylesheet/scss" lang="scss">
+.dialog-body {
+  height: 60vh;
+  overflow: auto;
+}
+</style>

+ 349 - 0
src/views/oms/promotion/shopifyPromotion/promotionGoodsList.vue

@@ -0,0 +1,349 @@
+<template>
+  <div>
+    <el-dialog
+      :title="$t('title.promotionGoodsTitle')"
+      fullscreen
+      :visible.sync="dialogFormVisible"
+    >
+      <el-container>
+        <el-main>
+          <div class="filter-container">
+            <el-input
+              v-model.trim="listQuery.name"
+              clearable
+              class="filter-item"
+              style="width: 200px;"
+              :placeholder="$t('label.skuName')"
+              @keyup.enter.native="retPage"
+            />
+            <el-input
+              v-model.trim="listQuery.skuCode"
+              clearable
+              class="filter-item"
+              style="width: 200px;"
+              :placeholder="$t('label.goodsSku')"
+              @keyup.enter.native="retPage"
+            />
+
+            <el-button
+              v-waves
+              class="filter-item"
+              type="primary"
+              icon="el-icon-search"
+              @click="retPage"
+              >{{ $t("view.search") }}
+            </el-button>
+
+            <el-button
+              v-if="status !== 1"
+              v-waves
+              class="filter-item"
+              type="primary"
+              icon="el-icon-circle-plus-outline"
+              @click="showDialog('')"
+              >{{ $t("view.create") }}
+            </el-button>
+
+            <el-button
+              v-if="status !== 1"
+              v-waves
+              class="filter-item"
+              type="primary"
+              icon="el-icon-upload"
+              @click="handleUpload"
+            >
+              {{ $t("view.import") }}
+            </el-button>
+          </div>
+          <el-table
+            v-loading="listLoading"
+            :key="tableKey"
+            :data="list"
+            stripe
+            border
+            fit
+            highlight-current-row
+            style="width: 100%;"
+          >
+            <el-table-column type="index" width="40"></el-table-column>
+
+            <el-table-column :label="$t('label.skuName')" show-overflow-tooltip>
+              <template v-slot="{ row }">
+                <span>{{ row.name }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column :label="$t('label.goodsSku')" align="center">
+              <template v-slot="{ row }">
+                <span>{{ row.skuCode }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column :label="$t('label.price')" align="center">
+              <template v-slot="{ row }">
+                <span>{{ row.price }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column :label="$t('label.color')" align="center">
+              <template v-slot="{ row }">
+                <span>{{ row.colorName }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column :label="$t('label.size')" align="center">
+              <template v-slot="{ row }">
+                <span>{{ row.sizes }}</span>
+              </template>
+            </el-table-column>
+
+            <el-table-column
+              v-if="status !== 1"
+              :label="$t('label.operation')"
+              width="150"
+              align="center"
+            >
+              <template v-slot="{ row }">
+                <el-tooltip
+                  class="item"
+                  effect="dark"
+                  :content="$t('view.delete')"
+                  placement="top-start"
+                >
+                  <el-button
+                    v-has="'promotionGift:delete'"
+                    type="danger"
+                    circle
+                    size="mini"
+                    icon="el-icon-delete"
+                    @click="handleDelete(row.id)"
+                  >
+                  </el-button>
+                </el-tooltip>
+              </template>
+            </el-table-column>
+          </el-table>
+          <!-- 分页 -->
+          <swPage
+            v-if="total > 0"
+            key="2"
+            :listQuery="listQuery"
+            :total="total"
+            pos="btmRight"
+            @retPage="getList"
+          />
+        </el-main>
+      </el-container>
+
+      <template slot="footer">
+        <div class="footer-class">
+          <el-button @click="dialogFormVisible = false"
+            >{{ $t("tagsView.close") }}
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      v-loading="pageLoad"
+      :title="$t('title.promotionGoodsImport')"
+      :visible.sync="uploadVisible"
+      width="38%"
+      :destroy-on-close="true"
+      :close-on-click-modal="false"
+    >
+      <el-form label-position="right" label-width="140px">
+        <el-form-item :label="$t('label.importTemplate')">
+          <el-button class="filter-item" @click="excelTemplate" type="primary">
+            {{ $t("view.downloadImportTemplate") }}
+          </el-button>
+        </el-form-item>
+
+        <el-form-item :label="$t('label.importData')">
+          <el-upload
+            ref="uploadRef"
+            :limit="1"
+            accept=".xlsx"
+            :headers="headers"
+            :action="uploadUrl"
+            :on-success="handleFileSuccess"
+            :auto-upload="false"
+            :data="uploadData"
+            drag
+          >
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">
+              {{ $t("view.uploadFile") }}<em>{{ $t("view.clickUp") }}</em>
+            </div>
+            <div class="el-upload__tip" slot="tip">
+              {{ $t("view.xlsxFormatOnly") }}
+            </div>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="uploadVisible = false">{{
+          $t("view.cancel")
+        }}</el-button>
+        <el-button type="primary" @click="submitUpload">{{
+          $t("view.confirm")
+        }}</el-button>
+      </div>
+    </el-dialog>
+
+    <promotion-goods-form
+      ref="promotionGoodsFormRef"
+      @refresh-table="getList"
+    ></promotion-goods-form>
+  </div>
+</template>
+
+<script>
+import waves from "@/directive/waves"; // 水波纹指令
+import SwPage from "@/views/common/swPage.vue";
+import ElContainer from "element-ui/packages/container/src/main";
+import promotionGoodsForm from "@/views/oms/promotion/promotion/promotionGoodsForm.vue";
+import { fetchList, deleteById } from "@/api/oms/order/promotionGoods";
+import { getToken } from "@/utils/auth";
+
+export default {
+  inject: ["reload"], //刷新
+  components: {
+    SwPage,
+    ElContainer,
+    promotionGoodsForm
+  },
+  name: "shopifyPromotionGoodsList",
+  directives: {
+    waves
+  },
+  data() {
+    return {
+      dialogFormVisible: false,
+      tableKey: 0,
+      list: [],
+      total: 0,
+      listLoading: false,
+      listQuery: {
+        upAndDown: null,
+        keywords: null,
+        promotionId: null,
+        skuCode: null,
+        name: null,
+        page: 1,
+        limit: 10
+      },
+      pageLoad: false,
+      uploadVisible: false,
+      uploadUrl:
+        process.env.VUE_APP_OMS_API + "/promotionOrderGoods/uploadExcel",
+      uploadData: {
+        promotionId: null
+      },
+      status: "" // 1 已审核通过
+    };
+  },
+  created() {},
+  computed: {
+    headers: function() {
+      return {
+        "X-Token": getToken()
+      };
+    }
+  },
+  methods: {
+    handleOpen(id, status) {
+      this.status = status;
+      this.listQuery.promotionId = id;
+      this.uploadData.promotionId = id;
+      this.dialogFormVisible = true;
+      this.retPage();
+    },
+    getList() {
+      this.listLoading = true;
+      fetchList(this.listQuery)
+        .then(response => {
+          if (response.code === 200) {
+            this.list = response.data.list;
+            this.total = response.data.total;
+            setTimeout(() => {
+              this.listLoading = false;
+            }, 0.5 * 1000);
+          }
+        })
+        .catch(() => {
+          setTimeout(() => {
+            this.listLoading = false;
+          }, 0.5 * 1000);
+        });
+    },
+    retPage() {
+      this.listQuery.page = 1;
+      this.getList();
+    },
+    handleDelete(id) {
+      this.$confirm("是否删除该记录?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        deleteById(id).then(res => {
+          if (res.code === 200) {
+            this.$message({
+              message: "操作成功",
+              type: "success"
+            });
+            this.getList();
+          }
+        });
+      });
+    },
+    showDialog(id) {
+      this.$refs.promotionGoodsFormRef.showDialog(
+        this.listQuery.promotionId,
+        id
+      );
+    },
+    excelTemplate() {
+      window.location.href =
+        process.env.VUE_APP_OMS_API + "/promotionOrderGoods/excelTemplate";
+    },
+    handleUpload() {
+      this.uploadVisible = true;
+    },
+    submitUpload() {
+      this.$refs.uploadRef.submit();
+      this.pageLoad = true;
+    },
+    //文件上传成功返回
+    handleFileSuccess(response, file, fileList) {
+      this.pageLoad = false;
+      if (file.response.code === 200) {
+        this.$message({
+          message: "导入成功",
+          type: "success"
+        });
+        this.uploadVisible = false;
+        this.getList();
+      } else {
+        this.$message.error(file.response.msg);
+        //删除上传列表中,失败的文件
+        let index = 0;
+        for (const i in fileList) {
+          if (fileList[i] == file) {
+            index = i;
+            break;
+          }
+        }
+        //移出当前文件对象
+        fileList.splice(index, 1);
+      }
+    }
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.footer-class {
+  position: fixed;
+  bottom: 20px;
+  right: 20px;
+}
+</style>

+ 139 - 0
src/views/oms/promotion/shopifyPromotion/promotionLogList.vue

@@ -0,0 +1,139 @@
+<template>
+  <div>
+    <el-dialog
+      :title="$t('title.operationLog')"
+      append-to-body
+      top="5vh"
+      width="60%"
+      :visible.sync="dialogFormVisible"
+    >
+      <div style="height: 72vh; overflow: auto">
+        <el-table
+          v-loading="listLoading"
+          :key="tableKey"
+          :data="list"
+          stripe
+          border
+          fit
+          highlight-current-row
+          style="width: 100%;"
+        >
+          <el-table-column type="index" width="40"></el-table-column>
+
+          <el-table-column
+            :label="$t('label.operator')"
+            align="center"
+            width="220"
+            show-overflow-tooltip
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.userName }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="$t('label.operationTime')"
+            align="center"
+            width="220"
+            show-overflow-tooltip
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.createTime }}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            :label="$t('label.operationMethod')"
+            align="center"
+            show-overflow-tooltip
+          >
+            <template v-slot="{ row }">
+              <span>{{ row.remark }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+        <!-- 分页 -->
+        <swPage
+          v-if="total > 0"
+          key="2"
+          :listQuery="listQuery"
+          :total="total"
+          pos="btmRight"
+          @retPage="getList"
+        />
+      </div>
+
+      <template slot="footer">
+        <el-button @click="dialogFormVisible = false"
+          >{{ $t("tagsView.close") }}
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import waves from "@/directive/waves"; // 水波纹指令
+import SwPage from "@/views/common/swPage.vue";
+import ElContainer from "element-ui/packages/container/src/main";
+import { promotionLogs } from "@/api/oms/order/promotion";
+
+export default {
+  inject: ["reload"], //刷新
+  components: {
+    SwPage,
+    ElContainer
+  },
+  name: "shopifyPromotionLogList",
+  directives: {
+    waves
+  },
+  data() {
+    return {
+      dialogFormVisible: false,
+      tableKey: 0,
+      list: [],
+      total: 0,
+      listLoading: false,
+      listQuery: {
+        upAndDown: null,
+        keywords: null,
+        page: 1,
+        limit: 10
+      }
+    };
+  },
+  created() {},
+  computed: {},
+  methods: {
+    handleOpen(id) {
+      this.listQuery.promotionId = id;
+      this.dialogFormVisible = true;
+      this.retPage();
+    },
+    getList() {
+      this.listLoading = true;
+      promotionLogs(this.listQuery)
+        .then(response => {
+          if (response.code === 200) {
+            this.list = response.data.list;
+            this.total = response.data.total;
+            setTimeout(() => {
+              this.listLoading = false;
+            }, 0.5 * 1000);
+          }
+        })
+        .catch(() => {
+          setTimeout(() => {
+            this.listLoading = false;
+          }, 0.5 * 1000);
+        });
+    },
+    retPage() {
+      this.listQuery.page = 1;
+      this.getList();
+    }
+  }
+};
+</script>
+
+<style scoped lang="scss"></style>

+ 13 - 0
src/views/oms/promotion/shopifyPromotion/test.vue

@@ -0,0 +1,13 @@
+<template>
+  <div>123</div>
+</template>
+
+<script>
+export default {
+
+}
+</script>
+
+<style>
+
+</style>

+ 93 - 90
vue.config.js

@@ -1,56 +1,60 @@
-'use strict';
-const path = require('path');
-const defaultSettings = require('./src/settings.js');
+"use strict";
+const path = require("path");
+const defaultSettings = require("./src/settings.js");
 
 function resolve(dir) {
-  return path.join(__dirname, dir)
+  return path.join(__dirname, dir);
 }
-const name = defaultSettings.title || '歌莉娅海外订单中心(FOMS)';// 标题
+const name = defaultSettings.title || "歌莉娅海外订单中心(FOMS)"; // 标题
 const port = process.env.port || process.env.npm_config_port || 9527; // 开发接口
 
 // 所有配置项描述 查看: https://cli.vuejs.org/config/
 module.exports = {
-  publicPath: './', // 基本路径
-  outputDir: 'dist', // 输出文件目录
-  assetsDir: 'static',// 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
+  publicPath: "./", // 基本路径
+  outputDir: "dist", // 输出文件目录
+  assetsDir: "static", // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
   // 指定生成的 index.html 的输出路径 (相对于 outputDir)。也可以是一个绝对路径
   // indexPath: './',
-  lintOnSave: process.env.NODE_ENV === 'production',// lintOnSave: eslint-loader 是否在保存的时候检查
+  lintOnSave: process.env.NODE_ENV === "production", // lintOnSave: eslint-loader 是否在保存的时候检查
   productionSourceMap: false, // 生产环境是否生成 sourceMap 文件
   devServer: {
     port: port,
-    host: 'swings.pim.com',
-    open: true,
+    // host: "swings.pim.com",
+    // open: true,
     overlay: {
       warnings: false,
       errors: true
     },
-    public: '0.0.0.0:9527', //可以实现热部署
+    public: "0.0.0.0:9527", //可以实现热部署
     proxy: {
-      [process.env.VUE_APP_OAUTH_API]: {
-        target: `http://localhost:19090/sso` ,
-        changeOrigin: true,
-        // logLevel: 'debug', //打印日志
-        pathRewrite: {
-          ['^' + process.env.VUE_APP_OAUTH_API]: ''
-        }
-      },
-      [process.env.VUE_APP_PIM_API]: {
-        target: `http://localhost:18080/pim`,
-        changeOrigin: true,
-        // logLevel: 'debug', //打印日志
-        pathRewrite: {
-          ['^' + process.env.VUE_APP_PIM_API]: ''
-        }
-      },
-      [process.env.VUE_APP_OMS_API]: {
-        target: `http://localhost:18081/oms`,
-        changeOrigin: true,
-        // logLevel: 'debug', //打印日志
-        pathRewrite: {
-          ['^' + process.env.VUE_APP_OMS_API]: ''
-        }
+      "/": {
+        target: "https://testfoms.gloria.com.cn",
+        changeOrigin: true
       }
+      // [process.env.VUE_APP_OAUTH_API]: {
+      //   target: `http://localhost:19090/sso` ,
+      //   changeOrigin: true,
+      //   // logLevel: 'debug', //打印日志
+      //   pathRewrite: {
+      //     ['^' + process.env.VUE_APP_OAUTH_API]: ''
+      //   }
+      // },
+      // [process.env.VUE_APP_PIM_API]: {
+      //   target: `http://localhost:18080/pim`,
+      //   changeOrigin: true,
+      //   // logLevel: 'debug', //打印日志
+      //   pathRewrite: {
+      //     ['^' + process.env.VUE_APP_PIM_API]: ''
+      //   }
+      // },
+      // [process.env.VUE_APP_OMS_API]: {
+      //   target: `http://localhost:18081/oms`,
+      //   changeOrigin: true,
+      //   // logLevel: 'debug', //打印日志
+      //   pathRewrite: {
+      //     ['^' + process.env.VUE_APP_OMS_API]: ''
+      //   }
+      // }
     }
   },
   // webpack配置
@@ -58,88 +62,87 @@ module.exports = {
     name: name,
     resolve: {
       alias: {
-        '@': resolve('src')
+        "@": resolve("src")
       }
     }
   },
   chainWebpack(config) {
-  	// 删除预加载
-    config.plugins.delete('preload');// TODO: need test
-    config.plugins.delete('prefetch');// TODO: need test
+    // 删除预加载
+    config.plugins.delete("preload"); // TODO: need test
+    config.plugins.delete("prefetch"); // TODO: need test
 
     // set svg-sprite-loader
     config.module
-      .rule('svg')
-      .exclude.add(resolve('src/icons'))
+      .rule("svg")
+      .exclude.add(resolve("src/icons"))
       .end();
     config.module
-      .rule('icons')
+      .rule("icons")
       .test(/\.svg$/)
-      .include.add(resolve('src/icons'))
+      .include.add(resolve("src/icons"))
       .end()
-      .use('svg-sprite-loader')
-      .loader('svg-sprite-loader')
+      .use("svg-sprite-loader")
+      .loader("svg-sprite-loader")
       .options({
-        symbolId: 'icon-[name]'
+        symbolId: "icon-[name]"
       })
       .end();
 
     // set preserveWhitespace
     config.module
-      .rule('vue')
-      .use('vue-loader')
-      .loader('vue-loader')
+      .rule("vue")
+      .use("vue-loader")
+      .loader("vue-loader")
       .tap(options => {
-        options.compilerOptions.preserveWhitespace = true
-        return options
+        options.compilerOptions.preserveWhitespace = true;
+        return options;
       })
       .end();
 
     config
       // https://webpack.js.org/configuration/devtool/#development
-      .when(process.env.NODE_ENV === 'development',
-        config => config.devtool('cheap-source-map')
+      .when(process.env.NODE_ENV === "development", config =>
+        config.devtool("cheap-source-map")
       );
 
-    config
-      .when(process.env.NODE_ENV !== 'development',
-        config => {//非开发环境
-          config
-            .plugin('ScriptExtHtmlWebpackPlugin')
-            .after('html')
-            .use('script-ext-html-webpack-plugin', [{
+    config.when(process.env.NODE_ENV !== "development", config => {
+      //非开发环境
+      config
+        .plugin("ScriptExtHtmlWebpackPlugin")
+        .after("html")
+        .use("script-ext-html-webpack-plugin", [
+          {
             // `runtime` must same as runtimeChunk name. default is `runtime`
-              inline: /runtime\..*\.js$/
-            }])
-            .end();
+            inline: /runtime\..*\.js$/
+          }
+        ])
+        .end();
 
-          // 分割代码
-          config
-            .optimization.splitChunks({
-              chunks: 'all',
-              cacheGroups: {
-                libs: {
-                  name: 'chunk-libs',
-                  test: /[\\/]node_modules[\\/]/,
-                  priority: 10,
-                  chunks: 'initial' // only package third parties that are initially dependent
-                },
-                elementUI: {
-                  name: 'chunk-elementUI', // split elementUI into a single package
-                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
-                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
-                },
-                commons: {
-                  name: 'chunk-commons',
-                  test: resolve('src/components'), // can customize your rules
-                  minChunks: 3, //  minimum common number
-                  priority: 5,
-                  reuseExistingChunk: false
-                }
-              }
-            });
-          config.optimization.runtimeChunk('single')
+      // 分割代码
+      config.optimization.splitChunks({
+        chunks: "all",
+        cacheGroups: {
+          libs: {
+            name: "chunk-libs",
+            test: /[\\/]node_modules[\\/]/,
+            priority: 10,
+            chunks: "initial" // only package third parties that are initially dependent
+          },
+          elementUI: {
+            name: "chunk-elementUI", // split elementUI into a single package
+            priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
+            test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
+          },
+          commons: {
+            name: "chunk-commons",
+            test: resolve("src/components"), // can customize your rules
+            minChunks: 3, //  minimum common number
+            priority: 5,
+            reuseExistingChunk: false
+          }
         }
-      )
+      });
+      config.optimization.runtimeChunk("single");
+    });
   }
 };