refactor(psi): 重构采购模块接口和页面

- 移除 psi_order 和 psi_product 文件中的接口定义
- 更新采购订单和产品页面的接口调用
- 调整采购订单列表页面的路由链接和按钮文案
- 移除产品仓库弹窗中的商品类型筛选
This commit is contained in:
mkm 2025-03-01 17:11:25 +08:00
parent 3ccd3341da
commit fbf9966c80
11 changed files with 634 additions and 102 deletions

View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 配送员表列表
export function apiDeliveryServiceLists(params: any) {
return request.get({ url: '/delivery_service/deliveryservice/lists', params })
}
// 添加配送员表
export function apiDeliveryServiceAdd(params: any) {
return request.post({ url: '/delivery_service/deliveryservice/add', params })
}
// 编辑配送员表
export function apiDeliveryServiceEdit(params: any) {
return request.post({ url: '/delivery_service/deliveryservice/edit', params })
}
// 删除配送员表
export function apiDeliveryServiceDelete(params: any) {
return request.post({ url: '/delivery_service/deliveryservice/delete', params })
}
// 配送员表详情
export function apiDeliveryServiceDetail(params: any) {
return request.get({ url: '/delivery_service/deliveryservice/detail', params })
}

View File

@ -1,42 +0,0 @@
import request from '@/utils/request'
// 商品仓储订单列表
export function apiWarehouseOrderLists(params: any) {
return request.get({ url: '/psi_order/psiorder/lists', params }, { urlPrefix: 'psi' })
}
// 添加商品仓储订单
export function apiWarehouseOrderAdd(params: any) {
return request.post({ url: '/psi_order/psiorder/add', params }, { urlPrefix: 'psi' })
}
// 添加出库单
export function apiWarehouseOrderOutbound(params: any) {
return request.post({ url: '/psi_order/psiorder/outbound', params }, { urlPrefix: 'psi' })
}
// 编辑商品仓储订单
export function apiWarehouseOrderEdit(params: any) {
return request.post({ url: '/psi_order/psiorder/edit', params }, { urlPrefix: 'psi' })
}
// 删除商品仓储订单
export function apiWarehouseOrderDelete(params: any) {
return request.post({ url: '/psi_order/psiorder/delete', params }, { urlPrefix: 'psi' })
}
// 商品仓储订单详情
export function apiWarehouseOrderDetail(params: any) {
return request.get({ url: '/psi_order/psiorder/detail', params }, { urlPrefix: 'psi' })
}
// 导出商品仓储入库订单
export function apiWarehouseOrderRentryExport(params: any) {
return request.post({ url: '/psi_order/psiorder/rentry_export', params }, { urlPrefix: 'psi' })
}
// 导出商品仓储出库订单
export function apiWarehouseOrderExport(params: any) {
return request.post({ url: '/psi_order/psiorder/export', params }, { urlPrefix: 'psi' })
}
// 编辑商品仓储订单
export function apiWarehouseOrderUpdateEdit(params: any) {
return request.post({ url: '/psi_order/psiorder/update_edit', params }, { urlPrefix: 'psi' })
}

View File

@ -1,43 +0,0 @@
import request from '@/utils/request'
// 商品仓储信息列表
export function apiWarehouseProductLists(params: any) {
return request.get({ url: '/psi_product/psiproduct/lists', params }, { urlPrefix: 'psi' })
}
// 添加商品仓储信息
export function apiWarehouseProductAdd(params: any) {
return request.post({ url: '/psi_product/psiproduct/add', params }, { urlPrefix: 'psi' })
}
// 编辑商品仓储信息
export function apiWarehouseProductEdit(params: any) {
return request.post({ url: '/psi_product/psiproduct/edit', params }, { urlPrefix: 'psi' })
}
// 删除商品仓储信息
export function apiWarehouseProductDelete(params: any) {
return request.post({ url: '/psi_product/psiproduct/delete', params }, { urlPrefix: 'psi' })
}
// 商品仓储信息详情
export function apiWarehouseProductDetail(params: any) {
return request.get({ url: '/psi_product/psiproduct/detail', params }, { urlPrefix: 'psi' })
}
// 商品仓储信息确认
export function apiWarehouseProductEnter(params: any) {
return request.post({ url: '/psi_product/psiproduct/enter', params }, { urlPrefix: 'psi' })
}
//商品结算
export function apiWarehouseProductSettlement(params: any) {
return request.post({ url: '/psi_product/psiproduct/settlement', params }, { urlPrefix: 'psi' })
}
/**
*
* @param params
* @returns
*/
export function apiWarehouseProductSetNums(params: any) {
return request.post({ url: '/psi_product/psiproduct/set_nums', params }, { urlPrefix: 'psi' })
}

