huang_an 1 year ago
parent
commit
025c0ffaf2

+ 154 - 0
src/api/inventory/index.js

@@ -0,0 +1,154 @@
+import request from '@/utils/request';
+
+// 查询临时盘点数据列表
+export async function getInventoryPlanList(params) {
+  const res = await request.get('/wms/plan/page', { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 新增临时盘点计划
+export async function saveInventoryPlan(params) {
+  const res = await request.post('/wms/plan/save', params);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 获取临时盘点计划详情
+export async function getInventoryPlanDetailById(id) {
+  const res = await request.get('/wms/plan/getById/' + id);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 修改临时盘点计划
+export async function updateInventoryPlan(params) {
+  const res = await request.post('/wms/plan/update', params);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 临时盘点计划删除
+export async function deleteInventoryPlan(data) {
+  const res = await request.delete(`/wms/plan/delete`, { data });
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 盘点计划派单
+export async function sendOrders(params) {
+  const res = await request.post('/wms/planOrder/sendOrders', params);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 盘点工单列表
+export async function getPlanOrderList(params) {
+  const res = await request.get('/wms/planOrder/page', { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 盘点工单详情
+export async function getOrderInfoByPlanId(params) {
+  const res = await request.get('/wms/plan/getOrderInfoByPlanId', {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 盘点计划撤回
+export async function revocationInventoryPlan(params) {
+  const res = await request.post('/wms/plan/revocation', params);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 盘点工单物品详情
+export async function getPlanDetailList(params) {
+  const res = await request.get('/wms/plandetail/page', {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 盘点报工
+export async function reportWork(data) {
+  console.log(data);
+  const res = await request.post('/wms/planOrder/reportWork', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 报损报溢列表
+export async function getReportsList(params) {
+  const res = await request.get('/wms/planProfitLoss/page', {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 获取临时盘点计划详情
+export async function getReportPlanDetailById(id) {
+  const res = await request.get('/wms/planProfitLoss/getById/' + id);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 报损报溢保存
+export async function saveReportsList(data) {
+  const res = await request.post('/wms/planProfitLoss/save', data);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 报损报溢修改
+export async function updateReportsList(data) {
+  const res = await request.post('/wms/planProfitLoss/update', data);
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 报损报溢列表
+export async function getReportList(params) {
+  const res = await request.get('/wms/plandetail/list', {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 65 - 0
src/components/CommomSelect/new-dept-select.vue

@@ -0,0 +1,65 @@
+<!-- 部门树形选择下拉框 -->
+<template>
+  <ele-tree-select
+    clearable
+    :value="value || ''"
+    :data="treeData"
+    label-key="name"
+    value-key="id"
+    default-expand-all
+    ref="treeSelect"
+    :disabled="isBindPlan"
+    :placeholder="placeholder"
+    @input="updateValue"
+    @change="changeChoose"
+  />
+</template>
+
+<script>
+  import { listOrganizations } from '@/api/system/organization';
+  export default {
+    props: {
+      // 选中的数据(v-model)
+      value: [Number, String],
+      // 提示信息
+      placeholder: {
+        type: String,
+        default: '请选择'
+      },
+      isBindPlan: {
+        type: Boolean,
+        default: false
+      }
+    },
+    data() {
+      return {
+        treeData: []
+      };
+    },
+    created() {
+      this.getData();
+    },
+    methods: {
+      async getData(params = {}) {
+        const data = await listOrganizations(params);
+        this.treeData = this.$util.toTreeData({
+          data: data || [],
+          idField: 'id',
+          parentIdField: 'parentId'
+        });
+      },
+      /* 更新选中数据 */
+      updateValue(value) {
+        this.$emit('input', value);
+      },
+
+      changeChoose(val) {
+        this.$emit(
+          'changeGroup',
+          val,
+          this.$refs.treeSelect.getNodeByValue(val)
+        );
+      }
+    }
+  };
+</script>

+ 144 - 144
src/views/equipmentDisposal/index.vue

@@ -92,161 +92,161 @@
 </template>
 
 <script>
-import { getList, remove,submit } from '@/api/equipmentDisposal/index.js';
+  import { getList, remove, submit } from '@/api/equipmentDisposal/index.js';
 
-import dictMixins from '@/mixins/dictMixins';
-import equipmentSearch from './components/search.vue';
-import edit from './components/edit';
+  import dictMixins from '@/mixins/dictMixins';
+  import equipmentSearch from './components/search.vue';
+  import edit from './components/edit';
 
-export default {
-  mixins: [dictMixins],
-  components: {
-    equipmentSearch,
-    edit
-  },
-
-  data() {
-    return {
-      loading: false,
-      // 表格列配置
-      columns: [
-        // {
-        //   width: 45,
-        //   type: 'selection',
-        //   columnKey: 'selection',
-        //   align: 'center'
-        // },
-        {
-          columnKey: 'index',
-          type: 'index',
-          label: '序号',
-          width: 55,
-          align: 'center',
-          showOverflowTooltip: true,
-          fixed: 'left'
-        },
-        {
-          prop: 'disposalType',
-          slot: 'disposalType',
-          align: 'center',
-          label: '处置方式',
-          showOverflowTooltip: true
-        },
+  export default {
+    mixins: [dictMixins],
+    components: {
+      equipmentSearch,
+      edit
+    },
 
-        {
-          columnKey: 'code',
-          align: 'center',
-          prop: 'code',
-          slot: 'code',
-          label: '编码',
-          showOverflowTooltip: true
-        },
-        {
-          prop: 'name',
-          align: 'center',
-          label: '名称',
-          showOverflowTooltip: true
-        },
-        {
-          prop: 'fixCode',
-          align: 'center',
-          label: '固资编码',
-          showOverflowTooltip: true,
-          formatter: (row, column, cellValue) => {
-            return row.deviceList.map((item) => item.fixCode).toString();
-          }
-        },
-        {
-          align: 'center',
-          label: '物品名称',
-          showOverflowTooltip: true,
-          formatter: (row, column, cellValue) => {
-            return row.deviceList.map((item) => item.name).toString();
-          }
-        },
-        {
-          prop: 'createUserName',
-          align: 'center',
-          label: '创建人'
-        },
-        {
-          prop: 'createTime',
-          align: 'center',
-          label: '创建时间'
-        },
-        {
-          prop: 'approvalStatus',
-          align: 'center',
-          label: '状态',
-          showOverflowTooltip: true,
-          formatter: (row, column, cellValue) => {
-            return cellValue == 0
-              ? '草稿'
-              : cellValue == 1
-              ? '审核中'
-              : '审核通过';
-          }
-        },
+    data() {
+      return {
+        loading: false,
+        // 表格列配置
+        columns: [
+          // {
+          //   width: 45,
+          //   type: 'selection',
+          //   columnKey: 'selection',
+          //   align: 'center'
+          // },
+          {
+            columnKey: 'index',
+            type: 'index',
+            label: '序号',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            prop: 'disposalType',
+            slot: 'disposalType',
+            align: 'center',
+            label: '处置方式',
+            showOverflowTooltip: true
+          },
 
-        {
-          columnKey: 'action',
-          slot: 'action',
-          align: 'center',
-          label: '操作',
-          width: 240,
-          fixed: 'right'
-        }
-      ],
-      networkCounts: {},
-      checkRadioData: [],
-      QRvisible: false
-    };
-  },
-  computed: {},
-  created() {
-    this.requestDict('设备处置方式');
-  },
-  methods: {
-    /* 表格数据源 */
-    datasource({ page, limit, where }) {
-      console.log('------reload-------');
-      // this.getNetWork(page, limit, where, order);
-      return getList({
-        ...where,
-        pageNum: page,
-        size: limit
-      });
-    },
+          {
+            columnKey: 'code',
+            align: 'center',
+            prop: 'code',
+            slot: 'code',
+            label: '编码',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'name',
+            align: 'center',
+            label: '名称',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'fixCode',
+            align: 'center',
+            label: '固资编码',
+            showOverflowTooltip: true,
+            formatter: (row, column, cellValue) => {
+              return row.deviceList.map((item) => item.fixCode).toString();
+            }
+          },
+          {
+            align: 'center',
+            label: '物品名称',
+            showOverflowTooltip: true,
+            formatter: (row, column, cellValue) => {
+              return row.deviceList.map((item) => item.name).toString();
+            }
+          },
+          {
+            prop: 'createUserName',
+            align: 'center',
+            label: '创建人'
+          },
+          {
+            prop: 'createTime',
+            align: 'center',
+            label: '创建时间'
+          },
+          {
+            prop: 'approvalStatus',
+            align: 'center',
+            label: '状态',
+            showOverflowTooltip: true,
+            formatter: (row, column, cellValue) => {
+              return cellValue == 0
+                ? '草稿'
+                : cellValue == 1
+                ? '审核中'
+                : '审核通过';
+            }
+          },
 
-    /* 刷新表格 */
-    reload(where) {
-      this.$refs.table.reload({ pageNum: 1, where: where });
-    },
-    open(row, type) {
-      this.$refs.edit.open(row, type);
+          {
+            columnKey: 'action',
+            slot: 'action',
+            align: 'center',
+            label: '操作',
+            width: 240,
+            fixed: 'right'
+          }
+        ],
+        networkCounts: {},
+        checkRadioData: [],
+        QRvisible: false
+      };
     },
-    submit(row) {
-      submit({businessId:row.id}).then((res) => {
-        this.$message.success('提交成功!');
-        this.reload();
-      });
+    computed: {},
+    created() {
+      this.requestDict('设备处置方式');
     },
-    remove(row) {
-      remove([row.id]).then((res) => {
-        this.$message.success('删除成功!');
-        this.reload();
-      });
+    methods: {
+      /* 表格数据源 */
+      datasource({ page, limit, where }) {
+        console.log('------reload-------');
+        // this.getNetWork(page, limit, where, order);
+        return getList({
+          ...where,
+          pageNum: page,
+          size: limit
+        });
+      },
+
+      /* 刷新表格 */
+      reload(where) {
+        this.$refs.table.reload({ pageNum: 1, where: where });
+      },
+      open(row, type) {
+        this.$refs.edit.open(row, type);
+      },
+      submit(row) {
+        submit({ businessId: row.id }).then((res) => {
+          this.$message.success('提交成功!');
+          this.reload();
+        });
+      },
+      remove(row) {
+        remove([row.id]).then((res) => {
+          this.$message.success('删除成功!');
+          this.reload();
+        });
+      }
     }
-  }
-};
+  };
 </script>
 <style lang="scss" scoped>
-@media print {
-  #printSection {
-    font-size: 34px;
-    span {
+  @media print {
+    #printSection {
       font-size: 34px;
+      span {
+        font-size: 34px;
+      }
     }
   }
-}
 </style>

+ 155 - 118
src/views/equipmentDisposal/infoDisposal/index.vue

@@ -60,139 +60,176 @@
 </template>
 
 <script>
-import dictMixins from '@/mixins/dictMixins';
-import infoEdit from './edit';
-import search from './search.vue';
-import {
-  getDisposalList,
-  removeDisposal
-} from '@/api/equipmentDisposal/index.js';
+  import { listOrganizations } from '@/api/system/organization';
+  import dictMixins from '@/mixins/dictMixins';
+  import infoEdit from './edit';
+  import search from './search.vue';
+  import {
+    getDisposalList,
+    removeDisposal
+  } from '@/api/equipmentDisposal/index.js';
 
-export default {
-  mixins: [dictMixins],
-  components: {
-    infoEdit,
-    search
-  },
-  props: {
-    isModal: {
-      default: false
+  export default {
+    mixins: [dictMixins],
+    components: {
+      infoEdit,
+      search
     },
-    disabledList: {
-      default: () => []
-    }
-  },
-  data() {
-    return {
-      loading: false,
-      // 表格列配置
-      columns: [],
-      selection: []
-    };
-  },
-  computed: {},
-  created() {
-    this.columns = [
-      {
-        width: 45,
-        columnKey: 'selection',
-        reserveSelection: true,
-        type: 'selection',
-        align: 'center',
-        selectable: (row, index) => {
-          return !this.disabledList.map((item) => item.id).includes(row.id);
-        }
-      },
-      {
-        columnKey: 'index',
-        type: 'index',
-        label: '序号',
-        width: 55,
-        align: 'center',
-        showOverflowTooltip: true,
-        fixed: 'left'
+    props: {
+      isModal: {
+        default: false
       },
+      disabledList: {
+        default: () => []
+      }
+    },
+    data() {
+      return {
+        loading: false,
+        // 表格列配置
+        columns: [],
+        selection: [],
+        treeData: []
+      };
+    },
+    computed: {},
+    created() {
+      this.columns = [
+        {
+          width: 45,
+          columnKey: 'selection',
+          reserveSelection: true,
+          type: 'selection',
+          align: 'center',
+          selectable: (row, index) => {
+            return !this.disabledList.map((item) => item.id).includes(row.id);
+          }
+        },
+        {
+          columnKey: 'index',
+          type: 'index',
+          label: '序号',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true,
+          fixed: 'left'
+        },
 
-      {
-        prop: 'name',
-        align: 'center',
-        label: '名称'
-      },
-      {
-        prop: 'type',
-        align: 'center',
-        label: '类型',
-        formatter: (row, column, cellValue) => {
-          return cellValue == 1 ? '输入框' : cellValue == 2 ? '部门选择框' : cellValue == 3 ? '日期选择框' : '';
+        {
+          prop: 'name',
+          align: 'center',
+          label: '名称'
+        },
+        {
+          prop: 'type',
+          align: 'center',
+          label: '类型',
+          formatter: (row, column, cellValue) => {
+            return cellValue == 1
+              ? '输入框'
+              : cellValue == 2
+              ? '部门选择框'
+              : cellValue == 3
+              ? '日期选择框'
+              : '';
+          }
+        },
+
+        {
+          prop: 'value',
+          align: 'center',
+          label: '内容',
+          formatter: (row, column, cellValue) => {
+            if (row.type == 1 || row.type == 3) {
+              return cellValue;
+            } else {
+              return this.findLabelByValue(this.treeData, cellValue);
+            }
+          }
+        },
+        {
+          prop: 'createUserName',
+          align: 'center',
+          label: '创建人'
+        },
+        {
+          prop: 'createTime',
+          align: 'center',
+          label: '创建时间'
+        },
+        {
+          columnKey: 'action',
+          slot: 'action',
+          align: 'center',
+          label: '操作',
+          width: 240,
+          fixed: 'right',
+          show: !this.isModal
+        }
+      ];
+      this.getData();
+    },
+    methods: {
+      findLabelByValue(tree, value) {
+        for (const node of tree) {
+          if (node.id === value) {
+            return node.name;
+          } else if (node.children) {
+            const foundLabel = this.findLabelByValue(node.children, value);
+            if (foundLabel) {
+              return foundLabel;
+            }
+          }
         }
+        return null; // 如果未找到,返回null
+      },
+      async getData(parmas = {}) {
+        const data = await listOrganizations(parmas);
+        this.treeData = this.$util.toTreeData({
+          data: data || [],
+          idField: 'id',
+          parentIdField: 'parentId'
+        });
+      },
+      /* 表格数据源 */
+      async datasource({ page, limit, where }) {
+        const row = await getDisposalList({
+          ...where,
+          pageNum: page,
+          size: limit
+        });
+        return row;
       },
 
-      {
-        prop: 'value',
-        align: 'center',
-        label: '内容'
+      /* 刷新表格 */
+      reload(where) {
+        this.$refs.table.reload({ pageNum: 1, where: where });
       },
-      {
-        prop: 'createUserName',
-        align: 'center',
-        label: '创建人'
+      open(row, type) {
+        this.$refs.edit.open(row, type);
       },
-      {
-        prop: 'createTime',
-        align: 'center',
-        label: '创建时间'
+      getValue() {
+        let select = JSON.parse(JSON.stringify(this.selection));
+        this.$refs.table.setSelectedRows([]);
+        this.selection = [];
+        return select;
       },
-      {
-        columnKey: 'action',
-        slot: 'action',
-        align: 'center',
-        label: '操作',
-        width: 240,
-        fixed: 'right',
-        show: !this.isModal
+      remove(row) {
+        removeDisposal([row.id]).then((res) => {
+          this.$message.success('删除成功!');
+          this.reload();
+        });
       }
-    ];
-  },
-  methods: {
-    /* 表格数据源 */
-    async datasource({ page, limit, where }) {
-      const row = await getDisposalList({
-        ...where,
-        pageNum: page,
-        size: limit
-      });
-      return row;
-    },
-
-    /* 刷新表格 */
-    reload(where) {
-      this.$refs.table.reload({ pageNum: 1, where: where });
-    },
-    open(row, type) {
-      this.$refs.edit.open(row, type);
-    },
-    getValue() {
-      let select = JSON.parse(JSON.stringify(this.selection));
-      this.$refs.table.setSelectedRows([]);
-      this.selection = [];
-      return select;
-    },
-    remove(row) {
-      removeDisposal([row.id]).then((res) => {
-        this.$message.success('删除成功!');
-        this.reload();
-      });
     }
-  }
-};
+  };
 </script>
 <style lang="scss" scoped>
-@media print {
-  #printSection {
-    font-size: 34px;
-    span {
+  @media print {
+    #printSection {
       font-size: 34px;
+      span {
+        font-size: 34px;
+      }
     }
   }
-}
 </style>

+ 623 - 0
src/views/stocktaking/plan/components/AddDialog.vue

@@ -0,0 +1,623 @@
+<template>
+  <!-- :title="`${type}临时盘点计划`" -->
+  <el-dialog
+    :visible.sync="visible"
+    title="临时盘点计划"
+    :before-close="cancel"
+    width="80vw"
+    class="temporary-dialog"
+  >
+    <el-form :model="formData" ref="formRef" :rules="rules" label-width="110px">
+      <el-row :gutter="20">
+        <!--        <el-col :span="8">
+          <el-form-item label="计划配置单号" prop="planCode">
+            <el-input
+              v-model="formData.planCode"
+              placeholder="自动生成"
+              disabled
+            ></el-input>
+          </el-form-item>
+        </el-col> -->
+        <el-col :span="8">
+          <el-form-item label="计划配置名称" prop="planName">
+            <el-input
+              v-model="formData.planName"
+              placeholder="请输入"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="自动派单" prop="isSyncBill">
+            <el-select
+              filterable
+              v-model="formData.isSyncBill"
+              class="w100"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in isOrNot"
+                :key="item.code"
+                :value="item.code"
+                :label="item.label"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="关联事项" prop="ruleId">
+            <el-select
+              filterable
+              v-model="formData.ruleId"
+              class="w100"
+              placeholder="请选择事项规则"
+            >
+              <el-option
+                v-for="item in ruleNameList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+                @click.native="() => (formData.ruleName = item.name)"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="盘点类型" prop="bizType">
+            <el-select
+              filterable
+              v-model="formData.bizType"
+              class="w100"
+              placeholder="请选择"
+              @change="
+                () => {
+                  if (formData.bizType === 2) {
+                    formData.bizTypeName = '';
+                    formData.bizTypeId = '';
+                  }
+                }
+              "
+            >
+              <el-option
+                v-for="item in wh_checkStatus"
+                :key="item.code"
+                :value="item.code"
+                :label="item.label"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item
+            label="盘点仓库"
+            :rules="[
+              {
+                required: formData.bizType !== 2,
+                message: '请选择盘点仓库',
+                trigger: 'blur'
+              }
+            ]"
+            prop="bizTypeId"
+          >
+            <el-select
+              filterable
+              placeholder="请选择"
+              class="w100"
+              v-model="formData.bizTypeId"
+              :disabled="formData.bizType === 2"
+            >
+              <el-option
+                v-for="item in warehouseList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+                @click.native="
+                  () => {
+                    formData.bizTypeName = item.name;
+                  }
+                "
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="审核部门" prop="deptName">
+            <!-- <selectTree
+              ref="deptRef"
+              class="w100"
+              :clearable="false"
+              :options="deptList"
+              size="small"
+              :props="{
+                value: 'code',
+                label: 'name',
+                children: 'children'
+              }"
+              @getValue="auditorDeptClick"
+            /> -->
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="审核人" prop="verifyUserId">
+            <el-select
+              filterable
+              class="form-ipt"
+              style="width: 100%"
+              size="small"
+              v-model="formData.verifyUserId"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in auditorList"
+                :key="item.userId"
+                :label="item.trueName"
+                :value="item.userId"
+                @click.native="
+                  () => {
+                    formData.verifyUserName = item.trueName;
+                  }
+                "
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="计划盘点时长" prop="duration">
+            <el-input v-model.number="formData.duration" placeholder="请输入">
+              <template #suffix>分钟</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="资产分类" prop="assetDict">
+            <!-- <el-select filterable 
+              class="form-ipt"
+              style="width: 100%"
+              size="small"
+              v-model="formData.assetDict"
+              placeholder="请选择"
+              @change="handleAssetsChange"
+            >
+              <el-option
+                v-for="item in warehousingType"
+                :key="item.key"
+                :label="item.label"
+                :value="item.key"
+                @click.native="
+                  () => {
+                    formData.assetsName = item.label
+                    assetsType = item.code
+                  }
+                "
+              >
+              </el-option>
+            </el-select> -->
+            <DictSelection
+              dictName="类型用途"
+              clearable
+              v-model="formData.assetDict"
+              @itemChange="handleAssetsChange"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="紧急程度" prop="urgent">
+            <el-select
+              filterable
+              placeholder="请选择"
+              class="w100"
+              v-model="formData.urgent"
+            >
+              <el-option
+                v-for="item in emergencyState"
+                :key="item.code"
+                :value="item.code"
+                :label="item.label"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <template v-if="formData.isSyncBill == 1">
+          <el-col :span="8">
+            <el-form-item label="执行部门" prop="executorDeptName">
+              <selectTree
+                ref="executorDeptRef"
+                class="w100"
+                :clearable="false"
+                :initStr="formData.executorDeptName"
+                :options="deptList"
+                size="small"
+                :props="{
+                  value: 'code',
+                  label: 'name',
+                  children: 'children'
+                }"
+                @getValue="excuteDeptClick"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="执行人员" prop="executorId">
+              <el-select
+                filterable
+                class="form-ipt"
+                style="width: 100%"
+                size="small"
+                v-model="formData.executorId"
+                placeholder="请选择"
+              >
+                <el-option
+                  v-for="item in staffList"
+                  :key="item.userId"
+                  :label="item.trueName"
+                  :value="item.userId"
+                  @click.native="
+                    () => {
+                      formData.executorName = item.trueName;
+                    }
+                  "
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </template>
+        <el-col :span="8">
+          <el-form-item label="锁库盘点" prop="isTreasuryLock">
+            <el-switch
+              v-model="formData.isTreasuryLock"
+              active-text="开"
+              inactive-text="关"
+              :active-value="1"
+              :inactive-value="0"
+            ></el-switch>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="备注" prop="remark">
+            <el-input
+              placeholder="请输入"
+              type="textarea"
+              :rows="2"
+              v-model="formData.remark"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <!-- 库外资产台账 -->
+      <!-- <Assets
+        ref="assetsRef"
+        :assetsName="formData.assetsName"
+        :assetsType="assetsType"
+        :bizType="formData.bizType"
+        v-if="formData.bizType === 2"
+      /> -->
+      <!-- 库内 库存台账 -->
+      <AssetsInWarehouse
+        ref="assetsRef"
+        :assetsName="formData.assetsName"
+        :warehouseId="formData.bizTypeId"
+        :assetsType="assetsType"
+        :bizType="formData.bizType"
+      />
+    </el-form>
+    <div slot="footer">
+      <el-button type="primary" @click="submit">提交</el-button>
+      <el-button type="primary" @click="cancel" plain>返回</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+  // import { isOrNot } from '@/utils/dict/common'
+  // import { handleSave, getRuleNameList } from '@/api/stockManagement/stocking'
+  // import { warehouseListValuable } from '@/api/stockManagement/warehouseDefinition'
+  // import { assetsMap } from './enum'
+  // import {
+  //   wh_checkStatus,
+  //   emergencyState,
+  //   warehousingType
+  // } from '@/utils/dict/warehouse'
+  // import org from '@/api/main/org'
+  // import user from '@/api/main/user'
+  // import selectTree from '@/components/selectTree'
+  // import common from '@/api/common'
+  import Assets from './Assets.vue';
+  import AssetsInWarehouse from './AssetsInWarehouse.vue';
+  // import { getRuleNo } from '@/utils/index'
+  export default {
+    components: {
+      // selectTree,
+      Assets,
+      AssetsInWarehouse
+    },
+    data() {
+      return {
+        // isOrNot,
+        // emergencyState,
+        // warehousingType,
+        // wh_checkStatus,
+        isOrNot: [],
+        emergencyState: [],
+        warehousingType: [],
+        ruleNameList: [],
+        warehouseList: [],
+        wh_checkStatus: [],
+        deptList: [],
+        auditorList: [],
+        staffList: [],
+        assetsList: [],
+        visible: false,
+        type: '新建',
+        // assetsType: warehousingType[0].code,
+        assetsType: 1,
+        formData: {
+          bizType: 1,
+          assetsName: '',
+          assetsId: '',
+          deptName: '',
+          deptCode: '',
+          auditorName: '',
+          bizTypeName: '',
+          bizTypeId: '',
+          ruleId: '',
+          isSyncBill: '',
+          planName: '',
+          // planCode: getRuleNo('PD'),
+          verifyUserId: '',
+          verifyUserName: '',
+          duration: '',
+          urgent: '',
+          assetDict: '',
+          executorDeptCode: '',
+          executorDeptName: '',
+          isTreasuryLock: 0,
+          executorId: '',
+          executorName: '',
+          remark: ''
+        },
+        rules: {
+          planName: [
+            { required: true, message: '请输入计划配置名称', trigger: 'blur' }
+          ],
+          isSyncBill: [
+            { required: true, message: '请选择自动派单', trigger: 'change' }
+          ],
+          // ruleId: [
+          //   { required: true, message: '请选择规则名称 ', trigger: 'change' }
+          // ],
+          bizType: [
+            { required: true, message: '请选择盘点类型', trigger: 'change' }
+          ],
+          // deptName: [
+          //   { required: true, message: '请选择审核部门', trigger: 'blur' }
+          // ],
+          // verifyUserId: [
+          //   { required: true, message: '请选择审核人', trigger: 'blur' }
+          // ],
+          duration: [
+            { required: true, message: '请输入计划盘点时长', trigger: 'blur' }
+          ],
+          assetDict: [
+            { required: true, message: '请选择资产分类', trigger: 'change' }
+          ],
+          executorDeptName: [
+            { required: true, message: '请选择执行部门', trigger: 'change' }
+          ],
+          executorId: [
+            { required: true, message: '请选择执行人员', trigger: 'change' }
+          ],
+          isTreasuryLock: [
+            { required: true, message: '请选择是否锁库盘点', trigger: 'change' }
+          ]
+        }
+      };
+    },
+    created() {
+      // this._getWarehouse()
+      // this._getRuleNameList()
+      // this._getDeptList()
+      //this._getEnumDefinitionList();
+    },
+
+    methods: {
+      open(type = '新建') {
+        this.type = type;
+        this.visible = true;
+      },
+      cancel() {
+        this.$refs.formRef.resetFields();
+        this.$refs.executorDeptRef && this.$refs.executorDeptRef.clearHandle();
+        this.$refs.deptRef && this.$refs.deptRef.clearHandle();
+        this.$refs.assetsRef && this.$refs.assetsRef.resetData();
+        this.assetsType = '';
+        this.formData.assetsName = '';
+        this.visible = false;
+      },
+      // 参数处理
+      getParams() {
+        const { classificationList = [], tableSelectionList = [] } =
+          (this.$refs.assetsRef && this.$refs.assetsRef.getSelectList()) || {};
+
+        const tableMap = assetsMap[this.formData.assetsName];
+
+        return {
+          ...this.formData,
+          classificationList: classificationList.map((i) => ({
+            classificationID: i.id,
+            classificationName: i.name
+          })),
+          planInventoryDetailList: tableSelectionList.map((item) => {
+            return {
+              informationId: item.id,
+              bizTypeId: item.bizTypeId,
+              assetCode: item.informationCode,
+              assetName: item.informationName,
+              assetBrand: item.brandNum,
+              specification: item.specification,
+              assetSku: item.modelType,
+              minPackUnit: item.packingUnit,
+              takeStockPattern: item.takeStockPattern,
+              univalence: item.univalence,
+              univalenceUnit: item.univalenceUnit,
+              isUnpack: item.isUnpack,
+              unit: item.measuringUnit
+            };
+            // if (this.formData.bizType == 2) {
+            //   const obj = {
+            //     assetLocationId: `${this.initLocation(
+            //       item.positionWorkshop
+            //     )}${this.initLocation(item.positionLine)}${this.initLocation(
+            //       item.positionFarm
+            //     )}${this.initLocation(item.positionFactory)}`,
+            //     assetLocationName: `${this.initLocation(
+            //       item.positionWorkshopCode
+            //     )}${this.initLocation(item.positionLineCode)}${this.initLocation(
+            //       item.positionFarmCode
+            //     )}${this.initLocation(item.positionFactoryCode)}`,
+            //     assetTypeDict: this.formData.assetDict,
+            //     bizTypeId: item.bizTypeId,
+            //     bizTypeName: item.bizTypeName,
+            //   };
+
+            //   for (const key in tableMap) {
+            //     obj[key] = item[tableMap[key]];
+            //   }
+            //   return obj;
+            // } else {
+            //   return {
+            //     ...item,
+            //     assetsId: item.assetSubType,
+            //     realInventoryNum: item.inventorySum,
+            //     assetBrand: item.brand,
+            //     assetSku: item.model,
+            //     minPackUnit: item.minPackUtil,
+            //     unit: item.basePackUtil,
+            //     materialType: item.assetType,
+            //   };
+            // }
+          }),
+          cycleType: 2,
+          planType: 'INVENTORY'
+        };
+      },
+      initLocation(inp) {
+        return inp ? inp + ',' : '';
+      },
+      async submit() {
+        this.$refs.formRef.validate(async (value) => {
+          if (value) {
+            const params = this.getParams();
+
+            if (
+              !(
+                params.classificationList.length ||
+                params.planInventoryDetailList.length
+              )
+            ) {
+              return this.$message.error('请选择资产分类台账!');
+            }
+
+            const res = await handleSave(params);
+
+            if (res?.success) {
+              this.$message.success('保存成功!');
+
+              this.$emit('success');
+              this.cancel();
+            }
+          }
+        });
+      },
+      async _getDeptList() {
+        let res = await org.tree();
+        if (res?.success) {
+          this.deptList = res.data;
+        }
+      },
+      handleAssetsChange(item) {
+        this.formData.assetsName = item.dictValue;
+        this.assetsType = item.dictCode;
+        this.$nextTick(
+          () =>
+            this.$refs.assetsRef && this.$refs.assetsRef.handleAssetsChange()
+        );
+      },
+      // 执行部门 点击事件
+      async excuteDeptClick(data) {
+        this.formData.executorDeptCode = data?.code;
+        this.formData.executorDeptName = data?.name;
+        this.formData.executorId = '';
+        this.formData.executorName = '';
+        if (data) {
+          this.$refs.formRef.validateField('executorDeptName');
+          this._getUserList(data.code).then((res) => {
+            if (data.code === this.formData.executorDeptCode) {
+              this.staffList = res;
+            }
+          });
+        }
+      },
+      // 审核部门 点击事件
+      async auditorDeptClick(data) {
+        this.formData.deptCode = data?.code;
+        this.formData.deptName = data?.name;
+        this.formData.verifyUserId = '';
+        this.formData.verifyUserName = '';
+        if (data) {
+          this.$refs.formRef.validateField('deptName');
+
+          this._getUserList(data.code).then((res) => {
+            if (data.code === this.formData.deptCode) {
+              this.auditorList = res;
+            }
+          });
+        }
+      },
+
+      _getUserList(deptCode) {
+        return new Promise(async (resolve) => {
+          let res = await user.list({ deptCode, size: 99999 });
+          if (res?.success) {
+            resolve(res.data.items);
+          }
+        });
+      },
+      async _getEnumDefinitionList() {
+        let res = await common.getEnumDefinitionList({ key: 'ASSECTSTYPE' });
+        if (res?.success) {
+          this.assetsList = res.data;
+        }
+      },
+
+      async _getWarehouse() {
+        const res = await warehouseListValuable();
+        if (res?.success) {
+          this.warehouseList = res.data.filter((i) => !!i.status);
+        }
+      },
+      async _getRuleNameList() {
+        const res = await getRuleNameList({ ruleTypeEm: 'INVENTORY' });
+        if (res?.success) {
+          this.ruleNameList = res.data || [];
+        }
+      }
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  ::v-deep.temporary-dialog {
+    .el-form-item {
+      margin-bottom: 20px !important;
+    }
+  }
+
+  .custom-tree-node {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-size: 14px;
+    padding-right: 8px;
+  }
+</style>

+ 462 - 0
src/views/stocktaking/plan/components/Assets.vue

@@ -0,0 +1,462 @@
+<template>
+  <div
+    class="assets-container"
+    v-show="assetsName && !['物料', '产品', '备品备件'].includes(assetsName)"
+  >
+    <div class="tree-wrapper" v-if="assetsName !== '物料'">
+      <div class="title">
+        {{ assetsName }}
+        <!-- <el-checkbox
+          :value="assetsSelectAll"
+          @click.native.prevent="handleAssetsSelectAll"
+        ></el-checkbox> -->
+      </div>
+      <div class="scroll-wrapper">
+        <el-tree
+          show-checkbox
+          :data="treeList"
+          :props="{
+            children: 'children',
+            value: 'code',
+            label: 'name'
+          }"
+          :filter-node-method="filterNode"
+          v-loading="treeLoading"
+          node-key="id"
+          ref="treeRef"
+          :highlight-current="true"
+          @node-click="handleNodeClick"
+          @check="handleCheckChange"
+        >
+          <span class="custom-tree-node" slot-scope="{ node, data }">
+            <span>{{ node.label }}</span>
+          </span>
+        </el-tree>
+      </div>
+    </div>
+    <div class="table-wrapper">
+      <el-table
+        style="width: 100%"
+        height="400px"
+        ref="tableRef"
+        :data="tableData"
+        @selection-change="handleSelectionChange"
+        @select="handleCurSelectionChange"
+        :key="assetsName !== '物料'"
+        :header-cell-style="{
+          background: '#F0F3F3',
+          border: 'none'
+        }"
+      >
+        <el-table-column
+          v-for="item in tableInfoData"
+          :key="item.key"
+          :prop="item.key"
+          :label="item.label"
+        >
+        </el-table-column>
+        <el-table-column type="selection" width="55"> </el-table-column>
+      </el-table>
+    </div>
+  </div>
+</template>
+
+<script>
+// import classManagement from '@/api/ledgerAssets/classManagement'
+// import book from '@/api/main/material/book'
+// import { tableContentData } from '../../../components/enum'
+// import {
+//   getList,
+//   getBoatList,
+//   getTurnoverCarList,
+//   getMouldList
+// } from '@/api/ledgerAssets/booksList'
+// import accountList from '@/api/sparepart/accountList'
+// import { getgoodspage } from '@/api/stockManagement/stocking'
+import { deepClone } from '@/utils'
+export default {
+  props: {
+    assetsName: {
+      type: String,
+      default: ''
+    },
+    tableValuableList: {
+      type: Array,
+      default: () => []
+    },
+    assetsType: {
+      type: [String, Number],
+      default: ''
+    },
+    bizType: {
+      type: [String, Number],
+      default: ''
+    }
+  },
+  data () {
+    return {
+      treeList: [],
+      tableInfoData: [],
+      tableData: [],
+      requestApi: '',
+      treeLoading: false,
+      tableSelectionList: {},
+      assetsSelectionList: [],
+      assetsSelectAll: false,
+      curNode: null
+    }
+  },
+  mounted () {
+    // this.handleAssetsChange()
+  },
+  methods: {
+    // 重置
+    resetData () {
+      this.clearSelection()
+      this.treeList = []
+    },
+    //清除选中
+    clearSelection () {
+      this.assetsSelectAll = false
+      this.tableData = []
+      this.tableSelectionList = {}
+    },
+    //派单过滤
+    filterNode (value, data, node) {
+      return (
+        this.tableValuableList.findIndex(item => item.bizTypeId === data.id) !==
+        -1
+      )
+    },
+    getSelectList () {
+      const classificationList =
+        (this.$refs.treeRef && this.$refs.treeRef.getCheckedNodes()) || []
+      return {
+        classificationList,
+        tableSelectionList: Object.values(this.tableSelectionList)
+          .flat()
+          .filter(
+            i => !classificationList.find(itm => i.classificationId == itm.id)
+          )
+      }
+    },
+    handleAssetsChange () {
+      this.clearSelection()
+      setTimeout(() => {
+        if (this.assetsName) {
+          let obj = tableContentData.find(item => item.name === this.assetsName)
+          this.tableInfoData = (obj && obj.tableData) || []
+
+          switch (this.assetsName) {
+            case '物料':
+              this.getBookList()
+              return
+            case '生产设备':
+              this.requestApi = getList
+              break
+            case '舟皿':
+              this.requestApi = getBoatList
+              break
+            case '周转车':
+              this.requestApi = getTurnoverCarList
+              break
+            case '模具':
+              this.requestApi = getMouldList
+              break
+            case '备品备件':
+              this.requestApi = accountList.getClassificationSpareList
+              break
+            default:
+              console.log(this.title)
+              break
+          }
+          this._getTreeList()
+        }
+      }, 0)
+    },
+    // 物料接口
+    async getBookList () {
+      const res = await book.getList({ page: 1, size: 9999 })
+      if (res?.success) {
+        if (this.tableValuableList.length) {
+          // 派单过滤
+          this.tableData = res.data.records.filter(
+            item =>
+              this.tableValuableList.findIndex(i => i.assetId == item.id) !== -1
+          )
+        } else {
+          this.tableData = res.data.records
+        }
+      }
+    },
+    // 设备、舟皿、周转车、模具
+    async _getTreeList () {
+      let res = await classManagement.getClassificationTreeAsyncCall({
+        id: '0',
+        type: this.assetsType
+      })
+      if (res?.success) {
+        this.treeList = this.formateTree(res.data[0]?.children || [])
+
+        if (this.tableValuableList?.length) {
+          this.$nextTick(() => {
+            this.$refs.treeRef.filter()
+          })
+        }
+      }
+    },
+    formateTree (list) {
+      const fn = arr => {
+        for (const p of arr) {
+          p.disabled = true
+
+          p.children?.length && fn(p.children)
+        }
+      }
+
+      fn(list)
+
+      return list
+    },
+    handleNodeClick (data, node) {
+      // if (!node.isLeaf) return //限制叶子节点·
+
+      // this.curNode = node
+      // const params = {}
+      // if (this.assetsName === '备品备件') {
+      //   params.classificationId = data.id
+      // } else {
+      //   if (data.children && data.children.length !== 0) {
+      //     params.classificationIdList = this.setclassIds(data.children, [])
+      //   } else {
+      //     params.classificationIdList = [data.id]
+      //   }
+      // }
+      // this.getTableInfo(params)
+      this.curNode = node
+      this.getTableInfo({
+        assetType: data.type,
+        classificationIds: [data.id]
+      })
+    },
+    setclassIds (data, list) {
+      if (data && data.length !== 0) {
+        data.forEach(item => {
+          if (item.children && item.children.length !== 0) {
+            this.setclassIds(item.children, list)
+          }
+          list.push(item.id)
+        })
+      }
+      return list
+    },
+    async getTableInfo (par) {
+      // if (!this.requestApi) return
+      // const res = await this.requestApi(
+      //   { page: 1, size: 9999, ...params },
+      //   params
+      // )
+      const params = {
+        page: 1,
+        size: 9999,
+        ...par
+      }
+
+      const res = await getgoodspage(params)
+      if (res?.success) {
+        const checkedTrees = this.$refs.treeRef.getCheckedKeys()
+        const tableSelectionList = deepClone(this.tableSelectionList)
+
+        if (this.tableValuableList && this.tableValuableList.length) {
+          // 派单过滤
+          this.tableData = res.data.records.filter(
+            item =>
+              this.tableValuableList.findIndex(i => i.assetId == item.id) !== -1
+          )
+        } else {
+          this.tableData = res.data.records
+        }
+
+        this.$nextTick(() => {
+          if (this.assetsName === '备品备件') {
+            if (checkedTrees.includes(params.classificationId + '')) {
+              this.$refs.tableRef.toggleAllSelection()
+            } else {
+              for (const key in tableSelectionList) {
+                tableSelectionList[key].forEach(item => {
+                  const row = this.tableData.find(i => i.id == item.id)
+                  if (row) {
+                    this.$refs.tableRef.toggleRowSelection(row, true)
+                  }
+                })
+              }
+            }
+          } else {
+            //分类选中
+            this.tableData.map(item => {
+              if (checkedTrees.includes(item.classificationId + '')) {
+                this.$refs.tableRef.toggleRowSelection(item)
+              }
+            })
+            // 表格选中(切换保存状态
+            for (const key in tableSelectionList) {
+              tableSelectionList[key].forEach(item => {
+                const row = this.tableData.find(i => i.id == item.id)
+                if (row) {
+                  this.$refs.tableRef.toggleRowSelection(row, true)
+                }
+              })
+            }
+          }
+        })
+      }
+    },
+    // tree点击选中状态改变
+    handleCheckChange (data, checkinfo) {
+      const isChecked = checkinfo.checkedKeys.indexOf(data.id) > -1
+
+      if (!isChecked) {
+        //取消全选
+        this.assetsSelectAll = false
+      }
+
+      if (this.curNode && this.curNode.data.id === data.id) {
+        this.tableData.forEach(row => {
+          this.$refs.tableRef.toggleRowSelection(row, isChecked)
+        })
+      }
+    },
+    // 资产分类全选  通过点击事件更改状态
+    handleAssetsSelectAll () {
+      this.assetsSelectAll = !this.assetsSelectAll
+      if (this.assetsSelectAll) {
+        const keys = this.treeList.map(item => item.id)
+        this.$refs.treeRef.setCheckedKeys(keys)
+      } else {
+        this.$refs.treeRef.setCheckedKeys([])
+      }
+
+      this.tableData.forEach(row => {
+        this.$refs.tableRef.toggleRowSelection(row, this.assetsSelectAll)
+      })
+    },
+    handleSelectionChange (val) {
+      let bizType = {}
+      if (this.curNode) {
+        bizType = {
+          bizTypeId: this.curNode.data?.id,
+          bizTypeName: this.curNode.data?.name
+        }
+
+        this.$set(
+          this.tableSelectionList,
+          this.curNode.data.id,
+          val.map(i => ({
+            ...i,
+            ...bizType
+          }))
+        )
+      }
+      this.tableData.forEach(item => {
+        let node = {
+          parent: this.$refs.treeRef.getNode(item.classificationId)
+        }
+        do {
+          node = node.parent
+          node.indeterminate = false
+        } while (node.parent)
+      })
+      val.forEach(item => {
+        let node = {
+          parent: this.$refs.treeRef.getNode(item.classificationId)
+        }
+        do {
+          node = node.parent
+          node.indeterminate = true
+        } while (node.parent)
+      })
+
+      // if (val.length > 0 && val.length === this.tableData.length) {
+      //   //全选
+      //   this.$refs.treeRef.setChecked(val[0].classificationId, true)
+      // }
+      // if (val.length === 0 && this.tableData.length > 0) {
+      //   //全不选
+      //   this.$refs.treeRef.setChecked(this.tableData[0].classificationId, false)
+      // }
+
+      // if (val.length && val.length < this.tableData.length) {
+      //   let node = { parent: this.curNode }
+      //   do {
+      //     node = node.parent
+      //     node.indeterminate = true
+      //   } while (node.parent)
+      // }
+    },
+    handleCurSelectionChange (selection, row) {
+      if (selection.findIndex(item => item.id === row.id) === -1) {
+        //取消选中
+        // this.$refs.treeRef.setChecked(row.classificationId, false)
+
+        for (const key in this.tableSelectionList) {
+          const idx = this.tableSelectionList[key].findIndex(
+            item => item.id === row.id
+          )
+          if (idx !== -1) {
+            this.tableSelectionList[key].splice(idx, 1)
+          }
+        }
+      }
+
+      // if (selection.length && selection.length < this.tableData.length) {
+      //   let node = { parent: this.curNode }
+      //   do {
+      //     node = node.parent
+      //     node.indeterminate = true
+      //   } while (node.parent)
+      // } else {
+      //   this.curNode.indeterminate = false
+      // }
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+::v-deep.assets-container {
+  display: flex;
+  .el-tree-node__content > .el-checkbox {
+    position: absolute;
+    right: 0;
+  }
+  .tree-wrapper {
+    width: 350px;
+    margin-right: 12px;
+    border: 1px solid #ccc;
+
+    .title {
+      text-align: center;
+      font-size: 16px;
+      font-weight: bold;
+      background: #f0f3f3;
+      padding: 4px;
+      padding-right: 8px;
+      .el-checkbox {
+        float: right;
+      }
+    }
+    .scroll-wrapper {
+      padding-top: 8px;
+    }
+    .el-checkbox__input.is-indeterminate .el-checkbox__inner {
+      background-color: #157a2c;
+      border-color: #157a2c;
+    }
+  }
+  .table-wrapper {
+    flex: 1;
+    padding: 8px;
+    border: 1px solid #ccc;
+  }
+}
+</style>

+ 501 - 0
src/views/stocktaking/plan/components/AssetsInWarehouse.vue

@@ -0,0 +1,501 @@
+<template>
+  <div class="assets-container" v-show="assetsName">
+    <div class="tree-wrapper">
+      <div class="title">
+        {{ assetsName }}
+        <!-- <el-checkbox
+          :value="assetsSelectAll"
+          @click.native.prevent="handleAssetsSelectAll"
+        ></el-checkbox> -->
+      </div>
+      <div class="scroll-wrapper">
+        <el-tree
+          show-checkbox
+          :data="treeList"
+          :props="{
+            children: 'children',
+            value: 'code',
+            label: 'name'
+          }"
+          :filter-node-method="filterNode"
+          v-loading="treeLoading"
+          node-key="id"
+          ref="treeRef"
+          :highlight-current="true"
+          @node-click="handleNodeClick"
+          @check="handleCheckChange"
+        >
+          <span class="custom-tree-node" slot-scope="{ node, data }">
+            <span>{{ node.label }}</span>
+          </span>
+        </el-tree>
+      </div>
+    </div>
+    <div class="table-wrapper">
+      <el-table
+        style="width: 100%"
+        height="400px"
+        ref="tableRef"
+        :data="tableData"
+        @selection-change="handleSelectionChange"
+        @select="handleCurSelectionChange"
+        :key="assetsName"
+        :header-cell-style="{
+          background: '#F0F3F3',
+          border: 'none'
+        }"
+      >
+        <el-table-column label="序号" type="index"> </el-table-column>
+        <el-table-column
+          v-for="item in tableInfoData"
+          :key="item.index"
+          :prop="item.inKey"
+          :label="item.label"
+        >
+          <template slot-scope="scope">
+            <div v-if="item.inKey == 'ckg'">{{ setZKG(scope.row) }}</div>
+            <div v-else-if="item.inKey == 'shrinkageCoefficient'">
+              {{ setExtendField(scope.row, 'shrinkageCoefficient') }}
+            </div>
+            <div v-else>{{ scope.row[item.inKey] }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column type="selection" width="55"> </el-table-column>
+      </el-table>
+    </div>
+  </div>
+</template>
+
+<script>
+// import classManagement from '@/api/ledgerAssets/classManagement'
+import { tableContentData } from './tableContentData.js'
+// import {
+//   getInventoryListGroup,
+//   getgoodspage
+// } from '@/api/stockManagement/stocking'
+import { deepClone } from '@/utils'
+
+export default {
+  props: {
+    assetsName: {
+      type: String,
+      default: ''
+    },
+    warehouseId: {
+      type: [Number, String],
+      default: ''
+    },
+    tableValuableList: {
+      type: Array,
+      default: () => []
+    },
+    assetsType: {
+      type: [String, Number],
+      default: ''
+    },
+    assetSubType: {
+      type: [String, Number],
+      default: ''
+    },
+    bizType: {
+      type: [String, Number],
+      default: ''
+    }
+  },
+  // watch: {
+  //   warehouseId() {
+  //     if (this.curNode) {
+  //       this.getTableInfo(
+  //         this.curNode.data.id === this.curNode.data.originId
+  //           ? ""
+  //           : this.curNode.data.id
+  //       );
+  //     }
+  //   },
+  // },
+  data () {
+    return {
+      treeList: [],
+      tableInfoData: [],
+      tableData: [],
+      requestApi: '',
+      treeLoading: false,
+      tableSelectionList: {},
+      assetsSelectionList: [],
+      assetsSelectAll: false,
+      curNode: null
+    }
+  },
+  mounted () {
+    // this.handleAssetsChange()
+  },
+  methods: {
+    // 重置
+    resetData () {
+      this.clearSelection()
+      this.treeList = []
+    },
+    //清除选中
+    clearSelection () {
+      this.assetsSelectAll = false
+      this.tableData = []
+      this.tableSelectionList = {}
+    },
+    //派单过滤
+    filterNode (value, data, node) {
+      return (
+        this.tableValuableList.findIndex(item => item.bizTypeId === data.id) !==
+        -1
+      )
+    },
+    getSelectList () {
+      const classificationList =
+        (this.$refs.treeRef && this.$refs.treeRef.getCheckedNodes()) || []
+      return {
+        classificationList,
+        tableSelectionList: Object.values(this.tableSelectionList).flat()
+        // tableSelectionList: Object.values(this.tableSelectionList)
+        //   .flat()
+        //   .filter(
+        //     (i) =>
+        //       !classificationList.find((itm) => i.classificationId == itm.id)
+        //   ),
+      }
+    },
+    handleAssetsChange () {
+      this.clearSelection()
+      setTimeout(() => {
+        if (this.assetsName) {
+          let obj = tableContentData.find(item => item.name === this.assetsName)
+          this.tableInfoData = (obj && obj.tableData) || []
+
+          this._getTreeList()
+        }
+      }, 0)
+    },
+    // 设备、舟皿、周转车、模具
+    async _getTreeList () {
+      let res = await classManagement.getClassificationTreeAsyncCall({
+        id: '0',
+        type: this.assetsType
+      })
+      if (res?.success) {
+        this.treeList = this.formateTree(res.data[0]?.children || [])
+
+        if (this.tableValuableList?.length) {
+          this.$nextTick(() => {
+            this.$refs.treeRef.filter()
+          })
+        }
+      }
+    },
+    formateTree (list) {
+      const fn = arr => {
+        for (const p of arr) {
+          p.disabled = true
+
+          p.children?.length && fn(p.children)
+        }
+      }
+
+      fn(list)
+
+      return list
+    },
+    handleNodeClick (data, node) {
+      console.log((data, node))
+      this.curNode = node
+      this.getTableInfo({
+        assetType: data.type,
+        classificationIds: [data.id]
+      })
+    },
+    setclassIds (data, list) {
+      if (data && data.length !== 0) {
+        data.forEach(item => {
+          if (item.children && item.children.length !== 0) {
+            this.setclassIds(item.children, list)
+          }
+          list.push(item.id)
+        })
+      }
+      return list
+    },
+    async getTableInfo (par) {
+      const params = {
+        page: 1,
+        size: 9999,
+        ...par
+      }
+
+      const res = await getgoodspage(params)
+      if (res?.success) {
+        const checkedTrees = this.$refs.treeRef.getCheckedKeys()
+        const tableSelectionList = deepClone(this.tableSelectionList)
+
+        if (this.tableValuableList && this.tableValuableList.length) {
+          // 派单过滤
+          this.tableData = res.data.records
+            .filter(
+              item =>
+                this.tableValuableList.findIndex(
+                  i => i.informationId == item.id
+                ) !== -1
+            )
+            .map((i, index) => ({
+              ...i,
+              index
+              //classificationId: assetSubType
+            }))
+        } else {
+          this.tableData = res.data.records.map((i, index) => ({
+            ...i,
+            index
+            //classificationId: assetSubType
+          }))
+        }
+        console.log(checkedTrees)
+        this.$nextTick(() => {
+          //分类选中
+          this.tableData.map(item => {
+            if (checkedTrees.includes(item.classificationId + '')) {
+              this.$refs.tableRef.toggleRowSelection(item)
+            }
+          })
+          // 表格选中(切换保存状态
+          for (const key in tableSelectionList) {
+            console.log('qqw', key)
+            tableSelectionList[key].forEach(item => {
+              const row = this.tableData.find(i => {
+                console.log(i.id, item.informationId)
+                return i.id === (item.informationId || item.id)
+              })
+              if (row) {
+                this.$refs.tableRef.toggleRowSelection(row, true)
+              }
+            })
+          }
+        })
+      }
+    },
+    // async getTableInfo (assetSubType) {
+    //   const params = {
+    //     page: 1,
+    //     size: 9999,
+    //     assetType: this.assetsType,
+    //     warehouseId: this.warehouseId
+    //   }
+
+    //   if (assetSubType) {
+    //     params.assetSubType = assetSubType
+    //   }
+    //   const res = await getgoodspage(params)
+    //   if (res?.success) {
+    //     const checkedTrees = this.$refs.treeRef.getCheckedKeys()
+    //     const tableSelectionList = deepClone(this.tableSelectionList)
+    //     if (this.tableValuableList && this.tableValuableList.length) {
+    //       // 派单过滤
+    //       this.tableData = res.data.records
+    //         .filter(
+    //           item =>
+    //             this.tableValuableList.findIndex(i => i.assetId == item.id) !==
+    //             -1
+    //         )
+    //         .map((i, index) => ({
+    //           ...i,
+    //           index,
+    //           classificationId: assetSubType
+    //         }))
+    //     } else {
+    //       this.tableData = res.data.records.map((i, index) => ({
+    //         ...i,
+    //         index,
+    //         classificationId: assetSubType
+    //       }))
+    //     }
+    //     this.$nextTick(() => {
+    //       //分类选中
+    //       this.tableData.map(item => {
+    //         if (checkedTrees.includes(item.classificationId + '')) {
+    //           this.$refs.tableRef.toggleRowSelection(item)
+    //         }
+    //       })
+    //       // 表格选中(切换保存状态
+    //       for (const key in tableSelectionList) {
+    //         tableSelectionList[key].forEach(item => {
+    //           const row = this.tableData.find(
+    //             i => i.classificationId === item.classificationId
+    //           )
+    //           if (row) {
+    //             this.$refs.tableRef.toggleRowSelection(row, true)
+    //           }
+    //         })
+    //       }
+    //     })
+    //   }
+    // },
+    // tree点击选中状态改变
+    handleCheckChange (data, checkinfo) {
+      const isChecked = checkinfo.checkedKeys.indexOf(data.id) > -1
+
+      if (!isChecked) {
+        //取消全选
+        this.assetsSelectAll = false
+      }
+
+      if (this.curNode && this.curNode.data.id === data.id) {
+        this.tableData.forEach(row => {
+          this.$refs.tableRef.toggleRowSelection(row, isChecked)
+        })
+      }
+    },
+    // 资产分类全选  通过点击事件更改状态
+    handleAssetsSelectAll () {
+      this.assetsSelectAll = !this.assetsSelectAll
+      if (this.assetsSelectAll) {
+        const keys = this.treeList.map(item => item.id)
+        this.$refs.treeRef.setCheckedKeys(keys)
+      } else {
+        this.$refs.treeRef.setCheckedKeys([])
+      }
+      this.tableData.forEach(row => {
+        this.$refs.tableRef.toggleRowSelection(row, this.assetsSelectAll)
+      })
+    },
+    handleSelectionChange (val) {
+      let bizType = {}
+      if (this.curNode) {
+        bizType = {
+          bizTypeId: this.curNode.data?.id,
+          bizTypeName: this.curNode.data?.name
+        }
+        this.$set(
+          this.tableSelectionList,
+          this.curNode.data.id,
+          val.map(i => ({
+            ...i,
+            ...bizType
+          }))
+        )
+      }
+
+      // if (val.length > 0 && val.length === this.tableData.length) {
+      //   //全选
+
+      //   val.forEach(item => {
+      //     this.$refs.treeRef.setChecked(item.classificationId, true)
+      //   })
+      // }
+      // if (val.length === 0 && this.tableData.length > 0) {
+      //   //全不选
+      //   this.tableData.forEach(item => {
+      //     this.$refs.treeRef.setChecked(item.classificationId, false)
+      //   })
+      // }
+      // if (val.length && val.length < this.tableData.length) {
+
+      this.tableData.forEach(item => {
+        let node = {
+          parent: this.$refs.treeRef.getNode(item.classificationId)
+        }
+        do {
+          node = node.parent
+          node.indeterminate = false
+        } while (node.parent)
+      })
+      val.forEach(item => {
+        let node = {
+          parent: this.$refs.treeRef.getNode(item.classificationId)
+        }
+        do {
+          node = node.parent
+          node.indeterminate = true
+        } while (node.parent)
+      })
+      // }
+    },
+    handleCurSelectionChange (selection, row) {
+      console.log(selection, row)
+      if (selection.findIndex(item => item.index === row.index) === -1) {
+        //取消选中
+        // this.$refs.treeRef.setChecked(row.classificationId, false)
+
+        for (const key in this.tableSelectionList) {
+          const idx = this.tableSelectionList[key].findIndex(
+            item => item.id === row.id
+          )
+          if (idx !== -1) {
+            this.tableSelectionList[key].splice(idx, 1)
+          }
+        }
+      }
+
+      // if (selection.length && selection.length < this.tableData.length) {
+      //   let node = { parent: this.curNode }
+      //   do {
+      //     node = node.parent
+      //     node.indeterminate = true
+      //   } while (node.parent)
+      // } else {
+      //   this.curNode.indeterminate = false
+      // }
+    },
+    // 设置长宽高
+    setZKG (row) {
+      if (row.extendField) {
+        let item = JSON.parse(row.extendField)
+        return `${item.length || '无'}/${item.width || '无'}/${
+          item.high || '无'
+        }`
+      }
+    },
+    // 显示扩展字段
+    setExtendField (row, type) {
+      if (row.extendField) {
+        let item = JSON.parse(row.extendField)
+        return item[type]
+      }
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+::v-deep.assets-container {
+  display: flex;
+  .el-tree-node__content > .el-checkbox {
+    position: absolute;
+    right: 0;
+  }
+  .tree-wrapper {
+    width: 350px;
+    margin-right: 12px;
+    border: 1px solid #ccc;
+
+    .title {
+      text-align: center;
+      font-size: 16px;
+      font-weight: bold;
+      background: #f0f3f3;
+      padding: 4px;
+      padding-right: 8px;
+      .el-checkbox {
+        float: right;
+      }
+    }
+    .scroll-wrapper {
+      padding-top: 8px;
+
+      .el-checkbox__input.is-indeterminate .el-checkbox__inner {
+        background-color: #157a2c;
+        border-color: #157a2c;
+      }
+    }
+  }
+  .table-wrapper {
+    flex: 1;
+    padding: 8px;
+    border: 1px solid #ccc;
+  }
+}
+</style>

+ 677 - 0
src/views/stocktaking/plan/components/addInventoryDialog.vue

@@ -0,0 +1,677 @@
+<template>
+  <el-dialog
+    :visible.sync="dialogVisible"
+    :title="dialogTile"
+    :before-close="handleClose"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    v-loading="addDialogLoading"
+    width="80%"
+  >
+    <HeaderTitle title="基本信息" size="16px"></HeaderTitle>
+    <el-form
+      :model="addForm"
+      class="add_form"
+      ref="addFormRef"
+      :rules="rules"
+      label-width="110px"
+    >
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="计划配置单号" prop="code">
+            <el-input
+              v-model="addForm.code"
+              placeholder="自动生成"
+              disabled
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="计划配置名字" prop="name">
+            <el-input
+              :disabled="isBindPlan"
+              v-model="addForm.name"
+              placeholder="请输入"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="自动派单" prop="autoOrder">
+            <el-select
+              v-model="addForm.autoOrder"
+              class="w100"
+              placeholder="请选择"
+              :disabled="isBindPlan"
+              filterable
+            >
+              <el-option :value="1" label="是"></el-option>
+              <el-option :value="0" label="否"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="规则名称" prop="ruleId">
+            <el-select
+              v-model="addForm.ruleId"
+              class="w100"
+              placeholder="请选择规则名称"
+              @change="change_ruleId"
+              :disabled="isBindPlan"
+              filterable
+            >
+              <el-option
+                v-for="item in ruleNameList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+                @click.native="addForm.ruleName = item.name"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="计划盘点时长" prop="executorDuration">
+            <el-input
+              v-model.number="addForm.executorDuration"
+              placeholder="请输入"
+              :disabled="isBindPlan"
+            >
+              <template #suffix>分钟</template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="盘点仓库" prop="warehouseId">
+            <el-select
+              placeholder="请选择"
+              class="w100"
+              :disabled="isBindPlan"
+              v-model="addForm.warehouseId"
+              @change="changeWarehouse"
+              filterable
+            >
+              <el-option
+                v-for="item in warehouseList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+                @click.native="
+                  () => {
+                    addForm.bizTypeName = item.name;
+                  }
+                "
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="审核人" prop="approvalUserId">
+            <el-select
+              v-model="addForm.approvalUserId"
+              size="small"
+              style="width: 100%"
+              :disabled="isBindPlan"
+              filterable
+            >
+              <el-option
+                v-for="item in uerList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="紧急程度" prop="urgent">
+            <DictSelection
+              :isProhibit="isBindPlan"
+              dictName="紧急程度"
+              clearable
+              filterable
+              v-model="addForm.urgent"
+            >
+            </DictSelection>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8" v-if="addForm.autoOrder">
+          <el-form-item label="执行部门" prop="executeGroupId">
+            <deptSelect
+              :isBindPlan="isBindPlan"
+              v-model="addForm.executeGroupId"
+              @changeGroup="searchDeptNodeClick"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8" v-if="addForm.autoOrder">
+          <el-form-item label="执行人员" prop="executorId">
+            <el-select
+              v-model="addForm.executorId"
+              @change="changeExecutor"
+              :disabled="isBindPlan"
+              size="small"
+              style="width: 100%"
+              filterable
+            >
+              <el-option
+                v-for="item in executorList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <!-- <el-col :span="8">
+          <el-form-item label="锁库盘点" prop="isTreasuryLock">
+            <el-switch
+              v-model="addForm.lockWarehouse"
+              active-text="开"
+              inactive-text="关"
+              :active-value="1"
+              :inactive-value="0"
+              :disabled="isBindPlan"
+            ></el-switch>
+          </el-form-item>
+        </el-col> -->
+        <el-col :span="24">
+          <el-form-item label="备注" prop="remark">
+            <el-input
+              placeholder="请输入"
+              type="textarea"
+              :rows="2"
+              resize="none"
+              v-model="addForm.remark"
+              :disabled="isBindPlan"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <HeaderTitle title="盘点物品信息" size="16px">
+        <el-select
+          :disabled="isBindPlan"
+          @change="dimensionChange"
+          v-model="dimension"
+          placeholder="请选择维度"
+        >
+          <el-option label="物品维度" :value="1"> </el-option>
+          <el-option label="批次维度" :value="2"> </el-option>
+        </el-select>
+        <el-button
+          v-if="!isBindPlan"
+          style="margin-left: 10px"
+          type="primary"
+          @click="addProducts"
+          >添加物品</el-button
+        >
+      </HeaderTitle>
+      <el-table
+        ref="table"
+        :data="productList"
+        :height="500"
+        row-key="id"
+        tooltip-effect="dark"
+        border
+      >
+        <el-table-column label="序号" type="index" width="50">
+        </el-table-column>
+        <el-table-column
+          label="物品编码"
+          prop="categoryCode"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          label="物品名称"
+          prop="categoryName"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          width="150"
+          prop="categoryLevelPath"
+          label="产品分类"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          label="批次号"
+          prop="batchNo"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          label="牌号"
+          prop="brandNum"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          label="型号"
+          prop="categoryModel"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          label="规格"
+          prop="specification"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          label="计量数量"
+          prop="measureQuantity"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          label="计量单位"
+          prop="measureUnit"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          label="重量"
+          prop="weight"
+          :show-overflow-tooltip="true"
+        >
+        </el-table-column>
+        <el-table-column
+          label="重量单位"
+          prop="weightUnit"
+          :show-overflow-tooltip="true"
+        >
+        </el-table-column>
+        <el-table-column v-if="!isBindPlan" label="操作" width="100">
+          <template slot-scope="{ row, $index }">
+            <el-button @click="deleted(row, $index)" type="text" size="small"
+              >删除</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-form>
+    <div v-if="!isBindPlan" slot="footer">
+      <el-button type="primary" size="small" @click="submit">提交</el-button>
+      <el-button size="small" @click="handleClose">关闭</el-button>
+    </div>
+    <div v-else slot="footer">
+      <el-button type="primary" size="small" @click="dialogVisible = false"
+        >确定</el-button
+      >
+      <el-button size="small" @click="dialogVisible = false">关闭</el-button>
+    </div>
+    <selectType
+      :visibleDialog.sync="visibleDialog"
+      :treeIds="productType"
+      :dimension="dimension"
+      :warehouseId="addForm.warehouseId"
+      :selectionIds="selectionIds"
+      :loadTree.sync="loadTree"
+      @selectTableData="addGoods"
+    />
+  </el-dialog>
+</template>
+
+<script>
+  import { getTreeByGroup } from '@/api/classifyManage';
+  import selectType from './selectType.vue';
+  import { getCode } from '@/api/codeManagement';
+  import {
+    getInventoryPlanDetailById,
+    saveInventoryPlan,
+    updateInventoryPlan
+  } from '@/api/inventory';
+  import {
+    getRule,
+    getWarehouseList,
+    getCategoryLevelIdByWarehouseId
+  } from '@/api/ruleManagement/plan';
+  import { getUserPage } from '@/api/system/organization';
+  import deptSelect from '@/components/CommomSelect/new-dept-select.vue';
+  export default {
+    props: {
+      dialogTile: {
+        type: String,
+        default: '新增临时盘点计划'
+      },
+      isBindPlan: {
+        type: Boolean,
+        default: function () {
+          return false;
+        }
+      },
+      id: {
+        type: String,
+        default: ''
+      }
+    },
+    components: {
+      deptSelect,
+      selectType
+    },
+    data() {
+      return {
+        visibleDialog: false,
+        type: 2, // 盘点类型 2仓储 4资产
+        dimension: 1, // 盘点维度1物品 2批次
+        factoryOptions: [],
+        workshopOptions: [],
+        productionLineOptions: [],
+        stationOptions: [],
+        codeList: [],
+        addDialogLoading: false,
+        dialogVisible: false,
+        wh_checkStatus: [], // 盘点类型
+        warehouseList: [], // 盘点仓库
+        uerList: [], // 审核人
+        executorList: [], // 执行人
+        assetsType: null,
+        planRuleInventoryDetailList: [],
+        tableList: [],
+        newColumns: [],
+        selection: [],
+        keyWord: '',
+        total: 0,
+        page: 1,
+        size: 10,
+        loadTree: true,
+        productList: [],
+        productType: [],
+        addForm: {
+          ruleId: '', // 规则名称
+          ruleName: '', // 规则名称
+          code: '', // 计划配置单号
+          name: '', // 计划配置名称
+          executeGroupId: '', // 执行部门code
+          executeGroupName: '', // 执行部门name
+          executorId: '', // 执行人id
+          executorName: '', // 执行人name
+          lockWarehouse: 1, // 是否锁库盘点
+          urgent: '1', // 紧急程度
+          warehouseId: '', // 盘点仓库Id
+          autoOrder: 1, // 是否自动派单
+          remark: '', // 备注
+          approvalUserId: '', // 审核人Id
+          approvalUserName: '', // 审核人name
+          executorDuration: 0 // 盘点时长
+        },
+        rules: {
+          code: [
+            { required: true, message: '请输入计划配置单号', trigger: 'blur' }
+          ],
+          name: [
+            { required: true, message: '请输入计划配置名称', trigger: 'blur' }
+          ],
+          autoOrder: [
+            { required: true, message: '请选择是否自动派单', trigger: 'change' }
+          ],
+          ruleId: [
+            { required: true, message: '请选择规则名称', trigger: 'change' }
+          ],
+          executorDuration: [
+            { required: true, message: '请输入计划完成时长', trigger: 'blur' }
+          ],
+          warehouseId: [
+            { required: true, message: '请选择盘点仓库', trigger: 'change' }
+          ],
+          executeGroupId: [
+            { required: true, message: '请选择选择执行部门', trigger: 'change' }
+          ],
+          executorId: [
+            { required: true, message: '请选择选择执行人员', trigger: 'change' }
+          ]
+        },
+        ruleNameList: []
+      };
+    },
+    watch: {
+      dialogVisible(val) {
+        if (val) {
+          // 获取审核人列表数据
+          this.getUserList();
+          // 获取盘点仓库
+          this._getWarehouse();
+          // 获取计划单号
+          this.getOrderCode();
+          // 获取规则名称
+          this._getRuleNameList();
+          // 获取物品类型
+          this.getGoodsList();
+          if (
+            this.dialogTile === '修改临时盘点计划' ||
+            this.dialogTile === '临时盘点计划详情'
+          ) {
+            getInventoryPlanDetailById(this.id).then(async (res) => {
+              res.urgent = String(res.urgent);
+              this.addForm = res;
+              this.dimension = res.planDetailVOS[0].batchNo ? 2 : 1;
+              if (this.addForm.executeGroupId) {
+                this.getUserList({ groupId: this.addForm.executeGroupId });
+              }
+              this.productList = res.planDetailVOS.map((item) => item.info);
+              getCategoryLevelIdByWarehouseId({
+                warehouseId: this.addForm.warehouseId
+              }).then((data) => {
+                console.log(data);
+                this.productType = Array.from(new Set(data));
+              });
+            });
+          } else {
+            this.productList = [];
+            this.addForm = {
+              ruleId: '', // 规则名称
+              ruleName: '', // 规则名称
+              code: '', // 计划配置单号
+              executeGroupId: '', // 执行部门code
+              executeGroupName: '', // 执行部门name
+              executorId: '', // 执行人id
+              executorName: '', // 执行人name
+              lockWarehouse: 1, // 是否锁库盘点
+              urgent: '1', // 紧急程度
+              warehouseId: '', // 盘点仓库Id
+              autoOrder: 1, // 是否自动派单
+              remark: '', // 备注
+              approvalUserId: '', // 审核人Id
+              approvalUserName: '', // 审核人name
+              executorDuration: 0 // 盘点时长
+            };
+          }
+        }
+      }
+    },
+    computed: {
+      clientEnvironmentId() {
+        return this.$store.state.user.info.clientEnvironmentId;
+      },
+      selectionIds() {
+        return this.productList.map((item) => item.categoryId);
+      }
+    },
+    methods: {
+      // 添加物品明细
+      async addGoods(data) {
+        console.log(data);
+        let productList = data.map((item) => {
+          return {
+            ...item
+          };
+        });
+        this.productList = this.productList.concat(productList);
+      },
+      addProducts() {
+        if (this.addForm.warehouseId) {
+          console.log(this.addForm.warehouseId);
+          this.visibleDialog = true;
+        } else {
+          this.$message.warning('请选择盘点仓库');
+        }
+      },
+      deleted(row, index) {
+        this.productList.splice(index, 1);
+      },
+      selecctedRow(val) {
+        this.selection = val;
+      },
+      dimensionChange() {
+        this.productList = [];
+      },
+      checkSelectable(row) {
+        return true;
+      },
+      // 改变规则名称
+      change_ruleId(val) {
+        this.addForm.ruleName = this.ruleNameList.filter(
+          (item) => item.id === val
+        )[0].name;
+      },
+      // 获取物品类型列表
+      async getGoodsList() {
+        const { data } = await getTreeByGroup({ type: this.type });
+        console.log('data------', data);
+        this.codeList = data;
+      },
+      // 获取规则名列表
+      async _getRuleNameList() {
+        const res = await getRule({ status: 1, type: 4, pageNum: 1, size: -1 });
+        if (res.list) {
+          this.ruleNameList = res.list || [];
+        }
+      },
+      // 获取计划配置单号
+      async getOrderCode(tips) {
+        const code = await getCode('inventoryconfig_code');
+        this.$set(this.addForm, 'code', code);
+      },
+      // 执行人选择
+      changeExecutor(val) {
+        if (val) {
+          this.addForm.executorId = val;
+          this.addForm.executorName = this.executorList.filter(
+            (item) => item.id === val
+          )[0].name;
+        }
+      },
+      // 仓库选择
+      changeWarehouse(val) {
+        if (val) {
+          this.addForm.warehouseId = val;
+          this.addForm.warehouseName = this.warehouseList.filter(
+            (item) => item.id === val
+          )[0].name;
+          this.productList = [];
+          getCategoryLevelIdByWarehouseId({ warehouseId: val }).then((data) => {
+            console.log(data);
+            this.productType = Array.from(new Set(data));
+          });
+        }
+      },
+      // 关闭弹窗
+      handleClose() {
+        this.dialogVisible = false;
+        this.$refs.addFormRef.resetFields();
+        this.addForm.assetsName = '';
+        this.assetsType = null;
+        this.addForm = {
+          ruleId: '', // 规则名称
+          ruleName: '', // 规则名称
+          code: '', // 计划配置单号
+          executeGroupId: '', // 执行部门code
+          executeGroupName: '', // 执行部门name
+          executorId: '', // 执行人id
+          executorName: '', // 执行人name
+          lockWarehouse: 1, // 是否锁库盘点
+          urgent: '1', // 紧急程度
+          warehouseId: '', // 盘点仓库Id
+          autoOrder: 1, // 是否自动派单
+          remark: '', // 备注
+          approvalUserId: '', // 审核人Id
+          approvalUserName: '', // 审核人name
+          executorDuration: 0 // 盘点时长
+        };
+      },
+
+      // 封装 - 获取盘点仓库
+      async _getWarehouse() {
+        const res = await getWarehouseList({});
+        console.log(res);
+        this.warehouseList = res.map((item) => {
+          return { ...item, name: item.factoryName + '-' + item.name };
+        });
+      },
+
+      //选择部门(搜索)
+      searchDeptNodeClick(info, row) {
+        console.log(info);
+        console.log(row);
+        if (info) {
+          const params = { groupId: info };
+          this.getUserList(params);
+          this.addForm.executeGroupName = row.name;
+        } else {
+          this.addForm.executeGroupId = null;
+        }
+      },
+
+      // 获取审核人列表、巡点检人员
+      async getUserList(params) {
+        try {
+          let data = { pageNum: 1, size: -1 };
+          // 如果传了参数就是获取巡点检人员数据
+          if (params) {
+            data = Object.assign(data, params);
+          }
+          const res = await getUserPage(data);
+          if (params) {
+            this.executorList = res.list;
+          } else {
+            this.uerList = res.list;
+          }
+        } catch (error) {}
+      },
+      submit() {
+        console.log(this.addForm);
+        this.$refs.addFormRef.validate(async (valid) => {
+          let res = null;
+          if (valid) {
+            let params = {
+              ...this.addForm,
+              planDetailAddPOList: this.productList.map((item) => {
+                return {
+                  batchNo: item.batchNo,
+                  categoryId: item.categoryId,
+                  categoryName: item.categoryName,
+                  info: item
+                };
+              })
+            };
+            if (this.productList?.length > 0) {
+              if (this.dialogTile === '修改临时盘点计划') {
+                res = await updateInventoryPlan(params);
+              } else {
+                res = await saveInventoryPlan(params);
+              }
+            } else {
+              return this.$message.error('请选择需要盘点物品');
+            }
+
+            if (res.code == 0) {
+              this.handleClose();
+              this.$message.success(res.message);
+              this.$emit('refreshList');
+            }
+          }
+        });
+      },
+      handleChangeassetDict(data) {
+        console.log(data);
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  ::v-deep .el-row {
+    display: flex;
+    flex-wrap: wrap;
+  }
+  .add_form {
+    ::v-deep .el-form-item {
+      margin-bottom: 20px !important;
+    }
+  }
+  .table_search {
+    margin-bottom: 5px;
+  }
+</style>

+ 137 - 0
src/views/stocktaking/plan/components/assetTree.vue

@@ -0,0 +1,137 @@
+<template>
+  <div class="tree-wrapper">
+    <el-tree
+      :data="treeList"
+      :props="defaultProps"
+      v-loading="treeLoading"
+      :node-key="nodeKey"
+      ref="tree"
+      :highlight-current="true"
+      :expand-on-click-node="false"
+      @node-click="handleNodeClick"
+      :default-expanded-keys="current && current.id ? [current.id] : []"
+    >
+    </el-tree>
+  </div>
+</template>
+
+<script>
+  import { getTreeByIds, getTreeByGroup } from '@/api/classifyManage';
+
+  export default {
+    props: {
+      defaultProps: {
+        type: Object,
+        default: function () {
+          return {
+            children: 'children',
+            value: 'id',
+            label: 'name'
+          };
+        }
+      },
+
+      // 初始请求treeList
+      init: {
+        type: Boolean,
+        default: true
+      },
+      treeIds: {
+        type: Array,
+        default: []
+      },
+      nodeKey: {
+        type: String,
+        default: 'id'
+      }
+    },
+    data() {
+      return {
+        treeList: [],
+        treeLoading: false,
+        current: {},
+        currentId: null,
+        currentKey: ''
+      };
+    },
+    mounted() {
+      if (this.init) {
+        this.getTreeData();
+      }
+    },
+    methods: {
+      // 获取树结构数据
+      getTreeData() {
+        return new Promise(async (resolve) => {
+          try {
+            this.treeLoading = true;
+            let res = null;
+            if (this.treeIds.length > 0) {
+              res = await getTreeByIds({ ids: this.treeIds.join(',') });
+            } else {
+              res = await getTreeByGroup({ type: 2 });
+            }
+            this.treeLoading = false;
+            if (res?.code === '0') {
+              this.treeList = res.data;
+              // this.$emit('setRootId', res.data[0]);
+              // this.$nextTick(() => {
+              //   // 默认高亮第一级树节点
+              //   if (this.treeList[0]) {
+              //     this.setCurrentKey(this.treeList[0]);
+              //     this.current = this.treeList[0];
+              //     // 默认点击加载数据
+              //     // const firstNode = document.querySelector('.el-tree-node');
+              //     // firstNode.click();
+              //     resolve(this.current);
+              //   }
+              // });
+              resolve();
+              return this.treeList;
+            }
+          } catch (error) {
+            console.log(error);
+          }
+          this.treeLoading = false;
+        });
+      },
+
+      handleNodeClick(data, node) {
+        console.log(data);
+        if (this.currentId == data.id) {
+          console.log('相同的!!!');
+          this.currentId = '';
+          this.$emit('handleNodeClick');
+          this.$refs.tree.setCurrentKey(null);
+        } else {
+          this.currentId = data.id;
+          this.$emit('handleNodeClick', data, node);
+        }
+      },
+      // 设置默认高亮行
+      setCurrentKey(id) {
+        this.currentKey = id;
+        this.$refs.tree.setCurrentKey(this.currentKey);
+      },
+
+      // 获取树的选中状态
+      getSelectList() {
+        const selectList = this.$refs.tree.getCurrentNode();
+        return selectList;
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .tree-wrapper {
+    width: 100%;
+    height: 100%;
+    overflow: auto;
+
+    :deep(.el-tree) {
+      display: inline-block;
+      min-width: 100%;
+    }
+  }
+</style>

+ 330 - 0
src/views/stocktaking/plan/components/assignDialog.vue

@@ -0,0 +1,330 @@
+<template>
+  <div>
+    <el-dialog
+      :title="`指派工单`"
+      append-to-body
+      :visible="visibleDialog"
+      :before-close="closeWindows"
+      width="80vw"
+    >
+      <div class="search_box">
+        <el-form :model="formData" ref="formRef" label-width="110px">
+          <el-row :gutter="15">
+            <el-col :span="8">
+              <el-form-item label="工单编号" prop="code">
+                <el-input
+                  disabled
+                  v-model="formData.code"
+                  placeholder="请输入"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="关联计划" prop="name">
+                <el-input
+                  disabled
+                  v-model="formData.name"
+                  placeholder="请输入"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="仓库" prop="warehouseName">
+                <el-input
+                  disabled
+                  v-model="formData.warehouseName"
+                  placeholder="请输入"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="执行部门" prop="executeGroupId">
+                <deptSelect
+                  v-model="formData.executeGroupId"
+                  @changeGroup="searchDeptNodeClick"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="执行人员" prop="executorId">
+                <el-select
+                  v-model="formData.executorId"
+                  @changeExecutor="executorChange"
+                  size="small"
+                  style="width: 100%"
+                  filterable
+                >
+                  <el-option
+                    v-for="item in executorList"
+                    :key="item.id"
+                    :value="item.id"
+                    :label="item.name"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <div class="flex_info">
+        <div class="flex_right">
+          <el-table
+            ref="multipleTable"
+            :data="tableData"
+            border
+            tooltip-effect="dark"
+            height="455px"
+            style="width: 100%"
+            @selection-change="handleSelectionChange"
+          >
+            <el-table-column
+              type="selection"
+              width="55"
+              align="center"
+              fixed="left"
+            >
+            </el-table-column>
+            <el-table-column label="序号" type="index" width="50">
+            </el-table-column>
+            <el-table-column
+              label="物品编码"
+              prop="info.categoryCode"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              label="物品名称"
+              prop="info.categoryName"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              width="150"
+              prop="info.categoryLevelPath"
+              label="产品分类"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              label="批次号"
+              prop="info.batchNo"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              label="牌号"
+              prop="info.brandNum"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              label="型号"
+              prop="info.categoryModel"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              label="规格"
+              prop="info.specification"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              label="计量数量"
+              prop="info.measureQuantity"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              label="计量单位"
+              prop="info.measureUnit"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              label="重量"
+              prop="info.weight"
+              :show-overflow-tooltip="true"
+            >
+            </el-table-column>
+            <el-table-column
+              label="重量单位"
+              prop="info.weightUnit"
+              :show-overflow-tooltip="true"
+            >
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
+      <div class="select-btn">
+        <el-button type="primary" @click="onConfirm">确定</el-button>
+        <el-button @click="closeWindows">关闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import { getInventoryPlanDetailById } from '@/api/inventory';
+  import deptSelect from '@/components/CommomSelect/new-dept-select.vue';
+  import { getUserPage } from '@/api/system/organization';
+  import { sendOrders } from '@/api/inventory';
+  import { fieldModel } from '@/api/codeManagement';
+  export default {
+    props: {
+      visibleDialog: {
+        type: Boolean,
+        default: false
+      },
+      planId: {
+        type: String,
+        default: ''
+      }
+    },
+    watch: {
+      tableData() {
+        this.doLayout();
+      },
+      visibleDialog(val) {
+        if (val) {
+          this._getInformation();
+        }
+      }
+    },
+    components: { deptSelect },
+    data() {
+      return {
+        formData: {},
+        executorList: [],
+        factoryList: [],
+        factoryId: '',
+        value: '',
+        treeType: '',
+        treeList: [],
+        tableData: [],
+        multipleSelection: [],
+        pages1: { classificationIdList: [] },
+        pages: {
+          pageNum: 1,
+          size: 15
+        },
+        total: 0,
+        curType: '',
+        classificationId: '',
+        memoSelection: [],
+        newColumns: [] // 动态表头
+      };
+    },
+    created() {
+      this.getFieldModel();
+    },
+    methods: {
+      executorChange(val) {
+        this.formData.executorName = this.executorList.filter(
+          (item) => item.id == val
+        )[0].name;
+      },
+      //选择部门(搜索)
+      searchDeptNodeClick(info, row) {
+        this.formData.executorId = '';
+        if (info) {
+          const params = { groupId: info };
+          this.getUserList(params);
+          this.formData.executeGroupName = row.name;
+        } else {
+          this.formData.executeGroupId = null;
+        }
+      },
+      // 获取审核人列表、巡点检人员
+      async getUserList(params) {
+        try {
+          let data = { pageNum: 1, size: -1 };
+          if (params) {
+            data = Object.assign(data, params);
+          }
+          const res = await getUserPage(data);
+          this.executorList = res.list;
+        } catch (error) {}
+      },
+      doLayout() {
+        let that = this;
+        this.$nextTick(() => {
+          that.$refs.multipleTable.doLayout();
+        });
+      },
+      // 获取动态表头
+      getFieldModel() {
+        fieldModel({ fieldModel: 't_main_category' }).then((res) => {
+          let newRes = res.map((m) => {
+            return {
+              prop: 'extField.' + m.prop,
+              label: m.label,
+              align: 'center',
+              showOverflowTooltip: true
+            };
+          });
+          this.newColumns = [...newRes];
+        });
+      },
+      onConfirm() {
+        if (this.multipleSelection.length > 0) {
+          let params = {
+            executeGroupId: this.formData.executeGroupId,
+            executeGroupName: this.formData.executeGroupName,
+            executorId: this.formData.executorId,
+            executorName: this.formData.executorName,
+            planDetailId: this.multipleSelection.map((item) => item.id),
+            planId: this.planId
+          };
+          sendOrders(params).then(() => {
+            this.$message.success('派单成功!');
+            this.$emit('flushed');
+            this.closeWindows();
+          });
+        } else {
+          this.$message.error('请选择物品!');
+        }
+      },
+      handleSelectionChange(val) {
+        this.multipleSelection = val;
+      },
+      closeWindows() {
+        this.multipleSelection = [];
+        this.$emit('update:visibleDialog', false);
+      },
+      async _getInformation() {
+        getInventoryPlanDetailById(this.planId).then((data) => {
+          this.formData = data;
+          this.getUserList({ groupId: data.executeGroupId });
+          this.tableData = data.planDetailVOS;
+        });
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  :deep(.el-checkbox__input.is-disabled .el-checkbox__inner) {
+    background-color: #eee !important;
+  }
+  .flex_info {
+    display: flex;
+    margin-top: 20px;
+    margin-bottom: 20px;
+    .flex_left {
+      width: 202px;
+      height: 434px;
+      padding: 10px;
+      border: 1px solid #d7d7d7;
+      overflow-y: auto;
+    }
+    .flex_right {
+      flex: 1;
+      margin-left: 10px;
+      overflow: hidden;
+    }
+  }
+  .search_box {
+    overflow: hidden;
+  }
+  .select-btn {
+    text-align: right;
+  }
+  .right {
+    text-align: right;
+  }
+  .mt10 {
+    margin-top: 10px;
+  }
+</style>

+ 238 - 0
src/views/stocktaking/plan/components/plan-search.vue

@@ -0,0 +1,238 @@
+<!-- 搜索表单 -->
+<template>
+  <el-form
+    label-width="100px"
+    class="ele-form-search"
+    @keyup.enter.native="search"
+    @submit.native.prevent
+  >
+    <el-row :gutter="15">
+      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="所属工厂" prop="factoryId">
+          <el-select
+            filterable
+            placeholder="请选择"
+            @change="getTreeData"
+            v-model="where.factoryId"
+            clearable
+            class="w100"
+          >
+            <el-option
+              v-for="item in factoryList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="盘点仓库" prop="warehouseId">
+          <el-select
+            filterable
+            placeholder="请选择"
+            v-model="where.warehouseId"
+            clearable
+            class="w100"
+          >
+            <el-option
+              v-for="item in warehouseList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="计划单号:">
+          <el-input clearable v-model="where.planCode" placeholder="请输入" />
+        </el-form-item>
+      </el-col>
+      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="计划名称:">
+          <el-input clearable v-model="where.planName" placeholder="请输入" />
+        </el-form-item>
+      </el-col>
+      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="状态:">
+          <el-select
+            filterable
+            class="w100"
+            size="small"
+            v-model="where.status"
+            placeholder="请选择"
+          >
+            <el-option
+              v-for="item in statusList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <!-- <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="组织机构:" prop="deptIds">
+          <auth-selection
+            v-model="where.deptIds"
+            style="width: 100%"
+          ></auth-selection>
+        </el-form-item>
+      </el-col> -->
+      <!-- <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="盘点部门:">
+          <DeptSelect v-model="where.executeGroupId" @input="nodeClick" />
+        </el-form-item>
+      </el-col>
+      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+        <el-form-item label="盘点人员:">
+          <el-select
+            filterable
+            class="w100"
+            size="small"
+            v-model="where.executorId"
+            placeholder="请选择"
+          >
+            <el-option
+              v-for="item in userList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-col> -->
+      <el-col v-bind="styleResponsive ? { lg: 18, md: 12 } : { span: 18 }">
+        <div class="ele-form-actions">
+          <el-button
+            type="primary"
+            icon="el-icon-search"
+            class="ele-btn-icon"
+            @click="search"
+            size="small"
+          >
+            查询
+          </el-button>
+          <el-button
+            @click="reset"
+            icon="el-icon-refresh-left"
+            size="small"
+            type="primary"
+            >重置</el-button
+          >
+        </div>
+      </el-col>
+    </el-row>
+  </el-form>
+</template>
+
+<script>
+  import DeptSelect from '@/components/CommomSelect/new-dept-select.vue';
+  import storageApi from '@/api/warehouseManagement/index.js';
+  import warehouseDefinition from '@/api/warehouseManagement/warehouseDefinition';
+  export default {
+    components: { DeptSelect },
+    data() {
+      // 默认表单数据
+      const defaultWhere = {
+        name: '',
+        factoryId: '',
+        warehouseId: '',
+        executorId: '',
+        code: '',
+        executeGroupId: '',
+        status: '',
+        planCode: '',
+        executeGroupName: '',
+        executorName: ''
+      };
+      return {
+        // 表单数据
+        defaultWhere: { ...defaultWhere },
+        warehouseList: [],
+        factoryList: [],
+        where: { ...defaultWhere },
+        treeData: [],
+        statusList: [
+          { label: '未派单', value: 0 },
+          { label: '已派单', value: 1 },
+          { label: '已完成', value: 2 },
+          { label: '已撤回', value: 3 }
+        ]
+      };
+    },
+    computed: {
+      // 是否开启响应式布局
+      styleResponsive() {
+        return this.$store.state.theme.styleResponsive;
+      }
+    },
+    created() {
+      this.getFactoryList();
+    },
+    methods: {
+      async nodeClick(id, data) {
+        this.where.executeGroupId = id;
+        if (data) {
+          this.where.executeGroupName = data.name;
+        }
+        this.where.executorName = '';
+        this.where.executorId = '';
+        if (id) {
+          let userData = await warehouseDefinition.getUserPage({
+            groupId: id,
+            size: 9999,
+            pageNum: 1
+          });
+          this.userList = userData.list;
+        }
+      },
+      async getTreeData(val) {
+        this.where.targetWarehouse = '';
+        this.where.sourceWarehouse = '';
+        try {
+          this.treeLoading = true;
+          let res = await storageApi.getWarehouseTrees({
+            factoriesId: val
+          });
+          this.treeLoading = false;
+          if (res?.code === '0') {
+            this.warehouseList = res.data;
+          }
+        } catch (error) {
+          console.log(error);
+        }
+        this.treeLoading = false;
+      },
+      //获取工厂列表
+      async getFactoryList() {
+        const res = await warehouseDefinition.getFactoryarea({
+          pageNum: 1,
+          size: 9999,
+          type: 1
+        });
+        this.factoryList = res.list;
+      },
+      /* 搜索 */
+      search() {
+        console.log(this.where);
+        this.$emit('search', this.where);
+      },
+      /*  重置 */
+      reset() {
+        this.where = { ...this.defaultWhere };
+        this.search();
+      }
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .ele-form-actions {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+  }
+</style>

+ 360 - 0
src/views/stocktaking/plan/components/selectType.vue

@@ -0,0 +1,360 @@
+<template>
+  <div>
+    <el-dialog
+      :title="`产品信息`"
+      append-to-body
+      :visible="visibleDialog"
+      :before-close="closeWindows"
+      width="80vw"
+    >
+      <div class="search_box">
+        <el-row :gutter="15">
+          <!-- <el-col :span="6">
+            <el-form label-width="80px" class="ele-form-search">
+              <el-form-item label="所属工厂" prop="factoryId">
+                <el-select
+                  filterable
+                  placeholder="请选择"
+                  v-model="factoryId"
+                  clearable
+                  class="w100"
+                >
+                  <el-option
+                    v-for="item in factoryList"
+                    :key="item.id"
+                    :label="item.name"
+                    :value="item.id"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-form>
+          </el-col> -->
+          <el-col :span="8">
+            <el-input v-model="value" placeholder="搜索物品编码、名称">
+              <el-button
+                slot="append"
+                type="primary"
+                icon="el-icon-search"
+                size="small"
+                @click="handleSearch"
+                >搜索</el-button
+              >
+            </el-input>
+          </el-col>
+        </el-row>
+      </div>
+      <div class="flex_info">
+        <div class="flex_left">
+          <AssetTree
+            ref="treeList"
+            :treeIds="treeIds"
+            @handleNodeClick="handleNodeClick"
+          />
+        </div>
+        <div class="flex_right">
+          <el-table
+            ref="multipleTable"
+            :data="tableData"
+            border
+            tooltip-effect="dark"
+            height="455px"
+            style="width: 100%"
+            :header-cell-style="{ background: '#F0F3F3', border: 'none' }"
+            @selection-change="handleSelectionChange"
+          >
+            <el-table-column
+              :selectable="selectable"
+              type="selection"
+              width="55"
+              align="center"
+            >
+            </el-table-column>
+            <el-table-column width="55px" label="序号" type="index">
+            </el-table-column>
+            <el-table-column
+              prop="categoryCode"
+              label="物品编码"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              prop="categoryName"
+              label="物品名称"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              width="150"
+              prop="categoryLevelPath"
+              label="产品分类"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              v-if="dimension == 2"
+              prop="batchNo"
+              label="批次号"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              prop="brandNum"
+              label="牌号"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              prop="categoryModel"
+              label="型号"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              prop="specification"
+              label="规格"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              v-for="(item, index) in newColumns"
+              :label="item.label"
+              :align="item.align"
+              :prop="item.prop"
+              :show-overflow-tooltip="item.showOverflowTooltip"
+            ></el-table-column>
+            <el-table-column
+              prop="measureQuantity"
+              label="计量数量"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              prop="measureUnit"
+              label="计量单位"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              prop="weightUnit"
+              label="重量单位"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              prop="weight"
+              label="重量"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+            <el-table-column
+              prop="weightUnit"
+              label="重量单位"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
+          </el-table>
+          <div class="right mt10">
+            <el-pagination
+              background
+              layout="total, sizes, prev, pager, next, jumper"
+              :total="total"
+              :page-sizes="[15, 30, 50, 100, 500]"
+              :page-size.sync="pages.size"
+              :current-page.sync="pages.pageNum"
+              @current-change="handleCurrentChange"
+              @size-change="handleSizeChange"
+            >
+            </el-pagination>
+          </div>
+        </div>
+      </div>
+      <div class="select-btn">
+        <el-button type="primary" @click="onConfirm">确定</el-button>
+        <el-button @click="closeWindows">关闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import AssetTree from './assetTree.vue';
+  import { getProductList, getBatchList } from '@/api/ruleManagement/plan';
+  import { fieldModel } from '@/api/codeManagement';
+  export default {
+    props: {
+      visibleDialog: {
+        type: Boolean,
+        default: false
+      },
+      treeIds: {
+        type: Array,
+        default: () => []
+      },
+      warehouseId: {
+        type: String,
+        default: ''
+      },
+      selectionIds: {
+        type: Array,
+        default: () => []
+      },
+      dimension: {
+        type: Number,
+        default: 1
+      },
+      loadTree: {
+        type: Boolean,
+        default: true
+      }
+    },
+    watch: {
+      tableData(val) {
+        this.doLayout();
+      },
+      visibleDialog: {
+        handler(v) {
+          if (v) {
+            this.getTreeList();
+          }
+        },
+        deep: true
+      }
+    },
+    components: { AssetTree },
+    data() {
+      return {
+        factoryList: [],
+        factoryId: '',
+        value: '',
+        treeType: '',
+        treeList: [],
+        tableData: [],
+        multipleSelection: [],
+        pages1: { classificationIdList: [] },
+        pages: {
+          pageNum: 1,
+          size: 15
+        },
+        total: 0,
+        curType: '',
+        classificationId: '',
+        memoSelection: [],
+        newColumns: [] // 动态表头
+      };
+    },
+    created() {
+      this.getFieldModel();
+    },
+    methods: {
+      selectable(row) {
+        return !this.selectionIds.includes(row.categoryId);
+      },
+      doLayout() {
+        let that = this;
+        this.$nextTick(() => {
+          that.$refs.multipleTable.doLayout();
+        });
+      },
+      // 获取动态表头
+      getFieldModel() {
+        fieldModel({ fieldModel: 't_main_category' }).then((res) => {
+          let newRes = res.map((m) => {
+            return {
+              prop: 'extField.' + m.prop,
+              label: m.label,
+              align: 'center',
+              showOverflowTooltip: true
+            };
+          });
+          this.newColumns = [...newRes];
+        });
+      },
+      handleSearch() {
+        this.pages.pageNum = 1;
+        this.initData();
+      },
+      onConfirm() {
+        this.$emit('selectTableData', [...this.multipleSelection]);
+        this.closeWindows();
+      },
+      getTreeList() {
+        this.$nextTick(() => {
+          this.$refs.treeList.getTreeData().then((data) => {
+            this.handleNodeClick(data);
+          });
+        });
+      },
+      handleSelectionChange(val) {
+        this.multipleSelection = val;
+      },
+      handleNodeClick(data) {
+        if (data) {
+          this.classificationId = data.id;
+          this.curType = data.type;
+        } else {
+          this.classificationId = '';
+          this.curType = '';
+        }
+        this.initData();
+      },
+      closeWindows() {
+        this.multipleSelection = [];
+        this.$emit('update:loadTree', false);
+        this.$emit('update:visibleDialog', false);
+        this.pages.pageNum = 1;
+      },
+      handleCurrentChange(e) {
+        this.initData();
+      },
+      handleSizeChange(e) {
+        this.pages.pageNum = 1;
+        this.initData();
+      },
+      initData() {
+        this._getInformation();
+      },
+      async _getInformation() {
+        console.log(this.warehouseId);
+        const params = {
+          ...this.pages,
+          keyWord: this.value,
+          warehouseId: this.warehouseId,
+          categoryLevelIds: this.classificationId
+        };
+        let res = null;
+        if (this.dimension == 1) {
+          res = await getProductList(params);
+        } else {
+          res = await getBatchList(params);
+        }
+        if (res && this.classificationId == params.categoryLevelIds) {
+          this.tableData = res.list;
+          this.total = res.count;
+        }
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  :deep(.el-checkbox__input.is-disabled .el-checkbox__inner) {
+    background-color: #eee !important;
+  }
+  .flex_info {
+    display: flex;
+    margin-top: 20px;
+    margin-bottom: 20px;
+    .flex_left {
+      width: 202px;
+      height: 434px;
+      padding: 10px;
+      border: 1px solid #d7d7d7;
+      overflow-y: auto;
+    }
+    .flex_right {
+      flex: 1;
+      margin-left: 10px;
+      overflow: hidden;
+    }
+  }
+  .search_box {
+    overflow: hidden;
+  }
+  .select-btn {
+    text-align: right;
+  }
+  .right {
+    text-align: right;
+  }
+  .mt10 {
+    margin-top: 10px;
+  }
+</style>

+ 86 - 0
src/views/stocktaking/plan/components/tableContentData.js

@@ -0,0 +1,86 @@
+// 盘点
+export const tableContentData = [
+    {
+        name: '原料',
+        tableData: [
+            { label: '物品编码', key: 'informationCode', inKey: 'informationCode' },
+            { label: '物品名称', key: 'informationName', inKey: 'informationName' },
+            { label: '牌号', key: 'brandNum', inKey: 'brandNum' },
+        ]
+    },
+    {
+        name: '耗材',
+        tableData: [
+            { label: '物品编码', key: 'informationCode', inKey: 'informationCode' },
+            { label: '物品名称', key: 'informationName', inKey: 'informationName' },
+            { label: '规格', key: 'specification', inKey: 'specification' },
+            { label: '型号', key: 'modelType', inKey: 'modelType' }
+        ]
+    },
+    {
+        name: '物料',
+        tableData: [
+            { label: '物品编码', key: 'informationCode', inKey: 'informationCode' },
+            { label: '物品名称', key: 'informationName', inKey: 'informationName' },
+            { label: '规格', key: 'specification', inKey: 'specification' },
+            { label: '型号', key: 'modelType', inKey: 'modelType' },    
+        ]
+    },
+    {
+        name: '产品',
+        tableData: [
+            { label: '物品编码', key: 'informationCode', inKey: 'informationCode' },
+            { label: '物品名称', key: 'informationName', inKey: 'informationName' },
+            { label: '牌号', key: 'brandNum', inKey: 'brandNum' },
+            { label: '型号', key: 'modelType', inKey: 'modelType' }
+        ]
+    },
+    {
+        name: '周转车',
+        tableData: [
+            { label: '物品编码', key: 'informationCode', inKey: 'informationCode' },
+            { label: '物品名称', key: 'informationName', inKey: 'informationName' },
+            { label: '规格', key: 'specification', inKey: 'specification' },
+            { label: '材质', key: 'specification', inKey: 'specification' },
+            { label: '长/宽/高', key: 'ckg', inKey: 'ckg' },
+        ]
+    },
+    {
+        name: '舟皿',
+        tableData: [
+            { label: '物品编码', key: 'informationCode', inKey: 'informationCode' },
+            { label: '物品名称', key: 'informationName', inKey: 'informationName' },
+            { label: '规格', key: 'specification', inKey: 'specification' },
+            { label: '型号', key: 'modelType', inKey: 'modelType' },    
+            { label: '长/宽/高', key: 'ckg', inKey: 'ckg' },
+        ]
+    },
+    {
+        name: '生产设备',
+        tableData: [
+            { label: '物品编码', key: 'informationCode', inKey: 'informationCode' },
+            { label: '物品名称', key: 'informationName', inKey: 'informationName' },
+            { label: '规格', key: 'specification', inKey: 'specification' },
+            { label: '型号', key: 'modelType', inKey: 'modelType' }
+        ]
+    },
+    {
+        name: '模具',
+        tableData: [
+            { label: '物品编码', key: 'informationCode', inKey: 'informationCode' },
+            { label: '物品名称', key: 'informationName', inKey: 'informationName' },
+            { label: '规格', key: 'specification', inKey: 'specification' },
+            { label: '型号', key: 'modelType', inKey: 'modelType' },
+            { label: '收缩系数', key: 'shrinkageCoefficient', inKey: 'shrinkageCoefficient' }
+        ]
+    },
+    {
+        name: '备品备件',
+        tableData: [
+            { label: '物品编码', key: 'informationCode', inKey: 'informationCode' },
+            { label: '物品名称', key: 'informationName', inKey: 'informationName' },
+            { label: '规格', key: 'specification', inKey: 'specification' },
+            { label: '型号', key: 'modelType', inKey: 'modelType' },    
+        ]
+    }
+]

+ 283 - 0
src/views/stocktaking/plan/index.vue

@@ -0,0 +1,283 @@
+<template>
+  <div id="stocktakingPlan_index">
+    <el-card shadow="never" v-loading="loading">
+      <plan-search ref="inventorySearch" @search="reload"> </plan-search>
+      <!-- 数据表格 -->
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        height="calc(100vh-300px)"
+        :pageSize="20"
+        :datasource="datasource"
+      >
+        <!-- 表头工具栏 -->
+        <template v-slot:toolbar>
+          <el-button
+            size="small"
+            type="primary"
+            icon="el-icon-plus"
+            class="ele-btn-icon"
+            @click="openEdit()"
+          >
+            新建临时计划
+          </el-button>
+        </template>
+        <template v-slot:code="{ row }">
+          <el-link type="primary" @click="goDetail(row)">
+            {{ row.code }}
+          </el-link>
+        </template>
+        <template v-slot:action="{ row }">
+          <el-link
+            v-if="row.planStatus == 0"
+            type="primary"
+            :underline="false"
+            icon="el-icon-edit"
+            @click="assign(row)"
+          >
+            派单
+          </el-link>
+          <el-link
+            v-if="row.planStatus == 0"
+            type="primary"
+            :underline="false"
+            icon="el-icon-edit"
+            @click="openEdit(row)"
+          >
+            修改
+          </el-link>
+          <el-link
+            type="primary"
+            :underline="false"
+            icon="el-icon-edit"
+            @click="revocationRow(row)"
+          >
+            撤回
+          </el-link>
+        </template>
+      </ele-pro-table>
+    </el-card>
+    <!-- 新建或编辑弹窗 -->
+    <AddInventoryDialog
+      ref="addInventoryDialogRef"
+      :dialogTile="dialogTitle"
+      :id="inventoryId"
+      @refreshList="resetForm"
+      :isBindPlan="isBindPlan"
+    />
+    <!-- 派单 -->
+    <AssignDialog
+      :visibleDialog.sync="visibleDialog"
+      :planId="planId"
+      @flushed="reload"
+    ></AssignDialog>
+  </div>
+</template>
+
+<script>
+  import PlanSearch from './components/plan-search.vue';
+  import AddInventoryDialog from './components/addInventoryDialog.vue';
+  import AssignDialog from './components/assignDialog.vue';
+  import {
+    getInventoryPlanList,
+    revocationInventoryPlan
+  } from '@/api/inventory';
+  export default {
+    components: {
+      PlanSearch,
+      AddInventoryDialog,
+      AssignDialog
+    },
+    data() {
+      return {
+        // 表格列配置
+        columns: [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            slot: 'code',
+            prop: 'code',
+            label: '计划单号',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
+          {
+            prop: 'name',
+            label: '计划名称',
+            align: 'center',
+            showOverflowTooltip: true,
+            slot: 'enable',
+            minWidth: 110
+          },
+          {
+            prop: 'warehouseName',
+            label: '盘点仓库',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
+          {
+            prop: 'ruleName',
+            label: '计划规则',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
+          {
+            prop: 'planStatus',
+            label: '状态',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110,
+            formatter: (row, column) => {
+              return this.statusList.filter(
+                (item) => item.value == row.planStatus
+              )[0].label;
+            }
+          },
+          {
+            prop: 'createName',
+            label: '创建人',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
+          {
+            prop: 'createTime',
+            label: '生成时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 250,
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            showOverflowTooltip: true
+          }
+        ],
+        // 加载状态
+        loading: false,
+        dialogTitle: '',
+        isBindPlan: false,
+        inventoryId: '',
+        planId: '',
+        // 0未派单;1已派单;2已完成;3已撤回;
+        statusList: [
+          { label: '未派单', value: 0 },
+          { label: '已派单', value: 1 },
+          { label: '已完成', value: 2 },
+          { label: '已撤回', value: 3 }
+        ],
+        visibleDialog: false
+      };
+    },
+    methods: {
+      assign(row) {
+        this.planId = row.id;
+        this.visibleDialog = true;
+      },
+      // 重置
+      resetForm() {
+        this.$refs.inventorySearch.reset();
+      },
+      /* 表格数据源 */
+      async datasource({ page, limit, where, order }) {
+        return await getInventoryPlanList({
+          pageNum: page,
+          size: limit,
+          ...where
+        });
+      },
+      /* 刷新表格 */
+      reload(where) {
+        this.$refs.table.reload({ page: 1, where });
+      },
+      openEdit(row) {
+        if (row) {
+          this.dialogTitle = '修改临时盘点计划';
+          this.inventoryId = row.id;
+        } else {
+          this.dialogTitle = '新增临时盘点计划';
+          this.inventoryId = '';
+        }
+        this.isBindPlan = false;
+        this.$refs.addInventoryDialogRef.dialogVisible = true;
+      },
+      // goDetail(row) {
+      //   this.dialogTitle = '临时盘点计划详情';
+      //   this.inventoryId = row.id;
+      //   this.isBindPlan = true;
+      //   this.$refs.addInventoryDialogRef.dialogVisible = true;
+      // },
+      goDetail(row) {
+        this.$router.push({
+          path: '/warehouseManagement/stocktaking/plan/details',
+          query: {
+            id: row.id
+          }
+        });
+      },
+      // 撤回
+      revocationRow(row) {
+        this.$confirm('是否确定撤回?', '提示', {
+          type: 'warning'
+        })
+          .then(() => {
+            revocationInventoryPlan({ id: row.id }).then((data) => {
+              console.log(data);
+              this.$message.success('撤回成功!');
+              this.reload();
+            });
+          })
+          .catch(() => {});
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  #stocktakingPlan_index {
+    height: calc(100vh - 96px);
+    width: 100%;
+    padding: 10px;
+    box-sizing: border-box;
+    // element-ui样式穿透
+    :deep(.el-card) {
+      height: 100%;
+      .el-card__body {
+        height: 100%;
+        box-sizing: border-box;
+        display: flex;
+        flex-direction: column;
+        .ele-pro-table {
+          flex: 1;
+          display: flex;
+          flex-direction: column;
+          .el-table {
+            flex: 1;
+            // display: flex;
+            // flex-direction: column;
+            // .el-table__body-wrapper {
+            //   flex: 1;
+            // }
+          }
+        }
+      }
+      .el-form-item {
+        margin-bottom: 5px !important;
+      }
+    }
+  }
+</style>

+ 3 - 0
src/views/stocktaking/reportLoss/index.vue

@@ -0,0 +1,3 @@
+<template>
+  <div id="stocktaking_reportLoss"> 报损报溢 </div>
+</template>

+ 3 - 0
src/views/stocktaking/work/indev.vue

@@ -0,0 +1,3 @@
+<template>
+  <div id="stocktaking_work"> 工单 </div>
+</template>

+ 1 - 1
vue.config.js

@@ -35,7 +35,7 @@ module.exports = {
         // target: 'http://124.71.68.31:50001',
         // target: 'http://192.168.1.139:18086', // 粟
         // target: 'http://192.168.1.132:18086', // 徐
-        target: 'http://192.168.1.116:18086', //本
+        target: 'http://192.168.1.251:18086', //本
         changeOrigin: true, // 只有这个值为true的情况下 才表示开启跨域
         pathRewrite: {
           '^/api': ''