Skip to content

Commit 491b3a5

Browse files
author
puhui999
committed
新增 banner 管理
1 parent 0730e21 commit 491b3a5

File tree

4 files changed

+377
-1
lines changed

4 files changed

+377
-1
lines changed

src/api/mall/market/banner/index.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import request from '@/config/axios'
2+
3+
export interface BannerVO {
4+
id: number
5+
title: string
6+
picUrl: string
7+
status: number
8+
url: string
9+
sort: number
10+
memo: string
11+
}
12+
13+
// 查询Banner管理列表
14+
export const getBannerPage = async (params) => {
15+
return await request.get({ url: `/market/banner/page`, params })
16+
}
17+
18+
// 查询Banner管理详情
19+
export const getBanner = async (id: number) => {
20+
return await request.get({ url: `/market/banner/get?id=` + id })
21+
}
22+
23+
// 新增Banner管理
24+
export const createBanner = async (data: BannerVO) => {
25+
return await request.post({ url: `/market/banner/create`, data })
26+
}
27+
28+
// 修改Banner管理
29+
export const updateBanner = async (data: BannerVO) => {
30+
return await request.put({ url: `/market/banner/update`, data })
31+
}
32+
33+
// 删除Banner管理
34+
export const deleteBanner = async (id: number) => {
35+
return await request.delete({ url: `/market/banner/delete?id=` + id })
36+
}