View File

@ -0,0 +1,60 @@
import request from '@/utils/request'
// 商品仓储订单列表
export function apiWarehouseOrderLists(params: any) {
return request.get({ url: '/purchase_order/purchaseorder/lists', params }, { urlPrefix: 'psi' })
}
// 添加商品仓储订单
export function apiWarehouseOrderAdd(params: any) {
return request.post({ url: '/purchase_order/purchaseorder/add', params }, { urlPrefix: 'psi' })
}
// 添加出库单
export function apiWarehouseOrderOutbound(params: any) {
return request.post(
{ url: '/purchase_order/purchaseorder/outbound', params },
{ urlPrefix: 'psi' }
)
}
// 编辑商品仓储订单
export function apiWarehouseOrderEdit(params: any) {
return request.post({ url: '/purchase_order/purchaseorder/edit', params }, { urlPrefix: 'psi' })
}
// 删除商品仓储订单
export function apiWarehouseOrderDelete(params: any) {
return request.post(
{ url: '/purchase_order/purchaseorder/delete', params },
{ urlPrefix: 'psi' }
)
}
// 商品仓储订单详情
export function apiWarehouseOrderDetail(params: any) {
return request.get(
{ url: '/purchase_order/purchaseorder/detail', params },
{ urlPrefix: 'psi' }
)
}
// 导出商品仓储入库订单
export function apiWarehouseOrderRentryExport(params: any) {
return request.post(
{ url: '/purchase_order/purchaseorder/rentry_export', params },
{ urlPrefix: 'psi' }
)
}
// 导出商品仓储出库订单
export function apiWarehouseOrderExport(params: any) {
return request.post(
{ url: '/purchase_order/purchaseorder/export', params },
{ urlPrefix: 'psi' }
)
}
// 编辑商品仓储订单
export function apiWarehouseOrderUpdateEdit(params: any) {
return request.post(
{ url: '/purchase_order/purchaseorder/update_edit', params },
{ urlPrefix: 'psi' }
)
}

View File

@ -0,0 +1,67 @@
import request from '@/utils/request'
// 商品仓储信息列表
export function apiWarehouseProductLists(params: any) {
return request.get(
{ url: '/purchase_product/purchaseproduct/lists', params },
{ urlPrefix: 'psi' }
)
}
// 添加商品仓储信息
export function apiWarehouseProductAdd(params: any) {
return request.post(
{ url: '/purchase_product/purchaseproduct/add', params },
{ urlPrefix: 'psi' }
)
}
// 编辑商品仓储信息
export function apiWarehouseProductEdit(params: any) {
return request.post(
{ url: '/purchase_product/purchaseproduct/edit', params },
{ urlPrefix: 'psi' }
)
}
// 删除商品仓储信息
export function apiWarehouseProductDelete(params: any) {
return request.post(
{ url: '/purchase_product/purchaseproduct/delete', params },
{ urlPrefix: 'psi' }
)
}
// 商品仓储信息详情
export function apiWarehouseProductDetail(params: any) {
return request.get(
{ url: '/purchase_product/purchaseproduct/detail', params },
{ urlPrefix: 'psi' }
)
}
// 商品仓储信息确认
export function apiWarehouseProductEnter(params: any) {
return request.post(
{ url: '/purchase_product/purchaseproduct/enter', params },
{ urlPrefix: 'psi' }
)
}
//商品结算
export function apiWarehouseProductSettlement(params: any) {
return request.post(
{ url: '/purchase_product/purchaseproduct/settlement', params },
{ urlPrefix: 'psi' }
)
}
/**
*
* @param params
* @returns
*/
export function apiWarehouseProductSetNums(params: any) {
return request.post(
{ url: '/purchase_product/purchaseproduct/set_nums', params },
{ urlPrefix: 'psi' }
)
}

