商品管理初始界面结构设计

This commit is contained in:
puhui999 2023-04-24 11:42:44 +08:00
parent c14b5c5bff
commit a0014bed65
7 changed files with 608 additions and 4 deletions

View File

@ -345,6 +345,29 @@ const remainingRouter: AppRouteRecordRaw[] = [
meta: { title: '商品属性值', icon: '', activeMenu: '/product/property' }
}
]
},
{
path: '/product',
component: Layout,
name: 'ProductManagementEdit',
meta: {
hidden: true
},
children: [
{
path: 'productManagementAdd',
component: () => import('@/views/mall/product/management/addForm.vue'),
name: 'ProductManagementAdd',
meta: {
noCache: true,
hidden: true,
canTo: true,
icon: 'ep:edit',
title: '添加商品',
activeMenu: '/product/product-management'
}
}
]
}
]

View File

@ -0,0 +1,53 @@
<template>
<ContentWrap v-loading="formLoading">
<el-tabs v-model="activeName">
<el-tab-pane label="商品信息" name="basicInfo">
<BasicInfoForm ref="basicInfoRef" />
</el-tab-pane>
<el-tab-pane label="商品详情" name="description">
<DescriptionForm ref="DescriptionRef" />
</el-tab-pane>
<el-tab-pane label="其他设置" name="otherSettings">
<OtherSettingsForm ref="otherSettingsRef" />
</el-tab-pane>
</el-tabs>
<el-form>
<el-form-item style="float: right">
<el-button :loading="formLoading" type="primary" @click="submitForm">保存</el-button>
<el-button @click="close">返回</el-button>
</el-form-item>
</el-form>
</ContentWrap>
</template>
<script lang="ts" name="ProductManagementForm" setup>
import { useTagsViewStore } from '@/store/modules/tagsView'
import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
// const { t } = useI18n() //
// const message = useMessage() //
const { push, currentRoute } = useRouter() //
// const { query } = useRoute() //
const { delView } = useTagsViewStore() //
const formLoading = ref(false) // 12
const activeName = ref('otherSettings') // Tag
const basicInfoRef = ref<ComponentRef<typeof BasicInfoForm>>()
const DescriptionRef = ref<ComponentRef<typeof DescriptionForm>>()
/** 获得详情 */
const getDetail = async () => {}
/** 提交按钮 */
const submitForm = async () => {}
/** 关闭按钮 */
const close = () => {
delView(unref(currentRoute))
push('/product/product-management')
}
/** 初始化 */
onMounted(() => {
getDetail()
})
</script>

View File

