Skip to content

Commit 4709c18

Browse files
YunaiVgitee-org
authored andcommitted
!284 完善 SPU,订单列表:完善表头宽度自适应
Merge pull request !284 from puhui999/dev-to-dev
2 parents 929fa9a + 491b3a5 commit 4709c18

File tree

20 files changed

+1191
-551
lines changed

20 files changed

+1191
-551
lines changed

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ VITE_OPEN=true
1111
VITE_APP_TENANT_ENABLE=true
1212

1313
# 验证码的开关
14-
VITE_APP_CAPTCHA_ENABLE=true
14+
VITE_APP_CAPTCHA_ENABLE=false
1515

1616
# 百度统计
1717
VITE_APP_BAIDU_CODE = a1ff8825baa73c3a78eb96aa40325abc

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"pinia": "^2.1.7",
5959
"qrcode": "^1.5.3",
6060
"qs": "^6.11.2",
61+
"sortablejs": "^1.15.0",
6162
"steady-xml": "^0.1.0",
6263
"url": "^0.11.3",
6364
"video.js": "^7.21.5",
@@ -82,6 +83,7 @@
8283
"@types/nprogress": "^0.2.1",
8384
"@types/qrcode": "^1.5.2",
8485
"@types/qs": "^6.9.8",
86+
"@types/sortablejs": "^1.15.4",
8587
"@typescript-eslint/eslint-plugin": "^6.7.5",
8688
"@typescript-eslint/parser": "^6.7.5",
8789
"@unocss/transformer-variant-group": "^0.56.5",

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/api/mall/product/spu.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,22 @@ export interface Sku {
2525
salesCount?: number // 商品销量
2626
}
2727