43
src/api/store_product.ts Normal file
View File

@ -0,0 +1,43 @@
import request from '@/utils/request'
// 商品表列表
export function apiStoreProductLists(params: any) {
return request.get({ url: '/store_product/storeproduct/lists', params })
}
// 添加商品表
export function apiStoreProductAdd(params: any) {
return request.post({ url: '/store_product/storeproduct/add', params })
}
// 编辑商品表
export function apiStoreProductEdit(params: any) {
return request.post({ url: '/store_product/storeproduct/edit', params })
}
// 商品状态
export function apiStoreProductStatus(params: any) {
return request.post({ url: '/store_product/storeproduct/status', params })
}
// 删除商品表
export function apiStoreProductDelete(params: any) {
return request.post({ url: '/store_product/storeproduct/delete', params })
}
export function apiStoreProductRestore(params: any) {
return request.post({ url: '/store_product/storeproduct/restore', params })
}
// 商品表详情
export function apiStoreProductDetail(params: any) {
return request.get({ url: '/store_product/storeproduct/detail', params })
}
// 复制商品到门店
export function apiStoreProductImport(params: any) {
return request.post({ url: '/store_product/storeproduct/import', params })
}
// 复制商品到门店
export function apiStoreProductCopy(params: any) {
return request.post({ url: '/store_product/storeproduct/copy', params })
}

View File

@ -10,18 +10,12 @@
placeholder="请输入商品名称" placeholder="请输入商品名称"
/> />
</el-form-item> </el-form-item>
<!-- <el-form-item label="状态" prop="is_show"> <!-- <el-form-item label="商品类型" prop="type_filter">
<el-radio-group v-model="queryParams.is_show">
<el-radio :label="1">上架</el-radio>
<el-radio :label="0">下架</el-radio>
</el-radio-group>
</el-form-item> -->
<el-form-item label="商品类型" prop="type_filter">
<el-radio-group v-model="queryParams.type_filter"> <el-radio-group v-model="queryParams.type_filter">
<el-radio :label="1">上架</el-radio> <el-radio :label="1">上架</el-radio>
<el-radio :label="0">临采</el-radio> <el-radio :label="0">临采</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item> -->
<el-form-item> <el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button> <el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button> <el-button @click="resetParams">重置</el-button>

View File

@ -1,2 +0,0 @@
<template><div></div></template>
<script setup lang="ts"></script>

View File

