Skip to content

Commit 36bb90f

Browse files
author
puhui999
committed
营销活动:新增文章分类管理
1 parent 532b237 commit 36bb90f

File tree

3 files changed

+381
-0
lines changed

3 files changed

+381
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import request from '@/config/axios'
2+
3+
export interface ArticleCategoryVO {
4+
id: number
5+
name: string
6+
picUrl: string
7+
status: number
8+
sort: number
9+
}
10+
11+
// 查询分类列表
12+
export const getArticleCategoryPage = async (params) => {
13+
return await request.get({ url: `/promotion/article-category/page`, params })
14+
}
15+
16+
// 查询分类详情
17+
export const getArticleCategory = async (id: number) => {
18+
return await request.get({ url: `/promotion/article-category/get?id=` + id })
19+
}
20+
21+
// 新增分类
22+
export const createArticleCategory = async (data: ArticleCategoryVO) => {
23+
return await request.post({ url: `/promotion/article-category/create`, data })
24+
}
25+
26+
// 修改分类
27+
export const updateArticleCategory = async (data: ArticleCategoryVO) => {
28+
return await request.put({ url: `/promotion/article-category/update`, data })
29+
}
30+
31+
// 删除分类
32+
export const deleteArticleCategory = async (id: number) => {
33+
return await request.delete({ url: `/promotion/article-category/delete?id=` + id })
34+
}
35+
36+
// 导出分类 Excel
37+
export const exportArticleCategory = async (params) => {
38+
return await request.download({ url: `/promotion/article-category/export-excel`, params })
39+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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-form-item label="分类名称" prop="name">
11+
<el-input v-model="formData.name" placeholder="请输入分类名称" />
12+
</el-form-item>
13+
<el-form-item label="图标地址" prop="picUrl">
14+
<UploadImg v-model="formData.picUrl" height="80px" />
15+
</el-form-item>
16+
<el-form-item label="状态" prop="status">
17+
<el-radio-group v-model="formData.status">
18+
<el-radio
19+
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
20+
:key="dict.value"
21+
:label="dict.value"
22+
>
23+
{{ dict.label }}
24+
</el-radio>
25+
</el-radio-group>
26+
</el-form-item>
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-form>
31+
<template #footer>
32+
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
33+
<el-button @click="dialogVisible = false">取 消</el-button>
34+
</template>
35+
</Dialog>
36+
</template>
37+
<script lang="ts" setup>
38+
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
39+
import * as ArticleCategoryApi from '@/api/mall/promotion/articleCategory'
40+
41+
const { t } = useI18n() // 国际化
42+
const message = useMessage() // 消息弹窗
43+
44+
const dialogVisible = ref(false) // 弹窗的是否展示
45+
const dialogTitle = ref('') // 弹窗的标题
46+
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
47+
const formType = ref('') // 表单的类型:create - 新增;update - 修改
48+
const formData = ref({
49+
id: undefined,
50+
name: undefined,
51+
picUrl: undefined,
52+
status: undefined,
53+
sort: undefined
54+
})
55+
const formRules = reactive({
56+
name: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }],
57+
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
58+
sort: [{ required: true, message: '排序不能为空', trigger: 'blur' }]
59+
})
60+
const formRef = ref() // 表单 Ref
61+
62+
/** 打开弹窗 */
63+
const open = async (type: string, id?: number) => {
64+
dialogVisible.value = true
65+
dialogTitle.value = t('action.' + type)
66+
formType.value = type
67+
resetForm()
68+
// 修改时,设置数据
69+
if (id) {
70+
formLoading.value = true
71+
try {
72+
formData.value = await ArticleCategoryApi.getArticleCategory(id)
73+
} finally {
74+
formLoading.value = false
75+
}
76+
}
77+
}
78+
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
79+
80+
/** 提交表单 */
81+
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
82+
const submitForm = async () => {
83+
// 校验表单
84+
if (!formRef) return
85+
const valid = await formRef.value.validate()
86+
if (!valid) return
87+
// 提交请求
88+
formLoading.value = true
89+
try {
90+
const data = formData.value as unknown as ArticleCategoryApi.ArticleCategoryVO
91+
if (formType.value === 'create') {
92+
await ArticleCategoryApi.createArticleCategory(data)
93+
message.success(t('common.createSuccess'))
94+
} else {
95+
await ArticleCategoryApi.updateArticleCategory(data)
96+
message.success(t('common.updateSuccess'))
97+
}
98+
dialogVisible.value = false
99+
// 发送操作成功的事件
100+
emit('success')
101+
} finally {
102+
formLoading.value = false
103+
}
104+
}
105+
106+
/** 重置表单 */
107+
const resetForm = () => {
108+
formData.value = {
109+
id: undefined,
110+
name: undefined,
111+
picUrl: undefined,
112+
status: undefined,
113+
sort: undefined
114+
}
115+
formRef.value?.resetFields()
116+
}
117+
</script>
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
<template>
2+
<ContentWrap>
3+
<!-- 搜索工作栏 -->
4+
<el-form
5+
ref="queryFormRef"
6+
:inline="true"
7+
:model="queryParams"
8+
class="-mb-15px"
9+
label-width="68px"
10+
>
11+
<el-form-item label="分类名称" prop="name">
12+
<el-input
13+
v-model="queryParams.name"
14+
class="!w-240px"
15+
clearable
16+
placeholder="请输入分类名称"
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="['promotion:article-category: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-button
60+
v-hasPermi="['promotion:article-category:export']"
61+
:loading="exportLoading"
62+
plain
63+
type="success"
64+
@click="handleExport"
65+
>
66+
<Icon class="mr-5px" icon="ep:download" />
67+
导出
68+
</el-button>
69+
</el-form-item>
70+
</el-form>
71+
</ContentWrap>
72+
73+
<!-- 列表 -->
74+
<ContentWrap>
75+
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
76+
<el-table-column align="center" label="编号" prop="id" />
77+
<el-table-column align="center" label="分类名称" prop="name" />
78+
<el-table-column label="分类图图" min-width="80">
79+
<template #default="{ row }">
80+
<el-image :src="row.picUrl" class="h-30px w-30px" @click="imagePreview(row.picUrl)" />
81+
</template>
82+
</el-table-column>
83+
<el-table-column align="center" label="状态" prop="status">
84+
<template #default="scope">
85+
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
86+
</template>
87+
</el-table-column>
88+
<el-table-column align="center" label="排序" prop="sort" />
89+
<el-table-column
90+
:formatter="dateFormatter"
91+
align="center"
92+
label="创建时间"
93+
prop="createTime"
94+
width="180px"
95+
/>
96+
<el-table-column align="center" label="操作">
97+
<template #default="scope">
98+
<el-button
99+
v-hasPermi="['promotion:article-category:update']"
100+
link
101+
type="primary"
102+
@click="openForm('update', scope.row.id)"
103+
>
104+
编辑
105+
</el-button>
106+
<el-button
107+
v-hasPermi="['promotion:article-category:delete']"
108+
link
109+
type="danger"
110+
@click="handleDelete(scope.row.id)"
111+
>
112+
删除
113+
</el-button>
114+
</template>
115+
</el-table-column>
116+
</el-table>
117+
<!-- 分页 -->
118+
<Pagination
119+
v-model:limit="queryParams.pageSize"
120+
v-model:page="queryParams.pageNo"
121+
:total="total"
122+
@pagination="getList"
123+
/>
124+
</ContentWrap>
125+
126+
<!-- 表单弹窗:添加/修改 -->
127+
<ArticleCategoryForm ref="formRef" @success="getList" />
128+
</template>
129+
130+
<script lang="ts" setup>
131+
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
132+
import { dateFormatter } from '@/utils/formatTime'
133+
import download from '@/utils/download'
134+
import * as ArticleCategoryApi from '@/api/mall/promotion/articleCategory'
135+
import ArticleCategoryForm from './ArticleCategoryForm.vue'
136+
import { createImageViewer } from '@/components/ImageViewer'
137+
138+
defineOptions({ name: 'ArticleCategory' })
139+
140+
const message = useMessage() // 消息弹窗
141+
const { t } = useI18n() // 国际化
142+
143+
const loading = ref(true) // 列表的加载中
144+
const total = ref(0) // 列表的总页数
145+
const list = ref([]) // 列表的数据
146+
const queryParams = reactive({
147+
pageNo: 1,
148+
pageSize: 10,
149+
name: null,
150+
status: null,
151+
createTime: []
152+
})
153+
const queryFormRef = ref() // 搜索的表单
154+
const exportLoading = ref(false) // 导出的加载中
155+
156+
/** 分类图预览 */
157+
const imagePreview = (imgUrl: string) => {
158+
createImageViewer({
159+
urlList: [imgUrl]
160+
})
161+
}
162+
163+
/** 查询列表 */
164+
const getList = async () => {
165+
loading.value = true
166+
try {
167+
const data = await ArticleCategoryApi.getArticleCategoryPage(queryParams)
168+
list.value = data.list
169+
total.value = data.total
170+
} finally {
171+
loading.value = false
172+
}
173+
}
174+
175+
/** 搜索按钮操作 */
176+
const handleQuery = () => {
177+
queryParams.pageNo = 1
178+
getList()
179+
}
180+
181+
/** 重置按钮操作 */
182+
const resetQuery = () => {
183+
queryFormRef.value.resetFields()
184+
handleQuery()
185+
}
186+
187+
/** 添加/修改操作 */
188+
const formRef = ref()
189+
const openForm = (type: string, id?: number) => {
190+
formRef.value.open(type, id)
191+
}
192+
193+
/** 删除按钮操作 */
194+
const handleDelete = async (id: number) => {
195+
try {
196+
// 删除的二次确认
197+
await message.delConfirm()
198+
// 发起删除
199+
await ArticleCategoryApi.deleteArticleCategory(id)
200+
message.success(t('common.delSuccess'))
201+
// 刷新列表
202+
await getList()
203+
} catch {}
204+
}
205+
206+
/** 导出按钮操作 */
207+
const handleExport = async () => {
208+
try {
209+
// 导出的二次确认
210+
await message.exportConfirm()
211+
// 发起导出
212+
exportLoading.value = true
213+
const data = await ArticleCategoryApi.exportArticleCategory(queryParams)
214+
download.excel(data, '分类.xls')
215+
} catch {
216+
} finally {
217+
exportLoading.value = false
218+
}
219+
}
220+
221+
/** 初始化 **/
222+
onMounted(() => {
223+
getList()
224+
})
225+
</script>

0 commit comments

Comments
 (0)