This commit is contained in:
qsh
2024-05-31 17:38:17 +08:00
parent de522af86f
commit a557255b4a
29 changed files with 675 additions and 260 deletions

View File

@@ -1,12 +1,12 @@
<template>
<el-tabs v-model="curTab" type="card" tab-position="top">
<el-tab-pane label="库存" name="1">
<el-tab-pane label="库存" name="1" v-if="checkPermi(['mall:inventory:index'])">
<InventoryDetail v-if="curTab == 1" />
</el-tab-pane>
<el-tab-pane label="库存变动记录" name="2">
<el-tab-pane label="库存变动记录" name="2" v-if="checkPermi(['mall:inventory:record'])">
<InventoryRecord v-if="curTab == 2" />
</el-tab-pane>
<el-tab-pane label="仓库" name="3">
<el-tab-pane label="仓库" name="3" v-if="checkPermi(['mall:inventory:depot'])">
<Warehouse v-if="curTab == 3" />
</el-tab-pane>
</el-tabs>
@@ -16,6 +16,7 @@
import InventoryDetail from './Comp/InventoryDetail.vue'
import Warehouse from './Comp/Warehouse.vue'
import InventoryRecord from './Comp/InventoryRecord.vue'
import { checkPermi } from '@/utils/permission'
const curTab = ref('1')
</script>

View File

