商品管理: 完善表单校验,优化信息提示,完成新建、编辑、提交逻辑
This commit is contained in:
parent
a0014bed65
commit
c38abc365c
22
src/api/mall/product/management/type/index.ts
Normal file
22
src/api/mall/product/management/type/index.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export interface SpuType {
|
||||||
|
name?: string // 商品名称
|
||||||
|
categoryId?: number // 商品分类
|
||||||
|
keyword?: string // 关键字
|
||||||
|
unit?: string // 单位
|
||||||
|
picUrl?: string // 商品封面图
|
||||||
|
sliderPicUrls?: string[] // 商品轮播图
|
||||||
|
introduction?: string // 商品简介
|
||||||
|
deliveryTemplateId?: number // 运费模版
|
||||||
|
selectRule?: string // 选择规格 TODO 暂时定义
|
||||||
|
specType?: boolean // 商品规格
|
||||||
|
subCommissionType?: boolean // 分销类型
|
||||||
|
description?: string // 商品详情
|
||||||
|
sort?: string // 商品排序
|
||||||
|
giveIntegral?: number // 赠送积分
|
||||||
|
virtualSalesCount?: number // 虚拟销量
|
||||||
|
recommendHot?: boolean // 是否热卖
|
||||||
|
recommendBenefit?: boolean // 是否优惠
|
||||||
|
recommendBest?: boolean // 是否精品
|
||||||
|
recommendNew?: boolean // 是否新品
|
||||||
|
recommendGood?: boolean // 是否优品
|
||||||
|
}
|
17
src/utils/object.ts
Normal file
17
src/utils/object.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* 将值复制到目标对象,且以目标对象属性为准,例:target: {a:1} source:{a:2,b:3} 结果为:{a:2}
|
||||||
|
* @param target 目标对象
|
||||||
|
* @param source 源对象
|
||||||
|
*/
|
||||||
|
export const copyValueToTarget = (target, source) => {
|
||||||
|
const newObj = Object.assign({}, target, source)
|
||||||
|
// 删除多余属性
|
||||||
|
Object.keys(newObj).forEach((key) => {
|
||||||
|
// 如果不是target中的属性则删除
|
||||||
|
if (Object.keys(target).indexOf(key) === -1) {
|
||||||
|
delete newObj[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 更新目标对象值
|
||||||
|
Object.assign(target, newObj)
|
||||||
|
}
|
@ -2,13 +2,25 @@
|
|||||||
<ContentWrap v-loading="formLoading">
|
<ContentWrap v-loading="formLoading">
|
||||||
<el-tabs v-model="activeName">
|
<el-tabs v-model="activeName">
|
||||||
<el-tab-pane label="商品信息" name="basicInfo">
|
<el-tab-pane label="商品信息" name="basicInfo">
|
||||||
<BasicInfoForm ref="basicInfoRef" />
|
<BasicInfoForm
|
||||||
|
ref="BasicInfoRef"
|
||||||
|
v-model:activeName="activeName"
|
||||||
|
:propFormData="formData"
|
||||||
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="商品详情" name="description">
|
<el-tab-pane label="商品详情" name="description">
|
||||||
<DescriptionForm ref="DescriptionRef" />
|
<DescriptionForm
|
||||||
|
ref="DescriptionRef"
|
||||||
|
v-model:activeName="activeName"
|
||||||
|
:propFormData="formData"
|
||||||
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="其他设置" name="otherSettings">
|
<el-tab-pane label="其他设置" name="otherSettings">
|
||||||
<OtherSettingsForm ref="otherSettingsRef" />
|
<OtherSettingsForm
|
||||||
|
ref="OtherSettingsRef"
|
||||||
|
v-model:activeName="activeName"
|
||||||
|
:propFormData="formData"
|
||||||
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<el-form>
|
<el-form>
|
||||||
@ -22,6 +34,7 @@
|
|||||||
<script lang="ts" name="ProductManagementForm" setup>
|
<script lang="ts" name="ProductManagementForm" setup>
|
||||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
import { useTagsViewStore } from '@/store/modules/tagsView'
|
||||||
import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
|
import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
|
||||||
|
import { SpuType } from '@/api/mall/product/management/type' // const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
// const { t } = useI18n() // 国际化
|
// const { t } = useI18n() // 国际化
|
||||||
// const message = useMessage() // 消息弹窗
|
// const message = useMessage() // 消息弹窗
|
||||||
@ -30,18 +43,77 @@ const { push, currentRoute } = useRouter() // 路由
|
|||||||
const { delView } = useTagsViewStore() // 视图操作
|
const { delView } = useTagsViewStore() // 视图操作
|
||||||
|
|
||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const activeName = ref('otherSettings') // Tag 激活的窗口
|
const activeName = ref('basicInfo') // Tag 激活的窗口
|
||||||
const basicInfoRef = ref<ComponentRef<typeof BasicInfoForm>>()
|
const BasicInfoRef = ref<ComponentRef<typeof BasicInfoForm>>() // 商品信息Ref
|
||||||
const DescriptionRef = ref<ComponentRef<typeof DescriptionForm>>()
|
const DescriptionRef = ref<ComponentRef<typeof DescriptionForm>>() // 商品详情Ref
|
||||||
|
const OtherSettingsRef = ref<ComponentRef<typeof OtherSettingsForm>>() // 其他设置Ref
|
||||||
|
const formData = ref<SpuType>({
|
||||||
|
name: '', // 商品名称
|
||||||
|
categoryId: 0, // 商品分类
|
||||||
|
keyword: '', // 关键字
|
||||||
|
unit: '', // 单位
|
||||||
|
picUrl: '', // 商品封面图
|
||||||
|
sliderPicUrls: [], // 商品轮播图
|
||||||
|
introduction: '', // 商品简介
|
||||||
|
deliveryTemplateId: 0, // 运费模版
|
||||||
|
selectRule: '',
|
||||||
|
specType: false, // 商品规格
|
||||||
|
subCommissionType: false, // 分销类型
|
||||||
|
description: '', // 商品详情
|
||||||
|
sort: 1, // 商品排序
|
||||||
|
giveIntegral: 1, // 赠送积分
|
||||||
|
virtualSalesCount: 1, // 虚拟销量
|
||||||
|
recommendHot: false, // 是否热卖
|
||||||
|
recommendBenefit: false, // 是否优惠
|
||||||
|
recommendBest: false, // 是否精品
|
||||||
|
recommendNew: false, // 是否新品
|
||||||
|
recommendGood: false // 是否优品
|
||||||
|
})
|
||||||
/** 获得详情 */
|
/** 获得详情 */
|
||||||
const getDetail = async () => {}
|
const getDetail = async () => {}
|
||||||
|
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
const submitForm = async () => {}
|
const submitForm = async () => {
|
||||||
|
// TODO 三个表单逐一校验,如果有一个表单校验不通过则切换到对应表单,如果有两个及以上的情况则切换到最前面的一个并弹出提示消息
|
||||||
|
// 校验各表单
|
||||||
|
try {
|
||||||
|
await unref(BasicInfoRef)?.validate()
|
||||||
|
await unref(DescriptionRef)?.validate()
|
||||||
|
await unref(OtherSettingsRef)?.validate()
|
||||||
|
// 校验都通过后提交表单
|
||||||
|
console.log(formData.value)
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 重置表单
|
||||||
|
*/
|
||||||
|
const resetForm = async () => {
|
||||||
|
formData.value = {
|
||||||
|
name: '', // 商品名称
|
||||||
|
categoryId: 0, // 商品分类
|
||||||
|
keyword: '', // 关键字
|
||||||
|
unit: '', // 单位
|
||||||
|
picUrl: '', // 商品封面图
|
||||||
|
sliderPicUrls: [], // 商品轮播图
|
||||||
|
introduction: '', // 商品简介
|
||||||
|
deliveryTemplateId: 0, // 运费模版
|
||||||
|
selectRule: '',
|
||||||
|
specType: false, // 商品规格
|
||||||
|
subCommissionType: false, // 分销类型
|
||||||
|
description: '', // 商品详情
|
||||||
|
sort: 1, // 商品排序
|
||||||
|
giveIntegral: 1, // 赠送积分
|
||||||
|
virtualSalesCount: 1, // 虚拟销量
|
||||||
|
recommendHot: false, // 是否热卖
|
||||||
|
recommendBenefit: false, // 是否优惠
|
||||||
|
recommendBest: false, // 是否精品
|
||||||
|
recommendNew: false, // 是否新品
|
||||||
|
recommendGood: false // 是否优品
|
||||||
|
}
|
||||||
|
}
|
||||||
/** 关闭按钮 */
|
/** 关闭按钮 */
|
||||||
const close = () => {
|
const close = () => {
|
||||||
|
resetForm()
|
||||||
delView(unref(currentRoute))
|
delView(unref(currentRoute))
|
||||||
push('/product/product-management')
|
push('/product/product-management')
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
<el-form ref="ProductManagementBasicInfoRef" :model="formData" :rules="rules" label-width="120px">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="商品名称" prop="name">
|
<el-form-item label="商品名称" prop="name">
|
||||||
@ -40,26 +40,12 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="商品封面图" prop="picUrl">
|
<el-form-item label="商品封面图" prop="picUrl">
|
||||||
<div class="demo-image__preview pt-5px pb-5px pl-11x pr-11px">
|
<UploadImg v-model="formData.picUrl" height="80px" />
|
||||||
<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-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="商品轮播图" prop="sliderPicUrls">
|
<el-form-item label="商品轮播图" prop="sliderPicUrls">
|
||||||
<el-button>添加轮播图</el-button>
|
<UploadImgs v-model="formData.sliderPicUrls" />
|
||||||
<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-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@ -72,6 +58,7 @@
|
|||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-button class="ml-20px">运费模板</el-button>
|
<el-button class="ml-20px">运费模板</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<!-- TODO 商品规格和分销类型切换待定 -->
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="商品规格" props="specType">
|
<el-form-item label="商品规格" props="specType">
|
||||||
<el-radio-group v-model="formData.specType" @change="changeSpecType(formData.specType)">
|
<el-radio-group v-model="formData.specType" @change="changeSpecType(formData.specType)">
|
||||||
@ -113,23 +100,31 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" name="ProductManagementBasicInfoForm" setup>
|
<script lang="ts" name="ProductManagementBasicInfoForm" setup>
|
||||||
// TODO 商品封面测试数据
|
import { PropType } from 'vue'
|
||||||
import { defaultProps } from '@/utils/tree'
|
import { defaultProps } from '@/utils/tree'
|
||||||
|
import type { SpuType } from '@/api/mall/product/management/type'
|
||||||
|
import { UploadImg, UploadImgs } from '@/components/UploadFile'
|
||||||
|
import { copyValueToTarget } from '@/utils/object'
|
||||||
|
|
||||||
const url = 'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg'
|
const message = useMessage() // 消息弹窗
|
||||||
const srcList = ['https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg']
|
const props = defineProps({
|
||||||
|
propFormData: {
|
||||||
|
type: Object as PropType<SpuType>,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const formRef = ref()
|
const ProductManagementBasicInfoRef = ref() // 表单Ref
|
||||||
const formData = ref({
|
const formData = ref<SpuType>({
|
||||||
name: '', // 商品名称
|
name: '', // 商品名称
|
||||||
categoryId: '', // 商品分类
|
categoryId: 155415, // 商品分类
|
||||||
keyword: '', // 关键字
|
keyword: '', // 关键字
|
||||||
unit: '', // 单位
|
unit: '', // 单位
|
||||||
picUrl: '', // 商品封面图
|
picUrl: '', // 商品封面图
|
||||||
sliderPicUrls: [], // 商品轮播图
|
sliderPicUrls: [], // 商品轮播图
|
||||||
introduction: '', // 商品简介
|
introduction: '', // 商品简介
|
||||||
deliveryTemplateId: '', // 运费模版
|
deliveryTemplateId: '', // 运费模版
|
||||||
selectRule: '',
|
selectRule: '', // 选择规则 TODO 暂定
|
||||||
specType: false, // 商品规格
|
specType: false, // 商品规格
|
||||||
subCommissionType: false // 分销类型
|
subCommissionType: false // 分销类型
|
||||||
})
|
})
|
||||||
@ -138,12 +133,47 @@ const rules = reactive({
|
|||||||
categoryId: [required],
|
categoryId: [required],
|
||||||
keyword: [required],
|
keyword: [required],
|
||||||
unit: [required],
|
unit: [required],
|
||||||
|
introduction: [required],
|
||||||
picUrl: [required],
|
picUrl: [required],
|
||||||
sliderPicUrls: [required],
|
sliderPicUrls: [required]
|
||||||
deliveryTemplateId: [required],
|
// deliveryTemplateId: [required],
|
||||||
specType: [required],
|
// specType: [required],
|
||||||
subCommissionType: [required]
|
// subCommissionType: [required],
|
||||||
})
|
})
|
||||||
|
/**
|
||||||
|
* 将传进来的值赋值给formData
|
||||||
|
*/
|
||||||
|
watch(
|
||||||
|
() => props.propFormData,
|
||||||
|
(data) => {
|
||||||
|
if (!data) return
|
||||||
|
copyValueToTarget(formData.value, data)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const emit = defineEmits(['update:activeName'])
|
||||||
|
/**
|
||||||
|
* 表单校验
|
||||||
|
*/
|
||||||
|
const validate = async () => {
|
||||||
|
// 校验表单
|
||||||
|
if (!ProductManagementBasicInfoRef) return
|
||||||
|
return await unref(ProductManagementBasicInfoRef).validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
message.warning('商品信息未完善!!')
|
||||||
|
emit('update:activeName', 'basicInfo')
|
||||||
|
// 目的截断之后的校验
|
||||||
|
throw new Error('商品信息未完善!!')
|
||||||
|
} else {
|
||||||
|
// 校验通过更新数据
|
||||||
|
Object.assign(props.propFormData, formData.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
defineExpose({ validate })
|
||||||
// 选择规格
|
// 选择规格
|
||||||
const changeSpecType = (specType) => {
|
const changeSpecType = (specType) => {
|
||||||
console.log(specType)
|
console.log(specType)
|
||||||
@ -157,35 +187,3 @@ const confirm = () => {}
|
|||||||
// 添加规格
|
// 添加规格
|
||||||
const addRule = () => {}
|
const addRule = () => {}
|
||||||
</script>
|
</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>
|
|
||||||
|
@ -1,13 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<!--富文本编辑器组件-->
|
<el-form ref="DescriptionFormRef" :model="formData" :rules="rules" label-width="120px">
|
||||||
<el-row>
|
<!--富文本编辑器组件-->
|
||||||
<Editor v-model="content" :editor-config="editorConfig" />
|
<el-form-item label="商品详情" prop="description">
|
||||||
</el-row>
|
<Editor v-model:modelValue="formData.description" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" name="DescriptionForm" setup>
|
<script lang="ts" name="DescriptionForm" setup>
|
||||||
|
import type { SpuType } from '@/api/mall/product/management/type'
|
||||||
import { Editor } from '@/components/Editor'
|
import { Editor } from '@/components/Editor'
|
||||||
import { createEditorConfig } from '@/views/mp/draft/editor-config'
|
import { PropType } from 'vue'
|
||||||
// TODO 模拟参数
|
import { copyValueToTarget } from '@/utils/object'
|
||||||
const content = ref('')
|
|
||||||
const editorConfig = createEditorConfig('', 1)
|
const message = useMessage() // 消息弹窗
|
||||||
|
const props = defineProps({
|
||||||
|
propFormData: {
|
||||||
|
type: Object as PropType<SpuType>,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const DescriptionFormRef = ref() // 表单Ref
|
||||||
|
const formData = ref<SpuType>({
|
||||||
|
description: '' // 商品详情
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* 富文本编辑器如果输入过再清空会有残留,需再重置一次
|
||||||
|
*/
|
||||||
|
watch(
|
||||||
|
() => formData.value.description,
|
||||||
|
(newValue) => {
|
||||||
|
if ('<p><br></p>' === newValue) {
|
||||||
|
formData.value.description = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// 表单规则
|
||||||
|
const rules = reactive({
|
||||||
|
description: [required]
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* 将传进来的值赋值给formData
|
||||||
|
*/
|
||||||
|
watch(
|
||||||
|
() => props.propFormData,
|
||||||
|
(data) => {
|
||||||
|
if (!data) return
|
||||||
|
copyValueToTarget(formData.value, data)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const emit = defineEmits(['update:activeName'])
|
||||||
|
/**
|
||||||
|
* 表单校验
|
||||||
|
*/
|
||||||
|
const validate = async () => {
|
||||||
|
// 校验表单
|
||||||
|
if (!DescriptionFormRef) return
|
||||||
|
return unref(DescriptionFormRef).validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
message.warning('商品详情为完善!!')
|
||||||
|
emit('update:activeName', 'description')
|
||||||
|
// 目的截断之后的校验
|
||||||
|
throw new Error('商品详情为完善!!')
|
||||||
|
} else {
|
||||||
|
// 校验通过更新数据
|
||||||
|
Object.assign(props.propFormData, formData.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
defineExpose({ validate })
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
<el-form ref="OtherSettingsFormRef" :model="formData" :rules="rules" label-width="120px">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="商品排序">
|
<el-form-item label="商品排序" prop="sort">
|
||||||
<el-input-number v-model="formData.sort" :min="0" />
|
<el-input-number v-model="formData.sort" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="赠送积分">
|
<el-form-item label="赠送积分" prop="giveIntegral">
|
||||||
<el-input-number v-model="formData.giveIntegral" :min="0" />
|
<el-input-number v-model="formData.giveIntegral" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="虚拟销量">
|
<el-form-item label="虚拟销量" prop="virtualSalesCount">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="formData.virtualSalesCount"
|
v-model="formData.virtualSalesCount"
|
||||||
:min="0"
|
:min="0"
|
||||||
@ -50,6 +50,18 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts" name="OtherSettingsForm" setup>
|
<script lang="ts" name="OtherSettingsForm" setup>
|
||||||
// 商品推荐
|
// 商品推荐
|
||||||
|
import type { SpuType } from '@/api/mall/product/management/type'
|
||||||
|
import { PropType } from 'vue'
|
||||||
|
import { copyValueToTarget } from '@/utils/object'
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const props = defineProps({
|
||||||
|
propFormData: {
|
||||||
|
type: Object as PropType<SpuType>,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 商品推荐选项
|
||||||
const recommend = [
|
const recommend = [
|
||||||
{ name: '是否热卖', value: 'recommendHot' },
|
{ name: '是否热卖', value: 'recommendHot' },
|
||||||
{ name: '是否优惠', value: 'recommendBenefit' },
|
{ name: '是否优惠', value: 'recommendBenefit' },
|
||||||
@ -57,7 +69,9 @@ const recommend = [
|
|||||||
{ name: '是否新品', value: 'recommendNew' },
|
{ name: '是否新品', value: 'recommendNew' },
|
||||||
{ name: '是否优品', value: 'recommendGood' }
|
{ name: '是否优品', value: 'recommendGood' }
|
||||||
]
|
]
|
||||||
const checkboxGroup = ref<string[]>([])
|
// 选中推荐选项
|
||||||
|
const checkboxGroup = ref<string[]>(['recommendHot'])
|
||||||
|
// 选择商品后赋值
|
||||||
const onChangeGroup = () => {
|
const onChangeGroup = () => {
|
||||||
checkboxGroup.value.includes('recommendHot')
|
checkboxGroup.value.includes('recommendHot')
|
||||||
? (formData.value.recommendHot = true)
|
? (formData.value.recommendHot = true)
|
||||||
@ -75,20 +89,63 @@ const onChangeGroup = () => {
|
|||||||
? (formData.value.recommendGood = true)
|
? (formData.value.recommendGood = true)
|
||||||
: (formData.value.recommendGood = false)
|
: (formData.value.recommendGood = false)
|
||||||
}
|
}
|
||||||
const formRef = ref()
|
const OtherSettingsFormRef = ref() // 表单Ref
|
||||||
const formData = ref({
|
// 表单数据
|
||||||
sort: '',
|
const formData = ref<SpuType>({
|
||||||
giveIntegral: 666,
|
sort: 12, // 商品排序
|
||||||
virtualSalesCount: 565656,
|
giveIntegral: 666, // 赠送积分
|
||||||
recommendHot: false,
|
virtualSalesCount: 565656, // 虚拟销量
|
||||||
recommendBenefit: false,
|
recommendHot: false, // 是否热卖
|
||||||
recommendBest: false,
|
recommendBenefit: false, // 是否优惠
|
||||||
recommendNew: false,
|
recommendBest: false, // 是否精品
|
||||||
recommendGood: false
|
recommendNew: false, // 是否新品
|
||||||
|
recommendGood: false // 是否优品
|
||||||
})
|
})
|
||||||
|
// 表单规则
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
sort: [required],
|
sort: [required],
|
||||||
giveIntegral: [required],
|
giveIntegral: [required],
|
||||||
virtualSalesCount: [required]
|
virtualSalesCount: [required]
|
||||||
})
|
})
|
||||||
|
/**
|
||||||
|
* 将传进来的值赋值给formData
|
||||||
|
*/
|
||||||
|
watch(
|
||||||
|
() => props.propFormData,
|
||||||
|
(data) => {
|
||||||
|
if (!data) return
|
||||||
|
copyValueToTarget(formData.value, data)
|
||||||
|
checkboxGroup.value = []
|
||||||
|
formData.value.recommendHot ? checkboxGroup.value.push('recommendHot') : ''
|
||||||
|
formData.value.recommendBenefit ? checkboxGroup.value.push('recommendBenefit') : ''
|
||||||
|
formData.value.recommendBest ? checkboxGroup.value.push('recommendBest') : ''
|
||||||
|
formData.value.recommendNew ? checkboxGroup.value.push('recommendNew') : ''
|
||||||
|
formData.value.recommendGood ? checkboxGroup.value.push('recommendGood') : ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const emit = defineEmits(['update:activeName'])
|
||||||
|
/**
|
||||||
|
* 表单校验
|
||||||
|
*/
|
||||||
|
const validate = async () => {
|
||||||
|
// 校验表单
|
||||||
|
if (!OtherSettingsFormRef) return
|
||||||
|
return await unref(OtherSettingsFormRef).validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
message.warning('商品其他设置未完善!!')
|
||||||
|
emit('update:activeName', 'otherSettings')
|
||||||
|
// 目的截断之后的校验
|
||||||
|
throw new Error('商品其他设置未完善!!')
|
||||||
|
} else {
|
||||||
|
// 校验通过更新数据
|
||||||
|
Object.assign(props.propFormData, formData.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ validate })
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,36 +2,36 @@
|
|||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-form
|
<el-form
|
||||||
class="-mb-15px"
|
|
||||||
:model="queryParams"
|
|
||||||
ref="queryFormRef"
|
ref="queryFormRef"
|
||||||
:inline="true"
|
:inline="true"
|
||||||
|
:model="queryParams"
|
||||||
|
class="-mb-15px"
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
<el-form-item label="字典名称" prop="name">
|
<el-form-item label="字典名称" prop="name">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.name"
|
v-model="queryParams.name"
|
||||||
placeholder="请输入字典名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入字典名称"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="字典类型" prop="type">
|
<el-form-item label="字典类型" prop="type">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.type"
|
v-model="queryParams.type"
|
||||||
placeholder="请输入字典类型"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入字典类型"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="queryParams.status"
|
v-model="queryParams.status"
|
||||||
placeholder="请选择字典状态"
|
|
||||||
clearable
|
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
|
clearable
|
||||||
|
placeholder="请选择字典状态"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
@ -44,33 +44,41 @@
|
|||||||
<el-form-item label="创建时间" prop="createTime">
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="queryParams.createTime"
|
v-model="queryParams.createTime"
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
type="daterange"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
type="daterange"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery">
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<Icon class="mr-5px" icon="ep:search" />
|
||||||
<el-button
|
搜索
|
||||||
type="primary"
|
</el-button>
|
||||||
plain
|
<el-button @click="resetQuery">
|
||||||
@click="openForm('create')"
|
<Icon class="mr-5px" icon="ep:refresh" />
|
||||||
v-hasPermi="['system:dict:create']"
|
重置
|
||||||
>
|
|
||||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="success"
|
v-hasPermi="['system:dict:create']"
|
||||||
plain
|
plain
|
||||||
@click="handleExport"
|
type="primary"
|
||||||
:loading="exportLoading"
|
@click="openForm('create')"
|
||||||
v-hasPermi="['system:dict:export']"
|
|
||||||
>
|
>
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
<Icon class="mr-5px" icon="ep:plus" />
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-hasPermi="['system:dict:export']"
|
||||||
|
:loading="exportLoading"
|
||||||
|
plain
|
||||||
|
type="success"
|
||||||
|
@click="handleExport"
|
||||||
|
>
|
||||||
|
<Icon class="mr-5px" icon="ep:download" />
|
||||||
|
导出
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -79,29 +87,29 @@
|
|||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="list">
|
||||||
<el-table-column label="字典编号" align="center" prop="id" />
|
<el-table-column align="center" label="字典编号" prop="id" />
|
||||||
<el-table-column label="字典名称" align="center" prop="name" show-overflow-tooltip />
|
<el-table-column align="center" label="字典名称" prop="name" show-overflow-tooltip />
|
||||||
<el-table-column label="字典类型" align="center" prop="type" width="300" />
|
<el-table-column align="center" label="字典类型" prop="type" width="300" />
|
||||||
<el-table-column label="状态" align="center" prop="status">
|
<el-table-column align="center" label="状态" prop="status">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="备注" align="center" prop="remark" />
|
<el-table-column align="center" label="备注" prop="remark" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="创建时间"
|
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
align="center"
|
align="center"
|
||||||
|
label="创建时间"
|
||||||
prop="createTime"
|
prop="createTime"
|
||||||
width="180"
|
width="180"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column align="center" label="操作">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
v-hasPermi="['system:dict:update']"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
v-hasPermi="['system:dict:update']"
|
|
||||||
>
|
>
|
||||||
修改
|
修改
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -109,10 +117,10 @@
|
|||||||
<el-button link type="primary">数据</el-button>
|
<el-button link type="primary">数据</el-button>
|
||||||
</router-link>
|
</router-link>
|
||||||
<el-button
|
<el-button
|
||||||
|
v-hasPermi="['system:dict:delete']"
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="handleDelete(scope.row.id)"
|
@click="handleDelete(scope.row.id)"
|
||||||
v-hasPermi="['system:dict:delete']"
|
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -121,9 +129,9 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
:total="total"
|
|
||||||
v-model:page="queryParams.pageNo"
|
|
||||||
v-model:limit="queryParams.pageSize"
|
v-model:limit="queryParams.pageSize"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
:total="total"
|
||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
@ -132,12 +140,13 @@
|
|||||||
<DictTypeForm ref="formRef" @success="getList" />
|
<DictTypeForm ref="formRef" @success="getList" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="SystemDictType">
|
<script lang="ts" name="SystemDictType" setup>
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import * as DictTypeApi from '@/api/system/dict/dict.type'
|
import * as DictTypeApi from '@/api/system/dict/dict.type'
|
||||||
import DictTypeForm from './DictTypeForm.vue'
|
import DictTypeForm from './DictTypeForm.vue'
|
||||||
import download from '@/utils/download'
|
import download from '@/utils/download'
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user