Jelajahi Sumber

维多利亚待出库调整

cz 1 tahun lalu
induk
melakukan
93c8a15314

+ 1 - 0
package.json

@@ -26,6 +26,7 @@
     "@antv/x6-plugin-stencil": "^2.0.2",
     "@antv/x6-plugin-transform": "^2.1.6",
     "@antv/x6-vue-shape": "^2.0.11",
+    "@tinymce/tinymce-vue": "^5.1.0",
     "@vue-flow/additional-components": "^1.3.3",
     "@vue-flow/core": "^1.18.2",
     "@vueup/vue-quill": "^1.0.0-alpha.40",

+ 98 - 0
src/components/Editor/TinymceEditor.vue

@@ -0,0 +1,98 @@
+<template>
+  <div>
+    <Editor
+      api-key="写你的key"
+      :init="init"
+      v-model:content="content"
+      ref="tinymce"
+    />
+  </div>
+</template>
+
+<script setup name="TinymceEditor">
+import Editor from "@tinymce/tinymce-vue";
+const { proxy } = getCurrentInstance();
+const props = defineProps(["value"]);
+const emit = defineEmits(["updateValue"]);
+const content = ref("");
+const tinymce = ref(null);
+const value = ref("");
+const init = reactive({
+  plugins: "lists link image table code help wordcount",
+  toolbar:
+    "myButton | fontselect | fontsizeselect | formatselect | bold italic underline forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table | image | removeformat",
+  content_css: "tinymce-5", //主题tinymce-5-dark || tinymce-5 || default || writer || document || dark
+  custom_undo_redo_levels: 50, //回退数量
+  end_container_on_empty_block: true, //块级文本是否换行
+  keep_styles: true, //回车是否保存原有样式,例如code块回车是否截断
+  menubar: false, //是否开启顶部菜单 > false 关闭菜单 |  'edit insert view format table tools help' 菜单按照这里排序 | 参考:https://www.tiny.cloud/docs/tinymce/6/menus-configuration-options/
+  toolbar_mode: "wrap", //功能栏是否换行 > | wrap 换行  | scrolling 滚动 | sliding 省略
+  toolbar_location: "top", //菜单栏位置 > bottom 底部 | top 顶部
+  style_formats_merge: true, //是否开启默认功能
+  elementpath: false, //是否展示编辑层级  > p span
+  resize: true, //调整宽高 > true 调整高 | false 不可调整宽高 | both 宽高可调
+  language: "zh_CN", //中文
+  images_upload_url: "/demo/upimg.php",
+  images_upload_base_path: "/demo",
+  // 自定义快捷将
+  text_patterns: [
+    { start: "---", replacement: "<hr/>" },
+    { start: "--", replacement: "—" },
+    { start: "-", replacement: "—" },
+    { start: "(c)", replacement: "©" },
+    { start: "//brb", replacement: "Be Right Back" },
+    {
+      start: "//h",
+      replacement:
+        '<h1 style="color: blue">Heading here</h1> <h2>Author: Name here</h2> <p><em>Date: 01/01/2000</em></p> <hr />',
+    },
+  ],
+  images_upload_handler: function (blobInfo, succFun, failFun) {
+    var xhr, formData;
+    var file = blobInfo.blob(); //转化为易于理解的file对象
+    xhr = new XMLHttpRequest();
+    xhr.withCredentials = false;
+    xhr.open("POST", "/demo/upimg.php");
+    xhr.onload = function () {
+      var json;
+      if (xhr.status != 200) {
+        failFun("HTTP Error: " + xhr.status);
+        return;
+      }
+      json = JSON.parse(xhr.responseText);
+      if (!json || typeof json.location != "string") {
+        failFun("Invalid JSON: " + xhr.responseText);
+        return;
+      }
+      succFun(json.location);
+    };
+    formData = new FormData();
+    formData.append("file", file, file.name); //此处与源文档不一样
+    xhr.send(formData);
+  },
+
+  // 自定义指令
+  text_patterns_lookup: (ctx) => {
+    const parentTag = ctx.block.nodeName.toLowerCase();
+    if (parentTag === "pre" || parentTag === "p") {
+      return [{ start: "`", end: "`", format: "code" }];
+    } else if (parentTag === "p") {
+      return [{ start: "*", end: "*", format: "bold" }];
+    } else if (parentTag === "span") {
+      return [
+        // ctx.text is the string from the start of the block to the cursor
+        { start: "brb", replacement: ctx.text + ": Be Right Back" },
+      ];
+    } else {
+      return [];
+    }
+  },
+});
+
+onMounted(() => {
+  content.value = props.value;
+});
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 46 - 0
src/components/Editor/aa.vue

