商城联调

salary
qsh 4 months ago
parent 94943df4f9
commit 86ffb5a9c9
  1. 40
      src/api/mall/warehouse/index.js
  2. 103
      src/views/MiniMall/Inventory/Comp/DialogWarehouse.vue
  3. 25
      src/views/MiniMall/Inventory/Comp/InventoryDetail.data.js
  4. 156
      src/views/MiniMall/Inventory/Comp/InventoryDetail.vue
  5. 180
      src/views/MiniMall/Inventory/Comp/InventoryRecord.vue
  6. 146
      src/views/MiniMall/Inventory/Comp/Warehouse.vue
  7. 2
      src/views/MiniMall/MallSet/Comp/BrandSet.vue
  8. 4
      src/views/MiniMall/MallSet/Comp/GeneralSet.vue
  9. 25
      src/views/MiniMall/Purchase/Comp/DialogAdd.vue
  10. 8
      src/views/MiniMall/Purchase/index.vue

@ -0,0 +1,40 @@
import request from '@/config/axios'
// 查询列表
export const getWarehousePage = async (params) => {
return await request.get({ url: '/admin-api/crm/erp-warehouse/page', params })
}
// 新增
export const createWarehouse = async (data) => {
return await request.post({ url: '/admin-api/crm/erp-warehouse/create', data: data })
}
// 修改
export const updateWarehouse = async (params) => {
return await request.put({ url: '/admin-api/crm/erp-warehouse/update', data: params })
}
// 删除
export const deleteWarehouse = async (id) => {
return await request.delete({ url: '/admin-api/crm/erp-warehouse/delete?id=' + id })
}
// 获取仓库
export const getWarehouse = async (id) => {
return await request.get({ url: '/admin-api/crm/erp-warehouse/get?id=' + id })
}
// 获取仓库列表
export const getSimpleWarehouseList = async () => {
return await request.get({ url: '/admin-api/crm/erp-warehouse/simple-list' })
}
// 获取库存
export const getInventoryList = async (params) => {
return await request.get({ url: '/admin-api/crm/erp-inventory/page', params })
}
// 获取库存变动记录
export const getInventoryRecord = async (params) => {
return await request.get({ url: '/admin-api/crm/erp-inventory-record/page', params })
}

