huminmin
21 小时以前 eb956d7f1a0d174c0d55fccebfa4872d2abfbe94
增加采购退货单列表和新增页面
已添加4个文件
772 ■■■■■ 文件已修改
src/api/procurementManagement/purchase_return_order.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/purchaseReturnOrder/New.vue 492 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/purchaseReturnOrder/ProductList.vue 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/purchaseReturnOrder/index.vue 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/procurementManagement/purchase_return_order.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
import request from "@/utils/request";
// é‡‡è´­é€€è´§å•
// åˆ†é¡µæŸ¥è¯¢
export function findPurchaseReturnOrderListPage(query) {
    return request({
        url: "/purchaseReturnOrders/listPage",
        method: "get",
        params: query,
    });
}
// æ–°å¢ž
export function createPurchaseReturnOrder(data) {
    return request({
        url: "/purchaseReturnOrders/add",
        method: "post",
        data
    });
}
src/views/procurementManagement/purchaseReturnOrder/New.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,492 @@
<template>
  <div>
    <el-dialog
        v-model="isShow"
        title="新增采购退货"
        width="1200"
        @close="closeModal"
    >
      <el-form label-width="140px" :model="formState" label-position="top" ref="formRef" :inline="true">
        <el-form-item
            label="退料单号"
            prop="no"
            :rules="[
                {
                  required: !formState.isDefaultNo,
                  message: '请输入退料单号',
                  trigger: 'blur',
                }
              ]"
        >
          <el-input
              v-model="formState.no"
              :placeholder="formState.isDefaultNo ? '使用系统编号' : '请输入退料单号'"
              :disabled="formState.isDefaultNo"
          >
            <template #append>
              <el-checkbox v-model="formState.isDefaultNo" size="large" @change="handleChangeIsDefaultNo" />
            </template>
          </el-input>
        </el-form-item>
        <el-form-item
            label="退货方式"
            prop="returnType"
            :rules="[
                {
                  required: true,
                  message: '请选择退货方式',
                  trigger: 'change',
                }
              ]"
        >
          <el-select
              v-model="formState.returnType"
              placeholder="请选择退货方式"
              style="width: 240px"
          >
            <el-option label="退货退款" :value="0" />
            <el-option label="拒收" :value="1" />
          </el-select>
        </el-form-item>
        <el-form-item
            label="供应商名称"
            prop="supplierId"
            :rules="[
              {
                required: true,
                message: '请选择供应商',
                trigger: 'change',
              }
            ]"
        >
          <el-select
              v-model="formState.supplierId"
              placeholder="请选择供应商"
              style="width: 240px"
              @focus="fetchSupplierOptions"
              @change="handleChangeSupplierId"
          >
            <el-option
              v-for="item in supplierOptions"
              :key="item.id"
              :label="item.supplierName"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item
            label="项目"
            prop="projectId"
        >
          <el-select
              v-model="formState.projectId"
              placeholder="请选择项目"
              style="width: 240px"
              @focus="fetchProjectOptions"
          >
            <el-option
                v-for="item in projectOptions"
                :key="item.id"
                :label="item.name"
                :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          label="项目阶段"
          prop="projectPhase"
        >
          <el-select
              v-model="formState.projectPhase"
              placeholder="请选择项目阶段"
              style="width: 240px"
          >
            <el-option
                v-for="item in projectStageOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item
            label="制作日期"
            prop="preparedAt"
            :rules="[
            {
              required: true,
              message: '请选择制作日期',
              trigger: 'change',
            }
          ]"
        >
          <el-date-picker
              v-model="formState.preparedAt"
              value-format="YYYY-MM-DD"
              format="YYYY-MM-DD"
              type="date"
              placeholder="请选择制作日期"
              style="width: 240px"
              clearable />
        </el-form-item>
        <el-form-item
            label="制单人:"
            prop="preparedUserId"
            :rules="[
              {
                required: true,
                message: '请选择制单人',
                trigger: 'change',
              }
            ]"
        >
          <el-select
              v-model="formState.preparedUserId"
              placeholder="请选择"
              clearable
              filterable
              default-first-option
              :reserve-keyword="false"
              style="width: 240px"
              @focus="fetchUserOptions"
          >
            <el-option
                v-for="item in userOptions"
                :key="item.userId"
                :label="item.nickName"
                :value="item.userId"
            />
          </el-select>
        </el-form-item>
        <el-form-item
            label="退料人:"
            prop="returnUserId"
            :rules="[
              {
                required: true,
                message: '请选择退料人',
                trigger: 'change',
              }
            ]"
        >
          <el-select
              v-model="formState.returnUserId"
              placeholder="请选择"
              clearable
              filterable
              default-first-option
              style="width: 240px"
              :reserve-keyword="false"
              @focus="fetchUserOptions"
          >
            <el-option
                v-for="item in userOptions"
                :key="item.userId"
                :label="item.nickName"
                :value="item.userId"
            />
          </el-select>
        </el-form-item>
        <el-form-item
            label="采购合同号:"
            prop="purchaseLedgerId"
            :rules="[
              {
                required: true,
                message: '请选择采购合同号',
                trigger: 'change',
              }
            ]"
        >
          <el-select
              v-model="formState.purchaseLedgerId"
              placeholder="请选择"
              clearable
              filterable
              default-first-option
              style="width: 240px"
              :reserve-keyword="false"
              @change="handleChangePurchaseLedgerId"
          >
            <el-option
                v-for="item in purchaseLedgerOptions"
                :key="item.id"
                :label="item.purchaseContractNumber"
                :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item
            label="备注:"
            prop="remark"
        >
          <el-input v-model="formState.remark" type="textarea" placeholder="请输入备注"/>
        </el-form-item>
      </el-form>
      <el-button type="primary" size="small" @click="isShowProductsModal = true" :disabled="!formState.purchaseLedgerId">添加产品</el-button>
      <el-table :data="products" border>
        <el-table-column align="center"
                         type="selection"
                         width="55" />
        <el-table-column align="center"
                         label="序号"
                         type="index"
                         width="60" />
        <el-table-column label="产品大类"
                         prop="productCategory" />
        <el-table-column label="规格型号"
                         prop="specificationModel" />
        <el-table-column label="单位"
                         prop="unit"
                         width="70" />
        <el-table-column label="数量"
                         prop="quantity"
                         width="70" />
        <el-table-column label="库存预警数量"
                         prop="warnNum"
                         width="120"
                         show-overflow-tooltip />
        <el-table-column label="税率(%)"
                         prop="taxRate"
                         width="80" />
        <el-table-column label="含税单价(元)"
                         prop="taxInclusiveUnitPrice"
                         :formatter="formattedNumber"
                         width="150" />
        <el-table-column label="含税总价(元)"
                         prop="taxInclusiveTotalPrice"
                         :formatter="formattedNumber"
                         width="150" />
        <el-table-column label="不含税总价(元)"
                         prop="taxExclusiveTotalPrice"
                         :formatter="formattedNumber"
                         width="150" />
        <el-table-column label="是否质检"
                         prop="isChecked"
                         width="150">
          <template #default="scope">
            <el-tag :type="scope.row.isChecked ? 'success' : 'info'">
              {{ scope.row.isChecked ? '是' : '否' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column fixed="right"
                         label="操作"
                         width="120"
                         align="center">
          <template #default="scope">
            <el-button
              link
              type="primary"
              size="small"
            >
              ç¼–辑
            </el-button>
            <el-button
                link
                type="danger"
                size="small"
                @click="delProduct(scope.$index)"
            >
              åˆ é™¤
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleSubmit">确认</el-button>
          <el-button @click="closeModal">取消</el-button>
        </div>
      </template>
    </el-dialog>
    <ProductList
        v-if="isShowProductsModal"
        v-model:visible="isShowProductsModal"
        :purchase-ledger-id="formState.purchaseLedgerId"
        @completed="handleAddProduct"
    />
  </div>
</template>
<script setup>
import {ref, computed, getCurrentInstance} from "vue";
import {createPurchaseReturnOrder} from "@/api/procurementManagement/purchase_return_order.js";
import {getOptions, purchaseList} from "@/api/procurementManagement/procurementLedger.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
const ProductList = defineAsyncComponent(() => import("@/views/procurementManagement/purchaseReturnOrder/ProductList.vue"));
const props = defineProps({
  visible: {
    type: Boolean,
    required: true,
  }
});
let { proxy } = getCurrentInstance()
const emit = defineEmits(['update:visible', 'completed']);
// å“åº”式数据(替代选项式的 data)
const formState = ref({
  no: '',
  isDefaultNo: true,
  returnType: 0,
  remark: '',
  supplierId: undefined,
  projectId: undefined,
  projectPhase: undefined,
  preparedAt: undefined,
  preparedUserId: undefined,
  returnUserId: undefined,
  purchaseLedgerId: undefined,
});
// ä¾›åº”商选项
const supplierOptions = ref([])
// é¡¹ç›®é€‰é¡¹
const projectOptions = ref([])
// é¡¹ç›®é˜¶æ®µé€‰é¡¹
const projectStageOptions = ref([
  {
    label: '立项',
    value: 0,
  },
  {
    label: '设计',
    value: 1,
  },
  {
    label: '采购',
    value: 2,
  },
  {
    label: '生产',
    value: 3,
  },
  {
    label: '出货',
    value: 4,
  }
])
// ç”¨æˆ·é€‰é¡¹
const userOptions = ref([])
// é‡‡è´­å°è´¦é€‰é¡¹
const purchaseLedgerOptions = ref([])
// äº§å“åˆ—表数据
const products = ref([])
// æ˜¯å¦å±•示产品列表数据
const isShowProductsModal = ref(false)
const isShow = computed({
  get() {
    return props.visible;
  },
  set(val) {
    emit('update:visible', val);
  },
});
const formattedNumber = (row, column, cellValue) => {
  return parseFloat(cellValue).toFixed(2);
};
const closeModal = () => {
  isShow.value = false;
};
// èŽ·å–ä¾›åº”å•†é€‰é¡¹
const fetchSupplierOptions = () => {
  if (supplierOptions.value.length > 0) {
    return
  }
  getOptions().then((res) => {
    supplierOptions.value = res.data;
  });
}
// èŽ·å–é¡¹ç›®é€‰é¡¹
const fetchProjectOptions = () => {
  if (projectOptions.value.length > 0) {
    return
  }
  // todo é¡¹ç›®é€‰é¡¹
}
// èŽ·å–ç”¨æˆ·é€‰é¡¹
const fetchUserOptions = () => {
  if (userOptions.value.length > 0) {
    return
  }
  userListNoPageByTenantId().then((res) => {
    userOptions.value = res.data;
  });
}
// å¤„理改变供应商数据
const handleChangeSupplierId = () => {
  formState.value.purchaseLedgerId = undefined
  fetchPurchaseLedgerOptions()
}
// èŽ·å–é‡‡è´­å°è´¦é€‰é¡¹
const fetchPurchaseLedgerOptions = () => {
  purchaseLedgerOptions.value = []
  if (formState.value.supplierId) {
    purchaseList({supplierId: formState.value.supplierId}).then((res) => {
      purchaseLedgerOptions.value = res.rows;
    });
  }
}
// å¤„理改变采购台账数据
const handleChangePurchaseLedgerId = () => {
  products.value = []
}
// å¤„理改变是否默认编号
const handleChangeIsDefaultNo = (checked) => {
  if (checked) {
    formState.value.no = ''
  }
}
// å¢žåŠ äº§å“
const handleAddProduct = (selectedRows) => {
  products.value.push(...selectedRows)
}
// åˆ é™¤å•项产品
const delProduct = (index) => {
  products.value.splice(index, 1)
}
// æäº¤è¡¨å•
const handleSubmit = () => {
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      createPurchaseReturnOrder(formState.value).then(res => {
        // å…³é—­æ¨¡æ€æ¡†
        isShow.value = false;
        // å‘ŠçŸ¥çˆ¶ç»„件已完成
        emit('completed');
        proxy.$modal.msgSuccess("提交成功");
      })
    }
  })
};
defineExpose({
  closeModal,
  handleSubmit,
  isShow,
});
</script>
src/views/procurementManagement/purchaseReturnOrder/ProductList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,151 @@
<template>
  <template>
    <div>
      <el-dialog
          v-model="isShow"
          title="新增产品"
          width="1200"
          @close="closeModal"
      >
        <div class="table_list">
          <el-table :data="tableData"
                    border
                    @selection-change="handleChangeSelection">
            <el-table-column align="center"
                             type="selection"
                             width="55" />
            <el-table-column align="center"
                             label="序号"
                             type="index"
                             width="60" />
            <el-table-column label="产品大类"
                             prop="productCategory" />
            <el-table-column label="规格型号"
                             prop="specificationModel" />
            <el-table-column label="单位"
                             prop="unit"
                             width="70" />
            <el-table-column label="数量"
                             prop="quantity"
                             width="70" />
            <el-table-column label="库存预警数量"
                             prop="warnNum"
                             width="120"
                             show-overflow-tooltip />
            <el-table-column label="税率(%)"
                             prop="taxRate"
                             width="80" />
            <el-table-column label="含税单价(元)"
                             prop="taxInclusiveUnitPrice"
                             :formatter="formattedNumber"
                             width="150" />
            <el-table-column label="含税总价(元)"
                             prop="taxInclusiveTotalPrice"
                             :formatter="formattedNumber"
                             width="150" />
            <el-table-column label="不含税总价(元)"
                             prop="taxExclusiveTotalPrice"
                             :formatter="formattedNumber"
                             width="150" />
            <el-table-column label="是否质检"
                             prop="isChecked"
                             width="150">
              <template #default="scope">
                <el-tag :type="scope.row.isChecked ? 'success' : 'info'">
                  {{ scope.row.isChecked ? '是' : '否' }}
                </el-tag>
              </template>
            </el-table-column>
          </el-table>
          <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
                      :page="page.current" :limit="page.size" @pagination="paginationChange" />
        </div>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" :disabled="selectedRows.length === 0" @click="handleSubmit">确认</el-button>
            <el-button @click="closeModal">取消</el-button>
          </div>
        </template>
      </el-dialog>
    </div>
  </template>