@@ -0,0 +1,46 @@
+<template>
+  <div class="app-container">
+    <Editor
+      id="tinymce"
+      v-model="tinymceHtml"
+      :init="init"
+      @paste="customPaste($event)"
+    /><!-- <div v-html="tinymceHtml"></div> -->
+  </div>
+</template>
+<script setup lang="ts">
+import { ref, onMounted, watch } from "vue";
+import tinymce from "tinymce/tinymce";
+// 使用该方法需要引入下面的数据
+import "tinymce/models/dom"; // 特别注意 tinymce 6.0.0 版本之后必须引入,否则不显示
+import "tinymce/themes/silver/theme";
+import Editor from "@tinymce/tinymce-vue"; // 引入组件
+import "tinymce/icons/default";
+import "tinymce/plugins/image";
+import "tinymce/plugins/link";
+import "tinymce/plugins/code";
+import "tinymce/plugins/table";
+import "tinymce/plugins/lists";
+import "tinymce/plugins/wordcount"; // 引入富文本编辑器主题的js和css
+import "tinymce/themes/silver/theme.min.js";
+import "tinymce/skins/ui/oxide/skin.min.css"; // 以上所有的样式在 node_modules 下面 tinymce 里面的 plugins 都能找到。
+const tinymceHtml = ref<string>("");
+const init = {
+  //初始化数据selector: 'textarea',height: 300, // 限制高度statusbar: false,object_resizing: false,image_description: false,image_dimensions: false, // 禁止操作图片plugins: 'link lists image code table wordcount', // 富文本插件font_size_formats: '8px 10px 12px 14px 16px 18px 24px 36px 48px 128px',font_family_formats:'微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif',toolbar:'undo redo fontfamily fontsize fontname bold italic underline strikethrough | fontsizeselect | forecolor | alignleft aligncenter alignright',branding: false, // //是否禁用“Powered by TinyMCE”menubar: false, //顶部菜单栏显示paste_data_images: false, // 禁止粘贴图片
+};
+
+const emits = defineEmits<{
+  (event: "update:bindHtml", val: string): void; // 富文本内容
+}>();
+
+onMounted(() => {
+  tinymce.init({}); // 初始化富文本
+}); // 实现双向绑定
+
+watch(
+  () => tinymceHtml.value,
+  () => {
+    emits("update:bindHtml", tinymce.activeEditor!.getContent());
+  }
+);
+</script>

+ 9 - 4
src/views/WDLY/basic/product/index.vue

