Files
jdt-admin/src/views/marketing/code/index.vue
Huakk 587b11e1ec
All checks were successful
continuous-integration/drone/push Build is passing
fix(custom):
2024-07-17 20:09:38 +08:00

495 lines
12 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.

<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="info" @click="saveCode">下载二维码</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"
:checked-row-keys="checkedRowKeysRef"
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 JSZip from 'jszip'
import { saveAs } from 'file-saver'
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,
}
checkedRowKeysRef.value = []
}
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,
})
}
handleclear()
getList()
} catch (error) {
// $message.error(error.msg)
}
}
})
}
// 下载二维码
const saveCode = async () => {
if (checkedRowKeysRef.value.length === 0) return $message.error('请选择二维码')
const zip = new JSZip()
data.value.forEach((item) => {
checkedRowKeysRef.value.forEach((id) => {
if (item.qid === id) {
const imageData = item.url.split(',')[1]
zip.file(`${item.qid}.png`, imageData, {
base64: true,
})
}
})
})
const content = await zip.generateAsync({ type: 'blob' })
saveAs(content, '二维码.zip')
}
</script>
<style lang="scss" scoped></style>