</template>
<script setup>
import {computed, reactive, ref} from "vue";
import {productList} from "@/api/procurementManagement/procurementLedger.js";
import {ElMessage} from "element-plus";
const props = defineProps({
  visible: {
    type: Boolean,
    required: true,
  },
  purchaseLedgerId: {
    type: Number,
    required: true,
  }
});
const emit = defineEmits(['update:visible', 'completed']);
const isShow = computed({
  get() {
    return props.visible;
  },
  set(val) {
    emit('update:visible', val);
  },
});
const tableData = ref([])
const selectedRows = ref([])
const tableLoading = ref(false)
const page = reactive({
  current: 1,
  size: 100,
})
const total = ref(0)
const formattedNumber = (row, column, cellValue) => {
  return parseFloat(cellValue).toFixed(2);
};
const paginationChange = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList()
}
const handleChangeSelection = (val) => {
  selectedRows.value = val;
}
const fetchData = () => {
  tableLoading.value = true;
  productList({salesLedgerId: props.purchaseLedgerId, type: 2}).then((res) => {
    tableData.value = res.data;
  }).finally(() => {
    tableLoading.value = false;
  })
}
const handleSubmit = () => {
  if (selectedRows.value.length === 0) {
    ElMessage.warning("请选择一条产品");
    return;
  }
  emit('completed', selectedRows.value);
}
const closeModal = () => {
  isShow.value = false;
};
onMounted(() => {
  fetchData()
})
</script>
src/views/procurementManagement/purchaseReturnOrder/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
<template>
  <div class="app-container">
    <div class="search_form">
      <el-form :model="searchForm"
               :inline="true">
        <el-form-item label="退料单号:">
          <el-input v-model="searchForm.no"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary"
                     @click="handleQuery"> æœç´¢ </el-button>
        </el-form-item>
      </el-form>
      <div>
        <el-button type="primary" @click="isShowNewModal = true">新增</el-button>
      </div>
    </div>
    <div class="table_list">
      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" :row-key="row => row.id" style="width: 100%" height="calc(100vh - 18.5em)">
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="退料单号" prop="no" show-overflow-tooltip />
        <el-table-column label="退货方式" prop="returnType" show-overflow-tooltip />
        <el-table-column label="供应商名称" prop="supplierName" show-overflow-tooltip />
        <el-table-column label="关联单号" prop="purchaseContractNumber" show-overflow-tooltip />
        <el-table-column label="退料人" prop="returnUserName" show-overflow-tooltip />
        <el-table-column label="备注" prop="remark"  show-overflow-tooltip />
        <el-table-column label="创建人" prop="createUserName"  show-overflow-tooltip />
        <el-table-column label="创建时间" prop="createTime" show-overflow-tooltip />
        <el-table-column label="最近更新时间" prop="updateTime" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" min-width="60" align="center">
          <template #default="scope">
            <el-button link type="primary" size="small">详情</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
                  :page="page.current" :limit="page.size" @pagination="paginationChange" />
    </div>
    <new v-if="isShowNewModal"
         v-model:visible="isShowNewModal"
         @completed="handleQuery" />
  </div>