28+
export interface GiveCouponTemplate {
29+
id?: number
30+
name?: string // 优惠券名称
31+
}
32+
2833
export interface Spu {
2934
id?: number
3035
name?: string // 商品名称
31-
categoryId?: number | null // 商品分类
36+
categoryId?: number | undefined // 商品分类
3237
keyword?: string // 关键字
33-
unit?: number | null // 单位
38+
unit?: number | undefined // 单位
3439
picUrl?: string // 商品封面图
3540
sliderPicUrls?: string[] // 商品轮播图
3641
introduction?: string // 商品简介
37-
deliveryTemplateId?: number | null // 运费模版
38-
brandId?: number | null // 商品品牌编号
42+
deliveryTemplateId?: number | undefined // 运费模版
43+
brandId?: number | undefined // 商品品牌编号
3944
specType?: boolean // 商品规格
4045
subCommissionType?: boolean // 分销类型
4146
skus?: Sku[] // sku数组
@@ -55,6 +60,8 @@ export interface Spu {
5560
stock?: number // 商品库存
5661
createTime?: Date // 商品创建时间
5762
status?: number // 商品状态
63+
activityOrders: number[] // 活动排序
64+
giveCouponTemplates: GiveCouponTemplate[] // 优惠卷
5865
}
5966

6067
// 获得 Spu 列表

src/api/mall/trade/delivery/pickUpStore/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const getDeliveryPickUpStore = async (id: number) => {
2626
}
2727

2828
// 查询自提门店精简列表
29-
export const getListAllSimple = async () => {
29+
export const getListAllSimple = async (): Promise<DeliveryPickUpStoreVO[]> => {
3030
return await request.get({ url: '/trade/delivery/pick-up-store/list-all-simple' })
3131
}
3232

src/utils/dict.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ export enum DICT_TYPE {
155155
// ========== MALL - 商品模块 ==========
156156
PRODUCT_UNIT = 'product_unit', // 商品单位
157157
PRODUCT_SPU_STATUS = 'product_spu_status', //商品状态
158+
PROMOTION_TYPE_ENUM = 'promotion_type_enum', // 营销类型枚举
158159

159160
// ========== MALL - 交易模块 ==========
160161
EXPRESS_CHARGE_MODE = 'trade_delivery_express_charge_mode', //快递的计费方式
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<template>
2+
<div ref="elTagWrappingRef">
3+
<template v-if="activityOrders && activityOrders.length > 0">
4+
<el-tag
5+
v-for="activityType in activityOrders"
6+
:key="activityType"
7+
:type="promotionTypes.find((item) => item.value === activityType)?.colorType"
8+
class="mr-[10px]"
9+
>
10+
{{ promotionTypes.find((item) => item.value === activityType)?.label }}
11+
</el-tag>
12+
</template>
13+
<template v-else>
14+
<el-tag
15+
v-for="type in promotionTypes"
16+
:key="type.value as number"
17+
:type="type.colorType"
18+
class="mr-[10px]"
19+
>
20+
{{ type.label }}
21+
</el-tag>
22+
</template>
23+
</div>
24+
</template>
25+
<script lang="ts" setup>
26+
import Sortable from 'sortablejs'
27+
import type { DictDataType } from '@/utils/dict'
28+
29+
defineOptions({ name: 'ActivityOrdersSort' })
30+
const props = defineProps<{
31+
promotionTypes: DictDataType[]
32+
activityOrders: number[]
33+
}>()
34+
const emit = defineEmits<{
35+
(e: 'update:activityOrders', v: number[])
36+
}>()
37+
const elTagWrappingRef = ref() // elTag 容器 Ref
38+
39+
const initSortable = () => {
40+
new Sortable(elTagWrappingRef.value, {
41+
swapThreshold: 1,
42+
animation: 150,
43+
onEnd: (el) => {
44+
const innerText = el.to.innerText
45+
// 将字符串按换行符分割成数组
46+
const activityOrder = innerText.split('\n')
47+
// 根据字符串中的顺序重新排序数组
48+
const sortedActivityOrder = activityOrder.map((activityName) => {
49+
return props.promotionTypes.find((item) => item.label === activityName)?.value
50+
})
51+
emit('update:activityOrders', sortedActivityOrder as number[])
52+
}
53+
})
54+
}
55+
onMounted(async () => {
56+
await nextTick()
57+
initSortable()
58+
})
59+
</script>
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
<template>
2+
<Dialog v-model="dialogVisible" :title="dialogTitle" width="65%">
3+
<!-- 搜索工作栏 -->
4+
<ContentWrap>
5+
<el-form
6+
ref="queryFormRef"
7+
:inline="true"
8+
:model="queryParams"
9+
class="-mb-15px"
10+
label-width="82px"
11+
>
12+
<el-form-item label="优惠券名称" prop="name">
13+
<el-input
14+
v-model="queryParams.name"
15+
class="!w-240px"
16+
clearable
17+
placeholder="请输入优惠劵名"
18+
@keyup="handleQuery"
19+
/>
20+
</el-form-item>
21+
<el-form-item label="优惠类型" prop="discountType">
22+
<el-select
23+
v-model="queryParams.discountType"
24+
class="!w-240px"
25+
clearable
26+
placeholder="请选择优惠券类型"
27+
>
28+
<el-option
29+
v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_DISCOUNT_TYPE)"
30+
:key="dict.value"
31+
:label="dict.label"
32+
:value="dict.value"
33+
/>
34+
</el-select>
35+
</el-form-item>
36+
<el-form-item label="优惠券状态" prop="status">
37+
<el-select
38+
v-model="queryParams.status"
39+
class="!w-240px"
40+
clearable
41+
placeholder="请选择优惠券状态"
42+
>
43+
<el-option
44+
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
45+
:key="dict.value"
46+
:label="dict.label"
47+
:value="dict.value"
48+
/>
49+
</el-select>
50+
</el-form-item>
51+
<el-form-item label="创建时间" prop="createTime">
52+
<el-date-picker
53+
v-model="queryParams.createTime"
54+
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
55+
class="!w-240px"
56+
end-placeholder="结束日期"
57+
start-placeholder="开始日期"
58+
type="daterange"
59+
value-format="YYYY-MM-DD HH:mm:ss"
60+
/>
61+
</el-form-item>
62+
<el-form-item>
63+
<el-button @click="handleQuery">
64+
<Icon class="mr-5px" icon="ep:search" />
65+
搜索
66+
</el-button>
67+
<el-button @click="resetQuery">
68+
<Icon class="mr-5px" icon="ep:refresh" />
69+
重置
70+
</el-button>
71+
</el-form-item>
72+
</el-form>
73+
</ContentWrap>
74+
75+
<!-- 列表 -->
76+
<ContentWrap>
77+
<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
78+
<el-table-column type="selection" width="55" />
79+
<el-table-column label="优惠券名称" min-width="140" prop="name" />
80+
<el-table-column label="类型" min-width="80" prop="productScope">
81+
<template #default="scope">
82+
<dict-tag :type="DICT_TYPE.PROMOTION_PRODUCT_SCOPE" :value="scope.row.productScope" />
83+
</template>
84+
</el-table-column>
85+
<el-table-column label="优惠" min-width="100" prop="discount">
86+
<template #default="scope">
87+
<dict-tag :type="DICT_TYPE.PROMOTION_DISCOUNT_TYPE" :value="scope.row.discountType" />
88+
{{ discountFormat(scope.row) }}
89+
</template>
90+
</el-table-column>
91+
<el-table-column label="领取方式" min-width="100" prop="takeType">
92+
<template #default="scope">
93+
<dict-tag :type="DICT_TYPE.PROMOTION_COUPON_TAKE_TYPE" :value="scope.row.takeType" />
94+
</template>
95+
</el-table-column>
96+
<el-table-column
97+
:formatter="validityTypeFormat"
98+
align="center"
99+
label="使用时间"
100+
prop="validityType"
101+
width="185"
102+
/>
103+
<el-table-column align="center" label="发放数量" prop="totalCount" />
104+
<el-table-column
105+
:formatter="remainedCountFormat"
106+
align="center"
107+
label="剩余数量"
108+
prop="totalCount"
109+
/>
110+
<el-table-column
111+
:formatter="takeLimitCountFormat"
112+
align="center"
113+
label="领取上限"
114+
prop="takeLimitCount"
115+
/>
116+
<el-table-column align="center" label="状态" prop="status">
117+
<template #default="scope">
118+
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
119+
</template>
120+
</el-table-column>
121+
<el-table-column
122+
:formatter="dateFormatter"
123+
align="center"
124+
label="创建时间"
125+
prop="createTime"
126+
width="180"
127+
/>
128+
</el-table>
129+
<!-- 分页 -->
130+
<Pagination
131+
v-model:limit="queryParams.pageSize"
132+
v-model:page="queryParams.pageNo"
133+
:total="total"
134+
@pagination="getList"
135+
/>
136+
</ContentWrap>
137+
<template #footer>
138+
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
139+
<el-button @click="dialogVisible = false">取 消</el-button>
140+
</template>
141+
</Dialog>
142+
</template>
143+
<script lang="ts" setup>
144+
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
145+
import {
146+
discountFormat,
147+
remainedCountFormat,
148+
takeLimitCountFormat,
149+
validityTypeFormat
150+
} from '@/views/mall/promotion/coupon/formatter'
151+
import { dateFormatter } from '@/utils/formatTime'
152+
import * as CouponTemplateApi from '@/api/mall/promotion/coupon/couponTemplate'
153+
import type { GiveCouponTemplate } from '@/api/mall/product/spu'
154+
155+
defineOptions({ name: 'CouponSelect' })
156+
157+
defineProps<{
158+
multipleSelection: GiveCouponTemplate[]
159+
}>()
160+
const emit = defineEmits<{
161+
(e: 'update:multipleSelection', v: GiveCouponTemplate[])
162+
}>()
163+
const dialogVisible = ref(false) // 弹窗的是否展示
164+
const dialogTitle = ref('选择优惠卷') // 弹窗的标题
165+
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
166+
const loading = ref(true) // 列表的加载中
167+
const total = ref(0) // 列表的总页数
168+
const list = ref([]) // 字典表格数据
169+
const queryParams = reactive({
170+
pageNo: 1,
171+
pageSize: 10,
172+
name: null,
173+
status: null,
174+
discountType: null,
175+
type: null,
176+
createTime: []
177+
})
178+
const queryFormRef = ref() // 搜索的表单
179+
180+
/** 查询列表 */
181+
const getList = async () => {
182+
loading.value = true
183+
try {
184+
// 执行查询
185+
const data = await CouponTemplateApi.getCouponTemplatePage(queryParams)
186+
list.value = data.list
187+
total.value = data.total
188+
} finally {
189+
loading.value = false
190+
}
191+
}
192+
193+
/** 搜索按钮操作 */
194+
const handleQuery = () => {
195+
queryParams.pageNo = 1
196+
getList()
197+
}
198+
199+
/** 重置按钮操作 */
200+
const resetQuery = () => {
201+
queryFormRef?.value?.resetFields()
202+
handleQuery()
203+
}
204+
/** 打开弹窗 */
205+
const open = async () => {
206+
dialogVisible.value = true
207+
resetQuery()
208+
}
209+
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
210+
const handleSelectionChange = (val: CouponTemplateApi.CouponTemplateVO[]) => {
211+
emit(
212+
'update:multipleSelection',
213+
val.map((item) => ({ id: item.id, name: item.name }))
214+
)
215+
}
216+
const submitForm = () => {
217+
dialogVisible.value = false
218+
}
219+
</script>
220+
<style lang="scss" scoped></style>

0 commit comments

Comments
 (0)