@@ -15,22 +15,31 @@
<el-button type="primary" @click="openForm('create', null)">新增</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="tableList">
<el-table-column prop="brandName" label="品牌名称" />
<el-table-column prop="orderNum" label="排序" width="100px" />
<el-table-column prop="remark" label="备注" />
<el-table-column label="创建时间" prop="createTime" width="180px" />
<el-table-column label="创建人" prop="createUser" width="150px" />
<el-table v-loading="loading" :data="list">
<el-table-column prop="name" label="品牌名称" />
<el-table-column prop="sort" label="排序" width="100px" />
<el-table-column prop="description" label="备注" />
<el-table-column label="开启状态" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="创建时间"
prop="createTime"
width="180px"
:formatter="dateFormatter"
/>
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" text @click="openForm('update', scope.row)">修改</el-button>
<el-button type="danger" text @click="handleDelete(scope.row)">删除</el-button>
<el-button type="primary" text @click="openForm('update', scope.row.id)">修改</el-button>
<el-button type="danger" text @click="handleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<Pagination
v-model:limit="searchForm.pageSize"
v-model:page="searchForm.pageNum"
v-model:page="searchForm.pageNo"
:total="total"
@pagination="handleQuery"
/>
@@ -40,51 +49,56 @@
</template>
<script setup name="BrandSet">
import { DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import * as ProductBrandApi from '@/api/mall/product/brand'
import DialogBrand from './DialogBrand.vue'
const searchForm = ref({
pageNum: 1,
name: undefined,
pageNo: 1,
pageSize: 20
})
const total = ref(0)
const brandDialog = ref()
const tableList = ref([])
const list = ref([])
const loading = ref(false)
function handleQuery() {
searchForm.value.pageNum = 1
searchForm.value.pageNo = 1
getList()
}
function resetQuery() {
searchForm.value = {
name: '',
pageSize: 20,
pageNum: 1
pageNo: 1
}
getList()
}
function getList() {
tableList.value = [
{
brandId: 1,
brandName: '测试'
}
]
}
function openForm(type, info) {
brandDialog.value.open(type, info)
}
async function handleDelete(row) {
async function getList() {
loading.value = true
try {
const data = await ProductBrandApi.getBrandParam(searchForm.value)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
function openForm(type, id) {
brandDialog.value.open(type, id)
}
async function handleDelete(id) {
try {
console.log(row)
// 删除的二次确认
await message.delConfirm()
// 发起删除
// await UserApi.deleteUser(row.id)
await ProductBrandApi.deleteBrand(id)
message.success(t('common.delSuccess'))
// 刷新列表
await getList()

View File

@@ -15,24 +15,28 @@
<el-button type="primary" @click="openForm('create', null)">新增</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="tableList"
row-key="categoryId"
:tree-props="{ children: 'children' }"
>
<el-table v-loading="loading" :data="list" row-key="id" :tree-props="{ children: 'children' }">
<el-table-column prop="categoryName" label="分类名称" />
<el-table-column prop="orderNum" label="排序" width="100px" />
<el-table-column prop="remark" label="备注" />
<el-table-column label="创建时间" prop="createTime" width="180px" />
<el-table-column label="创建人" prop="createUser" width="150px" />
<el-table-column label="状态" align="center" min-width="150" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="创建时间"
prop="createTime"
width="180px"
:formatter="dateFormatter"
/>
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" text @click="openForm('update', scope.row)">修改</el-button>
<el-button type="primary" text @click="openForm('createChildren', scope.row)"
>新增</el-button
>
<el-button type="danger" text @click="handleDelete(scope.row)">删除</el-button>
<el-button type="danger" text @click="handleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -48,58 +52,61 @@
</template>
<script setup name="CategorySet">
import * as ProductCategoryApi from '@/api/mall/product/category'
import { handleTree } from '@/utils/tree'
import DialogCategory from './DialogCategory.vue'
import { dateFormatter } from '@/utils/formatTime'
import { DICT_TYPE } from '@/utils/dict'
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const searchForm = ref({
pageNum: 1,
pageSize: 20
name: undefined
})
const total = ref(0)
const categoryDialog = ref()
const tableList = ref([])
const list = ref([])
const loading = ref(false)
function handleQuery() {
searchForm.value.pageNum = 1
getList()
}
function resetQuery() {
searchForm.value = {
name: '',
pageSize: 20,
pageNum: 1
name: undefined
}
getList()
}
function getList() {
tableList.value = [
{
categoryId: 1,
categoryName: '测试',
level: 1,
children: [{ categoryId: 1001, categoryName: '二级分类', level: 2, parentCategory: '测试' }]
}
]
async function getList() {
loading.value = true
try {
const data = await ProductCategoryApi.getCategoryList(searchForm.value)
list.value = handleTree(data, 'id', 'parentId')
} finally {
loading.value = false
}
}
function openForm(type, info) {
categoryDialog.value.open(type, info)
}
async function handleDelete(row) {
async function handleDelete(id) {
try {
console.log(row)
// 删除的二次确认
await message.delConfirm()
// 发起删除
// await UserApi.deleteUser(row.id)
await ProductCategoryApi.deleteCategory(id)
message.success(t('common.delSuccess'))
// 刷新列表
await getList()
} catch {}
}
handleQuery()
</script>
<style lang="scss" scoped></style>

View File

@@ -1,5 +1,5 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="800px">
<Dialog :title="dialogTitle" v-model="dialogVisible" width="500px">
<el-form
ref="formRef"
v-loading="formLoading"
@@ -7,11 +7,17 @@
:rules="formRules"
label-width="80px"
>
<el-form-item label="品牌名称" prop="brandName">
<el-input v-model="formData.brandName" placeholder="请输入品牌名称" />
<el-form-item label="品牌名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入品牌名称" />
</el-form-item>
<el-form-item label="排序" prop="orderNum">
<el-input v-model="formData.orderNum" placeholder="请输入排序" type="number" :min="0" />
<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="status">
<el-radio-group v-model="formData.status">
<el-radio :label="0"> 启用 </el-radio>
<el-radio :label="1"> 禁用 </el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
@@ -29,6 +35,8 @@
</Dialog>
</template>
<script name="DialogBrand" setup>
import * as ProductBrandApi from '@/api/mall/product/brand'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
@@ -37,27 +45,27 @@ const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref({
brandName: '',
orderNum: 1,
name: '',
sort: 1,
status: 0,
remark: ''
})
const formRules = reactive({
brandName: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type, info) => {
const open = async (type, id) => {
dialogVisible.value = true
dialogTitle.value = type == 'update' ? '修改品牌' : '新增品牌'
formType.value = type
resetForm()
// 修改时,设置数据
if (info.brandId) {
if (id) {
formLoading.value = true
try {
formData.value = { ...info }
// formData.value = await UserApi.getUser(id)
formData.value = await ProductBrandApi.getBrand(id)
} finally {
formLoading.value = false
}
@@ -75,12 +83,11 @@ const submitForm = async () => {
// 提交请求
formLoading.value = true
try {
// const data = formData.value as unknown as UserApi.UserVO
if (formType.value === 'create') {
// await UserApi.createUser(data)
await ProductBrandApi.createBrand(formData.value)
message.success(t('common.createSuccess'))
} else {
// await UserApi.updateUser(data)
await ProductBrandApi.updateBrand(formData.value)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
@@ -94,8 +101,9 @@ const submitForm = async () => {
/** 重置表单 */
const resetForm = () => {
formData.value = {
brandName: '',
orderNum: 1,
name: '',
sort: 1,
status: 0,
remark: ''
}
formRef.value?.resetFields()

View File

@@ -1,5 +1,5 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="800px">
<Dialog :title="dialogTitle" v-model="dialogVisible" width="500px">
<el-form
ref="formRef"
v-loading="formLoading"
@@ -10,11 +10,17 @@
<el-form-item v-if="formData.level > 1" label="上级分类">
<el-input v-model="formData.parentCategory" disabled />
</el-form-item>
<el-form-item label="分类名称" prop="categoryName">
<el-input v-model="formData.categoryName" placeholder="请输入分类名称" />
<el-form-item label="分类名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入分类名称" />
</el-form-item>
<el-form-item label="排序" prop="orderNum">
<el-input v-model="formData.orderNum" placeholder="请输入排序" type="number" :min="0" />
<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="status">
<el-radio-group v-model="formData.status">
<el-radio :label="0"> 启用 </el-radio>
<el-radio :label="1"> 禁用 </el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
@@ -32,6 +38,8 @@
</Dialog>
</template>
<script name="DialogCategory" setup>
import * as ProductCategoryApi from '@/api/mall/product/category'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
@@ -40,12 +48,13 @@ const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref({
categoryName: '',
orderNum: 1,
name: '',
sort: 1,
status: 0,
remark: ''
})
const formRules = reactive({
categoryName: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref
@@ -56,16 +65,15 @@ const open = async (type, info) => {
formType.value = type
resetForm()
// 修改时,设置数据
if (info.categoryId) {
if (info?.id) {
formLoading.value = true
try {
if (type == 'update') {
formData.value = { ...info }
formData.value = await ProductCategoryApi.getCategory(info.id)
} else {
formData.value.level = info.level + 1
formData.value.parentCategory = info.categoryName
formData.value.parentCategory = info.name
}
// formData.value = await UserApi.getUser(id)
} finally {
formLoading.value = false
}
@@ -83,12 +91,11 @@ const submitForm = async () => {
// 提交请求
formLoading.value = true
try {
// const data = formData.value as unknown as UserApi.UserVO
if (formType.value === 'create') {
// await UserApi.createUser(data)
await ProductCategoryApi.createCategory(formData.value)
message.success(t('common.createSuccess'))
} else {
// await UserApi.updateUser(data)
await ProductCategoryApi.updateCategory(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
@@ -102,8 +109,9 @@ const submitForm = async () => {
/** 重置表单 */
const resetForm = () => {
formData.value = {
categoryName: '',
orderNum: 1,
name: '',
sort: 1,
status: 0,
remark: ''
}
formRef.value?.resetFields()

View File

@@ -1,22 +1,22 @@
<template>
<el-tabs v-model="tabIndex" type="border-card">
<el-tab-pane label="产品属性" :name="0">
<FieldProduct />
<el-tab-pane label="产品属性" :name="0" v-if="checkPermi(['mall:setting:prod'])">
<FieldProduct v-if="tabIndex == 0" />
</el-tab-pane>
<el-tab-pane label="分类设置" :name="1">
<CategorySet />
<el-tab-pane label="分类设置" :name="1" v-if="checkPermi(['mall:setting:category'])">
<CategorySet v-if="tabIndex == 1" />
</el-tab-pane>
<el-tab-pane label="品牌设置" :name="2">
<BrandSet />
<el-tab-pane label="品牌设置" :name="2" v-if="checkPermi(['mall:setting:brand'])">
<BrandSet v-if="tabIndex == 2" />
</el-tab-pane>
<el-tab-pane label="供应商设置" :name="3">
<SupplierSet />
<el-tab-pane label="供应商设置" :name="3" v-if="checkPermi(['mall:setting:supplier'])">
<SupplierSet v-if="tabIndex == 3" />
</el-tab-pane>
<el-tab-pane label="常规设置" :name="4">
<GeneralSet />
<el-tab-pane label="常规设置" :name="4" v-if="checkPermi(['mall:setting:general'])">
<GeneralSet v-if="tabIndex == 4" />
</el-tab-pane>
<el-tab-pane label="消息通知" :name="9">
<MsgSend />
<el-tab-pane label="消息通知" :name="9" v-if="checkPermi(['mall:setting:msg'])">
<MsgSend v-if="tabIndex == 9" />
</el-tab-pane>
</el-tabs>
</template>
@@ -28,6 +28,7 @@ import MsgSend from './Comp/MsgSend.vue'
import CategorySet from './Comp/CategorySet.vue'
import BrandSet from './Comp/BrandSet.vue'
import SupplierSet from './Comp/SupplierSet.vue'
import { checkPermi } from '@/utils/permission'
const tabIndex = ref(0)
</script>

View File

@@ -16,6 +16,7 @@
placeholder="请选择分类"
filterable
show-all-levels
style="width: 100%"
/>
</el-form-item>
</el-col>
@@ -44,15 +45,15 @@
</el-form-item>
</el-col>
<el-col :span="12" :offset="0">
<el-form-item label="主图" prop="picUrl">
<UploadImg v-model="form.picUrl" height="100px" width="100px" />
<el-form-item label="主图" prop="mainImage">
<UploadImg v-model="form.mainImage" height="100px" width="100px" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24" :offset="0">
<el-form-item label="轮播图" prop="sliderPicUrls">
<UploadImgs v-model:modelValue="form.sliderPicUrls" height="100px" width="100px" />
<el-form-item label="轮播图" prop="carouselImages">
<UploadImgs v-model="form.carouselImages" height="100px" width="100px" />
</el-form-item>
</el-col>
</el-row>
@@ -60,7 +61,7 @@
<el-col :span="24" :offset="0">
<el-form-item label="商品规格">
<el-button @click="handleAddSpec">添加规格</el-button>
<el-col v-for="(item, index) in form.specsList" :key="index">
<el-col v-for="(item, index) in form.productSpecList" :key="index">
<div>
<el-text class="mx-1">属性名</el-text>
<el-tag class="mx-1" closable type="success" @close="handleCloseProperty(index)"
@@ -109,7 +110,7 @@
</template>
</el-table-column>
<el-table-column
v-for="col in form.specsList"
v-for="col in form.productSpecList"
:prop="col.id"
:key="col.id"
:label="col.name"
@@ -135,10 +136,10 @@
</div>
</el-tab-pane>
<el-tab-pane label="详细信息" name="detail">
<Editor v-model:modelValue="form.description" />
<Editor v-model:modelValue="form.detailInfo" />
</el-tab-pane>
</el-tabs>
<ProductAttributesAddForm ref="attributesAddFormRef" :propertyList="form.specsList" />
<ProductAttributesAddForm ref="attributesAddFormRef" :propertyList="form.productSpecList" />
</template>
<script setup>
@@ -148,27 +149,33 @@ const message = useMessage() // 消息弹窗
const tabName = ref('basic')
const form = ref({
name: '',
category: '',
brand: '',
intro: '',
picUrl: '',
sliderPicUrls: [],
specsList: [],
productName: undefined,
productCategory: undefined,
productBrand: undefined,
productIntro: undefined,
mainImage: '',
carouselImages: [],
productSpecList: [],
skuList: [],
description: null
detailInfo: null
})
const rules = ref({})
const attributesAddFormRef = ref() // 添加商品属性表单
const opts = {
brand: [],
productCategory: []
brand: [{ value: 1, label: '品牌1' }],
productCategory: [
{
id: 1,
label: '分类1',
children: [{ id: 2, label: '子分类1' }]
}
]
}
/** 删除属性*/
function handleCloseProperty(index) {
form.value.specsList?.splice(index, 1)
form.value.productSpecList?.splice(index, 1)
}
const attributeIndex = ref(null)
@@ -186,7 +193,7 @@ async function handleInputConfirm(index, propertyId) {
try {
// const id = await PropertyApi.createPropertyValue({ propertyId, name: inputValue.value })
const id = propertyId || parseInt(Math.random() * 1000000)
form.value.specsList[index].values.push({ id, name: inputValue.value })
form.value.productSpecList[index].values.push({ id, name: inputValue.value })
message.success('添加成功')
} catch {
message.error('添加失败,请重试')
@@ -199,7 +206,7 @@ async function handleInputConfirm(index, propertyId) {
function getTableList() {
let list = []
form.value.specsList.map((item) => {
form.value.productSpecList.map((item) => {
if (!list.length) {
item.values.map((it) => {
const obj = {}
@@ -238,8 +245,7 @@ const setInputRef = (el) => {
}
function handleAddSpec() {
const id = parseInt(Math.random() * 1000)
form.value.specsList.push({ name: `测试规格${id}`, id, values: [] })
attributesAddFormRef.value.open()
}
function onSubmit() {
@@ -249,19 +255,19 @@ function onSubmit() {
onMounted(() => {
if (route.query?.id) {
form.value = {
name: '商品名称哦~'
productName: '商品名称哦~'
}
} else {
form.value = {
name: '',
category: '',
brand: '',
intro: '',
picUrl: '',
sliderPicUrls: [],
specsList: [],
productName: undefined,
productCategory: undefined,
productBrand: undefined,
productIntro: undefined,
mainImage: 'https://ss-cloud.ahduima.com/1001/1796426117251600384.png',
carouselImages: ['https://ss-cloud.ahduima.com/1001/1796426117251600384.png'],
productSpecList: [],
skuList: [],
description: null
detailInfo: null
}
}
})

View File

@@ -38,9 +38,11 @@
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"> 搜索 </el-button>
<el-button @click="resetQuery"> 重置 </el-button>
<el-button plain type="primary" @click="openForm"> 新增 </el-button>
<el-button @click="handleQuery" v-hasPermi="['mall:prod:search']"> 搜索 </el-button>
<el-button @click="resetQuery" v-hasPermi="['mall:prod:reset']"> 重置 </el-button>
<el-button plain type="primary" @click="openForm" v-hasPermi="['mall:prod:add']">
新增
</el-button>
</el-form-item>
</el-form>
@@ -71,8 +73,22 @@
<el-table-column fixed="right" label="操作" min-width="80">
<template #default="{ row }">
<!-- TODO详情可以后面点做哈 -->
<el-button link type="primary" @click="openForm(row.productId)"> 修改 </el-button>
<el-button link type="danger" @click="handleDelete(row.productId)"> 删除 </el-button>
<el-button
link
type="primary"
@click="openForm(row.productId)"
v-hasPermi="['mall:prod:update']"
>
修改
</el-button>
<el-button
link
type="danger"
@click="handleDelete(row.productId)"
v-hasPermi="['mall:prod:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>

View File

@@ -1,16 +1,13 @@
<template>
<div>
<!-- 搜索工作栏 -->
<Search
:schema="allSchemas.searchSchema"
labelWidth="0"
expand
expand-field="supplier"
@search="setSearchParams"
@reset="setSearchParams"
>
<Search :schema="allSchemas.searchSchema" labelWidth="0">
<template #actionMore>
<el-button type="primary" @click="handleAdd">发起采购</el-button>
<el-button @click="getList" v-hasPermi="['mall:purchase:search']"> 搜索 </el-button>
<el-button @click="resetQuery" v-hasPermi="['mall:purchase:reset']"> 重置 </el-button>
<el-button type="primary" @click="handleAdd" v-hasPermi="['mall:purchase:add']">
发起采购
</el-button>
</template>
</Search>
<!-- 列表 -->
@@ -31,11 +28,32 @@
/>
<el-table-column label="操作" width="150px" fixed="right">
<template #default="{ row }">
<el-button type="primary" v-if="row.status == 1" link @click="handleAudit(row)"
>采购审核</el-button
<el-button
type="primary"
v-if="row.status == 1"
link
@click="handleAudit(row)"
v-hasPermi="['mall:purchase:audit']"
>
<el-button v-else type="primary" link @click="purchaseAgain(row)">再次采购</el-button>
<el-button type="primary" link @click="handleDetail(row)">详情</el-button>
采购审核
</el-button>
<el-button
v-else
type="primary"
link
@click="purchaseAgain(row)"
v-hasPermi="['mall:purchase:readd']"
>
再次采购
</el-button>
<el-button
type="primary"
link
@click="handleDetail(row)"
v-hasPermi="['mall:purchase:detail']"
>
详情
</el-button>
</template>
</el-table-column>
</SSTable>
@@ -59,7 +77,19 @@ const tableObject = ref({
pageSize: 20,
currentPage: 1
})
const setSearchParams = function () {
function resetQuery() {
queryParams.value = {
productName: undefined,
productBrand: undefined,
productCategory: undefined,
pageNo: 1,
pageSize: 10
}
getList()
}
const getList = function () {
tableObject.value.tableList = [
{ name: '测试', status: 1, statusName: '审核中', supplier: '林氏木业', purchaseCount: 10 },
{ name: '测试2', status: 2, statusName: '已通过', supplier: '张氏木业', purchaseCount: 1 },