</template>
<script setup>
import pagination from '@/components/PIMTable/Pagination.vue'
import { ref, reactive, toRefs, onMounted } from 'vue'
import {findPurchaseReturnOrderListPage} from "@/api/procurementManagement/purchase_return_order.js";
const New = defineAsyncComponent(() => import("@/views/procurementManagement/purchaseReturnOrder/New.vue"));
const tableData = ref([])
const selectedRows = ref([])
const tableLoading = ref(false)
const page = reactive({
  current: 1,
  size: 100,
})
const total = ref(0)
// æ˜¯å¦æ˜¾ç¤ºæ–°å¢žå¼¹æ¡†
const isShowNewModal = ref(false)
const data = reactive({
  searchForm: {
    no: '',
  }
})
const { searchForm } = toRefs(data)
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
  page.current = 1
  getList()
}
const paginationChange = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList()
}
const getList = () => {
  tableLoading.value = true
  findPurchaseReturnOrderListPage({ ...searchForm.value, ...page }).then(res => {
    tableLoading.value = false
    tableData.value = res.data.records
    total.value = res.data.total
  }).catch(() => {
    tableLoading.value = false
  })
}
// è¡¨æ ¼é€‰æ‹©æ•°æ®
const handleSelectionChange = (selection) => {
  // è¿‡æ»¤æŽ‰å­æ•°æ®
  selectedRows.value = selection.filter(item => item.id);
}
onMounted(() => {
  getList()
})
</script>