@ -0,0 +1,431 @@
<template>
<el-card>
<div class="mb-4 text-lg font-bold">预定单添加</div>
<div>
<el-form
ref="formRef"
:model="formData"
label-width="90px"
:inline="true"
:rules="formRules"
>
<el-row>
<el-col :span="12">
<el-form-item label="订单类型" prop="order_type">
<el-radio-group
v-model="formData.order_type"
@change="handleOrderType()"
>
<el-radio :label="7">采购订单</el-radio>
<el-radio :label="9">往期补单-入库</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6" v-if="formData.order_type == 7">
<el-form-item label="采购人员" prop="buyer_id" style="width: 300px">
<el-select
v-model="formData.buyer_id"
placeholder="请选择采购人员"
size="large"
>
<el-option
v-for="item in delivery_list"
:label="item.nickname"
:value="item.uid"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="备注" prop="mark">
<el-input v-model="formData.mark" type="input" style="width: 480px" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="商品" prop="product_id" class="w-full">
<div class="flex-1 w-full">
<div class="mb-2">
<el-button type="primary" @click="showProductModal()"
>添加商品</el-button
>
</div>
<el-table :data="productList">
<el-table-column label="商品ID" prop="id" show-overflow-tooltip>
<template #default="{ row, $index }">
<el-input
v-model="row.id"
@keydown.enter="enterProduct(row)"
:ref="(el) => (labelRefs[$index + 'id'] = el)"
@keyup="moveFocus($event, $index, 'id')"
/>
</template>
</el-table-column>
<el-table-column label="商品图片" prop="image" min-width="80">
<template #default="{ row }">
<el-image
style="width: 50px; height: 50px"
:src="row.image"
:preview-teleported="true"
/>
</template>
</el-table-column>
<el-table-column
label="商品名称"
prop="store_name"
show-overflow-tooltip
>
<template #default="{ row, $index }">
<el-input
v-model="row.store_name"
@keydown.enter="enterStoreName(row)"
:ref="(el) => (labelRefs[$index + 'store_name'] = el)"
@keyup="moveFocus($event, $index, 'store_name')"
/>
</template>
</el-table-column>
<el-table-column label="单位" min-width="80" show-overflow-tooltip>
<template #default="{ row }">
<div>{{ row.unit_name }}-{{ row.status_msg }}</div>
</template>
</el-table-column>
<el-table-column
label="仓库数量"
min-width="80"
show-overflow-tooltip
prop="stock"
/>
<el-table-column label="数量">
<template #default="{ row, $index }">
<el-input
v-model="row.nums"
@change="handleChange(row)"
:ref="(el) => (labelRefs[$index + 'nums'] = el)"
@keyup="moveFocus($event, $index, 'nums')"
/>
</template>
</el-table-column>
<el-table-column label="价格">
<template #default="{ row }">
<el-input v-model="row.price" disabled />
</template>
</el-table-column>
<el-table-column label="总价">
<template #default="{ row }">
<el-input v-model="row.total_price" disabled />
</template>
</el-table-column>
<el-table-column label="备注">
<template #default="{ row, $index }">
<el-input
v-model="row.mark"
:ref="(el) => (labelRefs[$index + 'mark'] = el)"
@keyup="moveFocus($event, $index, 'mark')"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button
type="danger"
link
@click="handleDeleteProdut(row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-form-item>
<el-row>
<el-button @click="handleSubmit(formRef)" type="primary" class="w-40 ml-20"
>提交</el-button
>
<el-form-item label="总价" prop="total_price">
<div>
{{ formData.total_price }}
<span class="ml-4">该金额只做前台展示,后台会从新计算</span>
</div>
</el-form-item>
</el-row>
</el-form>
</div>
<el-dialog v-model="showProduct" title="选择商品" width="70%">
<product-warehouse-pop
:key="productModalKey"
:userId="formData.uid"
:storeId="formData.store_id"
:order_type="formData.order_type"
@onBindStore="onBindProduct"
></product-warehouse-pop>
</el-dialog>
</el-card>
<el-dialog v-model="dialogProductShow" title="选择商品" width="1200">
<el-table :data="dialogProductLists" @current-change="handleCurrentChange" :height="300">
<el-table-column label="商品ID" prop="id" show-overflow-tooltip />
<el-table-column label="商品图片" prop="image" min-width="80">
<template #default="{ row }">
<el-image
style="width: 50px; height: 50px"
:src="row.image"
:preview-teleported="true"
/>
</template>
</el-table-column>
<el-table-column
label="商品名称"
prop="store_name"
min-width="200"
show-overflow-tooltip
/>
<el-table-column label="分类" prop="cate_name" min-width="120" show-overflow-tooltip />
<el-table-column label="单位" prop="unit_name" min-width="80" show-overflow-tooltip />
<el-table-column label="商品价格" prop="price" min-width="100" show-overflow-tooltip />
<el-table-column label="仓库库存" prop="stock" min-width="100" show-overflow-tooltip />
</el-table>
</el-dialog>
</template>
<script lang="ts" setup name="storeProductEdit">
import { ElMessage, type FormInstance } from 'element-plus'
import type { PropType } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { apiWarehouseOrderAdd } from '@/api/psi/purchase_order'
import { apiStoreProductDetail, apiStoreProductLists } from '@/api/store_product'
import { apiDeliveryServiceLists } from '@/api/delivery_service'
import feedback from '@/utils/feedback'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
// const formRef = shallowRef<FormInstance>()
const formRef = ref<FormInstance>()
//
const formData = reactive({
buyer_id: '',
total_price: 0,
order_type: 7,
mark: ''
})
const enterProduct = async (e: any) => {
const data = await apiStoreProductDetail({
id: e.id,
user_id: formData.uid,
store_id: formData.store_id
})
setData(e, data)
}
const setData = (e: any, data: any) => {
e.id = data.id
e.image = data.image
e.price = data.price
e.unit = data.unit
e.store_name = data.store_name
e.unit_name = data.unit_name
e.status_msg = data.status_msg
e.stock = data.stock
const ids: any[] = []
productList.value.forEach((item: any) => {
ids.push(item.id)
})
if (ids.includes(0) == false) {
productList.value.push({ id: 0 })
}
}
const showProduct = ref(false) //
//
const productList = ref([{ id: 0 }])
//
const handleDeleteProdut = (id: number) => {
productList.value = productList.value.filter((item: any) => item.id !== id)
}
//
const onBindProduct = (e: any[]) => {
e.forEach((item: any) => {
if (!productList.value.find((t: any) => t.id == item.id)) {
productList.value.push(item)
}
})
showProduct.value = false
}
function handleChange(row) {
row.total_price = (row.nums * row.price).toFixed(2)
if (row.total_price > 0) {
formData.total_price = (
parseFloat(formData.total_price) + parseFloat(row.total_price)
).toFixed(2)
}
}
function handleOrderType(row) {
if (formData.order_type == 7) {
formData.is_buyer = 0
} else {
formData.is_buyer = -1
}
}
const router = useRouter()
//
const handleSubmit = async (formEl: FormInstance | undefined) => {
const product_arr = productList.value.map((item: any) => {
return {
product_id: item.id,
nums: item.nums,
price: item.price || 0,
purchase: item.purchase || 0,
total_price: item.total_price || 0,
unit: item.unit,
mark: item.mark
}
})
await formEl.validate((valid, fields) => {
if (valid) {
apiWarehouseOrderAdd({
product_arr,
...formData
}).then((res) => {
setTimeout(() => {
router.push({
path: '/psi/purchase/purchase_order'
})
}, 2000)
})
}
})
}
const dialogProductLists = ref([])
const dialogProductShow = ref(false)
const dialogProductData = ref()
const enterStoreName = (e: any) => {
apiStoreProductLists({
store_name: e.store_name,
is_warehouse: 1,
order_type: formData.order_type,
user_id: formData.uid,
store_id: formData.store_id
// is_show: 1
}).then((res) => {
if (res.count == 1) {
const data = res.lists[0]
setData(e, data)
}
if (res.count > 1) {
dialogProductLists.value = res.lists
dialogProductShow.value = true
dialogProductData.value = e
}
})
}
//
const handleCurrentChange = (val: any[]) => {
if (val == null) {
return
}
setData(dialogProductData.value, val)
dialogProductShow.value = false
dialogProductLists.value = []
dialogProductData.value = []
}
const labelRefs = reactive<Record<string, HTMLElement>>({})
const moveFocus = (event: any, index: number, key: string) => {
const keyField = ['id', 'store_name', 'nums', 'mark']
// 38
if (event.keyCode === 38) {
if (index === 0) {
return //
}
labelRefs[index + key].blur()
nextTick(() => {
labelRefs[index - 1 + key].focus()
})
}
// 40
if (event.keyCode === 40) {
if (index === productList.value.length - 1) {
return //
}
labelRefs[index + key].blur()
nextTick(() => {
labelRefs[index + 1 + key].focus()
})
}
// 37
if (event.keyCode === 37) {
if (index === 0 && key === keyField[0]) {
return
}
labelRefs[index + key].blur()
// ,
if (key === keyField[0]) {
labelRefs[index - 1 + keyField[keyField.length - 1]].focus()
} else {
//
const preKeyIndex = keyField.findIndex((item) => item === key) - 1
nextTick(() => {
labelRefs[index + keyField[preKeyIndex]].focus()
})
}
}
// // 39
if (event.keyCode === 39) {
if (index === productList.value.length - 1 && key === keyField[keyField.length - 1]) {
return
}
labelRefs[index + key].blur()
// ,
if (key === keyField[keyField.length - 1]) {
labelRefs[index + 1 + keyField[0]].focus()
} else {
//
const nextKeyIndex = keyField.findIndex((item) => item === key) + 1
nextTick(() => {
labelRefs[index + keyField[nextKeyIndex]].focus()
})
}
}
}
//
const formRules = reactive<any>({
store_id: [
{
required: true,
message: '请选择门店',
trigger: ['blur']
}
],
arrival_time: [
{
required: true,
message: '请选择到货时间',
trigger: ['blur']
}
]
})
const delivery_list = ref([])
const getDeliveryList = () => {
apiDeliveryServiceLists({ type: 3 }).then((res) => {
delivery_list.value = res.lists
})
}
getDeliveryList()
const showProductModal = () => {
showProduct.value = true
}
const productModalKey = ref(0)
const resetUserId = (e) => {
productModalKey.value++
}
</script>

