parent
8eb8354d71
commit
4b7cd48796
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 5.7 KiB |
@ -0,0 +1,128 @@
|
||||
export const tableOption = {
|
||||
searchMenuSpan: 6,
|
||||
columnBtn: false,
|
||||
border: true,
|
||||
index: false,
|
||||
selection: true,
|
||||
indexLabel: '序号',
|
||||
stripe: true,
|
||||
menuAlign: 'center',
|
||||
menuWidth: 350,
|
||||
align: 'center',
|
||||
refreshBtn: true,
|
||||
searchSize: 'mini',
|
||||
addBtn: false,
|
||||
editBtn: false,
|
||||
viewBtn: false,
|
||||
delBtn: false,
|
||||
props: {
|
||||
label: 'label',
|
||||
value: 'value'
|
||||
},
|
||||
column: [
|
||||
|
||||
{
|
||||
label: '店铺id',
|
||||
prop: 'shopId',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺名称',
|
||||
prop: 'shopName',
|
||||
search: true
|
||||
}, {
|
||||
label: '店长用户id',
|
||||
prop: 'userId',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺类型',
|
||||
prop: 'shopType',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺简介',
|
||||
prop: 'intro',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺公告',
|
||||
prop: 'shopNotice',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺行业',
|
||||
prop: 'shopIndustry',
|
||||
search: true
|
||||
}, {
|
||||
label: '店长',
|
||||
prop: 'shopOwner',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺绑定的手机',
|
||||
prop: 'mobile',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺联系电话',
|
||||
prop: 'tel',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺所在纬度',
|
||||
prop: 'shopLat',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺所在经度',
|
||||
prop: 'shopLng',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺详细地址',
|
||||
prop: 'shopAddress',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺所在省份',
|
||||
prop: 'province',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺所在城市',
|
||||
prop: 'city',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺所在区域',
|
||||
prop: 'area',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺省市区代码',
|
||||
prop: 'pcaCode',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺logo',
|
||||
prop: 'shopLogo',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺相册',
|
||||
prop: 'shopPhotos',
|
||||
search: true
|
||||
}, {
|
||||
label: '每天营业时间段',
|
||||
prop: 'openTime',
|
||||
search: true
|
||||
}, {
|
||||
label: '店铺状态(-1:未开通 0: 停业中 1:营业中)',
|
||||
prop: 'shopStatus',
|
||||
search: true
|
||||
}, {
|
||||
label: '0:商家承担运费 1:买家承担运费',
|
||||
prop: 'transportType'
|
||||
}, {
|
||||
label: '固定运费',
|
||||
prop: 'fixedFreight'
|
||||
}, {
|
||||
label: '满X包邮',
|
||||
prop: 'fullFreeShipping'
|
||||
}, {
|
||||
label: '创建时间',
|
||||
prop: 'createTime'
|
||||
}, {
|
||||
label: '更新时间',
|
||||
prop: 'updateTime'
|
||||
}, {
|
||||
label: '分销设置(0关闭 1开启)',
|
||||
prop: 'isDistribution'
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div class="mod-prod-prod-transport">
|
||||
<el-form-item
|
||||
label="运费设置"
|
||||
:rules="[{ required: true, message: '运费模板不能为空'}]"
|
||||
>
|
||||
<el-select
|
||||
v-model="transportId"
|
||||
placeholder="请选择"
|
||||
@change="changeTransport"
|
||||
>
|
||||
<el-option
|
||||
v-for="transport in transportList"
|
||||
:key="transport.transportId"
|
||||
:label="transport.transName"
|
||||
:value="transport.transportId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-table
|
||||
v-if="transportInfo.transfees"
|
||||
:data="transportInfo.transfees"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
label="配送区域"
|
||||
width="350"
|
||||
>
|
||||
<template #default="scope">
|
||||
<span v-if="!scope.row.cityList.length">所有地区</span>
|
||||
<el-tag
|
||||
v-for="city in scope.row.cityList"
|
||||
v-else
|
||||
:key="city.areaId"
|
||||
>
|
||||
{{ city.areaName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="firstPiece"
|
||||
:label="tableTitle[0]"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="firstFee"
|
||||
:label="tableTitle[1]"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="continuousPiece"
|
||||
:label="tableTitle[2]"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="continuousFee"
|
||||
:label="tableTitle[3]"
|
||||
/>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="transportInfo.hasFreeCondition === 1">
|
||||
<el-table
|
||||
:data="transportInfo.transfeeFrees"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
label="指定区域"
|
||||
width="350"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
v-for="city in scope.row.freeCityList"
|
||||
:key="city.areaId"
|
||||
>
|
||||
{{ city.areaName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="freeType"
|
||||
label="包邮条件"
|
||||
>
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.freeType === 0">满件/重量/体积包邮</span>
|
||||
<span v-if="scope.row.freeType === 1">满金额包邮</span>
|
||||
<span v-if="scope.row.freeType === 2">满件/重量/体积且满金额包邮</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="amount">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.freeType === 1">满{{ scope.row.amount }}元金额包邮</span>
|
||||
<span v-if="scope.row.freeType === 0">满{{ scope.row.piece }}件/重量/体积包邮</span>
|
||||
<span v-if="scope.row.freeType === 2">满{{ scope.row.piece }}件/重量/体积且满{{ scope.row.amount }}元金额包邮</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
default: null,
|
||||
type: Number
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['input', 'update:modelValue'])
|
||||
const transportId = ref(null)
|
||||
const tableTitle = computed(() => {
|
||||
const titles = [['首件(个)', '运费(元)', '续件(个)', '续费(元)'], ['首重(kg)', '运费(元)', '续重(kg)', '续费(元)'], ['首体积(m³)', '运费(元)', '续体积(m³)', '续费(元)']]
|
||||
if (transportInfo.value.chargeType) {
|
||||
return titles[transportInfo.value.chargeType]
|
||||
}
|
||||
return titles[0]
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(id) => {
|
||||
transportId.value = id
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getTransportList()
|
||||
})
|
||||
|
||||
const transportList = ref([{
|
||||
transportId: null,
|
||||
transName: ''
|
||||
}])
|
||||
const getTransportList = () => {
|
||||
http({
|
||||
url: http.adornUrl('/shop/transport/list'),
|
||||
method: 'get',
|
||||
params: http.adornParams({})
|
||||
})
|
||||
.then(({ data }) => {
|
||||
transportList.value = data
|
||||
})
|
||||
}
|
||||
const transportInfo = ref({
|
||||
hasFreeCondition: false,
|
||||
transfeeFrees: [{ freeCityList: [] }]
|
||||
})
|
||||
const changeTransport = (id) => {
|
||||
emit('update:modelValue', id)
|
||||
if (!id) {
|
||||
return
|
||||
}
|
||||
http({
|
||||
url: http.adornUrl(`/shop/transport/info/${transportId.value}`),
|
||||
method: 'get',
|
||||
params: http.adornParams({})
|
||||
})
|
||||
.then(({ data }) => {
|
||||
transportInfo.value = data
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -0,0 +1,246 @@
|
||||
<template>
|
||||
<div class="mod-prod-sku-table">
|
||||
<el-form-item>
|
||||
<el-table
|
||||
:data="modelValue"
|
||||
border
|
||||
style="width: 100%; margin-top: 20px"
|
||||
>
|
||||
<el-table-column
|
||||
v-for="(leftTitle, index) in tableLeftTitles"
|
||||
:key="index"
|
||||
:label="leftTitle"
|
||||
>
|
||||
<template #default="scope">
|
||||
{{ scope.row.properties.split(';')[index].split(':')[1] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="tableLeftTitles.length"
|
||||
prop="pic"
|
||||
label="sku图片"
|
||||
width="180"
|
||||
>
|
||||
<template #default="scope">
|
||||
<pic-upload v-model="scope.row.pic" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="tableLeftTitles.length"
|
||||
prop="prodName"
|
||||
label="商品名称"
|
||||
width="250"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.prodName"
|
||||
type="textarea"
|
||||
:disabled="!scope.row.status"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="price"
|
||||
label="销售价"
|
||||
width="160"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.price"
|
||||
controls-position="right"
|
||||
:precision="2"
|
||||
:max="1000000000"
|
||||
:min="0.01"
|
||||
:disabled="!scope.row.status"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="oriPrice"
|
||||
label="市场价"
|
||||
width="160"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.oriPrice"
|
||||
controls-position="right"
|
||||
:precision="2"
|
||||
:max="1000000000"
|
||||
:min="0.01"
|
||||
:disabled="!scope.row.status"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="stocks"
|
||||
label="库存"
|
||||
width="160"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.stocks"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
type="number"
|
||||
:disabled="!scope.row.status"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="weight"
|
||||
label="商品重量(kg)"
|
||||
width="210"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.weight"
|
||||
:precision="2"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
:disabled="!scope.row.status"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="volume"
|
||||
label="商品体积(m³)"
|
||||
width="210"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.volume"
|
||||
:precision="2"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
:disabled="!scope.row.status"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.status"
|
||||
type="text"
|
||||
@click="changeSkuStatus(`${scope.$index}`)"
|
||||
>
|
||||
禁用
|
||||
</el-button>
|
||||
<el-button
|
||||
v-else
|
||||
type="text"
|
||||
@click="changeSkuStatus(`${scope.$index}`)"
|
||||
>
|
||||
启用
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { scoreProdStore } from '@/stores/prod.js'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
default: () => [],
|
||||
type: Array
|
||||
},
|
||||
prodName: {
|
||||
default: '',
|
||||
type: String
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const dbSpecs = ref([]) // 数据库中的规格
|
||||
let initing = false
|
||||
|
||||
const tableLeftTitles = computed(() => {
|
||||
const res = []
|
||||
for (let i = 0; i < skuTags.value.length; i++) {
|
||||
const skuTag = skuTags.value[i]
|
||||
res.push(skuTag.tagName)
|
||||
}
|
||||
return res
|
||||
})
|
||||
const prod = scoreProdStore()
|
||||
const skuTags = computed({
|
||||
get () { return prod.skuTags }
|
||||
})
|
||||
|
||||
watch(() => props.prodName,
|
||||
() => {
|
||||
skuAddProdName()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
http({
|
||||
url: http.adornUrl('/prod/spec/list'),
|
||||
method: 'get',
|
||||
params: http.adornParams()
|
||||
})
|
||||
.then(({ data }) => {
|
||||
dbSpecs.value = data
|
||||
})
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
initing = true
|
||||
}
|
||||
defineExpose({ init })
|
||||
|
||||
const changeSkuStatus = (tagIndex) => {
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
props.modelValue[tagIndex].status = props.modelValue[tagIndex].status ? 0 : 1
|
||||
}
|
||||
const skuAddProdName = () => {
|
||||
if (initing) return
|
||||
const skuList = []
|
||||
for (let i = 0; i < props.modelValue.length; i++) {
|
||||
const sku = Object.assign({}, props.modelValue[i])
|
||||
if (!sku.properties) {
|
||||
return
|
||||
}
|
||||
sku.skuName = ''
|
||||
const properties = sku.properties.split(';')
|
||||
for (const propertiesKey in properties) {
|
||||
sku.skuName += properties[propertiesKey].split(':')[1] + ' '
|
||||
}
|
||||
sku.prodName = props.prodName + ' ' + sku.skuName
|
||||
skuList.push(sku)
|
||||
}
|
||||
emit('update:modelValue', skuList)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mod-prod-sku-table{
|
||||
:deep(.pic-uploader-component .el-upload) {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
.pic-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
line-height: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
.pic {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
:deep(.pic-uploader-component .el-upload:hover) {
|
||||
border-color: #409EFF;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div class="mod-pickAddr">
|
||||
<avue-crud
|
||||
ref="crudRef"
|
||||
:page="page"
|
||||
:data="dataList"
|
||||
:option="tableOption"
|
||||
:permission="permission"
|
||||
@search-change="onSearch"
|
||||
@selection-change="selectionChange"
|
||||
@on-load="getDataList"
|
||||
>
|
||||
<template #menu-left>
|
||||
<!-- <el-button
|
||||
v-if="isAuth('shop:pickAddr:save')"
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
@click.stop="onAddOrUpdate()"
|
||||
>
|
||||
新增
|
||||
</el-button>
|
||||
|
||||
<el-button
|
||||
v-if="isAuth('shop:pickAddr:delete')"
|
||||
type="danger"
|
||||
:disabled="dataListSelections.length <= 0"
|
||||
@click="onDelete()"
|
||||
>
|
||||
批量删除
|
||||
</el-button> -->
|
||||
</template>
|
||||
|
||||
<template #menu="scope">
|
||||
<el-button
|
||||
v-if="isAuth('shop:shopDetail:info')"
|
||||
type="primary"
|
||||
@click.stop="onAddOrUpdate(scope.row.shopId)"
|
||||
>
|
||||
查看
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="isAuth('shop:shopDetail:shoutDown')"
|
||||
type="danger"
|
||||
@click.stop="onShouDown(scope.row.shopId)"
|
||||
>
|
||||
下架
|
||||
</el-button>
|
||||
<!-- <el-button
|
||||
v-if="isAuth('shop:pickAddr:update')"
|
||||
type="primary"
|
||||
icon="el-icon-edit"
|
||||
@click.stop="onAddOrUpdate(scope.row.addrId)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
|
||||
<el-button
|
||||
v-if="isAuth('shop:pickAddr:delete')"
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
@click.stop="onDelete(scope.row.addrId)"
|
||||
>
|
||||
删除
|
||||
</el-button> -->
|
||||
</template>
|
||||
</avue-crud>
|
||||
<!-- 弹窗, 新增 / 修改 -->
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { isAuth } from '@/utils'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { tableOption } from '@/crud/shop/shopList.js'
|
||||
|
||||
const permission = {
|
||||
delBtn: isAuth('prod:prod:delete')
|
||||
}
|
||||
const dataList = ref([])
|
||||
const dataListSelections = ref([])
|
||||
const page = reactive({
|
||||
total: 0, // 总页数
|
||||
currentPage: 1, // 当前页数
|
||||
pageSize: 10 // 每页显示多少条
|
||||
})
|
||||
const router = useRouter()
|
||||
/**
|
||||
* 新增 / 修改
|
||||
* @param id
|
||||
*/
|
||||
const onAddOrUpdate = (id) => {
|
||||
router.push({
|
||||
path: '/shopInfo',
|
||||
query: { shopId: id }
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取数据列表
|
||||
*/
|
||||
const getDataList = (pageParam, params, done) => {
|
||||
http({
|
||||
url: http.adornUrl('/shop/shopDetail/page'),
|
||||
method: 'get',
|
||||
params: http.adornParams(
|
||||
Object.assign(
|
||||
{
|
||||
current: pageParam == null ? page.currentPage : pageParam.currentPage,
|
||||
size: pageParam == null ? page.pageSize : pageParam.pageSize
|
||||
},
|
||||
params
|
||||
)
|
||||
)
|
||||
})
|
||||
.then(({ data }) => {
|
||||
dataList.value = data.records
|
||||
page.total = data.total
|
||||
if (done) done()
|
||||
})
|
||||
}
|
||||
|
||||
const addOrUpdateVisible = ref(false)
|
||||
const addOrUpdateRef = ref(null)
|
||||
|
||||
/* const onAddOrUpdate = (id) => {
|
||||
addOrUpdateVisible.value = true
|
||||
nextTick(() => {
|
||||
addOrUpdateRef.value?.init(id)
|
||||
})
|
||||
} */
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param id
|
||||
*/
|
||||
const onShouDown = (id) => {
|
||||
const ids = id ? [id] : dataListSelections.value?.map(item => {
|
||||
return item.addrId
|
||||
})
|
||||
ElMessageBox.confirm(
|
||||
'确定进行下架操作?', '提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
http({
|
||||
url: http.adornUrl('/shop/shopDetail/shoutDown'),
|
||||
method: 'delete',
|
||||
data: http.adornData(ids, false)
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
message: '操作成功',
|
||||
type: 'success',
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
getDataList(page)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件查询
|
||||
* @param params
|
||||
* @param done
|
||||
*/
|
||||
const onSearch = (params, done) => {
|
||||
getDataList(page, params, done)
|
||||
}
|
||||
/**
|
||||
* 多选变化
|
||||
* @param val
|
||||
*/
|
||||
const selectionChange = (val) => {
|
||||
dataListSelections.value = val
|
||||
}
|
||||
</script>
|
||||
Loading…
Reference in new issue