src/views/mall/promotion/article/index.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@
7878
<!-- 列表 -->
7979
<ContentWrap>
8080
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
81-
<el-table-column align="center" label="编号" min-width="60" prop="id" />
8281
<el-table-column align="center" label="封面" min-width="80" prop="picUrl">
8382
<template #default="{ row }">
8483
<el-image :src="row.picUrl" class="h-30px w-30px" @click="imagePreview(row.picUrl)" />
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<template>
2+
<Dialog v-model="dialogVisible" :title="dialogTitle">
3+
<el-form
4+
ref="formRef"
5+
v-loading="formLoading"
6+
:model="formData"
7+
:rules="formRules"
8+
label-width="100px"
9+
>
10+
<el-row>
11+
<el-col :span="24">
12+
<el-form-item label="Banner标题" prop="title">
13+
<el-input v-model="formData.title" placeholder="请输入Banner标题" />
14+
</el-form-item>
15+
</el-col>
16+
<el-col :span="24">
17+
<el-form-item label="图片">
18+
<UploadImg v-model="formData.picUrl" />
19+
</el-form-item>
20+
</el-col>
21+
<el-col :span="24">
22+
<el-form-item label="跳转地址" prop="url">
23+
<el-input v-model="formData.url" placeholder="请输入跳转地址" />
24+
</el-form-item>
25+
</el-col>
26+
<el-col :span="24">
27+
<el-form-item label="排序" prop="sort">
28+
<el-input-number v-model="formData.sort" :min="0" clearable controls-position="right" />
29+
</el-form-item>
30+
</el-col>
31+
<el-col :span="24">
32+
<el-form-item label="状态" prop="status">
33+
<el-radio-group v-model="formData.status">
34+
<el-radio
35+
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
36+
:key="dict.value"
37+
:label="dict.value"
38+
>
39+
{{ dict.label }}
40+
</el-radio>
41+
</el-radio-group>
42+
</el-form-item>
43+
</el-col>
44+
<el-col :span="24">
45+
<el-form-item label="描述" prop="memo">
46+
<el-input v-model="formData.memo" placeholder="请输入描述" type="textarea" />
47+
</el-form-item>
48+
</el-col>
49+
</el-row>
50+
</el-form>
51+
<template #footer>
52+
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
53+
<el-button @click="dialogVisible = false">取 消</el-button>
54+
</template>
55+
</Dialog>
56+
</template>
57+
<script lang="ts" setup>
58+
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
59+
import * as BannerApi from '@/api/mall/market/banner'
60+
61+
const { t } = useI18n() // 国际化
62+
const message = useMessage() // 消息弹窗
63+
64+
const dialogVisible = ref(false) // 弹窗的是否展示
65+
const dialogTitle = ref('') // 弹窗的标题
66+
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
67+
const formType = ref('') // 表单的类型:create - 新增;update - 修改
68+
const formData = ref({
69+
id: undefined,
70+
title: undefined,
71+
picUrl: undefined,
72+
status: 0,
73+
url: undefined,
74+
sort: 0,
75+
memo: undefined
76+
})
77+
const formRules = reactive({
78+
title: [{ required: true, message: 'Banner标题不能为空', trigger: 'blur' }],
79+
picUrl: [{ required: true, message: '图片URL不能为空', trigger: 'blur' }],
80+
status: [{ required: true, message: '活动状态不能为空', trigger: 'blur' }],
81+
url: [{ required: true, message: '跳转地址不能为空', trigger: 'blur' }]
82+
})
83+
const formRef = ref() // 表单 Ref
84+
85+
/** 打开弹窗 */
86+
const open = async (type: string, id?: number) => {
87+
dialogVisible.value = true
88+
dialogTitle.value = t('action.' + type)
89+
formType.value = type
90+
resetForm()
91+
// 修改时,设置数据
92+
if (id) {
93+
formLoading.value = true
94+
try {
95+
formData.value = await BannerApi.getBanner(id)
96+
} finally {
97+
formLoading.value = false
98+
}
99+
}
100+
}
101+
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
102+
103+
/** 提交表单 */
104+
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
105+
const submitForm = async () => {
106+
// 校验表单
107+
if (!formRef) return
108+
const valid = await formRef.value.validate()
109+
if (!valid) return
110+
// 提交请求
111+
formLoading.value = true
112+
try {
113+
const data = formData.value as unknown as BannerApi.BannerVO
114+
if (formType.value === 'create') {
115+
await BannerApi.createBanner(data)
116+
message.success(t('common.createSuccess'))
117+
} else {
118+
await BannerApi.updateBanner(data)
119+
message.success(t('common.updateSuccess'))
120+
}
121+
dialogVisible.value = false
122+
// 发送操作成功的事件
123+
emit('success')
124+
} finally {
125+
formLoading.value = false
126+
}
127+
}
128+
129+
/** 重置表单 */
130+
const resetForm = () => {
131+
formData.value = {
132+
id: undefined,
133+
title: undefined,
134+
picUrl: undefined,
135+
status: 0,
136+
url: undefined,
137+
sort: 0,
138+
memo: undefined
139+
}
140+
formRef.value?.resetFields()
141+
}
142+
</script>
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
<template>
2+
<ContentWrap>
3+
<!-- 搜索工作栏 -->
4+
<el-form
5+
ref="queryFormRef"
6+
:inline="true"
7+
:model="queryParams"
8+
class="-mb-15px"
9+
label-width="100px"
10+
>
11+
<el-form-item label="Banner标题" prop="title">
12+
<el-input
13+
v-model="queryParams.title"
14+
class="!w-240px"
15+
clearable
16+
placeholder="请输入Banner标题"
17+
@keyup.enter="handleQuery"
18+
/>
19+
</el-form-item>
20+
<el-form-item label="活动状态" prop="status">
21+
<el-select v-model="queryParams.status" class="!w-240px" clearable placeholder="全部">
22+
<el-option
23+
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
24+
:key="dict.value"
25+
:label="dict.label"
26+
:value="dict.value"
27+
/>
28+
</el-select>
29+
</el-form-item>
30+
<el-form-item label="创建时间" prop="createTime">
31+
<el-date-picker
32+
v-model="queryParams.createTime"
33+
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
34+
class="!w-240px"
35+
end-placeholder="结束日期"
36+
start-placeholder="开始日期"
37+
type="daterange"
38+
value-format="YYYY-MM-DD HH:mm:ss"
39+
/>
40+
</el-form-item>
41+
<el-form-item>
42+
<el-button @click="handleQuery">
43+
<Icon class="mr-5px" icon="ep:search" />
44+
搜索
45+
</el-button>
46+
<el-button @click="resetQuery">
47+
<Icon class="mr-5px" icon="ep:refresh" />
48+
重置
49+
</el-button>
50+
<el-button
51+
v-hasPermi="['market:banner:create']"
52+
plain
53+
type="primary"
54+
@click="openForm('create')"
55+
>
56+
<Icon class="mr-5px" icon="ep:plus" />
57+
新增
58+
</el-button>
59+
</el-form-item>
60+
</el-form>
61+
</ContentWrap>
62+
63+
<!-- 列表 -->
64+
<ContentWrap>
65+
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
66+
<el-table-column align="center" label="Banner标题" prop="title" />
67+
<el-table-column align="center" label="图片" min-width="80" prop="picUrl">
68+
<template #default="{ row }">
69+
<el-image :src="row.picUrl" class="h-30px w-30px" @click="imagePreview(row.picUrl)" />
70+
</template>
71+
</el-table-column>
72+
<el-table-column align="center" label="状态" prop="status">
73+
<template #default="scope">
74+
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
75+
</template>
76+
</el-table-column>
77+
<el-table-column align="center" label="跳转地址" prop="url" />
78+
<el-table-column
79+
:formatter="dateFormatter"
80+
align="center"
81+
label="创建时间"
82+
prop="createTime"
83+
width="180px"
84+
/>
85+
<el-table-column align="center" label="排序" prop="sort" />
86+
<el-table-column align="center" label="描述" prop="memo" />
87+
<el-table-column align="center" label="操作">
88+
<template #default="scope">
89+
<el-button
90+
v-hasPermi="['market:banner:update']"
91+
link
92+
type="primary"
93+
@click="openForm('update', scope.row.id)"
94+
>
95+
编辑
96+
</el-button>
97+
<el-button
98+
v-hasPermi="['market:banner:delete']"
99+
link
100+
type="danger"
101+
@click="handleDelete(scope.row.id)"
102+
>
103+
删除
104+
</el-button>
105+
</template>
106+
</el-table-column>
107+
</el-table>
108+
<!-- 分页 -->
109+
<Pagination
110+
v-model:limit="queryParams.pageSize"
111+
v-model:page="queryParams.pageNo"
112+
:total="total"
113+
@pagination="getList"
114+
/>
115+
</ContentWrap>
116+
117+
<!-- 表单弹窗:添加/修改 -->
118+
<BannerForm ref="formRef" @success="getList" />
119+
</template>
120+
121+
<script lang="ts" setup>
122+
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
123+
import { dateFormatter } from '@/utils/formatTime'
124+
import * as BannerApi from '@/api/mall/market/banner'
125+
import BannerForm from './BannerForm.vue'
126+
import { createImageViewer } from '@/components/ImageViewer'
127+
128+
defineOptions({ name: 'Banner' })
129+
130+
const message = useMessage() // 消息弹窗
131+
const { t } = useI18n() // 国际化
132+
133+
const loading = ref(true) // 列表的加载中
134+
const total = ref(0) // 列表的总页数
135+
const list = ref([]) // 列表的数据
136+
const queryParams = reactive({
137+
pageNo: 1,
138+
pageSize: 10,
139+
title: null,
140+
status: null,
141+
createTime: []
142+
})
143+
const queryFormRef = ref() // 搜索的表单
144+
145+
/** 文章封面预览 */
146+
const imagePreview = (imgUrl: string) => {
147+
createImageViewer({
148+
urlList: [imgUrl]
149+
})
150+
}
151+
152+
/** 查询列表 */
153+
const getList = async () => {
154+
loading.value = true
155+
try {
156+
const data = await BannerApi.getBannerPage(queryParams)
157+
list.value = data.list
158+
total.value = data.total
159+
} finally {
160+
loading.value = false
161+
}
162+
}
163+
164+
/** 搜索按钮操作 */
165+
const handleQuery = () => {
166+
queryParams.pageNo = 1
167+
getList()
168+
}
169+
170+
/** 重置按钮操作 */
171+
const resetQuery = () => {
172+
queryFormRef.value.resetFields()
173+
handleQuery()
174+
}
175+
176+
/** 添加/修改操作 */
177+
const formRef = ref()
178+
const openForm = (type: string, id?: number) => {
179+
formRef.value.open(type, id)
180+
}
181+
182+
/** 删除按钮操作 */
183+
const handleDelete = async (id: number) => {
184+
try {
185+
// 删除的二次确认
186+
await message.delConfirm()
187+
// 发起删除
188+
await BannerApi.deleteBanner(id)
189+
message.success(t('common.delSuccess'))
190+
// 刷新列表
191+
await getList()
192+
} catch {}
193+
}
194+
195+
/** 初始化 **/
196+
onMounted(() => {
197+
getList()
198+
})
199+
</script>

0 commit comments

Comments
 (0)