feat(custom): 新增营销-\>二维码管理
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-06-21 19:51:02 +08:00
parent 0865529e10
commit c233ad8f5a
4 changed files with 505 additions and 10 deletions

View File

@@ -78,5 +78,6 @@
"vite-plugin-html": "^3.2.0",
"vite-plugin-mock": "^2.9.8",
"vite-plugin-svg-icons": "^2.0.1"
}
},
"packageManager": "pnpm@9.1.4+sha512.9df9cf27c91715646c7d675d1c9c8e41f6fce88246f1318c1aa6a1ed1aeb3c4f032fcdf4ba63cc69c4fe6d634279176b5358727d8f2cc1e65b65f43ce2f8bfb0"
}

View File

@@ -3,4 +3,7 @@ import { request } from '@/utils'
export default {
getSignConfig: () => request.post('/gift/setting'),
setSignConfig: (data) => request.post('/gift/setting/edit', data),
getCodelist: (data) => request.post('/qrcode/list', data),
addCode: (data) => request.post('/qrcode/add', data),
updateCode: (data) => request.post('/qrcode/edit', data),
}

View File

@@ -0,0 +1,469 @@
<template>
<CommonPage show-footer :title="$route.title">
<!-- {{ queryData }} -->
<n-row gutter="12">
<n-col :span="24">
<div flex>
<n-card w-500>
<n-statistic label="未激活" tabular-nums>
<n-number-animation ref="numberAnimationInstRef" :from="0" :to="cardData.total" />
</n-statistic>
</n-card>
<n-card ml-10 w-500>
<n-statistic label="已激活" tabular-nums>
<n-number-animation ref="numberAnimationInstRef" :from="0" :to="cardData.service" />
</n-statistic>
</n-card>
<n-card ml-10 w-500>
<n-statistic label="未领取" tabular-nums>
<n-number-animation ref="numberAnimationInstRef" :from="0" :to="cardData.count" />
</n-statistic>
</n-card>
<n-card ml-10 w-500>
<n-statistic label="已领取" tabular-nums>
<n-number-animation ref="numberAnimationInstRef" :from="0" :to="cardData.count" />
</n-statistic>
</n-card>
</div>
</n-col>
<n-col :span="24">
<div mt-10>
<span>激活状态</span>
<n-radio-group v-model:value="queryData.status">
<n-radio-button
v-for="song in songs"
:key="song.value"
:value="song.value"
:label="song.label"
/>
</n-radio-group>
</div>
</n-col>
<n-col :span="24">
<div mt-10>
<span>领取状态</span>
<n-radio-group v-model:value="queryData.status1">
<n-radio-button
v-for="song in songs1"
:key="song.value"
:value="song.value"
:label="song.label"
/>
</n-radio-group>
</div>
</n-col>
<n-col :span="24">
<div mt-10 flex items-center>
<div w-100>关键字搜索</div>
<n-input-group>
<n-select
v-model:value="queryData.selectKey"
:style="{ width: '15%' }"
:options="selectOptions"
placeholder="请选择"
/>
<n-input v-model:value="queryData.word" :style="{ width: '20%' }" />
</n-input-group>
</div>
</n-col>
<n-col :span="10">
<div mt-10 flex items-center>
<span w-100>时间搜索</span>
<n-date-picker
v-model:formatted-value="queryData.time"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
clearable
/>
</div>
</n-col>
<n-col :span="24">
<div mt-10>
<n-button v-perms="['/admin/qrcode/add']" mr-10 type="primary" @click="openModal(1)">
新增二维码
</n-button>
<n-button v-perms="['/admin/qrcode/edit']" mr-10 type="warning" @click="openModal(2)">
修改二维码
</n-button>
<!-- <n-button mr-10 type="primary" @click="openModal(1)">新增二维码</n-button> -->
<!-- <n-button mr-10 type="warning" @click="openModal(3)">修改二维码</n-button> -->
<n-button type="primary" @click="getList">搜索</n-button>
<n-button ml-10 @click="clear">重置</n-button>
</div>
</n-col>
</n-row>
<n-data-table
class="mt-5"
:loading="loading"
:columns="columns"
:data="data"
:pagination="pagination"
:bordered="false"
:row-key="rowKey"
remote
@update:checked-row-keys="handleCheck"
/>
<n-modal v-model:show="showModal" :auto-focus="false">
<n-card
style="width: 600px"
:title="modelTitle"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<n-form ref="formRef" label-placement="left" :model="formValue" :rules="rules">
<n-form-item v-if="modalType === 1" label="新增数量:" path="number">
<n-input-number v-model:value="formValue.number" :min="1" clearable />
</n-form-item>
<n-form-item label="赠送豆子:" path="pulse">
<n-input-number v-model:value="formValue.pulse" :min="1" clearable />
</n-form-item>
<n-form-item label="激活状态:" path="activate_status">
<n-switch
v-model:value="formValue.activate_status"
:checked-value="1"
:unchecked-value="2"
/>
</n-form-item>
<n-form-item>
<div class="m-auto">
<n-button
class="m-auto"
type="primary"
attr-type="button"
@click="handleValidateClick"
>
提交
</n-button>
<n-button class="ml-10" @click="handleclear">取消</n-button>
</div>
</n-form-item>
</n-form>
</n-card>
</n-modal>
</CommonPage>
</template>
<script setup>
import { NButton } from 'naive-ui'
import api from '../api'
import { ref, resolveDirective, withDirectives } from 'vue'
const vPerms = resolveDirective('perms')
const songs = ref([
{
value: 1,
label: '已激活',
},
{
value: 2,
label: '未激活',
},
])
const songs1 = ref([
{
value: 1,
label: '已领取',
},
{
value: 2,
label: '未领取',
},
])
const selectOptions = ref([
{
value: 0,
label: 'ID',
},
{
value: 1,
label: '手机号',
},
])
const queryData = ref({
status: '',
status1: '',
time: null,
word: '',
selectKey: null,
})
const cardData = ref({})
const columns = ref([
{
type: 'selection',
},
{
title: 'ID',
align: 'center',
key: 'qid',
},
{
title: '二维码',
align: 'center',
slot: 'qrcode',
render(row) {
return h('img', {
src: row.url,
style: {
width: '50px',
height: '50px',
},
})
},
},
{
title: '用户',
align: 'center',
slot: 'user_name',
render(row) {
return h('span', row.User.nickName)
},
},
{
title: '用户电话',
align: 'center',
slot: 'phone',
render(row) {
return h('span', row.User.phone)
},
},
{
title: '赠送豆子',
align: 'center',
key: 'pulse',
},
{
title: '激活状态',
align: 'center',
slot: 'status',
render(row) {
switch (row.activate_status) {
case 1:
return h('span', '已激活')
case 2:
return h('span', '未激活')
}
},
},
{
title: '领取状态',
align: 'center',
slot: 'status',
render(row) {
switch (row.use_status) {
case 1:
return h('span', '已领取')
case 2:
return h('span', '未领取')
}
},
},
{
title: '激活时间',
align: 'center',
key: 'activate_time',
},
{
title: '领取时间',
align: 'center',
key: 'use_time',
},
{
title: '操作',
align: 'center',
slot: 'action',
render(row) {
if (row.use_status === 2) {
return withDirectives(
h(
NButton,
{
type: 'primary',
size: 'small',
onClick: () => openModal(2, row),
},
{
default: () => '编辑',
}
),
[[vPerms, ['/admin/qrcode/edit']]]
)
// return h(
// NButton,
// {
// type: 'primary',
// size: 'small',
// onClick: () => {
// openModal(2, row)
// },
// },
// {
// default: () => '编辑',
// }
// )
}
},
},
])
const data = ref([])
const pagination = ref({
page: 1,
pageSize: 10,
itemCount: 0,
prefix: ({ itemCount }) => {
return `${itemCount}`
},
onChange: (page) => {
pagination.value.page = page
getList()
},
onUpdatePageSize: (pageSize) => {
pagination.value.pageSize = pageSize
pagination.value.page = 1
getList()
},
})
onMounted(() => {
getList()
})
const loading = ref(false)
const getList = async () => {
loading.value = true
try {
const query_data = {
UseStatus: queryData.value.status,
ActivateStatus: queryData.value.status1,
StartTime: queryData.value.time === null ? '' : queryData.value.time[0] || '',
EndTime: queryData.value.time === null ? '' : queryData.value.time[1] || '',
}
switch (queryData.value.selectKey) {
case 0:
query_data['Qid'] = queryData.value.word
break
case 1:
query_data['Phone'] = queryData.value.word
break
}
const res = await api.getCodelist({
pageNum: pagination.value.page,
pageSize: pagination.value.pageSize,
...query_data,
})
data.value = res.data.data || []
pagination.value.itemCount = res.data.total
cardData.value.total = res.data.number
cardData.value.service = res.data.commission
cardData.value.count = 0
} catch (error) {
$message.error(error.msg)
}
loading.value = false
}
const clear = () => {
queryData.value = {
status: '',
status1: '',
time: null,
word: '',
selectKey: null,
}
getList()
}
const rowKey = (row) => row.qid
const checkedRowKeysRef = ref([])
const handleCheck = (rowKeys) => {
checkedRowKeysRef.value = rowKeys
}
const showModal = ref(false)
const modelTitle = ref('')
const formValue = ref({
number: null,
pulse: null,
activate_status: 2,
})
const rules = {
number: {
required: true,
type: 'number',
message: '请输入生成数量',
trigger: 'blur',
},
pulse: {
required: true,
type: 'number',
message: '请输入豆子数量',
trigger: 'blur',
},
}
const handleclear = () => {
showModal.value = false
formValue.value = {
number: null,
pulse: null,
activate_status: 2,
}
}
const modalType = ref(null)
const nowRow = ref([])
const openModal = (e, row) => {
showModal.value = true
modalType.value = e
modelTitle.value = e === 1 ? '新增二维码' : '编辑二维码'
if (e === 2) {
nowRow.value = [row.qid]
formValue.value.pulse = row.pulse
formValue.value.activate_status = row.activate_status
} else if (e === 3) {
nowRow.value = checkedRowKeysRef.value
}
}
const formRef = ref(null)
const handleValidateClick = (e) => {
e.preventDefault()
formRef.value?.validate(async (errors) => {
if (!errors) {
try {
if (modalType.value === 1) {
await api.addCode(formValue.value)
} else {
await api.updateCode({
qid: nowRow.value,
...formValue.value,
})
}
$message.success('成功')
handleclear()
getList()
} catch (error) {
// $message.error(error.msg)
}
}
})
}
</script>
<style lang="scss" scoped></style>

View File

@@ -90,7 +90,7 @@
<script setup>
import api from './api'
import { NEllipsis } from 'naive-ui'
import { NEllipsis, NButton, NPopconfirm } from 'naive-ui'
const loading = ref(false)
@@ -144,6 +144,8 @@ const columns = ref([
title: '订单号',
align: 'center',
key: 'oid',
width: 150,
fixed: 'left',
},
{
title: '用户',
@@ -228,14 +230,34 @@ const columns = ref([
align: 'center',
key: 'payment_time',
},
// {
// title: '操作',
// align: 'center',
// slot: 'action',
// render() {
// // console.log(row)
// },
// },
{
title: '操作',
align: 'center',
slot: 'action',
width: 100,
fixed: 'right',
render(row) {
return h(
NPopconfirm,
{},
{
default: () => '确定核销吗?',
trigger: () =>
h(
NButton,
{
text: true,
type: 'info',
onClick: () => {
console.log(row)
},
},
{ default: () => '核销' }
),
}
)
},
},
])
const data = ref([])