mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-10-31 10:18:43 +08:00 
			
		
		
		
	Merge remote-tracking branch 'yudao/dev' into dev-to-dev
This commit is contained in:
		| @@ -88,3 +88,8 @@ export const deleteSpu = (id: number) => { | |||||||
| export const exportSpu = async (params) => { | export const exportSpu = async (params) => { | ||||||
|   return await request.download({ url: '/product/spu/export', params }) |   return await request.download({ url: '/product/spu/export', params }) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // 获得商品 SPU 精简列表 | ||||||
|  | export const getSpuSimpleList = async () => { | ||||||
|  |   return request.get({ url: '/product/spu/get-simple-list' }) | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								src/api/mall/promotion/coupon.ts
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								src/api/mall/promotion/coupon.ts
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | import request from '@/config/axios' | ||||||
|  |  | ||||||
|  | // TODO @dhb52:vo 缺少 | ||||||
|  |  | ||||||
|  | // 删除优惠劵 | ||||||
|  | export const deleteCoupon = async (id: number) => { | ||||||
|  |   return request.delete({ | ||||||
|  |     url: `/promotion/coupon/delete?id=${id}` | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 获得优惠劵分页 | ||||||
|  | export const getCouponPage = async (params: PageParam) => { | ||||||
|  |   return request.get({ | ||||||
|  |     url: '/promotion/coupon/page', | ||||||
|  |     params: params | ||||||
|  |   }) | ||||||
|  | } | ||||||
							
								
								
									
										83
									
								
								src/api/mall/promotion/couponTemplate.ts
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										83
									
								
								src/api/mall/promotion/couponTemplate.ts
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | import request from '@/config/axios' | ||||||
|  |  | ||||||
|  | export interface CouponTemplateVO { | ||||||
|  |   id: number | ||||||
|  |   name: string | ||||||
|  |   status: number | ||||||
|  |   totalCount: number | ||||||
|  |   takeLimitCount: number | ||||||
|  |   takeType: number | ||||||
|  |   usePrice: number | ||||||
|  |   productScope: number | ||||||
|  |   productSpuIds: string | ||||||
|  |   validityType: number | ||||||
|  |   validStartTime: Date | ||||||
|  |   validEndTime: Date | ||||||
|  |   fixedStartTerm: number | ||||||
|  |   fixedEndTerm: number | ||||||
|  |   discountType: number | ||||||
|  |   discountPercent: number | ||||||
|  |   discountPrice: number | ||||||
|  |   discountLimitPrice: number | ||||||
|  |   takeCount: number | ||||||
|  |   useCount: number | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 创建优惠劵模板 | ||||||
|  | export function createCouponTemplate(data: CouponTemplateVO) { | ||||||
|  |   return request.post({ | ||||||
|  |     url: '/promotion/coupon-template/create', | ||||||
|  |     data: data | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 更新优惠劵模板 | ||||||
|  | export function updateCouponTemplate(data: CouponTemplateVO) { | ||||||
|  |   return request.put({ | ||||||
|  |     url: '/promotion/coupon-template/update', | ||||||
|  |     data: data | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 更新优惠劵模板的状态 | ||||||
|  | export function updateCouponTemplateStatus(id: number, status: [0, 1]) { | ||||||
|  |   const data = { | ||||||
|  |     id, | ||||||
|  |     status | ||||||
|  |   } | ||||||
|  |   return request.put({ | ||||||
|  |     url: '/promotion/coupon-template/update-status', | ||||||
|  |     data: data | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 删除优惠劵模板 | ||||||
|  | export function deleteCouponTemplate(id: number) { | ||||||
|  |   return request.delete({ | ||||||
|  |     url: '/promotion/coupon-template/delete?id=' + id | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 获得优惠劵模板 | ||||||
|  | export function getCouponTemplate(id: number) { | ||||||
|  |   return request.get({ | ||||||
|  |     url: '/promotion/coupon-template/get?id=' + id | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 获得优惠劵模板分页 | ||||||
|  | export function getCouponTemplatePage(params: PageParam) { | ||||||
|  |   return request.get({ | ||||||
|  |     url: '/promotion/coupon-template/page', | ||||||
|  |     params: params | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 导出优惠劵模板 Excel | ||||||
|  | export function exportCouponTemplateExcel(params: PageParam) { | ||||||
|  |   return request.get({ | ||||||
|  |     url: '/promotion/coupon-template/export-excel', | ||||||
|  |     params: params, | ||||||
|  |     responseType: 'blob' | ||||||
|  |   }) | ||||||
|  | } | ||||||
| @@ -52,8 +52,3 @@ export const updateDeliveryExpressTemplate = async (data: DeliveryExpressTemplat | |||||||
| export const deleteDeliveryExpressTemplate = async (id: number) => { | export const deleteDeliveryExpressTemplate = async (id: number) => { | ||||||
|   return await request.delete({ url: '/trade/delivery/express-template/delete?id=' + id }) |   return await request.delete({ url: '/trade/delivery/express-template/delete?id=' + id }) | ||||||
| } | } | ||||||
|  |  | ||||||
| // 导出快递运费模板 Excel |  | ||||||
| export const exportDeliveryExpressTemplateApi = async (params) => { |  | ||||||
|   return await request.download({ url: '/trade/delivery/express-template/export-excel', params }) |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -222,7 +222,7 @@ export const PayRefundStatusEnum = { | |||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 商品SPU枚举类 |  * 商品 SPU 状态 | ||||||
|  */ |  */ | ||||||
| export const ProductSpuStatusEnum = { | export const ProductSpuStatusEnum = { | ||||||
|   RECYCLE: { |   RECYCLE: { | ||||||
| @@ -238,3 +238,59 @@ export const ProductSpuStatusEnum = { | |||||||
|     name: '上架' |     name: '上架' | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 优惠劵模板的有限期类型的枚举 | ||||||
|  |  */ | ||||||
|  | export const CouponTemplateValidityTypeEnum = { | ||||||
|  |   DATE: { | ||||||
|  |     type: 1, | ||||||
|  |     name: '固定日期可用' | ||||||
|  |   }, | ||||||
|  |   TERM: { | ||||||
|  |     type: 2, | ||||||
|  |     name: '领取之后可用' | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 营销的商品范围枚举 | ||||||
|  |  */ | ||||||
|  | export const PromotionProductScopeEnum = { | ||||||
|  |   ALL: { | ||||||
|  |     scope: 1, | ||||||
|  |     name: '全部商品参与' | ||||||
|  |   }, | ||||||
|  |   SPU: { | ||||||
|  |     scope: 2, | ||||||
|  |     name: '指定商品参与' | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 营销的条件类型枚举 | ||||||
|  |  */ | ||||||
|  | export const PromotionConditionTypeEnum = { | ||||||
|  |   PRICE: { | ||||||
|  |     type: 10, | ||||||
|  |     name: '满 N 元' | ||||||
|  |   }, | ||||||
|  |   COUNT: { | ||||||
|  |     type: 20, | ||||||
|  |     name: '满 N 件' | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 优惠类型枚举 | ||||||
|  |  */ | ||||||
|  | export const PromotionDiscountTypeEnum = { | ||||||
|  |   PRICE: { | ||||||
|  |     type: 1, | ||||||
|  |     name: '满减' | ||||||
|  |   }, | ||||||
|  |   PERCENT: { | ||||||
|  |     type: 2, | ||||||
|  |     name: '折扣' | ||||||
|  |   } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -146,9 +146,12 @@ export enum DICT_TYPE { | |||||||
|   MP_AUTO_REPLY_REQUEST_MATCH = 'mp_auto_reply_request_match', // 自动回复请求匹配类型 |   MP_AUTO_REPLY_REQUEST_MATCH = 'mp_auto_reply_request_match', // 自动回复请求匹配类型 | ||||||
|   MP_MESSAGE_TYPE = 'mp_message_type', // 消息类型 |   MP_MESSAGE_TYPE = 'mp_message_type', // 消息类型 | ||||||
|  |  | ||||||
|   // ========== MALL 模块 ========== |   // ========== MALL - PROMOTION 模块 ========== | ||||||
|   PRODUCT_UNIT = 'product_unit', // 商品单位 |   PROMOTION_DISCOUNT_TYPE = 'promotion_discount_type', // 优惠类型 | ||||||
|   PRODUCT_SPU_STATUS = 'product_spu_status', //商品状态 |   PROMOTION_PRODUCT_SCOPE = 'promotion_product_scope', // 营销的商品范围 | ||||||
|   // ========== MALL 交易模块 ========== |   PROMOTION_COUPON_TEMPLATE_VALIDITY_TYPE = 'promotion_coupon_template_validity_type', // 优惠劵模板的有限期类型 | ||||||
|   EXPRESS_CHARGE_MODE = 'trade_delivery_express_charge_mode' //快递的计费方式 |   PROMOTION_COUPON_STATUS = 'promotion_coupon_status', // 优惠劵的状态 | ||||||
|  |   PROMOTION_COUPON_TAKE_TYPE = 'promotion_coupon_take_type', // 优惠劵的领取方式 | ||||||
|  |   PROMOTION_ACTIVITY_STATUS = 'promotion_activity_status', // 优惠活动的状态 | ||||||
|  |   PROMOTION_CONDITION_TYPE = 'promotion_condition_type' // 营销的条件类型枚举 | ||||||
| } | } | ||||||
|   | |||||||
| @@ -306,11 +306,14 @@ export const handleTree2 = (data, id, parentId, children, rootId) => { | |||||||
|   }) |   }) | ||||||
|   return treeData !== '' ? treeData : data |   return treeData !== '' ? treeData : data | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  |  * 校验选中的节点,是否为指定 level | ||||||
|  * |  * | ||||||
|  * @param tree 要操作的树结构数据 |  * @param tree 要操作的树结构数据 | ||||||
|  * @param nodeId 需要判断在什么层级的数据 |  * @param nodeId 需要判断在什么层级的数据 | ||||||
|  * @param level 检查的级别, 默认检查到二级 |  * @param level 检查的级别, 默认检查到二级 | ||||||
|  |  * @return true 是;false 否 | ||||||
|  */ |  */ | ||||||
| export const checkSelectedNode = (tree: any[], nodeId: any, level = 2): boolean => { | export const checkSelectedNode = (tree: any[], nodeId: any, level = 2): boolean => { | ||||||
|   if (typeof tree === 'undefined' || !Array.isArray(tree) || tree.length === 0) { |   if (typeof tree === 'undefined' || !Array.isArray(tree) || tree.length === 0) { | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| <template> | <template> | ||||||
|  |   <!-- 情况一:添加/修改 --> | ||||||
|   <el-form |   <el-form | ||||||
|     v-if="!isDetail" |     v-if="!isDetail" | ||||||
|     ref="productSpuBasicInfoRef" |     ref="productSpuBasicInfoRef" | ||||||
| @@ -23,7 +24,7 @@ | |||||||
|             class="w-1/1" |             class="w-1/1" | ||||||
|             node-key="id" |             node-key="id" | ||||||
|             placeholder="请选择商品分类" |             placeholder="请选择商品分类" | ||||||
|             @change="nodeClick" |             @change="categoryNodeClick" | ||||||
|           /> |           /> | ||||||
|         </el-form-item> |         </el-form-item> | ||||||
|       </el-col> |       </el-col> | ||||||
| @@ -126,8 +127,8 @@ | |||||||
|       </el-col> |       </el-col> | ||||||
|     </el-row> |     </el-row> | ||||||
|   </el-form> |   </el-form> | ||||||
|   <ProductAttributesAddForm ref="attributesAddFormRef" :propertyList="propertyList" /> |  | ||||||
|   <!-- 详情跟表单放在一块可以共用已有功能,再抽离成组件有点过度封装的感觉 --> |   <!-- 情况二:详情 --> | ||||||
|   <Descriptions v-if="isDetail" :data="formData" :schema="allSchemas.detailSchema"> |   <Descriptions v-if="isDetail" :data="formData" :schema="allSchemas.detailSchema"> | ||||||
|     <template #categoryId="{ row }"> {{ categoryString(row.categoryId) }}</template> |     <template #categoryId="{ row }"> {{ categoryString(row.categoryId) }}</template> | ||||||
|     <template #brandId="{ row }"> |     <template #brandId="{ row }"> | ||||||
| @@ -163,6 +164,10 @@ | |||||||
|       /> |       /> | ||||||
|     </template> |     </template> | ||||||
|   </Descriptions> |   </Descriptions> | ||||||
|  |  | ||||||
|  |   <!-- 商品属性添加 Form 表单 --> | ||||||
|  |   <!-- TODO @puhui999: ProductPropertyAddForm 是不是更合适呀 --> | ||||||
|  |   <ProductAttributesAddForm ref="attributesAddFormRef" :propertyList="propertyList" /> | ||||||
| </template> | </template> | ||||||
| <script lang="ts" name="ProductSpuBasicInfoForm" setup> | <script lang="ts" name="ProductSpuBasicInfoForm" setup> | ||||||
| import { PropType } from 'vue' | import { PropType } from 'vue' | ||||||
| @@ -257,7 +262,9 @@ watch( | |||||||
|       url: item |       url: item | ||||||
|     })) |     })) | ||||||
|     // 只有是多规格才处理 |     // 只有是多规格才处理 | ||||||
|     if (!formData.specType) return |     if (!formData.specType) { | ||||||
|  |       return | ||||||
|  |     } | ||||||
|     //  直接拿返回的 skus 属性逆向生成出 propertyList |     //  直接拿返回的 skus 属性逆向生成出 propertyList | ||||||
|     const properties = [] |     const properties = [] | ||||||
|     formData.skus.forEach((sku) => { |     formData.skus.forEach((sku) => { | ||||||
| @@ -287,8 +294,8 @@ const emit = defineEmits(['update:activeName']) | |||||||
| const validate = async () => { | const validate = async () => { | ||||||
|   // 校验 sku |   // 校验 sku | ||||||
|   if (!skuListRef.value.validateSku()) { |   if (!skuListRef.value.validateSku()) { | ||||||
|     message.warning('商品相关价格不能低于0.01元!!') |     message.warning('商品相关价格不能低于 0.01 元!!') | ||||||
|     throw new Error('商品相关价格不能低于0.01元!!') |     throw new Error('商品相关价格不能低于 0.01 元!!') | ||||||
|   } |   } | ||||||
|   // 校验表单 |   // 校验表单 | ||||||
|   if (!productSpuBasicInfoRef) return |   if (!productSpuBasicInfoRef) return | ||||||
| @@ -340,7 +347,7 @@ const categoryList = ref([]) // 分类树 | |||||||
| /** | /** | ||||||
|  * 选择分类时触发校验 |  * 选择分类时触发校验 | ||||||
|  */ |  */ | ||||||
| const nodeClick = () => { | const categoryNodeClick = () => { | ||||||
|   if (!checkSelectedNode(categoryList.value, formData.categoryId)) { |   if (!checkSelectedNode(categoryList.value, formData.categoryId)) { | ||||||
|     formData.categoryId = null |     formData.categoryId = null | ||||||
|     message.warning('必须选择二级及以下节点!!') |     message.warning('必须选择二级及以下节点!!') | ||||||
| @@ -348,6 +355,7 @@ const nodeClick = () => { | |||||||
| } | } | ||||||
| /** | /** | ||||||
|  * 获取分类的节点的完整结构 |  * 获取分类的节点的完整结构 | ||||||
|  |  * | ||||||
|  * @param categoryId 分类id |  * @param categoryId 分类id | ||||||
|  */ |  */ | ||||||
| const categoryString = (categoryId) => { | const categoryString = (categoryId) => { | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| <template> | <template> | ||||||
|  |   <!-- 情况一:添加/修改 --> | ||||||
|   <el-form |   <el-form | ||||||
|     v-if="!isDetail" |     v-if="!isDetail" | ||||||
|     ref="descriptionFormRef" |     ref="descriptionFormRef" | ||||||
| @@ -11,6 +12,8 @@ | |||||||
|       <Editor v-model:modelValue="formData.description" /> |       <Editor v-model:modelValue="formData.description" /> | ||||||
|     </el-form-item> |     </el-form-item> | ||||||
|   </el-form> |   </el-form> | ||||||
|  |  | ||||||
|  |   <!-- 情况二:详情 --> | ||||||
|   <Descriptions |   <Descriptions | ||||||
|     v-if="isDetail" |     v-if="isDetail" | ||||||
|     :data="formData" |     :data="formData" | ||||||
| @@ -30,10 +33,9 @@ import { PropType } from 'vue' | |||||||
| import { propTypes } from '@/utils/propTypes' | import { propTypes } from '@/utils/propTypes' | ||||||
| import { copyValueToTarget } from '@/utils' | import { copyValueToTarget } from '@/utils' | ||||||
| import { descriptionSchema } from './spu.data' | import { descriptionSchema } from './spu.data' | ||||||
|  | const message = useMessage() // 消息弹窗 | ||||||
|  |  | ||||||
| const { allSchemas } = useCrudSchemas(descriptionSchema) | const { allSchemas } = useCrudSchemas(descriptionSchema) | ||||||
|  |  | ||||||
| const message = useMessage() // 消息弹窗 |  | ||||||
| const props = defineProps({ | const props = defineProps({ | ||||||
|   propFormData: { |   propFormData: { | ||||||
|     type: Object as PropType<Spu>, |     type: Object as PropType<Spu>, | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| <template> | <template> | ||||||
|  |   <!-- 情况一:添加/修改 --> | ||||||
|   <el-form |   <el-form | ||||||
|     v-if="!isDetail" |     v-if="!isDetail" | ||||||
|     ref="otherSettingsFormRef" |     ref="otherSettingsFormRef" | ||||||
| @@ -56,6 +57,8 @@ | |||||||
|       </el-col> |       </el-col> | ||||||
|     </el-row> |     </el-row> | ||||||
|   </el-form> |   </el-form> | ||||||
|  |  | ||||||
|  |   <!-- 情况二:详情 --> | ||||||
|   <Descriptions v-if="isDetail" :data="formData" :schema="allSchemas.detailSchema"> |   <Descriptions v-if="isDetail" :data="formData" :schema="allSchemas.detailSchema"> | ||||||
|     <template #recommendHot="{ row }"> |     <template #recommendHot="{ row }"> | ||||||
|       {{ row.recommendHot ? '是' : '否' }} |       {{ row.recommendHot ? '是' : '否' }} | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| <template> | <template> | ||||||
|  |   <!-- 情况一:添加/修改 --> | ||||||
|   <el-table |   <el-table | ||||||
|     v-if="!isDetail" |     v-if="!isDetail" | ||||||
|     :data="isBatch ? skuList : formData!.skus" |     :data="isBatch ? skuList : formData!.skus" | ||||||
| @@ -109,6 +110,8 @@ | |||||||
|       </template> |       </template> | ||||||
|     </el-table-column> |     </el-table-column> | ||||||
|   </el-table> |   </el-table> | ||||||
|  |  | ||||||
|  |   <!-- 情况二:详情 --> | ||||||
|   <el-table |   <el-table | ||||||
|     v-if="isDetail" |     v-if="isDetail" | ||||||
|     :data="formData!.skus" |     :data="formData!.skus" | ||||||
| @@ -132,7 +135,6 @@ | |||||||
|         min-width="80" |         min-width="80" | ||||||
|       > |       > | ||||||
|         <template #default="{ row }"> |         <template #default="{ row }"> | ||||||
|           <!-- TODO puhui999:展示成蓝色,有点区分度哈 fix--> |  | ||||||
|           <span style="font-weight: bold; color: #40aaff"> |           <span style="font-weight: bold; color: #40aaff"> | ||||||
|             {{ row.properties[index]?.valueName }} |             {{ row.properties[index]?.valueName }} | ||||||
|           </span> |           </span> | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| import { CrudSchema } from '@/hooks/web/useCrudSchemas' | import { CrudSchema } from '@/hooks/web/useCrudSchemas' | ||||||
|  |  | ||||||
|  | // TODO @puhui999:如果只要 detail,可以不用 CrudSchema,只要描述的 Schema | ||||||
| export const basicInfoSchema = reactive<CrudSchema[]>([ | export const basicInfoSchema = reactive<CrudSchema[]>([ | ||||||
|   { |   { | ||||||
|     label: '商品名称', |     label: '商品名称', | ||||||
|   | |||||||
| @@ -171,7 +171,6 @@ | |||||||
|       </el-table-column> |       </el-table-column> | ||||||
|       <el-table-column align="center" fixed="right" label="操作" min-width="200"> |       <el-table-column align="center" fixed="right" label="操作" min-width="200"> | ||||||
|         <template #default="{ row }"> |         <template #default="{ row }"> | ||||||
|           <!-- TODO @puhui999:【详情】,可以后面点做哈 fix--> |  | ||||||
|           <el-button |           <el-button | ||||||
|             v-hasPermi="['product:spu:update']" |             v-hasPermi="['product:spu:update']" | ||||||
|             link |             link | ||||||
|   | |||||||
							
								
								
									
										200
									
								
								src/views/mall/promotion/coupon/index.vue
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										200
									
								
								src/views/mall/promotion/coupon/index.vue
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,200 @@ | |||||||
|  | <template> | ||||||
|  |   <doc-alert title="功能开启" url="https://doc.iocoder.cn/mall/build/" /> | ||||||
|  |  | ||||||
|  |   <ContentWrap> | ||||||
|  |     <!-- 搜索工作栏 --> | ||||||
|  |     <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> | ||||||
|  |       <el-form-item label="会员昵称" prop="nickname"> | ||||||
|  |         <el-input | ||||||
|  |           v-model="queryParams.nickname" | ||||||
|  |           placeholder="请输入会员昵称" | ||||||
|  |           clearable | ||||||
|  |           @keyup="handleQuery" | ||||||
|  |         /> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="创建时间" prop="createTime"> | ||||||
|  |         <el-date-picker | ||||||
|  |           v-model="queryParams.createTime" | ||||||
|  |           style="width: 240px" | ||||||
|  |           type="datetimerange" | ||||||
|  |           value-format="YYYY-MM-DD HH:mm:ss" | ||||||
|  |           range-separator="-" | ||||||
|  |           start-placeholder="开始日期" | ||||||
|  |           end-placeholder="结束日期" | ||||||
|  |           :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]" | ||||||
|  |         /> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item> | ||||||
|  |         <el-button type="primary" @click="handleQuery"> | ||||||
|  |           <Icon icon="ep:search" class="mr-5px" /> 搜索 | ||||||
|  |         </el-button> | ||||||
|  |         <el-button @click="resetQuery"> <Icon icon="ep:refresh" class="mr-5px" />重置 </el-button> | ||||||
|  |       </el-form-item> | ||||||
|  |     </el-form> | ||||||
|  |  | ||||||
|  |     <!-- 操作工具栏 --> | ||||||
|  |     <!-- <el-row :gutter="10" class="mb8"> | ||||||
|  |       <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" /> | ||||||
|  |     </el-row> --> | ||||||
|  |   </ContentWrap> | ||||||
|  |  | ||||||
|  |   <ContentWrap> | ||||||
|  |     <!-- Tab 选项:真正的内容在 Lab --> | ||||||
|  |     <el-tabs v-model="activeTab" type="card" @tab-change="onTabChange"> | ||||||
|  |       <el-tab-pane | ||||||
|  |         v-for="tab in statusTabs" | ||||||
|  |         :key="tab.value" | ||||||
|  |         :label="tab.label" | ||||||
|  |         :name="tab.value" | ||||||
|  |       /> | ||||||
|  |     </el-tabs> | ||||||
|  |  | ||||||
|  |     <!-- 列表 --> | ||||||
|  |     <el-table v-loading="loading" :data="list"> | ||||||
|  |       <el-table-column label="会员信息" align="center" prop="nickname" /> | ||||||
|  |       <!-- TODO 芋艿:以后支持头像,支持跳转 --> | ||||||
|  |       <el-table-column label="优惠劵" align="center" prop="name" /> | ||||||
|  |       <el-table-column label="优惠券类型" align="center" prop="discountType"> | ||||||
|  |         <template #default="scope"> | ||||||
|  |           <dict-tag :type="DICT_TYPE.PROMOTION_DISCOUNT_TYPE" :value="scope.row.discountType" /> | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |       <el-table-column label="领取方式" align="center" prop="takeType"> | ||||||
|  |         <template #default="scope"> | ||||||
|  |           <dict-tag :type="DICT_TYPE.PROMOTION_COUPON_TAKE_TYPE" :value="scope.row.takeType" /> | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |       <el-table-column label="状态" align="center" prop="status"> | ||||||
|  |         <template #default="scope"> | ||||||
|  |           <dict-tag :type="DICT_TYPE.PROMOTION_COUPON_STATUS" :value="scope.row.status" /> | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |       <el-table-column | ||||||
|  |         label="领取时间" | ||||||
|  |         align="center" | ||||||
|  |         prop="createTime" | ||||||
|  |         :formatter="dateFormatter" | ||||||
|  |         width="180" | ||||||
|  |       /> | ||||||
|  |       <el-table-column | ||||||
|  |         label="使用时间" | ||||||
|  |         align="center" | ||||||
|  |         prop="useTime" | ||||||
|  |         :formatter="dateFormatter" | ||||||
|  |         width="180" | ||||||
|  |       /> | ||||||
|  |       <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||||
|  |         <template #default="scope"> | ||||||
|  |           <el-button | ||||||
|  |             size="small" | ||||||
|  |             type="primary" | ||||||
|  |             link | ||||||
|  |             @click="handleDelete(scope.row)" | ||||||
|  |             v-hasPermi="['promotion:coupon:delete']" | ||||||
|  |             ><Icon icon="ep:delete" :size="12" class="mr-1px" />回收</el-button | ||||||
|  |           > | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |     </el-table> | ||||||
|  |  | ||||||
|  |     <!-- 分页组件 --> | ||||||
|  |     <pagination | ||||||
|  |       v-show="total > 0" | ||||||
|  |       :total="total" | ||||||
|  |       v-model:page="queryParams.pageNo" | ||||||
|  |       v-model:limit="queryParams.pageSize" | ||||||
|  |       @pagination="getList" | ||||||
|  |     /> | ||||||
|  |   </ContentWrap> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script setup lang="ts" name="PromotionCoupon"> | ||||||
|  | import { deleteCoupon, getCouponPage } from '@/api/mall/promotion/coupon' | ||||||
|  | import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||||
|  | import { dateFormatter } from '@/utils/formatTime' | ||||||
|  | import { FormInstance } from 'element-plus' | ||||||
|  |  | ||||||
|  | // 消息弹窗 | ||||||
|  | const message = useMessage() | ||||||
|  |  | ||||||
|  | // 遮罩层 | ||||||
|  | const loading = ref(true) | ||||||
|  | // 总条数 | ||||||
|  | const total = ref(0) | ||||||
|  | // 优惠劵列表 | ||||||
|  | const list = ref([]) | ||||||
|  | // 查询参数 | ||||||
|  | const queryParams = reactive({ | ||||||
|  |   pageNo: 1, | ||||||
|  |   pageSize: 10, | ||||||
|  |   createTime: [], | ||||||
|  |   status: undefined | ||||||
|  | }) | ||||||
|  | // Tab 筛选 | ||||||
|  | const activeTab = ref('all') | ||||||
|  |  | ||||||
|  | const statusTabs = reactive([ | ||||||
|  |   { | ||||||
|  |     label: '全部', | ||||||
|  |     value: 'all' | ||||||
|  |   } | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  | const queryFormRef = ref<FormInstance | null>(null) | ||||||
|  |  | ||||||
|  | /** 查询列表 */ | ||||||
|  | const getList = async () => { | ||||||
|  |   loading.value = true | ||||||
|  |   // 执行查询 | ||||||
|  |   try { | ||||||
|  |     const data = await getCouponPage(queryParams) | ||||||
|  |     list.value = data.list | ||||||
|  |     total.value = data.total | ||||||
|  |   } finally { | ||||||
|  |     loading.value = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 搜索按钮操作 */ | ||||||
|  | const handleQuery = () => { | ||||||
|  |   queryParams.pageNo = 1 | ||||||
|  |   getList() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 重置按钮操作 */ | ||||||
|  | const resetQuery = () => { | ||||||
|  |   queryFormRef.value?.resetFields() | ||||||
|  |   handleQuery() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 删除按钮操作 */ | ||||||
|  | const handleDelete = async (row) => { | ||||||
|  |   const id = row.id | ||||||
|  |  | ||||||
|  |   try { | ||||||
|  |     await message.confirm( | ||||||
|  |       '回收将会收回会员领取的待使用的优惠券,已使用的将无法回收,确定要回收所选优惠券吗?' | ||||||
|  |     ) | ||||||
|  |     await deleteCoupon(id) | ||||||
|  |     getList() | ||||||
|  |     message.notifySuccess('回收成功') | ||||||
|  |   } catch {} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** tab 切换 */ | ||||||
|  | const onTabChange = (tabName) => { | ||||||
|  |   queryParams.status = tabName === 'all' ? undefined : tabName | ||||||
|  |   getList() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | onMounted(() => { | ||||||
|  |   getList() | ||||||
|  |   // 设置 statuses 过滤 | ||||||
|  |   for (const dict of getIntDictOptions(DICT_TYPE.PROMOTION_COUPON_STATUS)) { | ||||||
|  |     statusTabs.push({ | ||||||
|  |       label: dict.label, | ||||||
|  |       value: dict.value as string | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
							
								
								
									
										614
									
								
								src/views/mall/promotion/couponTemplate/index.vue
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										614
									
								
								src/views/mall/promotion/couponTemplate/index.vue
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,614 @@ | |||||||
|  | <template> | ||||||
|  |   <doc-alert title="功能开启" url="https://doc.iocoder.cn/mall/build/" /> | ||||||
|  |  | ||||||
|  |   <!-- 搜索工作栏 --> | ||||||
|  |   <ContentWrap> | ||||||
|  |     <el-form | ||||||
|  |       :model="queryParams" | ||||||
|  |       ref="queryFormRef" | ||||||
|  |       :inline="true" | ||||||
|  |       v-show="showSearch" | ||||||
|  |       label-width="82px" | ||||||
|  |     > | ||||||
|  |       <el-form-item label="优惠券名称" prop="name"> | ||||||
|  |         <el-input | ||||||
|  |           v-model="queryParams.name" | ||||||
|  |           placeholder="请输入优惠劵名" | ||||||
|  |           clearable | ||||||
|  |           @keyup="handleQuery" | ||||||
|  |         /> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="优惠券类型" prop="discountType"> | ||||||
|  |         <el-select v-model="queryParams.discountType" placeholder="请选择优惠券类型" clearable> | ||||||
|  |           <el-option | ||||||
|  |             v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_DISCOUNT_TYPE)" | ||||||
|  |             :key="dict.value" | ||||||
|  |             :label="dict.label" | ||||||
|  |             :value="dict.value" | ||||||
|  |           /> | ||||||
|  |         </el-select> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="优惠券状态" prop="status"> | ||||||
|  |         <el-select v-model="queryParams.status" placeholder="请选择优惠券状态" clearable> | ||||||
|  |           <el-option | ||||||
|  |             v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" | ||||||
|  |             :key="dict.value" | ||||||
|  |             :label="dict.label" | ||||||
|  |             :value="dict.value" | ||||||
|  |           /> | ||||||
|  |         </el-select> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="创建时间" prop="createTime"> | ||||||
|  |         <el-date-picker | ||||||
|  |           v-model="queryParams.createTime" | ||||||
|  |           style="width: 240px" | ||||||
|  |           type="datetimerange" | ||||||
|  |           value-format="YYYY-MM-DD HH:mm:ss" | ||||||
|  |           range-separator="-" | ||||||
|  |           start-placeholder="开始日期" | ||||||
|  |           end-placeholder="结束日期" | ||||||
|  |           :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]" | ||||||
|  |         /> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item> | ||||||
|  |         <el-button type="primary" @click="handleQuery"> | ||||||
|  |           <Icon icon="ep:search" class="mr-5px" /> 搜索 | ||||||
|  |         </el-button> | ||||||
|  |         <el-button @click="resetQuery"> <Icon icon="ep:refresh" class="mr-5px" />重置 </el-button> | ||||||
|  |       </el-form-item> | ||||||
|  |     </el-form> | ||||||
|  |  | ||||||
|  |     <!-- 操作工具栏 --> | ||||||
|  |     <el-row :gutter="10" class="mb8"> | ||||||
|  |       <el-col :span="1.5"> | ||||||
|  |         <el-button | ||||||
|  |           type="primary" | ||||||
|  |           plain | ||||||
|  |           @click="handleAdd" | ||||||
|  |           v-hasPermi="['promotion:coupon-template:create']" | ||||||
|  |         > | ||||||
|  |           <Icon icon="ep:plus" class="mr-5px" />新增 | ||||||
|  |         </el-button> | ||||||
|  |         <el-button | ||||||
|  |           type="info" | ||||||
|  |           plain | ||||||
|  |           @click="$router.push('/promotion/coupon')" | ||||||
|  |           v-hasPermi="['promotion:coupon:query']" | ||||||
|  |         > | ||||||
|  |           <Icon icon="ep:operation" class="mr-5px" />会员优惠劵 | ||||||
|  |         </el-button> | ||||||
|  |       </el-col> | ||||||
|  |       <!-- <right-toolbar v-model:showSearch="showSearch" @query-table="getList" /> --> | ||||||
|  |     </el-row> | ||||||
|  |   </ContentWrap> | ||||||
|  |  | ||||||
|  |   <!-- 列表 --> | ||||||
|  |   <ContentWrap> | ||||||
|  |     <el-table v-loading="loading" :data="list"> | ||||||
|  |       <el-table-column label="优惠券名称" align="center" prop="name" /> | ||||||
|  |       <el-table-column label="优惠券类型" align="center" prop="discountType"> | ||||||
|  |         <template #default="scope"> | ||||||
|  |           <dict-tag :type="DICT_TYPE.PROMOTION_DISCOUNT_TYPE" :value="scope.row.discountType" /> | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |       <el-table-column | ||||||
|  |         label="优惠金额 / 折扣" | ||||||
|  |         align="center" | ||||||
|  |         prop="discount" | ||||||
|  |         :formatter="discountFormat" | ||||||
|  |       /> | ||||||
|  |       <el-table-column label="发放数量" align="center" prop="totalCount" /> | ||||||
|  |       <el-table-column | ||||||
|  |         label="剩余数量" | ||||||
|  |         align="center" | ||||||
|  |         prop="totalCount" | ||||||
|  |         :formatter="(row) => row.totalCount - row.takeCount" | ||||||
|  |       /> | ||||||
|  |       <el-table-column | ||||||
|  |         label="领取上限" | ||||||
|  |         align="center" | ||||||
|  |         prop="takeLimitCount" | ||||||
|  |         :formatter="takeLimitCountFormat" | ||||||
|  |       /> | ||||||
|  |       <el-table-column | ||||||
|  |         label="有效期限" | ||||||
|  |         align="center" | ||||||
|  |         prop="validityType" | ||||||
|  |         width="180" | ||||||
|  |         :formatter="validityTypeFormat" | ||||||
|  |       /> | ||||||
|  |       <el-table-column label="状态" align="center" prop="status"> | ||||||
|  |         <template #default="scope"> | ||||||
|  |           <el-switch | ||||||
|  |             v-model="scope.row.status" | ||||||
|  |             :active-value="0" | ||||||
|  |             :inactive-value="1" | ||||||
|  |             @change="handleStatusChange(scope.row)" | ||||||
|  |           /> | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |       <el-table-column | ||||||
|  |         label="创建时间" | ||||||
|  |         align="center" | ||||||
|  |         prop="createTime" | ||||||
|  |         :formatter="dateFormatter" | ||||||
|  |         width="180" | ||||||
|  |       /> | ||||||
|  |       <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||||
|  |         <template #default="scope"> | ||||||
|  |           <el-button | ||||||
|  |             size="small" | ||||||
|  |             type="primary" | ||||||
|  |             link | ||||||
|  |             @click="handleUpdate(scope.row)" | ||||||
|  |             v-hasPermi="['promotion:coupon-template:update']" | ||||||
|  |           > | ||||||
|  |             <Icon icon="ep:edit" :size="12" class="mr-1px" /> | ||||||
|  |             修改 | ||||||
|  |           </el-button> | ||||||
|  |           <el-button | ||||||
|  |             size="small" | ||||||
|  |             type="primary" | ||||||
|  |             link | ||||||
|  |             @click="handleDelete(scope.row)" | ||||||
|  |             v-hasPermi="['promotion:coupon-template:delete']" | ||||||
|  |           > | ||||||
|  |             <Icon icon="ep:delete" :size="12" class="mr-1px" /> | ||||||
|  |             删除 | ||||||
|  |           </el-button> | ||||||
|  |         </template> | ||||||
|  |       </el-table-column> | ||||||
|  |     </el-table> | ||||||
|  |   </ContentWrap> | ||||||
|  |  | ||||||
|  |   <!-- 分页组件 --> | ||||||
|  |   <pagination | ||||||
|  |     v-show="total > 0" | ||||||
|  |     :total="total" | ||||||
|  |     v-model:page="queryParams.pageNo" | ||||||
|  |     v-model:limit="queryParams.pageSize" | ||||||
|  |     @pagination="getList" | ||||||
|  |   /> | ||||||
|  |  | ||||||
|  |   <!-- 对话框(添加 / 修改) --> | ||||||
|  |   <el-dialog :title="title" v-model="open" width="600px" append-to-body> | ||||||
|  |     <el-form ref="formRef" :model="form" :rules="rules" label-width="140px"> | ||||||
|  |       <el-form-item label="优惠券名称" prop="name"> | ||||||
|  |         <el-input v-model="form.name" placeholder="请输入优惠券名称" /> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="优惠券类型" prop="discountType"> | ||||||
|  |         <el-radio-group v-model="form.discountType"> | ||||||
|  |           <el-radio | ||||||
|  |             v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_DISCOUNT_TYPE)" | ||||||
|  |             :key="dict.value" | ||||||
|  |             :label="parseInt(dict.value)" | ||||||
|  |             >{{ dict.label }}</el-radio | ||||||
|  |           > | ||||||
|  |         </el-radio-group> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item | ||||||
|  |         v-if="form.discountType === PromotionDiscountTypeEnum.PRICE.type" | ||||||
|  |         label="优惠券面额" | ||||||
|  |         prop="discountPrice" | ||||||
|  |       > | ||||||
|  |         <el-input-number | ||||||
|  |           v-model="form.discountPrice" | ||||||
|  |           placeholder="请输入优惠金额,单位:元" | ||||||
|  |           style="width: 400px" | ||||||
|  |           :precision="2" | ||||||
|  |           :min="0" | ||||||
|  |         /> | ||||||
|  |         元 | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item | ||||||
|  |         v-if="form.discountType === PromotionDiscountTypeEnum.PERCENT.type" | ||||||
|  |         label="优惠券折扣" | ||||||
|  |         prop="discountPercent" | ||||||
|  |       > | ||||||
|  |         <el-input-number | ||||||
|  |           v-model="form.discountPercent" | ||||||
|  |           placeholder="优惠券折扣不能小于 1 折,且不可大于 9.9 折" | ||||||
|  |           style="width: 400px" | ||||||
|  |           :precision="1" | ||||||
|  |           :min="1" | ||||||
|  |           :max="9.9" | ||||||
|  |         /> | ||||||
|  |         折 | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item | ||||||
|  |         v-if="form.discountType === PromotionDiscountTypeEnum.PERCENT.type" | ||||||
|  |         label="最多优惠" | ||||||
|  |         prop="discountLimitPrice" | ||||||
|  |       > | ||||||
|  |         <el-input-number | ||||||
|  |           v-model="form.discountLimitPrice" | ||||||
|  |           placeholder="请输入最多优惠" | ||||||
|  |           style="width: 400px" | ||||||
|  |           :precision="2" | ||||||
|  |           :min="0" | ||||||
|  |         /> | ||||||
|  |         元 | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="满多少元可以使用" prop="usePrice"> | ||||||
|  |         <el-input-number | ||||||
|  |           v-model="form.usePrice" | ||||||
|  |           placeholder="无门槛请设为 0" | ||||||
|  |           style="width: 400px" | ||||||
|  |           :precision="2" | ||||||
|  |           :min="0" | ||||||
|  |         /> | ||||||
|  |         元 | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="领取方式" prop="takeType"> | ||||||
|  |         <el-radio-group v-model="form.takeType"> | ||||||
|  |           <el-radio :key="1" :label="1">直接领取</el-radio> | ||||||
|  |           <el-radio :key="2" :label="2">指定发放</el-radio> | ||||||
|  |         </el-radio-group> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item v-if="form.takeType === 1" label="发放数量" prop="totalCount"> | ||||||
|  |         <el-input-number | ||||||
|  |           v-model="form.totalCount" | ||||||
|  |           placeholder="发放数量,没有之后不能领取或发放,-1 为不限制" | ||||||
|  |           style="width: 400px" | ||||||
|  |           :precision="0" | ||||||
|  |           :min="-1" | ||||||
|  |         /> | ||||||
|  |         张 | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item v-if="form.takeType === 1" label="每人限领个数" prop="takeLimitCount"> | ||||||
|  |         <el-input-number | ||||||
|  |           v-model="form.takeLimitCount" | ||||||
|  |           placeholder="设置为 -1 时,可无限领取" | ||||||
|  |           style="width: 400px" | ||||||
|  |           :precision="0" | ||||||
|  |           :min="-1" | ||||||
|  |         /> | ||||||
|  |         张 | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="有效期类型" prop="validityType"> | ||||||
|  |         <el-radio-group v-model="form.validityType"> | ||||||
|  |           <el-radio | ||||||
|  |             v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_COUPON_TEMPLATE_VALIDITY_TYPE)" | ||||||
|  |             :key="dict.value" | ||||||
|  |             :label="parseInt(dict.value)" | ||||||
|  |             >{{ dict.label }}</el-radio | ||||||
|  |           > | ||||||
|  |         </el-radio-group> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item | ||||||
|  |         v-if="form.validityType === CouponTemplateValidityTypeEnum.DATE.type" | ||||||
|  |         label="固定日期" | ||||||
|  |         prop="validTimes" | ||||||
|  |       > | ||||||
|  |         <el-date-picker | ||||||
|  |           v-model="form.validTimes" | ||||||
|  |           style="width: 240px" | ||||||
|  |           value-format="yyyy-MM-dd HH:mm:ss" | ||||||
|  |           type="datetimerange" | ||||||
|  |           :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]" | ||||||
|  |         /> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item | ||||||
|  |         v-if="form.validityType === CouponTemplateValidityTypeEnum.TERM.type" | ||||||
|  |         label="领取日期" | ||||||
|  |         prop="fixedStartTerm" | ||||||
|  |       > | ||||||
|  |         第 | ||||||
|  |         <el-input-number | ||||||
|  |           v-model="form.fixedStartTerm" | ||||||
|  |           placeholder="0 为今天生效" | ||||||
|  |           style="width: 165px" | ||||||
|  |           :precision="0" | ||||||
|  |           :min="0" | ||||||
|  |         /> | ||||||
|  |         至 | ||||||
|  |         <el-input-number | ||||||
|  |           v-model="form.fixedEndTerm" | ||||||
|  |           placeholder="请输入结束天数" | ||||||
|  |           style="width: 165px" | ||||||
|  |           :precision="0" | ||||||
|  |           :min="0" | ||||||
|  |         /> | ||||||
|  |         天有效 | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item label="活动商品" prop="productScope"> | ||||||
|  |         <el-radio-group v-model="form.productScope"> | ||||||
|  |           <el-radio | ||||||
|  |             v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_PRODUCT_SCOPE)" | ||||||
|  |             :key="dict.value" | ||||||
|  |             :label="parseInt(dict.value)" | ||||||
|  |             >{{ dict.label }}</el-radio | ||||||
|  |           > | ||||||
|  |         </el-radio-group> | ||||||
|  |       </el-form-item> | ||||||
|  |       <el-form-item | ||||||
|  |         v-if="form.productScope === PromotionProductScopeEnum.SPU.scope" | ||||||
|  |         prop="productSpuIds" | ||||||
|  |       > | ||||||
|  |         <el-select | ||||||
|  |           v-model="form.productSpuIds" | ||||||
|  |           placeholder="请选择活动商品" | ||||||
|  |           clearable | ||||||
|  |           size="small" | ||||||
|  |           multiple | ||||||
|  |           filterable | ||||||
|  |           style="width: 400px" | ||||||
|  |         > | ||||||
|  |           <el-option v-for="item in productSpus" :key="item.id" :label="item.name" :value="item.id"> | ||||||
|  |             <span style="float: left">{{ item.name }}</span> | ||||||
|  |             <span style="float: right; color: #8492a6; font-size: 13px" | ||||||
|  |               >¥{{ (item.minPrice / 100.0).toFixed(2) }}</span | ||||||
|  |             > | ||||||
|  |           </el-option> | ||||||
|  |         </el-select> | ||||||
|  |       </el-form-item> | ||||||
|  |     </el-form> | ||||||
|  |     <template #footer> | ||||||
|  |       <div class="dialog-footer"> | ||||||
|  |         <el-button type="primary" @click="submitForm">确 定</el-button> | ||||||
|  |         <el-button @click="cancel">取 消</el-button> | ||||||
|  |       </div> | ||||||
|  |     </template> | ||||||
|  |   </el-dialog> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script setup lang="ts" name="PromotionCouponTemplate"> | ||||||
|  | import { | ||||||
|  |   createCouponTemplate, | ||||||
|  |   updateCouponTemplate, | ||||||
|  |   deleteCouponTemplate, | ||||||
|  |   getCouponTemplate, | ||||||
|  |   getCouponTemplatePage, | ||||||
|  |   updateCouponTemplateStatus | ||||||
|  | } from '@/api/mall/promotion/couponTemplate' | ||||||
|  | import { | ||||||
|  |   CommonStatusEnum, | ||||||
|  |   CouponTemplateValidityTypeEnum, | ||||||
|  |   PromotionDiscountTypeEnum, | ||||||
|  |   PromotionProductScopeEnum | ||||||
|  | } from '@/utils/constants' | ||||||
|  | import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||||
|  | import { getSpuSimpleList } from '@/api/mall/product/spu' | ||||||
|  | import { dateFormatter, formatDate } from '@/utils/formatTime' | ||||||
|  | import { FormInstance } from 'element-plus' | ||||||
|  |  | ||||||
|  | // 消息弹窗 | ||||||
|  | const message = useMessage() | ||||||
|  |  | ||||||
|  | // 遮罩层 | ||||||
|  | const loading = ref(true) | ||||||
|  | // 显示搜索条件 | ||||||
|  | const showSearch = ref(true) | ||||||
|  | // 总条数 | ||||||
|  | const total = ref(0) | ||||||
|  | // 优惠劵列表 | ||||||
|  | const list = ref([]) | ||||||
|  | // 弹出层标题 | ||||||
|  | const title = ref('') | ||||||
|  | // 是否显示弹出层 | ||||||
|  | const open = ref(false) | ||||||
|  | // 查询参数 | ||||||
|  | const queryParams = reactive({ | ||||||
|  |   pageNo: 1, | ||||||
|  |   pageSize: 10, | ||||||
|  |   name: null, | ||||||
|  |   status: null, | ||||||
|  |   type: null, | ||||||
|  |   createTime: [] | ||||||
|  | }) | ||||||
|  | // 表单参数 | ||||||
|  | const form = ref<any>({}) | ||||||
|  | // 表单校验 | ||||||
|  | const rules = { | ||||||
|  |   name: [{ required: true, message: '优惠券名称不能为空', trigger: 'blur' }], | ||||||
|  |   discountType: [{ required: true, message: '优惠券类型不能为空', trigger: 'change' }], | ||||||
|  |   discountPrice: [{ required: true, message: '优惠券面额不能为空', trigger: 'blur' }], | ||||||
|  |   discountPercent: [{ required: true, message: '优惠券折扣不能为空', trigger: 'blur' }], | ||||||
|  |   discountLimitPrice: [{ required: true, message: '最多优惠不能为空', trigger: 'blur' }], | ||||||
|  |   usePrice: [{ required: true, message: '满多少元可以使用不能为空', trigger: 'blur' }], | ||||||
|  |   takeType: [{ required: true, message: '领取方式不能为空', trigger: 'change' }], | ||||||
|  |   totalCount: [{ required: true, message: '发放数量不能为空', trigger: 'blur' }], | ||||||
|  |   takeLimitCount: [{ required: true, message: '每人限领个数不能为空', trigger: 'blur' }], | ||||||
|  |   validityType: [{ required: true, message: '有效期类型不能为空', trigger: 'change' }], | ||||||
|  |   validTimes: [{ required: true, message: '固定日期不能为空', trigger: 'change' }], | ||||||
|  |   fixedStartTerm: [{ required: true, message: '开始领取天数不能为空', trigger: 'blur' }], | ||||||
|  |   fixedEndTerm: [{ required: true, message: '开始领取天数不能为空', trigger: 'blur' }], | ||||||
|  |   productScope: [{ required: true, message: '商品范围不能为空', trigger: 'blur' }], | ||||||
|  |   productSpuIds: [{ required: true, message: '商品范围不能为空', trigger: 'blur' }] | ||||||
|  | } | ||||||
|  | // 商品列表 | ||||||
|  | const productSpus = ref([]) | ||||||
|  | const queryFormRef = ref<FormInstance | null>(null) | ||||||
|  | const formRef = ref<FormInstance | null>(null) | ||||||
|  |  | ||||||
|  | onMounted(() => { | ||||||
|  |   getList() | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | /** 查询列表 */ | ||||||
|  | const getList = async () => { | ||||||
|  |   loading.value = true | ||||||
|  |   try { | ||||||
|  |     // 执行查询 | ||||||
|  |     const data = await getCouponTemplatePage(queryParams) | ||||||
|  |     list.value = data.list | ||||||
|  |     total.value = data.total | ||||||
|  |     // 查询商品列表 | ||||||
|  |     productSpus.value = await getSpuSimpleList() | ||||||
|  |   } finally { | ||||||
|  |     loading.value = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 取消按钮 */ | ||||||
|  | const cancel = () => { | ||||||
|  |   open.value = false | ||||||
|  |   reset() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 表单重置 */ | ||||||
|  | const reset = () => { | ||||||
|  |   form.value = { | ||||||
|  |     id: undefined, | ||||||
|  |     name: undefined, | ||||||
|  |     discountType: PromotionDiscountTypeEnum.PRICE.type, | ||||||
|  |     discountPrice: undefined, | ||||||
|  |     discountPercent: undefined, | ||||||
|  |     discountLimitPrice: undefined, | ||||||
|  |     usePrice: undefined, | ||||||
|  |     takeType: 1, | ||||||
|  |     totalCount: undefined, | ||||||
|  |     takeLimitCount: undefined, | ||||||
|  |     validityType: CouponTemplateValidityTypeEnum.DATE.type, | ||||||
|  |     validTimes: [], | ||||||
|  |     validStartTime: undefined, | ||||||
|  |     validEndTime: undefined, | ||||||
|  |     fixedStartTerm: undefined, | ||||||
|  |     fixedEndTerm: undefined, | ||||||
|  |     productScope: PromotionProductScopeEnum.ALL.scope, | ||||||
|  |     productSpuIds: [] | ||||||
|  |   } | ||||||
|  |   formRef.value?.resetFields() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 搜索按钮操作 */ | ||||||
|  | const handleQuery = () => { | ||||||
|  |   queryParams.pageNo = 1 | ||||||
|  |   getList() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 重置按钮操作 */ | ||||||
|  | const resetQuery = () => { | ||||||
|  |   queryFormRef?.value?.resetFields() | ||||||
|  |   handleQuery() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 新增按钮操作 */ | ||||||
|  | const handleAdd = () => { | ||||||
|  |   reset() | ||||||
|  |   open.value = true | ||||||
|  |   title.value = '添加优惠劵' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 修改按钮操作 */ | ||||||
|  | const handleUpdate = async (row: any) => { | ||||||
|  |   reset() | ||||||
|  |   const id = row.id | ||||||
|  |   try { | ||||||
|  |     const data = await getCouponTemplate(id) | ||||||
|  |     form.value = { | ||||||
|  |       ...data, | ||||||
|  |       discountPrice: data.discountPrice !== undefined ? data.discountPrice / 100.0 : undefined, | ||||||
|  |       discountPercent: data.discountPercent !== undefined ? data.discountPercent / 10.0 : undefined, | ||||||
|  |       discountLimitPrice: | ||||||
|  |         data.discountLimitPrice !== undefined ? data.discountLimitPrice / 100.0 : undefined, | ||||||
|  |       usePrice: data.usePrice !== undefined ? data.usePrice / 100.0 : undefined, | ||||||
|  |       validTimes: [data.validStartTime, data.validEndTime] | ||||||
|  |     } | ||||||
|  |     open.value = true | ||||||
|  |     title.value = '修改优惠劵' | ||||||
|  |   } catch {} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 提交按钮 */ | ||||||
|  | const submitForm = async () => { | ||||||
|  |   const valid = await formRef.value?.validate() | ||||||
|  |   if (!valid) { | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // 金额相关字段的缩放 | ||||||
|  |   let data = { | ||||||
|  |     ...form.value, | ||||||
|  |     discountPrice: | ||||||
|  |       form.value.discountPrice !== undefined ? form.value.discountPrice * 100 : undefined, | ||||||
|  |     discountPercent: | ||||||
|  |       form.value.discountPercent !== undefined ? form.value.discountPercent * 10 : undefined, | ||||||
|  |     discountLimitPrice: | ||||||
|  |       form.value.discountLimitPrice !== undefined ? form.value.discountLimitPrice * 100 : undefined, | ||||||
|  |     usePrice: form.value.usePrice !== undefined ? form.value.usePrice * 100 : undefined, | ||||||
|  |     validStartTime: | ||||||
|  |       form.value.validTimes && form.value.validTimes.length === 2 | ||||||
|  |         ? form.value.validTimes[0] | ||||||
|  |         : undefined, | ||||||
|  |     validEndTime: | ||||||
|  |       form.value.validTimes && form.value.validTimes.length === 2 | ||||||
|  |         ? form.value.validTimes[1] | ||||||
|  |         : undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // 修改的提交 | ||||||
|  |   if (form.value.id != null) { | ||||||
|  |     try { | ||||||
|  |       await updateCouponTemplate(data) | ||||||
|  |       message.success('修改成功') | ||||||
|  |       open.value = false | ||||||
|  |       getList() | ||||||
|  |     } catch {} | ||||||
|  |  | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   try { | ||||||
|  |     await createCouponTemplate(data) | ||||||
|  |     message.success('新增成功') | ||||||
|  |     open.value = false | ||||||
|  |     getList() | ||||||
|  |   } catch {} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 优惠劵模板状态修改 */ | ||||||
|  | const handleStatusChange = async (row: any) => { | ||||||
|  |   // 此时,row 已经变成目标状态了,所以可以直接提交请求和提示 | ||||||
|  |   let text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用' | ||||||
|  |  | ||||||
|  |   try { | ||||||
|  |     await message.confirm('确认要"' + text + '""' + row.name + '"优惠劵吗?') | ||||||
|  |     await updateCouponTemplateStatus(row.id, row.status) | ||||||
|  |     message.success(text + '成功') | ||||||
|  |   } catch { | ||||||
|  |     // 异常时,需要将 row.status 状态重置回之前的 | ||||||
|  |     row.status = | ||||||
|  |       row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE : CommonStatusEnum.ENABLE | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** 删除按钮操作 */ | ||||||
|  | const handleDelete = async (row: any) => { | ||||||
|  |   const id = row.id | ||||||
|  |   try { | ||||||
|  |     await message.confirm('是否确认删除优惠劵编号为"' + id + '"的数据项?') | ||||||
|  |     await deleteCouponTemplate(id) | ||||||
|  |   } catch {} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 格式化【优惠金额/折扣】 | ||||||
|  | const discountFormat = (row: any) => { | ||||||
|  |   if (row.discountType === PromotionDiscountTypeEnum.PRICE.type) { | ||||||
|  |     return `¥${(row.discountPrice / 100.0).toFixed(2)}` | ||||||
|  |   } | ||||||
|  |   if (row.discountType === PromotionDiscountTypeEnum.PERCENT.type) { | ||||||
|  |     return `¥${(row.discountPrice / 100.0).toFixed(2)}` | ||||||
|  |   } | ||||||
|  |   return '未知【' + row.discountType + '】' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 格式化【领取上限】 | ||||||
|  | const takeLimitCountFormat = (row: any) => { | ||||||
|  |   if (row.takeLimitCount === -1) { | ||||||
|  |     return '无领取限制' | ||||||
|  |   } | ||||||
|  |   return `${row.takeLimitCount} 张/人` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 格式化【有效期限】 | ||||||
|  | const validityTypeFormat = (row: any) => { | ||||||
|  |   if (row.validityType === CouponTemplateValidityTypeEnum.DATE.type) { | ||||||
|  |     return `${formatDate(row.validStartTime)} 至 ${formatDate(row.validEndTime)}` | ||||||
|  |   } | ||||||
|  |   if (row.validityType === CouponTemplateValidityTypeEnum.TERM.type) { | ||||||
|  |     return `领取后第 ${row.fixedStartTerm} - ${row.fixedEndTerm} 天内可用` | ||||||
|  |   } | ||||||
|  |   return '未知【' + row.validityType + '】' | ||||||
|  | } | ||||||
|  | </script> | ||||||
| @@ -171,7 +171,10 @@ const formRules = reactive({ | |||||||
|   sort: [{ required: true, message: '分类排序不能为空', trigger: 'blur' }] |   sort: [{ required: true, message: '分类排序不能为空', trigger: 'blur' }] | ||||||
| }) | }) | ||||||
| const formRef = ref() // 表单 Ref | const formRef = ref() // 表单 Ref | ||||||
| const areaCache = ref([]) //由于区域节点懒加载,已选区域节点需要缓存展示 | const areaCache = ref([]) // 由于区域节点懒加载,已选区域节点需要缓存展示 | ||||||
|  | // TODO @jason:配送的时候,只允许选择省市级别,不允许选择区;如果这样的话,是不是打开弹窗,直接把城市都请求过来; | ||||||
|  | // TODO @jaosn:因为只有省市两级,感觉就不用特殊做全国逻辑;选择全国,就默认把子节点都选择上;另外,选择父节点,要把子节点选中哈; | ||||||
|  |  | ||||||
| /** 打开弹窗 */ | /** 打开弹窗 */ | ||||||
| const open = async (type: string, id?: number) => { | const open = async (type: string, id?: number) => { | ||||||
|   dialogVisible.value = true |   dialogVisible.value = true | ||||||
| @@ -204,9 +207,9 @@ const open = async (type: string, id?: number) => { | |||||||
|         } |         } | ||||||
|         item.freePrice = fenToYuan(item.freePrice) |         item.freePrice = fenToYuan(item.freePrice) | ||||||
|       }) |       }) | ||||||
|       //已选的区域节点 |       // 已选的区域节点 | ||||||
|       const areaIds = chargeAreaIds.concat(freeAreaIds) |       const areaIds = chargeAreaIds.concat(freeAreaIds) | ||||||
|       //区域节点,懒加载方式。 已选节点需要缓存展示 |       // 区域节点,懒加载方式。已选节点需要缓存展示 | ||||||
|       areaCache.value = await getAreaListByIds(areaIds.join(',')) |       areaCache.value = await getAreaListByIds(areaIds.join(',')) | ||||||
|     } |     } | ||||||
|   } finally { |   } finally { | ||||||
| @@ -226,8 +229,9 @@ const submitForm = async () => { | |||||||
|   formLoading.value = true |   formLoading.value = true | ||||||
|   try { |   try { | ||||||
|     const data = formData.value as DeliveryExpressTemplateApi.DeliveryExpressTemplateVO |     const data = formData.value as DeliveryExpressTemplateApi.DeliveryExpressTemplateVO | ||||||
|  |     // 前端价格以元展示,提交到后端。用分计算 | ||||||
|  |     // TODO @jason:不能直接这样改,要复制出来改。不然后端操作失败,数据已经被改了 | ||||||
|     data.templateCharge.forEach((item) => { |     data.templateCharge.forEach((item) => { | ||||||
|       //前端价格以元展示,提交到后端。用分计算 |  | ||||||
|       item.startPrice = yuanToFen(item.startPrice) |       item.startPrice = yuanToFen(item.startPrice) | ||||||
|       item.extraPrice = yuanToFen(item.extraPrice) |       item.extraPrice = yuanToFen(item.extraPrice) | ||||||
|     }) |     }) | ||||||
| @@ -248,6 +252,7 @@ const submitForm = async () => { | |||||||
|     formLoading.value = false |     formLoading.value = false | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| /** 重置表单 */ | /** 重置表单 */ | ||||||
| const resetForm = () => { | const resetForm = () => { | ||||||
|   formData.value = { |   formData.value = { | ||||||
| @@ -269,6 +274,7 @@ const resetForm = () => { | |||||||
|   columnTitle.value = columnTitleMap.get(1) |   columnTitle.value = columnTitleMap.get(1) | ||||||
|   formRef.value?.resetFields() |   formRef.value?.resetFields() | ||||||
| } | } | ||||||
|  |  | ||||||
| /** 配送计费方法改变 */ | /** 配送计费方法改变 */ | ||||||
| const changeChargeMode = (chargeMode: number) => { | const changeChargeMode = (chargeMode: number) => { | ||||||
|   columnTitle.value = columnTitleMap.get(chargeMode) |   columnTitle.value = columnTitleMap.get(chargeMode) | ||||||
| @@ -276,6 +282,24 @@ const changeChargeMode = (chargeMode: number) => { | |||||||
| const defaultArea = [{ id: 1, name: '全国', disabled: false }] | const defaultArea = [{ id: 1, name: '全国', disabled: false }] | ||||||
|  |  | ||||||
| /** 初始化数据 */ | /** 初始化数据 */ | ||||||
|  | // TODO @jason:是不是不用写这样一个初始化方法,columnTitleMap 直接就可以了呀 | ||||||
|  | // const columnTitleMap = { | ||||||
|  | //   '1': { | ||||||
|  | //     startCountTitle: '首件', | ||||||
|  | //     extraCountTitle: '续件', | ||||||
|  | //     freeCountTitle: '包邮件数' | ||||||
|  | //   }, | ||||||
|  | //   '2': { | ||||||
|  | //     startCountTitle: '首件重量(kg)', | ||||||
|  | //     extraCountTitle: '续件重量(kg)', | ||||||
|  | //     freeCountTitle: '包邮重量(kg)' | ||||||
|  | //   }, | ||||||
|  | //   '3': { | ||||||
|  | //     startCountTitle: '首件体积(m³)', | ||||||
|  | //     extraCountTitle: '续件体积(m³)', | ||||||
|  | //     freeCountTitle: '包邮体积(m³)' | ||||||
|  | //   } | ||||||
|  | // } | ||||||
| const initData = async () => { | const initData = async () => { | ||||||
|   // TODO 从服务端全量加载数据, 后面看懒加载是不是可以从前端获取数据。 目前从后端获取数据 |   // TODO 从服务端全量加载数据, 后面看懒加载是不是可以从前端获取数据。 目前从后端获取数据 | ||||||
|   // formLoading.value = true |   // formLoading.value = true | ||||||
| @@ -286,7 +310,7 @@ const initData = async () => { | |||||||
|   // } finally { |   // } finally { | ||||||
|   //   formLoading.value = false |   //   formLoading.value = false | ||||||
|   // } |   // } | ||||||
|   //表头标题和计费方式的映射 |   // 表头标题和计费方式的映射 | ||||||
|   columnTitleMap.set(1, { |   columnTitleMap.set(1, { | ||||||
|     startCountTitle: '首件', |     startCountTitle: '首件', | ||||||
|     extraCountTitle: '续件', |     extraCountTitle: '续件', | ||||||
| @@ -320,6 +344,7 @@ const loadChargeArea = async (node, resolve) => { | |||||||
|     const item = data[0] |     const item = data[0] | ||||||
|     if (areaIds.includes(item.id)) { |     if (areaIds.includes(item.id)) { | ||||||
|       // TODO 禁止选中的区域有些问题, 导致修改时候不能重新选择 不知道如何处理。 暂时注释掉 @芋艿 有空瞅瞅 |       // TODO 禁止选中的区域有些问题, 导致修改时候不能重新选择 不知道如何处理。 暂时注释掉 @芋艿 有空瞅瞅 | ||||||
|  |       // TODO @jason:先不做这个功能哈。 | ||||||
|       //item.disabled = true |       //item.disabled = true | ||||||
|     } |     } | ||||||
|     resolve(data) |     resolve(data) | ||||||
| @@ -357,10 +382,11 @@ const loadFreeArea = async (node, resolve) => { | |||||||
|   } else { |   } else { | ||||||
|     const id = node.data.id |     const id = node.data.id | ||||||
|     const data = await getChildrenArea(id) |     const data = await getChildrenArea(id) | ||||||
|     //已选区域需要禁止再次选择 |     // 已选区域需要禁止再次选择 | ||||||
|     data.forEach((item) => { |     data.forEach((item) => { | ||||||
|       if (areaIds.includes(item.id)) { |       if (areaIds.includes(item.id)) { | ||||||
|         // TODO 禁止选中的区域有些问题, 导致修改时候不能重新选择 不知道如何处理。 暂时注释掉 @芋艿 有空瞅瞅 |         // TODO 禁止选中的区域有些问题, 导致修改时候不能重新选择 不知道如何处理。 暂时注释掉 @芋艿 有空瞅瞅 | ||||||
|  |         // TODO @jason:先不做这个功能哈。 | ||||||
|         //item.disabled = true |         //item.disabled = true | ||||||
|       } |       } | ||||||
|     }) |     }) | ||||||
| @@ -378,11 +404,13 @@ const addChargeArea = () => { | |||||||
|     extraPrice: 1 |     extraPrice: 1 | ||||||
|   }) |   }) | ||||||
| } | } | ||||||
|  |  | ||||||
| /** 删除计费区域 */ | /** 删除计费区域 */ | ||||||
| const deleteChargeArea = (index) => { | const deleteChargeArea = (index) => { | ||||||
|   const data = formData.value |   const data = formData.value | ||||||
|   data.templateCharge.splice(index, 1) |   data.templateCharge.splice(index, 1) | ||||||
| } | } | ||||||
|  |  | ||||||
| /** 添加包邮区域 */ | /** 添加包邮区域 */ | ||||||
| const addFreeArea = () => { | const addFreeArea = () => { | ||||||
|   const data = formData.value |   const data = formData.value | ||||||
| @@ -392,6 +420,7 @@ const addFreeArea = () => { | |||||||
|     freePrice: 1 |     freePrice: 1 | ||||||
|   }) |   }) | ||||||
| } | } | ||||||
|  |  | ||||||
| /** 删除包邮区域 */ | /** 删除包邮区域 */ | ||||||
| const deleteFreeArea = (index) => { | const deleteFreeArea = (index) => { | ||||||
|   const data = formData.value |   const data = formData.value | ||||||
|   | |||||||
| @@ -110,6 +110,7 @@ const queryParams = reactive({ | |||||||
|   chargeMode: undefined |   chargeMode: undefined | ||||||
| }) | }) | ||||||
| const queryFormRef = ref() // 搜索的表单 | const queryFormRef = ref() // 搜索的表单 | ||||||
|  |  | ||||||
| /** 查询列表 */ | /** 查询列表 */ | ||||||
| const getList = async () => { | const getList = async () => { | ||||||
|   loading.value = true |   loading.value = true | ||||||
|   | |||||||
| @@ -51,7 +51,7 @@ | |||||||
|       <el-row> |       <el-row> | ||||||
|         <el-col :span="12"> |         <el-col :span="12"> | ||||||
|           <el-form-item label="门店所在地区" prop="areaId"> |           <el-form-item label="门店所在地区" prop="areaId"> | ||||||
|             <el-cascader v-model="formData.areaId" :options="areaList" :props="cascaderProps" /> |             <el-cascader v-model="formData.areaId" :options="areaList" :props="areaTreeProps" /> | ||||||
|           </el-form-item> |           </el-form-item> | ||||||
|         </el-col> |         </el-col> | ||||||
|         <el-col :span="12"> |         <el-col :span="12"> | ||||||
| @@ -99,7 +99,7 @@ | |||||||
|         </el-col> |         </el-col> | ||||||
|       </el-row> |       </el-row> | ||||||
|       <el-form-item label="获取经纬度"> |       <el-form-item label="获取经纬度"> | ||||||
|         <el-button type="primary" @click="searchLocation">获取</el-button> |         <el-button type="primary" @click="mapDialogVisible.value = true">获取</el-button> | ||||||
|       </el-form-item> |       </el-form-item> | ||||||
|     </el-form> |     </el-form> | ||||||
|     <template #footer> |     <template #footer> | ||||||
| @@ -125,6 +125,7 @@ import { getAreaTree } from '@/api/system/area' | |||||||
| import * as ConfigApi from '@/api/infra/config' | import * as ConfigApi from '@/api/infra/config' | ||||||
| const { t } = useI18n() // 国际化 | const { t } = useI18n() // 国际化 | ||||||
| const message = useMessage() // 消息弹窗 | const message = useMessage() // 消息弹窗 | ||||||
|  |  | ||||||
| const dialogVisible = ref(false) // 弹窗的是否展示 | const dialogVisible = ref(false) // 弹窗的是否展示 | ||||||
| const mapDialogVisible = ref(false) // 地图弹窗的是否展示 | const mapDialogVisible = ref(false) // 地图弹窗的是否展示 | ||||||
| const dialogTitle = ref('') // 弹窗的标题 | const dialogTitle = ref('') // 弹窗的标题 | ||||||
| @@ -160,14 +161,15 @@ const formRules = reactive({ | |||||||
|   status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }] |   status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }] | ||||||
| }) | }) | ||||||
| const formRef = ref() // 表单 Ref | const formRef = ref() // 表单 Ref | ||||||
| const cascaderProps = { | const areaTreeProps = { | ||||||
|   children: 'children', |   children: 'children', | ||||||
|   label: 'name', |   label: 'name', | ||||||
|   value: 'id', |   value: 'id', | ||||||
|   emitPath: false |   emitPath: false | ||||||
| } | } | ||||||
| const areaList = ref() // 区域树 | const areaList = ref() // 区域树 | ||||||
| const tencentLbsUrl = ref('') //腾讯位置服务 url | const tencentLbsUrl = ref('') // 腾讯位置服务 url | ||||||
|  |  | ||||||
| /** 打开弹窗 */ | /** 打开弹窗 */ | ||||||
| const open = async (type: string, id?: number) => { | const open = async (type: string, id?: number) => { | ||||||
|   dialogVisible.value = true |   dialogVisible.value = true | ||||||
| @@ -196,7 +198,6 @@ const submitForm = async () => { | |||||||
|   // 提交请求 |   // 提交请求 | ||||||
|   formLoading.value = true |   formLoading.value = true | ||||||
|   try { |   try { | ||||||
|     console.log('formData.value', formData.value) |  | ||||||
|     const data = formData.value as DeliveryPickUpStoreApi.DeliveryPickUpStoreVO |     const data = formData.value as DeliveryPickUpStoreApi.DeliveryPickUpStoreVO | ||||||
|     if (formType.value === 'create') { |     if (formType.value === 'create') { | ||||||
|       await DeliveryPickUpStoreApi.createDeliveryPickUpStore(data) |       await DeliveryPickUpStoreApi.createDeliveryPickUpStore(data) | ||||||
| @@ -222,7 +223,7 @@ const resetForm = () => { | |||||||
|     logo: '', |     logo: '', | ||||||
|     detailAddress: '', |     detailAddress: '', | ||||||
|     introduction: '', |     introduction: '', | ||||||
|     areaId: 1, |     areaId: undefined, | ||||||
|     openingTime: undefined, |     openingTime: undefined, | ||||||
|     closingTime: undefined, |     closingTime: undefined, | ||||||
|     latitude: undefined, |     latitude: undefined, | ||||||
| @@ -232,11 +233,7 @@ const resetForm = () => { | |||||||
|   formRef.value?.resetFields() |   formRef.value?.resetFields() | ||||||
| } | } | ||||||
|  |  | ||||||
| //查找位置 | /** 选择经纬度 */ | ||||||
| const searchLocation = async () => { |  | ||||||
|   mapDialogVisible.value = true |  | ||||||
| } |  | ||||||
| // 选择经纬度 |  | ||||||
| const selectAddress = function (loc: any): void { | const selectAddress = function (loc: any): void { | ||||||
|   if (loc.latlng && loc.latlng.lat) { |   if (loc.latlng && loc.latlng.lat) { | ||||||
|     formData.value.latitude = loc.latlng.lat |     formData.value.latitude = loc.latlng.lat | ||||||
| @@ -246,6 +243,7 @@ const selectAddress = function (loc: any): void { | |||||||
|   } |   } | ||||||
|   mapDialogVisible.value = false |   mapDialogVisible.value = false | ||||||
| } | } | ||||||
|  |  | ||||||
| /** 初始化数据 */ | /** 初始化数据 */ | ||||||
| const initData = async () => { | const initData = async () => { | ||||||
|   formLoading.value = true |   formLoading.value = true | ||||||
| @@ -255,6 +253,7 @@ const initData = async () => { | |||||||
|   } finally { |   } finally { | ||||||
|     formLoading.value = false |     formLoading.value = false | ||||||
|   } |   } | ||||||
|  |   // TODO @jason:要不创建一个 initTencentLbsMap | ||||||
|   window.selectAddress = selectAddress |   window.selectAddress = selectAddress | ||||||
|   window.addEventListener( |   window.addEventListener( | ||||||
|     'message', |     'message', | ||||||
| @@ -262,7 +261,7 @@ const initData = async () => { | |||||||
|       // 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息 |       // 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息 | ||||||
|       let loc = event.data |       let loc = event.data | ||||||
|       if (loc && loc.module === 'locationPicker') { |       if (loc && loc.module === 'locationPicker') { | ||||||
|         // 防止其他应用也会向该页面post信息,需判断module是否为'locationPicker' |         // 防止其他应用也会向该页面 post 信息,需判断 module 是否为 'locationPicker' | ||||||
|         window.parent.selectAddress(loc) |         window.parent.selectAddress(loc) | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -121,6 +121,7 @@ import { dateFormatter } from '@/utils/formatTime' | |||||||
| import download from '@/utils/download' | import download from '@/utils/download' | ||||||
| const message = useMessage() // 消息弹窗 | const message = useMessage() // 消息弹窗 | ||||||
| const { t } = useI18n() // 国际化 | const { t } = useI18n() // 国际化 | ||||||
|  |  | ||||||
| const total = ref(0) // 列表的总页数 | const total = ref(0) // 列表的总页数 | ||||||
| const loading = ref(true) // 列表的加载中 | const loading = ref(true) // 列表的加载中 | ||||||
| const exportLoading = ref(false) // 导出的加载中 | const exportLoading = ref(false) // 导出的加载中 | ||||||
| @@ -134,6 +135,7 @@ const queryParams = reactive({ | |||||||
|   createTime: [] |   createTime: [] | ||||||
| }) | }) | ||||||
| const queryFormRef = ref() // 搜索的表单 | const queryFormRef = ref() // 搜索的表单 | ||||||
|  |  | ||||||
| /** 添加/修改操作 */ | /** 添加/修改操作 */ | ||||||
| const formRef = ref() | const formRef = ref() | ||||||
| const openForm = (type: string, id?: number) => { | const openForm = (type: string, id?: number) => { | ||||||
| @@ -153,7 +155,7 @@ const handleDelete = async (id: number) => { | |||||||
|   } catch {} |   } catch {} | ||||||
| } | } | ||||||
|  |  | ||||||
| //** 查询列表 */ | /** 查询列表 */ | ||||||
| const getList = async () => { | const getList = async () => { | ||||||
|   loading.value = true |   loading.value = true | ||||||
|   try { |   try { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 puhui999
					puhui999