@ -0,0 +1,191 @@
<template>
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="商品名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入商品名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商品分类" prop="categoryId">
<el-tree-select
v-model="formData.categoryId"
:data="[]"
:props="defaultProps"
check-strictly
node-key="id"
placeholder="请选择商品分类"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商品关键字" prop="keyword">
<el-input v-model="formData.keyword" placeholder="请输入商品关键字" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单位" prop="unit">
<el-input v-model="formData.unit" placeholder="请输入单位" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商品简介" prop="introduction">
<el-input
v-model="formData.introduction"
:rows="3"
placeholder="请输入商品简介"
type="textarea"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商品封面图" prop="picUrl">
<div class="demo-image__preview pt-5px pb-5px pl-11x pr-11px">
<el-image
:initial-index="0"
:preview-src-list="srcList"
:src="url"
:zoom-rate="1.2"
fit="cover"
style="width: 100%; height: 90px"
/>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="商品轮播图" prop="sliderPicUrls">
<el-button>添加轮播图</el-button>
<el-carousel :interval="3000" height="200px" style="width: 100%" type="card">
<el-carousel-item v-for="item in 6" :key="item">
<h3 justify="center" text="2xl">{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="运费模板" prop="deliveryTemplateId">
<el-select v-model="formData.deliveryTemplateId" placeholder="请选择" style="width: 100%">
<el-option v-for="item in []" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-button class="ml-20px">运费模板</el-button>
</el-col>
<el-col :span="12">
<el-form-item label="商品规格" props="specType">
<el-radio-group v-model="formData.specType" @change="changeSpecType(formData.specType)">
<el-radio :label="false" class="radio">单规格</el-radio>
<el-radio :label="true">多规格</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<!-- TODO 商品规格和分销类型切换待定 -->
<el-col :span="12">
<el-form-item label="分销类型" props="subCommissionType">
<el-radio-group
v-model="formData.subCommissionType"
@change="changeSubCommissionType(formData.subCommissionType)"
>
<el-radio :label="false">默认设置</el-radio>
<el-radio :label="true" class="radio">自行设置</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<!-- 多规格添加-->
<el-col v-if="formData.specType" :span="24">
<el-form-item label="选择规格" prop="">
<div class="acea-row">
<el-select v-model="formData.selectRule">
<el-option
v-for="item in []"
:key="item.id"
:label="item.ruleName"
:value="item.id"
/>
</el-select>
<el-button class="mr-20px" type="primary" @click="confirm">确认</el-button>
<el-button class="mr-15px" @click="addRule">添加规格</el-button>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script lang="ts" name="ProductManagementBasicInfoForm" setup>
// TODO
import { defaultProps } from '@/utils/tree'
const url = 'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg'
const srcList = ['https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg']
const formRef = ref()
const formData = ref({
name: '', //
categoryId: '', //
keyword: '', //
unit: '', //
picUrl: '', //
sliderPicUrls: [], //
introduction: '', //
deliveryTemplateId: '', //
selectRule: '',
specType: false, //
subCommissionType: false //
})
const rules = reactive({
name: [required],
categoryId: [required],
keyword: [required],
unit: [required],
picUrl: [required],
sliderPicUrls: [required],
deliveryTemplateId: [required],
specType: [required],
subCommissionType: [required]
})
//
const changeSpecType = (specType) => {
console.log(specType)
}
//
const changeSubCommissionType = (subCommissionType) => {
console.log(subCommissionType)
}
//
const confirm = () => {}
//
const addRule = () => {}
</script>
<style scoped>
/*TODO 商品轮播图测试样式*/
.el-carousel__item h3 {
color: #475669;
opacity: 0.75;
line-height: 200px;
margin: 0;
text-align: center;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n + 1) {
background-color: #d3dce6;
}
/*TODO 商品封面测试样式*/
.demo-image__error .image-slot {
font-size: 30px;
}
.demo-image__error .image-slot .el-icon {
font-size: 30px;
}
.demo-image__error .el-image {
width: 100%;
height: 200px;
}
</style>

View File

@ -0,0 +1,13 @@
<template>
<!--富文本编辑器组件-->
<el-row>
<Editor v-model="content" :editor-config="editorConfig" />
</el-row>
</template>
<script lang="ts" name="DescriptionForm" setup>
import { Editor } from '@/components/Editor'
import { createEditorConfig } from '@/views/mp/draft/editor-config'
// TODO
const content = ref('')
const editorConfig = createEditorConfig('', 1)
</script>

View File

@ -0,0 +1,94 @@
<template>
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
<el-row>
<el-col :span="24">
<el-col :span="8">
<el-form-item label="商品排序">
<el-input-number v-model="formData.sort" :min="0" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="赠送积分">
<el-input-number v-model="formData.giveIntegral" :min="0" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="虚拟销量">
<el-input-number
v-model="formData.virtualSalesCount"
:min="0"
placeholder="请输入虚拟销量"
/>
</el-form-item>
</el-col>
</el-col>
<el-col :span="24">
<el-form-item label="商品推荐">
<el-checkbox-group v-model="checkboxGroup" @change="onChangeGroup">
<el-checkbox v-for="(item, index) in recommend" :key="index" :label="item.value">
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
<el-col :span="24">
<!-- TODO tag展示暂时不考虑排序 -->
<el-form-item label="活动优先级">
<el-tag>默认</el-tag>
<el-tag class="ml-2" type="success">秒杀</el-tag>
<el-tag class="ml-2" type="info">砍价</el-tag>
<el-tag class="ml-2" type="warning">拼团</el-tag>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="赠送优惠劵">
<el-button>选择优惠券</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script lang="ts" name="OtherSettingsForm" setup>
//
const recommend = [
{ name: '是否热卖', value: 'recommendHot' },
{ name: '是否优惠', value: 'recommendBenefit' },
{ name: '是否精品', value: 'recommendBest' },
{ name: '是否新品', value: 'recommendNew' },
{ name: '是否优品', value: 'recommendGood' }
]
const checkboxGroup = ref<string[]>([])
const onChangeGroup = () => {
checkboxGroup.value.includes('recommendHot')
? (formData.value.recommendHot = true)
: (formData.value.recommendHot = false)
checkboxGroup.value.includes('recommendBenefit')
? (formData.value.recommendBenefit = true)
: (formData.value.recommendBenefit = false)
checkboxGroup.value.includes('recommendBest')
? (formData.value.recommendBest = true)
: (formData.value.recommendBest = false)
checkboxGroup.value.includes('recommendNew')
? (formData.value.recommendNew = true)
: (formData.value.recommendNew = false)
checkboxGroup.value.includes('recommendGood')
? (formData.value.recommendGood = true)
: (formData.value.recommendGood = false)
}
const formRef = ref()
const formData = ref({
sort: '',
giveIntegral: 666,
virtualSalesCount: 565656,
recommendHot: false,
recommendBenefit: false,
recommendBest: false,
recommendNew: false,
recommendGood: false
})
const rules = reactive({
sort: [required],
giveIntegral: [required],
virtualSalesCount: [required]
})
</script>

View File

@ -0,0 +1,5 @@
import BasicInfoForm from './BasicInfoForm.vue'
import DescriptionForm from './DescriptionForm.vue'
import OtherSettingsForm from './OtherSettingsForm.vue'
export { BasicInfoForm, DescriptionForm, OtherSettingsForm }

View File

@ -0,0 +1,225 @@
<template>
<!-- 搜索工作栏 -->
<ContentWrap>
<el-form
ref="queryFormRef"
:inline="true"
:model="queryParams"
class="-mb-15px"
label-width="68px"
>
<el-form-item label="品牌名称" prop="name">
<el-input
v-model="queryParams.name"
class="!w-240px"
clearable
placeholder="请输入品牌名称"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" class="!w-240px" clearable placeholder="请选择状态">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
end-placeholder="结束日期"
start-placeholder="开始日期"
type="daterange"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<Icon class="mr-5px" icon="ep:search" />
搜索
</el-button>
<el-button @click="resetQuery">
<Icon class="mr-5px" icon="ep:refresh" />
重置
</el-button>
<el-button
v-hasPermi="['product:brand:create']"
plain
type="primary"
@click="openForm('create')"
>
<Icon class="mr-5px" icon="ep:plus" />
新增
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-tabs v-model="queryParams.type" @tab-click="getList">
<el-tab-pane
v-for="(item, index) in headerNum"
:key="index"
:label="item.name + '(' + item.count + ')'"
:name="item.type.toString()"
/>
</el-tabs>
<el-table v-loading="loading" :data="list">
<el-table-column type="expand">
<template #default="{ row }">
<el-form class="demo-table-expand" inline label-position="left">
<el-form-item label="市场价:">
<span>{{ row.marketPrice }}</span>
</el-form-item>
<el-form-item label="成本价:">
<span>{{ row.costPrice }}</span>
</el-form-item>
<el-form-item label="虚拟销量:">
<span>{{ row.virtualSalesCount }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column label="商品图" min-width="80">
<template #default="{ row }">
<div class="demo-image__preview">
<el-image
:preview-src-list="[row.image]"
:src="row.image"
style="width: 36px; height: 36px"
/>
</div>
</template>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
label="商品名称"
min-width="300"
prop="storeName"
/>
<el-table-column align="center" label="商品售价" min-width="90" prop="price" />
<el-table-column align="center" label="销量" min-width="90" prop="sales" />
<el-table-column align="center" label="库存" min-width="90" prop="stock" />
<el-table-column align="center" label="排序" min-width="70" prop="sort" />
<el-table-column
:formatter="dateFormatter"
align="center"
label="创建时间"
prop="createTime"
width="180"
/>
<el-table-column fixed="right" label="状态" min-width="80">
<template #default="{ row }">
<!--TODO 暂时用COMMON_STATUS占位一下使其不报错 -->
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
</template>
</el-table-column>
<el-table-column align="center" fixed="right" label="操作" min-width="150" />
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNo"
:total="total"
@pagination="getList"
/>
</ContentWrap>
</template>
<script lang="ts" name="ProductManagement" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
// const message = useMessage() //
// const { t } = useI18n() //
const { push } = useRouter() //
const loading = ref(false) //
const total = ref(0) //
const list = ref<any[]>([]) //
const headerNum = ref([
{
count: 8,
name: '出售中商品',
type: 1
},
{
count: 0,
name: '仓库中商品',
type: 2
},
{
count: 0,
name: '已经售馨商品',
type: 3
},
{
count: 0,
name: '警戒库存',
type: 4
},
{
count: 0,
name: '商品回收站',
type: 5
}
])
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: undefined,
status: undefined,
createTime: [],
type: '1'
})
const queryFormRef = ref() //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
// const data = await ProductBrandApi.getBrandParam(queryParams)
// list.value = data.list
// total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
const openForm = () => {
push('/product/productManagementAdd')
}
/** 删除按钮操作 */
// const handleDelete = async (id: number) => {
// try {
// //
// await message.delConfirm()
// //
// await ProductBrandApi.deleteBrand(id)
// message.success(t('common.delSuccess'))
// //
// await getList()
// } catch {}
// }
/** 初始化 **/
onMounted(() => {
// getList()
})
</script>