mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-10-31 10:18:43 +08:00 
			
		
		
		
	code review:优化示例订单的实现
This commit is contained in:
		| @@ -116,7 +116,7 @@ | ||||
|  | ||||
| <script lang="ts" setup> | ||||
| import QrcodeVue from 'qrcode.vue' | ||||
| import { getOrder, submitOrder } from '@/api/pay/order' | ||||
| import * as PayOrderApi from '@/api/pay/order' | ||||
| import { PayChannelEnum, PayDisplayModeEnum, PayOrderStatusEnum } from '@/utils/constants' | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import { useTagsViewStore } from '@/store/modules/tagsView' | ||||
| @@ -224,34 +224,31 @@ const barCode = ref({ | ||||
| }) | ||||
|  | ||||
| /** 获得支付信息 */ | ||||
| const getDetail = () => { | ||||
| const getDetail = async () => { | ||||
|   // 1.1 未传递订单编号 | ||||
|   if (!id.value) { | ||||
|     message.error('未传递支付单号,无法查看对应的支付信息') | ||||
|     goReturnUrl('cancel') | ||||
|     return | ||||
|   } | ||||
|   getOrder(id.value).then((data) => { | ||||
|     // 1.2 无法查询到支付信息 | ||||
|     if (!data) { | ||||
|       message.error('支付订单不存在,请检查!') | ||||
|       goReturnUrl('cancel') | ||||
|       return | ||||
|     } | ||||
|     // 1.3 如果已支付、或者已关闭,则直接跳转 | ||||
|     if (data.status === PayOrderStatusEnum.SUCCESS.status) { | ||||
|       message.success('支付成功') | ||||
|       goReturnUrl('success') | ||||
|       return | ||||
|     } else if (data.status === PayOrderStatusEnum.CLOSED.status) { | ||||
|       message.error('无法支付,原因:订单已关闭') | ||||
|       goReturnUrl('close') | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     // 2. 可以展示 | ||||
|     payOrder.value = data | ||||
|   }) | ||||
|   const data = await PayOrderApi.getOrder(id.value) | ||||
|   payOrder.value = data | ||||
|   // 1.2 无法查询到支付信息 | ||||
|   if (!data) { | ||||
|     message.error('支付订单不存在,请检查!') | ||||
|     goReturnUrl('cancel') | ||||
|     return | ||||
|   } | ||||
|   // 1.3 如果已支付、或者已关闭,则直接跳转 | ||||
|   if (data.status === PayOrderStatusEnum.SUCCESS.status) { | ||||
|     message.success('支付成功') | ||||
|     goReturnUrl('success') | ||||
|     return | ||||
|   } else if (data.status === PayOrderStatusEnum.CLOSED.status) { | ||||
|     message.error('无法支付,原因:订单已关闭') | ||||
|     goReturnUrl('close') | ||||
|     return | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** 提交支付 */ | ||||
| @@ -290,38 +287,38 @@ const submit = (channelCode) => { | ||||
|   submit0(channelCode) | ||||
| } | ||||
|  | ||||
| const submit0 = (channelCode) => { | ||||
| const submit0 = async (channelCode) => { | ||||
|   submitLoading.value = true | ||||
|   submitOrder({ | ||||
|     id: id.value, | ||||
|     channelCode: channelCode, | ||||
|     returnUrl: location.href, // 支付成功后,支付渠道跳转回当前页;再由当前页,跳转回 {@link returnUrl} 对应的地址 | ||||
|     ...buildSubmitParam(channelCode) | ||||
|   }) | ||||
|     .then((data) => { | ||||
|       // 直接返回已支付的情况,例如说扫码支付 | ||||
|       if (data.status === PayOrderStatusEnum.SUCCESS.status) { | ||||
|         clearQueryInterval() | ||||
|         message.success('支付成功!') | ||||
|         goReturnUrl('success') | ||||
|         return | ||||
|       } | ||||
|   try { | ||||
|     const formData = { | ||||
|       id: id.value, | ||||
|       channelCode: channelCode, | ||||
|       returnUrl: location.href, // 支付成功后,支付渠道跳转回当前页;再由当前页,跳转回 {@link returnUrl} 对应的地址 | ||||
|       ...buildSubmitParam(channelCode) | ||||
|     } | ||||
|     const data = await PayOrderApi.submitOrder(formData) | ||||
|     // 直接返回已支付的情况,例如说扫码支付 | ||||
|     if (data.status === PayOrderStatusEnum.SUCCESS.status) { | ||||
|       clearQueryInterval() | ||||
|       message.success('支付成功!') | ||||
|       goReturnUrl('success') | ||||
|       return | ||||
|     } | ||||
|  | ||||
|       // 展示对应的界面 | ||||
|       if (data.displayMode === PayDisplayModeEnum.URL.mode) { | ||||
|         displayUrl(channelCode, data) | ||||
|       } else if (data.displayMode === PayDisplayModeEnum.QR_CODE.mode) { | ||||
|         displayQrCode(channelCode, data) | ||||
|       } else if (data.displayMode === PayDisplayModeEnum.APP.mode) { | ||||
|         displayApp(channelCode) | ||||
|       } | ||||
|     // 展示对应的界面 | ||||
|     if (data.displayMode === PayDisplayModeEnum.URL.mode) { | ||||
|       displayUrl(channelCode, data) | ||||
|     } else if (data.displayMode === PayDisplayModeEnum.QR_CODE.mode) { | ||||
|       displayQrCode(channelCode, data) | ||||
|     } else if (data.displayMode === PayDisplayModeEnum.APP.mode) { | ||||
|       displayApp(channelCode) | ||||
|     } | ||||
|  | ||||
|       // 打开轮询任务 | ||||
|       createQueryInterval() | ||||
|     }) | ||||
|     .catch(() => { | ||||
|       submitLoading.value = false | ||||
|     }) | ||||
|     // 打开轮询任务 | ||||
|     createQueryInterval() | ||||
|   } finally { | ||||
|     submitLoading.value = false | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** 构建提交支付的额外参数 */ | ||||
| @@ -385,21 +382,20 @@ const createQueryInterval = () => { | ||||
|   if (interval.value) { | ||||
|     return | ||||
|   } | ||||
|   interval.value = setInterval(() => { | ||||
|     getOrder(id.value).then((data) => { | ||||
|       // 已支付 | ||||
|       if (data.status === PayOrderStatusEnum.SUCCESS.status) { | ||||
|         clearQueryInterval() | ||||
|         message.success('支付成功!') | ||||
|         goReturnUrl('success') | ||||
|       } | ||||
|       // 已取消 | ||||
|       if (data.status === PayOrderStatusEnum.CLOSED.status) { | ||||
|         clearQueryInterval() | ||||
|         message.error('支付已关闭!') | ||||
|         goReturnUrl('close') | ||||
|       } | ||||
|     }) | ||||
|   interval.value = setInterval(async () => { | ||||
|     const data = await PayOrderApi.getOrder(id.value) | ||||
|     // 已支付 | ||||
|     if (data.status === PayOrderStatusEnum.SUCCESS.status) { | ||||
|       clearQueryInterval() | ||||
|       message.success('支付成功!') | ||||
|       goReturnUrl('success') | ||||
|     } | ||||
|     // 已取消 | ||||
|     if (data.status === PayOrderStatusEnum.CLOSED.status) { | ||||
|       clearQueryInterval() | ||||
|       message.error('支付已关闭!') | ||||
|       goReturnUrl('close') | ||||
|     } | ||||
|   }, 1000 * 2) | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2,140 +2,163 @@ | ||||
|   <!-- 操作工具栏 --> | ||||
|   <el-row :gutter="10" class="mb8"> | ||||
|     <el-col :span="1.5"> | ||||
|       <el-button type="primary" plain @click="handleAdd"><Icon icon="ep:plus" />发起订单</el-button> | ||||
|       <el-button type="primary" plain @click="openForm"><Icon icon="ep:plus" />发起订单</el-button> | ||||
|     </el-col> | ||||
|   </el-row> | ||||
|  | ||||
|   <!-- 列表 --> | ||||
|   <el-table v-loading="loading" :data="list"> | ||||
|     <el-table-column label="订单编号" align="center" prop="id" /> | ||||
|     <el-table-column label="用户编号" align="center" prop="userId" /> | ||||
|     <el-table-column label="商品名字" align="center" prop="spuName" /> | ||||
|     <el-table-column label="支付价格" align="center" prop="price"> | ||||
|       <template #default="scope"> | ||||
|         <span>¥{{ (scope.row.price / 100.0).toFixed(2) }}</span> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="退款金额" align="center" prop="refundPrice"> | ||||
|       <template #default="scope"> | ||||
|         <span>¥{{ (scope.row.refundPrice / 100.0).toFixed(2) }}</span> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column | ||||
|       label="创建时间" | ||||
|       align="center" | ||||
|       prop="createTime" | ||||
|       width="180" | ||||
|       :formatter="dateFormatter" | ||||
|   <ContentWrap> | ||||
|     <el-table v-loading="loading" :data="list"> | ||||
|       <el-table-column label="订单编号" align="center" prop="id" /> | ||||
|       <el-table-column label="用户编号" align="center" prop="userId" /> | ||||
|       <el-table-column label="商品名字" align="center" prop="spuName" /> | ||||
|       <el-table-column label="支付价格" align="center" prop="price"> | ||||
|         <template #default="scope"> | ||||
|           <span>¥{{ (scope.row.price / 100.0).toFixed(2) }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="退款金额" align="center" prop="refundPrice"> | ||||
|         <template #default="scope"> | ||||
|           <span>¥{{ (scope.row.refundPrice / 100.0).toFixed(2) }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column | ||||
|         label="创建时间" | ||||
|         align="center" | ||||
|         prop="createTime" | ||||
|         width="180" | ||||
|         :formatter="dateFormatter" | ||||
|       /> | ||||
|       <el-table-column label="支付单号" align="center" prop="payOrderId" /> | ||||
|       <el-table-column label="是否支付" align="center" prop="payStatus"> | ||||
|         <template #default="scope"> | ||||
|           <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.payStatus" /> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column | ||||
|         label="支付时间" | ||||
|         align="center" | ||||
|         prop="payTime" | ||||
|         width="180" | ||||
|         :formatter="dateFormatter" | ||||
|       /> | ||||
|       <el-table-column label="退款时间" align="center" prop="refundTime" width="180"> | ||||
|         <template #default="scope"> | ||||
|           <span v-if="scope.row.refundTime">{{ formatDate(scope.row.refundTime) }}</span> | ||||
|           <span v-else-if="scope.row.payRefundId">退款中,等待退款结果</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||
|         <template #default="scope"> | ||||
|           <el-button link type="primary" @click="handlePay(scope.row)" v-if="!scope.row.payStatus"> | ||||
|             前往支付 | ||||
|           </el-button> | ||||
|           <el-button | ||||
|             link | ||||
|             type="danger" | ||||
|             @click="handleRefund(scope.row)" | ||||
|             v-if="scope.row.payStatus && !scope.row.payRefundId" | ||||
|           > | ||||
|             发起退款 | ||||
|           </el-button> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|     </el-table> | ||||
|     <!-- 分页组件 --> | ||||
|     <Pagination | ||||
|       :total="total" | ||||
|       v-model:page="queryParams.pageNo" | ||||
|       v-model:limit="queryParams.pageSize" | ||||
|       @pagination="getList" | ||||
|     /> | ||||
|     <el-table-column label="支付单号" align="center" prop="payOrderId" /> | ||||
|     <el-table-column label="是否支付" align="center" prop="payStatus"> | ||||
|       <template #default="scope"> | ||||
|         <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.payStatus" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column | ||||
|       label="支付时间" | ||||
|       align="center" | ||||
|       prop="payTime" | ||||
|       width="180" | ||||
|       :formatter="dateFormatter" | ||||
|     /> | ||||
|     <el-table-column label="退款时间" align="center" prop="refundTime" width="180"> | ||||
|       <template #default="scope"> | ||||
|         <span v-if="scope.row.refundTime">{{ formatDate(scope.row.refundTime) }}</span> | ||||
|         <span v-else-if="scope.row.payRefundId">退款中,等待退款结果</span> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||
|       <template #default="scope"> | ||||
|         <el-button | ||||
|           size="small" | ||||
|           type="text" | ||||
|           icon="el-icon-edit" | ||||
|           @click="handlePay(scope.row)" | ||||
|           v-if="!scope.row.payStatus" | ||||
|           >前往支付</el-button | ||||
|         > | ||||
|         <el-button | ||||
|           size="small" | ||||
|           type="text" | ||||
|           icon="el-icon-delete" | ||||
|           @click="handleRefund(scope.row)" | ||||
|           v-if="scope.row.payStatus && !scope.row.payRefundId" | ||||
|           >发起退款</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> | ||||
|  | ||||
|   <!-- 对话框(添加 / 修改) --> | ||||
|   <el-dialog :title="title" v-model="open" width="500px" append-to-body destroy-on-close> | ||||
|     <el-form ref="formRef" :model="form" :rules="rules" label-width="80px"> | ||||
|   <Dialog title="发起订单" v-model="dialogVisible" width="500px"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="80px" | ||||
|     > | ||||
|       <el-form-item label="商品" prop="spuId"> | ||||
|         <el-select | ||||
|           v-model="form.spuId" | ||||
|           v-model="formData.spuId" | ||||
|           placeholder="请输入下单商品" | ||||
|           clearable | ||||
|           size="small" | ||||
|           style="width: 380px" | ||||
|         > | ||||
|           <el-option v-for="item in spus" :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.price / 100.0).toFixed(2) }}</span | ||||
|             > | ||||
|             <span style="float: right; color: #8492a6; font-size: 13px"> | ||||
|               ¥{{ (item.price / 100.0).toFixed(2) }} | ||||
|             </span> | ||||
|           </el-option> | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="cancel">取 消</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </el-dialog> | ||||
|   </Dialog> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts" setup name="PayDemoOrder"> | ||||
| import { createDemoOrder, getDemoOrderPage, refundDemoOrder } from '@/api/pay/demo' | ||||
| import { ref, onMounted } from 'vue' | ||||
| import * as PayDemoApi from '@/api/pay/demo' | ||||
| import { dateFormatter, formatDate } from '@/utils/formatTime' | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
|  | ||||
| const { t } = useI18n() // 国际化 | ||||
| const router = useRouter() // 路由对象 | ||||
| const message = useMessage() // 消息弹窗 | ||||
|  | ||||
| // 遮罩层 | ||||
| const loading = ref(true) | ||||
| // 总条数 | ||||
| const total = ref(0) | ||||
| // 示例订单列表 | ||||
| const list = ref([]) | ||||
| // 弹出层标题 | ||||
| const title = ref('') | ||||
| // 是否显示弹出层 | ||||
| const open = ref(false) | ||||
| // 查询参数 | ||||
| const loading = ref(true) // 列表的加载中 | ||||
| const total = ref(0) // 列表的总页数 | ||||
| const list = ref([]) // 列表的数据 | ||||
| const queryParams = ref({ | ||||
|   pageNo: 1, | ||||
|   pageSize: 10 | ||||
| }) | ||||
|  | ||||
| // 表单参数 | ||||
| const form = ref({}) | ||||
| // 表单校验 | ||||
| const rules = { | ||||
|   spuId: [{ required: true, message: '商品编号不能为空', trigger: 'blur' }] | ||||
| const formRef = ref() | ||||
|  | ||||
| /** 查询列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true | ||||
|   try { | ||||
|     const data = await PayDemoApi.getDemoOrderPage(queryParams) | ||||
|     list.value = data.list | ||||
|     total.value = data.total | ||||
|   } finally { | ||||
|     loading.value = false | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** 支付按钮操作 */ | ||||
| const handlePay = (row) => { | ||||
|   router.push({ | ||||
|     name: 'PayCashier', | ||||
|     query: { | ||||
|       id: row.payOrderId, | ||||
|       returnUrl: encodeURIComponent('/pay/demo-order?id=' + row.id) | ||||
|     } | ||||
|   }) | ||||
| } | ||||
|  | ||||
| /** 退款按钮操作 */ | ||||
| const handleRefund = async (row: any) => { | ||||
|   const id = row.id | ||||
|   try { | ||||
|     await message.confirm('是否确认退款编号为"' + id + '"的示例订单?') | ||||
|     await PayDemoApi.refundDemoOrder(id) | ||||
|     await getList() | ||||
|     message.success('发起退款成功!') | ||||
|   } catch {} | ||||
| } | ||||
|  | ||||
| // ========== 弹窗 ========== | ||||
|  | ||||
| // 商品数组 | ||||
| const spus = ref([ | ||||
|   { | ||||
| @@ -165,77 +188,45 @@ const spus = ref([ | ||||
|   } | ||||
| ]) | ||||
|  | ||||
| const formRef = ref() | ||||
|  | ||||
| /** 查询列表 */ | ||||
| const getList = () => { | ||||
|   loading.value = true | ||||
|   // 执行查询 | ||||
|   getDemoOrderPage(queryParams.value).then((data) => { | ||||
|     list.value = data.list | ||||
|     total.value = data.total | ||||
|     loading.value = false | ||||
|   }) | ||||
| } | ||||
|  | ||||
| /** 取消按钮 */ | ||||
| const cancel = () => { | ||||
|   open.value = false | ||||
|   reset() | ||||
| const dialogVisible = ref(false) // 弹窗的是否展示 | ||||
| const formLoading = ref(false) // 表单的加载中 | ||||
| const formData = ref({}) // 表单数据 | ||||
| const formRules = { | ||||
|   spuId: [{ required: true, message: '商品编号不能为空', trigger: 'blur' }] | ||||
| } | ||||
|  | ||||
| /** 表单重置 */ | ||||
| const reset = () => { | ||||
|   form.value = { | ||||
|   formData.value = { | ||||
|     spuId: undefined | ||||
|   } | ||||
|   formRef.value?.resetFields() | ||||
| } | ||||
|  | ||||
| /** 新增按钮操作 */ | ||||
| const handleAdd = () => { | ||||
| const openForm = () => { | ||||
|   reset() | ||||
|   open.value = true | ||||
|   title.value = '发起订单' | ||||
|   dialogVisible.value = true | ||||
| } | ||||
|  | ||||
| /** 提交按钮 */ | ||||
| const submitForm = async () => { | ||||
|   const valid = await formRef.value?.validate() | ||||
|   if (!valid) { | ||||
|     return | ||||
|   } | ||||
|   // 添加的提交 | ||||
|   createDemoOrder(form.value).then(() => { | ||||
|     message.success('新增成功') | ||||
|     open.value = false | ||||
|     getList() | ||||
|   }) | ||||
| } | ||||
|  | ||||
| /** 支付按钮操作 */ | ||||
| const handlePay = (row) => { | ||||
|   router.push({ | ||||
|     name: 'PayCashier', | ||||
|     query: { | ||||
|       id: row.payOrderId, | ||||
|       returnUrl: encodeURIComponent('/pay/demo-order?id=' + row.id) | ||||
|     } | ||||
|   }) | ||||
| } | ||||
|  | ||||
| /** 退款按钮操作 */ | ||||
| const handleRefund = async (row: any) => { | ||||
|   const id = row.id | ||||
|  | ||||
|   // 校验表单 | ||||
|   if (!formRef) return | ||||
|   const valid = await formRef.value.validate() | ||||
|   if (!valid) return | ||||
|   // 提交请求 | ||||
|   formLoading.value = true | ||||
|   try { | ||||
|     await message.confirm('是否确认退款编号为"' + id + '"的示例订单?') | ||||
|     await refundDemoOrder(id) | ||||
|     getList() | ||||
|     message.success('发起退款成功!') | ||||
|   } catch {} | ||||
|     await PayDemoApi.createDemoOrder(formData.value) | ||||
|     message.success(t('common.createSuccess')) | ||||
|     dialogVisible.value = false | ||||
|   } finally { | ||||
|     formLoading.value = false | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** 初始化 **/ | ||||
| onMounted(() => { | ||||
|   getList() | ||||
| }) | ||||
|   | ||||
| @@ -1,113 +0,0 @@ | ||||
| <template> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px"> | ||||
|       <el-form-item label="商户全称" prop="name"> | ||||
|         <el-input v-model="formData.name" placeholder="请输入商户全称" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="商户简称" prop="shortName"> | ||||
|         <el-input v-model="formData.shortName" placeholder="请输入商户简称" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="开启状态" prop="status"> | ||||
|         <el-select v-model="formData.status" clearable placeholder="请选择状态"> | ||||
|           <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="remark"> | ||||
|         <el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" /> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| import * as MerchantApi from '@/api/pay/merchant' | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import { CommonStatusEnum } from '@/utils/constants' | ||||
|  | ||||
| defineOptions({ name: 'PayMerchantForm' }) | ||||
|  | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
|  | ||||
| const dialogVisible = ref(false) // 弹窗的是否展示 | ||||
| const dialogTitle = ref('') // 弹窗的标题 | ||||
| const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 | ||||
| const formType = ref('') // 表单的类型:create - 新增;update - 修改 | ||||
| const formData = ref({ | ||||
|   id: undefined, | ||||
|   name: '', | ||||
|   shortName: '', | ||||
|   status: CommonStatusEnum.ENABLE, | ||||
|   remark: '' | ||||
| }) | ||||
| const formRules = reactive({ | ||||
|   name: [{ required: true, message: '商户名称不能为空', trigger: 'blur' }], | ||||
|   shortName: [{ required: true, message: '商户简称不能为空', trigger: 'blur' }], | ||||
|   status: [{ required: true, message: '状态不能为空', trigger: 'change' }] | ||||
| }) | ||||
| const formRef = ref() // 表单 Ref | ||||
|  | ||||
| /** 打开弹窗 */ | ||||
| const open = async (type: string, id?: number) => { | ||||
|   dialogVisible.value = true | ||||
|   dialogTitle.value = t('action.' + type) | ||||
|   formType.value = type | ||||
|   resetForm() | ||||
|   // 修改时,设置数据 | ||||
|   if (id) { | ||||
|     formLoading.value = true | ||||
|     try { | ||||
|       formData.value = await MerchantApi.getMerchant(id) | ||||
|     } finally { | ||||
|       formLoading.value = false | ||||
|     } | ||||
|   } | ||||
| } | ||||
| defineExpose({ open }) // 提供 open 方法,用于打开弹窗 | ||||
|  | ||||
| /** 提交表单 */ | ||||
| const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 | ||||
| const submitForm = async () => { | ||||
|   // 校验表单 | ||||
|   if (!formRef) return | ||||
|   const valid = await formRef.value.validate() | ||||
|   if (!valid) return | ||||
|   // 提交请求 | ||||
|   formLoading.value = true | ||||
|   try { | ||||
|     const data = formData.value as unknown as MerchantApi.MerchantVO | ||||
|     if (formType.value === 'create') { | ||||
|       await MerchantApi.createMerchant(data) | ||||
|       message.success(t('common.createSuccess')) | ||||
|     } else { | ||||
|       await MerchantApi.updateMerchant(data) | ||||
|       message.success(t('common.updateSuccess')) | ||||
|     } | ||||
|     dialogVisible.value = false | ||||
|     // 发送操作成功的事件 | ||||
|     emit('success') | ||||
|   } finally { | ||||
|     formLoading.value = false | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** 重置表单 */ | ||||
| const resetForm = () => { | ||||
|   formData.value = { | ||||
|     id: undefined, | ||||
|     name: '', | ||||
|     shortName: '', | ||||
|     status: CommonStatusEnum.ENABLE, | ||||
|     remark: '' | ||||
|   } | ||||
|   formRef.value?.resetFields() | ||||
| } | ||||
| </script> | ||||
| @@ -1,245 +0,0 @@ | ||||
| <template> | ||||
|   <ContentWrap> | ||||
|     <!-- 搜索工作栏 --> | ||||
|     <el-form | ||||
|       class="-mb-15px" | ||||
|       :model="queryParams" | ||||
|       ref="queryFormRef" | ||||
|       :inline="true" | ||||
|       label-width="68px" | ||||
|     > | ||||
|       <el-form-item label="商户号" prop="no"> | ||||
|         <el-input v-model="queryParams.no" placeholder="请输入商户号" clearable class="!w-240px" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="商户全称" prop="name"> | ||||
|         <el-input | ||||
|           v-model="queryParams.name" | ||||
|           placeholder="请输入商户全称" | ||||
|           clearable | ||||
|           class="!w-240px" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="商户简称" prop="shortName"> | ||||
|         <el-input | ||||
|           v-model="queryParams.shortName" | ||||
|           placeholder="请输入商户简称" | ||||
|           clearable | ||||
|           class="!w-240px" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="开启状态" prop="status"> | ||||
|         <el-select v-model="queryParams.status" placeholder="字典状态" clearable class="!w-240px"> | ||||
|           <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="remark"> | ||||
|         <el-input | ||||
|           v-model="queryParams.remark" | ||||
|           placeholder="请输入备注" | ||||
|           clearable | ||||
|           class="!w-240px" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="创建时间" prop="createTime"> | ||||
|         <el-date-picker | ||||
|           v-model="queryParams.createTime" | ||||
|           value-format="YYYY-MM-DD HH:mm:ss" | ||||
|           type="datetimerange" | ||||
|           start-placeholder="开始日期" | ||||
|           end-placeholder="结束日期" | ||||
|           class="!w-240px" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <el-button @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-button | ||||
|           plain | ||||
|           type="primary" | ||||
|           @click="openForm('create')" | ||||
|           v-hasPermi="['pay:merchant:create']" | ||||
|         > | ||||
|           <Icon icon="ep:plus" class="mr-5px" /> 新增 | ||||
|         </el-button> | ||||
|         <el-button | ||||
|           type="success" | ||||
|           plain | ||||
|           @click="handleExport" | ||||
|           :loading="exportLoading" | ||||
|           v-hasPermi="['pay:merchant:export']" | ||||
|         > | ||||
|           <Icon icon="ep:download" class="mr-5px" /> 导出 | ||||
|         </el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|   </ContentWrap> | ||||
|  | ||||
|   <!-- 列表 --> | ||||
|   <ContentWrap> | ||||
|     <el-table v-loading="loading" :data="list"> | ||||
|       <el-table-column label="商户编号" align="center" prop="id" /> | ||||
|       <el-table-column label="商户号" align="center" prop="no" /> | ||||
|       <el-table-column label="商户全称" align="center" prop="name" /> | ||||
|       <el-table-column label="商户简称" align="center" prop="shortName" /> | ||||
|       <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="remark" /> | ||||
|       <el-table-column | ||||
|         label="创建时间" | ||||
|         align="center" | ||||
|         prop="createTime" | ||||
|         :formatter="dateFormatter" | ||||
|         width="180" | ||||
|       /> | ||||
|       <el-table-column label="操作" align="center"> | ||||
|         <template #default="scope"> | ||||
|           <el-button | ||||
|             link | ||||
|             type="primary" | ||||
|             @click="openForm('update', scope.row.id)" | ||||
|             v-hasPermi="['pay:merchant:update']" | ||||
|           > | ||||
|             修改 | ||||
|           </el-button> | ||||
|           <el-button | ||||
|             link | ||||
|             type="danger" | ||||
|             @click="handleDelete(scope.row.id)" | ||||
|             v-hasPermi="['pay:merchant:delete']" | ||||
|           > | ||||
|             删除 | ||||
|           </el-button> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|     </el-table> | ||||
|     <!-- 分页 --> | ||||
|     <Pagination | ||||
|       :total="total" | ||||
|       v-model:page="queryParams.pageNo" | ||||
|       v-model:limit="queryParams.pageSize" | ||||
|       @pagination="getList" | ||||
|     /> | ||||
|   </ContentWrap> | ||||
|  | ||||
|   <!-- 表单弹窗:添加/修改 --> | ||||
|   <MerchantForm ref="formRef" @success="getList" /> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import { CommonStatusEnum } from '@/utils/constants' | ||||
| import { dateFormatter } from '@/utils/formatTime' | ||||
| import download from '@/utils/download' | ||||
| import * as MerchantApi from '@/api/pay/merchant' | ||||
| import MerchantForm from './MerchantForm.vue' | ||||
|  | ||||
| defineOptions({ name: 'PayMerchant' }) | ||||
|  | ||||
| const message = useMessage() // 消息弹窗 | ||||
| const { t } = useI18n() // 国际化 | ||||
|  | ||||
| const loading = ref(true) // 列表的加载中 | ||||
| const total = ref(0) // 列表的总页数 | ||||
| const list = ref([]) // 列表的数据 | ||||
| const queryParams = reactive({ | ||||
|   pageNo: 1, | ||||
|   pageSize: 10, | ||||
|   name: '', | ||||
|   shortName: '', | ||||
|   status: undefined | ||||
| }) | ||||
| const queryFormRef = ref() // 搜索的表单 | ||||
| const exportLoading = ref(false) // 导出的加载中 | ||||
|  | ||||
| /** 查询列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true | ||||
|   try { | ||||
|     const data = await MerchantApi.getMerchantPage(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 formRef = ref() | ||||
| const openForm = (type: string, id?: number) => { | ||||
|   formRef.value.open(type, id) | ||||
| } | ||||
|  | ||||
| /** 删除按钮操作 */ | ||||
| const handleDelete = async (id: number) => { | ||||
|   try { | ||||
|     // 删除的二次确认 | ||||
|     await message.delConfirm() | ||||
|     // 发起删除 | ||||
|     await MerchantApi.deleteMerchant(id) | ||||
|     message.success(t('common.delSuccess')) | ||||
|     // 刷新列表 | ||||
|     await getList() | ||||
|   } catch {} | ||||
| } | ||||
|  | ||||
| /** 修改状态操作 */ | ||||
| const handleStatusChange = async (row: MerchantApi.MerchantVO) => { | ||||
|   try { | ||||
|     // 修改状态的二次确认 | ||||
|     const text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用' | ||||
|     await message.confirm('确认要"' + text + '""' + row.name + '"商户吗?', t('common.reminder')) | ||||
|     // 发起修改状态 | ||||
|     await MerchantApi.updateMerchantStatus(row.id, row.status) | ||||
|     // 刷新列表 | ||||
|     await getList() | ||||
|   } catch { | ||||
|     // 取消后,进行恢复按钮 | ||||
|     row.status = | ||||
|       row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE : CommonStatusEnum.ENABLE | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** 导出按钮操作 */ | ||||
| const handleExport = async () => { | ||||
|   try { | ||||
|     // 导出的二次确认 | ||||
|     await message.exportConfirm() | ||||
|     // 发起导出 | ||||
|     exportLoading.value = true | ||||
|     const data = await MerchantApi.exportMerchant(queryParams) | ||||
|     download.excel(data, '商户信息.xls') | ||||
|   } catch { | ||||
|   } finally { | ||||
|     exportLoading.value = false | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** 初始化 **/ | ||||
| onMounted(() => { | ||||
|   getList() | ||||
| }) | ||||
| </script> | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV