瀏覽代碼

Merge branch 'sit' of http://120.46.155.214:3000/xiaodai2022/order-client-ui-pc into sit

snow 2 年之前
父節點
當前提交
74fb4efe64

+ 7 - 0
.env.jiesuan

@@ -0,0 +1,7 @@
+NODE_ENV = jiesuan
+
+# just a flag
+ENV = 'jiesuan'
+
+# base api
+VUE_APP_BASE_API = '/jiesuan-api'

+ 3 - 2
package.json

@@ -10,6 +10,7 @@
     "build:stage": "vue-cli-service build --mode staging",
     "build:dev": "vue-cli-service build --mode development",
     "build:process": "vue-cli-service build --mode process",
+    "build:jiesuan": "vue-cli-service build --mode jiesuan",
     "preview": "node build/index.js --preview",
     "new": "plop",
     "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
@@ -23,8 +24,6 @@
   "dependencies": {
     "@jiaminghi/data-view": "^2.7.3",
     "@types/echarts": "^4.4.3",
-    "echarts": "^4.6.0",
-    "vue-awesome": "^4.0.2",
     "babel-eslint": "^7.2.3",
     "babel-polyfill": "^6.26.0",
     "clipboard": "2.0.4",
@@ -35,6 +34,7 @@
     "dayjs": "^1.10.4",
     "driver.js": "0.9.5",
     "dropzone": "5.5.1",
+    "echarts": "^4.6.0",
     "element-ui": "^2.13.2",
     "file-saver": "2.0.1",
     "fuse.js": "3.4.4",
@@ -52,6 +52,7 @@
     "sortablejs": "1.8.4",
     "uglifyjs-webpack-plugin": "^2.2.0",
     "v-viewer": "^1.6.3",
+    "vue-awesome": "^4.0.2",
     "vue-count-to": "^1.0.13",
     "vue-pdf": "^4.3.0",
     "vue-puzzle-verification": "^1.0.2",

+ 40 - 0
src/apis/report/index.js

@@ -0,0 +1,40 @@
+// 物业管理员
+import http from "@/apis/axios";
+const api = "abutment/";
+export default {
+  // 添加
+  add: (data, params) => http(api + "filingAdd", data, "post", params),
+  // 分页查询
+  list: (data, params) => http(api + "filingList", data, "post", params),
+  // 删除
+  delete: (data, params) => http(api + "delete", data, "post", params),
+  // 详情
+  detail: (data, params) => http(api + "getOrderInfo", data, "post", params),
+  // 批量供应商确认
+  status: (data, params) =>
+    http(api + "changeOrderStatus", data, "post", params),
+  // 批量入库
+  addOrderIn: (data, params) => http(api + "addOrderIn", data, "post", params),
+  // 异常原因列表
+  resultlist: (data, params) => http(api + "resultlist", data, "post", params),
+  // 入库单验货
+  orderincheck: (data, params) =>
+    http(api + "orderincheck", data, "post", params),
+  // 入库单退货换货
+  orderinreturn: (data, params) =>
+    http(api + "orderinreturn", data, "post", params),
+  // 发货单状态修改
+  orderinstatus: (data, params) =>
+    http(api + "orderinstatus", data, "post", params),
+  // 采返商品详情
+  re_detail: (data, params) => http(api + "goodzxinfo", data, "post", params),
+  //商品成本详情
+  cost_detail: (data, params) => http(api + "goodupinfo", data, "post", params),
+
+  // 采返商品详情 订单生成前
+  cove_detail: (data, params) =>
+    http(api + "getGoodZxInfoByNotZixun", data, "post", params),
+  //导出
+  exportCgdList: (data, params) =>
+    http(api + "exportCgdList", data, "post", params),
+};

+ 587 - 0
src/components/in-address-modal/index.vue

@@ -0,0 +1,587 @@
+<template>
+  <el-dialog
+    v-loading="loading"
+    :title="title"
+    :center="true"
+    align="left"
+    top="8vh"
+    width="1040px"
+    :close-on-click-modal="false"
+    :visible.sync="showModelThis"
+    element-loading-text="拼命加载中"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0.8)"
+    @close="showModelThis = false"
+    append-to-body
+  >
+    <el-card style="margin-top: -25px">
+      <upload-excel :on-success="handleSuccess" :before-upload="beforeUpload" />
+      <el-form :model="ruleForm" ref="ruleForm" :size="'mini'">
+        <el-table
+          :data="ruleForm.order_addr"
+          border
+          :size="'mini'"
+          style="width: 100%"
+          max-height="400px"
+          row-key="key"
+        >
+          <el-table-column
+            prop="receipt_quantity"
+            label="收货总数"
+            width="100"
+            show-overflow-tooltip
+          />
+
+          <el-table-column
+            prop="contactor"
+            label="收件联系人"
+            show-overflow-tooltip
+            width="85"
+          />
+
+          <el-table-column
+            prop="mobile"
+            label="收货联系电话"
+            show-overflow-tooltip
+            width="100"
+          />
+          <el-table-column
+            show-overflow-tooltip
+            prop="in_addr"
+            label="收货省市区(文件导入)"
+            width="150"
+          />
+          <el-table-column
+            show-overflow-tooltip
+            prop="addr_code_name"
+            label="收货省市区(系统解析)"
+            width="150"
+          />
+          <el-table-column prop="addr" label="详细地址" show-overflow-tooltip />
+
+          <el-table-column fixed="right" width="80" label="操作">
+            <template slot-scope="scope">
+              <el-tooltip effect="dark" content="编辑" placement="top">
+                <i class="el-icon-edit tb-icon" @click="openHouseModal(scope.$index)"></i>
+              </el-tooltip>
+              <el-tooltip effect="dark" content="删除" placement="top">
+                <i
+                  class="el-icon-delete tb-icon"
+                  @click="deleteRow(scope.$index, ruleForm.order_addr)"
+                ></i>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form>
+      <div class="tr" style="padding: 10px 0 0 0">
+        <el-button type="primary" size="small" @click="submitForm">保 存 </el-button>
+      </div>
+    </el-card>
+  </el-dialog>
+</template>
+<script>
+import resToken from "@/mixins/resToken";
+import { province_list, city_list, county_list } from "@/assets/js/area-data";
+import {
+  isnumber,
+  isMobile,
+  isChinese,
+  isEmoticon,
+  isSpecialSymbol,
+  hasSpace,
+  isAddr,
+} from "@/utils/validate";
+export default {
+  name: "inAddrModel",
+  props: ["showModel", "id", "sitem"],
+  mixins: [resToken],
+  data() {
+    const validatemobile = (rule, value, callback) => {
+      if (value === "") {
+        callback(new Error("联系电话不能为空!"));
+      } else {
+        if (!isMobile(value)) {
+          callback(new Error("联系电话格式不正确!"));
+        } else {
+          callback();
+        }
+      }
+    };
+    const validateWeight = (rule, value, callback) => {
+      if (value === "") {
+        callback(new Error("收货总数不能为空!"));
+      } else {
+        if (!isnumber(value)) {
+          callback(new Error("收货总数仅支持整数!"));
+        } else {
+          callback();
+        }
+      }
+    };
+    const validatecontactor = (rule, value, callback) => {
+      if (value === "") {
+        callback(new Error("联系人不能为空!"));
+      } else {
+        if (value.length < 2 || value.length > 10) {
+          callback(new Error("联系人规则为2~10位汉字!"));
+        } else {
+          if (!isChinese(value)) {
+            callback(new Error("联系人规则为2~10位汉字!"));
+          } else if (isEmoticon(value)) {
+            callback(new Error("联系人规则为2~10位汉字!"));
+          } else {
+            callback();
+          }
+        }
+      }
+    };
+    const validateAddr = (rule, value, callback) => {
+      if (value === "") {
+        callback(new Error("详细地址不能为空!"));
+      } else {
+        if (hasSpace(value)) {
+          callback(new Error("不能出现回车/换行符!"));
+        } else if (isSpecialSymbol(value)) {
+          callback(new Error("不能使用英文特殊字符!"));
+        } else if (isAddr(value)) {
+          callback();
+        } else {
+          callback(new Error("详细地址填写不规范!"));
+        }
+      }
+    };
+    return {
+      showAddrAddEditModal: false,
+      AddrAddEditModalIndex: -1,
+      AddrAddEditModalSitem: {},
+      tableData: [],
+      tableHeader: [],
+      title: "",
+      showModelThis: false,
+      loading: false,
+      newTime: 0,
+      pickerOptions: {
+        disabledDate: (time) => {
+          return time.getTime() < new Date().valueOf();
+        },
+      },
+      rulesThis: this.rules,
+      ruleForm: {
+        order_addr: [], //收货地址
+      },
+      rules: {
+        receipt_quantity: [
+          {
+            required: true,
+            validator: validateWeight,
+            trigger: "blur",
+          },
+        ],
+
+        contactor: [
+          {
+            required: true,
+            trigger: "blur",
+            validator: validatecontactor,
+          },
+        ],
+        mobile: [
+          {
+            required: true,
+            validator: validatemobile,
+            trigger: "blur",
+          },
+        ],
+        addr_code: [
+          {
+            type: "array",
+            required: false,
+            trigger: "change",
+          },
+        ],
+        addr: [
+          {
+            required: true,
+            validator: validateAddr,
+            trigger: "blur",
+          },
+        ],
+      },
+    };
+  },
+  watch: {
+    showModel: function (val) {
+      this.showModelThis = val;
+      if (val) {
+        this.initForm();
+      }
+    },
+    showModelThis(val) {
+      if (!val) {
+        this.$emit("cancel");
+        this.$emit('update:showModel',val)
+      }
+    },
+  },
+  mounted() {
+    this.get_code();
+  },
+  methods: {
+    async resetForm() {
+      // 重置
+      await this.$nextTick(() => {
+        if (this.$refs.ruleForm) {
+          this.$refs.ruleForm.resetFields();
+          this.$refs.ruleForm.clearValidate();
+          this.ruleForm = {
+            order_addr: [],
+          };
+        }
+      });
+    },
+    // 省市区删除行操作
+    deleteRow(index, rows) {
+      rows.splice(index, 1);
+    },
+    showAddrAddEditModalRefresh(e) {
+      const { index, item } = e;
+
+      if (index === -1) {
+        this.ruleForm.order_addr.push(JSON.parse(JSON.stringify(item)));
+      } else {
+        const {
+          receipt_quantity,
+          contactor,
+          mobile,
+          addr_code,
+          addr_code_name,
+          addr,
+          id,
+        } = JSON.parse(JSON.stringify(item));
+        this.ruleForm.order_addr[index].receipt_quantity = receipt_quantity;
+        this.ruleForm.order_addr[index].contactor = contactor;
+        this.ruleForm.order_addr[index].mobile = mobile;
+        this.ruleForm.order_addr[index].addr_code = addr_code;
+        this.ruleForm.order_addr[index].addr_code_name = addr_code_name;
+        this.ruleForm.order_addr[index].addr = addr;
+        this.ruleForm.order_addr[index].id = id;
+      }
+      this.$refs.ruleForm.validateField("order_addr");
+    },
+    beforeUpload(file) {
+      const isLt1M = file.size / 1024 < 500;
+      if (isLt1M) {
+        return true;
+      }
+      this.$message({
+        message: "请不要上传大于500KB的文件.",
+        type: "warning",
+      });
+      return false;
+    },
+    handleSuccess({ results, header }) {
+      if (results.length === 0) {
+        this.$message.error("表格无有效数据!");
+        return;
+      }
+      if (results.length > 500) {
+        this.$message.error("地址数据不能超过500条!");
+        return;
+      }
+      let head = [
+        "收货总数",
+        "收货联系人",
+        "收货联系电话",
+        "收货省名称",
+        "收货市名称",
+        "收货区名称",
+        "详细地址",
+      ];
+      if (head.length !== header.length) {
+        this.$message.error("表头与导入模板不匹配!");
+        return;
+      }
+      let hederOk = true;
+      head.forEach((v1, i1) => {
+        if (v1 !== header[i1].replace(/\s*/g, "")) {
+          hederOk = false;
+        }
+      });
+
+      if (!hederOk) {
+        this.$message.error("表头与导入模板不匹配!");
+        return;
+      }
+      this.tableHeader = header;
+      this.tableData = [];
+      let list = results;
+      let tableOk = true;
+      this.ruleForm.order_addr = [];
+      list.forEach((v1) => {
+        let b = Object.values(v1);
+        let item = this.get_code(b[3], b[4], b[5]);
+        let model = {
+          receipt_quantity: b[0] + "",
+          contactor: b[1] + "",
+          mobile: b[2] + "",
+          in_addr: b[3] + "/" + b[4] + "/" + b[5],
+          addr_code_name: item.name + "",
+          addr_code: item.code,
+          addr: b[6] + "",
+          edit: false,
+        };
+        this.ruleForm.order_addr.push(model);
+      });
+      if (!tableOk) {
+        this.$message.error("最晚收货日期不正确,请将表格格式转为文本上传!");
+      }
+    },
+    openHouseModal(index) {
+      this.AddrAddEditModalIndex = index;
+
+      if (index === -1) {
+        this.AddrAddEditModalSitem = {};
+      } else {
+        this.AddrAddEditModalSitem = JSON.parse(
+          JSON.stringify(this.ruleForm.order_addr[index])
+        );
+      }
+      this.showAddrAddEditModal = true;
+      // let findex = this.ruleForm.order_addr.findIndex((v) => v.edit === true);
+      // if (findex !== -1) {
+      //   this.$message.warning("当前已有地址在编辑,请保存后再试!");
+      //   return;
+      // } else {
+      //   this.ruleForm.order_addr[index].edit = true;
+      // }
+    },
+    unique(arr) {
+      let hash = [];
+      for (let i = 0; i < arr.length; i++) {
+        let index = hash.findIndex((v1) => v1.inv_number === arr[i].inv_number);
+        if (index === -1) {
+          hash.push(arr[i]);
+        }
+      }
+      return hash;
+    },
+    setTime(time) {
+      time = time.replace(/\//g, "-");
+      time = time.replace(/\./g, "-");
+      let key = new Date(time).valueOf() + "";
+      if (key.length !== 13) {
+        time = "";
+      }
+      return time;
+    },
+    async initForm() {
+      this.rulesThis = this.rules;
+      await this.resetForm();
+      this.newTime = 0;
+      this.loading = true;
+      this.tableData = [];
+      this.tableHeader = [];
+      this.step = 1;
+      this.title = "批量导入收货地址信息";
+
+      this.changea();
+      this.loading = false;
+    },
+    refreshAll() {
+      this.showModelThis = false;
+      this.$emit("refresh");
+    },
+    changea() {
+      this.newTime = new Date().valueOf();
+    },
+
+    async submitForm() {
+        const { order_addr } = this.ruleForm;
+        if (order_addr.length < 1) {
+          this.$message.error("导入数据不能为空!");
+          this.loading = false;
+          return;
+        }
+        let isEdit = false;
+        order_addr.forEach((v) => {
+          v.err = false;
+          if (v.edit) {
+            v.err = true;
+            isEdit = true;
+          }
+        });
+        if (isEdit) {
+          this.$message.error("当前收货地址已在编辑,请保存后再试!");
+          this.loading = false;
+          return;
+        }
+        let cItem = null;
+        order_addr.some((x, i) => {
+          cItem = this.checkItem(x);
+          if (!cItem.isok) {
+            cItem.index = i;
+            return true;
+          }
+        });
+        if (cItem && !cItem.isok) {
+          this.$message.error(`第${cItem.index + 1}行,${cItem.message}`);
+          this.loading = false;
+          return;
+        }
+        let list = JSON.parse(JSON.stringify(order_addr));
+        this.$emit("refresh", { list: list });
+    },
+    checkItem(sitem) {
+      let model = {
+        isok: true,
+        message: "",
+      };
+      const { arrive_time, receipt_quantity, contactor, mobile, addr_code, addr } = sitem;
+      if (receipt_quantity === "" && model.isok) {
+        model.isok = false;
+        model.message = "收货总数不能为空!";
+      }
+      if (!isnumber(receipt_quantity) && model.isok) {
+        model.isok = false;
+        model.message = "收货总数仅支持整数!";
+      }
+      if (arrive_time === "" && model.isok) {
+        model.isok = false;
+        model.message = "最晚收货日期不能为空!";
+      }
+
+      if (contactor === "" && model.isok) {
+        model.isok = false;
+        model.message = "收货联系人不能为空!";
+      }
+      if (mobile === "" && model.isok) {
+        model.isok = false;
+        model.message = "收货联系电话不能为空!";
+      }
+      if (!isMobile(mobile) && model.isok) {
+        model.isok = false;
+        model.message = "收货联系电话格式不正确!";
+      }
+      // if (addr_code.length !== 3 && model.isok) {
+      //   model.isok = false;
+      //   model.message = "收货省市区不能为空!";
+      // }
+      if (addr === "" && model.isok) {
+        model.isok = false;
+        model.message = "详细地址不能为空!";
+      }
+      return model;
+    },
+    get_code(name1, name2, name3) {
+      let name = "",
+        code = [];
+      if (name1 && name2 && name3) {
+        for (let x in province_list) {
+          if (name1 === province_list[x]) {
+            code.push(x);
+            name += province_list[x];
+            break;
+          }
+        }
+        if (code.length === 1) {
+          for (let y in city_list) {
+            if (name2 === city_list[y]) {
+              code.push(y);
+              name += "/" + city_list[y];
+              break;
+            }
+          }
+        }
+        if (code.length === 2) {
+          for (let z in county_list) {
+            if (name3 === county_list[z]) {
+              code.push(z);
+              name += "/" + county_list[z];
+              break;
+            }
+          }
+        }
+
+        if (code.length === 3) {
+          let str1 = "",
+            str2 = "",
+            isok = false;
+          str1 = code[0].slice(0, 2);
+          str2 = code[1].slice(2, 4);
+          if (
+            code[1].indexOf(str1) === 0 &&
+            code[2].indexOf(str1) === 0 &&
+            code[2].indexOf(str2) == 2
+          ) {
+            isok = true;
+          }
+          if (!isok) {
+            name = "";
+            code = [];
+          }
+        } else {
+          name = "";
+          code = [];
+        }
+      }
+      return { name: name, code: code };
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.account {
+  .gongshi {
+    span {
+      vertical-align: top;
+      display: inline-block;
+      color: #000;
+    }
+    .icon-span {
+      padding: 0 5px;
+      height: 40px;
+      line-height: 40px;
+      font-size: 20px;
+      color: #606266;
+      display: inline-block;
+      // vertical-align: top;
+      // display: inline-block;
+    }
+    .label {
+      height: 40px;
+      line-height: 40px;
+    }
+    .tuan {
+      &.chu {
+        width: 60px;
+        height: 40px;
+        display: inline-block;
+        span {
+          width: 60px;
+          display: inline-block;
+          line-height: 20px;
+          text-align: center;
+          font-size: 12px;
+          height: 20px;
+          &:last-child {
+            border-top: 1px solid #606266;
+          }
+        }
+      }
+      &.cheng {
+        .name {
+          height: 40px;
+          line-height: 40px;
+        }
+        .icon-span {
+          line-height: 40px;
+          font-size: 16px;
+          padding: 0 1px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 19 - 0
src/config/env.jiesuan.js

@@ -0,0 +1,19 @@
+// 本地
+module.exports = {
+  title: "采销平台供应商端",
+  baseUrl: "http://localhost:8080",
+  api: {
+    userApi: "http://inv.sitw.wanyuhengtong.com/",
+    baseApi: "http://stock.api.caixiao365.com/",
+  },
+  webUrl: "http://share.sitw.wanyuhengtong.com/#/test-good-share?id=",
+  fileURL: `https://api2.edusit.zretchome.com`,
+  shareWebUrl: "http://ss.test241.wanyuhengtong.com/?prod=0&outCode=",
+  appId: "wx5ac3a2c2d72b6f26",
+  ding: {
+    //企业id
+    CorpId: "dingc78fa4301e1a424a35c2f4657eb6378f",
+    //应用凭证
+    AgentId: "1324690581",
+  },
+};

+ 29 - 0
src/router/data.js

@@ -149,5 +149,34 @@ const config = [
       },
     ],
   },
+  {
+    is_display: "1",
+    menu_img: "el-icon-s-order",
+    menu_name: "报备单管理",
+    menu_route: "report",
+    status: "1",
+    child: [
+      {
+        is_display: "1",
+        is_private: "0",
+        menu_img: "el-icon-s-order",
+        menu_name: "报备单管理",
+        menu_route: "index",
+        menu_url: "report/index",
+        status: "1",
+        alwaysShow: false,
+      },
+      {
+        is_display: "0",
+        is_private: "0",
+        menu_img: "el-icon-s-order",
+        menu_name: "报备单详情",
+        menu_route: "detail",
+        menu_url: "report/detail",
+        status: "1",
+        alwaysShow: false,
+      },
+    ],
+  },
 ];
 export default config;

+ 1 - 1
src/styles/index.scss

@@ -856,4 +856,4 @@ aside {
   // // font-weight: 400;
   // padding: 7px 15px;
   // border-radius: 4px;
-}
+}

+ 173 - 0
src/views/report/config/columns.js

@@ -0,0 +1,173 @@
+const columns = [
+  {
+    type: "selection",
+    fixed: "left",
+    _noset_: true
+  },
+  {
+    prop: "cgdNo",
+    label: "报备单编号",
+    width: "155px",
+  },
+  {
+    prop: "spuCode",
+    label: "商品分类",
+    width: "158px",
+  },
+  {
+    prop: "good_name",
+    label: "商品名称",
+    _slot_: "good_name",
+    'min-width': "145px",
+  },
+  {
+    prop: "good_price",
+    label: "销售数量",
+    width: "110px",
+  },
+  {
+    prop: "good_num",
+    label: "商品主图",
+    width: "110px",
+  },
+  {
+    prop: "total_fee",
+    label: "采购价",
+    width: "110px",
+  },
+  {
+    prop: "status",
+    label: "销售价",
+    width: "120px",
+  },
+  {
+    prop: "order_id",
+    label: "总服务费",
+    width: "110px"
+  },
+  {
+    prop: "lasttime",
+    label: "企业客户名称",
+    width: "145px",
+  },
+  {
+    prop: "addtime",
+    label: "企业客户编号",
+    width: "145px",
+  },
+  {
+    prop: "addtime",
+    label: "状态",
+    width: "145px",
+  },
+  {
+    prop: "",
+    label: "操作",
+    fixed: "right",
+    _noset_: true,
+    width: "50px",
+    _slot_: "operation",
+  },
+]
+const statusOptions = [
+  { value: "0", label: "待确认" },
+  { value: "1", label: "待入库" },
+  { value: "2", label: "部分入库" },
+  { value: "3", label: "入库完成" },
+  { value: "4", label: "已取消订单" },
+];
+const showColumns= [
+  {
+    prop: "cgdNo",
+    label: "销售订单编号",
+    span: 6
+  },
+  {
+    prop: "status",
+    label: "销售订单状态",
+    _slot_: "status",
+    span: 6
+  },
+  {
+    prop: "order_type",
+    label: "销售订单来源",
+    _slot_: "order_type",
+    span: 6
+  },
+  {
+    prop: "lasttime",
+    label: "要求入库时间",
+    span: 6
+  },
+ 
+  {
+    prop: "supplier_name",
+    label: "销售方公司",
+    _slot_: "supplier_name",
+  },
+  {
+    prop: "company",
+    label: "购买方公司",
+    _slot_: "company",
+  },
+
+  // {
+  //   prop: "wsm",
+  //   label: "仓库信息",
+  //   _slot_: "wsm",
+  // },
+ 
+ 
+ 
+  {
+    prop: "total_fee",
+    label: "采购总成本",
+    span: 8
+  },
+  {
+    prop: "good_price",
+    label: "销售订单价",
+    span: 8
+  },
+  {
+    prop: "good_num",
+    label: "采购总数量",
+    span: 8
+  },
+  {
+    prop: "send_num",
+    label: "已发货数量",
+    span: 8
+  },
+  {
+    prop: "wsend_num",
+    label: "未发货数量",
+    span: 8
+  },
+  {
+    prop: "addtime",
+    label: "创建时间",
+    span: 8
+  },
+  // {
+  //   prop: "gold_price",
+  //   label: "当前实时金价",
+  //   _slot_: "gold_price",
+  //   span: 12
+  // },
+  // {
+  //   prop: "customer",
+  //   label: "订单客户名称",
+  //   _slot_: "customer",
+  //   span: 12
+  // },
+  {
+    prop: "addr_info",
+    label: "收货信息",
+    _slot_: "addr_info",
+    span: 24
+  },
+]
+
+
+export { columns, statusOptions,showColumns }

+ 94 - 0
src/views/report/config/rules.js

@@ -0,0 +1,94 @@
+import { hasSpace, isAddr, isChinese, isEmoticon, isMobile, isnumber, isSpecialSymbol } from "@/utils/validate";
+
+export const addressRules = {
+  receipt_quantity: [
+    {
+      required: true,
+      trigger: "blur",
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("不能为空!"));
+        } else {
+          if (!isnumber(value)) {
+            callback(new Error("仅支持整数!"));
+          } else {
+            callback();
+          }
+        }
+      },
+    },
+  ],
+
+  contactor: [
+    {
+      required: true,
+      trigger: "blur",
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("联系人不能为空!"));
+        } else {
+          if (value.length < 2 || value.length > 10) {
+            callback(new Error("联系人规则为2~10位汉字!"));
+          } else {
+            if (!isChinese(value)) {
+              callback(new Error("联系人规则为2~10位汉字!"));
+            } else if (isEmoticon(value)) {
+              callback(new Error("联系人规则为2~10位汉字!"));
+            } else {
+              callback();
+            }
+          }
+        }
+      }
+    },
+  ],
+
+  mobile: [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("手机号不能为空!"));
+        } else {
+          if (!isMobile(value)) {
+            callback(new Error("手机号格式不正确!"));
+          } else {
+            callback();
+          }
+        }
+      },
+      trigger: "blur",
+    },
+  ],
+
+  addr_code: [
+    {
+      type: "array",
+      required: false,
+      message: "收货省市区不能为空",
+      trigger: "change",
+    },
+  ],
+  
+  addr: [
+    {
+      required: true,
+      trigger: "blur",
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("详细地址不能为空!"));
+        } else {
+          if (hasSpace(value)) {
+            callback(new Error("不能出现回车/换行符!"));
+          } else if (isSpecialSymbol(value)) {
+            callback(new Error("不能使用英文特殊字符!"));
+          } else if (isAddr(value)) {
+            callback();
+          } else {
+            callback(new Error("详细地址填写不规范!"));
+          }
+        }
+      }
+    },
+  ],
+};