@ -0,0 +1,103 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="500px">
<el-form
ref="formRef"
v-loading="formLoading"
:model="formData"
:rules="formRules"
label-width="80px"
>
<el-form-item label="仓库名称" prop="warehouseName">
<el-input v-model="formData.warehouseName" placeholder="请输入仓库名称" />
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input v-model="formData.sort" placeholder="请输入排序" type="number" :min="0" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
type="textarea"
v-model="formData.remark"
placeholder="请输入备注"
:autosize="{ minRows: 4, maxRows: 8 }"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button :disabled="formLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script name="DialogWarehouse" setup>
import * as WarehouseApi from '@/api/mall/warehouse'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
name: '',
sort: 1,
remark: ''
})
const formRules = reactive({
warehouseName: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type, id) => {
dialogVisible.value = true
dialogTitle.value = type == 'update' ? '修改仓库' : '新增仓库'
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await WarehouseApi.getWarehouse(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef.value) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
if (formType.value === 'create') {
await WarehouseApi.createWarehouse(formData.value)
message.success(t('common.createSuccess'))
} else {
await WarehouseApi.updateWarehouse(formData.value)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
name: '',
sort: 1,
remark: ''
}
formRef.value?.resetFields()
}
</script>

@ -1,37 +1,18 @@
// import { CrudSchema } from '@/hooks/web/useCrudSchemas'
// CrudSchema:https://doc.iocoder.cn/vue3/crud-schema/
const crudSchemas = reactive([ const crudSchemas = reactive([
{ {
label: '产品名称', label: '产品名称',
field: 'name', field: 'productName',
isSearch: true,
isTable: true isTable: true
}, },
{ {
label: '规格名称', label: '规格名称',
field: 'specsName', field: 'specsName',
isSearch: true,
isTable: true isTable: true
}, },
{ {
label: '仓库', label: '仓库',
field: 'warehouse', field: 'warehouseName',
isSearch: true, isTable: true
isTable: true,
search: {
component: 'Select',
api: () => [
{ label: '自营仓', value: 1 },
{ label: '供应商仓', value: 2 }
],
componentProps: {
optionsAlias: {
labelField: 'label',
valueField: 'value'
}
}
}
} }
]) ])
export const { allSchemas } = useCrudSchemas(crudSchemas) export const { allSchemas } = useCrudSchemas(crudSchemas)

@ -1,21 +1,56 @@
<template> <template>
<div> <div>
<!-- 搜索工作栏 --> <el-form inline :model="searchForm" class="-mb-15px" label-width="0">
<Search <el-form-item>
:schema="allSchemas.searchSchema" <el-select
labelWidth="0" v-model="searchForm.productId"
expand placeholder="选择产品"
expand-field="name" clearable
@search="setSearchParams" filterable
@reset="setSearchParams" @change="changeProd"
>
<el-option
v-for="item in opts.product"
:key="item.productId"
:label="item.productName"
:value="item.productId"
/> />
<!-- 列表 --> </el-select>
<SSTable </el-form-item>
class="mt-20px" <el-form-item>
v-model:tableObject="tableObject" <el-select
:tableColumns="allSchemas.tableColumns" v-model="searchForm.specsId"
@get-list="getTableList" placeholder="选择规格"
clearable
filterable
:disabled="!searchForm.productId"
> >
<el-option
v-for="item in opts.spec"
:key="item.specsId"
:label="item.specsName"
:value="item.specsId"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="searchForm.warehouseId" placeholder="仓库" clearable filterable>
<el-option
v-for="item in opts.warehouse"
:key="item.warehouseId"
:label="item.warehouseName"
:value="item.warehouseId"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleSearch"> 搜索 </el-button>
<el-button @click="resetQuery"> 重置 </el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<el-table v-loading="loading" class="mt-20px" :data="tableList" border>
<el-table-column <el-table-column
v-for="item in allSchemas.tableColumns" v-for="item in allSchemas.tableColumns"
:key="item.table?.field || item.field" :key="item.table?.field || item.field"
@ -25,36 +60,89 @@
min-width="150px" min-width="150px"
showOverflowTooltip showOverflowTooltip
/> />
<el-table-column prop="count" label="库存数量"> <el-table-column prop="num" label="库存数量" />
<!-- <template #default="{ row }"> </el-table>
<el-button v-if="row.count" type="primary" text @click="handleDetail">{{ <!-- 分页 -->
row.count <Pagination
}}</el-button> v-model:limit="searchForm.pageSize"
<span v-else>{{ row.count }}</span> v-model:page="searchForm.pageNo"
</template> --> :total="total"
</el-table-column> @pagination="getList"
</SSTable> />
</div> </div>
</template> </template>
<script setup> <script setup name="InventoryDetail">
import { allSchemas } from './InventoryDetail.data.js' import { allSchemas } from './InventoryDetail.data.js'
import { getSimpleWarehouseList, getInventoryList } from '@/api/mall/warehouse'
import { getSimpleProductList } from '@/api/mall/product'
const searchForm = ref({
productId: undefined,
specsId: undefined,
warehouseId: undefined,
pageNo: 1,
pageSize: 20
})
const tableObject = ref({ const opts = ref({
tableList: [], product: [],
loading: false, spec: [],
total: 1, warehouse: []
pageSize: 20,
currentPage: 1
}) })
function setSearchParams() { const loading = ref(false)
tableObject.value.tableList = [] const total = ref(0)
const tableList = ref([])
function resetQuery() {
searchForm.value = {
productId: undefined,
specsId: undefined,
warehouseId: undefined,
pageNo: 1,
pageSize: 20
}
} }
function getTableList() { function getOptions() {
tableObject.value.tableList = [] getSimpleProductList().then((data) => {
opts.value.product = data
})
getSimpleWarehouseList().then((data) => {
opts.value.warehouse = data
})
}
function handleSearch() {
searchForm.value.pageNo = 1
getList()
}
function changeProd(val) {
if (val) {
opts.value.spec = opts.value.product.find((it) => it.productId == val).productSpecList
} else {
opts.value.spec = []
}
searchForm.value.specsId = undefined
} }
async function getList() {
loading.value = true
try {
const data = await getInventoryList(searchForm.value)
tableList.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
onMounted(() => {
getOptions()
handleSearch()
})
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

@ -1,90 +1,150 @@
<template> <template>
<div> <div>
<Search <el-form inline :model="searchForm" class="-mb-15px" label-width="0">
:schema="allSchemas.searchSchema" <el-form-item>
labelWidth="0" <el-select
@search="setSearchParams" v-model="searchForm.productId"
@reset="setSearchParams" placeholder="选择产品"
clearable
filterable
@change="changeProd"
>
<el-option
v-for="item in opts.product"
:key="item.productId"
:label="item.productName"
:value="item.productId"
/> />
</el-select>
</el-form-item>
<el-form-item>
<el-select
v-model="searchForm.specsId"
placeholder="选择规格"
clearable
filterable
:disabled="!searchForm.productId"
>
<el-option
v-for="item in opts.spec"
:key="item.specsId"
:label="item.specsName"
:value="item.specsId"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="searchForm.warehouseId" placeholder="仓库" clearable filterable>
<el-option
v-for="item in opts.warehouse"
:key="item.warehouseId"
:label="item.warehouseName"
:value="item.warehouseId"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleSearch"> 搜索 </el-button>
<el-button @click="resetQuery"> 重置 </el-button>
</el-form-item>
</el-form>
<el-table class="mt-20px" :data="tableList" border> <el-table class="mt-20px" :data="tableList" border>
<el-table-column type="index" width="50px" /> <el-table-column type="index" width="50px" />
<el-table-column prop="" label="产品名称" /> <el-table-column prop="" label="产品名称" />
<el-table-column prop="" label="规格" /> <el-table-column prop="" label="规格" />
<el-table-column prop="" label="变动类型" /> <el-table-column label="变动类型">
<el-table-column prop="" label="数量" /> <template #default="{ row }">
<el-table-column prop="" label="金额" /> {{ ['', '入库', '出库'][row.changeType] }}
<el-table-column prop="" label="变动时间" /> </template>
<el-table-column prop="" label="变动人员" /> </el-table-column>
<el-table-column prop="num" label="数量" />
<el-table-column prop="money" label="金额" />
<el-table-column prop="changeTime" label="变动时间" :formatter="dateFormatter" />
<el-table-column prop="changeUser" label="变动人员" />
<el-table-column prop="" label="所属仓库" /> <el-table-column prop="" label="所属仓库" />
<el-table-column prop="" label="备注" /> <el-table-column prop="remark" label="备注" />
</el-table> </el-table>
<Pagination <Pagination
v-model:limit="searchForm.pageSize" v-model:limit="searchForm.pageSize"
v-model:page="searchForm.currentPage" v-model:page="searchForm.pageNo"
:total="total" :total="total"
@pagination="getList" @pagination="getList"
/> />
</div> </div>
</template> </template>
<script setup> <script setup name="InventoryDetail">
const crudSchemas = ref([ import { dateFormatter } from '@/utils/formatTime'
{ import { getSimpleWarehouseList, getInventoryRecord } from '@/api/mall/warehouse'
label: '仓库名称', import { getSimpleProductList } from '@/api/mall/product'
field: 'warehouse',
isSearch: true,
search: {
component: 'Select',
api: () => [
{ label: '自营仓', value: 1 },
{ label: '供应商仓', value: 2 }
],
componentProps: {
optionsAlias: {
labelField: 'label',
valueField: 'value'
}
}
}
},
{
label: '变动类型',
field: 'type',
isSearch: true,
search: {
component: 'Select',
api: () => [
{ label: '入库', value: 1 },
{ label: '出库', value: 2 },
{ label: '售后', value: 3 }
],
componentProps: {
optionsAlias: {
labelField: 'label',
valueField: 'value'
}
}
}
}
])
const { allSchemas } = useCrudSchemas(crudSchemas.value)
const searchForm = ref({ const searchForm = ref({
pageSize: 20, pproductId: undefined,
currentPage: 1 specsId: undefined,
warehouseId: undefined,
pageNo: 1,
pageSize: 20
}) })
const tableList = ref([]) const opts = ref({
product: [],
spec: [],
warehouse: []
})
const loading = ref(false)
const total = ref(0) const total = ref(0)
const tableList = ref([])
function getList() { function resetQuery() {
tableList.value = [] searchForm.value = {
productId: undefined,
specsId: undefined,
warehouseId: undefined,
pageNo: 1,
pageSize: 20
}
}
function getOptions() {
getSimpleProductList().then((data) => {
opts.value.product = data
})
getSimpleWarehouseList().then((data) => {
opts.value.warehouse = data
})
}
function handleSearch() {
searchForm.value.pageNo = 1
getList()
} }
function setSearchParams() { function changeProd(val) {
tableList.value = [] if (val) {
opts.value.spec = opts.value.product.find((it) => it.productId == val).productSpecList
} else {
opts.value.spec = []
} }
searchForm.value.specsId = undefined
}
async function getList() {
loading.value = true
try {
const data = await getInventoryRecord(searchForm.value)
tableList.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
onMounted(() => {
getOptions()
handleSearch()
})
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

@ -1,75 +1,115 @@
<template> <template>
<div> <div>
<!-- 搜索工作栏 --> <el-form inline :model="searchForm" class="-mb-15px" label-width="0" @submit.prevent>
<Search <el-form-item>
:schema="allSchemas.searchSchema" <el-input
labelWidth="0" v-model="searchForm.warehouseName"
@search="setSearchParams" placeholder="仓库名称"
@reset="setSearchParams" @keyup.enter="handleSearch"
/> />
<!-- 列表 --> </el-form-item>
<SSTable <el-form-item>
class="mt-20px" <el-button @click="handleSearch"> 搜索 </el-button>
v-model:tableObject="tableObject" <el-button @click="resetQuery"> 重置 </el-button>
:tableColumns="allSchemas.tableColumns" <el-button type="primary" @click="openForm('create', null)"> 新增 </el-button>
@get-list="getTableList" </el-form-item>
> </el-form>
<el-table-column type="index" width="80px" />
<el-table-column <el-table class="mt-20px" :data="tableList" border>
v-for="item in allSchemas.tableColumns" <el-table-column type="index" width="50px" />
:key="item.field" <el-table-column prop="warehouseName" label="仓库名称" />
:prop="item.field" <el-table-column prop="sort" label="排序" />
:label="item.label" <el-table-column prop="remark" label="备注" />
/> <el-table-column label="操作" width="120px">
<el-table-column label="操作" width="200px">
<template #default="{ row }"> <template #default="{ row }">
<el-button type="primary" text :disabled="row.default">修改</el-button> <el-button
<el-button type="danger" text :disabled="row.default" @click="remove(row)" type="primary"
>删除</el-button style="padding: 0"
text
@click="openForm('update', row.warehouseId)"
> >
修改
</el-button>
<el-button type="danger" style="padding: 0" text @click="handleRemove(row.warehouseId)">
删除
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</SSTable> </el-table>
<Pagination
v-model:limit="searchForm.pageSize"
v-model:page="searchForm.pageNo"
:total="total"
@pagination="getList"
/>
<DialogWarehouse ref="warehouseDialog" @success="handleSearch" />
</div> </div>
</template> </template>
<script setup> <script setup name="Warehouse">
const crudSchemas = ref([ import DialogWarehouse from './DialogWarehouse.vue'
{ import * as WarehouseApi from '@/api/mall/warehouse'
label: '仓库名称',
field: 'name',
isSearch: true,
isTable: true
}
])
const { allSchemas } = useCrudSchemas(crudSchemas.value) const message = useMessage() //
const { t } = useI18n() //
const tableObject = ref({ const searchForm = ref({
tableList: [], warehouseName: undefined,
loading: false, pageNo: 1,
total: 1, pageSize: 20
pageSize: 20,
currentPage: 1
}) })
function setSearchParams() { const loading = ref(false)
tableObject.value.tableList = [ const total = ref(0)
{ name: '自营仓', default: true }, const tableList = ref([])
{ name: '供应商仓', default: true }
] function resetQuery() {
searchForm.value = {
warehouseName: undefined,
pageNo: 1,
pageSize: 20
}
}
function handleSearch() {
searchForm.value.pageNo = 1
getList()
}
async function getList() {
loading.value = true
try {
const data = await WarehouseApi.getWarehousePage(searchForm.value)
tableList.value = data.list
total.value = data.total
} finally {
loading.value = false
}
} }
function getTableList() { const warehouseDialog = ref()
tableObject.value.tableList = [
{ name: '自营仓', default: true }, function openForm(type, id) {
{ name: '供应商仓', default: true } warehouseDialog.value.open(type, id)
]
} }
function remove(row) { async function handleRemove(id) {
console.log(row) try {
//
await message.delConfirm()
//
await WarehouseApi.deleteWarehouse(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch (err) {
console.log(err)
}
} }
onMounted(() => {
handleSearch()
})
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<el-form ref="queryForm" :model="searchForm" label-width="0" inline> <el-form ref="queryForm" :model="searchForm" label-width="0" inline @submit.prevent>
<el-form-item> <el-form-item>
<el-input <el-input
v-model="searchForm.name" v-model="searchForm.name"

@ -2,8 +2,8 @@
<el-form :model="form" ref="formRef" label-width="auto"> <el-form :model="form" ref="formRef" label-width="auto">
<el-form-item label="采购申请自动通过"> <el-form-item label="采购申请自动通过">
<el-radio-group v-model="form.autoAuditPurchase"> <el-radio-group v-model="form.autoAuditPurchase">
<el-radio :label="0"> </el-radio> <el-radio :label="true"> </el-radio>
<el-radio :label="1"> </el-radio> <el-radio :label="false"> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>

@ -67,9 +67,9 @@
> >
<el-option <el-option
v-for="item in warehouseOptions" v-for="item in warehouseOptions"
:key="item.value" :key="item.warehouseId"
:label="item.label" :label="item.warehouseName"
:value="item.value" :value="item.warehouseId"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -94,6 +94,11 @@
<script setup> <script setup>
import * as PurchaseApi from '@/api/mall/purchase' import * as PurchaseApi from '@/api/mall/purchase'
import * as WarehouseApi from '@/api/mall/warehouse'
const { t } = useI18n() //
const message = useMessage() //
const props = defineProps({ const props = defineProps({
opts: { opts: {
type: Object, type: Object,
@ -101,7 +106,8 @@ const props = defineProps({
return { return {
product: [], product: [],
spec: [], spec: [],
supplier: [] supplier: [],
warehouse: []
} }
} }
} }
@ -129,13 +135,16 @@ const rules = {
unitPrice: { required: true, message: '采购单价不可为空', trigger: 'change,blur' } unitPrice: { required: true, message: '采购单价不可为空', trigger: 'change,blur' }
} }
const warehouseOptions = ref([ const warehouseOptions = ref([])
{ label: '自营仓', value: 1 }, function getOptions() {
{ label: '供应商仓', value: 2 } WarehouseApi.getSimpleWarehouseList().then((data) => {
]) warehouseOptions.value = data
})
}
const open = (val) => { const open = (val) => {
dialogVisible.value = true dialogVisible.value = true
getOptions()
form.value = { ...val } || { form.value = { ...val } || {
productId: undefined, productId: undefined,
specsId: undefined, specsId: undefined,

@ -47,6 +47,8 @@
<el-date-picker <el-date-picker
v-model="queryParams.applyTime" v-model="queryParams.applyTime"
type="daterange" type="daterange"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
range-separator="-" range-separator="-"
start-placeholder="申请时间" start-placeholder="申请时间"
end-placeholder="申请时间" end-placeholder="申请时间"
@ -56,6 +58,8 @@
<el-date-picker <el-date-picker
v-model="queryParams.checkTime" v-model="queryParams.checkTime"
type="daterange" type="daterange"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
range-separator="-" range-separator="-"
start-placeholder="审核时间" start-placeholder="审核时间"
end-placeholder="审核时间" end-placeholder="审核时间"
@ -81,11 +85,11 @@
:formatter="item.formatter" :formatter="item.formatter"
showOverflowTooltip showOverflowTooltip
/> />
<el-table-column label="操作" width="150px" fixed="right"> <el-table-column label="操作" width="240px" fixed="right">
<template #default="{ row }"> <template #default="{ row }">
<el-button <el-button
type="primary" type="primary"
v-if="row.status == 1" v-if="row.auditStatus == 1"
link link
@click="handleAudit(row)" @click="handleAudit(row)"
v-hasPermi="['mall:purchase:audit']" v-hasPermi="['mall:purchase:audit']"

Loading…
Cancel
Save