View File

@ -72,13 +72,12 @@
</el-card> </el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never"> <el-card class="!border-none" v-loading="pager.loading" shadow="never">
<router-link <router-link
v-perms="['warehousing']"
:to="{ :to="{
path: 'warehousing' path: 'purchase_order_add'
}" }"
class="ml-4" class="ml-4"
> >
<el-button type="primary"> 入库 </el-button> <el-button type="primary"> 添加 </el-button>
</router-link> </router-link>
<div class="mt-4"> <div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange"> <el-table :data="pager.lists" @selection-change="handleSelectionChange">
@ -139,7 +138,7 @@
<script lang="ts" setup name="warehouseOrderLists"> <script lang="ts" setup name="warehouseOrderLists">
import { usePaging } from '@/hooks/usePaging' import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions' import { useDictData } from '@/hooks/useDictOptions'
import { apiWarehouseOrderLists, apiWarehouseOrderDelete } from '@/api/psi/psi_order' import { apiWarehouseOrderLists, apiWarehouseOrderDelete } from '@/api/psi/purchase_order'
import { timeFormat } from '@/utils/util' import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback' import feedback from '@/utils/feedback'
// import EditPopup from './edit.vue' // import EditPopup from './edit.vue'

View File

@ -116,9 +116,8 @@
prop="financial_pm_name" prop="financial_pm_name"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column label="批次" prop="batch" show-overflow-tooltip />
<el-table-column label="数量" prop="nums" show-overflow-tooltip /> <el-table-column label="数量" prop="nums" show-overflow-tooltip />
<el-table-column label="采购价" prop="purchase" show-overflow-tooltip /> <el-table-column label="采购价" prop="price" show-overflow-tooltip />
<el-table-column label="总价" prop="total_price" show-overflow-tooltip /> <el-table-column label="总价" prop="total_price" show-overflow-tooltip />
<el-table-column label="操作时间" prop="create_time" show-overflow-tooltip /> <el-table-column label="操作时间" prop="create_time" show-overflow-tooltip />
<el-table-column label="生产期" prop="manufacture" show-overflow-tooltip /> <el-table-column label="生产期" prop="manufacture" show-overflow-tooltip />
@ -144,7 +143,7 @@ import {
apiWarehouseProductLists, apiWarehouseProductLists,
apiWarehouseProductDelete, apiWarehouseProductDelete,
apiWarehouseProductEnter apiWarehouseProductEnter
} from '@/api/psi/psi_product' } from '@/api/psi/purchase_product'
import { timeFormat } from '@/utils/util' import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback' import feedback from '@/utils/feedback'
// import EditPopup from './edit.vue' // import EditPopup from './edit.vue'