+ 467 - 0
src/views/report/cpns/report-form.vue

@@ -0,0 +1,467 @@
+<template>
+  <el-form label-position="left" label-width="100px" size="mini" ref="formRef" :model="formData">
+    <el-row :gutter="10">
+      <el-col :span="12">
+        <el-form-item label="供应商名称">
+          <el-select disabled style="width:100%" :value="business_companyNo">
+            <el-option v-for="(item, index) in companyList" :key="item.supplierNo + item.id + index"
+              :label="item.supplierName" :disabled="item.status !== '1'" :value="item.supplierNo">
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-form-item label="客户名称" prop="companyName">
+          <el-input placeholder="客户名称" v-model="formData.companyName" />
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+    <el-row :gutter="10">
+      <el-col :span="12">
+        <el-form-item label="业务员公司" prop="">
+          <search-work-company :placeholder="'业务公司'" :size="'mini'"  @searchChange="company_idsearchChange" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-form-item label="销售数量" prop="num">
+          <el-input placeholder="销售数量" v-model="formData.num" />
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+    <el-row :gutter="10">
+      <el-col :span="6">
+        <el-form-item label="是否确定售价" prop="is_determine_price">
+          <el-select placeholder="是否确定售价" v-model="formData.is_determine_price">
+            <el-option value="0" label="否" />
+            <el-option value="1" label="是" />
+          </el-select>
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="服务费比例" prop="service_proportion">
+          <el-input placeholder="服务费比例" v-model="formData.service_proportion" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="期望服务费" prop="expect_service">
+          <el-input placeholder="期望服务费" v-model="formData.expect_service" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="服务费比例">
+          <el-input placeholder="服务费比例" />
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+
+    <el-row :gutter="10">
+      <el-col :span="5">
+        <el-form-item label="有效期" prop="preservation_day">
+          <digital-input :placeholder="'有效期'" :min="0" :max="100000000000" :position="'right'" :precision="0"
+            :size="'mini'" :controls="false" :append="'天'" @reschange="number_change($event, 'preservation_day')" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="5">
+        <el-form-item label="物流时间" prop="delivery_day">
+          <digital-input :placeholder="'物流时间'" :min="0" :max="100000000000" :position="'right'" :precision="0"
+            :size="'mini'" :controls="false" :append="'天'" @reschange="number_change($event, 'delivery_day')" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="5">
+        <el-form-item label="生产工期" prop="make_day">
+          <digital-input :placeholder="'生产工期'" :min="0" :max="100000000000" :position="'right'" :precision="0"
+            :size="'mini'" :controls="false" :append="'天'" @reschange="number_change($event, 'make_day')" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="4">
+        <el-form-item label="税点" label-width="60px" prop="tax">
+          <digital-input :placeholder="'税点'" :min="0" :max="100000000000" :position="'right'" :precision="0"
+            :size="'mini'" :controls="false" :append="'%'" @reschange="number_change($event, 'tax')" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="5">
+        <el-form-item label="单位" label-width="60px" prop="unit_id">
+          <search-unit :value="formData.unit_id" :size="'mini'" placeholder="单位" @searchChange="unitsearchChange" />
+        </el-form-item>
+
+      </el-col>
+    </el-row>
+
+    <el-row :gutter="10">
+      <el-col :span="12">
+        <el-form-item label="品牌" prop="brand_id">
+          <search-brand size="mini" :value="brandid" placeholder="请选择品牌" @searchChange="brandidsearchChange" />
+        </el-form-item>
+
+        <el-form-item label="分类" prop="cat_id">
+          <search-sort :placeholder="'分类'" size="mini" @searchChange="cat_id_change" />
+        </el-form-item>
+
+        <el-form-item label="商品名称" prop="good_name">
+          <el-input placeholder="商品名称" v-model="formData.good_name" />
+        </el-form-item>
+
+        <el-form-item label="产地" prop="origin_place">
+          <select-area :placeholder="'产地'" size="mini" @selectChange="selectAreaorigin_place($event, 'origin_place')" />
+        </el-form-item>
+
+        <el-form-item label="发货地" prop="delivery_place">
+          <select-area :placeholder="'发货地'" size="mini"
+            @selectChange="selectAreaorigin_place($event, 'delivery_place')" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-table :data="speclist" :size="'mini'" border style="width: 100%" height="164px">
+          <el-table-column prop="spec_value" label="规格类型" />
+          <el-table-column prop="spec_value_value" label="规格值" />
+          <el-table-column fixed="right">
+            <template slot="header" slot-scope="scope">
+              <span>操作</span>
+              <el-tooltip class="item" effect="dark" content="添加规格类型" placement="top">
+                <i class="el-icon-circle-plus-outline fr" style="font-size: 18px; margin-top: 2px"
+                  @click="() => handleSpecModal(-1)" />
+              </el-tooltip>
+            </template>
+            <template slot-scope="scope">
+              <el-tooltip effect="dark" content="修改" placement="top">
+                <i class="el-icon-edit tb-icon" @click="() => handleSpecModal(scope.$index)"></i>
+              </el-tooltip>
+
+              <el-tooltip effect="dark" content="删除" placement="top">
+                <i class="el-icon-delete tb-icon"></i>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <SpecModal :index="modalIndex" :showModel.sync="showModal" :sitem="spec" @refresh="handleEditSpec" />
+      </el-col>
+    </el-row>
+
+    <el-row :gutter="10">
+      <el-col :span="6">
+        <el-form-item label="总重量" prop="weight">
+          <digital-input :placeholder="'总重量'" :min="0" :max="100000000000" :position="'right'" :precision="0"
+            :size="'mini'" :controls="false" :append="'g'" @reschange="number_change($event, 'weight')" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="供应区域" prop="supply_area">
+          <el-select v-model="formData.supply_area" placeholder="供应区域">
+            <el-option label="全国" value="1" />
+            <el-option label="全国除偏移" value="2" />
+          </el-select>
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="付款方式" prop="pay_way">
+          <el-select v-model="formData.pay_way" placeholder="付款方式" style="wdith:100%" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="裸价" label-width="60px" prop="cgd_charge">
+          <digital-input :placeholder="'裸价'" :min="0" :max="100000000000" :position="'right'" :precision="3"
+            :size="'mini'" :controls="false" :append="'元'" @reschange="number_change($event, 'cgd_charge')" />
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+    <el-row :gutter="10">
+      <el-col :span="6">
+        <el-form-item label="贵金属重量" prop="gold_weight">
+          <digital-input :placeholder="'金属重量'" :min="0" :max="100000000000" :position="'right'" :precision="3"
+            :size="'mini'" :controls="false" :append="'g'" @reschange="number_change($event, 'gold_weight')" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="贵金属种类" prop="noble_metal">
+          <search-metal-kind :value="formData.noble_metal" :size="'mini'" :placeholder="'贵金属种类'"
+            @searchChange="noble_metalsearchChange" />
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+    <el-row :gutter="10">
+      <el-col :span="12">
+        <el-form-item label="配置要求" prop="config">
+          <el-select placeholder="配置要求" v-model="formData.config">
+            <el-option v-for="(item, index) in configOptions" :key="index" :label="item" :value="item" />
+          </el-select>
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-form-item label="其他配置要求" prop="otherConfig">
+          <el-input v-model="formData.otherConfig" placeholder="其他配置要求" />
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+    <el-row>
+      <el-form-item label="备注" prop="remark">
+        <el-input type="textarea" placeholder="备注" v-model="formData.remark" />
+      </el-form-item>
+    </el-row>
+
+    <el-row>
+      <el-form-item label="工艺说明">
+        <el-input placeholder="工艺说明" />
+      </el-form-item>
+    </el-row>
+    <!-- v-if="formData.good_img" -->
+    <el-row>
+      <el-form-item label="商品图片(<1mb)" prop="good_img" class="activity-upload">
+        <div class="btnupload" style="position: relative; margin-left: 10px" v-if="formData.good_img">
+          <img :src="formData.good_img" class="avatar" />
+        </div>
+        <div>
+          <i class="el-icon-plus avatar-uploader-icon" style="position: relative; width: 50px; height: 50px">
+            <file-upload class="Upload" :accept="'.jpg,.png,.jpeg'" :multiple="true" :disabled="type === 'view'"
+              :uploadcondition="beforeAvatarUpload" @UploadErrorEvent="UploadErrorEventgood_img"
+              @UploadSuccessEvent="UploadSuccessEventgood_img"></file-upload>
+          </i>
+        </div>
+      </el-form-item>
+    </el-row>
+
+    <el-row>
+      <div style="display:flex;justify-content:flex-end;width:100%;margin-bottom: 10px;">
+        <el-button type="primary" size="small" @click="handleConfirm">保存</el-button>
+      </div>
+    </el-row>
+  </el-form>
+</template>
+
+
+<script>
+import { mapGetters } from "vuex";
+import { get_company_list } from "@/utils/auth";
+import SpecModal from './spec-modal.vue';
+import asyncRequest from "@/apis/report";
+
+export default {
+  data() {
+    return {
+      spec: {},
+      speclist: [],
+      companyList: [],
+      showModal: false,
+      modalIndex: '',
+      configOptions: ["证书", "包装盒", "绒布袋", "标签", "其他"],
+      formRef: null,
+      formData: {
+        num: 0,
+        companyName: "",
+        is_determine_price: "",
+        is_determine_price: "0",
+        service_proportion: "",
+        expect_service: "",
+        brand_id: "",
+        preservation_day: "",
+        delivery_day: "",
+        make_day: "",
+        tax: "",
+        unit_id: "",
+        cat_id: "",
+        good_name: "",
+        origin_place: [],
+        delivery_place: [],
+        weight: "",
+        supply_area: "",
+        pay_way: "",
+        cgd_charge: "",
+        gold_weight: "",
+        noble_metal: "",
+        config: "",
+        otherConfig: "",
+        good_img: ""
+      }
+    }
+  },
+  components: {
+    SpecModal
+  },
+  computed: {
+    ...mapGetters(['business_companyNo'])
+  },
+  mounted() {
+    this.companyList = get_company_list() ? JSON.parse(get_company_list()) : [];
+  },
+  methods: {
+    handleSpecModal(index) {
+      this.showModal = true;
+      this.modalIndex = index;
+      this.spec = index >= 0 ? this.speclist[index] : {};
+    },
+    handleEditSpec(spec) {
+      const shallowSpacData = { ...spec };
+      if (this.modalIndex === -1) {
+        this.speclist.push(shallowSpacData);
+        return
+      }
+      this.$set(this.speclist, this.modalIndex, shallowSpacData);
+    },
+    async brandidsearchChange(e) {
+      const { id } = e ?? {};
+      this.formData.brand_id = id;
+    },
+    async number_change(e, key) {
+      this.formData[key] = e + "" || "0"
+    },
+    unitsearchChange(e) {
+      const { code } = e;
+      this.formData.unit_id = code;
+    },
+    async cat_id_change(e) {
+      const { pid, id } = e;
+      // if (pid === "6") {
+      //   this.$message.warning("不允许反馈贵金属商品!");
+      //   this.ruleForm.cat_id = [];
+      // } else {
+      //   this.ruleForm.cat_id = id ? [id] : [];
+      // }
+      this.formData.cat_id = id;
+    },
+    selectAreaorigin_place(e, key) {
+      this.formData[key].origin_place = e;
+    },
+    //贵金属种类选择
+    async noble_metalsearchChange(e) {
+      const { id, code, label } = e;
+      this.formData.noble_metal = id || "";
+    },
+    UploadErrorEventgood_img(res) {
+      this.imgUploadError(1, res);
+    },
+    imgUploadError(type, res) {
+      if (res !== "break") {
+        this.$message.error("图片上传失败!");
+        // this.$refs.ruleForm.validateField(
+        //   type === 1 ? "good_img" : type === 2 ? "good_img" : ""
+        // );
+      }
+    },
+    //判断图片规格
+    beforeAvatarUpload(file) {
+      let isJPG = false;
+      if (
+        file.type === "image/jpg" ||
+        file.type === "image/png" ||
+        file.type === "image/jpeg"
+      ) {
+        isJPG = true;
+      }
+      const isLt2M = file.size / 1024 / 1024 < 1;
+      if (!isJPG) {
+        this.$message.error("图片格式不正确!");
+      }
+      if (!isLt2M) {
+        this.$message.error("图片大小不能超过 1MB!");
+      }
+      return isJPG && isLt2M;
+    },
+    closeImg(index, key) {
+      this.formData[key].splice(index, 1);
+      // this.$refs.ruleForm.validateField(key);
+    },
+    async UploadSuccessEventgood_img(data) {
+      await this.UploadSuccessEvent(1, data);
+    },
+    //图片上传成功
+    async UploadSuccessEvent(type, data) {
+      // if (this.ruleForm.good_img.length > 10) {
+      //   this.$message.warning("上传图片最多不能超过10张");
+      //   return;
+      // }
+      const { url } = data;
+      if (url === "noToken") {
+        await this.logout();
+      } else if (url === "noSupplierNo") {
+        this.$notify({
+          title: "当前供应商参数错误",
+          dangerouslyUseHTMLString: true,
+          message: "5秒后,请您重新登录!",
+        });
+        await setTimeout(async () => {
+          await this.logout();
+        }, 5000);
+      } else {
+        if (type === 1) {
+          this.formData.good_img = url
+          // this.$refs.ruleForm.validateField("good_img");
+        } else if (type === 2) {
+          this.formData.good_img = url
+          // this.$refs.ruleForm.validateField("good_img");
+        }
+        this.$message.success("图片上传成功!");
+      }
+    },
+    handleConfirm() {
+      this.$refs.formRef.validate(async isValid => {
+        if (!isValid) return;
+
+        const spec_list = this.speclist;
+        const supplierNo = this.business_companyNo;
+
+        const {
+          num,
+          companyName,
+          is_determine_price,
+          cgd_charge,
+          service_proportion,
+          expect_service,
+          brand_id,
+          preservation_day,
+          delivery_day,
+          make_day,
+          tax,
+          unit_id,
+          cat_id,
+          good_name,
+          delivery_place,
+          origin_place,
+          weight,
+          supply_area,
+          pay_way,
+          gold_weight,
+          noble_metal,
+          config,
+          other_config,
+          remark,
+          cost_desc,
+          
+        } = this.formData;
+
+        const params = {
+          customerCode,
+          companyName,
+          num
+        }
+
+        // const { data, code, message } = await asyncRequest.add(this.formData);
+
+        // if(code === 0){
+        //   this.$router.push("/report/index");
+        // }
+      })
+    }
+  }
+}
+</script>

