Files
jdt-admin/src/views/commodity/hot_list/index.vue
Huakk 2e3a445eb5
All checks were successful
continuous-integration/drone/push Build is passing
fix(custom):
2024-08-04 00:20:26 +08:00

662 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- eslint-disable vue/no-v-html -->
<template>
<CommonPage show-footer :title="$route.title">
<!-- {{ queryParams }} -->
<n-grid class="mb-10" x-gap="12">
<n-gi span="12" mt-10 flex items-center>
<span w-100>筛选条件:</span>
<n-input-group>
<n-select
v-model:value="queryParams.selectKey"
:style="{ width: '25%' }"
:options="selectOptions"
placeholder="请选择"
/>
<n-input v-model:value="queryParams.word" :style="{ width: '50%' }" />
</n-input-group>
</n-gi>
<n-gi :span="24" mt-10>
<div>
<span>审核状态</span>
<n-radio-group v-model:value="queryParams.status">
<n-radio-button
v-for="song in [
{
label: '已审核',
value: 1,
},
{
label: '拒绝',
value: 2,
},
{
label: '待审核',
value: 3,
},
]"
:key="song.value"
:value="song.value"
:label="song.label"
/>
</n-radio-group>
</div>
</n-gi>
<n-gi :span="24" mt-10>
<div>
<span>商品类型:</span>
<n-radio-group v-model:value="queryParams.type">
<n-radio-button
v-for="song in [
{
label: '普通商品',
value: 0,
},
{
label: '活动商品',
value: 1,
},
{
label: '积分商品',
value: 2,
},
{
label: '摇球商品',
value: 3,
},
]"
:key="song.value"
:value="song.value"
:label="song.label"
/>
</n-radio-group>
</div>
</n-gi>
<n-gi span="24" mt-10 flex items-center>
<n-button type="primary" @click="getList">查询</n-button>
<n-button ml-10 @click="clear">重置</n-button>
</n-gi>
<n-gi span="24" mt-10 flex items-center>
<n-button strong secondary type="primary" @click="veeifys()">批量审核</n-button>
<n-button strong secondary ml-10 type="primary" @click="changeGoodsType(0)">
设为普通商品
</n-button>
<n-button strong secondary ml-10 type="warning" @click="changeGoodsType(1)">
设为活动商品
</n-button>
<n-button strong secondary ml-10 type="info" @click="changeGoodsType(2)">
设为兑换商品
</n-button>
<n-button strong secondary ml-10 type="error" @click="changeGoodsType(3)">
设为摇球机活动商品
</n-button>
</n-gi>
</n-grid>
<n-data-table
:loading="loading"
:columns="columns"
:data="data"
:pagination="pagination"
:bordered="false"
:row-key="(row) => row.gid"
:checked-row-keys="queryParams.checkedRowKeysRef"
remote
@update:checked-row-keys="handleCheck"
/>
<!-- 拒绝 -->
<n-modal v-model:show="isNoteModel">
<n-card
style="width: 500px"
title="拒绝信息"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<n-input v-model:value="notesVal" type="textarea" placeholder="请输入拒绝理由...." />
<div m-auto p-10>
<n-button type="primary" @click="veeify">确定</n-button>
<n-button ml-10 @click="clear">取消</n-button>
</div>
</n-card>
</n-modal>
<!-- 豆子设置 -->
<n-modal v-model:show="isDzModel">
<n-card
style="width: 500px"
title="赠送/比例"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<n-form ref="formRef" :model="nowRow" :rules="rules" label-placement="left">
<n-grid :cols="24">
<n-form-item-gi :span="20" label="商品赠送豆子" path="pulse">
<n-input-number
v-model:value="nowRow.pulse"
clearable
placeholder="请输入赠送豆子数量...."
:min="0"
/>
</n-form-item-gi>
<n-form-item-gi :span="20" label="商品赠送积分" path="integral">
<n-input-number
v-model:value="nowRow.integral"
clearable
placeholder="请输入赠送积分数量...."
:min="0"
/>
</n-form-item-gi>
<n-form-item-gi :span="18" label="商品分佣类型" path="commission_type">
<n-select
v-model:value="nowRow.commission_type"
placeholder="请选择分佣类型"
clearable
:options="[
{
label: '百分比',
value: 1,
},
{
label: '数值',
value: 2,
},
]"
/>
</n-form-item-gi>
<n-form-item-gi :span="20" label="商品分佣比例" path="commission">
<n-input-number
v-model:value="nowRow.commission"
clearable
placeholder="请输入分佣比例...."
:min="0"
/>
</n-form-item-gi>
<n-form-item-gi :span="20" label="豆子过期时间" path="expiration">
<n-input-number
v-model:value="nowRow.expiration"
clearable
placeholder="请输入豆子过期时间"
:min="0"
/>
</n-form-item-gi>
<n-form-item-gi :span="12">
<div m-auto p-10>
<n-button type="primary" @click="veeify">确定</n-button>
<n-button ml-10 @click="clear">取消</n-button>
</div>
</n-form-item-gi>
</n-grid>
</n-form>
</n-card>
</n-modal>
<!-- 商品详情 -->
<n-drawer v-model:show="showDrawer" :width="502">
<n-drawer-content title="商品详情" closable>
<n-space vertical>
<div>
<span>商品分类:</span>
<span>{{ goodInfo.class_name }}</span>
</div>
<div>
<span>商品名称:</span>
<span>{{ goodInfo.name }}</span>
</div>
<div flex items-center>
<span>封面:</span>
<n-image width="100" :src="goodInfo.cover" />
</div>
<div flex items-center>
<span>轮播图:</span>
<div w-400 overflow-auto>
<n-image
v-for="(url, index) in goodInfo.rotation?.split(',')"
:key="index"
width="100"
:src="url"
/>
</div>
</div>
<div>
<span>商品价格:</span>
<span>{{ goodInfo.number }}</span>
</div>
<div>
<span>市场价格:</span>
<span>{{ goodInfo.market_num }}</span>
</div>
<div>
<span>商品库存:</span>
<span>{{ goodInfo.stock }}</span>
</div>
<div>
<span>商品简介:</span>
<span>{{ goodInfo.profile }}</span>
</div>
<div>
<span>商品详情:</span>
<div v-html="goodInfo.details"></div>
</div>
</n-space>
</n-drawer-content>
</n-drawer>
</CommonPage>
</template>
<script setup>
import api from './api'
import { NButton, NImage, NSpace, NEllipsis, NTag } from 'naive-ui'
import { h, withDirectives, resolveDirective } from 'vue'
const vPerms = resolveDirective('perms')
const loading = ref(false)
const isNoteModel = ref(false)
const isDzModel = ref(false)
const goodInfo = ref({})
const showDrawer = ref(false)
const notesVal = ref('')
const formRef = ref(null)
const selectOptions = ref([
{
label: '商品名称',
value: 0,
},
{
label: '商家名称',
value: 1,
},
])
const queryParams = ref({
selectKey: 0,
word: '',
type: '',
status: 0,
checkedRowKeysRef: [],
})
const handleCheck = (row) => {
queryParams.value.checkedRowKeysRef = row
}
const changeGoodsType = async (type) => {
if (queryParams.value.checkedRowKeysRef.length === 0) return $message.info('没有选中商品')
await api.updateType({
type: type,
gid: queryParams.value.checkedRowKeysRef,
})
getList()
queryParams.value.checkedRowKeysRef = []
}
const rules = {
pulse: {
required: true,
type: 'number',
message: '请输入赠送豆子数量',
trigger: 'blur',
},
integral: {
required: true,
type: 'number',
message: '请输入赠送积分数量',
trigger: 'blur',
},
commission_type: {
required: true,
type: 'number',
message: '请选择分佣类型',
trigger: 'change',
},
commission: {
required: true,
type: 'number',
message: '请输入分佣比例',
trigger: 'blur',
},
}
const nowRow = ref({})
const nowKey = ref(null)
const columns = ref([
{
type: 'selection',
},
{
title: '商品名称',
slot: 'name',
align: 'center',
render: (row) => {
return h(
NEllipsis,
{
style: 'max-width: 200px',
},
{
default: () => row.name,
}
)
},
},
{
title: '商家名称',
slot: 'store_name',
align: 'center',
render: (row) => {
return h(
'span',
{},
{
default: () => row.Store.name,
}
)
},
},
{
title: '商品封面',
slot: 'cover',
align: 'center',
render(row) {
return h(NImage, {
src: row.cover,
width: '30',
})
},
},
{
title: '商品分类',
slot: 'Classify',
align: 'center',
render(row) {
return h(
'div',
{},
{
default: () => row.Classify.name,
}
)
},
},
{
title: '商品类型',
slot: 'type',
align: 'center',
render(row) {
const obj = {
0: {
type: 'success',
text: '普通商品',
},
1: {
type: 'warning',
text: '活动商品',
},
2: {
type: 'info',
text: '兑换商品',
},
3: {
type: 'error',
text: '摇球机活动商品',
},
}
return h(
NTag,
{
type: obj[row.type].type,
},
{
default: () => obj[row.type].text,
}
)
},
},
{
title: '商品价格(元)',
key: 'number',
align: 'center',
},
{
title: '商品库存',
key: 'stock',
align: 'center',
},
{
title: '赠送豆子',
key: 'pulse',
align: 'center',
},
{
title: '赠送积分',
key: 'integral',
align: 'center',
},
{
title: '分佣类型',
slot: 'commission_type',
align: 'center',
render(row) {
return row.commission_type === 1 ? '百分比' : '数值'
},
},
{
title: '分佣比例',
key: 'commission',
align: 'center',
},
{
title: '商品状态',
slot: 'status',
align: 'center',
render(row) {
return row.status === 3 ? '待审核' : row.status === 1 ? '已审核' : '已拒绝'
},
},
{
title: '备注',
key: 'notes',
align: 'center',
},
{
title: '操作',
slot: 'action',
align: 'center',
render(row) {
let el = []
if (row.status === 3) {
el = [
h(
NSpace,
{
justify: 'center',
},
{
default: () => [
withDirectives(
h(
NButton,
{
type: 'primary',
text: true,
onClick: () => {
nowKey.value = 1
nowRow.value = { ...row }
veeify()
},
},
() => '审核通过'
),
[[vPerms, ['/admin/goods/process']]]
),
withDirectives(
h(
NButton,
{
type: 'error',
text: true,
onClick: () => {
nowKey.value = 2
nowRow.value = { ...row }
isNoteModel.value = true
},
},
() => '审核拒绝'
),
[[vPerms, ['/admin/goods/process']]]
),
withDirectives(
h(
NButton,
{
type: 'warning',
text: true,
onClick: () => {
nowKey.value = 3
goodInfo.value = { ...row }
showDrawer.value = true
},
},
() => '商品详情'
),
[[vPerms, ['/admin/goods/process']]]
),
],
}
),
]
} else {
el = [
withDirectives(
h(
NButton,
{
type: 'info',
text: true,
onClick: () => {
nowRow.value = { ...row }
nowKey.value = 3
isDzModel.value = true
},
},
{
default: () => '赠送/比例',
}
),
[[vPerms, ['/admin/goods/process']]]
),
]
}
return el
},
},
])
const data = ref([])
const pagination = ref({
page: 1,
pageSize: 10,
itemCount: 0,
onChange: (page) => {
pagination.value.page = page
getList()
},
onUpdatePageSize: (pageSize) => {
pagination.value.pageSize = pageSize
pagination.value.page = 1
getList()
},
})
onMounted(() => {
getList()
})
const getList = async () => {
loading.value = true
try {
const query_data = {
status: queryParams.value.status,
type: queryParams.value.type,
}
query_data[queryParams.value.selectKey === 0 ? 'name' : 'store_name'] = queryParams.value.word
const res = await api.getHotlist({
pageNum: pagination.value.page,
pageSize: pagination.value.pageSize,
...query_data,
})
data.value = res.data.data.sort((a, b) => b.status - a.status) || []
pagination.value.itemCount = res.data.total
} catch (error) {
$message.error(error.msg)
}
loading.value = false
}
const clear = () => {
isNoteModel.value = false
isDzModel.value = false
notesVal.value = ''
nowRow.value = {}
queryParams.value = {
selectKey: 0,
word: '',
type: '',
status: 0,
checkedRowKeysRef: [],
}
getList()
}
const veeify = async () => {
let data = {}
if (nowKey.value === 1 || nowKey.value === 2) {
data = {
gid: [nowRow.value.gid],
status: nowKey.value,
notes: notesVal.value,
}
await api.getHotStatus(data)
await getList()
clear()
} else {
formRef.value?.validate(async (errors) => {
if (!errors) {
data = {
...nowRow.value,
gid: [nowRow.value.gid],
}
await api.getHotStatus(data)
await getList()
clear()
}
})
}
}
const veeifys = async () => {
if (queryParams.value.checkedRowKeysRef.length === 0) return $message.info('没有选中商品')
await api.getHotStatus({
gid: queryParams.value.checkedRowKeysRef,
status: 1,
notes: '',
})
clear()
}
</script>
<style lang="scss" scoped></style>