@@ -753,6 +753,7 @@ const formConfig = computed(() => {
 const newPassword = () => {
   formData.data.password = generatePassword();
 };
+
 const generatePassword = () => {
   var length = 12,
     charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
@@ -934,10 +935,14 @@ const getDtl = (row) => {
   modalType.value = "edit";
   proxy.post("/productInfo/detailByWdly", { id: row.id }).then((res) => {
     if (res.victoriatouristJson) {
-      const jsonObj = parse(res.victoriatouristJson);
-      if (jsonObj && jsonObj.deptId) {
-        deptIdCopy.value = jsonObj.deptId.value;
-      }
+      res.victoriatouristJson = res.victoriatouristJson.replace(
+        /\"deptId":(\d+)/g,
+        '"deptId": "$1"'
+      );
+      res.victoriatouristJson = res.victoriatouristJson.replace(
+        /\"linkProductId":(\d+)/g,
+        '"linkProductId": "$1"'
+      );
     }
     fileList.value = row.fileList.map((x) => ({ ...x, url: x.fileUrl }));
     fileListCopy.value = [...fileList.value];

+ 1 - 1
src/views/WDLY/outInBound/waitInBound/index.vue

@@ -61,7 +61,7 @@
                       v-model="row.quantity"
                       :precision="0"
                       :controls="false"
-                      :min="1"
+                      :min="0"
                       onmousewheel="return false;"
                     />
                   </el-form-item>

+ 168 - 188
src/views/WDLY/outInBound/waitOutBound/index.vue

@@ -32,7 +32,7 @@
         :formConfig="formConfig"
         :formOption="formOption"
         v-model="formData.data"
-        :rules="rules"
+        :rules="submitType == 5 ? rulesOne : rules"
         ref="byform"
       >
         <template #products>
@@ -40,11 +40,20 @@
             <el-table :data="formData.data.jdOrderDetailsList">
               <el-table-column prop="productCode" label="物品编码" />
               <el-table-column prop="productName" label="物品名称" />
-              <el-table-column prop="productSpec" label="规格型号" />
-              <el-table-column prop="waitQuantity" label="待出库数量" />
+              <!-- <el-table-column
+                prop="productSpec"
+                label="规格型号"
+                v-if="submitType == 5"
+              /> -->
+              <el-table-column prop="waitQuantity" label="应出库" />
+              <el-table-column
+                prop="receiptQuantity"
+                label="已出库"
+                v-if="submitType != 5"
+              />
               <el-table-column
                 prop="quantity"
-                label="出库数量"
+                label="本次出库"
                 min-width="150"
                 v-if="submitType != 5"
               >
@@ -163,6 +172,27 @@ let rules = ref({
     { required: true, message: "请选择调入仓库", trigger: "change" },
   ],
   quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
+  logisticsCompanyCode: [
+    { required: true, message: "请选择物流/快递公司", trigger: "change" },
+  ],
+  logisticsCode: [
+    { required: true, message: "请输入物流/快递单号", trigger: "blur" },
+  ],
+});
+let rulesOne = ref({
+  type: [
+    { required: true, message: "请选择仓库类型", trigger: ["blur", "change"] },
+  ],
+  warehouseId: [
+    { required: true, message: "请选择仓库名称", trigger: "change" },
+  ],
+  outWarehouseId: [
+    { required: true, message: "请选择调出仓库", trigger: "change" },
+  ],
+  inWarehouseId: [
+    { required: true, message: "请选择调入仓库", trigger: "change" },
+  ],
+  quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
 });
 const { proxy } = getCurrentInstance();
 const selectConfig = reactive([
@@ -207,51 +237,20 @@ const config = computed(() => {
     },
     {
       attrs: {
-        label: "单号",
+        label: "关联单号",
         prop: "businessCode",
       },
     },
-
-    {
-      attrs: {
-        label: "物品类型",
-        prop: "productDefinition",
-      },
-      render(definition) {
-        return definition == 1 ? "产品" : definition == 2 ? "物料" : "";
-      },
-    },
-    {
-      attrs: {
-        label: "物品编码",
-        prop: "productCustomCode",
-      },
-    },
-    {
-      attrs: {
-        label: "物品名称",
-        prop: "productName",
-      },
-    },
-    {
-      attrs: {
-        label: "型号规格",
-        prop: "productSpec",
-      },
-    },
     {
       attrs: {
-        label: "单位",
-        prop: "productUnit",
-      },
-      render(unit) {
-        return proxy.dictValueLabel(unit, productUnit.value);
+        label: "操作人",
+        prop: "operatorName",
       },
     },
     {
       attrs: {
-        label: "待出库",
-        prop: "quantity",
+        label: "操作时间",
+        prop: "createTime",
       },
     },
     {
@@ -312,48 +311,41 @@ const configData = computed(() => [
   [
     {
       type: "title",
-      title: "待出库信息",
-    },
-    {
-      type: "select",
-      prop: "warehouseId",
-      label: "仓库名称",
-      itemWidth: 30,
-      data: warehouseList.value,
+      title: "基础信息",
     },
     {
       type: "select",
       prop: "businessType",
-      label: "出库类型",
+      label: "数据来源",
       required: true,
       disabled: true,
-      itemWidth: 30,
+      itemWidth: 25,
       data: businessType,
     },
-    // {
-    //   type: "input",
-    //   prop: "businessCode",
-    //   label: "单号",
-    //   required: true,
-    //   disabled: true,
-    //   itemWidth: 40,
-    // },
     {
-      type: "title",
-      title: "待出库明细",
-    },
-    {
-      type: "slot",
-      slotName: "products",
+      type: "input",
+      prop: "businessCode",
+      label: "关联单号",
+      required: true,
+      disabled: true,
+      itemWidth: 30,
     },
     {
-      type: "title",
-      title: "物流信息",
+      type: "select",
+      prop: "warehouseId",
+      label: "仓库名称",
+      itemWidth: 100,
+      data: warehouseList.value,
+      style: {
+        width: "53%",
+      },
     },
     {
       type: "select",
       prop: "logisticsCompanyCode",
-      itemWidth: 50,
+      label: "物流/快递信息",
+      placeholder: "物流/快递公司",
+      itemWidth: 25,
       style: {
         width: "100%",
       },
@@ -363,8 +355,17 @@ const configData = computed(() => [
     {
       type: "input",
       prop: "logisticsCode",
+      label: " ",
       placeholder: "物流/快递单号",
-      itemWidth: 50,
+      itemWidth: 30,
+    },
+    {
+      type: "title",
+      title: "出库明细",
+    },
+    {
+      type: "slot",
+      slotName: "products",
     },
   ],
   [
@@ -403,21 +404,11 @@ const configData = computed(() => [
       disabled: false,
     },
     {
-      type: "title",
-      title: "调仓明细",
-    },
-    {
-      type: "slot",
-      slotName: "products",
-    },
-    {
-      type: "title",
-      title: "物流信息",
-    },
-    {
       type: "select",
       prop: "logisticsCompanyCode",
       itemWidth: 50,
+      label: "物流/快递信息",
+      placeholder: "物流/快递公司",
       style: {
         width: "100%",
       },
@@ -427,16 +418,25 @@ const configData = computed(() => [
     {
       type: "input",
       prop: "logisticsCode",
+      label: " ",
       placeholder: "物流/快递单号",
       itemWidth: 50,
     },
+    {
+      type: "title",
+      title: "调仓明细",
+    },
+    {
+      type: "slot",
+      slotName: "products",
+    },
   ],
 ]);
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
   proxy
-    .post("/stockWaitDetails/page", sourceList.value.pagination)
+    .post("/stockWait/pageByWdly", sourceList.value.pagination)
     .then((message) => {
       sourceList.value.data = message.rows.map((x) => ({
         ...x,
@@ -459,43 +459,38 @@ const openModal = () => {
 const submitForm = () => {
   byform.value.handleSubmit((valid) => {
     if (submitType.value == 4) {
-      const data = {
-        id: formData.data.id,
-        businessType: formData.data.businessType,
-        warehouseId: formData.data.warehouseId,
-      };
-      if (
-        formData.data.jdOrderDetailsList &&
-        formData.data.jdOrderDetailsList.length > 0
-      ) {
-        data.quantity = formData.data.jdOrderDetailsList[0].quantity;
-        data.waitQuantity = formData.data.jdOrderDetailsList[0].waitQuantity;
-      }
-      if (!(data.quantity > 0)) {
+      const list = formData.data.jdOrderDetailsList;
+      const total = list.reduce((total, x) => (total += Number(x.quantity)), 0);
+      if (total > 0) {
+        const data = {
+          id: formData.data.id,
+          businessType: formData.data.businessType,
+          warehouseId: formData.data.warehouseId,
+          stockWaitDetailsList: list.map((x) => ({
+            id: x.id,
+            quantity: x.quantity,
+            productId: x.productId,
+          })),
+        };
+        submitLoading.value = true;
+        proxy.post("/purchaseBack/backOuts", data).then(
+          (res) => {
+            ElMessage({
+              message: "操作成功",
+              type: "success",
+            });
+            dialogVisible.value = false;
+            submitLoading.value = false;
+            getList();
+          },
+          (err) => (submitLoading.value = false)
+        );
+      } else {
         return ElMessage({
           message: "出库数量不能为0!",
           type: "info",
         });
       }
-      if (data.quantity > data.waitQuantity) {
-        return ElMessage({
-          message: "出库数量不能大于待出库数量!",
-          type: "info",
-        });
-      }
-      submitLoading.value = true;
-      proxy.post("/purchaseBack/backOut", data).then(
-        (res) => {
-          ElMessage({
-            message: "操作成功",
-            type: "success",
-          });
-          dialogVisible.value = false;
-          submitLoading.value = false;
-          getList();
-        },
-        (err) => (submitLoading.value = false)
-      );
     } else if (submitType.value == 5) {
       if (formData.data.inWarehouseId === formData.data.outWarehouseId) {
         return ElMessage({
@@ -514,7 +509,7 @@ const submitForm = () => {
         }
         if (e.quantity > e.waitQuantity) {
           return ElMessage({
-            message: "调仓数量不能大于出库数量!",
+            message: "调仓数量不能大于出库数量!",
             type: "info",
           });
         }
@@ -533,44 +528,40 @@ const submitForm = () => {
         (err) => (submitLoading.value = false)
       );
     } else if (submitType.value == 6) {
-      const data = {
-        id: formData.data.id,
-        businessType: formData.data.businessType,
-        warehouseId: formData.data.warehouseId,
-      };
-
-      if (
-        formData.data.jdOrderDetailsList &&
-        formData.data.jdOrderDetailsList.length > 0
-      ) {
-        data.quantity = formData.data.jdOrderDetailsList[0].quantity;
-        data.waitQuantity = formData.data.jdOrderDetailsList[0].waitQuantity;
-      }
-      if (!(data.quantity > 0)) {
+      const list = formData.data.jdOrderDetailsList;
+      const total = list.reduce((total, x) => (total += Number(x.quantity)), 0);
+      if (total > 0) {
+        const data = {
+          id: formData.data.id,
+          businessId: formData.data.businessId,
+          businessType: formData.data.businessType,
+          warehouseId: formData.data.warehouseId,
+          type: "2", //2是出库
+          stockWaitDetailsList: list.map((x) => ({
+            id: x.id,
+            quantity: x.quantity,
+            productId: x.productId,
+          })),
+        };
+        submitLoading.value = true;
+        proxy.post("/stockWait/addByWdly", data).then(
+          (res) => {
+            ElMessage({
+              message: "操作成功",
+              type: "success",
+            });
+            dialogVisible.value = false;
+            submitLoading.value = false;
+            getList();
+          },
+          (err) => (submitLoading.value = false)
+        );
+      } else {
         return ElMessage({
           message: "出库数量不能为0!",
           type: "info",
         });
       }
-      if (data.quantity > data.waitQuantity) {
-        return ElMessage({
-          message: "出库数量不能大于待出库数量!",
-          type: "info",
-        });
-      }
-      submitLoading.value = true;
-      proxy.post("/stockWaitDetails/add", data).then(
-        (res) => {
-          ElMessage({
-            message: "操作成功",
-            type: "success",
-          });
-          dialogVisible.value = false;
-          submitLoading.value = false;
-          getList();
-        },
-        (err) => (submitLoading.value = false)
-      );
     }
   });
 };
@@ -580,61 +571,50 @@ const outBound = (row) => {
   if (row.businessType == 4) {
     modalType.value = "other";
     formConfig.value = configData.value[0];
-    formData.data = {
-      id: row.id,
-      warehouseId: "",
-      businessType: row.businessType + "",
-      businessCode: row.businessCode,
-      jdOrderDetailsList: [
-        {
-          waitQuantity: row.quantity,
-          quantity: undefined,
-          productCode: row.productCode,
-          productName: row.productName,
-          productSpec: row.productSpec,
-        },
-      ],
-    };
-    dialogVisible.value = true;
+    proxy.post("/stockWait/detailByWdly", { id: row.id }).then((res) => {
+      res.jdOrderDetailsList = res.stockWaitDetailsList.map((x) => ({
+        ...x,
+        waitQuantity: x.quantity,
+        quantity: undefined,
+      }));
+      res.businessType = res.businessType + "";
+      formData.data = res;
+      dialogVisible.value = true;
+    });
   } else if (row.businessType == 5) {
     modalType.value = "add";
     formConfig.value = configData.value[1];
     proxy.post("/jdOrder/detail", { id: row.businessId }).then((res) => {
+      res.jdOrderDetailsList = res.jdOrderDetailsList.map((x) => ({
+        waitQuantity: x.quantity,
+        quantity: undefined,
+        productId: x.productId,
+        id: x.id,
+        productCode: x.productCode,
+        productName: x.productName,
+        productSpec: x.productSpec,
+      }));
       formData.data = {
         id: row.businessId,
         outWarehouseId: "",
         inWarehouseId: "",
-        jdOrderDetailsList: res.jdOrderDetailsList.map((x) => ({
-          waitQuantity: row.quantity,
-          quantity: row.quantity,
-          productId: x.productId,
-          id: x.id,
-          productCode: x.productCode,
-          productName: x.productName,
-          productSpec: x.productSpec,
-        })),
+        jdOrderDetailsList: res.jdOrderDetailsList,
       };
       dialogVisible.value = true;
     });
   } else if (row.businessType == 6) {
     modalType.value = "edit";
     formConfig.value = configData.value[0];
-    formData.data = {
-      id: row.id,
-      warehouseId: "",
-      businessType: row.businessType + "",
-      businessCode: row.businessCode,
-      jdOrderDetailsList: [
-        {
-          waitQuantity: row.quantity,
-          quantity: undefined,
-          productCode: row.productCode,
-          productName: row.productName,
-          productSpec: row.productSpec,
-        },
-      ],
-    };
-    dialogVisible.value = true;
+    proxy.post("/stockWait/detailByWdly", { id: row.id }).then((res) => {
+      res.jdOrderDetailsList = res.stockWaitDetailsList.map((x) => ({
+        ...x,
+        waitQuantity: x.quantity,
+        quantity: undefined,
+      }));
+      res.businessType = res.businessType + "";
+      formData.data = res;
+      dialogVisible.value = true;
+    });
   }
 };
 const warehouseType = ref([]);

+ 8 - 2
src/views/connect/E-mail/mail/com/left.vue

@@ -114,7 +114,12 @@
                   v-if="data.id == '0'"
                   style="margin-right: 5px"
                 ></i>
-                <span>{{ data.name }}</span>
+                <span
+                  >{{ data.name }}
+                  <span v-if="data.userId && data.children.length === 0">
+                    (点击获取员工邮箱)</span
+                  ></span
+                >
               </span>
             </template>
           </el-tree>
@@ -595,7 +600,8 @@ const getMialList = () => {
     if (res && res.length > 0) {
       res = res.map((x) => ({
         ...x,
-        name: x.nickName + "(点击获取员工邮箱)",
+        name: x.nickName,
+        children: [],
       }));
     }
     staffMailData.value = [

+ 3 - 0
src/views/connect/E-mail/mail/com/mailWrite.vue

@@ -201,6 +201,7 @@
               @updateValue="updateContent"
               ref="contentEditor"
             />
+            <!-- <TinymceEditor :value="formData.data.content" ref="contentEditor" /> -->
           </div>
         </el-form-item>
         <el-form-item label="发件人" prop="replyTo">
@@ -222,6 +223,8 @@
 import byForm from "@/components/byForm/index";
 import { ElMessage, ElMessageBox } from "element-plus";
 import Editor from "@/components/Editor/index.vue";
+import TinymceEditor from "@/components/Editor/TinymceEditor.vue";
+
 import { validEmail } from "@/utils/validate.js";
 import useMailStore from "@/store/modules/mail";
 import { nextTick } from "vue";