+ 262 - 0
src/views/report/cpns/spec-modal.vue

@@ -0,0 +1,262 @@
+<template>
+  <el-dialog
+    v-loading="loading"
+    :title="title"
+    :center="true"
+    align="left"
+    top="5vh"
+    width="1040px"
+    :close-on-click-modal="false"
+    :visible.sync="showModelThis"
+    element-loading-text="拼命加载中"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0.8)"
+    @close="showModelThis = false"
+  >
+    <el-card style="margin: -20px 0 0 0">
+      <el-row :gutter="10">
+        <el-col :span="24">
+          <el-form
+            ref="ruleForm"
+            :model="ruleForm"
+            status-icon
+            :size="'small'"
+            :rules="rulesThis"
+            label-width="30px"
+            class="demo-ruleForm"
+          >
+            <el-form-item label="规格值" prop="spec_value_id">
+              <div
+                v-if="specVlist.length > 0"
+                style="max-height: 600px; overflow-y: scroll"
+              >
+                <el-radio-group
+                  v-model="ruleForm.spec_value_id"
+                  @change="spec_value_id_change"
+                >
+                  <el-radio
+                    v-for="item in specVlist"
+                    :key="item.id + item.spec_value"
+                    :label="item.id"
+                    >{{ item.spec_value }}</el-radio
+                  >
+                </el-radio-group>
+              </div>
+              <div class="no-data tc" style="" v-else>暂无规格值,请添加!</div>
+            </el-form-item>
+            <el-row>
+              <el-col :span="6">
+                <el-form-item label="类型" prop="spec_id" label-width="58px">
+                  <search-spec
+                    :value="ruleForm.spec_id"
+                    :disabled="sitem.isMust"
+                    :size="'small'"
+                    :isDetail="false"
+                    :placeholder="'规格类型'"
+                    @searchChange="spec_idsearchChange"
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="18" style="text-align: right; padding: 0px 0 0 10px">
+                <el-input
+                  style="width: 209px"
+                  v-model="sinput"
+                  class="fl"
+                  :disabled="id == 'edit'"
+                  :size="'small'"
+                  placeholder="规格值名称,如红色"
+                  maxlength="100"
+                />
+                <el-button
+                  style="margin: 0 0 0 10px"
+                  icon="el-icon-plus"
+                  :size="'small'"
+                  @click="add_spec"
+                  class="fl"
+                  >新增规格值</el-button
+                >
+                <el-button
+                  v-if="id !== 'edit'"
+                  :size="'small'"
+                  type="primary"
+                  @click="submitForm"
+                  >保 存
+                </el-button>
+                <el-button @click="showModelThis = false" :size="'small'">{{
+                  id == "edit" ? "关 闭" : "取 消"
+                }}</el-button>
+              </el-col>
+            </el-row>
+          </el-form>
+        </el-col>
+      </el-row>
+    </el-card>
+  </el-dialog>
+</template>
+<script>
+import asyncRequest from "@/apis/goodsCost";
+import resToken from "@/mixins/resToken";
+export default {
+  name: "brand",
+  props: ["showModel", "index", "sitem"],
+  mixins: [resToken],
+  data() {
+    return {
+      loading: false,
+      title: "商品规格",
+      sinput: "",
+      showModelThis: this.showModel,
+      specVlist: [],
+      ruleForm: {},
+      rulesThis: this.rules,
+
+      rules: {
+        spec_id: [
+          {
+            required: true,
+            message: "规格类型不能为空",
+            trigger: "change",
+          },
+        ],
+        spec_value_id: [{ required: true, message: "请选择规格值", trigger: "change" }],
+      },
+    };
+  },
+  watch: {
+    showModel: function (val) {
+      this.showModelThis = val;
+      if (val) {
+        this.initForm();
+      }
+    },
+    showModelThis(val) {
+      if (!val) {
+        this.$emit("cancel");
+        this.$emit("update:showModel",val);
+      }
+    },
+  },
+  methods: {
+    async initForm() {
+      this.loading = true;
+      this.sinput = "";
+      this.resetFormData();
+      this.rulesThis = this.rules;
+      if (this.index + "" === "-1") {
+        this.title = "添加商品规格值";
+      } else {
+        this.title = "修改商品规格值";
+      }
+      await this.resetForm();
+      this.loading = false;
+    },
+    async resetForm() {
+      // 重置
+      await this.$nextTick(() => {
+        if (this.$refs.ruleForm) {
+          this.$refs.ruleForm.resetFields();
+          this.$refs.ruleForm.clearValidate();
+          this.resetFormData();
+        }
+      });
+    },
+    async resetFormData() {
+      const {
+        id,
+        spec_id,
+        spec_value,
+        spec_value_id,
+        spec_value_value,
+        isMust,
+      } = this.sitem;
+      this.ruleForm = {
+        index: this.index,
+        id: id || "",
+        spec_id: spec_id || "",
+        spec_value: spec_value || "",
+        isMust: isMust || false,
+        spec_value_id: spec_value_id || "",
+        spec_value_value: spec_value_value || "",
+      };
+      if (spec_id) {
+        await this.getlist();
+      }
+    },
+    async add_spec() {
+      const { spec_id } = this.ruleForm;
+      if (spec_id) {
+        if (this.sinput) {
+          const res = await asyncRequest.valueadd({
+            spec_id: spec_id,
+            spec_value: this.sinput,
+          });
+          const { code, data } = await this.useResHandle(res);
+          if (code === 0) {
+            await this.getlist();
+          }
+        } else {
+          this.$message.warning("请输入规格值!");
+        }
+      } else {
+        this.$message.warning("请选择规格类型!");
+      }
+    },
+    async spec_idsearchChange(e) {
+      const { id, spec_name } = e;
+      this.ruleForm.spec_id = id || "";
+      this.ruleForm.spec_value = spec_name || "";
+      this.$refs.ruleForm.validateField("spec_id");
+      await this.getlist();
+    },
+    spec_value_id_change(e) {
+      if (e) {
+        const { id, spec_value } = this.specVlist.find((i) => i.id === e);
+        this.ruleForm.spec_value_id = id || "";
+        this.ruleForm.spec_value_value = spec_value || "";
+      } else {
+        this.ruleForm.spec_value_id = "";
+        this.ruleForm.spec_value_value = "";
+      }
+      this.$refs.ruleForm.validateField("spec_value_id");
+    },
+    async getlist() {
+      const { spec_id } = this.ruleForm;
+      if (spec_id) {
+        const res = await asyncRequest.valueall({
+          spec_id: spec_id,
+        });
+        const { code, data } = await this.useResHandle(res);
+        if (code === 0) {
+          this.specVlist = data;
+        }
+      } else {
+        this.specVlist = [];
+      }
+    },
+
+    async submitForm() {
+      await this.$refs.ruleForm.validate(async (valid) => {
+        if (valid) {
+          this.showModelThis = false;
+          this.$emit("refresh", this.ruleForm);
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.goodsCostAdd {
+  .no-data {
+    text-align: center;
+    line-height: 32px;
+    color: #8492a6;
+    // border: 1px solid #ccc;
+    border-radius: 6px;
+  }
+}
+</style>

+ 156 - 0
src/views/report/cpns/wait-transferred.vue

@@ -0,0 +1,156 @@
+<template>
+  <div>
+    <el-form ref="formRef" :model="editCacheData" :rules="rules">
+      <el-table border size="mini" :data="list" max-height="300px">
+        <el-table-column label="收货总数" prop="receipt_quantity">
+          <template slot-scope="scope">
+            <el-form-item v-if="scope.$index === editIndex" prop="receipt_quantity">
+              <el-input size="mini" placeholder="收货总数" v-model="editCacheData.receipt_quantity" />
+            </el-form-item>
+            <span v-else>{{ scope.row.receipt_quantity }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="收货联系人">
+          <template slot-scope="scope">
+            <el-form-item v-if="scope.$index === editIndex" prop="contactor">
+              <el-input size="mini" placeholder="收货联系人" v-model="editCacheData.contactor" />
+            </el-form-item>
+            <span v-else>{{ scope.row.contactor }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="收货联系电话" prop="mobile">
+          <template slot-scope="scope">
+            <el-form-item v-if="scope.$index === editIndex" prop="mobile">
+              <el-input size="mini" placeholder="收货联系电话" v-model="editCacheData.mobile" />
+            </el-form-item>
+            <span v-else>{{ scope.row.mobile }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="收货省市区" prop="in_addr">
+          <template slot-scope="scope">
+            <el-form-item v-if="scope.$index === editIndex" prop="in_addr">
+              <select-area :value="editCacheData.in_addr" :placeholder="'收货省市区'" size="mini" @selectChange="handleInAddrChange($event)" />
+            </el-form-item>
+            <span v-else>{{ scope.row.in_addr }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="详细地址" prop="addr">
+          <template slot-scope="scope">
+            <el-form-item v-if="scope.$index === editIndex" prop="addr">
+              <el-input size="mini" placeholder="详细地址" v-model="editCacheData.addr" />
+            </el-form-item>
+            <span v-else>{{ scope.row.addr }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column width="90px">
+          <template #header>
+            <el-tooltip placement="top" content="下载收货模板">
+              <el-button type="text" icon="el-icon-download" />
+            </el-tooltip>
+
+            <el-tooltip placement="top" content="导入收货地址">
+              <el-button type="text" icon="el-icon-upload2" @click="handleShowModal" />
+            </el-tooltip>
+
+            <el-tooltip placement="top" content="手动添加地址">
+              <el-button type="text" icon="el-icon-circle-plus-outline" @click="handlePushAddress" />
+            </el-tooltip>
+          </template>
+
+          <template slot-scope="scope">
+            <el-button v-if="Number(editIndex) === Number(scope.$index)" type="text" icon="el-icon-circle-check"
+              @click="handleSave()" />
+            <el-button v-else type="text" icon="el-icon-edit" @click="handleSetEdit(scope.$index)" />
+            <el-button type="text" icon="el-icon-delete" @click="handleDelete(scope.$index)" />
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-form>
+
+
+    <in-address-modal :show-model.sync="showModal" :loading="false" @refresh="handleRefresh" />
+  </div>
+</template>
+
+
+<script>
+import InAddressModal from "@/components/in-address-modal"
+import { addressRules } from "./../config/rules"
+
+const defaultAddressData = {
+  receipt_quantity: '',
+  contactor: '',
+  in_addr: '',
+  mobile: '',
+  addr: ''
+}
+
+export default {
+  data() {
+    return {
+      list: [],
+      editIndex: -1,
+      loading: false,
+      showModal: false,
+      rules: addressRules,
+      editCacheData: { ...defaultAddressData }
+    }
+  },
+  components: {
+    InAddressModal
+  },
+  methods: {
+    handleShowModal() {
+      this.showModal = true;
+    },
+    
+    handleSetEdit(index) {
+      if (this.editIndex >= 0) {
+        this.$message.warning('当前已有地址在编辑,请保存后再试!');
+        return;
+      }
+      this.editIndex = index;
+     
+      const { contactor, receipt_quantity, mobile, in_addr, addr } = this.list[index];
+
+      this.editCacheData = {
+        contactor, receipt_quantity, mobile, in_addr, addr
+      }
+    },
+
+    handleDelete(index) {
+      this.list.splice(index, 1)
+      if (this.editIndex >= 0) this.editIndex = -1;
+    },
+
+    handleSave() {
+      this.$refs.formRef.validate(isValid => {
+        if (!isValid) return;
+        this.$set(this.list, this.editIndex, this.editCacheData)
+        this.editCacheData = { ...defaultAddressData }
+        this.editIndex = -1;
+      })
+    },
+
+    handleRefresh(data) {
+      this.list = [...this.list, ...data.list]
+      this.showModal = false;
+    },
+
+    handlePushAddress() {
+      if (this.editIndex >= 0) {
+        this.$message.warning('当前已有地址在编辑,请保存后再试!');
+        return;
+      }
+
+      this.list.push({ ...defaultAddressData })
+      this.editIndex = this.list.length - 1;
+    },
+
+    handleInAddrChange(e){
+      this.editCacheData['in_addr'] = e;
+    }
+  }
+}
+</script>

+ 52 - 0
src/views/report/detail.vue

@@ -0,0 +1,52 @@
+<template>
+  <div class="report-detail__container">
+    <el-tabs v-model="activeTabs">
+      <el-tab-pane name="1" :label="title">
+        <el-collapse v-model="collapses">
+          <el-collapse-item name="1" :title="title">
+            <report-form />
+          </el-collapse-item>
+
+          <tempalte v-if="preview">
+            <el-collapse-item name="2" title="待转单">
+              <wait-transferred />
+            </el-collapse-item>
+          </tempalte>
+        </el-collapse>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import ReportForm from './cpns/report-form.vue'
+import WaitTransferred from './cpns/wait-transferred.vue'
+
+export default {
+  data() {
+    return {
+      activeTabs: '1',
+      collapses:['1','2']
+    }
+  },
+  components: {
+    ReportForm,
+    WaitTransferred
+  },
+  computed: {
+    title() {
+      return this.isPreview ? '报备单详情' : '新建报备单'
+    },
+    preview() {
+      return !!this.$route.query.id && this.$route.query.id !== 'add'
+    }
+  }
+}
+</script>
+
+
+<style lang="scss" scoped>
+.report-detail__container {
+  padding: 15px;
+}
+</style>

+ 341 - 0
src/views/report/index.vue

@@ -0,0 +1,341 @@
+<template>
+  <div class="purchaseOrder pagePadding">
+    <ex-table
+      v-loading="loading"
+      :table="table"
+      :data="tableData"
+      :columns="columns"
+      :page="pageInfo"
+      :size="size"
+      @page-curr-change="handlePageChange"
+      @page-size-change="handleSizeChange"
+      @screen-reset="
+        pageInfo.curr = 1;
+        parmValue.page = 1;
+        searchList();
+      "
+      @screen-submit="
+        pageInfo.curr = 1;
+        parmValue.page = 1;
+        searchList();
+      "
+      @selection="selection_change"
+    >
+      <template #table-header="{}">
+        <div style="width: 100%">
+          <el-row style="padding: 0 0 0 80px" :gutter="10">
+            <el-col :span="4" style="width: 303px; padding: 0 0 0 10px">
+              <period-date-picker
+                :type="1"
+                :width="'135px'"
+                :size="searchSize"
+                :start="timeOBJ.start"
+                :end="timeOBJ.end"
+                @timeReturned="handleTime"
+              />
+            </el-col>
+
+            <el-col :span="4">
+              <el-input size="mini" placeholder="咨询单号" />
+            </el-col>
+
+            <el-col :span="4">
+              <el-input size="mini" placeholder="商品名称" />
+            </el-col>
+
+            <el-col :span="4">
+              <el-input size="mini" placeholder="商品编码" />
+            </el-col>
+            
+            <el-col :span="3" style="width: 66px; float: right">
+              <el-button
+                :size="searchSize"
+                type="primary"
+                style="float: right; margin-left: 5px"
+                @click="searchList"
+              >
+                刷新
+              </el-button>
+            </el-col>
+            <el-col :span="4" style="width: 66px; float: right">
+              <el-button type="warning" class="fr" :size="searchSize" @click="restSearch">
+                重置
+              </el-button>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="3" class="fr" style="width: 66px; margin-top: 10px">
+              <el-button
+                :size="searchSize"
+                type="success"
+                style="float: right"
+                @click="routeGoto('/report/detail', { id: 'add', type: 'add' })"
+              >
+                添加
+              </el-button>
+            </el-col>
+
+            <el-col :span="4" style="margin-top:15px;margin-right:10px">
+              <el-input size="mini" placeholder="企业客户名称" />
+            </el-col>
+
+            <el-col :span="4" style="margin-top:15px;margin-right:10px">
+              <el-input size="mini" placeholder="企业客户编码" />
+            </el-col>
+
+            
+            <el-col :span="4" style="margin-top:15px;margin-right:10px">
+              <el-select size="mini" placeholder="请选择状态" />
+            </el-col>
+          </el-row>
+        </div>
+      </template>
+      <template #good_name="{ scope }">
+        <span>{{ scope.row.good_name }}</span>
+        <span v-for="(si, i) in scope.row.speclist" :key="si.spec_id + i">
+          {{ i === 0 ? "__" : "--" }}{{ si.spec_name }}[{{ si.spec_value }}]
+        </span>
+      </template>
+      <template #status="{ scope }">
+        <el-tag
+          :size="tablebtnSize"
+          v-text="
+            (statusOptions.find((item) => item.value == scope.row.status) || {}).label ||
+            '--'
+          "
+        ></el-tag>
+      </template>
+      <template #order_id="{ scope }">
+        <el-tag
+          :size="tablebtnSize"
+          v-text="
+            (cg_order_type_options.find((item) => item.id == scope.row.order_type) || {})
+              .label || '--'
+          "
+        ></el-tag>
+      </template>
+      <template #operation="{ scope }">
+        <el-tooltip effect="dark" content="详情" placement="top">
+          <i
+            class="el-icon-view tb-icon"
+            @click="getRouter('/report/detail', scope.row.cgdNo)"
+          ></i>
+        </el-tooltip>
+      </template>
+    </ex-table>
+  </div>
+</template>
+<script>
+import mixinPage from "@/mixins/elPaginationHandle";
+import resToken from "@/mixins/resToken";
+import urlConfig from "@/apis/url-config";
+import asyncRequest from "@/apis/report";
+import { columns, statusOptions } from "./config/columns";
+import { cg_order_type_options } from "@/assets/js/statusList";
+import { mapGetters } from "vuex";
+
+export default {
+  name: "purchaseOrder",
+  mixins: [mixinPage, resToken],
+  components: {},
+  computed: {
+    ...mapGetters(["tablebtnSize", "searchSize", "size", "business_companyNo"]),
+    maxNo() {
+      return this.business_companyNo;
+    },
+  },
+
+  watch: {
+    maxNo(val, oldval) {
+      this.restSearch();
+    },
+  },
+  data() {
+    return {
+      //入库公司
+      supplierName: "",
+      cg_order_type_options,
+      //入库仓库
+      stockName: "",
+      changeList: [],
+      fileUrl: urlConfig.baseURL,
+      sitem: null,
+      select: "1",
+      input: "",
+      timeOBJ: {
+        start: "", //起始时间
+        end: "", // 结束时间
+      },
+      // 状态
+      statusOptions: statusOptions,
+      loading: false,
+      showModel: false,
+      isDetail: false,
+      modelId: 0,
+      wsm_code: [],
+      wsm_supplierNo: [],
+      parmValue: {
+        start: "", //新建起始时间
+        end: "", // 新建结束时间
+      },
+      tableData: [],
+      passwordModel: false,
+      passwordModelId: 0,
+      isPasswordDetail: false,
+      // 表格 - 数据
+      tableData: [],
+      // 表格 - 参数
+      table: {
+        stripe: true,
+        border: true,
+        _defaultHeader_: ["setcol"],
+      },
+      // 表格 - 分页
+      pageInfo: {
+        size: 15,
+        curr: 1,
+        total: 0,
+      },
+      // 表格 - 列参数
+      columns: columns,
+    };
+  },
+  mounted() {
+    const { back } = this.$route.query;
+    if (back) {
+      this.parmValue = JSON.parse(back);
+      console.log(this.parmValue);
+      const { page, size, start, end  } = this.parmValue;
+
+      this.pageInfo = {
+        size: size,
+        curr: page,
+        total: 0,
+      };
+      //多选条件
+      this.select = this.parmValue.select;
+    } else {
+      this.select = "1";
+    }
+    this.searchList();
+  },
+
+  methods: {
+    getRouter(toRouter, queryId) {
+      if (toRouter && queryId) {
+        let model = {
+          id: queryId,
+        };
+
+        //有多选框的条件
+        this.parmValue.select = this.select;
+        this.parmValue.sselect = this.sselect;
+        this.parmValue.input = this.input;
+
+        let routerModel = {
+          options: JSON.parse(JSON.stringify(this.parmValue)),
+          router: this.$route.path,
+        };
+        model.preModel = JSON.stringify(routerModel);
+
+        this.routeGoto(toRouter, model);
+      } else {
+        this.$message.warning("暂未找到相关流程!");
+      }
+    },
+    //选中触发函数
+    selection_change(e) {
+      const { list } = e;
+      //选中的数组集合
+      this.changeList = list.length > 0 ? JSON.parse(JSON.stringify(list)) : [];
+    },
+    showal(list, message, code) {
+      let htmlList = "<ul>";
+      list.forEach((v) => {
+        htmlList += `<li>${code !== "" ? v[code] : v}</li>`;
+      });
+      htmlList += "</ul>";
+      this.$notify({
+        title: message,
+        dangerouslyUseHTMLString: true,
+        message: htmlList,
+      });
+    },
+    restSearch() {
+      this.select = "1";
+      this.input = "";
+      this.wsm_code = [];
+      this.wsm_supplierNo = [];
+      this.timeOBJ = {
+        start: "", //起始时间
+        end: "", // 结束时间
+      };
+      this.parmValue = {
+        bk_code: "", // 备库编码
+        wsm_in_code: "", // 入库单号
+        cgdNo: "", // 销售订单编码
+        apply_name: "", // 申请人
+        good_name: "", // 产品名称
+        good_code: "", // 产品属性编号
+        status: "", //状态
+        wsm_code: "", //入货仓库编码
+        start: "", //新建起始时间
+        end: "", // 新建结束时间
+        last_start: "", //最后入库时间开始
+        last_end: "", //最后入库时间结束
+        orderCode: "", //订单编号
+        company_name: "", //部门
+        page: 1, // 页码
+        size: 15, // 每页显示条数
+      };
+      // 表格 - 分页
+      this.pageInfo = {
+        size: 15,
+        curr: 1,
+        total: 0,
+      };
+      this.searchList();
+    },
+    async searchList() {
+      if (this.loading) return;
+
+      if (
+        (this.timeOBJ.start !== "" && this.timeOBJ.end === "") ||
+        (this.timeOBJ.start === "" && this.timeOBJ.end !== "")
+      ) {
+        this.$message.warning("时间区间不完整!");
+        return;
+      }
+
+      this.loading = true;
+      this.parmValue.cgdNo = this.select === "1" ? this.input : ""; // 销售订单编码
+      this.parmValue.good_code = this.select === "4" ? this.input : ""; // 产品属性编号
+      this.parmValue.good_name = this.select === "5" ? this.input : ""; // 产品名称
+      console.log(this.pageInfo);
+      // this.wsm_supplierNo = [];
+      const res = await asyncRequest.list(this.parmValue);
+      const { code, data } = await this.useResHandle(res);
+      if (code === 0) {
+        const { list, count } = data;
+        this.tableData = list;
+        this.pageInfo.total = Number(count);
+      } else {
+        this.tableData = [];
+        this.pageInfo.total = 0;
+      }
+      this.loading = false;
+    },
+    // 时间
+    async handleTime(e) {
+      this.timeOBJ.start = e?.startTime ?? "";
+      this.timeOBJ.end = e?.endTime ?? "";
+      await this.handleClick(this.sselect);
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.purchaseOrder {
+  // text-align: right;
+}
+</style>