This commit is contained in:
41
package.json
41
package.json
@@ -33,50 +33,53 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@unocss/eslint-config": "^0.55.7",
|
||||
"@vueuse/core": "^10.6.1",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"axios": "^1.6.2",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^5.4.3",
|
||||
"axios": "^1.7.2",
|
||||
"dayjs": "^1.11.11",
|
||||
"echarts": "^5.5.1",
|
||||
"file-saver": "^2.0.5",
|
||||
"jszip": "^3.10.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"md-editor-v3": "^4.9.0",
|
||||
"md-editor-v3": "^4.17.3",
|
||||
"mockjs": "^1.1.0",
|
||||
"pinia": "^2.1.7",
|
||||
"vite": "^4.5.0",
|
||||
"vite": "^4.5.3",
|
||||
"vue": "3.3.4",
|
||||
"vue-echarts": "^6.6.1",
|
||||
"vue-router": "^4.2.5",
|
||||
"vue-echarts": "^6.7.3",
|
||||
"vue-router": "^4.4.0",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.8.1",
|
||||
"@commitlint/config-conventional": "^17.8.1",
|
||||
"@iconify/json": "^2.2.150",
|
||||
"@iconify/vue": "^4.1.1",
|
||||
"@iconify/json": "^2.2.228",
|
||||
"@iconify/vue": "^4.1.2",
|
||||
"@unocss/preset-rem-to-px": "^0.55.7",
|
||||
"@vitejs/plugin-vue": "^4.5.1",
|
||||
"@vue/compiler-sfc": "^3.3.9",
|
||||
"@vitejs/plugin-vue": "^4.6.2",
|
||||
"@vue/compiler-sfc": "^3.4.32",
|
||||
"@zclzone/eslint-config": "^0.0.4",
|
||||
"chalk": "^5.3.0",
|
||||
"commitizen": "^4.3.0",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"cz-customizable": "^7.0.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"cz-customizable": "^7.1.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"esno": "^0.17.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^13.3.0",
|
||||
"naive-ui": "^2.35.0",
|
||||
"rollup-plugin-visualizer": "^5.9.3",
|
||||
"sass": "^1.69.5",
|
||||
"naive-ui": "^2.39.0",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"sass": "^1.77.8",
|
||||
"unocss": "0.55.0",
|
||||
"unplugin-auto-import": "^0.16.7",
|
||||
"unplugin-icons": "^0.16.6",
|
||||
"unplugin-vue-components": "^0.25.2",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-mock": "^2.9.8",
|
||||
"vite-plugin-svg-icons": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@9.1.4+sha512.9df9cf27c91715646c7d675d1c9c8e41f6fce88246f1318c1aa6a1ed1aeb3c4f032fcdf4ba63cc69c4fe6d634279176b5358727d8f2cc1e65b65f43ce2f8bfb0"
|
||||
}
|
||||
|
||||
3383
pnpm-lock.yaml
generated
3383
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -64,11 +64,11 @@ function filterAsyncRoutes(routes = [], firstRoute = true) {
|
||||
children: [],
|
||||
}
|
||||
|
||||
if (route.route === '/' && firstRoute) {
|
||||
curRoute['redirect'] = route.subMenu[0].route
|
||||
} else if (route.subMenu && route.type === 1) {
|
||||
curRoute['redirect'] = `${route.subMenu[0].route}`
|
||||
}
|
||||
// if (route.route === '/' && firstRoute) {
|
||||
// curRoute['redirect'] = route.subMenu[0].route
|
||||
// } else if (route.subMenu && route.type === 1) {
|
||||
// curRoute['redirect'] = `${route.subMenu[0].route}`
|
||||
// }
|
||||
|
||||
if (route.subMenu && route.subMenu.length) {
|
||||
curRoute.children = filterAsyncRoutes(route.subMenu, false)
|
||||
@@ -84,7 +84,6 @@ function filterAsyncRoutes(routes = [], firstRoute = true) {
|
||||
curRoute.component = loadRouteView(route.components)
|
||||
break
|
||||
}
|
||||
|
||||
ret.push(curRoute)
|
||||
})
|
||||
return ret
|
||||
|
||||
@@ -3,4 +3,5 @@ import { request } from '@/utils'
|
||||
export default {
|
||||
getHotlist: (data) => request.post('/goods', data),
|
||||
getHotStatus: (data) => request.post('/goods/process', data),
|
||||
updateType: (data) => request.post('/goods/edit/activity', data),
|
||||
}
|
||||
|
||||
@@ -1,13 +1,49 @@
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<template>
|
||||
<CommonPage show-footer :title="$route.title">
|
||||
<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: '20%' }"
|
||||
:options="selectOptions"
|
||||
placeholder="请选择"
|
||||
/>
|
||||
<n-input v-model:value="queryParams.word" :style="{ width: '30%' }" />
|
||||
</n-input-group>
|
||||
</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="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">
|
||||
@@ -152,7 +188,7 @@
|
||||
|
||||
<script setup>
|
||||
import api from './api'
|
||||
import { NButton, NImage, NSpace, NEllipsis } from 'naive-ui'
|
||||
import { NButton, NImage, NSpace, NEllipsis, NTag } from 'naive-ui'
|
||||
import { h, withDirectives, resolveDirective } from 'vue'
|
||||
|
||||
const vPerms = resolveDirective('perms')
|
||||
@@ -171,6 +207,33 @@ const notesVal = ref('')
|
||||
|
||||
const formRef = ref(null)
|
||||
|
||||
const selectOptions = ref([
|
||||
{
|
||||
label: '商品名称',
|
||||
value: 0,
|
||||
},
|
||||
])
|
||||
|
||||
const queryParams = ref({
|
||||
selectKey: 0,
|
||||
word: '',
|
||||
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,
|
||||
@@ -202,6 +265,9 @@ const nowRow = ref({})
|
||||
const nowKey = ref(null)
|
||||
|
||||
const columns = ref([
|
||||
{
|
||||
type: 'selection',
|
||||
},
|
||||
{
|
||||
title: '商品名称',
|
||||
slot: 'name',
|
||||
@@ -243,6 +309,40 @@ const columns = ref([
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
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',
|
||||
@@ -411,8 +511,9 @@ const getList = async () => {
|
||||
const res = await api.getHotlist({
|
||||
pageNum: pagination.value.page,
|
||||
pageSize: pagination.value.pageSize,
|
||||
name: queryParams.value.word,
|
||||
})
|
||||
data.value = res.data.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)
|
||||
@@ -425,6 +526,8 @@ const clear = () => {
|
||||
isDzModel.value = false
|
||||
notesVal.value = ''
|
||||
nowRow.value = {}
|
||||
queryParams.value.word = ''
|
||||
getList()
|
||||
}
|
||||
|
||||
const veeify = async () => {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<img src="@/assets/images/404.webp" width="500" />
|
||||
</template>
|
||||
<template #footer>
|
||||
<n-button @click="replace('/')">返回首页</n-button>
|
||||
<n-button @click="replace('/workbench')">返回首页</n-button>
|
||||
</template>
|
||||
</n-result>
|
||||
</AppPage>
|
||||
|
||||
@@ -109,13 +109,15 @@ async function handleLogin() {
|
||||
lStorage.remove('loginInfo')
|
||||
}
|
||||
await addDynamicRoutes()
|
||||
// console.log(query)
|
||||
if (query.redirect) {
|
||||
const path = query.redirect
|
||||
Reflect.deleteProperty(query, 'redirect')
|
||||
router.push({ path, query })
|
||||
} else {
|
||||
router.push('/')
|
||||
router.push('/workbench')
|
||||
}
|
||||
// router.push('/workbench')
|
||||
} catch (error) {
|
||||
$message.removeMessage()
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
|
||||
494
src/views/marketing/code/index.vue
Normal file
494
src/views/marketing/code/index.vue
Normal file
@@ -0,0 +1,494 @@
|
||||
<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>
|
||||
@@ -251,7 +251,7 @@ const columns = ref([
|
||||
title: '支付方式',
|
||||
align: 'center',
|
||||
slot: 'pay_type',
|
||||
render: (row) => h('span', row.pay_type === 1 ? '微信' : '积分'),
|
||||
render: (row) => h('span', row.PayInfo.name),
|
||||
},
|
||||
{
|
||||
title: '商家名称',
|
||||
|
||||
@@ -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([])
|
||||
|
||||
7
src/views/system/payMag/api.js
Normal file
7
src/views/system/payMag/api.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { request } from '@/utils'
|
||||
|
||||
export default {
|
||||
getData: (data) => request.post('/paytype/list', data),
|
||||
add: (data) => request.post('/paytype/add', data),
|
||||
edit: (data) => request.post('/paytype/edit', data),
|
||||
}
|
||||
283
src/views/system/payMag/index.vue
Normal file
283
src/views/system/payMag/index.vue
Normal file
@@ -0,0 +1,283 @@
|
||||
<template>
|
||||
<CommonPage show-footer :title="$route.title">
|
||||
<n-button v-perms="['/admin/paytype/add']" type="primary" @click="openModal(1)">
|
||||
添加支付方式
|
||||
</n-button>
|
||||
<n-data-table
|
||||
class="mt-5"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
:pagination="pagination"
|
||||
:bordered="false"
|
||||
remote
|
||||
/>
|
||||
|
||||
<n-modal v-model:show="showModal">
|
||||
<n-card
|
||||
style="width: 600px"
|
||||
title="添加/编辑支付方式"
|
||||
:bordered="false"
|
||||
size="huge"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
>
|
||||
<n-form ref="formRef" :model="model" :rules="rules" label-placement="left">
|
||||
<n-grid :cols="24" :x-gap="24">
|
||||
<n-form-item-gi :span="16" label="支付图标:" path="icon">
|
||||
<Upload v-model:list="model.icon" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="16" label="支付名称:" path="name">
|
||||
<n-input v-model:value="model.name" placeholder="请输入支付名称" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="16" label="启用状态:">
|
||||
<n-switch v-model:value="model.status" :checked-value="1" :unchecked-value="2" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="16" label="余额状态:" path="state">
|
||||
<n-select
|
||||
v-model:value="model.state"
|
||||
:options="[
|
||||
{
|
||||
label: '无限',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '有限',
|
||||
value: 2,
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi v-if="model.state === 2" :span="16" label="商家余额:" path="amount">
|
||||
<n-input-number v-model:value="model.amount" placeholder="请输入商家余额" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="18">
|
||||
<div m-auto>
|
||||
<n-button type="primary" @click="handleValidateClick">保存</n-button>
|
||||
<n-button ml-10 @click="clear">取消</n-button>
|
||||
</div>
|
||||
</n-form-item-gi>
|
||||
</n-grid>
|
||||
</n-form>
|
||||
</n-card>
|
||||
</n-modal>
|
||||
</CommonPage>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { h, withDirectives, resolveDirective } from 'vue'
|
||||
import api from './api'
|
||||
import { NTag, NButton } from 'naive-ui'
|
||||
import Upload from '@/components/Upload.vue'
|
||||
|
||||
const vPerms = resolveDirective('perms')
|
||||
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
const columns = ref([
|
||||
{
|
||||
title: 'icon',
|
||||
slot: 'icon',
|
||||
align: 'center',
|
||||
render: (row) => {
|
||||
return h('img', {
|
||||
src: row.icon[0].url,
|
||||
width: 50,
|
||||
height: 50,
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '支付名称',
|
||||
key: 'name',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
slot: 'status',
|
||||
align: 'center',
|
||||
render: (row) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: row.status === 1 ? 'success' : 'warning',
|
||||
},
|
||||
{
|
||||
default: () => (row.status === 1 ? '启用' : '禁用'),
|
||||
}
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '商家余额',
|
||||
slot: 'amount',
|
||||
align: 'center',
|
||||
render: (row) => {
|
||||
return h(
|
||||
'span',
|
||||
{},
|
||||
{
|
||||
default: () => (row.state === 1 ? '无限' : row.amount),
|
||||
}
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '余额状态',
|
||||
slot: 'state',
|
||||
align: 'center',
|
||||
render: (row) => {
|
||||
return h(
|
||||
'span',
|
||||
{},
|
||||
{
|
||||
default: () => (row.state === 1 ? '无限' : '有限'),
|
||||
}
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
slot: 'action',
|
||||
align: 'center',
|
||||
render: (row) => {
|
||||
return [
|
||||
withDirectives(
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
text: true,
|
||||
onClick: () => {
|
||||
openModal(2, row)
|
||||
},
|
||||
},
|
||||
{
|
||||
default: () => '编辑',
|
||||
}
|
||||
),
|
||||
[[vPerms, ['/admin/paytype/edit']]]
|
||||
),
|
||||
]
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
const data = ref([])
|
||||
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
itemCount: 0,
|
||||
onChange: (page) => {
|
||||
pagination.value.page = page
|
||||
getList()
|
||||
},
|
||||
})
|
||||
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
const res = await api.getData({
|
||||
page: pagination.value.page,
|
||||
pageSize: pagination.value.pageSize,
|
||||
})
|
||||
data.value =
|
||||
res.data.data.map((item) => ({
|
||||
...item,
|
||||
icon: [
|
||||
{
|
||||
id: item.ID,
|
||||
url: item.icon,
|
||||
status: 'finished',
|
||||
},
|
||||
],
|
||||
})) || []
|
||||
// console.log(res)
|
||||
pagination.value.itemCount = res.data.total
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const showModal = ref(false)
|
||||
|
||||
const model = ref({
|
||||
icon: [],
|
||||
name: '',
|
||||
status: 1,
|
||||
state: 1,
|
||||
amount: 0,
|
||||
})
|
||||
|
||||
const formRef = ref(null)
|
||||
|
||||
const rules = ref({
|
||||
icon: {
|
||||
required: true,
|
||||
type: 'array',
|
||||
message: '请上传图片',
|
||||
},
|
||||
name: {
|
||||
required: true,
|
||||
message: '请输入支付名称',
|
||||
},
|
||||
state: {
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请选择余额状态',
|
||||
},
|
||||
amount: {
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请输入商家余额',
|
||||
},
|
||||
})
|
||||
|
||||
const nowType = ref(1)
|
||||
|
||||
const openModal = (type, row = {}) => {
|
||||
nowType.value = type
|
||||
if (type === 2) {
|
||||
model.value = {
|
||||
...row,
|
||||
}
|
||||
}
|
||||
showModal.value = true
|
||||
}
|
||||
|
||||
const handleValidateClick = async (e) => {
|
||||
e.preventDefault()
|
||||
formRef.value?.validate(async (errors) => {
|
||||
if (!errors) {
|
||||
try {
|
||||
const data = {
|
||||
...model.value,
|
||||
icon: model.value.icon[0].url,
|
||||
}
|
||||
if (nowType.value === 1) {
|
||||
await api.add(data)
|
||||
} else {
|
||||
await api.edit(data)
|
||||
}
|
||||
clear()
|
||||
getList()
|
||||
} catch (error) {
|
||||
$message.error(error.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
const clear = async () => {
|
||||
model.value = {
|
||||
icon: [],
|
||||
name: '',
|
||||
status: 1,
|
||||
state: 1,
|
||||
amount: 0,
|
||||
}
|
||||
showModal.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
Reference in New Issue
Block a user